Install
$ agentstack add mcp-chandshy-mailpouch ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
mailpouch
mailpouch is an MCP server that gives AI agents a typed, permission-gated, audit-logged tool surface over private-mail providers — Proton Mail (via Proton Bridge) and plain IMAP.
The pitch in one line: if you picked Proton Mail because you didn't want a third party reading your inbox, you don't suddenly want to hand a chatbot OAuth access to that same inbox so it can triage on your behalf. The usual "connect your email" integrations route everything through someone else's servers and ask for blanket scopes. Hand-rolled IMAP inside the agent is worse — no permission boundary, no audit trail, and the model holds your credentials in its context window. Neither option respects why you chose the provider in the first place.
mailpouch runs locally and speaks to Proton Bridge over a TLS socket on your own machine; nothing leaves the box unless you asked it to. 76 tools across reading, sending, drafts, folders, search, analytics, aliases, Proton Pass, and system control, tiered into core / extended / complete so an agent that only reads doesn't burn context on Bridge lifecycle tools it will never call. Every connecting client gets its own grant with folder allowlists, IP pins, per-tool rate caps, expiry, and account binding — all hashed-args in the audit log, never the values. Delete, trash, spam, and alias removal round-trip through MCP elicitation for human confirmation before they execute. That last part sounds like theatre until you watch an agent try to empty a folder and get blocked mid-call.
It is real because the primitives are real: OAuth 2.1 with PKCE S256, RFC 7591 dynamic client registration, RFC 8707 resource indicators, RFC 9728 protected-resource metadata, and an OAuth client_credentials grant so headless agents authenticate too — every agent gets its own gated, revocable identity. Credentials live in the OS keychain. A local FTS5 index with BM25 ranking handles phrase, boolean, prefix, and column-filter queries so your search terms never leave your laptop. Desktop notifications use native osascript / notify-send / powershell.exe with no added dependency; webhook dispatch auto-detects CloudEvents 1.0, Slack, or Discord, signs with HMAC, and retries with eight-attempt exponential backoff. So how do you point it at your Bridge install and wire up a client?
[](https://github.com/chandshy/mailpouch/actions/workflows/ci.yml) [](https://www.npmjs.com/package/mailpouch) [](https://opensource.org/licenses/MIT) [](https://nodejs.org/) [](https://www.typescriptlang.org/) [](https://github.com/modelcontextprotocol/sdk) [](#development)
Read, compose, and manage your encrypted Proton Mail inbox from any AI assistant — over stdio or remote HTTP — with human-controlled permissions.
⚠ Proton Terms of Service Notice
This is an unofficial third-party tool that connects to Proton Mail through Proton Bridge's local IMAP/SMTP surface. It is not affiliated with, endorsed by, or authored by Proton AG.
Proton's Terms of Service (proton.me/legal/terms) §2.10 prohibits "accessing the Services through automated means (including but not limited to bots, scripts, or similar technologies)". The textual reading covers agentic / scripted workloads against Bridge even though Bridge itself is a sanctioned surface.
This server is designed to keep access user-initiated, not autonomous:
- Default permission preset is
read_only. Sending, deletion, and folder mutation require explicit user opt-in via the settings UI. - Destructive tools (delete / empty_trash / move-to-trash / move-to-spam /
alias_delete/pass_get) require explicit confirmation. With MCP elicitation-capable clients, the server prompts the user out-of-band before executing; non-elicitation clients must pass{ confirmed: true }. - Elevated permissions require out-of-band human approval (settings UI button or terminal), not an agent-only grant.
- The settings UI shows a first-run ToS acknowledgement the user must click through before credentials are accepted.
You remain the operator of your Proton account. Running this server against your own account is your decision to make under Proton's ToS; the authors disclaim responsibility for ToS compliance on your behalf.
What It Does
Proton Mail encrypts your email end-to-end, which means no third-party API can read it. Proton Bridge solves this by decrypting email locally. This MCP server connects to Bridge and gives Claude (or any MCP host) structured, permission-gated access to your inbox.
Your emails are decrypted on your own machine by Proton Bridge. This server never persists email content — everything stays in memory and is cleared on restart. You control exactly what the AI can do through a preset permission system with human-gated escalation for anything sensitive.
Quick Start (zero to running)
Prereq: Proton Bridge installed, running, and signed in.
- Add the MCP server to your client. This one form works whether or not mailpouch is globally installed:
``json { "mcpServers": { "mailpouch": { "command": "npx", "args": ["-y", "mailpouch"] } } } ``
- Configure Bridge credentials — either path writes
~/.mailpouch.json(+ OS keychain):
- Interactive wizard:
npx -y mailpouch-settings - Non-interactive (scriptable / agent-driven):
npx -y mailpouch setup --username you@proton.me --password-stdin
(paste the Proton Bridge password — Bridge → Settings → IMAP/SMTP → Password — not your Proton login password)
- Verify:
npx -y mailpouch doctor— prints the exact next step until it reportsready. (Agents can call the always-availablesetup_statustool for the same diagnosis.)
- Approve the agent. On first connect, every client is gated behind a one-time human Approve/Deny — open the settings UI (
http://localhost:8766/#/agents) and click Approve. This is expected, not an error.
That's it. The sections below cover everything in depth.
Key Features
- 76 tools — 73 categorized across 11 categories (reading, search, analytics, sending, drafts, scheduling, follow-up reminders, folder management, bulk actions, deletion, Bridge/server lifecycle, plus optional companion services: SimpleLogin aliases, Proton Pass, local FTS5 search), plus 3 always-available meta-tools (
setup_status,request_permission_escalation,check_escalation_status). See [src/config/schema.ts](src/config/schema.ts) (ALL_TOOLS,TOOL_CATEGORIES,ALWAYS_AVAILABLE_TOOLS) for the canonical inventory. - Two transports — stdio (default, Claude Desktop) and HTTP (remote / self-host). HTTP is OAuth-only:
authorization_code+ PKCE-S256 for interactive agents andclient_credentialsfor headless service accounts, with RFC 7591 Dynamic Client Registration, RFC 8414 authorization-server metadata, and RFC 9728 protected-resource metadata. Per-caller token-bucket rate limiting on every endpoint. - Progressive tool tiering —
core/extended/completecontrols how many tools land in the client'sListToolsresponse, so context isn't burned on tools you don't use. Configurable viatoolTierorMAILPOUCH_TIER. - Destructive-tool confirmation — uses MCP elicitation when the client supports it (Claude Desktop, Cline) so the user sees a prompt before any delete / trash / spam /
alias_delete/pass_getruns. Falls back to a required{ confirmed: true }argument for clients without elicitation. - 5 permission presets — read-only by default; write access requires explicit opt-in. Per-tool overrides and rate limits via the Custom preset.
- Human-gated escalation — agents request elevated permissions, you approve via browser UI or terminal; the agent cannot approve its own requests.
- Browser-based settings UI at
localhost:8766— auto-starts with the daemon; setup wizard, live connection test, per-tool toggles, escalation approval panel, per-agent Approve/Deny. - Native system tray icon — always visible, clickable menu opens the settings UI or quits. Rendered via a bundled Rust (napi-rs) binding around the
tauri-apps/tray-iconcrate — the same one Tauri ships in production — so the tray behaves correctly on modern GNOME (where the legacy Go-binary library shows a generic placeholder), NSStatusBar on macOS, and Shell_NotifyIcon on Windows. Prebuilts for linux-x64/arm64, darwin-arm64, win32-x64/arm64 ship inside the main package; darwin-x64 (Intel Mac) falls back to the legacy Go backend cleanly. - 6 MCP prompts — triage inbox, compose reply, daily briefing, find subscriptions, thread summary, draft in my voice.
- MCP Resources — individual emails and folders addressable via
email://andfolder://URIs. - Scheduled email delivery — queue emails for future sending; survives server restarts. Plus
remind_if_no_replyfor outbound follow-ups gated on inbox replies. - Optional companion services — SimpleLogin alias management (6 tools, requires API key), Proton Pass via pass-cli (3 tools, requires PAT), local FTS5 full-text index (3 tools, requires
better-sqlite3). - TLS-strict by default — refuses to connect to localhost Bridge without a pinned cert, requires Bridge ≥
3.22.0, exponential backoff on SMTP abuse-signal responses. - Multi-account — configure more than one Proton / IMAP account; hot-swap the active account from the Settings UI with no server restart. Tools accept an optional
account_idargument to route a single call to a specific account. See [src/accounts/](src/accounts/). - Per-agent grants — each MCP client (identified by its OAuth
client_id) is gated by its own approvable grant, with optional folder allowlists, IP pins, per-tool rate caps, expiry, and account binding. Separate from the global preset and the escalation flow. See [src/agents/](src/agents/). - Live notifications — desktop toasts (no extra deps) and outbound webhooks (CloudEvents / Slack / Discord, HMAC-signed, retried) fire on grant-state changes. See [
src/notifications/](src/notifications/). - 2,205 tests passing (Vitest); minimal
anyusage in production source (private Node.js readline internals only).
Documentation: [HELP.md](HELP.md) (task-oriented how-tos) · [READMEFIRSTAI.md](READMEFIRSTAI.md) (agent API reference) · [docs/index.md](docs/index.md) (full index)
Quick Start
Ask Claude things like:
"Summarize everything from my boss this week"
"Find emails about my Acme invoice and draft a reply"
"Move all order confirmations to my Shopping folder"
"What's my average email response time this month?"
"Schedule a follow-up email to alice@example.com for next Monday at 9am"
"Remind me if there's no reply within 3 business days"
With read-only permissions (the default), Claude can read, search, and analyse your inbox but cannot send, move, delete, or change anything.
Prerequisites
| Requirement | Version | Notes | |---|---|---| | Node.js | >= 20.0.0 | Check with node --version · nodejs.org | | npm | >= 9.0.0 | Bundled with Node.js | | Proton Bridge | >= 3.22.0 | Must be running and signed in · proton.me/mail/bridge | | Proton Mail account | Paid plan | Bridge requires a paid Proton plan (Mail Plus, Unlimited, etc.) | | MCP client | Latest | Claude Desktop, Cline, or any MCP-compatible host · claude.ai/download |
Supported on macOS, Windows, and Linux.
Linux runtime libraries
The native tray binding dynamically links against two GTK system libraries that are preinstalled on every modern desktop Linux distribution (Ubuntu ≥ 18.04, Fedora ≥ 34, Mint, Pop!_OS, Arch, etc.). No manual install is needed on a normal desktop system — just a note for server / container / minimal-WM deployments:
| Runtime library | Package name | |---|---| | libgtk-3.so.0 | libgtk-3-0 (Debian/Ubuntu) · gtk3 (Fedora/Arch) | | libayatana-appindicator3.so.1 | libayatana-appindicator3-1 (Debian/Ubuntu) · libayatana-appindicator-gtk3 (Fedora) |
If both are missing (headless server, container, SSH-only host), mailpouch's tray startup logs a skip reason and continues without the icon — the MCP server itself runs unaffected. macOS and Windows ship their native equivalents as part of the OS.
Proton Bridge ports
Bridge listens locally on:
| Protocol | Host | Port | |---|---|---| | SMTP (sending) | 127.0.0.1 | 1025 | | IMAP (reading) | 127.0.0.1 | 1143 |
> Use 127.0.0.1, not localhost. On some systems localhost resolves to ::1 (IPv6), which Bridge does not listen on.
Installation
Option A — npm (recommended)
npm install -g mailpouch
Or skip the install entirely — npx -y mailpouch runs the latest published version on demand, which is exactly what the canonical MCP client config below uses.
Option B — From source
git clone https://github.com/chandshy/mailpouch.git
cd mailpouch
npm install
npm run build
Optional companions
Install only if you plan to use the corresponding tool group:
| Optional dep | Enables | Install | |---|---|---| | better-sqlite3 | fts_search / fts_rebuild / fts_status (local FTS5 index) | npm install better-sqlite3 | | pass-cli (Proton's Go CLI) | pass_list / pass_search / pass_get | See pass-cli; set a Pass PAT in the settings UI | | SimpleLogin API key | alias_* tools | Generate at app.simplelogin.io; paste in settings UI |
Tools in unconfigured groups return a clean configuration error rather than failing silently.
Setup Wizard
Run the settings server to complete first-time setup:
npx -y mailpouch-settings
# Then open http://localhost:8766
The 6-step wizard walks you through everything automatically:
- Welcome — overview, ToS acknowledgement, and prerequisites checklist
- Bridge health check — live TCP test to ports 1025 and 1143; blocks progress until Bridge is reachable
- Account — your Proton Mail address and Bridge password (Bridge app → Settings → IMAP/SMTP → Password — this is not your Proton login password)
- Permission preset — choose what the AI is allowed to do (see table below)
- Review — confirm your settings before saving
- Done — displays the exact JSON snippet to paste into your MCP client config; optionally writes it for you automatically
Settings are saved to ~/.mailpouch.json with mode 0600 (owner read/write only). The Bridge password and SMTP token prefer the OS keychain when available.
Non-interactive setup (agents / CI)
When a browser/TUI wizard isn't an option, configure credentials from the command line — it writes the same ~/.mailpouch.json (+ keychain) the wizard does:
# password from stdin (keeps the secret out of the process list)
printf '%s' "$BRIDGE_PASSWORD" | npx -y mailpouch setup --username you@proton.me --password-stdin
# or from a file, or inline; optional non-default ports / cert
npx -y mailpouch setup --username you@proton.me --password-file ./bridge.pw \
[--imap-host 127.0.0.1 --imap-port 1143 --smtp-host 127.0.0.1 --smtp-port 1025] \
[--bridge-cert /path/cert.pem | --insecure]
Then check the install end-to-end:
npx -y mailpouch doctor # human-readable diagnosis + next step; exit 0 when ready
npx -y mailpouch doctor --json # structured output for scripts
npx -y mailpouch status # is it running? ports, connection, approved agents (read-only)
npx -y mailpouch --help # all commands + flags + the config/log paths
doctor reports the same state machine the always-available setup_status MCP tool returns: unconfigured → bridge-unreachable → pending-approval → ready, each with the exact action t
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: chandshy
- Source: chandshy/mailpouch
- License: MIT
- Homepage: https://www.npmjs.com/package/mailpouch
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.