feat(mcp): add direct MCP OAuth dynamic client registration - #1413
Open
jhrozek wants to merge 17 commits into
Open
feat(mcp): add direct MCP OAuth dynamic client registration#1413jhrozek wants to merge 17 commits into
jhrozek wants to merge 17 commits into
Conversation
Co-Authored-By: mecatl <noreply@stacklok.com>
Co-Authored-By: mecatl <noreply@stacklok.com>
Co-Authored-By: mecatl <noreply@mecatl.dev>
Co-Authored-By: mecatl <noreply@stacklok.com>
Co-Authored-By: mecatl <mecatl@users.noreply.github.com>
Co-Authored-By: mecatl <mecatl@users.noreply.github.com>
Co-Authored-By: mecatl <mecatl@users.noreply.github.com>
Add explicit registration reset/retry login flags, redacted operator remedies, and the no-refresh qualification procedure. Co-Authored-By: mecatl <noreply@stacklok.com>
Keep the explicit callback lifecycle while satisfying the repository cyclomatic-complexity gate. Co-Authored-By: mecatl <noreply@stacklok.com>
Keep the plan in progress until its missing named proofs, resource audit, review, and live qualification are complete. Co-Authored-By: mecatl <noreply@stacklok.com>
Co-Authored-By: mecatl <noreply@mecatl.dev>
Co-Authored-By: mecatl <noreply@stacklok.com>
Co-Authored-By: mecatl <noreply@stacklok.com>
Validate the current generation grant before registration reset and adopt only a strictly matching ready winner after uncertain registration outcomes. Pin the pending-CAS race matrix with deterministic store and HTTP barriers while retaining the authorization hardening from R01. Co-Authored-By: mecatl <noreply@stacklok.com>
Harden persisted DCR validation and explicit expiry reauthorization. Exercise reset and retry through the public CLI boundary, and restore candidate documentation status pending final qualification. Co-Authored-By: mecatl <noreply@stacklok.com>
Classify uncertain registration outcomes durably, keep server-advertised registration scopes out of local authority, and make operator recovery remedies match the recorded failure stage. Co-Authored-By: mecatl <noreply@stacklok.com>
Co-Authored-By: mecatl <noreply@stacklok.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a direct (non-broker) MCP OAuth client mode that uses RFC 7591 Dynamic
Client Registration, so a desktop operator can point mecatl at a protected
Streamable HTTP MCP server with only an endpoint URL — no ToolHive broker,
no manually pasted client ID/secret.
client: {mode: dcr, dcr: {}}form for a direct/global MCP OAuthprofile, separate from the existing broker/preregistered/CIMD forms.
dynamically registers a public client, then runs the existing
authorization-code/PKCE loopback login flow.
scopes: [openid]andrequest_refresh_token: falseare accepted; an unsolicited refresh tokenfails login before persistence. Resource-bound public-client refresh is
deferred to Support resource-bound public-client OAuth refresh for direct MCP DCR #1355.
generation-bound, CAS-protected records in the existing encrypted local
credential store; explicit
--reset-dcr-registration/--retry-dcr-registrationrecovery flags cover corrupt/interrupted state.egress, exact-issuer-origin validation, redacted errors, and rejection of
the SDK's Basic-auth probe for the restored public client (only the
parameter-form fallback with the exact
client_idis admitted).docs/adr/0325-direct-mcp-dcr.mdanddocs/acceptance/direct-mcp-dcr.mdfor the full decision record andacceptance criteria.
Verification
task lint && task testgreen.connector-gateway.stacklok.dev/gw/mcpwith real browser consent: registration, login, tool discovery/call, and
credential reuse across a mecatui restart all verified. Post-expiry
login-required and re-login/registration-reuse verification is in
progress and will be confirmed before merge.
Fixes: #1265
🤖 Generated with Claude Code