Fastmail Blade MCP
The only MCP server built on Fastmail's native JMAP protocol — email, masked email, and push notifications with token-efficient output.
Wraps the Fastmail JMAP API via jmapc as an MCP server using FastMCP 2.0.
Why Fastmail Blade?
Every other email MCP uses IMAP — a 1986 protocol that was never designed for programmatic access. Fastmail Blade uses JMAP, Fastmail's native protocol:
- JMAP-native — stateless, JSON-based, supports batch operations natively. No IDLE hacks, no MIME parsing, no connection state management.
- 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.
- Push notifications — real-time EventSource via JMAP Push. Know when mail arrives without polling.
- Incremental sync — JMAP state tokens for delta changes. Get only what's new since your last check, not the entire mailbox.
- Token-efficient — concise pipe-delimited output, null-field omission. IMAP MCPs dump raw headers and MIME multipart.
- Write-safe — env-gated writes, batch limits (50 max), credential scrubbing on all error paths.
Features
- 18 tools: email read/write/manage, masked email, push notifications, meta
- Masked Email management — no other MCP server exposes this Fastmail extension
- JMAP Push (EventSource) — real-time state change notifications
- Write-gate — all write operations disabled by default (
FASTMAIL_WRITE_ENABLED=true) - Token-efficient — concise output, capped lists, null-field omission
- Batch limits —
mail_bulkcapped at 50,mail_searchdefaults to 20 - SKILL.md — self-teaching instructions for Claude
Requirements
- macOS (tested) or Linux
- Python 3.12+
- uv
- Fastmail account with API token
Quick Start
# Clone and install
cd fastmail-blade-mcp
uv sync
# Set your API token
export FASTMAIL_API_TOKEN=fmu1-xxxxxxxx
# Run (stdio transport)
uv run fastmail-blade-mcp
Claude Code
claude mcp add fastmail-blade -- uv run --directory ~/src/fastmail-blade-mcp fastmail-blade-mcp
Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"fastmail-blade": {
"command": "uv",
"args": ["run", "--directory", "/path/to/fastmail-blade-mcp", "fastmail-blade-mcp"],
"env": {
"FASTMAIL_API_TOKEN": "fmu1-xxxxxxxx",
"FASTMAIL_WRITE_ENABLED": "false"
}
}
}
}
Tools (18)
Email Read (5)
| Tool | Description |
|---|---|
mail_mailboxes |
Mailbox list with ID, name, total/unread, role |
mail_read |
Full email: headers + body |
mail_search |
Search with filters (sender, subject, date, mailbox, keywords) |
mail_threads |
Chronological conversation view |
mail_snippets |
Search with highlighted context excerpts |
Email State & Sync (2)
| Tool | Description |
|---|---|
mail_state |
Get JMAP state token for change tracking |
mail_changes |
Incremental changes since a previous state token |
Email Write (4, gated)
| Tool | Description |
|---|---|
mail_send |
Send new email |
mail_reply |
Reply (preserves threading) |
mail_move |
Move to mailbox |
mail_flag |
Set/clear keywords ($flagged, $seen, etc.) |
Email Manage (2, gated)
| Tool | Description |
|---|---|
mail_delete |
Move to Trash (default); permanent destroy requires confirm=true |
mail_bulk |
Bulk action on up to 50 emails |
Masked Email (3)
| Tool | Description |
|---|---|
masked_list |
List aliases with state, domain, description |
masked_create |
Create new masked alias (gated) |
masked_update |
Update state/description (gated; state=deleted requires confirm=true) |
Push (2)
| Tool | Description |
|---|---|
push_subscribe |
Listen for state changes via EventSource |
push_status |
Check EventSource availability |
Security
| Layer | Control |
|---|---|
| Secrets | FASTMAIL_API_TOKEN from env (never logged) |
| Transport | stdio default (no network exposure) |
| Write gate | FASTMAIL_WRITE_ENABLED default false |
| Batch limits | mail_bulk capped at 50 |
| Token scrubbing | API token removed from all error output |
| HTTP auth | Optional bearer token middleware |
HTTP Transport
export FASTMAIL_MCP_TRANSPORT=http
export FASTMAIL_MCP_HOST=127.0.0.1
export FASTMAIL_MCP_PORT=8767
export FASTMAIL_MCP_API_TOKEN=your-secret-token
uv run fastmail-blade-mcp
Environment Variables
| Variable | Default | Description |
|---|---|---|
FASTMAIL_API_TOKEN |
(required) | Fastmail API token |
FASTMAIL_WRITE_ENABLED |
false |
Enable write operations |
FASTMAIL_MCP_TRANSPORT |
stdio |
Transport: stdio or http |
FASTMAIL_MCP_HOST |
127.0.0.1 |
HTTP bind host |
FASTMAIL_MCP_PORT |
8767 |
HTTP bind port |
FASTMAIL_MCP_API_TOKEN |
(none) | Bearer token for HTTP auth |
Architecture
src/fastmail_blade_mcp/
├── server.py — FastMCP 2.0 server, 18 @mcp.tool decorators
├── client.py — JMAP client via jmapc, masked email, push subscriptions
├── formatters.py — Token-efficient output (pipe-delimited, null omission)
├── models.py — Config, write-gate, batch limits
└── auth.py — Bearer token middleware for HTTP transport
Built with FastMCP 2.0 and jmapc.
Development
make install-dev # Install with dev dependencies
make test # Run unit tests (92 tests, mocked)
make test-e2e # Run E2E tests (requires live Fastmail)
make check # Lint + format + type-check
make run # Start the server
License
MIT
Metadata
Release files for fastmail-blade-mcp 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fastmail_blade_mcp-0.6.0.tar.gz | 134.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fastmail_blade_mcp-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 160.9 kB
Release files / fastmail_blade_mcp-0.6.0.tar.gz
| Download URL | fastmail_blade_mcp-0.6.0.tar.gz |
|---|---|
| Size | 134.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1cea04a21ad82eeda10f9f0e3562ba33c33e90b76ee5075e6642447ae1d1ea77
|
|
BLAKE2b-256 checksum How to use checksums |
90d2b6ba7b0d3a7b9c6d7322dbd6c44e935443519e427843ff0ab45b16aa1a08
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 11, 2026.
Transparency logRelease files / fastmail_blade_mcp-0.6.0-py3-none-any.whl
| Download URL | fastmail_blade_mcp-0.6.0-py3-none-any.whl |
|---|---|
| Size | 26.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7f94cb628309d9db932d99fe5b6937d159341aad966b452800ff9863b4597787
|
|
BLAKE2b-256 checksum How to use checksums |
46e0694cfd894f070f1ec26d6b1d5a5d98bb1b0f42b15aa8eeee19a4a4a77bc1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 11, 2026.
Transparency log