Skip to content

feat(gmail): add --inline and --text content modes to gmail attachment#5

Closed
chrischall wants to merge 1 commit into
mainfrom
claude/gmail-attachment-inline
Closed

feat(gmail): add --inline and --text content modes to gmail attachment#5
chrischall wants to merge 1 commit into
mainfrom
claude/gmail-attachment-inline

Conversation

@chrischall

Copy link
Copy Markdown
Owner

Problem

gog gmail attachment <messageId> <attachmentId> downloads the bytes, writes them to a local file, and returns only that path. When the caller is a remote MCP client (Claude), the path is unreadable — every attachment download is a dead end.

Changes

  • --inline — returns the content base64-encoded in a contentBase64 JSON field for attachments up to 3 MiB (maxInlineAttachmentBytes). Oversized attachments keep the existing path-only behavior plus an explanatory reason, so callers get a clear signal instead of silently unusable output.
  • --text — returns extracted text in a text field:
    • PDFs via github.com/ledongthuc/pdf (pure Go, panic-guarded); a note flags scanned/image-only PDFs with no text layer.
    • HTML: tags/scripts/styles stripped (gmailcontent.StripHTMLTags).
    • Plain text (and JSON/XML/YAML): returned verbatim.
    • Unsupported types (e.g. images) return a reason pointing at --inline/--out.
    • Mutually exclusive with --inline (usage error).
  • Both modes resolve filename/mimeType from the message payload, with a single-attachment fallback — Gmail attachment IDs are not stable across API responses, so an exact ID match can miss — and content sniffing (%PDF- header, http.DetectContentType) when metadata is unavailable.
  • The file is still written as before; default output (no new flags) is byte-for-byte unchanged ({path, cached, bytes}), so existing local workflows are unaffected.
  • gog gmail get was checked for the same gap: bodies are already inlined (BestBodyText); only attachments resolve to IDs, which these flags now cover.

Tests

TDD throughout (12 new command-level tests against the httptest Gmail API): small-attachment inline round-trip, oversize fallback with reason, default-output unchanged, flag mutual exclusion, PDF extraction (hand-assembled minimal PDF fixture), image-only PDF note, HTML tag-stripping, plain-text verbatim, unsupported-type reason, oversize text reason, unstable-attachment-ID metadata fallback, no-metadata content sniffing.

make lint test passes. Live-verified against a real Gmail account: default/--text/--inline on a real PDF attachment (text extracted; base64 round-trips to the exact original bytes) — both via the CLI and end-to-end through the gogcli-mcp stdio server.

🤖 Generated with Claude Code

gog gmail attachment previously only wrote the attachment to a local file
and returned the path — a dead end for remote callers (MCP clients) that
cannot read the host filesystem.

- --inline: returns the content base64-encoded in a contentBase64 field
  (JSON) for attachments up to 3 MiB; larger ones keep the path-only
  behavior with an explanatory `reason` instead of failing silently.
- --text: returns extracted text in a `text` field — PDFs via a pure-Go
  text extractor (with a `note` when the PDF is scanned/image-only),
  HTML with tags stripped, plain text verbatim. Unsupported types return
  a clear `reason`. Mutually exclusive with --inline.
- Both modes resolve filename/mimeType from the message payload, with a
  single-attachment fallback (Gmail attachment IDs are not stable across
  API responses) and content sniffing when metadata is unavailable.
- Default behavior (no new flags) is unchanged: {path, cached, bytes}.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@chrischall

Copy link
Copy Markdown
Owner Author

Reopened against upstream instead: openclaw#919

@chrischall chrischall closed this Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant