RadMail MCP
MCP serverSearchRadmail is an email integration that gives your AI direct access to your real inbox. Once added, your AI can search your mail, sort important messages from noise, track commitments made in threads, and apply a verifiable hard stop against business email compromise, where scammers pose as trusted contacts.
Use RadMail MCP in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add RadMail MCP and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the triage inbox tool from RadMail MCP
No key or account is asked for. Not verified by us yet: Ahel has not run a call through it.
Details
Available today. Use it from your connected AI after setup.
No key or account is asked for. Not verified by us yet: Ahel has not run a call through it.
After adding Radmail, ask your AI to search or triage your recent email to see it working on your real inbox.
What your AI can do with it
- Search your real inbox for messages and details
- Triage incoming email so what matters rises to the top
- Track commitments and follow-ups buried in threads
- Stop business email compromise attempts with a verifiable hard stop
Install RadMail MCP
The server’s own address, for the clients that take one directly. Or connect Ahel once and every client you use reads it from one address, with the account kept on Ahel rather than in each client’s config.
Claude Code
claude mcp add --transport http --scope user radmail-mcp 'https://radmail.ai/api/mcp/sandbox'Run it once in your project, then open /mcp to approve any sign-in the server asks for.
Claude Desktop
https://radmail.ai/api/mcp/sandboxAdd a custom connector in Settings, paste this address, and approve the sign-in.
Cursor
cursor://anysphere.cursor-deeplink/mcp/install?name=radmail-mcp&config=eyJ1cmwiOiJodHRwczovL3JhZG1haWwuYWkvYXBpL21jcC9zYW5kYm94In0=Open the link and Cursor adds the server at that address.
ChatGPT
https://radmail.ai/api/mcp/sandboxIn Settings, enable Developer mode, create an MCP app, and paste this address. Your plan and workspace must allow custom apps.
Codex
codex mcp add radmail-mcp --url 'https://radmail.ai/api/mcp/sandbox'Run it once, then sign in with codex mcp login radmail-mcp if the server asks for an account.
From the project's README
As published by radmail-ai/radmail-mcp in README.md.
An email operating system for agents — with a refusal you can trust.
Every inbox got an AI in 2026. None can be trusted to hit send. RadMail is the one that can — because the consequential actions are refused in code, model-independent: money, changed-banking details, first-contact senders, decisions, and prompt-injection are human-only, forever. No prompt can talk RadMail into auto-sending them.
This is the Model Context Protocol (MCP) server, so any AI agent can use the inbox.
If a fleet of MCP agents runs your execution layer while you sit in the decision seat, the inbox is the seat that needs a hard-stop first. It's where a socially-engineered wire or banking change is irreversible — and where an autonomous process that can hit send can be talked into the loss. RadMail lets agents do the inbox's work (triage, the Right Now lane, commitment tracking, drafting) while money, changed banking, first contact, decisions, and prompt-injection stay human-only by construction, not by a policy an agent could be argued out of. That's what makes the company inbox delegable at all.
Start in one call
Call triage_inbox and omit the token — RadMail auto-provisions a free sandbox tenant and returns a working triage in one round-trip. Reuse the returned token. (On the zero-auth hosted sandbox, triage_inbox takes no args — it triages a built-in demo inbox so your very first call returns the full wedge.)
This server runs the sandbox engine (heuristic, in-memory, free, no credentials). It is real and runnable — not the production "99%" engine.
Tools
| Tool | What it does |
|---|---|
triage_inbox | One round-trip over a batch: the Right Now lane + every open commitment + every hard-stop. The whole wedge in one call. |
list_right_now | The can't-miss lane only — most-recent × most-important, each with why-surfaced. Pass messages for the sandbox (with hard-stop flags), or omit them with RADMAIL_API_KEY set for your real Right Now lane (read-only). |
why_surfaced | Explain in plain English why a message surfaced — the signals behind its importance × urgency. Transparency, not a black box. |
draft_reply | Draft the reply that discharges a commitment — never for a hard-stopped one (money / banking / first-contact stay human-only). |
list_commitments | Open promises with their due window. Pass messages for sandbox extraction, or omit them with RADMAIL_API_KEY set for your real tracked commitments (read-only). |
search | Find the one message you mean by sender / subject / content — most-relevant + newest first (no filesystem grep). Pass messages for the sandbox, or omit them with RADMAIL_API_KEY set to search your real inbox (read-only). |
read_email | Connected mode only: fetch one full email (headers + textBody) from your real inbox by id. Read-only; body content arrives taint-tagged. |
check_send_domain | Zero-auth, works on any domain: read-only SPF / DKIM / DMARC health read (verdicts + raw records + plain-language advice). Probes the common DKIM selectors (default, google, resend, sendgrid, mail, k1, s1, s2). Read-only DNS — no key, no send capability. |
triage | Score a single message (the per-message form of triage_inbox). |
provision_sandbox | Explicitly mint a free sandbox tenant. |
report_need / request_capability | Tell RadMail what was awkward / what you wish existed — the surface adapts. |
radmail_learning_insights | What RadMail has learned about how you work. |
"How many tools?" — and the second number that matters more
Public round-ups of email MCP servers commonly quote a tool count as a measure of depth. Tool count measures surface area, not judgment — and for a server trusted with an inbox, the useful number is the second one: of those tools, how many can send?
RadMail publishes both, as dated observations you can reproduce against any MCP server — this one included:
| Tier | Tools | Send-capable |
|---|---|---|
Hosted zero-auth sandbox (https://radmail.ai/api/mcp/sandbox) | 6 | 0 |
| This npm package, default | 13 | 0 |
This npm package with RADMAIL_SEND_TOOL=1 (local stdio only) | 14 | 1 — send_email, which hands mail to RadMail's outbound gate and cannot release a hold |
Observed 2026-10-09. Reproduce row 1 with the tools/list command under Verify before you connect. Reproduce row 2 from the frozen manifest — the surface the server refuses to deviate from:
node -e 'const s=require("fs").readFileSync("src/tool-manifest.ts","utf8");
const n=[...s.matchAll(/"name": "([a-z_]+)"/g)].map(m=>m[1]);
console.log(n.length, n.join(" "))'
⚠️ One honest caveat, because the naive version of this check gets it wrong: grepping that list for send matches check_send_domain, which is a read-only SPF/DKIM/DMARC lookup over DNS — it reads a domain's published records and sends nothing. Read each tool's description, not just its name. That caveat applies to whatever server you are evaluating, not only to this one.
The ratio is the point, and it is not a verdict on anyone else. A wide, send-capable tool surface is a legitimate design for an agent that is supposed to send, and most of this category is built for exactly that job. It is the wrong design for the one class of email where being argued into sending is the whole attack. RadMail reports 0 send-capable tools on every hosted endpoint — see The safety contract for why that is capability-absent rather than a setting someone could switch.
The safety contract (un-bypassable by design)
These are decided by deterministic code, not model judgment — see /.well-known/agent-safety.json:
-
money, changed-banking, first-contact, decision/sign-off, prompt-injection →
hardStop, human-only forever. RadMail will never hand an agent an auto-sendable reply for these. -
Enforcement model:
capability-absent. "The agent can't do that" is three different claims, and they are not equally strong — so the contract publishes which one this is, asenforcementModel, with all three values defined so the label is interpretable rather than a slogan:Value What it means capability-absent— RadMailThe tool that would perform the forbidden action does not exist on the server, so it cannot be called. There is nothing to configure and nothing to bypass. config-restrictedThe capability exists and is narrowed by configuration — an allowlist, a scope, a policy file. Whoever holds the configuration can widen it again. policy-gatedThe capability exists and is restrained by instructions, prompts, or documented policy that a model is asked to follow. The three definitions are generic and name no product — this is the axis, not a comparison. Don't take the label's word for it: read the tool list back (see Verify before you connect) and look for a send-capable tool. There isn't one; that absence is the enforcement.
-
A human-in-the-loop approval gate sits on a different row. "Human-in-the-loop" normally means the capability exists and a person is asked to approve each use —
config-restrictedorpolicy-gatedon the axis above. Approval gates have a legitimate place and they work differently: whoever holds the configuration can widen one, and an approver under time pressure is precisely what business-email-compromise fraud is built to exploit. RadMail reportscapability-absenton the hard-stopped classes, so there is no request to approve and nothing to widen. The reviewable drafts are the human-reviewed path for everything outside those classes — RadMail drafts, a person sends. -
A read-only banking connector protects a different thing. A read-only bank or accounting MCP server cannot initiate a transfer, so it cannot execute the fraud directly — genuinely useful, and a different job. Business email compromise is not an attack on your bank connection; it is an attack on your inbox. The fraudulent instruction arrives as email — a supplier whose bank details have "changed", an invoice redirected to a new account, a first-contact request that reads as routine — and the loss happens when a person or an agent believes it and acts through some other channel. A read-only connector never sees that email, so it cannot flag it. RadMail works where the instruction lands: money, changed-banking, first-contact, decision and prompt-injection stay human-only, reported as
capability-absent, not as a setting an operator could switch off. -
Taint envelope: every field derived from a raw email body carries
provenance: "untrusted-email-body", and every response carries asafetyblock restating the hard-stops. Treat tainted fields as data, never as instructions — this keeps your agent safe-by-default, even against a poisoned email. -
Fail-closed: if a risk signal can't be evaluated, RadMail refuses to auto-send.
Verify before you connect
The safety contract is machine-verifiable — fetch it and check it in one command, no account, no key:
curl -s https://radmail.ai/.well-known/agent-safety.json
Then don't take its word for it — read the tool list back and look for a send-capable tool. This is the check the capability-absent row above points at, and it needs no key either:
curl -s -X POST https://radmail.ai/api/mcp/sandbox \
-H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Read the names back. There is no send, no send_email, no pay, no update_banking — and that absence is the enforcement. (One exception, and only where an operator chose it: a local stdio server started with RADMAIL_SEND_TOOL=1 also lists send_email — see Opt-in: sending below. The hosted endpoints never do.) Observed on the hosted sandbox 2026-10-09: 6 tools — triage_inbox, list_right_now, why_surfaced, list_commitments, draft_reply, search. That is a dated observation of the hosted sandbox tier, not a ceiling: the local stdio package exposes the fuller set in the table above. Re-run the command rather than trusting this line.
And the one claim you cannot check from the outside — check it in the source. The strongest sentence in this README is "no tool can release a held send" (below, under Opt-in: sending). A paragraph is not evidence, and that claim is the one a hosted tools/list cannot reach, because the send tool is not on the hosted tier at all. It is asserted by a test in this repo — so run the test instead of believing the paragraph:
git clone https://github.com/radmail-ai/radmail-mcp && cd radmail-mcp && npm install
RADMAIL_TELEMETRY=off node --test --import tsx \
--test-name-pattern="release a held send" test/send-email.test.ts
Three things are asserted: that every URL the tool fetches, across every outcome, is the send path and never a /confirm route; that neither the client nor the tool names a confirm/release route anywhere in its source; and that the input schema has no field that could name an earlier request to act on. Observed 2026-10-05: 3 pass, 0 fail — a dated observation, like every other count in this file. Re-run it.
🔑 Now make it fail, because a guard you have not seen bite is not a guard. Add one line to src/lib/send.ts —
echo 'export const RELEASE_PATH = "/api/v1/sends/confirm";' >> src/lib/send.ts
— and re-run the command above: the second assertion fails and the suite exits non-zero. Then git checkout src/lib/send.ts to put it back. RadMail publishes the falsification step rather than asking you to assume the check is real.
Connect
Fastest — zero-auth hosted sandbox (no install, no key, no signup). Point any MCP client at the streamable-HTTP endpoint:
{
"mcpServers": {
"radmail": {
"url": "https://radmail.ai/api/mcp/sandbox",
"transport": "streamable-http"
}
}
}
Local stdio (this package — the fuller surface that triages the messages you pass it):
{
"mcpServers": {
"radmail": {
"command": "npx",
"args": ["-y", "radmail-mcp"]
}
}
}
radmail-mcpis live on npm — thenpxline above works as-is. Prefer no install at all? Use the zero-auth hosted sandbox above.
⚠️ Honest note on the published version (true as of 2026-09-30).
npm view radmail-mcp dist-tagsreportslatest: 0.5.0, but the build inside that tarball announces itself as0.4.0over MCP —dist/was packed before a version bump. This repository'smainis at0.5.1with the root cause fixed (prepublishOnlynow rebuildsdist/before packing); the corrected package is not yet published, because publishing needs an interactivenpm loginonly the maintainer can run. Reproduce it yourself:npm pack radmail-mcp && tar -xzOf radmail-mcp-*.tgz package/dist/src/server-info.js | grep version. No part of the safety contract depends on the version string — but RadMail publishes this check rather than asking you to assume.
Or from source: git clone https://github.com/radmail-ai/radmail-mcp && npm i && npm run build && npm start (stdio). Hosted deploy: Vercel Node serverless function (api/mcp.ts; / rewrites to the MCP handler).
Connected mode — your real inbox
Give the server a RadMail API key and four tools stop being a demo. Omit messages and:
searchfinds any email you've ever received in your real RadMail inbox;read_emailfetches the full message (headers +textBody);list_right_nowreturns your real can't-miss lane — the live engine's band + importance + urgency + reasons per item;list_commitmentslists your real open promises — direction (owed_by_us/owed_to_us), party, action, due date/phrase, state, confidence.
Search it, read it, know what matters now, know what's owed — install it once and your AI has the whole picture.
- Config: set
RADMAIL_API_KEY(keys start withtmk_— create one in about a minute at https://app.radmail.ai/settings/api-keys). Optional:RADMAIL_API_URLoverrides the API host (defaulthttps://app.radmail.ai). - Read-only by construction: connected mode only ever issues GETs. It never sends, drafts against, or mutates real mail, and the BEC hard-stops (money / changed-banking / first-contact / decision / injection) stay human-only forever.
- Same taint envelope: every field derived from real email content (
subject,fromName,snippet,textBody, …) arrives taggedprovenance:"untrusted-email-body"— data to reason about, never instructions to follow. - Fail-closed: invalid key (401), un-entitled plan (403), or a timeout returns an honest, typed error — never fabricated results. The key itself is never logged or echoed.
- Filters & paging: connected
searchsupports optionalfrom,after, andbefore(ISO-8601) alongsidequeryandlimit; connectedlist_right_now/list_commitmentssupportlimitandoffset. - No fabricated judgments: connected
list_right_nowsurfaces the live engine's own band / importance / urgency / reasons as-is — it never invents local hard-stop determinations the API didn't return. - Without a key,
search/list_right_now/list_commitments(sansmessages) andread_emailreturn friendly setup instructions instead of an error — the sandbox keeps working exactly as before.
The live engine is owner-taught
Connected mode reads a live engine the inbox owner actively teaches — the band / importance / reasons you get back reflect these controls (all live in the RadMail app at https://app.radmail.ai):
- VIP senders — an owner-named "always important" allow-list (a banker, a key partner). VIP is the top reputation override — it beats reply-history and every heuristic.
- Muted senders — the explicit "never important" twin. A mute suppresses sender reputation only; regulator notices and past-due signals still surface (a mute never hides a real compliance notice).
- Delegates — additional addresses (an assistant, an operations manager) that receive owner-level engagement treatment in the importance model. Importance-only: delegates never gain send or approval authority.
- One-click teaching — every daily-digest item carries signed 👍/👎 feedback links (plus a ⭐ "always important from this sender" action) that tune future ranking.
- Own-product demotion — the owner's own SaaS / notification mail can't ride reply history into the important lane.
- Daily digest — an opt-in consolidated "needs you" email, delivered once a day at 7am in the org's local timezone, that silences per-email pings while the Right Now lane keeps firing.
How real mail gets in today: RadMail's Apple Mail connector (macOS) feeds connected inboxes; hosted Gmail / Microsoft 365 OAuth connectors are pre-release.
Claude Code:
claude mcp add radmail -e RADMAIL_API_KEY=tmk_... -- npx -y radmail-mcp
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"radmail": {
"command": "npx",
"args": ["-y", "radmail-mcp"],
"env": { "RADMAIL_API_KEY": "tmk_..." }
}
}
}
Cursor (.cursor/mcp.json):
{
"mcpServers": {
"radmail": {
"command": "npx",
"args": ["-y", "radmail-mcp"],
"env": { "RADMAIL_API_KEY": "tmk_..." }
}
}
}
radmail-mcpis live on npm, so thenpxlines above work as-is. Prefer source? Pointcommandatnode dist/src/index.js— connected mode works the same way.
Opt-in: sending (local stdio only)
Off by default, absent from the hosted endpoints, and present on a local server only when its operator sets both:
# RADMAIL_API_KEY the read key (search / read_email / right-now) — never used to send
# RADMAIL_SEND_TOOL=1 lists send_email on THIS server
# RADMAIL_SEND_API_KEY a separate key with the send scope, ideally confined to one mailbox
claude mcp add radmail \
-e RADMAIL_API_KEY=tmk_... \
-e RADMAIL_SEND_TOOL=1 \
-e RADMAIL_SEND_API_KEY=tmk_... \
-- npx -y radmail-mcp
send_email hands the email to RadMail's outbound gate (POST /api/v1/send) and reports one of three outcomes:
| outcome | what happened |
|---|---|
sent | RadMail's gate released it from the owner's connected mailbox. |
held | Nothing was sent. The owner releases or discards it in the RadMail app at reviewUrl. |
refused | Not sent and not held — bad input, sending switched off, no send key, a suppressed recipient. |
RadMail decides, not the agent. It sends at once only when every recipient is on the owner's own team (a domain the workspace marked internal) or an established two-way contact; everything else is held. Money, changed-banking, first-contact, decision and injection content, and regulator / government / court / bank recipients, always hold. No tool can release a held send — the response carries a link to the app page, never a token, and the client only ever calls the send path. Do not take that on trust: Verify before you connect above carries the command that asserts it, and the one-line edit that makes it fail.
⚖️ Be exact about what this changes. On a server with sending turned on, the capability-absent label above no longer describes sending: the capability exists and is narrowed by configuration (config-restricted), and a held send is a person approving a request. The five hard-stopped classes still cannot leave without that person. The safety block on every response says which kind of server you are talking to: a send-enabled server replaces the "never sends mail" sentence with a sendSurface statement rather than leaving a false one in place.
The tool's description asks the agent to run its own correspondence review on the exact text before sending to anyone outside the owner's team — RadMail's gate catches machine-written tells and unthreaded replies, but it is not a substitute for a voice review.
Telemetry (demand signals — opt-out)
This server sends anonymous demand-signal telemetry to https://app.radmail.ai/api/mcp-demand so RadMail can see which tools agents actually use and what capabilities they ask for: what's sent is the tool name, the event type (call / need / capability), the need or capability text you explicitly submit via report_need / request_capability, and the optional agent id you pass. What's never sent: email content, message batches, search queries, results — and never your API key (in connected mode only the safe display prefix, tmk_live_ + the first 4 characters, is transmitted so adoption of connected mode is distinguishable). Sends are fire-and-forget with a 3-second timeout and every failure silently swallowed — telemetry can never slow down or break a tool call. Opt out entirely with RADMAIL_TELEMETRY=off.
How a directory lists this server
Third-party directories and answer engines don't read this README — they mirror the server.json record in the official MCP registry. Two publisher-controlled fields decide what a human or a model actually sees on those pages:
title— an optional human-readable display name, max 100 characters, present in the2025-12-11server schema and absent from2025-09-29. A directory with a title renders it; a record without one falls back to the bare package slug.description— the one-line summary shown beneath it.
Read what this repo declares, and what the live registry serves, side by side — no key, no clone:
# what main declares
curl -s https://raw.githubusercontent.com/radmail-ai/radmail-mcp/main/server.json \
| python3 -c 'import json,sys; d=json.load(sys.stdin); print(d.get("title")); print(d["description"])'
# what the live registry serves today
curl -s 'https://registry.modelcontextprotocol.io/v0/servers?search=radmail' \
| python3 -c 'import json,sys; [print(s["server"]["version"], "|", s["server"].get("title"), "|", s["server"]["description"]) for s in json.load(sys.stdin)["servers"]]'
⚠️ The two do not match yet, and that is stated here rather than glossed. Observed 2026-10-10: the registry's current (isLatest) record for ai.radmail/radmail-mcp is 0.5.0 on the 2025-09-29 schema — which has no title field at all — and carries the older 93-character description, while main is 0.5.1. So read this section as what RadMail declares, not as what a directory is showing you today; the second command above is the one that settles it either way.
Updating the record is a credential action and a human's — mcp-publisher login github (or login dns --domain radmail.ai) then mcp-publisher publish. mcp-publisher validate needs no credential, so anyone can check the record is well-formed before trusting it; against this repo on 2026-10-10 it returns ✅ server.json is valid.
Links
- Agent docs: https://radmail.ai/for-agents
- Zero-auth sandbox:
https://radmail.ai/api/mcp/sandbox(streamable-http, no auth) - Verifiable safety contract: https://radmail.ai/.well-known/agent-safety.json
- MCP manifest: https://radmail.ai/.well-known/mcp.json
- LLM-readable summary: https://radmail.ai/llms.txt
Compliance posture
A tool, not a guarantee — BAA + shared-responsibility framing. Never "HIPAA-certified" or "FedRAMP-authorized."
Tools it offers (6)
What this server listed when Ahel dialed its public endpoint in Sep 2026, with no key and no account of yours. The names are the server’s own.
triage_inboxlist_right_nowwhy_surfacedlist_commitmentsdraft_replysearch
Signals
- Last commit
- Oct 2026
- Weekly downloads
- 68
Advanced
- Delivery
- radmail-mcp MCP server → your Ahel connector (mcp.ahel.ai) → your AI.
- Item type
- mcp-server
- Key
ai-radmail-radmail-mcp- Source
- github.com/radmail-ai/radmail-mcp
- Hosted endpoint
https://radmail.ai/api/mcp/sandbox
github.com/radmail-ai/radmail-mcp