# MCP Gateway

The Zuplo MCP Gateway fronts one or more remote
[Model Context Protocol](https://modelcontextprotocol.io) (MCP) servers with a
single, OAuth-protected endpoint that AI clients connect to. Users sign in once
through your identity provider, the gateway brokers credentials to each upstream
server, and every tool call lands in your analytics — without raw tokens ever
reaching the AI client.

## What it does

The gateway sits between MCP clients (Claude Desktop, Claude Code, ChatGPT,
Cursor, VS Code, and any other client that speaks the MCP authorization spec)
and the upstream MCP servers your team relies on (Linear, Notion, Stripe,
GitHub, Slack, internal services, and so on).

For each MCP request, the gateway:

- Authenticates the user through your existing OAuth or OIDC identity provider —
  Auth0, Okta, or any RFC 8414 / OIDC discovery-compatible authorization server.
- Issues its own short-lived bearer token bound to a specific MCP route, so no
  upstream token is ever exposed to the client.
- Resolves the right upstream credential per user. For OAuth-protected
  upstreams, each user goes through a one-time consent and the gateway stores
  their per-upstream tokens encrypted at rest.
- Optionally curates the set of tools, prompts, and resources each route
  exposes, so an agent only sees the capabilities you've approved.
- Emits structured analytics events for every tool call, capability list, auth
  event, and upstream proxy hop.

## Why use it

Without a gateway, every MCP server an employee connects to is its own silo —
its own OAuth flow, its own audit trail (or none), its own surface area for
prompt injection or token misuse. A few problems compound quickly:

- **Shadow MCP.** Employees connect Claude, Cursor, and ChatGPT to third-party
  MCP servers faster than security teams can review them.
- **Scattered OAuth.** Every MCP server prompts for a separate browser login;
  users paste raw tokens into AI clients to make things work.
- **Audit gaps.** The MCP spec defines no log format, no per-user attribution,
  no SIEM hook.
- **Tool sprawl.** Agents that mount every MCP server they can find end up with
  hundreds of tools, which floods the context window and degrades model
  performance.

The MCP Gateway addresses each of these by putting the gateway in front of every
upstream MCP server and producing one auditable trail.

## The five problems an MCP Gateway solves

Every gateway feature maps to one of five problems that show up the moment a
team uses more than one or two MCP servers:

1. **Discovery.** A single catalog of approved MCP servers your developers and
   agents can connect to. No more sharing OAuth client IDs in Slack.
2. **Authentication.** Translation from your corporate SSO to whatever each
   upstream MCP requires — OAuth, API key, or anything in between. MCP client
   config files no longer hold raw upstream credentials.
3. **Authorization.** Curate which tools each route exposes. A read-only view of
   Stripe and a full-power view of the same upstream is a configuration change,
   not a separate deployment.
4. **Observability.** Every tool call, capability list, and auth event is
   structured-logged and visible in the analytics dashboard.
5. **Guardrails.** Compose the gateway with Zuplo's PII redaction, prompt
   injection detection, and other security policies. The MCP traffic runs
   through the same policy engine your REST APIs already use.

## Two ways the gateway is used

The same product solves two distinct shapes of problem:

- **Inside-out** — governing how your own employees and internal agents reach
  third-party MCP servers (Linear, Notion, Stripe, Grafana, Slack, and dozens of
  others). This is how Zuplo's own team uses the MCP Gateway day to day: every
  internal MCP call from every employee goes through one gateway.
- **Outside-in** — publishing your own MCP server to external consumers with the
  same OAuth, rate limiting, audit, and analytics surface you'd expect from any
  modern API.

Both flows use the same configuration model and the same policy engine.

## Part of API Management

The MCP Gateway isn't a separate product. It's a set of policies and a route
handler that run inside the same Zuplo platform that runs your REST and GraphQL
APIs. A project gets MCP Gateway functionality by adding the `McpGatewayPlugin`,
an MCP OAuth policy, and one MCP route per upstream — the same OpenAPI-as-config
model, the same deployment and observability primitives, applied to MCP traffic.
If your team already uses Zuplo, every existing skill and integration carries
over.

## Who it's for

- **Platform teams** that want to ship a single, governed MCP endpoint to
  developers and let them connect their preferred AI clients.
- **Security and IT teams** that need SSO, audit logs, and the ability to curate
  tool exposure.
- **Anyone building agents** that need to call multiple upstream MCP services
  without managing per-server credentials in client config files.

## MCP Gateway vs. the MCP Server handler

Zuplo offers two distinct MCP features. They solve different problems and can
live in the same project.

| Feature                                              | What it does                                                                                            | When to use it                                                                                                        |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| **MCP Gateway**                                      | Proxies traffic to one or more upstream MCP servers. Handles OAuth, capability curation, and analytics. | You want to expose existing MCP servers (Linear, Stripe, internal services, etc.) to AI clients through one endpoint. |
| **[MCP Server handler](../handlers/mcp-server.mdx)** | Turns your OpenAPI routes into an MCP server. Each route becomes an MCP tool, prompt, or resource.      | You want to expose your own API as MCP so AI clients can call it as tools.                                            |

If you maintain your own REST or GraphQL API and want AI agents to use it, reach
for the MCP Server handler. If you want a single front door to a set of MCP
servers that already exist, this is the right product.

## Architecture

```mermaid
flowchart LR
  subgraph clients[MCP Clients]
    A[Claude Desktop]
    B[Cursor]
    C[ChatGPT]
  end

  subgraph gateway[Zuplo MCP Gateway]
    direction TB
    R["MCP route /mcp/&lt;name&gt;"]
    AUTH[OAuth 2.1 AS + RS]
    FILTER[Capability filter]
    TX[Per-user token store]
  end

  subgraph upstream[Upstream MCP Servers]
    L[Linear]
    N[Notion]
    S[Stripe]
  end

  IDP[OIDC Identity Provider]

  A -->|Bearer token| R
  B -->|Bearer token| R
  C -->|Bearer token| R
  R --> AUTH
  R --> FILTER
  FILTER --> TX
  TX -->|Per-upstream token| L
  TX -->|Per-upstream token| N
  TX -->|Per-upstream token| S
  AUTH <-->|Browser login| IDP
```

Each client connects to one or more MCP routes on the gateway. Each route is a
path in `routes.oas.json` that uses the `McpProxyHandler` and points at one
upstream MCP server, optionally with a curated subset of its capabilities. The
gateway is built on the standard MCP authorization spec, so any spec-compliant
MCP client discovers and authenticates against it without custom configuration.

## What you get today

- A code-configured gateway that drops into any Zuplo project: add the
  `McpGatewayPlugin`, declare an OAuth policy, and add one route per upstream
  MCP server.
- An OAuth 2.1 authorization server that implements RFC 9728 Protected Resource
  Metadata, RFC 8414 Authorization Server Metadata, OpenID Connect discovery,
  RFC 7591 Dynamic Client Registration, OAuth Client ID Metadata Documents, and
  PKCE.
- Per-user OAuth federation to upstream MCP servers with automatic token
  refresh, plus an optional shared-OAuth mode for service-account-style
  connections.
- An optional `mcp-capability-filter-inbound` policy for per-route curation of
  tools, prompts, resources, and resource templates — including description and
  annotation overrides.
- A built-in analytics dashboard covering events, success rate, latency,
  capability volume, failure origins, and user-level breakdowns.

The gateway implements the MCP authorization spec at revision
[`2025-11-25`](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization),
which is the current revision at the time of writing.

## Next steps

- [Quickstart](./quickstart.mdx) — add the MCP Gateway plugin to a Zuplo
  project, configure an OAuth policy, expose one upstream MCP server, and
  connect Claude Desktop.
- [How it works](./how-it-works.mdx) — the request lifecycle, the two OAuth
  surfaces, and the configuration model.
- [Reference](./reference.mdx) — the full URL catalog, default TTLs, and
  configuration constants.
- [Troubleshooting](./troubleshooting.mdx) — symptoms, likely causes, and fixes
  for the common issues.
