An open API service indexing awesome lists of open source software.

https://github.com/groupthink-dev/fastmail-blade-mcp


https://github.com/groupthink-dev/fastmail-blade-mcp

Last synced: about 1 month ago
JSON representation

Awesome Lists containing this project

README

          

# Fastmail Blade MCP

The only [MCP](https://modelcontextprotocol.io) server built on Fastmail's native JMAP protocol — email, masked email, and push notifications with token-efficient output.

Wraps 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).

## 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_bulk` capped at 50, `mail_search` defaults to 20
- **SKILL.md** — self-teaching instructions for Claude

## Requirements

- macOS (tested) or Linux
- Python 3.12+
- [uv](https://docs.astral.sh/uv/)
- Fastmail account with API token

## Quick Start

```bash
# 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

```bash
claude mcp add fastmail-blade -- uv run --directory ~/src/fastmail-blade-mcp fastmail-blade-mcp
```

### Claude Desktop (claude_desktop_config.json)

```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) or permanently destroy |
| `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) |

### 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

```bash
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](https://github.com/jlowin/fastmcp) and [jmapc](https://github.com/smkent/jmapc).

## Development

```bash
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