# What is an MCP gateway, and why do agents need one? (/blog/what-is-an-mcp-gateway)

![Illustration: A small friendly robot with a round camera-eye head walks through one open doorway in a long wall.](/blog/what-is-an-mcp-gateway/hero.webp)

An MCP gateway is one remote MCP server that fronts many tools and app accounts behind a single sign-in. An agent connects to one URL, authenticates once, and receives the tools its caller is allowed to use. The gateway keeps the credentials, applies the organization's spend caps, and records every call in an audit trail.

**Nine entries, or one URL per client**

* Without a gateway: Claude Code, Codex and Cursor each carry a Notion, a Slack and a GitHub server, each with its own token. 3 × 3 = 9 entries.
* With a gateway: each client carries one entry, `https://api.corespeed.io/mcp`, and one sign-in. 3 + 3.
* The gateway holds the tokens, caps spend and records every call.
* Notion, Slack and GitHub are each connected once. The agent gets tools and never receives a token.

## What problem does an MCP gateway solve? \[#what-problem-does-an-mcp-gateway-solve]

Without a gateway, every agent client needs its own entry for every app. Claude Code gets a Notion server, a Slack server and a GitHub server. Codex gets the same three again. Cursor gets them a third time. Each entry carries its own token, its own refresh logic and its own failure mode. Five people on three clients with ten apps is 150 entries to keep correct, before anyone leaves or rotates a key.

This is the N times M problem: N clients multiplied by M apps. A gateway collapses it to N plus M. Each client registers one server. Each app is connected once, in the gateway, by whoever owns the account. The agent then sees every connected app through one URL.

CoreSpeed's gateway is `https://api.corespeed.io/mcp`. It speaks Streamable HTTP, and any client with an `mcpServers` map registers it with one entry:

```json
{ "mcpServers": { "corespeed": { "type": "http", "url": "https://api.corespeed.io/mcp" } } }
```

Claude Code takes the same server with `claude mcp add corespeed https://api.corespeed.io/mcp --transport http --scope user`. User scope matters: the entry applies to every project, so you add it once per client. The [MCP server docs](/docs/mcp) give the equivalent step for Codex, Cursor, Copilot in VS Code, OpenClaw, Hermes, claude.ai and ChatGPT.

## How does a gateway decide which tools to list? \[#how-does-a-gateway-decide-which-tools-to-list]

A gateway's `tools/list` is caller-specific. It returns exactly what this sign-in can call: the tools of the apps connected for this caller, the built-in capabilities this caller has enabled, and the `manage__*` account tools. Two members of the same organization can get different lists from the same URL, and that is the intended behavior.

Names follow the pattern `<capability>__<operation>`: `notion__create_page`, `slack__post_message`, `memory__search_memory`, `web__search`. Your organization's own MCP servers appear as `org__<slug>__<tool>`.

Read the list with three caveats. Absence is a decision: the capability is off, or the app is not connected. Presence is not health: an account in `needs_reauth` still lists its tools, and calls fail until a member reauthorizes it in Dashboard → Connectors. Presence is not permission: session-gated `manage__*` tools are listed for an API key but answer `jwt_session_required`. Never hard-code an inventory in application code. Run `tools/list` after authentication and use the names and input schemas it returns.

## Where do the credentials live? \[#where-do-the-credentials-live]

In the gateway. When a member connects Notion through CoreSpeed, the OAuth token goes into the platform's custody, is refreshed when the provider allows, and is exposed as namespaced tools. The agent calls `notion__create_page`; the platform performs the action with the right account. The agent never receives the token.

That changes what a leak costs. A prompt that talks the agent into printing its secrets finds no app token to print. Rotation happens in one place. A connection that goes stale shows as `needs_reauth`, and the member fixes it in the dashboard without touching any client config. Every connection is private, reachable only by the member who made it, or shared with the whole organization. An agent principal with an `sk-csa-` key reaches shared connections only. The [connectors docs](/docs/connectors) describe the three ways to connect: OAuth, a pasted API key, or your own OAuth app.

## How do spend caps and an audit trail attach? \[#how-do-spend-caps-and-an-audit-trail-attach]

Because every call passes through one server, every call can be priced and recorded in one place. CoreSpeed prices each metered action in credits, and each charge lands itemized in the organization ledger. Two boundaries apply. The organization wallet: past the billing threshold, later metered calls are refused before the tool runs, as a `200` response with `isError: true` and the code `payment_required`. The API key: a monthly spend cap answers `key_spend_limit_exceeded` until the month rolls over or the cap is raised. Discovery, account reads and key management keep working through both.

The activity trail records each call with its action, actor, organization, outcome (`ok`, `error`, `held` or `denied`), surface and time. Members see their own actions; org admins see the organization. API-key activity is attributed through the key's owning identity. Prompts are never copied into the trail. See [Activity and audit](/docs/activity).

| Concern       | A local server per app, per client | One gateway                               |
| ------------- | ---------------------------------- | ----------------------------------------- |
| Configuration | N clients times M apps             | N clients plus M apps                     |
| Credentials   | In each client's config or process | In platform custody; the agent gets tools |
| Tool list     | Whatever the server exposes        | What this caller may call                 |
| Spend         | Per provider account, per client   | One ledger, caps per org and per key      |
| Audit         | Per client, if any                 | One trail across every client             |

## What does a gateway not see? \[#what-does-a-gateway-not-see]

A gateway judges, meters and records only the calls routed through it. A local stdio server the agent also has installed, a shell command, or a direct HTTP call from the agent's own code never reach it. Keep that in mind when you read the trail, and keep the client's own confirmation on for writes when other MCP servers are connected alongside.

The same limit applies to policy. Smart Approval, the gate CoreSpeed puts in front of writes, covers every agent and client on the team with one rulebook, for calls made through CoreSpeed. [Introducing CoreSpeed](/blog/introducing-corespeed) explains why the organization, rather than any one agent, is the unit that owns connections, memory, budgets and the trail.

## FAQ \[#faq]

**Is an MCP gateway the same as an MCP server?**

A gateway is an MCP server. What differs is what sits behind it: many apps and accounts, with sign-in, custody, caps and audit attached.

**Do I still need local MCP servers?**

Sometimes. A single-tool local server is fine for one person on one machine. A gateway earns its place when several people, clients or apps are involved.

**Does the gateway see my agent's conversation?**

No. It sees the tool call: the tool name, the arguments and the caller's identity.

**A tool I expect is missing from `tools/list`. Why?**

The app is not connected, or the capability is off in Dashboard → Tools. An agent key also reaches shared connections only, so a private connection never appears to it.