MCP Gateway quickstart
This guide walks through adding MCP Gateway features to a Zuplo project, configuring authentication, exposing one upstream MCP server, and connecting Claude Desktop. The MCP Gateway isn't a separate project type — every Zuplo project can become an MCP Gateway by adding a plugin, a couple of policies, and a route.
The example uses Linear as the upstream MCP server and Auth0 as the identity provider. The same pattern applies to any other upstream that speaks the MCP authorization spec and any OIDC-compatible identity provider. For a generic OIDC setup, see Configuring Okta.
Prerequisites
- A Zuplo project. Create one from the new project page if you don't have one already.
- An Auth0 tenant with a Regular Web Application configured. The Auth0 setup section in Configuring Auth0 covers the dashboard side.
- The
AUTH0_DOMAIN,AUTH0_CLIENT_ID, andAUTH0_CLIENT_SECRETfrom your Auth0 application.
-
Pin the compatibility date
MCP Gateway features require
compatibilityDate >= 2026-03-01inzuplo.jsonc:zuplo.jsoncExisting projects on an older date need to bump it before adding MCP features. New projects default to a recent date, so most won't need to change anything.
-
Register the MCP Gateway plugin
Add a
modules/zuplo.runtime.tsfile (or edit the existing one) and registerMcpGatewayPlugin:modules/zuplo.runtime.tsThe plugin registers the OAuth metadata, authorization endpoints, consent page, and upstream connect callbacks the gateway needs.
-
Add an MCP OAuth policy
Open
config/policies.jsonand add the Auth0 MCP OAuth policy. It authenticates inbound MCP requests against your Auth0 tenant:config/policies.jsonauth0Domainis a bare hostname (my-tenant.us.auth0.com), not a URL.Set the three environment variables on the project —
AUTH0_DOMAINin plain config andAUTH0_CLIENT_ID/AUTH0_CLIENT_SECRETin the secret store. -
Add a token-exchange policy for the upstream
Each OAuth-protected upstream gets its own
mcp-token-exchange-inboundpolicy. The policy looks up the user's upstream credential and attaches it as the upstreamAuthorizationheader. Add this entry toconfig/policies.json:config/policies.jsonauthMode: "user-oauth"means each user connects their own Linear account the first time they call the route.clientRegistration: { "mode": "auto" }lets the gateway register itself with Linear's OAuth server on demand, using OAuth Client ID Metadata Documents with a DCR fallback — no upstream client credentials need to live in source control. -
Add the route
Open
config/routes.oas.jsonand add an MCP route. The handler points at Linear's MCP server URL; the inbound policy chain attaches the OAuth policy followed by the token exchange policy:config/routes.oas.jsonoperationIdis the stable identifier for the route. It appears in analytics and is part of the per-user upstream connection key — pick it once and don't change it. -
Run the gateway
Run
zuplo devfrom the project root:CodeThe route is now reachable at
http://127.0.0.1:9000/mcp/linear-v1. Deploy when you're ready to expose it publicly; the route then lives athttps://<your-deployment>/mcp/linear-v1.A quick sanity check is to send an unauthenticated POST:
CodeThe gateway should return
401 Unauthorizedwith aWWW-Authenticateheader that points at the Protected Resource Metadata URL. If you see that, the OAuth policy is wired up correctly. -
Connect Claude Desktop
Open Claude Desktop, go to Settings → Connectors, scroll to the bottom of the list, and click Add custom connector. Paste the route URL — for the locally-running gateway, that's
http://127.0.0.1:9000/mcp/linear-v1; for a deployed gateway, use the public URL — and click Add.Claude Desktop opens the gateway's OAuth flow in a browser:
- Sign in with Auth0.
- The gateway's consent page lists Linear with a Connect button.
- Click Connect, complete Linear's OAuth flow, then click Authorize to finish.
Subsequent requests reuse the issued tokens. For per-client setup details, see Connect MCP clients.
-
Test it
In Claude Desktop, prompt the model with something that requires Linear — "list my open issues" is a good test. Claude asks for permission to call the tool, then returns results proxied through the gateway.
Open the project's Analytics dashboard and switch to the MCP tab to see the call appear in the events timeline, the success rate, the top capabilities table, and the user breakdown.
Next steps
- Connect more clients — Claude Code, Cursor, VS Code, ChatGPT, and any other MCP client.
- How it works — the request lifecycle and the two OAuth surfaces.
- Add more upstreams — front several upstream MCP servers from one Zuplo project.
- Capability filtering — curate the tools, prompts, and resources each route exposes, including description and annotation overrides.