zuplo 6.70.53 → 6.70.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/docs/mcp-gateway/auth/configuring-auth0.mdx +216 -0
  2. package/docs/mcp-gateway/auth/configuring-clerk.mdx +153 -0
  3. package/docs/mcp-gateway/auth/configuring-cognito.mdx +128 -0
  4. package/docs/mcp-gateway/auth/configuring-entra.mdx +134 -0
  5. package/docs/mcp-gateway/auth/configuring-generic-oidc.mdx +242 -0
  6. package/docs/mcp-gateway/auth/configuring-google.mdx +117 -0
  7. package/docs/mcp-gateway/auth/configuring-keycloak.mdx +125 -0
  8. package/docs/mcp-gateway/auth/configuring-logto.mdx +116 -0
  9. package/docs/mcp-gateway/auth/configuring-okta.mdx +199 -0
  10. package/docs/mcp-gateway/auth/configuring-onelogin.mdx +122 -0
  11. package/docs/mcp-gateway/auth/configuring-ping.mdx +157 -0
  12. package/docs/mcp-gateway/auth/configuring-workos.mdx +117 -0
  13. package/docs/mcp-gateway/auth/manual-oauth-testing.mdx +528 -0
  14. package/docs/mcp-gateway/auth/overview.mdx +314 -0
  15. package/docs/mcp-gateway/auth/upstream-oauth.mdx +221 -0
  16. package/docs/mcp-gateway/capability-filtering.mdx +162 -0
  17. package/docs/mcp-gateway/code-config/compatibility-dates.mdx +33 -0
  18. package/docs/mcp-gateway/code-config/local-development.mdx +198 -0
  19. package/docs/mcp-gateway/code-config/mcp-proxy-handler.mdx +186 -0
  20. package/docs/mcp-gateway/code-config/multi-upstream.mdx +293 -0
  21. package/docs/mcp-gateway/code-config/overview.mdx +210 -0
  22. package/docs/mcp-gateway/connect-clients/chatgpt.mdx +127 -0
  23. package/docs/mcp-gateway/connect-clients/claude-code.mdx +184 -0
  24. package/docs/mcp-gateway/connect-clients/claude-desktop.mdx +160 -0
  25. package/docs/mcp-gateway/connect-clients/cursor.mdx +100 -0
  26. package/docs/mcp-gateway/connect-clients/other-clients.mdx +207 -0
  27. package/docs/mcp-gateway/connect-clients/overview.mdx +137 -0
  28. package/docs/mcp-gateway/connect-clients/vs-code.mdx +128 -0
  29. package/docs/mcp-gateway/how-it-works.mdx +266 -0
  30. package/docs/mcp-gateway/how-to/connect-upstream-oauth.mdx +268 -0
  31. package/docs/mcp-gateway/how-to/curate-tools.mdx +278 -0
  32. package/docs/mcp-gateway/introduction.mdx +151 -0
  33. package/docs/mcp-gateway/observability/analytics.mdx +191 -0
  34. package/docs/mcp-gateway/observability/logging.mdx +191 -0
  35. package/docs/mcp-gateway/quickstart.mdx +266 -0
  36. package/docs/mcp-gateway/reference.mdx +148 -0
  37. package/docs/mcp-gateway/test-clients.mdx +130 -0
  38. package/docs/mcp-gateway/troubleshooting.mdx +228 -0
  39. package/docs/mcp-server/introduction.mdx +10 -0
  40. package/docs/mcp-server/openai-apps-sdk.mdx +12 -0
  41. package/docs/policies/_index.md +14 -0
  42. package/docs/policies/akamai-ai-firewall/schema.json +1 -0
  43. package/docs/policies/akamai-firewall-for-ai-inbound/schema.json +1 -0
  44. package/docs/policies/akamai-firewall-for-ai-outbound/schema.json +1 -0
  45. package/docs/policies/amberflo-metering-inbound/schema.json +1 -0
  46. package/docs/policies/api-key-inbound/schema.json +1 -0
  47. package/docs/policies/audit-log-inbound/schema.json +1 -0
  48. package/docs/policies/auth0-jwt-auth-inbound/schema.json +1 -0
  49. package/docs/policies/authzen-inbound/schema.json +1 -0
  50. package/docs/policies/axiomatics-authz-inbound/schema.json +1 -0
  51. package/docs/policies/basic-auth-inbound/schema.json +1 -0
  52. package/docs/policies/bot-detection-inbound/schema.json +1 -0
  53. package/docs/policies/brownout-inbound/schema.json +1 -0
  54. package/docs/policies/caching-inbound/schema.json +1 -0
  55. package/docs/policies/change-method-inbound/schema.json +1 -0
  56. package/docs/policies/clear-headers-inbound/schema.json +1 -0
  57. package/docs/policies/clear-headers-outbound/schema.json +1 -0
  58. package/docs/policies/clerk-jwt-auth-inbound/schema.json +1 -0
  59. package/docs/policies/cognito-jwt-auth-inbound/schema.json +1 -0
  60. package/docs/policies/comet-opik-tracing-inbound/schema.json +1 -0
  61. package/docs/policies/complex-rate-limit-inbound/schema.json +1 -0
  62. package/docs/policies/composite-inbound/schema.json +1 -0
  63. package/docs/policies/composite-outbound/schema.json +1 -0
  64. package/docs/policies/curity-phantom-token-inbound/schema.json +1 -0
  65. package/docs/policies/firebase-jwt-inbound/schema.json +1 -0
  66. package/docs/policies/formdata-to-json-inbound/schema.json +1 -0
  67. package/docs/policies/galileo-tracing-inbound/schema.json +1 -0
  68. package/docs/policies/geo-filter-inbound/schema.json +1 -0
  69. package/docs/policies/graphql-complexity-limit-inbound/schema.json +1 -0
  70. package/docs/policies/graphql-disable-introspection-inbound/schema.json +1 -0
  71. package/docs/policies/graphql-introspection-filter-outbound/schema.json +1 -0
  72. package/docs/policies/http-deprecation-outbound/schema.json +1 -0
  73. package/docs/policies/jwt-scopes-inbound/schema.json +1 -0
  74. package/docs/policies/ldap-auth-inbound/schema.json +1 -0
  75. package/docs/policies/mcp-auth0-oauth-inbound/doc.md +54 -0
  76. package/docs/policies/mcp-auth0-oauth-inbound/intro.md +7 -0
  77. package/docs/policies/mcp-auth0-oauth-inbound/schema.json +135 -0
  78. package/docs/policies/mcp-capability-filter-inbound/doc.md +58 -0
  79. package/docs/policies/mcp-capability-filter-inbound/intro.md +9 -0
  80. package/docs/policies/mcp-capability-filter-inbound/schema.json +212 -0
  81. package/docs/policies/mcp-clerk-oauth-inbound/doc.md +34 -0
  82. package/docs/policies/mcp-clerk-oauth-inbound/intro.md +1 -0
  83. package/docs/policies/mcp-clerk-oauth-inbound/schema.json +134 -0
  84. package/docs/policies/mcp-cognito-oauth-inbound/doc.md +52 -0
  85. package/docs/policies/mcp-cognito-oauth-inbound/intro.md +7 -0
  86. package/docs/policies/mcp-cognito-oauth-inbound/schema.json +152 -0
  87. package/docs/policies/mcp-entra-oauth-inbound/doc.md +51 -0
  88. package/docs/policies/mcp-entra-oauth-inbound/intro.md +6 -0
  89. package/docs/policies/mcp-entra-oauth-inbound/schema.json +131 -0
  90. package/docs/policies/mcp-google-oauth-inbound/doc.md +52 -0
  91. package/docs/policies/mcp-google-oauth-inbound/intro.md +6 -0
  92. package/docs/policies/mcp-google-oauth-inbound/schema.json +125 -0
  93. package/docs/policies/mcp-keycloak-oauth-inbound/doc.md +43 -0
  94. package/docs/policies/mcp-keycloak-oauth-inbound/intro.md +2 -0
  95. package/docs/policies/mcp-keycloak-oauth-inbound/schema.json +140 -0
  96. package/docs/policies/mcp-logto-oauth-inbound/doc.md +52 -0
  97. package/docs/policies/mcp-logto-oauth-inbound/intro.md +6 -0
  98. package/docs/policies/mcp-logto-oauth-inbound/schema.json +131 -0
  99. package/docs/policies/mcp-oauth-inbound/doc.md +70 -0
  100. package/docs/policies/mcp-oauth-inbound/intro.md +11 -0
  101. package/docs/policies/mcp-oauth-inbound/schema.json +177 -0
  102. package/docs/policies/mcp-okta-oauth-inbound/doc.md +61 -0
  103. package/docs/policies/mcp-okta-oauth-inbound/intro.md +7 -0
  104. package/docs/policies/mcp-okta-oauth-inbound/schema.json +137 -0
  105. package/docs/policies/mcp-onelogin-oauth-inbound/doc.md +50 -0
  106. package/docs/policies/mcp-onelogin-oauth-inbound/intro.md +6 -0
  107. package/docs/policies/mcp-onelogin-oauth-inbound/schema.json +131 -0
  108. package/docs/policies/mcp-ping-oauth-inbound/doc.md +80 -0
  109. package/docs/policies/mcp-ping-oauth-inbound/intro.md +7 -0
  110. package/docs/policies/mcp-ping-oauth-inbound/schema.json +151 -0
  111. package/docs/policies/mcp-token-exchange-inbound/doc.md +135 -0
  112. package/docs/policies/mcp-token-exchange-inbound/intro.md +6 -0
  113. package/docs/policies/mcp-token-exchange-inbound/schema.json +134 -0
  114. package/docs/policies/mcp-workos-oauth-inbound/doc.md +50 -0
  115. package/docs/policies/mcp-workos-oauth-inbound/intro.md +6 -0
  116. package/docs/policies/mcp-workos-oauth-inbound/schema.json +125 -0
  117. package/docs/policies/mock-api-inbound/schema.json +1 -0
  118. package/docs/policies/moesif-inbound/schema.json +1 -0
  119. package/docs/policies/monetization-inbound/schema.json +1 -0
  120. package/docs/policies/mtls-auth-inbound/schema.json +1 -0
  121. package/docs/policies/okta-fga-authz-inbound/schema.json +1 -0
  122. package/docs/policies/okta-jwt-auth-inbound/schema.json +1 -0
  123. package/docs/policies/open-id-jwt-auth-inbound/schema.json +1 -0
  124. package/docs/policies/openfga-authz-inbound/schema.json +1 -0
  125. package/docs/policies/openmeter-inbound/schema.json +1 -0
  126. package/docs/policies/prompt-injection-outbound/schema.json +1 -0
  127. package/docs/policies/propel-auth-jwt-inbound/schema.json +1 -0
  128. package/docs/policies/query-param-to-header-inbound/schema.json +1 -0
  129. package/docs/policies/quota-inbound/schema.json +1 -0
  130. package/docs/policies/rate-limit-inbound/schema.json +1 -0
  131. package/docs/policies/readme-metrics-inbound/schema.json +1 -0
  132. package/docs/policies/remove-headers-inbound/schema.json +1 -0
  133. package/docs/policies/remove-headers-outbound/schema.json +1 -0
  134. package/docs/policies/remove-query-params-inbound/schema.json +1 -0
  135. package/docs/policies/replace-string-outbound/schema.json +1 -0
  136. package/docs/policies/request-size-limit-inbound/schema.json +1 -0
  137. package/docs/policies/request-validation-inbound/schema.json +1 -0
  138. package/docs/policies/require-origin-inbound/schema.json +1 -0
  139. package/docs/policies/secret-masking-outbound/schema.json +1 -0
  140. package/docs/policies/semantic-cache-inbound/schema.json +1 -0
  141. package/docs/policies/set-body-inbound/schema.json +1 -0
  142. package/docs/policies/set-headers-inbound/schema.json +1 -0
  143. package/docs/policies/set-headers-outbound/schema.json +1 -0
  144. package/docs/policies/set-query-params-inbound/schema.json +1 -0
  145. package/docs/policies/set-status-outbound/schema.json +1 -0
  146. package/docs/policies/set-upstream-api-key-inbound/schema.json +1 -0
  147. package/docs/policies/sleep-inbound/schema.json +1 -0
  148. package/docs/policies/stripe-webhook-verification-inbound/schema.json +1 -0
  149. package/docs/policies/supabase-jwt-auth-inbound/schema.json +1 -0
  150. package/docs/policies/upstream-azure-ad-service-auth-inbound/schema.json +1 -0
  151. package/docs/policies/upstream-firebase-admin-auth-inbound/schema.json +1 -0
  152. package/docs/policies/upstream-firebase-user-auth-inbound/schema.json +1 -0
  153. package/docs/policies/upstream-gcp-federated-auth-inbound/schema.json +1 -0
  154. package/docs/policies/upstream-gcp-jwt-inbound/schema.json +1 -0
  155. package/docs/policies/upstream-gcp-service-auth-inbound/schema.json +1 -0
  156. package/docs/policies/upstream-zuplo-jwt-auth-inbound/schema.json +1 -0
  157. package/docs/policies/validate-json-schema-inbound/schema.json +1 -0
  158. package/docs/policies/web-bot-auth-inbound/schema.json +1 -0
  159. package/docs/policies/xml-to-json-outbound/schema.json +1 -0
  160. package/package.json +4 -4
@@ -0,0 +1,216 @@
1
+ ---
2
+ title: "Configuring Auth0"
3
+ sidebar_label: "Auth0"
4
+ description:
5
+ Configure Auth0 to back the MCP Gateway's downstream OAuth using the
6
+ mcp-auth0-oauth-inbound policy. Covers tenant setup, application
7
+ configuration, and wiring the policy in your gateway project.
8
+ ---
9
+
10
+ The MCP Gateway can use Auth0 as the identity provider behind its downstream
11
+ OAuth flow. The `mcp-auth0-oauth-inbound` policy is an Auth0-friendly wrapper
12
+ around the generic `mcp-oauth-inbound` policy: provide your Auth0 domain, a
13
+ client ID, and a client secret, and the policy derives the OIDC issuer, JWKS
14
+ URL, and Auth0 authorize and token URLs for you.
15
+
16
+ This guide walks through the Auth0 dashboard setup, then shows how to wire the
17
+ policy into your gateway project. Read the
18
+ [authentication overview](./overview.mdx) first for the two-layer model and the
19
+ role each policy plays.
20
+
21
+ :::note
22
+
23
+ This guide assumes you have a working Auth0 tenant. The
24
+ [Auth0 MCP client registration guide](https://auth0.com/ai/docs/mcp/guides/registering-your-mcp-client-application)
25
+ is the authoritative source for Auth0-side configuration.
26
+
27
+ :::
28
+
29
+ Most projects only need three options: `auth0Domain`, `clientId`, and
30
+ `clientSecret`. `audience`, `scope`, and the TTL options are all optional.
31
+
32
+ :::caution
33
+
34
+ `auth0Domain` is a **bare hostname**, not a URL. Use `my-tenant.us.auth0.com`,
35
+ not `https://my-tenant.us.auth0.com/`.
36
+
37
+ :::
38
+
39
+ ## Set up the Auth0 tenant
40
+
41
+ The MCP Gateway acts as an OAuth 2.1 authorization server in front of Auth0.
42
+ Auth0 handles browser login and identity; the gateway issues its own access
43
+ tokens that bind to MCP routes. The Auth0 application you create represents the
44
+ **gateway's identity** against Auth0, not the MCP client.
45
+
46
+ ### Create an Auth0 application
47
+
48
+ 1. In the Auth0 Dashboard, open **Applications > Applications** and click
49
+ **Create Application**.
50
+ 2. Set a name (for example, `Zuplo MCP Gateway`).
51
+ 3. Choose **Regular Web Application** as the application type and click
52
+ **Create**.
53
+ 4. On the **Settings** tab, note the **Domain**, **Client ID**, and **Client
54
+ Secret**. You'll wire these into the policy in the next section.
55
+
56
+ ### Configure callback and origin URLs
57
+
58
+ The gateway completes browser login by redirecting back to its own
59
+ `/oauth/callback` endpoint, so Auth0 needs that URL on its allow-list.
60
+
61
+ On the same **Settings** tab:
62
+
63
+ 1. Set **Allowed Callback URLs** to your gateway's
64
+ `https://<gateway-host>/oauth/callback`. For local development against
65
+ `zuplo dev`, add `http://localhost:9000/oauth/callback` as well.
66
+ 2. Set **Allowed Web Origins** to the gateway origin `https://<gateway-host>`
67
+ (plus `http://localhost:9000` for local dev).
68
+ 3. Save changes.
69
+
70
+ ### Optional: Set an audience
71
+
72
+ If you want Auth0 to issue identity-bound API access tokens (for example, to
73
+ validate Auth0-issued tokens against a specific resource server), create an API
74
+ under **Applications > APIs** with an identifier like
75
+ `https://gateway.example.com` and pass that identifier as the `audience` option
76
+ on the policy. When omitted, Auth0 acts only as the browser identity layer and
77
+ the gateway alone owns the OAuth grant the MCP client receives.
78
+
79
+ ### Connections and dynamic client registration
80
+
81
+ The downstream OAuth flow only requires Auth0 to authenticate the user and
82
+ return an ID token. CIMD and DCR on Auth0's side concern the **upstream MCP
83
+ server's** trust of clients, not the gateway's trust of Auth0. If you also
84
+ configure Auth0 itself as an upstream MCP authorization provider (rare), follow
85
+ Auth0's own guide for
86
+ [enabling CIMD](https://auth0.com/ai/docs/mcp/guides/registering-your-mcp-client-application/manual-cimd-registration)
87
+ or
88
+ [enabling DCR](https://auth0.com/ai/docs/mcp/guides/registering-your-mcp-client-application/dynamic-client-registration).
89
+
90
+ ## Wire the policy into the gateway
91
+
92
+ Add the policy to `config/policies.json`:
93
+
94
+ ```json
95
+ {
96
+ "name": "auth0-managed-oauth",
97
+ "policyType": "mcp-auth0-oauth-inbound",
98
+ "handler": {
99
+ "module": "$import(@zuplo/runtime/mcp-gateway)",
100
+ "export": "McpAuth0OAuthInboundPolicy",
101
+ "options": {
102
+ "auth0Domain": "$env(AUTH0_DOMAIN)",
103
+ "clientId": "$env(AUTH0_CLIENT_ID)",
104
+ "clientSecret": "$env(AUTH0_CLIENT_SECRET)"
105
+ }
106
+ }
107
+ }
108
+ ```
109
+
110
+ Set the three environment variables in your Zuplo project's environment
111
+ configuration. `AUTH0_DOMAIN` is the bare hostname; the secret values belong in
112
+ the project secret store.
113
+
114
+ Attach the policy to each MCP route in `config/routes.oas.json`:
115
+
116
+ ```jsonc
117
+ {
118
+ "paths": {
119
+ "/mcp/linear": {
120
+ "get,post": {
121
+ "operationId": "linear-mcp-server",
122
+ "x-zuplo-route": {
123
+ "corsPolicy": "none",
124
+ "handler": {
125
+ "module": "$import(@zuplo/runtime/mcp-gateway)",
126
+ "export": "McpProxyHandler",
127
+ "options": {
128
+ "rewritePattern": "https://mcp.linear.app/mcp",
129
+ },
130
+ },
131
+ "policies": {
132
+ "inbound": ["auth0-managed-oauth", "mcp-token-exchange-linear"],
133
+ },
134
+ },
135
+ },
136
+ },
137
+ },
138
+ }
139
+ ```
140
+
141
+ Finally, register the gateway plugin in `modules/zuplo.runtime.ts` so the
142
+ runtime registers the OAuth endpoints automatically:
143
+
144
+ ```ts
145
+ import { RuntimeExtensions } from "@zuplo/runtime";
146
+ import { McpGatewayPlugin } from "@zuplo/runtime/mcp-gateway";
147
+
148
+ export function runtimeInit(runtime: RuntimeExtensions) {
149
+ runtime.addPlugin(new McpGatewayPlugin());
150
+ }
151
+ ```
152
+
153
+ One MCP OAuth policy serves every MCP route in the project — there's no need to
154
+ declare it more than once. Attaching the same policy by name to each route is
155
+ the canonical pattern.
156
+
157
+ ## Full options reference
158
+
159
+ `mcp-auth0-oauth-inbound` has three required options and a few optional
160
+ overrides. The complete schema is documented on the policy reference page; the
161
+ fields you'll touch most often are:
162
+
163
+ | Option | Required | Default | Notes |
164
+ | ----------------------------------------- | -------- | ---------------------- | ------------------------------------------------------------------------------------------ |
165
+ | `auth0Domain` | yes | — | Bare hostname (`my-tenant.us.auth0.com`). No scheme, must contain a dot. |
166
+ | `clientId` | yes | — | Auth0 application client ID. |
167
+ | `clientSecret` | yes | — | Auth0 application client secret. Use `$env(...)` to source from a secret. |
168
+ | `audience` | no | unset | Optional Auth0 API identifier. Sent as the `?audience=` parameter to Auth0's `/authorize`. |
169
+ | `scope` | no | `openid profile email` | OIDC scopes requested during browser login. |
170
+ | `gateway.accessTokenTtlSeconds` | no | `900` | Gateway-issued access token lifetime. |
171
+ | `gateway.refreshTokenTtlSeconds` | no | long-lived | Gateway-issued refresh token lifetime. Override only if you need to shorten sessions. |
172
+ | `gateway.cimdEnabled` | no | `true` | Advertise CIMD support in AS metadata. |
173
+ | `browserLoginOverrides.sessionTtlSeconds` | no | `28800` | Browser session cookie lifetime (8 hours). |
174
+ | `browserLoginOverrides.stateTtlSeconds` | no | `900` | Browser-login state record lifetime. |
175
+ | `browserLoginOverrides.remoteTimeoutMs` | no | `10000` | Outbound timeout to Auth0 (token exchange, JWKS fetch). |
176
+
177
+ ## Test the configuration
178
+
179
+ The fastest sanity check is to try connecting an MCP client:
180
+
181
+ 1. Open Claude Desktop, Cursor, Claude Code, or another OAuth-aware MCP client.
182
+ 2. Add a remote MCP server pointing at one of your `/mcp/{slug}` routes on the
183
+ gateway.
184
+ 3. The client should redirect you to Auth0's login page. After login, the
185
+ gateway's consent screen renders. Approve it.
186
+ 4. The client receives an access token and can call `tools/list`.
187
+
188
+ If something fails partway through, walk the flow manually using the
189
+ [manual OAuth testing guide](./manual-oauth-testing.mdx) — it exercises every
190
+ endpoint with `curl` so you can see the raw responses.
191
+
192
+ ## Common issues
193
+
194
+ - **"Invalid Auth0 domain" at boot.** The `auth0Domain` value includes a scheme
195
+ prefix or doesn't contain a dot. Use `my-tenant.us.auth0.com`.
196
+ - **Browser login redirects but the callback fails.** The
197
+ `https://<gateway-host>/oauth/callback` URL isn't on the **Allowed Callback
198
+ URLs** list for the Auth0 application.
199
+ - **Token endpoint returns `invalid_audience`.** The MCP client is reusing a
200
+ token bound to a different route. Each gateway-issued token binds to one
201
+ `operationId`; the client must obtain a separate token per route.
202
+ - **Issuer in AS metadata is wrong.** The gateway derives its issuer from the
203
+ incoming request origin. Check that your custom domain or proxy forwards the
204
+ correct `Host` or `X-Forwarded-Host` header. See
205
+ [Troubleshooting](../troubleshooting.mdx).
206
+ - **MCP client can't discover the AS.** Confirm the `mcp-auth0-oauth-inbound`
207
+ policy is attached to the route in `routes.oas.json` and that the
208
+ `McpGatewayPlugin` is registered in `modules/zuplo.runtime.ts`. The internal
209
+ OAuth endpoints register only when both are present.
210
+
211
+ ## Related
212
+
213
+ - [Authentication overview](./overview.mdx)
214
+ - `mcp-auth0-oauth-inbound` policy reference
215
+ - [Configuring Okta or any other OIDC IdP](./configuring-okta.mdx)
216
+ - [Per-user OAuth to upstream MCP servers](./upstream-oauth.mdx)
@@ -0,0 +1,153 @@
1
+ ---
2
+ title: "Configuring Clerk"
3
+ sidebar_label: "Clerk"
4
+ description:
5
+ Configure Clerk to back the MCP Gateway's downstream OAuth using the
6
+ mcp-clerk-oauth-inbound policy. Covers OAuth application setup and wiring the
7
+ policy in your gateway project.
8
+ ---
9
+
10
+ The MCP Gateway can use [Clerk](https://clerk.com/) as the identity provider
11
+ behind its downstream OAuth flow. The `mcp-clerk-oauth-inbound` policy is a
12
+ Clerk-friendly wrapper around the generic `mcp-oauth-inbound` policy: provide
13
+ your Clerk Frontend API URL, a client ID, and a client secret, and the policy
14
+ derives the OIDC issuer, JWKS URL, and authorize and token URLs for you.
15
+
16
+ This guide walks through the Clerk dashboard setup, then wires the policy into a
17
+ gateway project. Read the [authentication overview](./overview.mdx) first for
18
+ the two-layer OAuth model.
19
+
20
+ ## Set up Clerk
21
+
22
+ The MCP Gateway acts as an OAuth 2.1 authorization server in front of Clerk.
23
+ Clerk handles browser login; the gateway issues its own access tokens that bind
24
+ to MCP routes.
25
+
26
+ ### Create an OAuth application
27
+
28
+ 1. In the Clerk Dashboard, switch to the instance you want the gateway to use,
29
+ then open **Configure → OAuth Applications**.
30
+ 2. Click **Add OAuth application**.
31
+ 3. Give the application a name (for example, `Zuplo MCP Gateway`).
32
+ 4. Set **Redirect URIs** to `https://<gateway-host>/oauth/callback`. Add
33
+ `http://localhost:9000/oauth/callback` for local development with
34
+ `zuplo dev`.
35
+ 5. Select the OIDC scopes the gateway needs — `openid`, `profile`, and `email`
36
+ are enough.
37
+ 6. Click **Save**.
38
+
39
+ Note the **Client ID** and **Client Secret** from the application's detail page.
40
+ You'll wire these into the policy in the next section.
41
+
42
+ ### Find the Frontend API URL
43
+
44
+ Open **Configure → Domains** in the Clerk Dashboard. The **Frontend API URL** is
45
+ shown at the top — it looks like `https://verb-noun-00.clerk.accounts.dev` on
46
+ development instances or `https://clerk.example.com` on production instances
47
+ with a custom domain. Copy the origin (no trailing path).
48
+
49
+ ## Wire the policy into the gateway
50
+
51
+ Add the policy to `config/policies.json`:
52
+
53
+ ```json
54
+ {
55
+ "name": "clerk-managed-oauth",
56
+ "policyType": "mcp-clerk-oauth-inbound",
57
+ "handler": {
58
+ "module": "$import(@zuplo/runtime/mcp-gateway)",
59
+ "export": "McpClerkOAuthInboundPolicy",
60
+ "options": {
61
+ "frontendApiUrl": "$env(CLERK_FRONTEND_API_URL)",
62
+ "clientId": "$env(CLERK_CLIENT_ID)",
63
+ "clientSecret": "$env(CLERK_CLIENT_SECRET)"
64
+ }
65
+ }
66
+ }
67
+ ```
68
+
69
+ :::caution
70
+
71
+ `frontendApiUrl` is the origin only. Don't include a path, query string, or
72
+ fragment — the policy fails at boot if any of those are present.
73
+
74
+ :::
75
+
76
+ Set the three environment variables in your project's environment configuration.
77
+ `CLERK_FRONTEND_API_URL` goes in plain config; the secret values belong in the
78
+ project secret store.
79
+
80
+ Attach the policy to each MCP route in `config/routes.oas.json`:
81
+
82
+ ```jsonc
83
+ {
84
+ "paths": {
85
+ "/mcp/linear-v1": {
86
+ "get,post": {
87
+ "operationId": "linear-mcp-server",
88
+ "x-zuplo-route": {
89
+ "corsPolicy": "none",
90
+ "handler": {
91
+ "module": "$import(@zuplo/runtime/mcp-gateway)",
92
+ "export": "McpProxyHandler",
93
+ "options": {
94
+ "rewritePattern": "https://mcp.linear.app/mcp",
95
+ },
96
+ },
97
+ "policies": {
98
+ "inbound": ["clerk-managed-oauth", "mcp-token-exchange-linear"],
99
+ },
100
+ },
101
+ },
102
+ },
103
+ },
104
+ }
105
+ ```
106
+
107
+ Register the gateway plugin in `modules/zuplo.runtime.ts`:
108
+
109
+ ```ts
110
+ import { RuntimeExtensions } from "@zuplo/runtime";
111
+ import { McpGatewayPlugin } from "@zuplo/runtime/mcp-gateway";
112
+
113
+ export function runtimeInit(runtime: RuntimeExtensions) {
114
+ runtime.addPlugin(new McpGatewayPlugin());
115
+ }
116
+ ```
117
+
118
+ ## What the wrapper derives
119
+
120
+ | Generic field | Derived value |
121
+ | ----------------------- | ---------------------------------------- |
122
+ | `oidc.issuer` | `{frontendApiUrl}` |
123
+ | `oidc.jwksUrl` | `{frontendApiUrl}/.well-known/jwks.json` |
124
+ | `browserLogin.url` | `{frontendApiUrl}/oauth/authorize` |
125
+ | `browserLogin.tokenUrl` | `{frontendApiUrl}/oauth/token` |
126
+
127
+ ## Test the configuration
128
+
129
+ The fastest sanity check is to connect an MCP client:
130
+
131
+ 1. Open Claude Desktop, Cursor, Claude Code, or another OAuth-aware MCP client.
132
+ 2. Add a remote MCP server pointing at one of your `/mcp/{slug}` routes.
133
+ 3. The client should redirect you to Clerk's login page. After login, the
134
+ gateway's consent screen renders. Approve it.
135
+ 4. The client receives an access token and can call `tools/list`.
136
+
137
+ If something fails partway through, walk the flow manually using the
138
+ [manual OAuth testing guide](./manual-oauth-testing.mdx) — it exercises every
139
+ endpoint with `curl` so you can see the raw responses.
140
+
141
+ ## Common issues
142
+
143
+ - **The policy rejects `frontendApiUrl` at boot.** The value includes a path,
144
+ query string, or fragment. Use only the origin (`https://clerk.example.com`).
145
+ - **Browser login redirects but the callback fails.** The
146
+ `https://<gateway-host>/oauth/callback` URL isn't on the OAuth application's
147
+ redirect URIs allow-list in Clerk.
148
+
149
+ ## Related
150
+
151
+ - [Authentication overview](./overview.mdx)
152
+ - [Configuring a generic OIDC provider](./configuring-generic-oidc.mdx)
153
+ - [Per-user OAuth to upstream MCP servers](./upstream-oauth.mdx)
@@ -0,0 +1,128 @@
1
+ ---
2
+ title: "Configuring Amazon Cognito"
3
+ sidebar_label: "Amazon Cognito"
4
+ description:
5
+ Configure Amazon Cognito to back the MCP Gateway's downstream OAuth using the
6
+ mcp-cognito-oauth-inbound policy. Covers user pool setup, hosted UI domain,
7
+ and wiring the policy in your gateway project.
8
+ ---
9
+
10
+ The MCP Gateway can use Amazon Cognito as the identity provider behind its
11
+ downstream OAuth flow. The `mcp-cognito-oauth-inbound` policy is a
12
+ Cognito-friendly wrapper around the generic `mcp-oauth-inbound` policy: provide
13
+ your AWS region, user pool ID, hosted UI domain, client ID, and client secret,
14
+ and the policy derives the OIDC issuer, JWKS URL, and authorize and token URLs
15
+ for you.
16
+
17
+ This guide walks through the Cognito user pool setup, then wires the policy into
18
+ a gateway project. Read the [authentication overview](./overview.mdx) first for
19
+ the two-layer OAuth model.
20
+
21
+ :::note
22
+
23
+ Cognito splits OIDC across two domains: discovery and JWKS are served from the
24
+ Cognito IDP service domain (`cognito-idp.{region}.amazonaws.com/{userPoolId}`),
25
+ while browser login is served from the **user pool hosted UI domain**. The
26
+ wrapper handles both.
27
+
28
+ :::
29
+
30
+ ## Set up Cognito
31
+
32
+ ### Create or pick a user pool
33
+
34
+ 1. In the AWS Cognito console, open **User pools** and either pick an existing
35
+ pool or create a new one. Note the **User pool ID** (it looks like
36
+ `us-east-1_AbCdEf123`).
37
+ 2. Under **App integration**, set up a **hosted UI domain**. You can use a
38
+ Cognito-prefix domain like `my-pool.auth.us-east-1.amazoncognito.com` or a
39
+ custom domain like `auth.example.com`. The wrapper takes only the host — no
40
+ scheme, no path.
41
+
42
+ ### Create an app client
43
+
44
+ 1. Under **App integration → App clients**, click **Create app client**.
45
+ 2. Choose **Confidential client**. The client must have a client secret — the
46
+ gateway needs it for the federated token exchange.
47
+ 3. Set **Allowed callback URLs** to `https://<gateway-host>/oauth/callback`. Add
48
+ `http://localhost:9000/oauth/callback` for local development.
49
+ 4. Enable **Authorization code grant** under allowed OAuth flows.
50
+ 5. Enable the OIDC scopes the gateway needs — `openid`, `profile`, and `email`.
51
+ 6. Click **Create app client**.
52
+
53
+ Note the **Client ID** and **Client Secret** from the app client's detail page.
54
+
55
+ ## Wire the policy into the gateway
56
+
57
+ Add the policy to `config/policies.json`:
58
+
59
+ ```json
60
+ {
61
+ "name": "cognito-managed-oauth",
62
+ "policyType": "mcp-cognito-oauth-inbound",
63
+ "handler": {
64
+ "module": "$import(@zuplo/runtime/mcp-gateway)",
65
+ "export": "McpCognitoOAuthInboundPolicy",
66
+ "options": {
67
+ "awsRegion": "us-east-1",
68
+ "userPoolId": "$env(COGNITO_USER_POOL_ID)",
69
+ "userPoolDomain": "$env(COGNITO_USER_POOL_DOMAIN)",
70
+ "clientId": "$env(COGNITO_CLIENT_ID)",
71
+ "clientSecret": "$env(COGNITO_CLIENT_SECRET)"
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ :::caution
78
+
79
+ `userPoolDomain` is the hosted UI host only — no `https://`, no trailing slash,
80
+ no path. The policy fails at boot if any of those are present.
81
+
82
+ :::
83
+
84
+ Attach the policy to each MCP route in `config/routes.oas.json` and register the
85
+ gateway plugin in `modules/zuplo.runtime.ts` (see
86
+ [Configuring Auth0](./configuring-auth0.mdx#wire-the-policy-into-the-gateway)
87
+ for the route and plugin patterns — they're identical across all wrappers).
88
+
89
+ ## What the wrapper derives
90
+
91
+ | Generic field | Derived value |
92
+ | ----------------------- | ---------------------------------------------------------------------------------- |
93
+ | `oidc.issuer` | `https://cognito-idp.{awsRegion}.amazonaws.com/{userPoolId}` |
94
+ | `oidc.jwksUrl` | `https://cognito-idp.{awsRegion}.amazonaws.com/{userPoolId}/.well-known/jwks.json` |
95
+ | `browserLogin.url` | `https://{userPoolDomain}/oauth2/authorize` |
96
+ | `browserLogin.tokenUrl` | `https://{userPoolDomain}/oauth2/token` |
97
+
98
+ ## Test the configuration
99
+
100
+ The fastest sanity check is to connect an MCP client:
101
+
102
+ 1. Open Claude Desktop, Cursor, Claude Code, or another OAuth-aware MCP client.
103
+ 2. Add a remote MCP server pointing at one of your `/mcp/{slug}` routes.
104
+ 3. The client should redirect you to the Cognito hosted UI sign-in page. After
105
+ login, the gateway's consent screen renders. Approve it.
106
+ 4. The client receives an access token and can call `tools/list`.
107
+
108
+ If something fails partway through, walk the flow manually using the
109
+ [manual OAuth testing guide](./manual-oauth-testing.mdx) — it exercises every
110
+ endpoint with `curl` so you can see the raw responses.
111
+
112
+ ## Common issues
113
+
114
+ - **The policy rejects `userPoolDomain` at boot.** The value includes
115
+ `https://`, a trailing slash, or an OAuth path. Strip those — use only
116
+ `auth.example.com` or `my-pool.auth.us-east-1.amazoncognito.com`.
117
+ - **Browser login lands on a Cognito error page.** The callback URL on the app
118
+ client doesn't match. Set it to `https://<gateway-host>/oauth/callback`
119
+ exactly.
120
+ - **`invalid_client` from Cognito's token endpoint.** The app client doesn't
121
+ have a client secret, or the secret value doesn't match. Cognito confidential
122
+ clients require both ID and secret.
123
+
124
+ ## Related
125
+
126
+ - [Authentication overview](./overview.mdx)
127
+ - [Configuring a generic OIDC provider](./configuring-generic-oidc.mdx)
128
+ - [Per-user OAuth to upstream MCP servers](./upstream-oauth.mdx)
@@ -0,0 +1,134 @@
1
+ ---
2
+ title: "Configuring Microsoft Entra ID"
3
+ sidebar_label: "Microsoft Entra"
4
+ description:
5
+ Configure Microsoft Entra ID to back the MCP Gateway's downstream OAuth using
6
+ the mcp-entra-oauth-inbound policy. Covers app registration and wiring the
7
+ policy in your gateway project.
8
+ ---
9
+
10
+ The MCP Gateway can use Microsoft Entra ID (formerly Azure AD) as the identity
11
+ provider behind its downstream OAuth flow. The `mcp-entra-oauth-inbound` policy
12
+ is an Entra-friendly wrapper around the generic `mcp-oauth-inbound` policy:
13
+ provide your Entra tenant UUID, a client ID, and a client secret, and the policy
14
+ derives the v2 OIDC issuer, JWKS URL, and authorize and token URLs for you.
15
+
16
+ This guide walks through the Microsoft Entra admin center setup, then wires the
17
+ policy into a gateway project. Read the
18
+ [authentication overview](./overview.mdx) first for the two-layer OAuth model.
19
+
20
+ :::caution
21
+
22
+ This policy is **single-tenant**. The multi-tenant aliases `common`,
23
+ `organizations`, and `consumers` are not supported because Entra's issuer claim
24
+ is tenant-specific and the gateway enforces an exact issuer match. Use a real
25
+ tenant UUID.
26
+
27
+ :::
28
+
29
+ ## Set up Microsoft Entra
30
+
31
+ The MCP Gateway acts as an OAuth 2.1 authorization server in front of Entra.
32
+ Entra handles browser login; the gateway issues its own access tokens that bind
33
+ to MCP routes.
34
+
35
+ ### Register an application
36
+
37
+ 1. In the Microsoft Entra admin center, open **Identity → Applications → App
38
+ registrations** and click **New registration**.
39
+ 2. Give the application a name (for example, `Zuplo MCP Gateway`).
40
+ 3. Under **Supported account types**, choose **Accounts in this organizational
41
+ directory only (single tenant)**. The wrapper does not support multi-tenant
42
+ modes.
43
+ 4. Under **Redirect URI**, choose **Web** and set the value to
44
+ `https://<gateway-host>/oauth/callback`. Click **Register**.
45
+ 5. On the application's **Overview** page, note the **Application (client) ID**
46
+ and the **Directory (tenant) ID**. Both are UUIDs.
47
+
48
+ ### Add a client secret
49
+
50
+ 1. Open **Certificates & secrets** on the application and click **New client
51
+ secret**.
52
+ 2. Set a description and an expiration window, then click **Add**.
53
+ 3. Copy the secret **Value** immediately — Entra only shows it once.
54
+
55
+ ### Add the local development redirect URI
56
+
57
+ 1. Open **Authentication** on the application.
58
+ 2. Add `http://localhost:9000/oauth/callback` under **Web → Redirect URIs**.
59
+ 3. Save.
60
+
61
+ ### Optional: restrict access
62
+
63
+ By default any user in the tenant can sign in. To restrict access to specific
64
+ groups, open **Enterprise applications**, find the same application, and use
65
+ **Properties → Assignment required** plus **Users and groups** assignments.
66
+
67
+ ## Wire the policy into the gateway
68
+
69
+ Add the policy to `config/policies.json`:
70
+
71
+ ```json
72
+ {
73
+ "name": "entra-managed-oauth",
74
+ "policyType": "mcp-entra-oauth-inbound",
75
+ "handler": {
76
+ "module": "$import(@zuplo/runtime/mcp-gateway)",
77
+ "export": "McpEntraOAuthInboundPolicy",
78
+ "options": {
79
+ "tenantId": "$env(ENTRA_TENANT_ID)",
80
+ "clientId": "$env(ENTRA_CLIENT_ID)",
81
+ "clientSecret": "$env(ENTRA_CLIENT_SECRET)"
82
+ }
83
+ }
84
+ }
85
+ ```
86
+
87
+ Set the three environment variables in your project's environment configuration.
88
+ The secret values belong in the project secret store.
89
+
90
+ Attach the policy to each MCP route in `config/routes.oas.json` and register the
91
+ gateway plugin in `modules/zuplo.runtime.ts` (see
92
+ [Configuring Auth0](./configuring-auth0.mdx#wire-the-policy-into-the-gateway)
93
+ for the route and plugin patterns — they're identical across all wrappers).
94
+
95
+ ## What the wrapper derives
96
+
97
+ | Generic field | Derived value |
98
+ | ----------------------- | -------------------------------------------------------------------- |
99
+ | `oidc.issuer` | `https://login.microsoftonline.com/{tenantId}/v2.0` |
100
+ | `oidc.jwksUrl` | `https://login.microsoftonline.com/{tenantId}/discovery/v2.0/keys` |
101
+ | `browserLogin.url` | `https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize` |
102
+ | `browserLogin.tokenUrl` | `https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token` |
103
+
104
+ ## Test the configuration
105
+
106
+ The fastest sanity check is to connect an MCP client:
107
+
108
+ 1. Open Claude Desktop, Cursor, Claude Code, or another OAuth-aware MCP client.
109
+ 2. Add a remote MCP server pointing at one of your `/mcp/{slug}` routes.
110
+ 3. The client should redirect you to the Microsoft sign-in page. After login,
111
+ the gateway's consent screen renders. Approve it.
112
+ 4. The client receives an access token and can call `tools/list`.
113
+
114
+ If something fails partway through, walk the flow manually using the
115
+ [manual OAuth testing guide](./manual-oauth-testing.mdx) — it exercises every
116
+ endpoint with `curl` so you can see the raw responses.
117
+
118
+ ## Common issues
119
+
120
+ - **`tenantId` rejected at boot.** The wrapper accepts only a tenant UUID, not a
121
+ verified domain, `common`, `organizations`, or `consumers`. Look up the tenant
122
+ ID under **Overview** in the Entra admin center.
123
+ - **`AADSTS50011` redirect URI mismatch.** The redirect URI on the app
124
+ registration doesn't match `https://<gateway-host>/oauth/callback` exactly.
125
+ Match scheme, host, and path.
126
+ - **`AADSTS700016` application not found.** The client ID doesn't belong to the
127
+ tenant the wrapper is configured with. Make sure `tenantId` and `clientId`
128
+ come from the same app registration.
129
+
130
+ ## Related
131
+
132
+ - [Authentication overview](./overview.mdx)
133
+ - [Configuring a generic OIDC provider](./configuring-generic-oidc.mdx)
134
+ - [Per-user OAuth to upstream MCP servers](./upstream-oauth.mdx)