Skip to content

fix(mcp): invalidate OAuth tokens when the configured client changes (port of cline/cline#12983) - #84905

Merged
teknium1 merged 1 commit into
mainfrom
cline-port/mcp-oauth-client-change
Aug 13, 2026
Merged

fix(mcp): invalidate OAuth tokens when the configured client changes (port of cline/cline#12983)#84905
teknium1 merged 1 commit into
mainfrom
cline-port/mcp-oauth-client-change

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Editing a server's oauth.client_id / oauth.client_secret in config.yaml now discards the OAuth tokens minted under the previous client identity, instead of leaving stale tokens that fail every request with invalid_client until the user manually wipes ~/.hermes/mcp-tokens/<server>.*.

Port of the "invalidate tokens when OAuth client changes" invariant from cline/cline#12983 (their pre-registered-OAuth-clients-for-remote-MCP feature — hermes already ships pre-registered clients, but not this half).

Root cause: _maybe_preregister_client() unconditionally overwrote client.json with the config-supplied identity and never touched the token files. Pre-registered clients are deliberately exempt from the invalid_client auto-poison path (_maybe_flag_poisoned_client — a config-supplied identity can't be healed by re-registration), so nothing ever recovered: the stale tokens wedged the server permanently.

Changes

  • tools/mcp_oauth.py: new _invalidate_tokens_on_client_change() — compares the on-disk client.json identity (client_id + client_secret) against the incoming config identity before the pre-register overwrite; on mismatch removes tokens.json + meta.json (with a warning log pointing at hermes mcp login). Unchanged identity is a strict no-op; missing/dynamic-registration client.json is a no-op (nothing provably stale).
  • tests/tools/test_mcp_oauth.py: TestInvalidateTokensOnClientChange — 6 tests covering changed client_id, changed secret, unchanged identity (preserved), no prior client info (no-op), and both end-to-end _maybe_preregister_client flows.

Validation

Before After
E2E probe (isolated HERMES_HOME, real _maybe_preregister_client, client-a → client-b) stale access_token minted under client-a still on disk tokens + meta removed, client.json = client-b, warning logged
tests/tools/test_mcp_oauth.py 44 passed 50 passed
tests/tools/test_mcp_oauth_manager.py 9 passed
Sabotage run (wiring line removed) new e2e test FAILS, restored → green

Adjacent open PRs checked for overlap: #35965/#37840 (force browser login for preregistered clients — orthogonal: login UX, not token staleness), #30391 (refresh-rejection cleanup — reactive path; this PR is the proactive config-edit path), #16711 (redirect-URI persistence). None invalidate tokens on config-identity change.

Infographic

mcp-oauth-client-change


Opened by the weekly Cline PR scout (cron). Awaiting review — not merged.

Port from cline/cline#12983 (the 'invalidate tokens when OAuth client
changes' invariant): tokens are minted for a specific client_id, so after
a user edits oauth.client_id / oauth.client_secret in config.yaml the old
tokens can only fail with invalid_client. Pre-registered clients are
deliberately exempt from the invalid_client auto-poison path, so the stale
tokens wedged every request until ~/.hermes/mcp-tokens/<server>.* was
wiped by hand.

_maybe_preregister_client() now compares the on-disk client.json identity
against the incoming config identity before overwriting it and discards
tokens.json + meta.json on a mismatch (with a log line pointing at
hermes mcp login). Unchanged identity is a strict no-op.

Proven live on main with an isolated-HERMES_HOME E2E probe; regression
tests sabotage-verified (fail without the wiring line).
@alt-glitch alt-glitch added type/bug Something isn't working tool/mcp MCP client and OAuth area/auth Authentication, OAuth, credential pools P2 Medium — degraded but workaround exists sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data labels Aug 13, 2026
@teknium1
teknium1 merged commit 3eac116 into main Aug 13, 2026
50 checks passed
@teknium1
teknium1 deleted the cline-port/mcp-oauth-client-change branch August 13, 2026 02:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools P2 Medium — degraded but workaround exists sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data tool/mcp MCP client and OAuth type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants