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.

ServerRunsToolsScope field on toolNarrowed credential vs the send toolAuthInbox
Email for AgentsHosted6No, held server-sideFiltered from tools/list; a call gets HTTP 403OAuth only; API keys refusedProvisions
AgentMailHosted, stdio bridges37 live; docs say 24 + 2NoSees it, refused at call timeOAuth or API keyProvisions
ResendHosted and npm106NoNo read-only key exists; a send-only key sees all 106OAuth or API keyNo mailbox object
Mailtrapnpm125NoSees it, refused at call timeAPI tokenProvisions
Postmarknpm24NoCannot be narrowedServer tokenNone; send only
Mailgunnpm74; 1 with --tags validateNo; _meta product tagOperator flag removes tools; key not consultedAPI keyNo mailbox object
NylasHosted38not documentednot documentedAPI keyBorrows via grant
Gmail MCP (Google)Hosted, preview11 pages; table lists 10not documentedNo send tool for anyoneOAuthBorrows
SendmuxHosted and PyPI54No; map in sourceHosted: filtered by token, call re-checkedOAuth; API key locallyProvisions
MultiMailHosted and npm50In description text onlySees it, 403 at call timeAPI key; OAuth hostedProvisions
Cloudflare agentic-inboxYour Worker13NoCannot be narrowedCloudflare AccessProvisions
Google Workspace MCPSelf-run15 Gmail; 8 read-onlyNoOperator flag removes tools and narrows OAuthOAuth, your clientBorrows
ms-365-mcp-serverSelf-run51 mail; 23 read-onlyNoOperator flag removes tools and narrows OAuthOAuth (MSAL)Borrows
Gmail-MCP-Server (archived)Self-run19NoCannot be narrowedLocal OAuth fileBorrows
mcp-email-serverSelf-run18NoSees it; refused if no SMTP is setLocal IMAP/SMTPBorrows
email-mcpSelf-run49; 28 read-onlyNoOperator config removes all four send toolsLocal IMAP/SMTPBorrows
imap-mcp + smtp-mcpSelf-run6 + 4 by defaultNoSend tools absent until SMTP_ALLOW_SEND=trueLocal credentialsBorrows
Smithery “gmail”Hosted31No field in recordnot documentednot documentedBorrows

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.

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 initializeEndpoints
Full tools/list returned with no credential67
401, protected-resource metadata found58
401 with a WWW-Authenticate challenge, no metadata found8
401 with no challenge7
initialize accepted, tools/list refused or malformed3
URL is a template, such as one containing {api_key}3
402, 404, other HTTP errors, or unreachable36

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 offersEndpoints
A scope whose name includes send, such as mail:send or email:send13
A single non-identity scope, such as mcp or full_api_access14
Nothing: the field is absent12
Several scopes, none named for sending10
Identity scopes only, such as openid, email and profile8
Read and draft scopes, no send scope at all1

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.

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.

  1. Fetch both discovery documents and read scopes_supported in 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.
  2. Call tools/list with no credential. If it answers, the list was not computed from a credential.
  3. Connect with the narrowest credential it documents and call tools/list again. If a credential that cannot send still lists the send tool, the server is in the call-time-refusal group.
  4. 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.


Keep reading

All guides · Documentation · Integrations