Configuring Logto
The MCP Gateway can use Logto as the identity provider
behind its downstream OAuth flow. The mcp-logto-oauth-inbound policy is a
Logto-friendly wrapper around the generic mcp-oauth-inbound policy: provide
your Logto tenant endpoint, a client ID, and a client secret, and the policy
derives the OIDC issuer, JWKS URL, and authorize and token URLs from Logto's
/oidc mount point.
This guide walks through the Logto console setup, then wires the policy into a gateway project. Read the authentication overview first for the two-layer OAuth model.
Set up Logto
The MCP Gateway acts as an OAuth 2.1 authorization server in front of Logto. Logto handles browser login; the gateway issues its own access tokens that bind to MCP routes.
Create a Traditional Web application
- In the Logto Console, open Applications and click Create application.
- Pick Traditional Web as the application type. (Not SPA, not Native — the gateway needs a confidential client with a secret.)
- Give the application a name (for example,
Zuplo MCP Gateway) and click Create application. - On the application's Settings tab, set Redirect URIs to
https://<gateway-host>/oauth/callback. Addhttp://localhost:9000/oauth/callbackfor local development. - Save.
Note the App ID (= client ID) and App secret (= client secret) from the application's detail page.
Find your tenant endpoint
Open Settings → Domains in the Logto Console. Your default tenant endpoint
looks like https://your-tenant.logto.app. If you've configured a custom
domain, use that instead. The wrapper takes the origin only — no /oidc, no
.well-known/..., no trailing slash.
Wire the policy into the gateway
Add the policy to config/policies.json:
Code
Attach the policy to each MCP route in config/routes.oas.json and register the
gateway plugin in modules/zuplo.runtime.ts (see
Configuring Auth0
for the route and plugin patterns — they're identical across all wrappers).
What the wrapper derives
Given logtoEndpoint: "https://acme.logto.app":
| Generic field | Derived value |
|---|---|
oidc.issuer | https://acme.logto.app/oidc |
oidc.jwksUrl | https://acme.logto.app/oidc/jwks |
browserLogin.url | https://acme.logto.app/oidc/auth |
browserLogin.tokenUrl | https://acme.logto.app/oidc/token |
These endpoint shapes come from Logto's OIDC provider mounted at /oidc and its
discovery document at
https://<your-logto-endpoint>/oidc/.well-known/openid-configuration.
Test the configuration
The fastest sanity check is to connect an MCP client:
- Open Claude Desktop, Cursor, Claude Code, or another OAuth-aware MCP client.
- Add a remote MCP server pointing at one of your
/mcp/{slug}routes. - The client should redirect you to the Logto sign-in page. After login, the gateway's consent screen renders. Approve it.
- The client receives an access token and can call
tools/list.
If something fails partway through, walk the flow manually using the
manual OAuth testing guide — it exercises every
endpoint with curl so you can see the raw responses.
Common issues
logtoEndpointrejected at boot. The value includes/oidc,/.well-known/openid-configuration, or another path. Use the bare tenant endpoint origin.redirect_urirejected by Logto. The redirect URI on the application doesn't matchhttps://<gateway-host>/oauth/callback. Match scheme, host, and path.