Skip to content

feat(mcp-oauth): support static clientId for servers without DCR#379

Open
proyectoauraorg wants to merge 9 commits into
Zoo-Code-Org:mainfrom
proyectoauraorg:feat/mcp-oauth-static-clientid
Open

feat(mcp-oauth): support static clientId for servers without DCR#379
proyectoauraorg wants to merge 9 commits into
Zoo-Code-Org:mainfrom
proyectoauraorg:feat/mcp-oauth-static-clientid

Conversation

@proyectoauraorg
Copy link
Copy Markdown
Contributor

@proyectoauraorg proyectoauraorg commented May 28, 2026

Related GitHub Issue

Aligned with VS Code 1.122 feature #257415 — MCP OAuth with custom clientId.

Description

Adds optional oauth.clientId field to MCP server configuration. When provided, the OAuth provider uses this clientId directly instead of performing Dynamic Client Registration (DCR). This enables connections to OAuth-protected MCP servers that don't support RFC 7591 DCR.

Use case: Many corporate and self-hosted MCP servers require a pre-registered clientId but don't support DCR. Currently, Zoo Code cannot connect to these servers via OAuth.

Changes:

  • BaseConfigSchema: add oauth.clientId optional field
  • McpOAuthClientProvider: accept clientId in create() options, use it in registerClientIfNeeded() to skip DCR
  • McpHub: pass oauth.clientId from config to the provider
  • Tests: 2 new tests covering static clientId and precedence over cached DCR data

Example configuration in .roo/mcp.json:

{
  "mcpServers": {
    "corporate-server": {
      "type": "streamable-http",
      "url": "https://mcp.corporate.example.com",
      "oauth": {
        "clientId": "my-app-id-12345"
      }
    }
  }
}

Test Procedure

Unit tests (104 passed):

cd src && npx vitest run services/mcp/__tests__/McpOAuthClientProvider.spec.ts services/mcp/__tests__/McpHub.spec.ts
  • McpOAuthClientProvider.spec.ts — 44 tests (42 existing + 2 new for static clientId)
  • McpHub.spec.ts — 60 tests (all existing, schema change verified)

New tests:

  1. should use static clientId instead of performing DCR — verifies clientId is used directly
  2. should use static clientId even when cached data exists — verifies static takes precedence over cached DCR

Pre-Submission Checklist

  • Issue Linked: Aligned with VS Code 1.122 feature.
  • Scope: Focused on static clientId support only.
  • Self-Review: Thorough review performed.
  • Testing: 2 new tests added, 104/104 pass.
  • Documentation Impact: No doc updates needed (self-documenting config field).
  • Contribution Guidelines: Read and agreed.

Documentation Updates

  • No documentation updates are required.

Summary by CodeRabbit

  • New Features

    • OAuth server configuration now supports an optional client identifier field, providing additional flexibility for authentication setup.
  • Tests

    • Added test coverage for the new OAuth client identifier feature, verifying proper handling across various configuration scenarios.

Review Change Stack

proyectoauraorg and others added 3 commits May 26, 2026 00:05
…provider

Merging 12 new test cases covering completePrompt, streaming resilience, and edge cases.
Dependabot bump. Compatible: project requires node>=20.20.2, uuid v14 requires node>=20.
Add optional oauth.clientId field to MCP server configuration schema.
When provided, the OAuth provider uses this clientId directly instead of
performing Dynamic Client Registration (DCR). This enables connections
to OAuth-protected MCP servers that don't support RFC 7591 DCR.

Changes:
- BaseConfigSchema: add oauth.clientId optional field
- McpOAuthClientProvider: accept clientId in create() options,
  use it in registerClientIfNeeded() to skip DCR
- McpHub: pass oauth.clientId from config to the provider
- Tests: 2 new tests covering static clientId and precedence over cache

Aligned with VS Code 1.122 feature: MCP OAuth with custom clientId.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d827c919-6c1a-4b76-8224-df18386b4db8

📥 Commits

Reviewing files that changed from the base of the PR and between 250fd05 and 0fb7fc0.

📒 Files selected for processing (1)
  • src/api/providers/__tests__/mimo.spec.ts
💤 Files with no reviewable changes (1)
  • src/api/providers/tests/mimo.spec.ts

📝 Walkthrough

Walkthrough

MCP server configuration now accepts an optional oauth.clientId field, which McpHub passes to McpOAuthClientProvider.create(). The provider stores this static identifier and uses it directly during client registration, bypassing Dynamic Client Registration when provided. Tests verify the static clientId is used and takes precedence over cached client info.

Changes

Static clientId OAuth Configuration

Layer / File(s) Summary
Configuration contract and hub integration
src/services/mcp/McpHub.ts
ServerConfigSchema now accepts optional oauth.clientId, and McpHub passes this value to McpOAuthClientProvider.create() when establishing streamable-http connections.
Provider static clientId support
src/services/mcp/McpOAuthClientProvider.ts
McpOAuthClientProvider stores optional _staticClientId, create() accepts clientId option, and registerClientIfNeeded() populates _clientInfo directly with the static client_id and redirect URL when present, bypassing DCR and SecretStorage lookup.
Static clientId verification tests
src/services/mcp/__tests__/McpOAuthClientProvider.spec.ts
Vitest cases confirm provided clientId is used directly during registration and that it takes precedence over cached client_info in SecretStorage.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • Zoo-Code-Org/Zoo-Code#1: Extends the same McpHub/McpOAuthClientProvider implementation by plumbing an optional static oauth.clientId into registerClientIfNeeded() to bypass DCR when set.

Suggested reviewers

  • edelauna
  • taltas
  • navedmerchant
  • hannesrudolph
  • JamesRobert20

Poem

🐰 A static client whispers to the auth,
No more registration dance required,
Configuration blooms with optional paths,
OAuth simplified, DCR retired!
hops merrily 🌟

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding support for static clientId in MCP OAuth configuration to enable servers without DCR support.
Description check ✅ Passed The description follows the required template structure with all key sections completed: linked issue, implementation details, test procedure, checklist, and example configuration.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 28, 2026

Codecov Report

❌ Patch coverage is 93.75000% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/services/mcp/McpHub.ts 83.33% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@edelauna
Copy link
Copy Markdown
Contributor

edelauna commented May 28, 2026

Wouldn't this also require a secret?

This would also require the whole normal OAuth 2.0 flow to be available when provided. This is larger than a 3 file change.

@taltas
Copy link
Copy Markdown
Contributor

taltas commented May 29, 2026

Thanks for the contribution. There is also the huge readme file that was committed like your other PRs, we should remove it.

An accidental uuid 11.1.0→14.0.0 bump leaked into this branch and broke the
Windows unit tests: uuid@14 drops the Math.random fallback and now requires
globalThis.crypto.getRandomValues, which the Vitest forks pool on Windows
(Node 20) does not provide. Reverting to ^11.1.0 matches upstream/main and
restores green CI.
@proyectoauraorg
Copy link
Copy Markdown
Contributor Author

Done — removed the stray tmp/README.md (280832c). It was an accidental local file that leaked into the branch. Thanks for flagging it.

@proyectoauraorg
Copy link
Copy Markdown
Contributor Author

Thanks for the careful review.

This change reuses the existing authorization-code + PKCE flow already implemented in McpOAuthClientProvider. The new behavior is limited to allowing a preconfigured clientId from mcp.json for servers that don't support Dynamic Client Registration (DCR), which is why the implementation stays relatively small.

A client secret is not always required here. The provider already negotiates token_endpoint_auth_method, using PKCE-only public clients (none) when supported, and client_secret_post for confidential clients when advertised by the server. So a static clientId without a secret is valid for public-client flows per RFC 8252 / MCP auth expectations.

That said, you're correct that confidential-client setups requiring client_secret_post would need additional configuration beyond a clientId. The token exchange path already supports sending a secret; the current config surface just doesn't expose one yet. If support for non-DCR confidential clients is desired, I can follow up with an optional clientSecret config field.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants