Integrations · September 26, 2026
Email MCP Server Comparison: Who Filters tools/list
An email MCP server comparison on one property: does a narrower credential shrink tools/list? 18 servers audited, 182 registry endpoints probed.
Connect an email MCP server to an agent and the agent learns what it can do from one
response: tools/list. If a send tool is in that list, the model knows it can send, and
anything it reads can try to talk it into doing so. Whether a narrower credential removes
that tool, or leaves it in place and refuses the call later, decides how much one hostile
email can do. The protocol permits the first design in so many words. Almost nobody
ships it.
This email MCP server comparison measures that property. On 25 September 2026 we ran or
read the source of 18 email MCP servers, ours included, and sent one anonymous
initialize to each of the 182 Streamable HTTP endpoints the official MCP registry
returns for seven email search terms. Two of the 18 compute tools/list from the
credential presented. Sixty-seven of the 182 endpoints hand their full tool list to a
caller with no credential at all. Every value below has a source link or a stated
method, and “not documented” means exactly that. For setup instructions rather than a
survey, read how an MCP email server works.
How we found the servers and what we measured
The method has a boundary, and here it is. We queried the registry’s public API,
GET /v0/servers?search=<term>&limit=100, following nextCursor to the end, for seven
terms: email, mail, gmail, outlook, inbox, smtp, imap. The registry’s
OpenAPI description defines
search as “Search servers by name (substring match)”, so a server whose name contains
none of those strings is invisible to this method. Keeping only entries marked isLatest
gave 313 unique names. Of those, 168 list only a hosted remote, 120 only a package, 20
both and 5 neither.
We did not clean that set by hand, because a hand classification nobody else can see is not a finding. It includes address verifiers, email finders, campaign platforms, a physical-mail service, and 18 Alpic-hosted entries whose descriptions are placeholders (“Description of my MCP server”, “Still WiP”, “Non functional server (yet)”) or a generic one-liner. Where that noise matters to a number, we say so.
The 313 names carry 182 streamable-http remotes and 20 legacy sse remotes. To each
Streamable HTTP URL we sent one unauthenticated initialize (protocol version
2025-06-18), then notifications/initialized and tools/list if it answered 200. On a
401 we fetched the protected-resource metadata, from the WWW-Authenticate header if it
named one and otherwise from /.well-known/oauth-protected-resource, and then the
authorization-server metadata it pointed to. We called no tools. Anyone can repeat this
with a registry query and three JSON-RPC requests per URL.
The other directories gave less. Smithery’s registry API
returned 124 results for “email” and supplied one audit row. Glama’s API answered 401 and
asks for an API key. PulseMCP’s v0beta API returned HTTP 410 with the code
API_SUNSET. punkpeye/awesome-mcp-servers
has 126 top-level entries matching email, mail, Gmail, Outlook, IMAP, SMTP or inbox as a
whole word, case-insensitive, 61 of them in its Communication section. None of those is
published by Resend, Postmark, Mailgun or Mailtrap.
For the deep audit we picked 18 servers: every mail vendor’s own server we could find,
the email result with the highest useCount on Smithery (57,738 for its “gmail”), widely
used open-source Gmail, Microsoft 365 and IMAP servers (Google Workspace MCP, GongRzhe’s
Gmail server, ms-365-mcp-server and mcp-email-server had 3,227, 1,164, 997 and 337 GitHub
stars), and servers with an unusual design. Where a package ran over stdio, we started it
with made-up credentials and recorded its tools/list. Where it could not start without a
real account, we read the source or the vendor’s documentation.
An email MCP server comparison on six questions
“Narrowed credential” means the most restricted credential the server documents. The five possible answers in that column are defined two sections down.
| Server | Runs | Tools | Scope field on tool | Narrowed credential vs the send tool | Auth | Inbox |
|---|---|---|---|---|---|---|
| Email for Agents | Hosted | 6 | No, held server-side | Filtered from tools/list; a call gets HTTP 403 | OAuth only; API keys refused | Provisions |
| AgentMail | Hosted, stdio bridges | 37 live; docs say 24 + 2 | No | Sees it, refused at call time | OAuth or API key | Provisions |
| Resend | Hosted and npm | 106 | No | No read-only key exists; a send-only key sees all 106 | OAuth or API key | No mailbox object |
| Mailtrap | npm | 125 | No | Sees it, refused at call time | API token | Provisions |
| Postmark | npm | 24 | No | Cannot be narrowed | Server token | None; send only |
| Mailgun | npm | 74; 1 with --tags validate | No; _meta product tag | Operator flag removes tools; key not consulted | API key | No mailbox object |
| Nylas | Hosted | 38 | not documented | not documented | API key | Borrows via grant |
| Gmail MCP (Google) | Hosted, preview | 11 pages; table lists 10 | not documented | No send tool for anyone | OAuth | Borrows |
| Sendmux | Hosted and PyPI | 54 | No; map in source | Hosted: filtered by token, call re-checked | OAuth; API key locally | Provisions |
| MultiMail | Hosted and npm | 50 | In description text only | Sees it, 403 at call time | API key; OAuth hosted | Provisions |
| Cloudflare agentic-inbox | Your Worker | 13 | No | Cannot be narrowed | Cloudflare Access | Provisions |
| Google Workspace MCP | Self-run | 15 Gmail; 8 read-only | No | Operator flag removes tools and narrows OAuth | OAuth, your client | Borrows |
| ms-365-mcp-server | Self-run | 51 mail; 23 read-only | No | Operator flag removes tools and narrows OAuth | OAuth (MSAL) | Borrows |
| Gmail-MCP-Server (archived) | Self-run | 19 | No | Cannot be narrowed | Local OAuth file | Borrows |
| mcp-email-server | Self-run | 18 | No | Sees it; refused if no SMTP is set | Local IMAP/SMTP | Borrows |
| email-mcp | Self-run | 49; 28 read-only | No | Operator config removes all four send tools | Local IMAP/SMTP | Borrows |
| imap-mcp + smtp-mcp | Self-run | 6 + 4 by default | No | Send tools absent until SMTP_ALLOW_SEND=true | Local credentials | Borrows |
| Smithery “gmail” | Hosted | 31 | No field in record | not documented | not documented | Borrows |
Tool counts are what tools/list returned today, except for Nylas, Google, Cloudflare,
GongRzhe, Sendmux and Smithery’s Gmail, which come from documentation, source or registry
records. Where two sources disagree we give both. AgentMail’s
MCP page says “The server exposes 24
tools”, plus two organisation tools for OAuth sessions; the hosted server returned 37,
which is also the count in the mcp-manifest.json in its repository. Google’s reference
has 11 tool pages, create_label included, while its toolset table still lists 10.
No tool in the audit says what permission it needs
None of the 16 servers whose tool definitions we could read puts a permission or scope
field on them. Nylas and Google do not publish theirs. The protocol gives them nowhere
standard to put one: the
2026-07-28 tools specification
defines a tool as name, title, description, icons, inputSchema, outputSchema
and annotations, plus the generic _meta extension object in the schema, and none of
these is a permission field.
What the same page does say is the strongest primary support for filtering by credential.
The set returned by tools/list “MUST NOT vary per-connection”, but it “MAY vary by the
authorization presented on the request”, the example given being “returning only the
tools the caller’s granted scopes permit”. So a server that filters by scope is following
the specification, not working around it. The specification permits it and does not
require it, and that gap is where most of this table sits.
Several servers know the mapping and keep it inside. Ours holds a scopes array on each
of its six tools and strips it before responding, which you can see from the outside:
the definitions tools/list returns carry no scope field. Sendmux has a
TOOL_PERMISSION_REQUIREMENTS table
mapping 54 tools to scopes such as mailbox.read and email.send. AgentMail’s manifest
marks two tools oauthOnly, and that flag does not appear on the wire. Mailgun uses
_meta for a com.mailgun/tags array, ["send"] on 71 of its 74 tools, a product label
that decides which tools its --tags flag loads, not what a key may do. MultiMail writes
“Requires oversight scope on the API key” into descriptions, which a model can read and a
client cannot parse.
Of the 67 anonymous tool lists in the registry probe, 102 of 1,331 tool definitions
carried a per-tool securitySchemes array, and all 102 came from three servers:
Primitive (30 of 30), Mailcheer (17 of 17) and Mailrith, a campaign platform (55 of 55).
Mailcheer’s send_email declares {"type": "oauth2", "scopes": ["emails:send"]}. That is
the shape proposed in
SEP-1488,
which GitHub shows as open and labelled draft. SEP-1880, which would have added
tool-level scope requirements, was closed as not planned in favour of it.
Behaviour annotations are common and are not a substitute. AgentMail annotates all 37
tools, Mailtrap all 125, Postmark all 24, and send_message on AgentMail says
"destructiveHint": true. The specification says clients “MUST consider tool
annotations to be untrusted unless they come from trusted servers”, so an annotation tells
a client how careful to be, not what a credential is allowed to do.
Narrowing a credential rarely changes what the agent sees
The narrowed-credential column resolves to five behaviours, and the distribution is the finding.
- Filtered by the credential presented, call re-checked: 2 of 18. Our server and
Sendmux’s hosted endpoint. Sendmux runs FastMCP’s
AuthMiddlewareover its permission table, and FastMCP’s documentation says that middleware applies checks “globally to all components”, “filtering list responses and blocking unauthorized execution”. The same page says that in stdio mode “all auth checks are skipped”, so Sendmux’s local package does not filter this way. - Filtered by operator configuration at startup: 5. Mailgun, Google Workspace MCP,
ms-365-mcp-server, email-mcp and ni-c’s pair. The tool list follows a flag or an
environment variable, not the key. Two of them close the loop in the right direction:
Google Workspace MCP in
--read-onlymode requests only read-only Google scopes, and ms-365-mcp-server derives its token request from the tools left enabled. With--permissions gmail:drafts, Google Workspace MCP returned 12 tools andsend_gmail_messagewas not one of them. - No send tool for anyone: 1. Google’s Gmail server.
- Sees the send tool, refused when it calls it: 4. AgentMail, Mailtrap, MultiMail and mcp-email-server.
- Cannot be narrowed to read-only: 4. Resend, Postmark, Cloudflare agentic-inbox and GongRzhe’s Gmail server. Two more, Nylas and Smithery’s Gmail, do not document it.
The four in the “sees it” row are not careless about credentials, which is what makes the
pattern worth naming. AgentMail’s key model is finer than ours. Its
permissions page describes a whitelist with
separate message_read, message_send and draft_send permissions, layered on pod- and
inbox-scoped keys, and gives a complete example of a read-only key. The MCP server does
not consult any of it when listing tools. A comment in its
server source
says tool definitions are “identical for every request”, and the client is built “inside
the tool callback at invocation time”. A request carrying a made-up key that began with
am_ received all 37 tools, including send_message. The two oauthOnly tools were in
that list too, and the same source says API-key requests to them “return an error”.
Mailtrap is the same shape. Its token documentation lets you “Assign permissions by checking the boxes in the corresponding access level columns”, and its server returns a fixed array of 125 tools whatever the token holds. MultiMail’s source maps an HTTP 403 to “API key lacks required scope for this operation”, which is a call-time refusal by construction.
Resend and Postmark fail the column for a different reason. Resend’s
API key reference offers
two permissions, full_access and sending_access, the second described as “Can only
send emails”. A key can be narrowed to sending and never to reading, and all 106 tools are
registered regardless. Postmark’s README is the most candid document in the audit: its
tokens do not support “sub-scoped permissions”, and a server token “grants full access to
all operations on the server it belongs to”. It then lists its four sending tools and four
destructive ones by name. Every vendor should publish that table.
Google’s Gmail server is the instructive case. Its
tool reference has
create_draft among its tools and nothing that sends. The
configuration guide
has you request gmail.readonly and gmail.compose, and Google’s
scope reference describes
gmail.compose as “Manage drafts and send emails”. The tool surface cannot send. The
token behind it can. For an agent confined to that server this is a strong boundary; for
the token itself, handed to any other client, it is not a boundary at all. Our
email.draft grant differs on exactly this point: the credential itself carries no
messages:send, so there is nothing for another client to use.
What 182 hosted endpoints show a stranger
The anonymous probe of every Streamable HTTP remote in the 313-name set split as follows.
Response to an anonymous initialize | Endpoints |
|---|---|
Full tools/list returned with no credential | 67 |
| 401, protected-resource metadata found | 58 |
401 with a WWW-Authenticate challenge, no metadata found | 8 |
| 401 with no challenge | 7 |
initialize accepted, tools/list refused or malformed | 3 |
URL is a template, such as one containing {api_key} | 3 |
| 402, 404, other HTTP errors, or unreachable | 36 |
The open lists deserve a fair reading. Many belong to address verifiers and lookup
services, and serving a list anonymously does not mean a call
works anonymously. It does mean the list was not computed from a credential, because
there was none. Nineteen of the 67 include a tool whose name contains send, reply or
compose as a word. That rule over-counts: by their own descriptions, pipeworx’s
send-that-email analyses whether to send, Radmail’s match is draft_reply, and
bot.mailbox sends physical letters. Named tools such as send_email on Primitive,
Mailcheer, MisarMail and mifactory are real email sends, listed to anyone who asks.
The 58 OAuth endpoints show what narrowing a client could even ask for. We sorted each
by the scopes_supported in its protected-resource metadata, putting it in the first
row that fits:
What scopes_supported offers | Endpoints |
|---|---|
A scope whose name includes send, such as mail:send or email:send | 13 |
A single non-identity scope, such as mcp or full_api_access | 14 |
| Nothing: the field is absent | 12 |
| Several scopes, none named for sending | 10 |
Identity scopes only, such as openid, email and profile | 8 |
| Read and draft scopes, no send scope at all | 1 |
The protected-resource document is not the whole story, and a client that reads only
it can be misled. For 20 of the 58, the authorization server’s scopes_supported
differs from the protected resource’s. Eleven of the 12 with no field in the protected
resource do list scopes at their authorization server, though none of those names a send
scope. Resend, which is outside the registry set, shows the pattern: its protected
resource at mcp.resend.com has no scopes_supported, while its
authorization server
offers full_access and emails:send. AgentMail’s protected resource lists openid,
email, profile and user:org:read; its authorization server adds identity and
metadata scopes, none for sending.
A separate send scope is necessary for credential-based filtering and not evidence of it. Without accounts on those 13 services we cannot see whether their tool lists shrink, and we are not going to guess.
Where Email for Agents is behind
We scored ourselves on the same terms. Our source repository is private, so every
claim below is one you can check from outside: the two discovery documents are public
URLs, and the tool list is what tools/list returns for the grant you hold. Our row is
one of the two in the filtered-by-credential group, and it is not the best row on every
other axis.
- Our two discovery documents disagree. The protected-resource metadata at
/.well-known/oauth-protected-resource/mcpadvertises onlyemail.read. The authorization-server metadata advertisesemail.read,email.draft,email.sendandoffline_access. A client that requests only what the protected-resource document lists gets the read preset and a four-tool session. It is the same mismatch we found at 20 of the 58 endpoints above. - Our grants are coarser than Sendmux’s or AgentMail’s. We offer three presets over 32 internal scopes. Sendmux advertises 15 OAuth scopes. AgentMail’s key permissions reach down to whether a key can see messages labelled spam.
- Our tools carry no annotations and no titles. Of the 15 other servers whose tool
definitions we could read, 11 annotate some or all of them. Ours give a client no
readOnlyHintwith which to auto-approve a read. - We do not declare
listChanged. Ourinitializereturnscapabilities: { tools: {} }, although a demoted human shrinks the list mid-session, as described in the tool surface permission boundary. - Our refusal is not the protocol’s. The specification lists “Unknown tool” as a JSON-RPC protocol error. Ours is HTTP 403 with no JSON-RPC envelope, which is harder for a strict client to handle.
- An agent cannot create an inbox over our MCP. AgentMail, Mailtrap, Sendmux and MultiMail expose inbox or mailbox creation as a tool. Our six tools read, draft and send.
Two designs elsewhere deserve credit. ni-c’s smtp-mcp keeps send tools out of
tools/list until an operator sets SMTP_ALLOW_SEND=true, checks every recipient against
an allowlist, and asks a human to approve each message through MCP elicitation, bound to a
SHA-256 fingerprint of that message. Google put the draft-only boundary into the product
itself. Both reach the same conclusion by a different route: the safest send tool is one
the model was never told about.
Checking a server before you connect it
You do not need our table for a server you are evaluating. Four requests settle the important column.
- Fetch both discovery documents and read
scopes_supportedin each: the protected resource at/.well-known/oauth-protected-resource, and the authorization server it names. They can disagree, as ours and Resend’s do. If neither offers anything but a catch-all or identity scopes, a client has nothing narrower to ask for. - Call
tools/listwith no credential. If it answers, the list was not computed from a credential. - Connect with the narrowest credential it documents and call
tools/listagain. If a credential that cannot send still lists the send tool, the server is in the call-time-refusal group. - Call the send tool anyway, straight over HTTP. A readable tool error is a refusal the model can argue with. A tool that was never listed, and a call that returns nothing the client can hand back to the model, is a boundary.
Then decide by the job. For an agent that only reads, a server in the filtered groups, or Google’s draft-only server, removes the risk at discovery. For one that must send, filtering matters less than recipient policy and approval, set out in human approval before an agent sends email and in scoped credentials for agent email. Our own connection presets and inbox policies are on the agent controls page, and every way to connect is listed on the integrations hub.
Sources
All pages and endpoints below were read or queried on 2026-09-25. Repositories were cloned at their default branch the same day.
- MCP registry OpenAPI and the registry servers API
- Smithery registry search and Smithery “gmail” record
- punkpeye/awesome-mcp-servers
- MCP tools specification, 2026-07-28
- SEP-1488 and SEP-1880
- AgentMail MCP repository,
AgentMail MCP docs,
AgentMail permissions and
https://mcp.agentmail.to/.well-known/oauth-protected-resource/mcp - Resend MCP repository,
Resend create API key,
https://mcp.resend.com/.well-known/oauth-protected-resourceandhttps://api.resend.com/.well-known/oauth-authorization-server - Mailtrap MCP repository and Mailtrap API tokens
- Postmark MCP repository
- Mailgun MCP repository
- Nylas MCP documentation
- Gmail MCP reference, Gmail MCP configuration and Gmail API scopes
- Sendmux SDK repository and FastMCP authorization
- MultiMail MCP repository
- Cloudflare agentic-inbox
- taylorwilsdon/google_workspace_mcp
- Softeria/ms-365-mcp-server
- GongRzhe/Gmail-MCP-Server
- Wh1isper/mcp-email-server
- codefuturist/email-mcp
- ni-c/imap-mcp and ni-c/smtp-mcp
- Our own endpoints:
https://mcp.emailforagents.ai/.well-known/oauth-protected-resource/mcpandhttps://mcp.emailforagents.ai/.well-known/oauth-authorization-server
Keep reading
The MCP Tool Surface Is the Permission Boundary
How the MCP tool surface permission boundary is computed per request, what a filtered tools/call returns, and three ways the tool list shrinks under you.
MCP Email Server: Give Your Agent Client a Real Inbox
How a remote MCP email server works, what the consent screen must show, how to scope a grant to one inbox, and how to verify it before allowing sends.
Scoped Credentials for Agent Email: Read, Draft, Send
Give an agent the smallest useful email permission: project and inbox scoping, one-time secrets, draft-only grants, rotation, and revocation you can verify.