An MCP gateway is a proxy that sits between your AI clients and a set of MCP servers. To Claude, Cursor or your own agent it looks like one MCP server with one URL. Behind that URL it acts as an MCP client to many upstream servers, merges their tools into one list, and applies the policies you care about: who can call what, which credentials go where, and what gets logged.
That is the whole idea. The details matter more than the definition, though, and many of the pages ranking for "mcp gateway" skip the hardest one: what happens to OAuth when the upstream server is somebody else's remote service. This guide covers what gateways do, how the main open-source and managed options differ, what we saw when we put an open-source gateway in front of DialMCP's own OAuth-protected endpoint, and the cases where you don't need a gateway at all.
What an MCP gateway is (and what the spec says about it)
The Model Context Protocol itself has no gateway concept. The architecture page of the current spec (revision 2026-07-28) defines three roles: hosts, clients and servers. A host runs one client per server connection. The word "gateway" appears only in passing, as an example of an intermediary. The Streamable HTTP transport lists gateways among the intermediaries that can read the Mcp-Method and Mcp-Name headers to route requests without parsing the JSON body, and the caching rules mention a "shared gateway" that may cache responses. Neither defines a gateway role.
So a gateway is not a new protocol role. It is a product category built from the existing roles:
- Facing your clients, the gateway is an MCP server. It exposes a single endpoint, usually Streamable HTTP, sometimes stdio.
- Facing the upstream servers, it is an MCP client. It connects to each one, lists their tools, and forwards
tools/callrequests.
MCP's official security best practices guide does describe something close. It calls it an "MCP Proxy Server": a server that connects MCP clients to third-party APIs while "acting as a single OAuth client to the third-party API server." Keep that phrase in mind. It explains most of the security rules later in this article.
What an MCP gateway does
Gateway products bundle different features, but most include some mix of these:
- Aggregation. Several servers appear as one endpoint. Tool names usually get a prefix so two servers'
searchtools don't collide. Agent Router (formerly Envoy AI Gateway), for example, renames a GitHub tool togithub__issue_read. - Virtual servers or profiles. You pick a subset of tools from several upstreams and publish them as a new server for one team or one agent. Docker calls these profiles, IBM ContextForge calls them virtual servers, and Obot calls them virtual MCPs (vMCPs).
- Inbound authentication. The gateway checks who the caller is (API key, JWT, OAuth, a corporate identity provider) before any tool runs.
- Authorization and tool allowlists. Role-based rules decide which user or client can see and call which tools.
- Upstream credentials. The gateway holds the keys or tokens for the servers behind it, so individual laptops don't have to.
- Audit logs and tracing. Every tool call passes through one place, which makes it the natural spot for logs and OpenTelemetry traces.
- Rate limits and quotas, often inherited from an existing API gateway.
- Transport bridging. A local stdio server can be exposed over HTTP, or an HTTP server over stdio for clients that only launch local processes.
- Hosting. Some gateways also start and supervise the servers, as containers or Kubernetes workloads.
That list fits one situation well: many people, many servers, and a security team asking what the agents can touch.
MCP gateway vs MCP server
A gateway is an MCP server, technically. The difference is what sits behind it.
| Local MCP server | Hosted remote MCP server | MCP gateway | |
|---|---|---|---|
| What it is | A process your client launches over stdio | A single-purpose service at an HTTPS URL | A proxy that fronts many servers |
| Who runs it | You, on your machine | The vendor | You or your platform team (or a cloud provider) |
| Tools come from | Its own code | Its own code | Upstream servers |
| Credentials | Environment variables | OAuth to that one service | Held or brokered by the gateway |
| Typical example | A filesystem or git server | DialMCP at https://mcp.dialmcp.com/mcp | Docker MCP Gateway, IBM ContextForge |
A hosted remote server does one job and owns its own authorization. A gateway doesn't do any job itself. It governs access to servers that do. Plenty of teams need both: a gateway for internal servers, plus a few vendor-hosted servers connected directly or registered behind the gateway. For the difference between local and remote servers in more depth, see remote MCP servers explained.
The hard part: OAuth to remote servers behind a gateway
Aggregating local stdio servers is simple. The gateway starts them and passes them environment variables. Remote third-party servers are harder, because many of them use OAuth with a per-user browser sign-in. GitHub's, Notion's and DialMCP's remote servers all support (and DialMCP's requires) a per-user OAuth sign-in in the browser.
A gateway that merges those servers into one endpoint runs into a structural problem. The documentation for agentgateway, a Linux Foundation project, states it plainly: "A client that connects to one federated endpoint has no way to run a separate authorization flow for every upstream server behind it." Its advice is to expose such servers on separate paths instead of multiplexing them.
The obvious shortcut is to take the token the client sent to the gateway and forward it upstream. The spec rules that out. The authorization spec requires servers to validate that access tokens were issued for them, and says: "MCP servers MUST NOT accept or transit any other tokens." The security best practices name the pattern "token passthrough," call it "explicitly forbidden," and add that proxy servers "MUST implement per-client consent" to avoid confused-deputy attacks. In a confused-deputy attack, a proxy with broad upstream access is tricked into using that access on behalf of the wrong client.
Gateway products use one of four credential models for upstreams:
| Model | How it works | Documented by |
|---|---|---|
| Per-user token vault | Each user runs the upstream OAuth flow once, through the gateway. The gateway stores that user's token and attaches it to their calls. | IBM ContextForge, Cloudflare MCP server portals (on_behalf), Obot, Amazon Bedrock AgentCore Gateway (authorization code) |
| Token exchange | The gateway trades the caller's token for a new one issued to the upstream (RFC 8693), so the upstream never sees the original. | agentgateway, Kong (v3.14+), Obot, Amazon Bedrock AgentCore Gateway |
| Static shared credential | One API key or header per upstream, used for every caller. Simple, but every user acts as the same identity. | Microsoft MCP Gateway (Key Vault headers), MCPJungle, Agent Router, agentgateway |
| Header forwarding | The caller supplies an upstream credential, such as a personal access token, and the gateway forwards that header. | Agent Router, Azure API Management |
The static model is fine for an internal server that should act as a service account. It is the wrong fit for a server where identity is the product. With DialMCP, the verified phone number you sign in with becomes the caller ID on every call you authorize. A shared credential behind a gateway would put every user's calls on one person's number. That is exactly what the per-user model exists to prevent.
What happened when we put a gateway in front of DialMCP
We tested how an open-source gateway treats a real OAuth-protected remote server. On September 29, 2026, we ran IBM ContextForge locally (version 1.0.7 of the mcp-contextforge-gateway package, as installed from PyPI with uvx) (1.0.11 has since been released; we have not re-tested it) and registered https://mcp.dialmcp.com/mcp as an upstream.
- Without credentials, registration failed. ContextForge connects to the upstream when you register it. DialMCP answered
401 Unauthorizedwith aWWW-Authenticateheader pointing at its protected resource metadata, and the gateway returned a 502: "Failed to initialize gateway … 401 Unauthorized." - The OAuth config tripped SSRF protection first. Our first
auth_type: oauthregistration came back 422 because the redirect URI waslocalhost, which ContextForge blocks by default. A hostname that didn't resolve failed the same way. For a local test we setSSRF_ALLOW_LOCALHOST=true. In production you would use the gateway's real public callback URL. - With OAuth configured, registration succeeded with zero tools. We gave it the grant type
authorization_codeand the issuerhttps://mcp.dialmcp.com. ContextForge found DialMCP's/authorizeand/tokenendpoints through RFC 8414 metadata, noted that dynamic client registration was available, and saved the gateway withtoolCount: 0. That is by design: for authorization-code upstreams it waits until a user signs in, then stores tokens per gateway and per user. - The sign-in redirect was spec-shaped. Starting the per-user flow produced a redirect to DialMCP's authorize endpoint with a freshly registered
client_id, PKCE withcode_challenge_method=S256, and an RFC 8707 resource indicator. DialMCP served its normal "Sign in · dialmcp" page.
We stopped at the sign-in page, since finishing it needs an SMS-verified phone, so we have not verified the full tool list through the gateway. Two details are still worth knowing if you put any OAuth server behind a gateway:
- ContextForge sent
resource=https://mcp.dialmcp.com, while DialMCP's metadata advertiseshttps://mcp.dialmcp.com/mcp. The spec lists both as valid canonical URIs, but says clients SHOULD send "the most specific URI that they can." If an upstream rejects tokens after a gateway login, compare these two values first. - The gateway registered itself with dynamic client registration. The 2026-07-28 spec deprecates that in favor of Client ID Metadata Documents. It still works wherever the authorization server supports it, as DialMCP's does today, but check that your gateway and your upstreams agree on a registration method.
To poke at an OAuth server the same way without a gateway, the MCP Inspector walkthrough covers the same 401 and metadata checks from the client side.
Open-source MCP gateways compared
"Open source" covers very different tools, from a single-developer CLI to a Kubernetes control plane. Here is how the main ones compare on the points above. Licenses come from each project's GitHub repository as of September 29, 2026.
| Gateway | License | Runs as | Upstream credentials |
|---|---|---|---|
| Docker MCP Gateway | MIT | Docker CLI plugin, local | Secrets and OAuth tokens in Docker Desktop or the OS credential store, single user |
| IBM ContextForge | Apache-2.0 | Python app, Docker or Kubernetes | Per-user encrypted OAuth tokens, static headers |
| agentgateway | Apache-2.0 | Standalone binary or Kubernetes controller | Static per-target keys, token exchange; per-user OAuth on separate paths |
| Microsoft MCP Gateway | MIT | Kubernetes | Static headers from Azure Key Vault, Entra ID for callers |
| Obot | MIT | Self-hosted platform on Docker or Kubernetes | Per-user credentials and token exchange |
| MCPJungle | MPL-2.0 | Self-hosted server | Static bearer token or headers; its README says OAuth support is "coming soon" |
| Lasso MCP Gateway | MIT | Local Python proxy | Not documented; focus is guardrail plugins that mask secrets and PII |
A quick guide to which one fits:
- One developer who wants isolation and a catalog: Docker MCP Gateway.
- A team that wants per-user OAuth and virtual servers without a cloud vendor: ContextForge or Obot.
- A platform team already running Kubernetes Gateway API or Envoy: agentgateway or Agent Router.
- An Azure and Entra ID shop running its own servers on AKS: Microsoft MCP Gateway.
Docker MCP Gateway
Docker's gateway is the docker mcp CLI plugin behind Docker Desktop's MCP Toolkit. It runs catalog servers in isolated containers and exposes them through one endpoint:
docker mcp gateway run
docker mcp gateway run --port 8080 --transport streaming
The default transport is stdio, which suits a single client on your laptop. The streaming transport serves several clients, and Docker's security notes say the HTTP transports require a bearer token by default (MCP_GATEWAY_AUTH_TOKEN). Remote servers with OAuth are authorized through the CLI, for example docker mcp oauth authorize notion-remote, and the token lands in your local credential store. It is a strong single-user tool. Docker's docs note that "MCP Gateway as part of Docker AI Governance is an invite-only feature," and the open-source README doesn't document multi-user RBAC. For containerizing your own server rather than running a catalog, see deploying an MCP server with Docker.
Managed MCP gateways
If you already run an API gateway or a cloud identity stack, the gateway may already be a feature you pay for:
- Amazon Bedrock AgentCore Gateway combines MCP targets, Lambda functions and OpenAPI specs into one virtual MCP server, with OAuth or IAM for inbound calls. Its outbound-auth table lists "Token passthrough: No" for MCP server targets.
- Azure API Management can expose a REST API as an MCP server or pass through an existing one. External servers must support MCP 2025-06-18 or later, and prompts aren't supported for them.
- Cloudflare MCP server portals put several servers behind one URL under Cloudflare Access. Users are "prompted to authenticate separately to each server that requires OAuth."
- Kong AI Gateway offers MCP proxying through its AI MCP Proxy plugin, which is only available with AI Gateway Enterprise, and through the newer AI MCP Server entity in AI Gateway 2.0. Its AI MCP OAuth2 plugin, in tech preview, "does not pass access tokens to upstream services" and supports token exchange from v3.14.
We haven't listed prices, because they depend on tier and usage. Check each vendor's current pricing page.
What the 2026-07-28 spec changed for gateways
Several ranking articles describe session affinity, meaning pinning a client to the same backend for the life of a session, as a core gateway job. That was true when MCP had sessions. The 2026-07-28 revision made the protocol stateless. It removed the initialize handshake and the Mcp-Session-Id header, and every request now carries its own version and capabilities. The new required Mcp-Method header, plus Mcp-Name on tools/call, resources/read and prompts/get, lets intermediaries route without reading bodies.
For gateway buyers, session stickiness now matters only for older clients and servers, and routing on headers is simpler to scale than parsing every body. Check which protocol revisions a product supports on each side. Cloudflare's portal docs, for example, explicitly list stateless 2026-07-28 support alongside earlier 2025 clients.
When you don't need an MCP gateway
A gateway is infrastructure. It adds a service to run, a place for credentials to leak from, and one more hop on every tool call. You probably don't need one if:
- You are one person with a handful of servers. Your client already runs one connection per server, and stdio servers read their credentials from your environment. A gateway would be managing a problem you don't have.
- Your client supports remote OAuth natively. Claude, ChatGPT (in Developer mode on paid plans), Cursor, VS Code and Codex can all connect to a remote URL and run the sign-in themselves. For a vendor-hosted server like DialMCP, connecting the URL directly keeps the OAuth relationship between you and the service, with no token broker in the middle.
- Your pain is tool-list size, not governance. The MCP client best practices describe progressive tool discovery and code mode as client-side answers to tool bloat.
- The server is single-purpose and already enforces its own rules. A gateway's rate limits and allowlists add little when the server already enforces tighter ones itself.
You probably do want one when several people share servers, when security needs one audit trail, or when internal servers must not be reachable from laptops. Before you pick one, ask two questions: which credential model does it use for your per-user OAuth upstreams, and does it ever forward caller tokens upstream? It shouldn't, unless the upstream issued them.
Where DialMCP fits
DialMCP is not a gateway. It is one hosted, single-purpose MCP server: it lets your agent place real phone calls from your own verified number and returns a transcript and outcome. Its four tools are small enough that tool-list bloat isn't an issue. Its limits, disclosure and opt-out rules are enforced server-side, as the safety page explains, whichever client or gateway sits in front.
Most people should connect it directly, using the hosted endpoint. If your organization routes all MCP traffic through a gateway, register DialMCP with a per-user OAuth model so each person signs in with their own number. The OAuth docs describe what that sign-in involves.
Further reading
- Remote MCP servers explained
- The best remote MCP servers
- MCP Inspector: test a local or remote server
- DialMCP's hosted endpoint
- DialMCP OAuth and phone verification
- MCP authorization spec (2026-07-28)
- MCP security best practices
- agentgateway: MCP configuration modes
Need your agent to make a phone call? DialMCP is one hosted MCP server, no gateway required. Add https://mcp.dialmcp.com/mcp to your client, sign in with your own mobile number, and your agent can place calls from it.
FAQ
What is an MCP gateway?
An MCP gateway is a proxy that presents many MCP servers to AI clients as one endpoint. It is an MCP server to the client and an MCP client to each upstream, and it usually adds authentication, tool allowlists, credential handling and logging. The MCP spec doesn't define gateways; they are built from its host, client and server roles.
What is the difference between an MCP gateway and an MCP server?
An MCP server provides tools itself. A gateway provides no tools of its own; it aggregates and governs the tools of servers behind it. To the client, both look like an MCP server at a URL.
Is there a good open-source MCP gateway?
Several. Docker MCP Gateway (MIT) suits single developers. IBM ContextForge (Apache-2.0) and Obot (MIT) support per-user OAuth for teams. agentgateway (Apache-2.0, a Linux Foundation project) and Agent Router (formerly Envoy AI Gateway) suit Kubernetes platform teams. Microsoft's MCP Gateway (MIT) targets Kubernetes with Entra ID.
Can an MCP gateway forward my OAuth token to the upstream server?
It shouldn't. The MCP authorization spec says servers "MUST NOT accept or transit any other tokens," and the security guidance forbids token passthrough. Well-designed gateways store a separate per-user token for each upstream or use token exchange instead.
Is an MCP gateway the same as an MCP aggregator?
Aggregation, merging several servers' tools into one list, is one feature of most gateways. A pure aggregator does only that. A gateway usually adds authentication, authorization, credentials and audit on top.
Do I need a gateway to use a remote MCP server like DialMCP?
No. Any client that supports remote MCP can connect to https://mcp.dialmcp.com/mcp directly and run the OAuth sign-in itself. A gateway only makes sense if your organization already routes MCP traffic through one, and then it should use per-user OAuth.