Skip to main content
Glama
jacoblazdade

tuta-cowork-bridge

by jacoblazdade

tuta-cowork-bridge

Self-hosted MCP bridge connecting Tuta Mail to Claude Cowork and other remote MCP clients — read-only by default, with opt-in tools for cleaning up and sending mail.

Unofficial — use at your own risk. This project is not affiliated with or endorsed by Tuta GmbH or Anthropic. Tuta has no public API; this bridge relies on the community reverse-engineered client in tutaproxy, which can break when Tuta changes its protocol. Using an unofficial client may conflict with Tuta's terms of service — see Terms of service before connecting your account.

Out of the box Claude can list, search and read your mail, follow threads and draft replies in the conversation; nothing can be modified. If you opt in (TCB_WRITE_TOOLS), Claude can also move, trash/restore, mark and label mail, create/rename folders and send mail to an allowlist of recipients — see Write tools. Permanent deletion is never available. Tools that are not enabled do not exist in the server, and calls to them are rejected at the HTTP boundary.

Claude Cowork (Anthropic cloud)
      │ HTTPS + X-API-Key
      ▼
Tailscale Funnel (public HTTPS, TLS terminated by tailscaled)
      │ http://127.0.0.1:8080/mcp
      ▼
tuta-cowork-bridge ── API-key guard ── 7 read-only MCP tools
      │
      ▼
tutaproxy TutaClient (pinned submodule) ──► Tuta servers

See ARCHITECTURE.md for the design and SECURITY.md for the threat model.

Tools

Tool

What it does

list_folders

Folders and labels (id, name, type)

list_emails

Newest emails in a folder, metadata only; unread_only, cursor paging

search_emails

Bounded newest-first scan of one folder: sender, recipient, correspondent, subject, date range, unread, attachments, optional body text (≤ 25 bodies per call)

read_email

Headers, full recipient lists, attachment names, plain-text body (≤ 50 000 chars)

get_email_metadata

Same without the body

get_thread

The conversation an email belongs to, optionally with bodies

connector_status

Version, read-only flag, enabled write groups, Tuta session state

Reading an email does not mark it as read. Custom folders and labels work everywhere a folder is accepted, by name or folder_id (e.g. search_emails(folder="Freelance", sender="…")).

Write tools (opt-in)

Enable groups with TCB_WRITE_TOOLS in your private bridge.env, then scripts/install-service.sh:

Group

Tools

Notes

organize

move_emails, trash_emails, restore_emails, mark_emails

"Delete" = Trash. restore_emails returns mail to the folder it was trashed from. Move targets: inbox, archive, spam, custom folders.

folders

create_folder, rename_folder, label_emails

Custom folders only; no folder deletion. Labels must already exist.

send

send_email

Plain-text mail from your address. Every recipient must match TCB_SEND_ALLOWLIST (default me = only yourself; also name@domain, @domain, or *). No BCC, no attachments, max 10 recipients. Sent as a new message (not threaded).

Server-side guardrails regardless of the client: ≤ 50 emails per call, daily caps (TCB_DAILY_WRITE_LIMIT modified emails, TCB_DAILY_SEND_LIMIT sends), no automatic retry for sends, and a private audit log (TCB_AUDIT_FILE, JSON lines, ids/actions/recipient domains only — never subjects, bodies or addresses) that also powers undo and the caps. Write tools carry readOnlyHint=false (and destructiveHint=true for trash/send) so clients can ask before running them. Inbox rules are not supported (Tuta's rule storage is not implemented by the client library); create rules in the Tuta app — Claude can propose them and sort existing mail with move_emails.

Related MCP server: gmail-mcp-imap

Requirements

  • macOS (Apple Silicon or Intel) with a user that stays logged in, or Linux / a container (see Other deployments)

  • uv, git, Python 3.12–3.13 (uv installs it if needed)

  • Tailscale with HTTPS certificates and Funnel enabled for the machine (for Claude Cowork / claude.ai), or any other TLS reverse proxy you trust

  • A Tuta account. With 2FA, add a separate Authenticator (TOTP) factor for the bridge (passkeys/security keys cannot be used unattended)

Install (macOS + Tailscale Funnel)

git clone --recurse-submodules https://github.com/jacoblazdade/tuta-cowork-bridge.git
cd tuta-cowork-bridge
scripts/setup.sh            # deps, settings, credentials into the Keychain, API key
scripts/live-check.sh       # one Tuta login, prints counts only
scripts/install-service.sh  # launchd agent, loopback listener on 127.0.0.1:8080

setup.sh asks for your Tuta email, password and (optionally) a TOTP seed at security's hidden prompt; values go straight into your login Keychain (service tuta-cowork-bridge). If you add a new TOTP factor in Tuta, confirm it with the code from scripts/totp-code.sh.

Publish through Funnel. If another service already uses / on port 443, mount the bridge under a prefix — Tailscale strips it before proxying:

scripts/funnel.sh on --path /tuta     # → https://<machine>.<tailnet>.ts.net/tuta/mcp
scripts/external-check.sh https://<machine>.<tailnet>.ts.net/tuta/mcp

funnel.sh off --path /tuta removes only the bridge's route. Do not use tailscale funnel --https=443 off: it removes every route on that port.

Retrieve the API key

Copy it to the clipboard without displaying it, paste it where needed, then clear the clipboard:

security find-generic-password -s tuta-cowork-bridge -a TCB_API_KEY -w | pbcopy
pbcopy < /dev/null

Connect Claude Cowork / claude.ai

  1. Claude → Customize → Connectors → + Add → Add custom connector (Team/Enterprise: an owner adds it under Organization settings → Connectors).

  2. Name: Tuta Mail (Self-Hosted); URL: https://<machine>.<tailnet>.ts.net/tuta/mcp.

  3. Authentication: no OAuth / no sign-in. Add a request header X-API-Key with the key.

  4. Enable the connector in a Cowork session (connector/tools menu) and ask e.g. "Show me my latest 10 emails."

Connections come from Anthropic's cloud, so the URL must be publicly reachable — a tailnet-only tailscale serve URL is not enough.

Connect Claude Code (same machine)

Uses the running service over loopback; the key is fetched from the Keychain at connect time by a headersHelper, so it is never written to Claude Code's config:

claude mcp add-json --scope user tuta-mail \
  "{\"type\":\"http\",\"url\":\"http://127.0.0.1:8080/mcp\",\"headersHelper\":\"$PWD/scripts/claude-code-headers.sh\"}"
claude mcp get tuta-mail

For a client without header support, tuta-cowork-bridge stdio serves the same tools over stdio (it logs in to Tuta separately).

Operating

Task

Command

Health (launchd, listener, authenticated probe, Funnel routes)

scripts/status.sh

Start / stop / restart

scripts/start.sh · scripts/stop.sh · scripts/restart.sh

Logs (redacted, no mail content)

scripts/logs.sh [lines] · scripts/logs.sh -f

Public endpoint check

scripts/external-check.sh <url>

Rotate the API key

scripts/setup.sh --rotate-key && scripts/restart.sh, then update clients

Re-enter Tuta credentials

scripts/setup.sh --credentials && scripts/restart.sh

Tests (synthetic data only)

scripts/test.sh

Uninstall the service

scripts/install-service.sh --remove

Review write actions

tail ~/Library/Application\ Support/tuta-cowork-bridge/audit.jsonl

To run a second instance on the same machine (e.g. a test checkout), give it its own TCB_LABEL, TCB_PORT, TCB_CONFIG_DIR and TCB_KEYCHAIN_SERVICE.

Private state lives outside the repository: settings in ~/Library/Application Support/tuta-cowork-bridge/bridge.env, logs in ~/Library/Logs/tuta-cowork-bridge/, the agent in ~/Library/LaunchAgents/io.github.tuta-cowork-bridge.plist, secrets in the Keychain.

Configuration

All settings are TCB_* environment variables; see .env.example. Highlights: TCB_HOST/TCB_PORT/TCB_MCP_PATH (listener, loopback enforced), TCB_PUBLIC_HOSTS (Host-header allowlist), TCB_CREDENTIAL_BACKEND (keychain or file), TCB_RATE_PER_MINUTE, TCB_TOOL_TIMEOUT, TCB_SOURCE_URL (source link shown by connector_status; keep it pointing at the code you run — AGPL §13).

Other deployments

The application only needs a loopback (or container-internal) listener and an HTTPS proxy that forwards the X-API-Key header:

  • Linux / systemd: TCB_CREDENTIAL_BACKEND=file with TCB_CREDENTIALS_FILE pointing to a chmod 600 file outside the repo (TUTA_EMAIL, TUTA_PASSWORD, TUTA_TOTP_SECRET, TCB_API_KEY), run tuta-cowork-bridge serve, front it with Tailscale Funnel, Caddy, etc.

  • Container: mount the credentials file read-only, set TCB_HOST=0.0.0.0 and TCB_ALLOW_NON_LOOPBACK=1, and publish the port on 127.0.0.1 only.

Limitations

  • Unofficial protocol. Tuta can reject the pinned client version (HTTP 474) or change its model; updating means moving the tutaproxy submodule to a newer reviewed release.

  • No server-side search. Tuta's search index lives in its clients. search_emails scans one folder newest-first (default 300, max 2000 messages per call, continue with next_cursor). Body search fetches at most 25 bodies per call. No full-text index is built.

  • recipient matches the first recipient only (full lists come from read_email).

  • Attachments: names and types only; contents are never downloaded.

  • Threads list up to 100 conversation entries.

  • After a macOS reboot with FileVault, nothing runs until the user logs in (the login Keychain and the per-user launchd agent need the session). Tailscale's GUI app has the same requirement.

  • kill -9/power loss skips the Tuta logout; that session expires server-side.

  • One Tuta session per bridge process; the API key is read at startup (restart after rotation).

  • Write tools: no inbox rules, no folder deletion, no permanent deletion, no drafts, no attachments; send_email does not thread replies into the original conversation.

Terms of service

Read Tuta's terms yourself; this is not legal advice. Points relevant to this project (as of October 2026):

  • Reverse engineering (§ 12): the licence excludes reverse engineering unless permitted by law or contract. This bridge does not reverse-engineer anything itself, but depends on tutaproxy, which does (Tuta's own clients are open source; EU law permits some reverse engineering for interoperability). Tuta may block service for terms violations (§ 11.1).

  • Sending limits (§ 7.2–7.4): no more than 100 emails per hour, no bulk mailings, no mail to recipients without consent. The send group defaults to 20 sends/day and your own address only; keep any changes well within these limits.

You are responsible for how you use this software with your account.

Acknowledgements and licence

Built on tutaproxy (Tuta API client and crypto) and TutaMCP (mail decryption helpers) by peix2, both AGPL-3.0-or-later, used unmodified as pinned git submodules. Neither project's MCP tools are registered. Generic improvements are intended to go upstream.

Licensed under AGPL-3.0-or-later (LICENSE), matching upstream. If you run a modified version for others over a network, you must offer them its source (set TCB_SOURCE_URL). The software comes with no warranty (LICENSE §§ 15–16).

Tuta and Tutanota are trademarks of Tuta GmbH. Claude and Claude Cowork are trademarks of Anthropic PBC. Tailscale is a trademark of Tailscale Inc. Names are used only to describe compatibility.

Related MCP Connectors

  • Hosted email MCP for your own Gmail, Outlook.com, Microsoft 365, iCloud or IMAP inbox: read, search, draft, reply in thread, forward and file mail. It moves or flags up to 500 messages in one call, and a send leaves exactly one copy in Sent. A calendar is a separate connection, and connecting one adds diary and scheduling tools.

  • Your own IMAP mailbox in any MCP client: search, read, flag, move; send and delete need confirm.

  • Your agent needs a mailbox of its own — to receive, thread, draft and send, with attachments, without borrowing your personal inbox or your company's SMTP. **What you can ask for** • "Create an inbox for this agent and tell me its address." • "Read the new messages in this thread and draft a reply." • "Send this message with the attachment and wait for the response." • "Search this inbox for everything from that domain." • "Show delivery metrics and the events on this inbox." **How to use it** Point any MCP client at https://mcp.aisa.one/mail/mcp and sign in with OAuth — there is no key to create or paste. 49 tools: create and delete inboxes, list and read messages, raw message bodies, attachments, threads, drafts and draft attachments, send and reply, message search, inbox events, metrics, and list entries — reads and writes. **Why this rather than the source** A real inbox an agent owns, rather than an SMTP credential it borrows from a human. **It is also a door to the rest** The same login reaches 26 sources and 580+ operations. Find the contact elsewhere in the catalogue, then write to them from here — without adding a second server. **What it costs** Finding and inspecting an operation is free. Running one is billed per call at API prices, with no seat and no monthly minimum, and every call takes max_price_usd so an agent cannot overspend by accident. **Where else it reaches** https://mcp.aisa.one/sales/mcp finds the person to write to.

  • Your mailbox for MCP clients: search, read, draft, send, rules and notes. Sending is off by default.

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server giving Claude access to Tuta mail, calendar, contacts and drive. Supports mail modes (dedicated/shared/folder), trusted sender filtering with E2E verification, and Docker-based setup.
    AGPL 3.0
  • A
    license
    B
    quality
    C
    maintenance
    Enables email management through IMAP/SMTP, including reading, sending, replying, starring, deleting, labeling emails, handling attachments, and filtering by Gmail smart categories. Works with MCP-compatible clients like Claude Desktop and Claude Code using App Password authentication.
    19
    70 npm
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables Claude and other MCP clients to search, read, write and organise mail on Stalwart servers over JMAP — including folders, Sieve filters, out-of-office replies and one-click unsubscribe — with draft-first and confirmation safeguards against prompt injection. A separate admin endpoint additionally exposes account, domain, mailing-list, queue, IP, log and task management through Stalwart's JMAP management API.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables Claude to search and read multiple Gmail or Google Workspace mail accounts at once through a local, read-only MCP server, with every result labeled by the account it came from. Tokens stay in the OS keychain, no server is run by the authors, and write actions such as sending, deleting, or archiving are not supported.
    94 npm
    1
    AGPL 3.0