Skip to content

fix(brains): Claude Code owns the MCP credential via its own OAuth login [BRNS-CORE-015] - #18

Merged
olegshmuelov merged 3 commits into
mainfrom
fix/claude-plugin-mcp-oauth
Jul 30, 2026
Merged

fix(brains): Claude Code owns the MCP credential via its own OAuth login [BRNS-CORE-015]#18
olegshmuelov merged 3 commits into
mainfrom
fix/claude-plugin-mcp-oauth

Conversation

@olegshmuelov

Copy link
Copy Markdown
Contributor

Summary

  • The Claude Code plugin stops carrying a bearer token for MCP: mcpServers.brains.headers is deleted and users sign in with claude mcp login plugin:brains:brains — mirroring the Codex cutover in fix(brains): Codex owns the MCP credential via its own OAuth login #16. A declared Authorization header disables the OAuth login outright, so the two shapes cannot coexist.
  • userConfig.token becomes optional with copy naming its real job (conversation capture and the inbox): a required: true config left unset makes Claude Code silently drop the MCP server, so header removal and the optional token ship as one atomic change.
  • Both manifests move to 2.5.0; README's "Install for Claude Code" is rewritten around the sign-in flow with an ### Optional: token section and an ### Already installed? migration path; the drift nudge adds the sign-in step.
  • The contract suite pins the new shape at Codex-mirror strength: headers absent, inline single server with a key allow-list (a stray in-server key passes claude plugin validate --strict silently), token copy and the pre-Optional README region pinned verbatim, shell blocks must parse, and claude plugin validate --strict runs for real in CI — fail-closed when the CLI is missing — via a pinned @anthropic-ai/claude-code install.

Test

  • Contract suite green at each commit; 68 mutation proofs (flip → red → revert) including stays-green counter-proofs for the validator's blind spots.
  • Live against a local stub authorization server in an isolated CLAUDE_CONFIG_DIR: no-token install leaves the server registered and needing authentication, login completes, bearer replays on reconnect. Verified on Claude Code 2.1.220.

Board: BRNS-CORE-015

@olegshmuelov
olegshmuelov marked this pull request as ready for review July 29, 2026 13:01

@stefan-ssv-labs stefan-ssv-labs left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ review-pr: clean against BRNS-CORE-015.

RaekwonIII
RaekwonIII previously approved these changes Jul 30, 2026

@RaekwonIII RaekwonIII left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed against #16 (its stacked base) — a faithful, correct mirror of the Codex cutover for Claude Code. Approving, with two non-blocking confirmations at the end.

What checks out

  • Manifest changes are right and correctly atomic. Authorization: Bearer ${user_config.token} removed, tokenrequired: false with reframed copy, both manifests → 2.5.0. These must ship together: removing the header while leaving required: true unset makes Claude Code silently DROP the server, and leaving the header with an empty token sends Bearer and disables OAuth. The drift nudge now appends claude mcp login plugin:brains:brains so an already-installed user re-auths after the force-reinstall.
  • The contract test is excellent — and stronger than #16 exactly where #16 was weakest. claude plugin validate --strict runs for real in CI against a pinned @anthropic-ai/claude-code@2.1.220 and FAILS CLOSED when the CLI is missing (assert(!inCI, …)). That's the lesson from #16's SKIP-in-CI resolved-config check applied where the CLI is actually pinnable — nicely done. Plus: verbatim copy pins, bash -n on every README shell block (catches the <your token> angle-bracket-redirection class), a duplicate-root-mcpServers defense (JSON.parse keeps the last dup), and an in-server key allow-list since validate --strict is silent on unknown nested keys. 68 mutation proofs.
  • Valid JSON, only the 6 intended files touched, README slicing headings all present.

Ordering note

#18 is stacked on #16, so it merges after/with it. Worth surfacing that this inverts #16's "guide-live-before-plugin" rule#16 required the web guide (#1066) live first; here the redesigned web guide (#1072) is gated to ship after 2.5.0 publishes. That's fine because #18 carries its own migration guidance (README ### Already installed? + the login-carrying drift nudge), so it's self-sufficient during the window before #1072 is live — just confirm that inversion is intentional.

Two non-blocking confirmations

  1. Existing-user notification. #16 said existing token-based installs are "notified directly." #18 flips Claude Code — likely the larger install base — and the force-reinstall to 2.5.0 breaks existing header auth until the user runs claude mcp login. The drift nudge + README migration path mitigate in-client; is there a direct-notify plan mirroring #16's for the Claude cohort?
  2. Guide-ordering inversion above — confirm intended.

Neither blocks merge.

Base automatically changed from fix/dist-012-codex-oauth to main July 30, 2026 10:51
@olegshmuelov
olegshmuelov dismissed stale reviews from RaekwonIII and stefan-ssv-labs July 30, 2026 10:51

The base branch was changed.

@olegshmuelov
olegshmuelov force-pushed the fix/claude-plugin-mcp-oauth branch 2 times, most recently from f646c37 to af04781 Compare July 30, 2026 11:00
@olegshmuelov
olegshmuelov merged commit e02de9a into main Jul 30, 2026
3 checks passed
@olegshmuelov
olegshmuelov deleted the fix/claude-plugin-mcp-oauth branch July 30, 2026 11:05
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