zuplo 7.4.4 → 7.4.6

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 (40) hide show
  1. package/docs/articles/ci-cd-azure/local-testing.mdx +22 -4
  2. package/docs/articles/ci-cd-bitbucket/local-testing.mdx +22 -4
  3. package/docs/articles/ci-cd-circleci/local-testing.mdx +21 -4
  4. package/docs/articles/ci-cd-github/deploy-and-test.mdx +28 -13
  5. package/docs/articles/ci-cd-github/local-testing.mdx +36 -16
  6. package/docs/articles/ci-cd-gitlab/local-testing.mdx +22 -4
  7. package/docs/articles/github-deployment-testing.mdx +118 -31
  8. package/docs/articles/testing-getting-started.mdx +220 -0
  9. package/docs/articles/testing-preview-environments.mdx +148 -0
  10. package/docs/articles/testing-recipes.mdx +429 -0
  11. package/docs/articles/testing.mdx +138 -408
  12. package/docs/mcp-gateway/auth/configuring-auth0.mdx +6 -5
  13. package/docs/mcp-gateway/auth/configuring-clerk.mdx +4 -4
  14. package/docs/mcp-gateway/auth/configuring-cognito.mdx +5 -4
  15. package/docs/mcp-gateway/auth/configuring-entra.mdx +5 -4
  16. package/docs/mcp-gateway/auth/configuring-generic-oidc.mdx +8 -8
  17. package/docs/mcp-gateway/auth/configuring-google.mdx +4 -4
  18. package/docs/mcp-gateway/auth/configuring-keycloak.mdx +4 -3
  19. package/docs/mcp-gateway/auth/configuring-logto.mdx +4 -4
  20. package/docs/mcp-gateway/auth/configuring-okta.mdx +3 -3
  21. package/docs/mcp-gateway/auth/configuring-onelogin.mdx +3 -3
  22. package/docs/mcp-gateway/auth/configuring-ping.mdx +3 -3
  23. package/docs/mcp-gateway/auth/configuring-workos.mdx +5 -4
  24. package/docs/mcp-gateway/auth/manual-oauth-testing.mdx +8 -8
  25. package/docs/mcp-gateway/auth/overview.mdx +17 -17
  26. package/docs/mcp-gateway/auth/upstream-oauth.mdx +5 -5
  27. package/docs/mcp-gateway/code-config/local-development.mdx +14 -12
  28. package/docs/mcp-gateway/code-config/overview.mdx +9 -4
  29. package/docs/mcp-gateway/connect-clients/chatgpt.mdx +114 -56
  30. package/docs/mcp-gateway/how-it-works.mdx +11 -9
  31. package/docs/mcp-gateway/introduction.mdx +3 -1
  32. package/docs/mcp-gateway/quickstart-local.mdx +7 -7
  33. package/docs/mcp-gateway/reference.mdx +58 -25
  34. package/docs/mcp-gateway/server-registry.mdx +179 -0
  35. package/docs/mcp-gateway/test-clients.mdx +2 -2
  36. package/docs/mcp-server/custom-tools.mdx +32 -0
  37. package/docs/programmable-api/mcp-gateway-plugin.mdx +137 -0
  38. package/docs/programmable-api/mcp-sdk.mdx +240 -0
  39. package/docs/self-hosted/overview.md +2 -0
  40. package/package.json +5 -5
@@ -2,22 +2,28 @@
2
2
  title: "Connect ChatGPT"
3
3
  sidebar_label: "ChatGPT"
4
4
  description:
5
- Connect ChatGPT to a Zuplo MCP Gateway as a custom connector using Developer
6
- Mode, complete the OAuth flow, and start using your tools in conversation.
5
+ Connect ChatGPT to a Zuplo MCP Gateway as a custom app using Developer Mode,
6
+ scan the gateway tools, complete the OAuth flow, and use the app in
7
+ conversation.
7
8
  ---
8
9
 
9
- ChatGPT connects to remote MCP servers as **custom connectors**. To add a custom
10
- connector that exposes general-purpose MCP tools, you need to enable **Developer
11
- Mode** on your ChatGPT account. Once enabled, paste the gateway URL into
12
- ChatGPT's connector settings and complete the OAuth flow.
10
+ ChatGPT connects to remote MCP servers as **custom apps**. OpenAI previously
11
+ called these "custom connectors", and some ChatGPT screens still use connector
12
+ language, but the current ChatGPT docs use **apps** as the primary term.
13
+
14
+ To add a Zuplo MCP Gateway route to ChatGPT, enable **Developer Mode**, create
15
+ an app that points at the gateway's public MCP route URL, scan the tools, and
16
+ complete the OAuth flow.
13
17
 
14
18
  :::note
15
19
 
16
- ChatGPT's general-purpose custom-connector support runs through Developer Mode,
17
- which is available on Pro, Team, Enterprise, and Edu plans. Before Developer
18
- Mode shipped, connector support in ChatGPT was limited to read-only Deep
19
- Research connectors. Use Developer Mode to expose the full range of tools the
20
- Zuplo MCP Gateway provides.
20
+ OpenAI's current ChatGPT docs describe full MCP app support, including
21
+ write/modify actions, as a beta for ChatGPT Business, Enterprise, and Edu plans
22
+ on ChatGPT web. Pro users can connect MCP servers with read/fetch permissions in
23
+ Developer Mode, but full MCP support is not currently available to Pro users.
24
+ Check OpenAI's
25
+ [Developer mode and MCP apps in ChatGPT](https://help.openai.com/en/articles/12584461-developer-mode-apps-and-full-mcp-connectors-in-chatgpt-beta)
26
+ article for the latest plan availability.
21
27
 
22
28
  :::
23
29
 
@@ -25,12 +31,20 @@ Zuplo MCP Gateway provides.
25
31
 
26
32
  - A Zuplo project with the MCP Gateway plugin configured and at least one MCP
27
33
  route. See the [quickstart](../quickstart.mdx) if you haven't set one up yet.
28
- - A ChatGPT Pro, Team, Enterprise, or Edu subscription.
29
- - Developer Mode enabled on your ChatGPT account. The toggle lives in
30
- **Settings** **Connectors** **Advanced** (the exact location varies by
31
- plan; see OpenAI's
32
- [Apps SDK documentation](https://developers.openai.com/apps-sdk/) for current
33
- instructions).
34
+ - A ChatGPT Business, Enterprise, or Edu workspace for full MCP apps. Pro users
35
+ can use read/fetch MCP servers only.
36
+ - Developer Mode enabled for the ChatGPT account or workspace. OpenAI's current
37
+ Apps SDK guide says to enable it from **Settings** → **Apps & Connectors** →
38
+ **Advanced settings**. Business and Enterprise/Edu workspaces may require an
39
+ admin or owner to enable Developer Mode first from workspace settings.
40
+ - A public HTTPS MCP route URL. ChatGPT does not connect directly to localhost
41
+ or private-network MCP servers. For local or private development, use OpenAI's
42
+ [Secure MCP Tunnel](https://developers.openai.com/api/docs/guides/secure-mcp-tunnel)
43
+ or another HTTPS tunnel.
44
+ - If your gateway uses OAuth, the identity provider should support the MCP
45
+ authorization requirements ChatGPT expects. For long-lived connections, verify
46
+ that your provider can issue refresh tokens; OpenAI recommends advertising and
47
+ requesting the `offline_access` scope when using OpenID Connect.
34
48
 
35
49
  ## Get the route URL
36
50
 
@@ -38,58 +52,89 @@ Each MCP route in `config/routes.oas.json` is reachable at
38
52
  `https://{deploymentUrl}/{routePath}` once deployed — for example
39
53
  `https://{deploymentUrl}/mcp/linear-v1`.
40
54
 
41
- ## Add the connector
55
+ ## Add the app
42
56
 
43
57
  <Stepper>
44
58
 
45
- 1. **Open Connectors settings in ChatGPT.**
59
+ 1. **Enable Developer Mode.**
60
+
61
+ In ChatGPT web, open **Settings** → **Apps & Connectors** → **Advanced
62
+ settings** and enable **Developer Mode**. In Business, Enterprise, or Edu
63
+ workspaces, an admin or owner may need to enable Developer Mode from
64
+ workspace settings first. See OpenAI's
65
+ [Developer mode and MCP apps in ChatGPT](https://help.openai.com/en/articles/12584461-developer-mode-apps-and-full-mcp-connectors-in-chatgpt-beta)
66
+ article for the current plan-specific path.
67
+
68
+ 2. **Create an app.**
69
+
70
+ Open **Settings** → **Apps & Connectors** and click **Create**. In some
71
+ workspaces, the create flow is under **Workspace settings** → **Apps** →
72
+ **Create**.
46
73
 
47
- In the ChatGPT web app, open **Settings** → **Connectors**.
74
+ 3. **Enter the gateway app details.**
48
75
 
49
- 2. **Add a custom connector.**
76
+ Provide a name, description, and the gateway route URL. Use the public MCP
77
+ route URL as the app or connector URL, for example
78
+ `https://{deploymentUrl}/mcp/linear-v1`.
50
79
 
51
- Click the option to add a custom connector. Depending on your plan, this may
52
- be **Add custom connector**, **Create**, or **Advanced** → **Add MCP
53
- server**.
80
+ 4. **Choose the authentication method.**
54
81
 
55
- 3. **Enter the gateway URL.**
82
+ If the gateway route is protected, choose OAuth or the OAuth/OpenID Connect
83
+ option in ChatGPT. The Zuplo gateway exposes the MCP OAuth metadata ChatGPT
84
+ needs for discovery.
56
85
 
57
- Paste the route URL. Give the connector a name and description — these are
58
- what ChatGPT shows in the conversation interface.
86
+ 5. **Scan the gateway tools.**
59
87
 
60
- 4. **Authenticate against the gateway.**
88
+ Click **Scan Tools**. If ChatGPT opens an authorization prompt, complete the
89
+ gateway sign-in with the identity provider you configured for the route. Wait
90
+ for ChatGPT to finish scanning and show the tools exposed by the gateway.
61
91
 
62
- Save the connector. ChatGPT opens the gateway's OAuth flow. Sign in with the
63
- identity provider you configured for the gateway.
92
+ 6. **Complete the upstream connection.**
64
93
 
65
- 5. **Complete the upstream connection.**
94
+ If the upstream MCP server also requires per-user OAuth, the gateway shows a
95
+ consent page with that upstream server. Click **Connect**, complete the
96
+ upstream OAuth flow, then click **Authorize** to return to ChatGPT.
66
97
 
67
- The gateway shows a consent page with the upstream MCP server the route
68
- proxies to. Click **Connect** next to the upstream, complete its OAuth flow,
69
- then click **Authorize** to finish.
98
+ 7. **Create the app.**
70
99
 
71
- 6. **Enable the connector for chats.**
100
+ Click **Create** after the scan succeeds. ChatGPT shows the app as a
101
+ Developer Mode app for your account, or as a draft app in workspace settings.
72
102
 
73
- Back in ChatGPT, enable the connector for the conversations or assistants
74
- where you want it active. Tools from the gateway then appear when ChatGPT
75
- needs them.
103
+ 8. **Use the app in a chat.**
104
+
105
+ Start a new chat, click the **+** button near the message composer, choose
106
+ **More**, and select your app. Prompt ChatGPT with a request that should use
107
+ one of the gateway tools.
76
108
 
77
109
  </Stepper>
78
110
 
111
+ ## Publish for a workspace
112
+
113
+ Developer Mode apps are private while you test them. To make the app available
114
+ to a Business, Enterprise, or Edu workspace, an admin or owner must publish it
115
+ from **Workspace settings** → **Apps**. OpenAI notes that workspace apps use a
116
+ reviewed snapshot of the available tools; after changing the gateway's tools or
117
+ tool schemas, refresh the app's actions in ChatGPT before publishing or
118
+ republishing.
119
+
79
120
  ## What ChatGPT supports
80
121
 
81
- ChatGPT registers itself with the gateway through
82
- [Dynamic Client Registration (DCR)](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization)
83
- and the newer
84
- [Client ID Metadata Documents (CIMD)](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization)
85
- flow. It supports:
122
+ ChatGPT acts as an MCP client for the gateway. For authenticated MCP servers,
123
+ OpenAI's Apps SDK authentication guide says ChatGPT supports
124
+ [Client ID Metadata Documents (CIMD)](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization),
125
+ [Dynamic Client Registration (DCR)](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization),
126
+ predefined OAuth clients, and Authorization Code with PKCE. The gateway handles
127
+ the resource metadata and OAuth challenge flow for MCP clients.
128
+
129
+ ChatGPT supports:
86
130
 
87
- - **Tools** — invoke gateway-exposed tools from the conversation.
88
- - **MCP Apps** render interactive HTML widgets inline. This is the same
89
- surface that powers the OpenAI Apps SDK, which is built directly on top of MCP
90
- Apps.
131
+ - **Tools** — invoke gateway-exposed tools from the conversation. Full MCP apps
132
+ no longer need to expose only `search` and `fetch` tools, though company
133
+ knowledge and deep research still use read/fetch-style access.
134
+ - **MCP Apps** — render interactive HTML widgets inline through the OpenAI Apps
135
+ SDK conventions. The Apps SDK is built on top of MCP.
91
136
 
92
- ChatGPT doesn't currently consume prompts, resources, roots, sampling, or
137
+ ChatGPT doesn't currently consume arbitrary MCP prompts, roots, sampling, or
93
138
  elicitation from a remote MCP server.
94
139
 
95
140
  ## Build an Apps SDK app on top of the gateway
@@ -107,21 +152,34 @@ For more background on Apps SDK and Zuplo-hosted MCP servers, see
107
152
 
108
153
  ## Troubleshooting
109
154
 
110
- - **"Custom connector" option isn't visible.** Confirm your plan supports
111
- Developer Mode (Pro, Team, Enterprise, or Edu) and that Developer Mode is
112
- enabled in your settings.
155
+ - **Create or Developer Mode isn't visible.** Confirm your plan supports the
156
+ level of MCP access you need. Full MCP apps currently require ChatGPT
157
+ Business, Enterprise, or Edu. Your workspace admin may also need to enable
158
+ Developer Mode or grant access with RBAC.
113
159
  - **Sign-in succeeds but no tools appear.** Tools only appear when ChatGPT
114
160
  decides to invoke them. Try a prompt that mentions the action you want to
115
- take. If the connector itself is disabled in a conversation, ChatGPT doesn't
116
- see any of its tools.
161
+ take. If the app is not selected from the composer, ChatGPT doesn't see any of
162
+ its tools.
163
+ - **Tool scan fails.** Confirm the MCP route is reachable over public HTTPS and
164
+ that the route returns the MCP OAuth metadata ChatGPT expects. Localhost and
165
+ private-network URLs require a tunnel.
117
166
  - **OAuth fails with a redirect error.** ChatGPT registers its redirect URI
118
- dynamically. The gateway accepts dynamic registration by default. If you've
119
- locked down DCR on your identity provider, switch to a provider that supports
120
- DCR, or pre-register an OAuth app for ChatGPT.
167
+ through CIMD, DCR, or a predefined OAuth client, depending on how the app is
168
+ configured. If your identity provider blocks dynamic redirect URIs, use CIMD
169
+ or pre-register the redirect URL ChatGPT shows on the app management page.
170
+ - **Users have to reauthenticate often.** Check whether your identity provider
171
+ issues refresh tokens. OpenAI's ChatGPT docs call out `offline_access` for
172
+ OpenID Connect providers.
121
173
 
122
174
  ## Related
123
175
 
124
176
  - [Connect MCP clients overview](./overview.mdx)
125
177
  - OpenAI's [Apps SDK documentation](https://developers.openai.com/apps-sdk/)
178
+ - OpenAI's
179
+ [Connect from ChatGPT](https://developers.openai.com/apps-sdk/deploy/connect-chatgpt)
180
+ guide
181
+ - OpenAI's
182
+ [Developer mode and MCP apps in ChatGPT](https://help.openai.com/en/articles/12584461-developer-mode-apps-and-full-mcp-connectors-in-chatgpt-beta)
183
+ article
126
184
  - [OpenAI Apps SDK with Zuplo](../../mcp-server/openai-apps-sdk.mdx)
127
185
  - [Authentication overview](../auth/overview.mdx)
@@ -55,8 +55,8 @@ upstream:
55
55
  stores per-user tokens encrypted at rest.
56
56
  8. The user approves consent. The gateway redirects the client back with an
57
57
  authorization code.
58
- 9. The client exchanges the code at `/oauth/token` and receives an access token
59
- scoped to `mcp:tools`.
58
+ 9. The client exchanges the code at `/__zuplo/oauth/token` and receives an
59
+ access token scoped to `mcp:tools`.
60
60
  10. The client POSTs to the MCP route with the bearer token. The gateway
61
61
  validates the token, attaches the user's upstream credential, and proxies to
62
62
  the upstream MCP server.
@@ -66,9 +66,9 @@ subsequent calls.
66
66
 
67
67
  Three details that come up during debugging:
68
68
 
69
- - The `resource` parameter (RFC 8707) is required on `/oauth/authorize` and
70
- `/oauth/token`. The gateway rejects tokens whose audience doesn't match the
71
- route they're being used against.
69
+ - The `resource` parameter (RFC 8707) is required on `/__zuplo/oauth/authorize`
70
+ and `/__zuplo/oauth/token`. The gateway rejects tokens whose audience doesn't
71
+ match the route they're being used against.
72
72
  - The consent screen lists the upstream the route depends on with a **Connect**
73
73
  button. The user can't approve the grant until the upstream is connected.
74
74
  - The upstream OAuth flow runs once per (user, upstream) pair. Subsequent
@@ -127,9 +127,9 @@ Client registration with the upstream supports two modes:
127
127
 
128
128
  - `clientRegistration: { mode: "auto" }` (the default) — the gateway publishes a
129
129
  per-upstream OAuth Client ID Metadata Document at
130
- `/.well-known/oauth-client/<connection>` and tells the upstream that URL is
131
- the `client_id`. If the upstream doesn't support CIMD, the gateway falls back
132
- to RFC 7591 Dynamic Client Registration.
130
+ `/__zuplo/.well-known/oauth-client/<connection>` and tells the upstream that
131
+ URL is the `client_id`. If the upstream doesn't support CIMD, the gateway
132
+ falls back to RFC 7591 Dynamic Client Registration.
133
133
  - `clientRegistration: { mode: "manual" }` — supply a pre-registered `clientId`
134
134
  and `clientSecret` (and optional auth method).
135
135
 
@@ -168,7 +168,7 @@ project that uses the gateway has the same shape:
168
168
  | Piece | Lives in | Purpose |
169
169
  | ---------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
170
170
  | `compatibilityDate >= 2026-03-01` | `zuplo.jsonc` | Unlocks MCP Gateway features. Required. |
171
- | `McpGatewayPlugin` | `modules/zuplo.runtime.ts` | Registers the OAuth metadata, authorization endpoints, consent page, and upstream connect callbacks. |
171
+ | `McpGatewayPlugin` | `modules/zuplo.runtime.ts` | Registers the OAuth metadata, authorization endpoints, consent page, upstream connect callbacks, and the [read-only MCP Server Registry](./server-registry.mdx). See [`McpGatewayPlugin` reference](../programmable-api/mcp-gateway-plugin.mdx) for all options. |
172
172
  | One MCP OAuth policy | `config/policies.json` | Authenticates inbound MCP requests against your identity provider. One per project — pick the [wrapper for your IdP](./auth/overview.mdx#identity-providers) (Auth0, Cognito, Clerk, Entra, Google, Keycloak, Logto, Okta, OneLogin, Ping, WorkOS) or `mcp-oauth-inbound` for any other OIDC provider. |
173
173
  | One `mcp-token-exchange-inbound` policy per upstream | `config/policies.json` | Resolves the user's upstream credential and attaches it as the upstream `Authorization` header. Omit for non-OAuth upstreams. |
174
174
  | Optional `mcp-capability-filter-inbound` policy | `config/policies.json` | Curates the tools, prompts, resources, and resource templates the route exposes. |
@@ -262,5 +262,7 @@ A few capabilities are intentionally out of scope, at least today:
262
262
  with the full standards table.
263
263
  - [Reference](./reference.mdx) — the full URL catalog, default TTLs,
264
264
  compatibility date, and OAuth metadata extensions.
265
+ - [Server Registry](./server-registry.mdx) — the read-only MCP Server Registry
266
+ API the gateway serves by default.
265
267
  - [Troubleshooting](./troubleshooting.mdx) — the gotchas that catch most people
266
268
  the first time.
@@ -32,7 +32,9 @@ prompt injection or token misuse. Each gateway feature maps to one of five
32
32
  problems that show up the moment a team uses more than one or two MCP servers:
33
33
 
34
34
  1. **Discovery.** A single catalog of approved MCP servers your developers and
35
- agents can connect to. No more sharing OAuth client IDs in Slack.
35
+ agents can connect to. The gateway serves a read-only
36
+ [MCP Server Registry](./server-registry.mdx) API that advertises every
37
+ registered MCP route — no more sharing OAuth client IDs in Slack.
36
38
  2. **Authentication.** Translation from your corporate SSO to whatever each
37
39
  upstream MCP requires. MCP client config files no longer hold raw upstream
38
40
  credentials.
@@ -91,7 +91,7 @@ older project and the build complains about the compatibility date, see
91
91
  "jwksUrl": "http://127.0.0.1:9000/.well-known/jwks.json"
92
92
  },
93
93
  "browserLogin": {
94
- "url": "http://127.0.0.1:9000/oauth/dev-login"
94
+ "url": "http://127.0.0.1:9000/__zuplo/oauth/dev-login"
95
95
  }
96
96
  }
97
97
  }
@@ -100,12 +100,12 @@ older project and the build complains about the compatibility date, see
100
100
 
101
101
  :::caution
102
102
 
103
- `/oauth/dev-login` returns `403 Forbidden` for any request that doesn't
104
- arrive over loopback, so it's safe to leave configured, but only useful in
105
- local dev. Production deployments should use a real OIDC provider through one
106
- of the [IdP wrappers](./auth/overview.mdx#identity-providers). A common
107
- pattern is keeping two OAuth policies (one for production, one for dev) and
108
- selecting between them in `routes.oas.json` by environment.
103
+ `/__zuplo/oauth/dev-login` returns `403 Forbidden` for any request that
104
+ doesn't arrive over loopback, so it's safe to leave configured, but only
105
+ useful in local dev. Production deployments should use a real OIDC provider
106
+ through one of the [IdP wrappers](./auth/overview.mdx#identity-providers). A
107
+ common pattern is keeping two OAuth policies (one for production, one for
108
+ dev) and selecting between them in `routes.oas.json` by environment.
109
109
 
110
110
  :::
111
111
 
@@ -16,37 +16,70 @@ The URLs below are all relative to the gateway origin. For a project deployed to
16
16
  `https://my-gateway.zuplo.dev` with an MCP route at `/mcp/linear-v1`, the public
17
17
  route is `https://my-gateway.zuplo.dev/mcp/linear-v1`.
18
18
 
19
+ The gateway mounts its internal OAuth and upstream-connection action routes
20
+ under the `basePath` configured on the `McpGatewayPlugin`. The default base path
21
+ is `/__zuplo`, which keeps gateway endpoints out of your API's route namespace.
22
+ Discovery documents (`/.well-known/…`) always stay at the origin root because
23
+ RFC 8414 / RFC 9728 locate them relative to the issuer. Pass `basePath: "/"` in
24
+ the plugin options to mount action routes at the origin root instead.
25
+
19
26
  ### Well-known metadata
20
27
 
21
28
  | Path | Methods | Purpose |
22
29
  | ------------------------------------------------------ | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
23
30
  | `/.well-known/oauth-authorization-server` | `GET`, `OPTIONS` | RFC 8414 Authorization Server metadata for the gateway. Issuer is the gateway origin. |
24
- | `/.well-known/oauth-authorization-server/{routePath*}` | `GET`, `OPTIONS` | Per-route AS metadata. The issuer is rebound to the route's canonical URI, and `authorization_endpoint` points at `/oauth/authorize/{routePath}`. |
31
+ | `/.well-known/oauth-authorization-server/{routePath*}` | `GET`, `OPTIONS` | Per-route AS metadata. The issuer is rebound to the route's canonical URI, and `authorization_endpoint` points at `{basePath}/oauth/authorize/{routePath}`. |
25
32
  | `/.well-known/oauth-protected-resource/{routePath*}` | `GET`, `OPTIONS` | RFC 9728 Protected Resource Metadata for an MCP route. Lists `resource`, `resource_name`, `authorization_servers`, `bearer_methods_supported`, `scopes_supported`, and `mcp_protocol_version`. |
26
- | `/.well-known/oauth-client/{connection}` | `GET` | OAuth Client ID Metadata Document the gateway hosts to identify itself to an upstream provider. Requires the `?authProfileId=` query parameter. |
27
33
 
28
34
  These routes are CORS-permissive (`Access-Control-Allow-Origin: *`) because
29
35
  spec-compliant browser-resident MCP clients fetch them cross-origin.
30
36
 
31
37
  ### OAuth endpoints
32
38
 
33
- | Path | Methods | Purpose |
34
- | ------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
35
- | `/oauth/register` | `POST` | RFC 7591 Dynamic Client Registration. Supports `none`, `client_secret_basic`, `client_secret_post`, and `private_key_jwt` token-endpoint auth methods. DCR clients expire after 90 days. |
36
- | `/oauth/authorize` | `GET` | Gateway-wide authorization endpoint. Requires the `resource` parameter unless exactly one MCP route is configured. |
37
- | `/oauth/authorize/{routePath*}` | `GET` | Per-route authorization endpoint. The `resource` is implicit from the path. |
38
- | `/oauth/callback` | `GET` | Browser-login callback from the configured identity provider. Renders the consent page. |
39
- | `/oauth/setup` | `GET`, `POST` | Consent screen. Lists the upstream the requested MCP route depends on. `POST` accepts `decision=continue` / `approve` / `cancel`. |
40
- | `/oauth/token` | `POST` | RFC 6749 token endpoint. Supports `authorization_code` and `refresh_token` grants. |
41
- | `/oauth/revoke` | `POST` | RFC 7009 revocation endpoint. Accepts public-client revocations without authentication. |
42
- | `/oauth/dev-login` | `GET` | Loopback-only dev shortcut. Returns `403` over non-loopback addresses. |
39
+ Paths below use the default `basePath` of `/__zuplo`. Substitute your configured
40
+ `basePath` if you changed it.
41
+
42
+ | Path | Methods | Purpose |
43
+ | ------------------------------------------------ | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
44
+ | `/__zuplo/oauth/register` | `POST` | RFC 7591 Dynamic Client Registration. Supports `none`, `client_secret_basic`, `client_secret_post`, and `private_key_jwt` token-endpoint auth methods. DCR clients expire after 90 days. |
45
+ | `/__zuplo/oauth/authorize` | `GET` | Gateway-wide authorization endpoint. Requires the `resource` parameter unless exactly one MCP route is configured. |
46
+ | `/__zuplo/oauth/authorize/{routePath*}` | `GET` | Per-route authorization endpoint. The `resource` is implicit from the path. |
47
+ | `/__zuplo/oauth/callback` | `GET` | Browser-login callback from the configured identity provider. Renders the consent page. |
48
+ | `/__zuplo/oauth/setup` | `GET`, `POST` | Consent screen. Lists the upstream the requested MCP route depends on. `POST` accepts `decision=continue` / `approve` / `cancel`. |
49
+ | `/__zuplo/oauth/token` | `POST` | RFC 6749 token endpoint. Supports `authorization_code` and `refresh_token` grants. |
50
+ | `/__zuplo/oauth/revoke` | `POST` | RFC 7009 revocation endpoint. Accepts public-client revocations without authentication. |
51
+ | `/__zuplo/oauth/dev-login` | `GET` | Loopback-only dev shortcut. Returns `403` over non-loopback addresses. |
52
+ | `/__zuplo/.well-known/oauth-client/{connection}` | `GET` | OAuth Client ID Metadata Document the gateway hosts to identify itself to an upstream provider. Requires the `?authProfileId=` query parameter. |
43
53
 
44
54
  ### Upstream connection endpoints
45
55
 
46
- | Path | Methods | Purpose |
47
- | ----------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
48
- | `/auth/connections/{connection}/connect` | `GET` | Browser entry to the upstream OAuth flow. With `redirect=true`, returns a 302 to the upstream `/authorize`; otherwise returns `428` with the connect-required payload. |
49
- | `/auth/connections/{connection}/callback` | `GET` | Upstream OAuth callback. Renders a success or failure page. |
56
+ | Path | Methods | Purpose |
57
+ | ------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
58
+ | `/__zuplo/auth/connections/{connection}/connect` | `GET` | Browser entry to the upstream OAuth flow. With `redirect=true`, returns a 302 to the upstream `/authorize`; otherwise returns `428` with the connect-required payload. |
59
+ | `/__zuplo/auth/connections/{connection}/callback` | `GET` | Upstream OAuth callback. Renders a success or failure page. |
60
+
61
+ ### MCP Server Registry
62
+
63
+ The gateway serves a read-only
64
+ [MCP Server Registry API](https://github.com/modelcontextprotocol/registry)
65
+ (v0.1) that advertises every MCP route. Enabled by default; see
66
+ [Server Registry](./server-registry.mdx) for the endpoint reference and
67
+ [`McpGatewayPlugin`](../programmable-api/mcp-gateway-plugin.mdx#registry) for
68
+ configuration.
69
+
70
+ | Path | Methods | Purpose |
71
+ | -------------------------------------------------------------------- | ---------------- | ---------------------------------------------------------------------- |
72
+ | `{registryPath}/v0.1/servers` | `GET`, `OPTIONS` | List servers with `cursor`/`limit`/`search`/`version`/`updated_since`. |
73
+ | `{registryPath}/v0.1/servers/{serverName}/versions` | `GET`, `OPTIONS` | List versions for a single server. |
74
+ | `{registryPath}/v0.1/servers/{serverName}/versions/{version}` | `GET`, `OPTIONS` | Get a specific version (supports `latest` alias). |
75
+ | `{registryPath}/v0.1/publish` | `POST` | `501` — publishing is optional in the spec and not supported. |
76
+ | `{registryPath}/v0.1/servers/{serverName}/versions/{version}` | `PUT`, `DELETE` | `501` — version update/delete is optional in the spec. |
77
+ | `{registryPath}/v0.1/servers/{serverName}/versions/{version}/status` | `PATCH` | `403` — no publish/edit permissions. |
78
+ | `{registryPath}/v0.1/servers/{serverName}/status` | `PATCH` | `403` — no publish/edit permissions. |
79
+
80
+ `{registryPath}` defaults to `/__zuplo/mcp-registry`. Discovery GETs are
81
+ unauthenticated and CORS-permissive. Error bodies use the spec's
82
+ `{"error": "..."}` shape.
50
83
 
51
84
  ### Customer-defined MCP routes
52
85
 
@@ -74,17 +107,17 @@ DCR requests that include any other scope value are rejected with
74
107
  | Refresh token / grant | ~10 years | `gateway.refreshTokenTtlSeconds` on the OAuth policy. | Downstream refresh grants are gateway client sessions, not upstream OAuth token lifetimes. The default is intentionally long so the gateway doesn't impose a shorter session bound than the upstream provider's refresh-token policy already does. |
75
108
  | DCR-registered client | 90 days | Not configurable. | Encourages clients to use CIMD where possible; stale DCR clients age out automatically. |
76
109
  | Authorization code | 60 seconds | Not configurable. | OAuth 2.1 recommendation. |
77
- | `oauth_authorize` state | 15 minutes | `browserLogin.stateTtlSeconds`. | Window between `/oauth/authorize` and `/oauth/callback`. |
110
+ | `oauth_authorize` state | 15 minutes | `browserLogin.stateTtlSeconds`. | Window between `/__zuplo/oauth/authorize` and `/__zuplo/oauth/callback`. |
78
111
 
79
112
  ## Headers
80
113
 
81
114
  ### Required on requests to MCP routes
82
115
 
83
- | Header | Required | Notes |
84
- | --------------------------------------------- | ----------------------- | ----------------------------------------------------------------------------------- |
85
- | `Authorization: Bearer <token>` | Yes (after initial 401) | Opaque access token issued by `/oauth/token`. Tokens in query strings are rejected. |
86
- | `Accept: application/json, text/event-stream` | Yes | Per the Streamable HTTP transport spec. The gateway forwards the body as-is. |
87
- | `MCP-Protocol-Version: 2025-11-25` | Yes after `initialize` | Per the MCP spec. The gateway tracks the current MCP protocol revision. |
116
+ | Header | Required | Notes |
117
+ | --------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------- |
118
+ | `Authorization: Bearer <token>` | Yes (after initial 401) | Opaque access token issued by `/__zuplo/oauth/token`. Tokens in query strings are rejected. |
119
+ | `Accept: application/json, text/event-stream` | Yes | Per the Streamable HTTP transport spec. The gateway forwards the body as-is. |
120
+ | `MCP-Protocol-Version: 2025-11-25` | Yes after `initialize` | Per the MCP spec. The gateway tracks the current MCP protocol revision. |
88
121
 
89
122
  ### Honored when present
90
123
 
@@ -119,9 +152,9 @@ See [Compatibility dates](./code-config/compatibility-dates.mdx).
119
152
  In addition to the standard RFC 8414 / OIDC discovery fields, the gateway
120
153
  publishes a vendor extension:
121
154
 
122
- | Field | Type | Values | Purpose |
123
- | ---------------------------- | ------ | --------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
124
- | `x-zuplo-browser-login-kind` | string | `"federated_oidc"`, `"local_dev"` | Lets client tooling special-case local development configurations (which use `/oauth/dev-login` and a loopback IdP). |
155
+ | Field | Type | Values | Purpose |
156
+ | ---------------------------- | ------ | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
157
+ | `x-zuplo-browser-login-kind` | string | `"federated_oidc"`, `"local_dev"` | Lets client tooling special-case local development configurations (which use `/__zuplo/oauth/dev-login` and a loopback IdP). |
125
158
 
126
159
  ## Public route URL pattern
127
160