Other formats agents might prefer:
markdownjsonllms.txt

Agent? You probably want markdown or json, or Pod over MCP.

Reported issues for mcp-gee-sweet

Pod holds 23 of 139 GitHub reports that passed its relevance review. This can include external user reports, maintainer-confirmed bugs, and concrete feature gaps. Treat them as evidence to inspect, not a count of distinct defects.

Back to mcp-gee-sweet.

Most discussed

qa: dedicated QA Google account, calendar, and pollution cleanup

Consolidates #225, #226, #249 — all three are the same underlying fix: QA runs currently use a personal Google account and primary calendar, which pollutes real Drive/Calendar with stray artifacts and blocks safe share/permission testing. One dedicated account (and the OAuth-scope follow-on) solves all three angles together.

  • Dedicated QA account — create mcp-gee-sweet-qa@ (OAuth) for QA runs, plus a second mcp-gee-sweet-qa-2@ account for share/permission tests (replaces…

Read the thread · 2026-07-14 · open · 3 comments

Markdown-to-Doc conversion silently keeps GitHub/GitLab-style #slug anchor links as dead hyperlinks instead of resolving to Docs-native internal links

Context

Source markdown (GitLab Pages-published policy docs) uses standard GitHub/GitLab-style heading-anchor links for internal cross-references, e.g.:

Approved encryption algorithms are contained in [Appendix A](#appendix-a---approved-hashing-algorithms).

These render correctly as in-page jump links on GitLab Pages (which auto-generates heading slugs), but after create_doc_from_file conversion, the resulting Google Doc has "Appendix A" as a styled hyperlink (blue,…

Read the thread · 2026-07-24 · closed · external user · 2 comments

markdown-to-Doc conversion silently drops images; no path from local files to inline images

Context

Follow-up split-out from #332, focused specifically on the markdown-to-Doc image gap.

create_doc and write_doc_content support content_format="markdown" for headings, lists, links, tables, etc., but standard markdown image syntax (![alt](path)) is silently dropped/ignored during conversion. There's no way to reference a local file path or even a relative path from the caller's working directory - only insert_inline_image supports images, and only via a public HTTPS URL or an…

Read the thread · 2026-07-16 · closed · external user · 2 comments

feat(calendar): list_all_events — query all subscribed calendars in parallel

Summary

Add a list_all_events tool that fans out list_events calls across all subscribed calendars in parallel and returns a unified result, eliminating the need to call list_events once per calendar.

Motivation

Currently querying multiple calendars requires one list_events call per calendar. During QA for #155 this was done manually with 8 parallel tool calls. A single tool that handles fan-out internally is faster and more convenient.

Proposed API


[Read the thread](https://github.com/khuisman/mcp-gee-sweet/issues/194) · 2026-06-25 · closed · 2 comments

### decision-needed: evaluate deprecating share_spreadsheet in favor of share_file

## Why

Surfaced during architecture review for `docs/decisions/decision-comments-first-class.md` (#661), as a parallel instance of the same pattern that motivated that doc: `share_spreadsheet` (`tools/drive/sharing.py`) is the project's original tool (PR #1, predating Drive having its own domain). `share_file`, added later, is a **strict superset** of its capability — `share_spreadsheet`'s always-`type=user` email+role shape is fully expressible as `share_file(file_id=spreadsheet_id,…

[Read the thread](https://github.com/khuisman/mcp-gee-sweet/issues/665) · 2026-08-29 · open · 1 comment

### sync_folder dry_run response exceeds 40k-char cap on moderately-sized folders (deterministic, not size-related to the actual folder size)

## Summary

`sync_folder(dry_run=True)` fails with a hard error once a folder's file count pushes the response past a 40,000-character safety cap. Hit this today syncing a Drive folder with 303 local files / 280 Drive files (upload direction):

Error executing tool sync_folder: sync_folder: the response is 40119 characters, over the 40000-character safety cap. Recursive syncs can produce very large result lists. Narrow folder_id, direction, or recursive scope, or set MAX_TOOL_RESPONSE_CHARS…

Read the thread · 2026-08-03 · closed · external user · 1 comment

Unsupported/dropped markdown constructs collapse their paragraph into adjacent content instead of preserving block-level structure

Context

Both #333 (dropped images) and #399 (dropped thematic breaks) exhibit the same underlying behavior: when the markdown-to-Doc converter can't represent a construct, it deletes that construct's entire paragraph rather than leaving an empty block in its place.

This breaks fidelity with how every standard CommonMark-compliant viewer (GitHub, GitLab Pages, VS Code preview, etc.) degrades. In those renderers, block-level separation is preserved regardless of whether a specific inline…

Read the thread · 2026-07-22 · closed · external user · 1 comment

create_doc_from_file / markdown conversion silently drops thematic breaks (---), worse than design doc anticipated

Context

While converting a batch of policy markdown files to Google Docs via create_doc_from_file, found that a --- thematic break (used as a visual section divider directly under the doc title in every source file) is completely dropped during conversion — no paragraph, no <hr>-equivalent, no trace at all in the resulting Doc's structure.

Repro:

# Title

---

## Heading

Converts to a Doc where the "Title" heading and "Heading" paragraph sit immediately adjacent (the…

Read the thread · 2026-07-22 · closed · external user · 1 comment

Most recent

Decide + test intended rendering for min_depth>=2 isolated bullet runs (behavior change from PR #711)

Summary

PR #711 (issue #439) changed how an isolated contiguous bullet run — every BulletItem at depth > 0 with no depth == 0 sibling in the same createParagraphBullets call — is rendered. The fix wraps such a run with a throwaway 0-tab anchor paragraph so the real items land at their true nestingLevel. For a min_depth == 1 run this produces nestingLevel 1 (the intended #439 fix). For a min_depth >= 2 run it now produces an absolute nestingLevel of 2+ — i.e.…

Read the thread · 2026-09-09 · open · 0 comments

create_paragraph_bullets collapses an all-nesting_level>=1 run to nestingLevel 0 (same #439 shape, unfixed path in style.py)

Summary

create_paragraph_bullets (src/mcp_gee_sweet/tools/docs/style.py) implements the same "leading-tab characters + one createParagraphBullets call per contiguous run" mechanism that emitter.py's deferred bullet pass uses, but it did not receive the #439 fix (PR #711, emitter.py only). The same collapse-to-nestingLevel 0 bug is still reachable through this tool.

Mechanism

style.py (~L697-717): for each unit it emits insertText of "\t" * nesting_level at the…

Read the thread · 2026-09-09 · open · 0 comments

find_free_slots per-calendar error shape is less detailed than list_all_events for the same failure mode

`find_free_slots` inlines a bad calendar ID as `busy[""] = [{"error": "notFound"}]` (a bare reason string), whereas `list_all_events` inlines `{calendar_id, calendar_summary, error: ""}` for the identical failure. Both handle the failure gracefully (no abort) — this is a consistency/detail-level gap, not a crash.

Expected: align the two tools' per-calendar error shape, or document why they intentionally differ.

Found during the v0.9.0 QA pass…

Read the thread · 2026-09-05 · open · 0 comments

download_file with a non-existent trailing-slash directory creates a clobbering file instead of the directory

`download_file(file_id, local_path="/some/new/dir/", ...)` where `/some/new/dir/` doesn't exist yet creates a plain file at that literal path (not a directory containing the downloaded file), and reports `local_path` as if it had saved the file inside a directory. Every subsequent download to the same `local_path` silently overwrites that file with no warning. Once the directory already exists, all directory-target behavior is correct.

Expected: create the directory (`mkdir…

Read the thread · 2026-09-05 · open · 0 comments

list_folders with no parent ignores DRIVE_FOLDER_ID, hardcodes personal My-Drive root

`tools/drive/files.py` `list_folders(parent_folder_id=None)` appends `q += " and 'root' in parents"` unconditionally when no parent is given — unlike `create_folder`/`create_spreadsheet`, which resolve a missing parent from `lc.folder_id` (= `DRIVE_FOLDER_ID`). On a Shared-Drive deployment (`DRIVE_FOLDER_ID` set) `list_folders(None)` therefore lists the OAuth user's personal My-Drive root, not the configured default; for a pure service-account deployment there is no personal…

Read the thread · 2026-09-05 · open · 0 comments

list_files/list_spreadsheets/list_folders: folder-listing cache key omits max_results — silent truncation + cache poisoning

The folder-listing cache (shared by `list_files`, and transitively `list_spreadsheets`/`list_folders`) keys its cached entries without `max_results` as part of the key. Two live-reproduced consequences:

  1. A call with a smaller `max_results` than a prior cached call for the same folder gets served the prior (larger, unfiltered) cached result and ignores its own limit — e.g. `list_files(FOLDER_ID, max_results=2)` returned 5 items because an earlier default-size call had already…

Read the thread · 2026-09-05 · closed · 0 comments

share_spreadsheet fails with "File not found" on any Shared Drive file — missing supportsAllDrives=True

`tools/drive/sharing.py`'s `share_spreadsheet._share_one` calls `drive_service.permissions().create(fileId=spreadsheet_id, ...)` with no `supportsAllDrives=True` — the only permission-mutating call in the file missing it (`update_permission`, `remove_permission`, `list_permissions`, `transfer_ownership`, and `share_file._share_one` all pass it). On a Shared Drive item, the Drive API returns "File not found" for a `permissions().create()` call that omits this flag, so…

Read the thread · 2026-09-05 · closed · 0 comments

docs image-sharing failure paths: unrevocable anyone:reader grant + missing folder-cache invalidation in _replace_doc_content

Summary

Two non-blocking cleanup gaps in the inline-image sharing failure paths, surfaced by /code-review high during QA of PR #652 (#649) and judged non-blocking for that PR (the primary #649 fix — surface the orphan file id — works). Related dedup is tracked separately in #511.

1. Post-share failure carries file_id but not permission_id — public grant can be left unrevocable

All three call sites wrap permissions().create() and files().get(webContentLink) in one try:…

Read the thread · 2026-08-29 · open · 0 comments

feat(drive): full comments/replies CRUD parity (delete, reply, reopen, get, update)

Why

Per docs/decisions/decision-comments-first-class.md (#661): the Drive comments/replies resource fully supports create/get/list/update/delete on both (confirmed live against the real API discovery doc), but this codebase only implements list/create for comments and a resolve-flavored create for replies. delete_doc_comment was explicitly out of scope for #151 per its own QA docs — this closes that gap along with the rest.

Depends on #663 (generalization/rename)…

Read the thread · 2026-08-29 · open · 0 comments

feat(drive): generalize comment tools to tools/drive/comments.py

Why

Per docs/decisions/decision-comments-first-class.md (#661): list_doc_comments/add_doc_comment/resolve_doc_comment (tools/docs/comments.py, #151) already call the generic Drive comments()/replies() resource against any fileId — confirmed live against a real Spreadsheet with zero code changes. The only thing scoping them to Docs is naming and module placement.

What this needs

  • Move the implementation to tools/drive/comments.py. Retire tools/docs/comments.py. -…

Read the thread · 2026-08-29 · open · 0 comments

sync_folder reports "in sync" when mtimes match but content differs (rename-in-place); use_checksum can't catch it

Problem

sync_folder silently reports "in sync" for a name whose content differs on the two sides, whenever the two mtimes happen to agree. The most reliable way to produce this is a rename-in-place: mv preserves mtime, so renaming Pt 6.pngPt 3.png locally changes what's behind the name Pt 3.png while leaving its mtime exactly as it was. Drive's Pt 3.png still holds the old Pt 3 content, the mtimes match, and the sync skips it — permanently, since nothing will ever…

Read the thread · 2026-08-25 · open · external user · 0 comments

Add /roadmap-status command — role-based "what's left, who's doing it" report

Why

Kai currently reconstructs "what's left and who owns it" by hand each time (cross-referencing gh issue list by label, worktree state, open PRs) — there's no repeatable command for it. Requested by the user 2026-08-18 while doing a v0.9 role assessment (dev vs. QA vs. doc vs. prompt vs. design throughput) — that assessment found the bottleneck wasn't dev throughput but QA-infra decisions and an unowned design gap (#588), which took manual cross-referencing across several `gh issue…

Read the thread · 2026-08-19 · closed · 0 comments

get_doc_as_markdown: silent content loss on two narrow edge cases

Two narrow edge cases in the new get_doc_as_markdown tool (#300, PR #591) silently drop real content with no error, no placeholder, and no trace — found during PR #591's QA round 1 code review and confirmed live.

1. Image dropped when mixed into an all-Courier-New paragraph

ast_to_markdown.py's _is_code_block filters node.runs to Run items only before checking font_family, so an Image node sitting in a paragraph whose text runs are all styled font_family="Courier New" is…

Read the thread · 2026-08-15 · closed · 0 comments

observability: _timed logs 200 status for tool calls that catch their own exception and return {error: ...}

Context

Raised during PR #577 (issue #494) code review. server.py's _timed wrapper logs whatever status the tool call returns; a tool that catches its own exception internally and returns {"error": ...} (the established convention for search_files, search_spreadsheets, and now list_shared_with_me/list_recent_files per #494) never raises, so _timed logs a 200 for it same as a genuine success.

Impact

A real Drive/Sheets/Docs API outage on one of these tools produces an…

Read the thread · 2026-08-12 · open · 0 comments

Inline-image pre-validation only checks the 25-megapixel limit, not Google's 50MB file-size limit (#400 follow-up)

Live-discovered during PR #554's QA round 2 (issue #400, oversized inline-image handling).

docs/images.py's own module docstring cites both of Google Docs' documented insertInlineImage limits: "the ceiling as 25 megapixels (also 50MB, PNG/JPEG/GIF only)." But check_dimensions/check_image_bytes only implement the megapixel check — there's no byte-size check anywhere in the module.

Confirmed live: a real, Pillow-decodable PNG under 25 megapixels but with a large byte size…

Read the thread · 2026-08-10 · closed · 0 comments

The remaining reports are on the project's issue tracker.