Repository navigation
Description
Problem (one or two sentences)
Zoo Code cannot connect to an enterprise OAuth MCP server when the authorization server blocks open dynamic client registration. Users must paste a new short-lived access token into their MCP settings every time the token expires.
Context (who is affected and when)
This affects users who connect Zoo Code to remote Streamable HTTP MCP servers in enterprise OAuth environments. These environments often require a pre-registered public client and an exact loopback redirect URI.
Zoo Code discovers the OAuth server and calls its dynamic registration endpoint. Our PingFederate server protects that endpoint with a privileged registration token. Zoo Code then shows this error before browser sign-in:
Please provide a valid Access Token with the correct scope.
We tested a local change with Zoo Code 3.90.0. Zoo Code connected successfully after it used our registered public client, requested approved scopes, used a fixed callback, and omitted an unsupported resource parameter.
Desired behavior (conceptual, not technical)
Let users select a pre-registered OAuth client for a remote MCP server. Let users set the approved scopes and callback URI. Let users omit or replace the OAuth resource value when their authorization server uses an audience instead.
Zoo Code should complete browser sign-in with PKCE. It should store the access token and refresh token in VS Code Secret Storage. It should refresh an expired access token without asking the user to copy and paste another token.
Keep the current automatic discovery and dynamic registration behavior when users do not provide OAuth settings.
Constraints / preferences (optional)
Do not store access tokens, refresh tokens, registration tokens, or client secrets in the MCP JSON file.
Require PKCE S256 for public clients. Allow HTTP callback URIs only on loopback hosts. Report whether discovery, registration, callback binding, authorization, token exchange, refresh, or MCP connection failed.
A public PKCE client must not require a client secret. If Zoo Code supports confidential clients, store the client secret in VS Code Secret Storage.
Key stored credentials by both MCP server URL and OAuth client ID. This prevents one client configuration from reusing another client's credentials.
Request checklist
- I searched the existing Issues and Discussions for duplicates
- This describes a specific problem with clear context and impact
Zoo Code Task Links (optional)
No response
Acceptance criteria (optional)
Given a remote Streamable HTTP MCP server that requires OAuth
And an authorization server that blocks open dynamic client registration
And a user configures a pre-registered public client ID
When the user connects the MCP server
Then Zoo Code does not call the dynamic registration endpoint
And Zoo Code starts Authorization Code with PKCE
And Zoo Code requests only the configured scopes
And Zoo Code binds and sends the configured loopback redirect URI
Given the OAuth configuration disables the resource indicator
When Zoo Code sends authorization, code exchange, and refresh requests
Then those requests do not contain a resource parameter
Given the authorization server returns an access token and refresh token
When the access token expires
Then Zoo Code refreshes it without manual token copy and paste
And Zoo Code keeps both tokens in VS Code Secret Storage
Given no static OAuth configuration
When Zoo Code connects to an OAuth MCP server
Then the existing discovery and dynamic registration behavior remains unchanged
Proposed approach (optional)
Add optional OAuth settings to Streamable HTTP MCP configuration. A possible shape is:
{
"mcpServers": {
"enterprise-mcp": {
"type": "streamable-http",
"url": "https://mcp.example.com/mcp",
"oauth": {
"clientId": "pre-registered-public-client",
"scope": "openid profile email offline_access",
"redirectUri": "http://localhost:33418/callback",
"resource": false
}
}
}
}
Use clientId to skip dynamic registration. Split scope into the exact requested scopes. Bind the callback listener to redirectUri and send the same value in the authorization and token requests.
Use these resource values:
- Omitted or "auto": keep the current MCP resource behavior.
- false: do not send a resource parameter.
- A string: send that resource value.
We validated this approach locally with Zoo Code 3.90.0. Browser PKCE sign-in completed. The authorization server issued access and refresh tokens. Zoo Code stored the credentials. The MCP server connected. An authenticated tool call succeeded.
Trade-offs / risks (optional)
A fixed callback port can already be in use. Zoo Code should show a clear error and let the user choose another registered loopback URI.
Disabling the resource parameter is less strict than the current automatic MCP behavior. Keep the default behavior standards-based. Require users to choose the override for authorization servers that select tokens by audience.
Static client settings add configuration work. They avoid distributing privileged dynamic-registration tokens and support enterprise authorization policies.
A future option could support client metadata documents. A direct client ID setting is still needed for authorization servers that use conventional pre-registration.
Activity
SoccerField24x7 commentedon Oct 21, 2026
Claiming
fix(mcp): preserve SDK OAuth resource (Zoo-Code-Org#2096)
fix(mcp): keep OAuth requests consistent (Zoo-Code-Org#2096)
fix(mcp): persist OAuth request constraints (Zoo-Code-Org#2096)
test(mcp): cover OAuth creation constraints (Zoo-Code-Org#2096)
fix(mcp): close OAuth lifecycle gaps (Zoo-Code-Org#2096)
fix(mcp): harden callback and token storage (Zoo-Code-Org#2096)
Add static OAuth client settings for MCP servers (Zoo-Code-Org#2129)
Add static OAuth client settings for MCP servers (Zoo-Code-Org#2129)