MCP Gateways
If you sell MCP to other companies, agents rarely talk to one server with one set of credentials. They hit your own tools, a customer's HubSpot, a remote Linear server, sometimes a different environment per tenant. An MCP gateway is the one URL those agents actually connect to. It decides which downstream server to call, and which credential to use.
This page covers how that setup works. For what teams build with it, like per-customer tools or auditing tool calls, see MCP Gateway Use Cases. If you are protecting a single MCP server, start with the MCP overview and the MCP server guide.
If pre-built clients inside your company should reach third-party tools with nothing in the middle, look at Cross App Access first.
Why a Gateway
Without one, every agent needs a token for every backend, and customer secrets end up in client config.
The gateway is the Resource the agent authenticates to. Behind it, downstream services come in two kinds:
- Services Descope doesn't protect (HubSpot, Google, a partner API). Their OAuth tokens and API keys live in Connections.
- Your internal APIs and MCP servers that Descope does protect. Each one is its own Resource with its own audience.
Either way, the agent's token only works at the gateway. When a tool call needs a downstream service, the gateway exchanges that token with Descope. For an internal Resource, it gets a new JWT whose aud is that API. For a third-party service, it gets the Connection credential.
Policies decide which agent, for which tenant, may use which server and scopes.
How Descope Fits
Descope can be the identity provider for a gateway you already run, or it can be the gateway.
| Role | Who terminates MCP | What you configure in Descope |
|---|---|---|
| Identity provider for your gateway | Your own proxy, or something like Azure AI Gateway, Kong AI Gateway, Portkey, Golf.dev, or agentgateway | Login, consent, an MCP Server Resource for the gateway, Clients, Policies, and Connections |
| Descope Agent Gateway (early access) | Descope | The same identity model, plus routes to different MCP servers. A route can be for one tenant or for everyone who uses the gateway |
Note
The Descope Agent Gateway is in early access. This feature must be deployed in your own infrastructure, and can be exposed to your external customers.
Please reach out to Descope Support, for more details. For creating gateways and routes in the Console, see Gateways.
In either case, the agent's token is only ever minted for the gateway itself, not for every backend the gateway can reach.
When Descope is only the IdP, the gateway simply validates Descope JWTs (issuer, JWKs, aud, scope) and then the gateway can perform token exchange or connection token fetching calls to provide to downstream servers.
How Much of the Stack Descope Protects
You don't have to put every backend behind Descope on day one. The gateway is the only thing that has to validate Descope tokens. What happens behind it is up to you, and most teams move through the same three stages.
Stage 1: Protect the Gateway Only
Model the gateway as a Resource and let Descope handle inbound auth: login, consent, CIMD/DCR, and policies for both user-delegated (authorization code) and machine-to-machine (client credentials) access. Once the gateway accepts the token, your own STS, or whatever auth your downstream services already use, takes over. It's the smallest change, and you still get a first layer of control over which agents and users reach the gateway at all.
Descope decides who gets into the gateway. Everything to the right of the gateway is still yours to secure, store, and refresh.
Stage 2: Add Credential Management
Store the tokens your downstream services depend on in Connections: external OAuth tokens (HubSpot, Google, Slack) and static API keys, per user or per tenant. The gateway pulls them at tool time with token exchange, and Descope handles refresh, so you aren't running a token store next to the gateway.
The secret store is gone. Third-party credentials come out of Descope, scoped to the user or tenant on the inbound token. Internal APIs still use whatever auth they had before.
Stage 3: Protect Your Backends as Resources
As internal APIs and MCP servers move onto Descope, give each one its own Resource and audience. The gateway exchanges the inbound token for a token minted for that backend, with only the scopes policy allows. Every hop becomes its own grant in the audit log instead of a shared secret.
The gateway makes the same exchange call for both targets. Only the resource parameter changes, and the billing API validates a Descope JWT minted for its own audience.
We recommend starting with the first two together: the Agentic Identity Hub for inbound auth to the gateway, and Connections for downstream credentials. That way you never store or refresh tokens yourself.
Then move internal services onto Resources as you get to them. The gateway code barely changes between stage 2 and stage 3, because it was already calling token exchange.
Architecture
The rest of this page describes the full version, where backends you own are Resources too. Create an MCP Server Resource whose audience is the gateway URL. MCP clients discover that Resource, register with CIMD or DCR, and log in against Descope. The access token's aud is the gateway, not HubSpot and not your billing API.
The gateway is also a Client. After it validates the inbound token, it should not forward that JWT to a server that expects a different audience. It exchanges at the Descope token endpoint (RFC 8693) and gets back either:
- A Connection credential (vaulted OAuth token or API key) for a third-party MCP server or API
- A Resource token with a different
audfor an MCP server or API you protect with Descope
A policy with grant type Delegated access (token exchange) has to allow that hop. Token exchange never shows a consent screen. Why passthrough is usually the wrong move, and how Resource vs Connection targets differ, is in Downstream credential access and Calling external APIs from MCP tools.
That is the same working model as the Hub: the agent authenticates to a Resource, and the Resource pulls secrets from Connections at runtime. The agent never holds the third-party credential.
Don't put every downstream audience on the inbound gateway token. The agent holds a gateway-scoped token. The gateway exchanges it at tool time, so each hop is policy-checked and audited.
For how this plays out with multiple customers, mixed internal and third-party servers, and tool-call auditing, see MCP Gateway Use Cases.
Token Exchange on the Gateway Path
The agent gets its first token with an authentication grant (authorization code, client credentials, JWT bearer, and similar). Token exchange is the second step: retarget that token to a Resource or Connection. It is always on at the project token endpoint. There is no per-app toggle. A Delegated access (token exchange) policy has to allow the subject, target, and scopes.
Register a Client for the gateway (or for each internal MCP server that performs exchanges). Enable client credentials on that Client. Put client_id and client_secret on the gateway, not in the MCP client.
At tool execution the gateway posts to the token endpoint:
POST /oauth2/v1/apps/token
Authorization: Basic {base64(gateway_client_id:gateway_client_secret)}
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&subject_token={inbound_access_token}
&subject_token_type=urn:ietf:params:oauth:token-type:access_token
&resource={resource_url_or_connection_id}resource picks the path. A Descope Resource URL returns a JWT for that audience. A Connection id returns the vaulted credential. The Python MCP SDK can do this exchange from tool handlers.
Using Descope as the IdP for Another Gateway
If the product can validate an OIDC JWT against a JWKS, it can sit in front of your MCP servers with Descope as the authorization server. Model the gateway as an MCP Server Resource so CIMD/DCR, consent, and agent inventory stay in the Hub.
Point it at:
- JWKS:
__BaseURL__/__ProjectID__/.well-known/jwks.json(OIDC endpoints) - Issuer: the MCP Server Issuer URL from Usage Samples
- Audience: the gateway Resource URL
- Scopes: the MCP Server scopes you defined for the gateway, read from the token's
scopeclaim
Scopes are what let the gateway do more than a yes/no check. The token only carries the scopes the user consented to and policy allowed, so the gateway can require mcp:read on one route or tool and a write scope on another. Most of the gateways below can match on scope directly, for example Portkey's claimValues, Kong consumer ACLs, or an APIM validate-jwt required claim.
Note
If you need perform introspection, you can call the /userinfo endpoint, or the /introspection endpoint to retrieve the latest roles and permissions for a particular user or client.
After it accepts the inbound token, still exchange instead of forwarding that JWT everywhere. Kong's AI MCP OAuth2 plugin and Azure APIM policies can strip or swap the credential on the way out. That is the same audience split as Architecture.
MCP-Aware Gateways
These terminate MCP (or proxy it to HTTP) and can use Descope as the IdP.
| Gateway | How it talks to Descope | Where to start |
|---|---|---|
| Azure AI Gateway | Azure API Management (including the AI Gateway tier) validates inbound JWTs with validate-jwt against Descope's JWKS. Microsoft's MCP samples often show Entra's validate-azure-ad-token. For Descope, use generic validate-jwt. | Secure MCP servers in API Management, Descope JWTs with APIM |
| Kong AI Gateway | The AI MCP OAuth2 plugin implements MCP OAuth. Set jwks_endpoint to Descope's JWKS. Kong's cookbooks show Okta, Keycloak, Entra, Auth0, Cognito, and Google. Descope is that JWKS path, not RFC 7662 introspection. The plugin can also swap the inbound token before calling upstream. | Secure an internal MCP gateway, Authenticating Kong Gateway with Descope |
| Portkey | Portkey validates the Descope JWT, then forwards claims to downstream MCP servers. | Descope + Portkey |
| Golf.dev | Golf.dev enforces Descope roles and scopes at MCP method and tool granularity. | Descope + Golf.dev |
| agentgateway | agentgateway calls Descope as the policy decision point on each request. | Enforce with a Gateway |
| TrueFoundry MCP Gateway | Inbound auth includes an identity-provider JWT (their docs show Okta, Auth0, and Entra). Point that check at Descope's issuer and JWKS. | TrueFoundry MCP Gateway |
| LiteLLM | LiteLLM validates JWTs via JWT_PUBLIC_KEY_URL (JWKS or OIDC discovery), with optional JWT_ISSUER and JWT_AUDIENCE. | LiteLLM OIDC JWT auth |
Anything else that verifies RS256 JWTs from a JWKS, checks iss and aud, and keeps CIMD/DCR pointed at Descope works the same way.
API Gateways in Front of MCP
Some teams terminate TLS and JWT validation on a general API gateway, then forward MCP to a backend. The same JWT authorizer pages apply: Azure API Management, AWS API Gateway, GCP API Gateway, Google Apigee, and Kong Gateway (OpenID Connect or JWT plugin, not only the AI Gateway SKU).
Use a JWT template when the gateway expects a fully qualified iss URL. The Azure and AWS templates in the Console do that.
Next Steps
Create an MCP Server Resource for the gateway and a Client it uses for exchanges. Write Policies for consent and Delegated access (token exchange), and store per-tenant secrets in Connections. Implement the exchange in tool handlers with Downstream credential access or the MCP SDKs.
If you're serving multiple customers, MCP Gateway Use Cases covers tenant-scoped Connections, policies, and one MCP server per customer. If customers bring their own workforce IdP, add XAA on the tenant. For the Descope Agent Gateway, contact Descope Support to enable it, then create your gateway and routes on the Gateways page.
Python MCP SDK
Learn how to use the Descope Python MCP SDK to integrate authentication, authorization, and connection token retrieval with your MCP servers.
Use Cases
Common ways to use an MCP gateway with Descope, including per-customer B2B tools, mixing your own and third-party MCP servers, and governing tool calls.