Self-hosted, read-only MCP server that serves IMAP mail from a local notmuch index over authenticated HTTP
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Documented (README)
- !Install pipes a remote script into a shell (curl | sh)
git clone https://github.com/wildsurfer/your-mail-mcp{
"mcpServers": {
"your-mail-mcp": {
"command": "your-mail-mcp",
"env": {
"PUBLIC_URL": "<public_url>"
}
}
}
}PUBLIC_URLResumen de MCP Servers
# your-mail-mcp
[](https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.wildsurfer)
[](https://glama.ai/mcp/servers/wildsurfer/your-mail-mcp)
Your mail already holds the answers: booking references, gate codes,
invoices, warranty periods, promises people made in writing. This server lets
your AI assistant find them.
**Ask it things like:**
- "Find the booking reference for the June ferry."
- "What was the wifi password the hotel sent last summer?"
- "What did the accountant answer about VAT, and when?"
- "Collect everything between me and the builder about the roof, in order,
and summarize who promised what."
- "What arrived this morning, across all my accounts, that actually needs me?"
**Use it for:**
- **Search that understands questions.** Full-text search over your entire
history, every account in one index, phrased the way you think instead of
the way search syntax works.
- **Triage from your phone.** A morning summary of what came in overnight,
with junk already filtered out, from wherever you are.
- **Mail as context for other work.** Pull the client's requirements out of
the thread and into your coding or writing session, instead of retyping
them.
- **Agents you can leave running.** The server can only read. A malicious
email that reaches your assistant gets read and nothing more, because
sending, deleting and moving do not exist here. That makes scheduled
digests and always-on agents a calm thing to run.
Setup is two files and `docker compose up -d` — see [Running it](#running-it).
A self-hosted MCP server that gives an MCP client (Claude, or any other client
that speaks streamable HTTP MCP with OAuth) read access to your mail. It
mirrors one or more IMAP accounts into a local maildir with
[mbsync](https://isync.sourceforge.io/), indexes them with
[notmuch](https://notmuchmail.org/), and answers tool calls from that index.

Mail only ever moves left to right in that picture. The one arrow the server
makes back toward a provider is an IMAP `LIST`, issued once per account at
startup and repeated hourly, to find out what that server calls its junk and
trash folders; it never selects a mailbox and never fetches a message. The
diagram source is
[`docs/diagrams/how-it-works.html`](docs/diagrams/how-it-works.html).
## What it cannot do
The read-only property is built into the architecture.
The mirror is pull-only. The generated mbsync configuration for every account
carries `Sync Pull`, `Create Near`, `Remove None`, `Expunge None` — nothing in
that configuration can push a change back to the server, delete a message, or
expunge one.
The only IMAP operation anywhere in the Go code is `LIST`, issued once per
account at startup and repeated hourly to find each account's junk and trash
folders (see [Provider notes](#provider-notes) and
[Troubleshooting](#troubleshooting)). An account whose `exclude_folders` is
set by hand skips that call entirely. That connection logs in, lists
mailboxes, and logs out. It never selects a mailbox and never fetches a
message.
There is no send, no delete, no move, and no tag. Attachments are listed in
`show` and `thread` and served read-only by the `attachment` tool, one part
at a time: images inline up to 5MB, textual parts as marked text, and other
binaries as a short-lived signed link to `GET /attachment/{id}/{part}`
(a bearer token works there too). Nothing in the process holds write access
to any account.
Eleven tools, all read-only:
| Tool | What it does |
|---|---|
| `search` | Search mail. Returns thread summaries as JSON. |
| `ids` | Return the message ids matching a query. |
| `files` | Return the maildir file paths matching a query. |
| `count` | Count the messages matching a query. |
| `show` | Show one message: headers and decoded body, as JSON. |
| `thread` | Show the whole thread containing a message. Excludes junk/trash replies by default; set `include_excluded` to include them. |
| `text` | Return the plain-text body of one message, converting HTML. |
| `folders` | List accounts, their folders, index tags, and each account's last sync and last error. |
| `refresh` | Sync INBOX now and report how many messages arrived. |
| `status` | Sync health per account: first-sync completion, last sync, messages indexed, errors and backoff. |
| `attachment` | One attachment or MIME part of a message, by part number from `show`. Images inline, text (JSON and XML included) as a marked block, other binaries as a signed download link. |
`search`, `ids`, `files` and `count` take a notmuch query (`from:`, `to:`,
`subject:`, `tag:`, `folder:`, `date:2026-01-01..2026-06-30`, combined with
and/or/not), an optional `account` to scope to one account, and can include
junk/trash with `include_excluded`.
## Running it
Three ways to run this. They differ in one thing: who can reach the server.
Start at case 1 and move up only when you need to. None of them is hardened
beyond the defaults — that is [Hardening](#hardening), further down, and it is
deliberately separate so you can get the thing working first.
| | Where it runs | Who can reach it | Your mail is stored on |
|---|---|---|---|
| **1** | your machine | that machine only | your machine |
| **2** | your machine | you, from anywhere | your machine |
| **3** | a VPS | you, from anywhere | a rented disk |
The server ships as a container image at
`ghcr.io/wildsurfer/your-mail-mcp`, built and published by CI for amd64 and
arm64. Nothing needs compiling, and every case starts the same way — two
files in an empty directory:
```bash
mkdir your-mail && cd your-mail
curl -fsSLO https://raw.githubusercontent.com/wildsurfer/your-mail-mcp/main/compose.yaml
curl -fsSL https://raw.githubusercontent.com/wildsurfer/your-mail-mcp/main/accounts.example.json -o accounts.json
```
Edit `accounts.json` with your accounts (see
[The accounts file](#the-accounts-file)), then put the secrets it references
in a `.env` file next to `compose.yaml`:
```bash
# .env
OAUTH_PASSPHRASE=pick-a-long-one-you-can-type-on-a-smartphone
WORK_PASS=your-gmail-app-password
PERSONAL_PASS=your-icloud-app-specific-password
```
`OAUTH_PASSPHRASE` is the only credential between the internet and your mail
in cases 2 and 3. Treat it accordingly.
These two files hold your mail passwords. If you ever put this directory
under version control or into a backup that leaves the machine, treat them
accordingly.
---
### Case 1 — on your machine, for your machine only
The server binds to loopback. Nothing outside your machine can reach it, so
there is no TLS to arrange and no hostname to own. Your CLI tools can use it.
Your smartphone cannot.
Add one line to `.env`:
```bash
PUBLIC_URL=http://127.0.0.1:8080
```
Then start it:
```bash
docker compose up -d
docker compose logs -f # watch the first sync
```
The first sync populates the maildir and takes a while on a large mailbox. It
is slower than it could be on purpose, one IMAP command at a time, because
providers throttle. There is no separate initialization step.
**Claude Code**
```bash
claude mcp add --transport http your-mail http://127.0.0.1:8080/mcp
```
Then run `/mcp` inside Claude Code, pick `your-mail`, and authenticate. A
browser opens the consent page, which asks for one thing: your
`OAUTH_PASSPHRASE`. Until you do this, `claude mcp list` shows
`Needs authentication`.
**Codex**
```bash
codex mcp add your-mail --url http://127.0.0.1:8080/mcp
codex mcp login your-mail
```
`codex mcp list` shows the auth status. If the tools still do not appear in a
session after a successful login, that is a known Codex bug where the OAuth
credentials are obtained and then never used
([openai/codex#20009](https://github.com/openai/codex/issues/20009)). Use the
bridge below until it is fixed.
<details>
<summary>Fallback for any client whose OAuth support is broken</summary>
`mcp-remote` does the OAuth dance itself and re-exposes the server over
stdio, which every MCP client supports:
```toml
# ~/.codex/config.toml
[mcp_servers.your-mail]
command = "npx"
args = ["-y", "mcp-remote", "http://127.0.0.1:8080/mcp"]
```
It opens the same consent page on first run and caches the tokens.
</details>
---
### Case 2 — on your machine, reachable from anywhere
Same server, plus something that gives it a public HTTPS address. Your mail
stays on your machine, and nothing listens on your home network, because the
tunnel dials out. You need this for the smartphone and desktop apps: a custom
connector is fetched by the vendor's servers, so it cannot reach a private
address.
#### With Tailscale (no domain needed)
One command, same on macOS and Linux, and you get an HTTPS hostname without
owning a domain.
```bash
tailscale funnel --bg 8080
```
`--bg` keeps it running across reboots. It prints the public URL, which looks
like `https://your-machine.your-tailnet.ts.net`. That is the hostname to use:
```bash
# .env
PUBLIC_URL=https://your-machine.your-tailnet.ts.net
```
```bash
docker compose up -d
```
Funnel needs HTTPS certificates and the Funnel node attribute enabled for
your tailnet; the CLI offers to add the policy line the first time, and the
rest is in your admin console. `tailscale funnel status` shows what is
exposed, and `tailscale funnel --https=443 off` takes it down.
#### With Cloudflare (you own a domain, and it is on Cloudflare)
Use this if you want a hostname on your own domain rather than a `.ts.net`
one. `mail.example.com` below is **your** domain, already added to your
Cloudflare account — Cloudflare does not hand you a hostname for a named
tunnel.
```baLo que la gente pregunta sobre your-mail-mcp
¿Qué es wildsurfer/your-mail-mcp?
+
wildsurfer/your-mail-mcp es mcp servers para el ecosistema de Claude AI. Self-hosted, read-only MCP server that serves IMAP mail from a local notmuch index over authenticated HTTP Tiene 1 estrellas en GitHub y su última actualización registrada es del 2026-08-26.
¿Cómo se instala your-mail-mcp?
+
Puedes instalar your-mail-mcp clonando el repositorio (https://github.com/wildsurfer/your-mail-mcp) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.
¿Es seguro usar wildsurfer/your-mail-mcp?
+
Nuestro agente de seguridad ha analizado wildsurfer/your-mail-mcp y le ha asignado un Trust Score de 79/100 (tier: Trusted). Revisa el desglose completo de comprobaciones superadas y flags en esta página.
¿Quién mantiene wildsurfer/your-mail-mcp?
+
wildsurfer/your-mail-mcp es mantenido por wildsurfer. La última actividad registrada en GitHub es del 2026-08-26, con 0 issues abiertos.
¿Hay alternativas a your-mail-mcp?
+
Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.
Despliega your-mail-mcp en tu cloud
Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.
¿Mantienes este repo? Añade un badge a tu README
Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.
[](https://claudewave.com/repo/wildsurfer-your-mail-mcp)<a href="https://claudewave.com/repo/wildsurfer-your-mail-mcp"><img src="https://claudewave.com/api/badge/wildsurfer-your-mail-mcp" alt="Featured on ClaudeWave: wildsurfer/your-mail-mcp" width="320" height="64" /></a>Más MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
The fastest path to AI-powered full stack observability, even for lean teams.
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!