Skip to content

feat(auth): support OAuth 2.0 client_credentials grant type#1231

Open
MukundaKatta wants to merge 1 commit intomodelcontextprotocol:mainfrom
MukundaKatta:feat/oauth-client-credentials
Open

feat(auth): support OAuth 2.0 client_credentials grant type#1231
MukundaKatta wants to merge 1 commit intomodelcontextprotocol:mainfrom
MukundaKatta:feat/oauth-client-credentials

Conversation

@MukundaKatta
Copy link
Copy Markdown

Closes #1225

Why

MCP servers fronted by an API gateway with M2M credentials currently require users to manually obtain a Bearer token outside the inspector and paste it into a custom header. The issue asks for native client_credentials support so the inspector can do this exchange itself.

What

  • New client/src/lib/clientCredentialsAuth.ts exporting:
    • buildClientCredentialsRequest() - pure builder for the RFC 6749 section 4.4 token request (HTTP Basic by default, body fallback, optional scope, optional RFC 8707 resource).
    • exchangeClientCredentials() - performs the POST against the token endpoint, surfaces OAuth error/error_description on failure, returns parsed OAuthTokens.
  • Refactored AuthDebugger to expose two tabs: Authorization Code (existing, unchanged behaviour) and Client Credentials (new). The new tab renders fields for token endpoint, client ID, client secret, optional scope, and a select for Basic vs body client authentication.
  • Tokens obtained via the new flow are saved through the existing DebugInspectorOAuthClientProvider, so the rest of the connection / proxy stack picks them up unchanged. The proxy fetchFn is reused too, so the request goes through the inspector proxy when one is configured (avoids browser CORS on the auth server's token endpoint).

Tested

  • New unit tests in client/src/lib/__tests__/clientCredentialsAuth.test.ts:
    • default Basic auth + body shape
    • scope trimming / omission
    • body-mode credentials
    • URL-encoded special chars in basic credentials
    • successful token round-trip with a mocked fetch
    • error payload surfacing (invalid_client: secret rejected)
    • non-JSON error fallback to status line
  • Existing AuthDebugger tests remain valid: the default tab is authorization_code, so all previously-asserted buttons (Guided OAuth Flow, Quick OAuth Flow, Clear OAuth State, Continue from OAuthFlowProgress) are still rendered.

Manual verification (suggested for reviewers): point the inspector at any MCP server behind an OAuth 2.0 client_credentials gateway (Auth0 M2M, Okta service apps, Keycloak service accounts, etc.), open Authentication Settings -> Client Credentials, fill in token endpoint / client id / secret / optional scope, click "Request Token", confirm the access token is fetched and used by subsequent requests without any header copy/paste.

Add a Client Credentials tab to the AuthDebugger so MCP servers secured
behind an API gateway with M2M credentials can be inspected without
manually pasting a Bearer token. Users provide a token endpoint, client
ID, client secret, and optional scope; tokens are stored via the
existing DebugInspectorOAuthClientProvider so the rest of the stack
picks them up unchanged.

The new helper exchangeClientCredentials is a small, fetchFn-pluggable
RFC 6749 4.4 token request, so it works through the inspector proxy and
is unit-testable. The existing authorization_code flow is unchanged.

Closes modelcontextprotocol#1225
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant