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 secondmcp-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 () 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["
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:
- 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. Retiretools/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.png → Pt 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.