Document both OAuth client paths for custom MCP servers - #38
Open
tpavlu wants to merge 2 commits into
Open
Conversation
Word-level pass toward simplified technical English. Swaps requires/required and previous for their plainer equivalents on lines this PR introduced. No technical content or product names changed.
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.
What changed and why
The custom MCP server page said OAuth means dynamic client registration, full stop. That is only one of the two client models the server accepts — you can also paste a client ID and secret you registered yourself, plus a short allowlist of extra authorization parameters that exists because some authorization servers (Google's, notably) will not issue a refresh token without one. None of that was documented. This adds an OAuth section covering both client models and refresh behaviour, an Extra authorization parameters section with the allowlist and a worked config, a sentence on one-server-per-config and field-level rejection of unsupported fields, and four new rows in the support table. No existing headings, structure, or correct prose were changed.
Verified
All in
ref-tools/ref:plan-app/server/src/services/mcpOAuthProvider.ts—saveClientInformationstores DCR-registered clients asoauthClientSource: 'dynamic';plan-app/server/src/routes/integrations.ts(/mcp/save, ~L401–416) stores a user-suppliedoauthblock asoauthClientSource: 'pre-registered'.clientMetadatacomment states pre-registered clients keep their own auth method.oauth.clientId/oauth.clientSecretboth required, non-empty strings.plan-app/shared/mcpServerSpec.tsL384–403.access_type,prompt,login_hint,include_granted_scopes.ALLOWED_AUTHORIZATION_PARAMSinplan-app/shared/mcpServerSpec.tsL73–78; anything else returns anunsupported_fielderror at save time (L435–454). The doc comment above it gives the rationale documented here (Google needsaccess_type=offline, optionallyprompt=consent, to issue a refresh token).PROTECTED_AUTHORIZATION_PARAMSinmcpOAuthProvider.tsL37–47 (response_type,client_id,redirect_uri,state,code_challenge,code_challenge_method,resource,scope,nonce) are re-asserted from the SDK-built URL after the extra params are applied.getFreshAccessTokeninmcpOAuthProvider.tsrefreshes on expiry; with no refresh token, or on a failed/unauthorized refresh, it callsmarkNeedsAuth, which sets the server's status toneeds_auth.resolveEffectiveAuthcomputesoauthClientChanged(integrations.tsL238–253);/mcp/saveclears stored tokens in the same write and saves the server asneeds_auth(L417–435, plus theconsentPendinglogic at L373–377).parseMcpServerSpecrejectsnames.length !== 1withserver_count(mcpServerSpec.tsL205–218); anmcpServerswrapper is accepted and unwrapped.STDIO_KEYS(command,args,env,cwd) and any key outsidetype/url/headers/enabled/oauthproduce one diagnostic per offending token (mcpServerSpec.tsL247–294); the file's overview states the fail-closed intent explicitly.mcp_json_panel(which controls the JSON view where anoauthblock can be entered) is enabled at 100% for the production environment.Unverified / omitted
plan-app/client/src/components/settings/McpServersSection.tsx,useMcpServerDraft.ts) is a Form ⇆ JSON tabbed panel: the Form tab has name, URL, and header rows only, and there is no "choose an authentication method" control — OAuth is configurable only in the JSON view (isFormEditablereturns false when anoauthblock is present; the form tab disables with "OAuth fields can only be edited as JSON"). Only the OAuth bullet's claim was corrected; the click path was not rewritten, since it cannot be confirmed without seeing the UI. A follow-up with a screenshot or a walkthrough would unblock rewriting steps 1–6.Conflicts
docs.jsonwas not edited; this PR touchesplans/integrations/custom-mcp.mdxonly, so no conflicts with sibling PRs in this batch are expected.Generated by Claude Code