Skip to content

MCP oauth: support client_secret_post and client_secret_basic #257277

@kyle-leonhard

Description

@kyle-leonhard

Hi! I'm debugging why client_secret is omitted from calls to my oauth token endpoint when testing locally. Neither the Authorization header or client_secret field are set. The oauth flow works fine with both the MCP inspector and Claude Code, fwiw. I'm unfortunately not able to find any useful trace logs in vscode. When I try to restart the server to test the flow, after one initial failure, the MCP: * logs spin with Waiting for server to respond to initialize request.... This prevents me from switching the MCP: * logs to trace early enough in the flow.

As best as I can tell, the call to exchangeCodeForToken is omitting the client_secret field which implies the _clientSecret field on DynamicAuthProvider is unset when called in registerDynamicAuthProvider or _createWithLoopbackServer. This occurs with both local and remote authorization servers.

It might be nice to respect the token_endpoint_auth_method returned in authorization server metadata. Currently, it's always passed as none when registering a client.

Authorization server metadata:

{
  authorization_endpoint: "http://localhost:3000/oauth/authorize",
  token_endpoint: "http://localhost:3000/oauth/token",
  token_endpoint_auth_methods_supported: ["client_secret_basic"],
  registration_endpoint: "http://localhost:3000/oauth/register",
  issuer: "http://localhost:3000",
  scopes_supported: ["read_write"],
  grant_types_supported: ["authorization_code"],
  response_types_supported: ["code"],
  code_challenge_methods_supported: ["S256"]
}

Client registration is successful, I see the client in the Authentication command. The registration response looks like:

{
  client_id: "...",
  client_name: "Visual Studio Code",
  scope: "read_write",
  token_endpoint_auth_method: "client_secret_basic",
  redirect_uris: ["https://insiders.vscode.dev/redirect", "https://vscode.dev/redirect", "http://localhost/", "http://127.0.0.1/", "http://localhost:33418/", "http://127.0.0.1:33418/"],
  grant_types: ["authorization_code", "refresh_token"],
  response_types: ["code"],
  client_secret_expires_at: 1755746519,
  client_secret: "..." }

The Authorization request and redirect are successful, but the token endpoint rejects the token call because no authorization header (I logged all headers to confirm) or client_secret parameter are set. The token endpoint request looks like:

POST /oauth/token
host: localhost:3000
connection: close
content-type: application/x-www-form-urlencoded
accept: application/json
accept-language: *
sec-fetch-mode: cors
user-agent: node
accept-encoding: gzip, deflate
content-length: 1028
x-request-id: ab07c6f8-d0ce-4b7d-a95f-85b07baac79e

{
  grant_type: "authorization_code",
  client_id: "...",
  redirect_uri: "http://127.0.0.1:33418/",
  code: "...",
  code_verifier: "...")
}

vscode logs show: Error getting token from server metadata: Error: Failed to create authentication token

Metadata

Metadata

Labels

authenticationIssues with the Authentication platformchat-mcpfeature-requestRequest for new features or functionality

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions