Skip to main content
Glama
neil-zielsdorf

tbird-mcp

README.md
# tbird-mcp — Thunderbird-aware Mail MCP

An MCP server that **reads/searches your mail from Thunderbird's local store**
and **sends mail over SMTP from any of your identities**, then files a copy in
the account's Sent folder so it shows up in Thunderbird normally.

Thunderbird has no programmatic send API, so "send through Thunderbird" really
means: read Thunderbird's on-disk mbox files, but put outgoing mail on the wire
ourselves via SMTP. Account and identity configuration is auto-discovered from
Thunderbird's `prefs.js` — you don't re-enter any of it.

## What v1 does

- **Read** — every account, from the local mbox store. Streams even
  multi-gigabyte folders without loading them into memory, and skips messages
  Thunderbird has flagged deleted-but-not-compacted.
- **Send** — any plain-SMTP identity (Migadu, Zoho, Fastmail, generic SMTP, …),
  auto-discovered from Thunderbird.
- **Deferred to v2** — sending **as** Outlook/hotmail. Microsoft disabled basic
  SMTP auth for personal accounts, so it needs a Microsoft Graph / OAuth2 app
  registration. The transport seam is in place (`transports.GraphTransport`);
  until then, `send_mail` from an Outlook identity returns a clear error.

## Tools

| Tool | Purpose |
|------|---------|
| `list_accounts` | Incoming accounts + their on-disk store dir |
| `list_folders(account)` | mbox folders for an account |
| `search_mail(...)` | Filter by account/folder/since/before/from/to/subject/body/has_attachment |
| `read_message(message_id)` | Headers + decoded body |
| `list_attachments(message_id)` | Attachment filenames |
| `extract_attachments(message_id, dest_dir)` | Save attachments (the PDFs) to disk |
| `list_identities` | Send-from addresses + whether each can send now |
| `send_mail(...)` | Send via SMTP, file a copy in Sent. **`dry_run=True` by default** |
| `reload_config` | Re-read prefs.js / credentials.toml after editing |

`search_mail` returns an opaque `id` per message; pass it to the read/extract
tools. **`send_mail` defaults to `dry_run=True`** and returns a preview — pass
`dry_run=False` to actually send.

## Install

```bash
cd ~/agents/personal/mcp-servers/tbird-mcp
uv sync                 # creates .venv with the mcp SDK
uv run python tests/make_fixture.py   # (tests only) generate the sample mbox
uv run pytest -q        # 20+ tests, no real mail sent
```

## 1. Register with Claude Code

Add to your MCP config (e.g. `~/.claude.json`, or via `claude mcp add`):

```json
{
  "mcpServers": {
    "tbird": {
      "command": "uv",
      "args": ["run", "--directory",
               "/path/to/tbird-mcp",
               "tbird-mcp"]
    }
  }
}
```

Optional environment overrides:

- `TBIRD_PROFILE` — absolute path to a specific Thunderbird profile dir
  (default: the active profile from `profiles.ini`).
- `TBIRD_CREDENTIALS` — path to the credentials file
  (default: `~/.config/tbird-mcp/credentials.toml`).

## 2. Add credentials (only needed for sending)

Reading needs no credentials. Sending does:

```bash
mkdir -p ~/.config/tbird-mcp
cp credentials.toml.example ~/.config/tbird-mcp/credentials.toml
chmod 600 ~/.config/tbird-mcp/credentials.toml
$EDITOR ~/.config/tbird-mcp/credentials.toml
```

Use **app passwords**, not your account login passwords:

- **Migadu** — Admin → Mailboxes → the mailbox → *App passwords* → create one.
  Aliases can't authenticate; create the app password on the **real mailbox**
  and point each alias at it with an `[identity."alias@…"] auth_user = "…"`
  block. One mailbox app password typically covers all aliases on its domain.
- **Zoho** — myaccount.zoho.com → Security → *App Passwords* → generate.

After editing, call `reload_config` (or restart the server).

## 3. (Later) v2 — sending as Outlook/hotmail

Outlook/hotmail send needs a one-time, free Azure app registration to obtain a
client ID, then OAuth2 device-code auth against Microsoft Graph's `Mail.Send`
scope. The `graph` transport slot is already wired into the identity registry;
v2 fills in `GraphTransport.send`. Until then, send from a Migadu/Zoho/SMTP
identity, or use Thunderbird directly.

## Notes / limitations

- Search streams the whole folder file, so a query against a multi-gigabyte
  folder takes a few seconds — narrow with `account` + a tight `limit`.
- Message ids encode a byte offset into the mbox; if Thunderbird **compacts**
  a folder, re-run the search to get fresh ids.
- Sub-folders inside `*.sbd` directories aren't enumerated in v1 (top-level
  folders only).

TDQS

A3.7/5.0

Scored across 9 tools

Disambiguation5/5

Each tool targets a distinct action: listing accounts, listing folders, searching, reading, attachments, identities, sending, and reloading config. There is no overlap in functionality.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern in snake_case (e.g., list_accounts, search_mail, send_mail), making it easy to predict tool names.

Tool Count5/5

9 tools is well-scoped for a Thunderbird mail MCP, covering essential operations without being overwhelming or too sparse.

Completeness4/5

The set covers key mail operations (account listing, search, read, send, attachments) but is missing operations like create/delete folders or mark as read, which are minor gaps for the intended use.

Maintenance

ActivityInactive
ResponsivenessNo issues