{"id":49418366,"url":"https://github.com/groupthink-dev/fastmail-blade-mcp","last_synced_at":"2026-04-29T04:12:34.883Z","repository":{"id":347364529,"uuid":"1191668648","full_name":"Groupthink-dev/fastmail-blade-mcp","owner":"Groupthink-dev","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-21T09:56:38.000Z","size":124,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-21T11:40:32.961Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Groupthink-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-25T13:23:58.000Z","updated_at":"2026-04-21T09:56:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Groupthink-dev/fastmail-blade-mcp","commit_stats":null,"previous_names":["groupthink-dev/fastmail-blade-mcp"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Groupthink-dev/fastmail-blade-mcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Groupthink-dev%2Ffastmail-blade-mcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Groupthink-dev%2Ffastmail-blade-mcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Groupthink-dev%2Ffastmail-blade-mcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Groupthink-dev%2Ffastmail-blade-mcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Groupthink-dev","download_url":"https://codeload.github.com/Groupthink-dev/fastmail-blade-mcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Groupthink-dev%2Ffastmail-blade-mcp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32410084,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T03:46:11.172Z","status":"ssl_error","status_checked_at":"2026-04-29T03:37:55.317Z","response_time":110,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-29T04:12:27.382Z","updated_at":"2026-04-29T04:12:34.877Z","avatar_url":"https://github.com/Groupthink-dev.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fastmail Blade MCP\n\nThe only [MCP](https://modelcontextprotocol.io) server built on Fastmail's native JMAP protocol — email, masked email, and push notifications with token-efficient output.\n\nWraps the [Fastmail JMAP API](https://www.fastmail.com/dev/) via [jmapc](https://github.com/smkent/jmapc) as an MCP server using [FastMCP 2.0](https://github.com/jlowin/fastmcp).\n\n## Why Fastmail Blade?\n\nEvery other email MCP uses IMAP — a 1986 protocol that was never designed for programmatic access. Fastmail Blade uses **JMAP**, Fastmail's native protocol:\n\n- **JMAP-native** — stateless, JSON-based, supports batch operations natively. No IDLE hacks, no MIME parsing, no connection state management.\n- **Masked Email** — full CRUD for Fastmail's privacy aliases (create, list, enable/disable). No IMAP MCP can touch this — it's a Fastmail extension that only exists in JMAP.\n- **Push notifications** — real-time EventSource via JMAP Push. Know when mail arrives without polling.\n- **Incremental sync** — JMAP state tokens for delta changes. Get only what's new since your last check, not the entire mailbox.\n- **Token-efficient** — concise pipe-delimited output, null-field omission. IMAP MCPs dump raw headers and MIME multipart.\n- **Write-safe** — env-gated writes, batch limits (50 max), credential scrubbing on all error paths.\n\n## Features\n\n- **18 tools**: email read/write/manage, masked email, push notifications, meta\n- **Masked Email management** — no other MCP server exposes this Fastmail extension\n- **JMAP Push (EventSource)** — real-time state change notifications\n- **Write-gate** — all write operations disabled by default (`FASTMAIL_WRITE_ENABLED=true`)\n- **Token-efficient** — concise output, capped lists, null-field omission\n- **Batch limits** — `mail_bulk` capped at 50, `mail_search` defaults to 20\n- **SKILL.md** — self-teaching instructions for Claude\n\n## Requirements\n\n- macOS (tested) or Linux\n- Python 3.12+\n- [uv](https://docs.astral.sh/uv/)\n- Fastmail account with API token\n\n## Quick Start\n\n```bash\n# Clone and install\ncd fastmail-blade-mcp\nuv sync\n\n# Set your API token\nexport FASTMAIL_API_TOKEN=fmu1-xxxxxxxx\n\n# Run (stdio transport)\nuv run fastmail-blade-mcp\n```\n\n### Claude Code\n\n```bash\nclaude mcp add fastmail-blade -- uv run --directory ~/src/fastmail-blade-mcp fastmail-blade-mcp\n```\n\n### Claude Desktop (claude_desktop_config.json)\n\n```json\n{\n  \"mcpServers\": {\n    \"fastmail-blade\": {\n      \"command\": \"uv\",\n      \"args\": [\"run\", \"--directory\", \"/path/to/fastmail-blade-mcp\", \"fastmail-blade-mcp\"],\n      \"env\": {\n        \"FASTMAIL_API_TOKEN\": \"fmu1-xxxxxxxx\",\n        \"FASTMAIL_WRITE_ENABLED\": \"false\"\n      }\n    }\n  }\n}\n```\n\n## Tools (18)\n\n### Email Read (5)\n\n| Tool | Description |\n|------|-------------|\n| `mail_mailboxes` | Mailbox list with ID, name, total/unread, role |\n| `mail_read` | Full email: headers + body |\n| `mail_search` | Search with filters (sender, subject, date, mailbox, keywords) |\n| `mail_threads` | Chronological conversation view |\n| `mail_snippets` | Search with highlighted context excerpts |\n\n### Email State \u0026 Sync (2)\n\n| Tool | Description |\n|------|-------------|\n| `mail_state` | Get JMAP state token for change tracking |\n| `mail_changes` | Incremental changes since a previous state token |\n\n### Email Write (4, gated)\n\n| Tool | Description |\n|------|-------------|\n| `mail_send` | Send new email |\n| `mail_reply` | Reply (preserves threading) |\n| `mail_move` | Move to mailbox |\n| `mail_flag` | Set/clear keywords ($flagged, $seen, etc.) |\n\n### Email Manage (2, gated)\n\n| Tool | Description |\n|------|-------------|\n| `mail_delete` | Move to Trash (default) or permanently destroy |\n| `mail_bulk` | Bulk action on up to 50 emails |\n\n### Masked Email (3)\n\n| Tool | Description |\n|------|-------------|\n| `masked_list` | List aliases with state, domain, description |\n| `masked_create` | Create new masked alias (gated) |\n| `masked_update` | Update state/description (gated) |\n\n### Push (2)\n\n| Tool | Description |\n|------|-------------|\n| `push_subscribe` | Listen for state changes via EventSource |\n| `push_status` | Check EventSource availability |\n\n## Security\n\n| Layer | Control |\n|-------|---------|\n| Secrets | `FASTMAIL_API_TOKEN` from env (never logged) |\n| Transport | stdio default (no network exposure) |\n| Write gate | `FASTMAIL_WRITE_ENABLED` default false |\n| Batch limits | `mail_bulk` capped at 50 |\n| Token scrubbing | API token removed from all error output |\n| HTTP auth | Optional bearer token middleware |\n\n## HTTP Transport\n\n```bash\nexport FASTMAIL_MCP_TRANSPORT=http\nexport FASTMAIL_MCP_HOST=127.0.0.1\nexport FASTMAIL_MCP_PORT=8767\nexport FASTMAIL_MCP_API_TOKEN=your-secret-token\n\nuv run fastmail-blade-mcp\n```\n\n## Environment Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `FASTMAIL_API_TOKEN` | (required) | Fastmail API token |\n| `FASTMAIL_WRITE_ENABLED` | `false` | Enable write operations |\n| `FASTMAIL_MCP_TRANSPORT` | `stdio` | Transport: `stdio` or `http` |\n| `FASTMAIL_MCP_HOST` | `127.0.0.1` | HTTP bind host |\n| `FASTMAIL_MCP_PORT` | `8767` | HTTP bind port |\n| `FASTMAIL_MCP_API_TOKEN` | (none) | Bearer token for HTTP auth |\n\n## Architecture\n\n```\nsrc/fastmail_blade_mcp/\n├── server.py       — FastMCP 2.0 server, 18 @mcp.tool decorators\n├── client.py       — JMAP client via jmapc, masked email, push subscriptions\n├── formatters.py   — Token-efficient output (pipe-delimited, null omission)\n├── models.py       — Config, write-gate, batch limits\n└── auth.py         — Bearer token middleware for HTTP transport\n```\n\nBuilt with [FastMCP 2.0](https://github.com/jlowin/fastmcp) and [jmapc](https://github.com/smkent/jmapc).\n\n## Development\n\n```bash\nmake install-dev    # Install with dev dependencies\nmake test           # Run unit tests (92 tests, mocked)\nmake test-e2e       # Run E2E tests (requires live Fastmail)\nmake check          # Lint + format + type-check\nmake run            # Start the server\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgroupthink-dev%2Ffastmail-blade-mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgroupthink-dev%2Ffastmail-blade-mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgroupthink-dev%2Ffastmail-blade-mcp/lists"}