MCP gateways
Start with a team that has done everything right. Twelve MCP servers, all useful: the issue tracker, the wiki, two databases, the deployment tool, a log search, a few more. Every developer has them configured locally. Which means every developer holds a token for the issue tracker, a token for the wiki, a read credential for each database, and a deploy credential, on a laptop, in a JSON file, rotated whenever somebody remembers.
Now the team is forty people and the twelve servers are fifty. A new starter's first day includes pasting a config file somebody sent them in a chat message. Nobody can say which of the fifty a given person can reach. And when a row goes missing from the production database, the question "which agent deleted it, running as whom" has no answer anywhere, because the database only saw a connection using a shared credential.
An MCP gatewaya service that presents many MCP servers to a client as one. It holds the downstream credentials, decides which servers and tools each client may reach, and records what was done.Full glossary entryIntroduced in MCP gateways is the thing that goes in the middle. It is a single MCP server, from the client's point of view, that fronts many real servers behind it. The client connects to one place. The gateway holds the credentials, decides what each client may reach, and writes down what happened.
Fan-in
The client-facing half is the simple half. One endpoint, presenting the tools of every server behind it as though they were its own.
What that does to a developer's machine is the visible win. Fifty server entries, each with its own command or URL and its own secret, collapse to one entry with one address. Adding a fifty-first server for everybody is a change on the gateway, and no developer touches anything. Removing one is the same change in reverse, and that matters more. Today, taking a server off fifty laptops is a message in a channel and a hope.
The gateway also absorbs the transport differences. Some servers run as local processes on the developer's machine and some are remote HTTP services. A gateway can host the local-process ones itself and present everything to the client over one remote connection, which is how a developer on a locked-down laptop gets access to a server they are not allowed to install.
The credential problem
Credentials are the reason most of these get built. Everything above is convenience.
Without a gateway, every developer holds a credential for every system their agent can touch. Fifty servers and forty developers is two thousand credential placements, sitting in config files, surviving on laptops after people leave, and rotated when somebody has an afternoon. The credentials are also usually broader than they need to be, because the easy thing to issue is a token that works.
With a gateway, the developer holds nothing. The gateway holds one credential per downstream system, in a secret store, and the user authenticates to the gateway. Rotating a credential becomes one change in one place. Revoking a person's access becomes a change to that person's account at the gateway, which takes effect immediately across all fifty servers rather than depending on somebody wiping their laptop.
There is a design choice underneath. It is the one to ask a vendor about. The gateway can call downstream using a service credential shared by everyone, or it can call downstream as the user, holding a per-user token it obtained when that user signed in. The shared credential is simpler and means the downstream system's own permissions are useless, because every request looks the same to it. Acting as the user keeps the downstream system's permissions working, so a person who cannot read a repository directly cannot read it through an agent either. Ask which one you are getting.
Policy
Policy enforcementthe gateway deciding, per request, whether this principal may call this tool on this server. The answer is allow, deny, or held until a named human approves it.Full glossary entryIntroduced in MCP gateways is the gateway deciding, per request, whether this principal may do this thing.
The useful granularity is the tool, not the server. "Alice's agent may reach the database server" is not a decision anybody wants to make, because that server exposes query and it also exposes execute. Allow and deny lists at tool level are what makes the answer usable: read tools for everybody, write tools for the team that owns the system, and nothing destructive by default.
Policy also attaches to the agent rather than only the person. A developer typing at a terminal and an unattended agent running on a schedule are different principals with the same human behind them, and the scheduled one should usually be able to do less.
For destructive tools, the third option beside allow and deny is approval. The gateway holds the call, asks a named human, and releases it when they say yes. Approval is expensive in latency and cheap in incidents. Use it for anything that drops a table, sends money, or posts publicly. It produces the paper trail on its own, since the approval and the call end up in the same record.
Audit
An Audit logthe record of which principal called which tool, with which arguments, against which server, and what came back. No single MCP server can produce one, because a server never learns which human is behind the client.Full glossary entryIntroduced in MCP gateways is the record of which principal called which tool, with which arguments, at what time, against which server, and what came back.
Each item on that list is something an incident review asks for. Somebody notices the missing row on Tuesday and wants to know who, running what, at which minute, with which arguments. Most compliance regimes want a version of the same thing, plus evidence that the log cannot be edited by the people it records.
No individual MCP server gives you this. A server sees a connection and a request. It does not know which human is behind the client, because that information does not survive the hop. The gateway is the only component that knows both ends at once, so it is the only place the record can be written.
Arguments have to be captured, because "alice called query" tells you nothing and "alice called query with DELETE FROM orders WHERE ..." tells you everything. Results have to be captured at least in summary too, because half the incidents are about what came back rather than what went in. Both of those make the audit store sensitive in its own right, so it wants the same retention and redaction thinking as any other log full of production data.
There is a trade in that note. The downstream system's own log now shows the gateway doing everything, so the gateway's log is the only place the person is named. Everything then rests on the gateway's log being trustworthy.
Namespacing and collisions
Two servers both expose a tool called search. So do three of the other forty-eight. Fanning them all into one endpoint produces five tools with the same name, and a model asked to pick between them has nothing to pick on.
Tool namespacingprefixing each tool with the server it came from, so two servers exposing a tool of the same name can both be presented to one client. The prefix is text the model reads, so it changes behaviour as well as resolving the collision.Full glossary entryIntroduced in MCP gateways is the gateway prefixing each tool with the server it came from, so search becomes wiki.search and logs.search and tracker.search. The collision goes away and the names carry information the model can use.
There is a cost hiding in that. Renaming a tool changes what the model sees, and models are sensitive to tool names in the way they are sensitive to any other text. A prompt that worked when the tool was called search may behave differently when it is called internal_wiki_v2_search_pages. Long generated prefixes are also a token cost repeated on every request. Prefer short, stable, human-chosen prefixes over anything derived from a server's full identifier.
A registry of approved servers
A Server registrythe reviewed list of MCP servers an organisation has approved, with an owner and a pinned version for each. It turns adding a server from a pasted config line into an act with a name on it.Full glossary entryIntroduced in MCP gateways is the list of MCP servers the organisation has approved, with who owns each one, what it connects to, and what its tools can do.
The point is procedural rather than technical. Without a registry, adding a server is a line somebody pastes into a config file, and the review that happens is none. MCP servers are ordinary programs that hold credentials and take instructions from a model, so the ones people paste in are the ones nobody has read. A registry makes adding a server an act with a name on it.
Once the gateway will only connect to servers in the registry, the registry stops being a wiki page that drifts and becomes the thing that decides. That is the version to build.
The gateway does not fix the context cost
Fan-in changes the client's configuration. It does not change what the model sees.
Every tool the gateway presents still arrives as a tool definition in the context window, on every request, before the user has typed anything. Take fifty servers averaging eight tools each, and say each definition runs to 300 tokens, which is a long description and a wide schema rather than a typical one. That is 120,000 tokens of tool definitions in front of a model that has not been asked a question yet. A 200,000 token window does hold that. What it leaves is 80,000 tokens for the conversation, the documents the agent retrieves and the answer, so the menu has taken more of the window than the work is going to get. You pay for those tokens on every request too, and the model gets worse at choosing as the menu grows.
So a gateway that is doing its job filters. Which tools a given client sees should depend on who that client is and what it is for, and the default should be a small set rather than everything the organisation owns. Some gateways do this by group, some let a client request a subset at connection time, and some expose a search tool that finds other tools on demand. Whichever it is, "presents all fifty servers to everyone" is a configuration to fix rather than a feature.
What it costs
It is another hop, with the same consequences as any other. Tool calls are already slower than model calls in most loops, so the added latency usually hides, but the gateway being down means every agent in the organisation loses every tool at once.
The gateway also holds every credential the organisation has issued to an agent, which makes it the most attractive thing on the network. It needs the treatment you would give a secret store, not the treatment you would give an internal API, and the audit log needs to be somewhere its own administrators cannot edit.
And it does not make a bad server safe. A gateway controls who reaches a server and records what they asked it. It has no opinion about what the server does once the call arrives. A server whose read_file accepts ../../ and returns anything on the disk is just as dangerous behind a gateway, and the audit log will faithfully record the moment it happened. Reviewing the server is a separate job that the gateway does not do for you.
Review the server before you add it to the registry. Do not add a server on request alone.
- Name an owner inside the organisation. Record the owner in the registry.
- Read the server's source, or confirm the publisher and the release you are pinning.
- Pin the version. Do not track a moving tag.
- List every tool the server exposes. Mark each tool read or write.
- Issue the narrowest downstream credential that makes the read tools work.
- Deny every write tool by default. Grant a write tool to a named group.
- Require approval on any tool that deletes data, moves money, or publishes.
- Confirm the gateway logs the arguments of every call to this server.
- Grant the server to one team first. Review the audit log after two weeks.
This is not an LLM gateway
Both are called gateways. Both are run by a platform team, both appear in the same architecture diagram, and the two get treated as one box more often than not. They sit on opposite sides of the harness and solve unrelated problems.
An MCP gateway is on the path out to tools and data. Tool calls go out, tool results come back. It decides which servers a client may reach, whose credential is used, and it records what got done. Its subject is access, credentials and audit.
An LLM gateway is on the path out to the models. Prompts go out, completions come back. It decides which model gets the call, what the call costs, and whether the caller is allowed to make it. Its subject is spend, routing and model choice.
| MCP gateway | LLM gateway | |
|---|---|---|
| Sits between | Harness and tools | Harness and models |
| Carries | Tool calls and tool results | Prompts and completions |
| Behind it | MCP servers | Model vendors |
| Decides | Which server, whose credential, what was done | Which model, what it costs, is it allowed |
| The problem it solves | Access and audit | Spend and model choice |
| Who asks for it | Security, and whoever answers the audit | Finance, and the team that owns the budget |
Most organisations meet the LLM gateway first, because the invoice arrives before the audit does. Meeting it first gets you no closer to this one, and neither gateway can see the traffic the other carries.
Terms introduced
- MCP gateway: a service that presents many MCP servers to a client as one, holding the downstream credentials and deciding which servers and tools each client may reach.
- Tool namespacing: prefixing each tool with the server it came from, so that two servers exposing a tool of the same name can both be presented to one client.
- Server registry: the reviewed list of MCP servers an organisation has approved, with an owner and a pinned version for each.
- Policy enforcement: the gateway deciding per request whether this principal may call this tool on this server, by allow list, deny list, or held-for-approval.
- Audit log: the record of which principal called which tool, with which arguments, against which server, and what came back.
How providers do it
Neither vendor sells a box called an MCP gateway. Both ship a subset of the jobs one does, inside the harness rather than beside it, and both stop at the same place.
| Question | Anthropic | Cursor |
|---|---|---|
| Remote servers | Claude Code: http (alias streamable-http), sse, stdio, ws. Connectors: Streamable HTTP, legacy SSE deprecated | stdio, SSE, Streamable HTTP |
| Admin-approved server list | managed-mcp.json takes exclusive control; allowedMcpServers and deniedMcpServers by URL, command or name | Team dashboard MCP Configuration, by command pattern or URL pattern |
| Policy at tool granularity | Not documented on the MCP or managed MCP pages | Per-server Tools field, server:tool with wildcards |
| User auth to a remote server | OAuth from /mcp or claude mcp login, or static headers, or a headersHelper script | OAuth per user, or custom headers and env |
| Per-tool-call audit for an admin | Not in the audit log export. Configuration events only in the Compliance API feed. Per-call needs OpenTelemetry | Not in the audit log, which carries mcp_authentication only. Per-call needs OpenTelemetry |
Every row above is confirmed. Left open in the tabs: whether a Claude.ai admin can block an
arbitrary custom connector URL, whether Anthropic documents any tool-level allow list, whether
Compliance API session transcripts contain individual tool calls, the permissions.json schema
for Cursor MCP entries, and whether Cursor's general cursor.tool.calls metric names the server
and the tool.
The last row is the one that decides an architecture. Both vendors' admin-facing audit logs record that MCP was configured and that somebody authenticated, and neither records which tool was called with which arguments. An organisation that needs that record has to collect telemetry itself or put a real gateway on the path.
- Anthropic
- Cursor
What this maps to: Anthropic ships no product called an MCP gateway. The gateway's jobs are split across two places. Claude Code takes an enterprise MCP configuration deployed to the machine, which is where the allow list, the deny list and the exclusive-control mode live. Claude.ai and Claude Desktop take their connectors from Organization settings > Connectors, which is where an admin decides which connectors exist, who gets them, and which scopes they may request.
| Question | Answer | Status |
|---|---|---|
| Remote MCP servers, and over which transport | Claude Code documents four transport types: http (accepting streamable-http as an alias), sse (deprecated, still supported), stdio, and ws. Custom connectors for Claude.ai and Desktop document Streamable HTTP, with the legacy HTTP+SSE transport being deprecated | confirmed |
| Remote MCP from the API itself | The MCP connector (beta, header mcp-client-2025-11-20) takes an mcp_servers array of type: "url" entries. "Local STDIO servers cannot be connected directly" | confirmed |
| Admin-managed list of servers, Claude Code | A managed-mcp.json at a system path. Where it is deployed, Claude Code loads only the servers it defines and a user "can't add, modify, or use any other MCP servers", including servers passed with --mcp-config. An empty server map disables MCP | confirmed |
| Allow and deny lists | allowedMcpServers and deniedMcpServers, keyed by serverUrl, command or serverName. Deny lists merge from every settings scope. allowManagedMcpServersOnly: true makes user, project and local allow lists be ignored while the deny list still merges | confirmed |
| Servers added alongside a user's own | managedMcpServers, readable only from managed settings and ignored anywhere else | confirmed |
| Admin control, Claude.ai and Desktop | Per connector, an admin enables it, picks the roles that receive it automatically, and chooses which scopes Claude may request. A connector can be required to connect only through the organisation's identity provider | confirmed |
| Whether a Claude.ai admin can block a user adding an arbitrary custom remote MCP URL | The organisation-authorization article describes enable, roles and scopes per connector and does not describe a URL allow list or block list | unconfirmed; open question |
| Tool-granularity policy | Not found in the Claude Code MCP or managed MCP pages. Scope selection on a Claude.ai connector governs what Claude may request, which is not the same thing as a per-tool allow list | unconfirmed; open question |
| How a user authenticates to a remote server | Claude Code runs an OAuth 2.0 flow from /mcp or claude mcp login <name>, and also takes static headers with --header, a headersHelper script for short-lived credentials, and ${VAR} expansion in URLs and headers. Claude.ai and Desktop use OAuth with Dynamic Client Registration. The API's MCP connector runs no flow: the caller obtains the token and passes it as authorization_token | confirmed |
| Audit of MCP tool calls | The Claude.ai CSV audit log export lists around 28 event types covering authentication, projects, organisation management and conversations. No MCP, connector or tool-call event appears in that list | confirmed |
| MCP events in the Compliance API activity feed | GET /v1/compliance/activities carries mcp_server_created, mcp_server_updated, mcp_server_deleted, mcp_server_managed_auth_updated, mcp_server_managed_auth_token_exchanged and mcp_tool_policy_updated, among others. These are configuration and administration events. No documented activity type means "this principal invoked this tool on this server" | confirmed |
| Per-call tool audit | The documented route is telemetry the customer collects. With OpenTelemetry export configured, Claude Code "can record which MCP servers and tools users invoke", and OTEL_LOG_TOOL_DETAILS=1 includes the MCP server and tool names in tool events | confirmed |
| Whether Compliance API session transcripts expose individual MCP tool calls | The compliance sessions page was not read | unconfirmed; open question |
Their vocabulary
| Standard term | Their term |
|---|---|
| Server registry | Managed MCP configuration (managed-mcp.json), or the connector list in Organization settings |
| Policy enforcement | Allow list and deny list settings; connector scopes |
| Audit log | Audit log export (Claude.ai), Compliance API activity feed (configuration events), OpenTelemetry export (per-call) |
| Remote server | Custom connector, or a remote MCP server |
Where to look
For Claude Code, the managed MCP settings file on the machine, and the error Cannot add MCP server: enterprise MCP configuration is active and has exclusive control over MCP servers as the sign it is in force. For Claude.ai, Organization settings > Connectors for the list and the roles, and Data and Privacy > Export logs for the audit CSV. For per-tool-call records, the OpenTelemetry collector the organisation runs itself.
One boundary catches people out: connectors the desktop app delivers into its own sessions are governed from the Claude.ai organisation settings, so the Claude Code managed configuration does not reach them.
Last verified: 2026-09-09 against https://code.claude.com/docs/en/managed-mcp, https://code.claude.com/docs/en/mcp, https://claude.com/docs/connectors/building, https://platform.claude.com/docs/en/agents-and-tools/mcp-connector, https://support.claude.com/en/articles/15537633-authorize-mcp-connectors-for-your-entire-organization, https://support.claude.com/en/articles/9970975-access-audit-logs and https://platform.claude.com/docs/en/api/compliance/activities/list.
What this maps to: Cursor has no gateway product either, but it puts the same controls in a team dashboard rather than in a file on the machine. Team Settings > MCP Configuration (Enterprise) is the approved-server list, and it carries a per-server tool allow list, which is the closest thing either vendor documents to policy at tool granularity.
| Question | Answer | Status |
|---|---|---|
| Remote MCP servers, and over which transport | Three transports documented: stdio (local, Cursor-managed, single user), SSE, and Streamable HTTP. The last two are documented as local or remote and usable by multiple users | confirmed |
| Admin-managed list of servers | MCP Configuration in the team dashboard, Enterprise only. Servers are approved as command entries, matched against the command and args joined with spaces, or as URL entries matched against a URL pattern such as https://*.acme.com/* | confirmed |
| Policy at tool granularity | Yes. Per server, an admin can "restrict which tools can run by listing them in that server's Tools field, or leave the field empty to allow all tools from that server". Entries use server:tool with wildcards: server:tool, server:*, *:tool, *:* | confirmed |
| Precedence between settings sources | Three sources, applied in order, with a higher one replacing a lower one rather than merging: the team dashboard, ~/.cursor/permissions.json distributed by MDM, then editor settings and inline allow list additions | confirmed |
| Network restriction per server | Remote servers are restricted to the URL pattern they were approved under. Local stdio servers run sandboxed with one of "Allow all", "Allowlist", "Deny all" or "No sandbox". A User MCP Network Denylist can block destinations for servers an admin has not approved | confirmed |
| Distributing servers to a team | Dashboard > Integrations & MCP. "Add to Team Marketplace" makes a server installable from Customize in the Agent Window, the IDE and the CLI | confirmed |
Exact permissions.json schema for MCP entries | The permissions reference page was not read | unconfirmed; open question |
| How a user authenticates to a remote server | OAuth, per user, including for servers shared at team level. Static OAuth client credentials can be set in mcp.json, with the client secret optional and scopes discovered from /.well-known/oauth-authorization-server when omitted. Custom headers, env, and ${env:NAME} interpolation are also supported | confirmed |
| Audit of MCP tool calls, in the audit log | No. The documented Enterprise audit log event list contains one MCP entry, mcp_authentication, which is an authentication event. The page also states that agent responses and generated code content are not logged | confirmed |
| Per-call tool records | Available through OpenTelemetry export, which the organisation runs. Documented items include the metric cursor.tool.calls with a cursor.tool.kind attribute distinguishing builtin from MCP, the log event cursor.grok_bot.mcp_tool_call, and cursor.cloud_agent.mcp_auth_error | confirmed |
Whether the general cursor.tool.calls metric carries the server name and tool name | The OpenTelemetry export page states the builtin-versus-MCP kind attribute and does not state server or tool name attribution for that metric | unconfirmed; open question |
Their vocabulary
| Standard term | Their term |
|---|---|
| Server registry | MCP Configuration, with command entries and URL entries |
| Policy enforcement | The Tools field on an approved server; network policy; User MCP Network Denylist |
| Audit log | Audit log (configuration and authentication events), OpenTelemetry Export (per-call telemetry) |
| Fan-in to a team | Team Marketplace |
Where to look
Team Settings > MCP Configuration for the approved list and the per-server tool allow lists. Dashboard > Integrations & MCP for what a team can install. The audit log for who authenticated to what. For any question shaped as "which tool did this person call", the OpenTelemetry collector, not the dashboard.
Last verified: 2026-09-09 against https://cursor.com/docs/mcp, https://cursor.com/docs/enterprise/model-and-integration-management, https://cursor.com/docs/enterprise/compliance-and-monitoring and https://cursor.com/docs/enterprise/opentelemetry-export.