{
  "markdown": "# gmail-attachments-mcp\n\n<!-- mcp-name: io.github.zayansalman/gmail-attachments-mcp -->\n\nA focused [Model Context Protocol](https://modelcontextprotocol.io) server (and standalone CLI) for downloading Gmail attachments to disk. Three tools, read-only OAuth scope, no extra surface area.\n\nBuilt because the hosted `claude.ai Gmail` connector in Claude Desktop returns attachment **IDs and metadata only** — not the actual bytes. This server fills that gap for any MCP client (Claude Code, Claude Desktop, Cursor, Cline, etc.), and also works as a plain CLI for cron jobs and shell scripts.\n\nIf you used [`@GongRzhe/Gmail-MCP-Server`](https://github.com/GongRzhe/Gmail-MCP-Server) (1.1k★, archived 2026-03-03) for its attachment-download workflow, this is a minimal successor focused on that single capability.\n\n## Features\n\n- **3 MCP tools** — `gmail_search`, `gmail_download_thread_attachments`, `gmail_download_latest_matching`. That's the whole API.\n- **Read-only OAuth scope** (`gmail.readonly`) — can't send, delete, or modify mail.\n- **Works as both an MCP server and a standalone CLI** — same code, same auth token, both surfaces.\n- **Env-var-driven config** — `GMAIL_MCP_CREDENTIALS`, `GMAIL_MCP_TOKEN`, `GMAIL_MCP_DEFAULT_DEST_DIR`.\n- **Cron-friendly** — once authorized, the cached refresh token lets headless jobs run indefinitely.\n\n## Install\n\n```bash\npip install gmail-attachments-mcp\n# or, with uv:\nuv tool install gmail-attachments-mcp\n```\n\n## One-time setup (~10 minutes)\n\nYou need a Google Cloud OAuth client. The server runs entirely on your machine; nothing leaves it.\n\n1. Sign in to [Google Cloud Console](https://console.cloud.google.com/) with the Gmail account whose attachments you want to download.\n2. Create a project (or pick an existing one).\n3. Enable the Gmail API: [console.cloud.google.com/apis/library/gmail.googleapis.com](https://console.cloud.google.com/apis/library/gmail.googleapis.com).\n4. Configure the OAuth consent screen under **APIs & Services → OAuth consent screen**:\n   - **Google Workspace** users: User type = **Internal** (no app verification needed).\n   - **Personal Gmail** users: User type = **External**. Add your own Gmail address as a test user under \"Test users\".\n5. **APIs & Services → Credentials → + Create credentials → OAuth client ID**\n   - Application type: **Desktop app**\n   - Download the JSON.\n6. Run setup:\n\n```bash\ngmail-attachments-mcp setup --import-credentials ~/Downloads/client_secret_*.json\n```\n\nA browser window opens for OAuth consent. After consent, a refresh token is cached at `~/.config/gmail-attachments-mcp/token.json` (or `$XDG_CONFIG_HOME/gmail-attachments-mcp/`).\n\nVerify:\n```bash\ngmail-attachments-mcp status\ngmail-attachments-mcp search \"has:attachment newer_than:7d\" --max 3\n```\n\nSee [docs/setup-google-oauth.md](docs/setup-google-oauth.md) for screenshots and troubleshooting.\n\n## Use it from Claude Code\n\n```bash\nclaude mcp add --scope user gmail-attachments gmail-attachments-mcp -- serve\n```\n\nThen in any Claude Code session:\n\n> Use the gmail-attachments MCP to download the latest CV from `careers@example.com` to `~/CVs`.\n\n## Use it from Claude Desktop\n\nEdit `~/Library/Application Support/Claude/claude_desktop_config.json` (Mac) or `%APPDATA%/Claude/claude_desktop_config.json` (Windows):\n\n```json\n{\n  \"mcpServers\": {\n    \"gmail-attachments\": {\n      \"command\": \"gmail-attachments-mcp\",\n      \"args\": [\"serve\"]\n    }\n  }\n}\n```\n\nRestart Claude Desktop. See [docs/claude-desktop.md](docs/claude-desktop.md) for details.\n\n## Use it from Cursor / Cline / Continue / others\n\nAny MCP client that supports stdio servers. Point it at the same `gmail-attachments-mcp serve` command. See [docs/other-clients.md](docs/other-clients.md).\n\n## Use it from the shell or cron\n\n```bash\n# Search\ngmail-attachments-mcp search \"from:noreply@stripe.com has:attachment newer_than:30d\"\n\n# Download every attachment from a specific thread\ngmail-attachments-mcp thread 19db831fab15b507 --dest ~/Invoices\n\n# Download from the latest match, only PDFs\ngmail-attachments-mcp latest \"from:hr@example.com has:attachment\" --dest ~/CVs --ext .pdf,.docx\n```\n\nCron example — pull CV attachments hourly:\n```cron\n0 * * * * /usr/local/bin/gmail-attachments-mcp latest \"to:careers@example.com has:attachment newer_than:2d\" --dest ~/CVs --ext .pdf,.docx >> ~/.cache/gmail-attachments-mcp.log 2>&1\n```\n\n## The 3 MCP tools\n\n### `gmail_search(query, max_results=10)`\nReturns thread summaries with attachment filenames. Use Gmail's standard query syntax.\n\n```json\n[\n  {\n    \"thread_id\": \"19db831fab15b507\",\n    \"subject\": \"Folon Q3 2026 Quarterly Product Recap\",\n    \"sender\": \"Manon Muhtasin Rahman <manon@example.com>\",\n    \"date\": \"Thu, 23 Apr 2026 08:35:00 +0600\",\n    \"snippet\": \"Hi everyone, Attached is...\",\n    \"message_count\": 1,\n    \"attachment_count\": 1,\n    \"attachment_filenames\": [\"Folon Quarterly Report Q3 2026.pdf\"]\n  }\n]\n```\n\n### `gmail_download_thread_attachments(thread_id, dest_dir?, extensions?)`\nDownloads every attachment in a thread to disk. Returns `path`, `size_bytes`, `mime_type`, `original_filename` per file.\n\n### `gmail_download_latest_matching(query, dest_dir?, extensions?)`\nConvenience: search + download from the single most recent match, in one call.\n\n## Configuration\n\nAll paths can be overridden via environment variables.\n\n| Variable | Default | What |\n|---|---|---|\n| `GMAIL_MCP_CREDENTIALS` | `~/.config/gmail-attachments-mcp/credentials.json` | OAuth client secret JSON |\n| `GMAIL_MCP_TOKEN` | `~/.config/gmail-attachments-mcp/token.json` | Cached refresh token |\n| `GMAIL_MCP_DEFAULT_DEST_DIR` | `~/Downloads` | Default download destination |\n| `GMAIL_MCP_SCOPES` | `https://www.googleapis.com/auth/gmail.readonly` | OAuth scopes (comma-separated) |\n| `XDG_CONFIG_HOME` | `~/.config` | Standard XDG override |\n\n## Security\n\n- **Token storage**: refresh token is written to `~/.config/gmail-attachments-mcp/token.json` with mode `0600`. Anyone with shell access to your account can read your Gmail. Treat the file like a password.\n- **OAuth scope**: default is `gmail.readonly`. Cannot send, delete, or modify mail. If you change `$GMAIL_MCP_SCOPES`, you're on the hook for the consequences.\n- **Credential file**: your OAuth client secret JSON is *not* a password — it identifies your app to Google. But never commit it. The included `.gitignore` blocks the common filenames.\n- **OAuth client**: your client lives in *your* Google Cloud project. There's no central server, no telemetry, nothing leaves your machine.\n\n## Troubleshooting\n\n**`No valid Gmail token` when invoked from Claude Desktop / cron**\nThe first OAuth flow requires a browser. Run `gmail-attachments-mcp setup` once in a terminal where a browser can open. Subsequent runs use the cached refresh token.\n\n**`Token has been expired or revoked`**\nRefresh tokens stay valid as long as you use them at least every 6 months and don't revoke them at [myaccount.google.com/permissions](https://myaccount.google.com/permissions). Re-auth:\n```bash\ngmail-attachments-mcp setup --reauth\n```\n\n**`Access blocked: This app's request is invalid`**\nOn personal Gmail, your OAuth consent screen needs your address listed under **Test users**. Workspace users should select **Internal** audience to avoid this.\n\n**`HttpError 403: Request had insufficient authentication scopes`**\nYou changed `$GMAIL_MCP_SCOPES` without re-authorizing. Run `gmail-attachments-mcp setup --reauth`.\n\n## Comparison with other Gmail MCP servers\n\n| Server | Scope | Tools | Maintenance |\n|---|---|---|---|\n| Anthropic hosted `claude.ai Gmail` | Read/write, hosted | many | Active, but **no attachment bytes** |\n| [GongRzhe/Gmail-MCP-Server](https://github.com/GongRzhe/Gmail-MCP-Server) | Full mailbox | 19 | **Archived 2026-03-03** |\n| [shinzo-labs/gmail-mcp](https://github.com/shinzo-labs/gmail-mcp) | Full mailbox | ~30 | Active |\n| **gmail-attachments-mcp** (this) | **read-only** | **3** | Active |\n\nPick this one if you want a tiny, focused, read-only tool. Pick a fuller one if you also need to send mail, manage labels, drafts, threads, etc.\n\n## Authentication — bring your own Google OAuth client\n\nThere are **no API keys and no shipped secrets**. The server authenticates to *your* Google account with an OAuth client *you* create, and caches a refresh token locally. The author has zero access to your data.\n\n- **Why your own client?** Google's restricted scopes (here, `gmail.readonly`) can't be redistributed in a shared app, and an unverified shared app is capped at 100 users. \"Bring your own OAuth client\" is the standard pattern for personal-data MCP servers.\n- **What you need:** a free Google Cloud project, the Gmail API enabled, an OAuth consent screen, and a Desktop OAuth client. Full walkthrough → [docs/setup-google-oauth.md](docs/setup-google-oauth.md).\n- **Where your token lives:** `~/.config/gmail-attachments-mcp/token.json` (mode `0600`). Delete it to revoke locally; revoke fully at [myaccount.google.com/permissions](https://myaccount.google.com/permissions).\n- **No hosted/SaaS option** — everything runs locally; your mail never touches a third-party server.\n\n## Related tools\n\nPart of a small family of focused, local MCP servers for Google Workspace data the hosted connectors don't expose:\n\n- **gmail-attachments-mcp** — download Gmail attachment bytes to disk *(this repo)*\n- **[google-drive-comments-mcp](https://github.com/zayansalman/google-drive-comments-mcp)** — read comment threads on Docs/Sheets/Slides\n- **[google-drive-files-mcp](https://github.com/zayansalman/google-drive-files-mcp)** — move/organize Drive files\n\nThey can share one OAuth login or stay isolated — see each repo's setup.\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n\n## Contributing\n\nIssues and PRs welcome. Run `pytest` and `ruff check src tests` before submitting.\n\n```bash\ngit clone https://github.com/zayansalman/gmail-attachments-mcp\ncd gmail-attachments-mcp\npip install -e \".[dev]\"\npytest\n```\n",
  "bytes": 9937,
  "sha": "e8875b72d008b7ca93dbfbd06bc2842e2ff1cc4241bf7754f5dfb7a0829bf405",
  "repo_slug": "zayansalman/gmail-attachments-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_zayansalman_gmail_attachments__69c51ec6/readme"
}