Turn Thunderbird into an MCP (Model Context Protocol) server. Any MCP-compatible AI assistant — Claude Code, Claude Desktop, Cursor, Continue, or a local LLM — can read your mail, draft replies, manage filters, organize your inbox, and work with your calendar. 41 tools, one open protocol, zero vendor lock-in.
stdio HTTP (localhost:8765–8774)
MCP client <-----------> Bridge <---------------------------> Thunderbird
(Claude etc.) mcp-bridge.cjs Extension + HTTP server
The Thunderbird extension embeds a minimal HTTP server on localhost, authenticated with a per-session bearer token. The Node.js bridge (mcp-bridge.cjs) translates between MCP's stdio protocol and HTTP, discovering the port and token automatically via a connection file.
Download dist/thunderbird-mcp.xpi and install it in Thunderbird:
Tools → Add-ons → Install Add-on From File, then restart.
Add this to your MCP client config (e.g. ~/.claude.json for Claude Code):
{
"mcpServers": {
"thunderbird-mail": {
"command": "node",
"args": ["/absolute/path/to/thunderbird-mcp/mcp-bridge.cjs"]
}
}
}Done. Your AI now has access to Thunderbird.
| Tool | Description |
|---|---|
listAccounts |
List all mail accounts and identities |
listFolders |
Browse folder tree with message counts |
searchMessages |
Full-text search with filters (from, to, subject, date, tags) |
getMessage |
Read a message — markdown / text / html / raw source |
getMessages |
Batch read up to 50 messages |
getRecentMessages |
Recent messages with date/unread/flagged filters |
getThread |
Get all messages in a conversation thread |
getEmailStats |
Inbox analytics: counts, top senders, daily histogram |
displayMessage |
Open a message in the Thunderbird GUI |
updateMessage |
Mark read/unread, flag, tag, move, or trash |
deleteMessages |
Delete messages (with dry-run preview) |
createFolder |
Create a new subfolder |
renameFolder |
Rename a folder |
deleteFolder |
Delete a folder (move to trash) |
moveFolder |
Move a folder under a new parent |
emptyTrash |
Permanently empty the trash |
emptyJunk |
Permanently empty the spam folder |
| Tool | Description |
|---|---|
sendMail |
Compose and send — review window by default, skipReview to send directly |
saveDraft |
Save a draft without sending or opening compose |
replyToMessage |
Reply with quoted original and correct threading headers |
forwardMessage |
Forward a message, preserving all attachments |
All compose tools validate the from identity — if the sender address isn't a configured Thunderbird identity, the tool returns an error rather than silently using the wrong account.
| Tool | Description |
|---|---|
listFilters |
List all filter rules with human-readable conditions/actions |
createFilter |
Create a filter with structured conditions and actions |
updateFilter |
Modify a filter's name, enabled state, conditions, or actions |
deleteFilter |
Delete a filter by index |
reorderFilters |
Change filter execution priority |
applyFilters |
Run filters against a folder — let AI organize your inbox |
| Tool | Description |
|---|---|
searchContacts |
Search contacts by name or email across all address books |
createContact |
Create a contact in any writable address book |
updateContact |
Update a contact's email, name, or display name |
deleteContact |
Delete a contact by UID |
| Tool | Description |
|---|---|
listCalendars |
List all calendars with their capabilities |
listCategories |
List calendar category names |
createEvent |
Create a calendar event |
listEvents |
List events in a date range |
updateEvent |
Modify event title, time, location, description, or status |
deleteEvent |
Delete an event by ID |
createTask |
Create a task/todo |
listTasks |
List tasks with completion/due-date filters |
updateTask |
Update task title, due date, priority, or completion |
| Tool | Description |
|---|---|
getAccountAccess |
Show which accounts and tools are accessible |
- Bearer token authentication: The HTTP server requires a per-session token, generated at startup and written to
<TmpD>/thunderbird-mcp/connection.jsonwith0600permissions. - Dynamic port: Tries ports 8765–8774, recording the chosen port in the connection file.
- Account access control: Restrict which mail accounts are visible to MCP clients via the extension settings page.
- Tool access control: Disable specific tools from the settings page.
- Send safety: Optionally block
skipReview: trueto prevent silent sending. - Localhost only: Binds to
127.0.0.1by default.
# Install dev dependencies
npm install
# Build everything (bridge + extension + xpi)
npm run build
# Run tests
npm test
# Type-check only
npm run typecheckthunderbird-mcp/
├── mcp-bridge.cjs # stdio ↔ HTTP bridge (built from src/bridge/)
├── src/
│ ├── bridge/
│ │ └── mcp-bridge.ts # MCP lifecycle + connection discovery
│ └── extension/
│ ├── background.ts # Extension entry point
│ ├── thunderbird.d.ts # Thunderbird WebExtension API types
│ └── mcp_server/
│ ├── server.ts # Tool registry, routing, access control
│ └── tools/ # 41 tool implementations
│ ├── mail.ts
│ ├── compose.ts
│ ├── filters.ts
│ ├── contacts.ts
│ ├── calendar.ts
│ └── access.ts
├── extension/ # Static extension assets
│ ├── manifest.json
│ ├── mcp_server/
│ │ ├── schema.json # Experiment API schema
│ │ └── api.js # HTTP server via XPCOM nsIServerSocket
│ ├── options.html # Settings UI
│ └── icons/
├── dist/
│ └── thunderbird-mcp.xpi # Built extension package
├── scripts/
│ └── build.sh
└── test/
- IMAP folders may lag — click a folder in Thunderbird to sync.
- Pure HTML emails are converted to plain text.
- Recurring calendar events are modified as a series, not individual instances.
- Filter operations on IMAP accounts only apply to locally cached messages.
searchBodyon IMAP requires offline sync enabled (Gloda limitation).
MIT. The embedded HTTP server is written from scratch using Mozilla's XPCOM nsIServerSocket — no third-party HTTP library is bundled.