Skip to content

fix(mcp): refresh expired OAuth tokens automatically - #5573

Merged
chengyongru merged 6 commits into
HKUDS:mainfrom
chengyongru:codex/mcp-oauth-refresh
Sep 10, 2026
Merged

chengyongru merged 6 commits into
HKUDS:mainfrom
chengyongru:codex/mcp-oauth-refresh

Conversation

@chengyongru

@chengyongru chengyongru commented Aug 27, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • persist absolute OAuth token expiry, authorization-server metadata, and the issuer bound to newly issued credentials so refresh survives gateway restarts
  • refresh an expired token before the request, or discover the same bound authorization server after a 401 and refresh once before interactive authorization
  • serialize refreshes per MCP server across providers/processes, then atomically compare-and-swap rotated tokens
  • preserve credentials on transient refresh failures; clear only rejected grants/clients and recover from stale token endpoints
  • never send legacy unbound or issuer-mismatched refresh tokens to a newly advertised authorization server; those records require one interactive authorization to establish the binding
  • activate the gateway-owned MCP connection before cleaning up the temporary OAuth probe, so slow cleanup cannot leave the WebUI in a failed state after successful authorization

Context

Addresses NAN-72.

This is a compatibility layer for the MCP Python SDK restart behavior tracked in modelcontextprotocol/python-sdk#3250 and the proposed upstream fix #3328. An explicit contract test makes incompatible SDK changes fail loudly until the workaround can be removed. Removal after the upstream fix lands is tracked in NAN-73.

Current verification (a91c356)

  • Python OAuth and WebUI API tests: 57 passed on MCP SDK 1.30.0; 24 OAuth tests also passed on 1.26.0, including SSE message POST 401 refresh and discovery-outage recovery both in-process and after restart
  • WebUI OAuth tests: 11 passed
  • WebUI production build, Ruff, and BasedPyright: passed
  • Built WebUI on an isolated gateway: MCP catalog reload and failure-to-management interaction passed; the failed credential state used an HTTP response fixture
  • Live third-party OAuth was not rerun; external catalog icons returned 404 or timed out
  • GitHub Actions: 7 jobs passed, 1 conditionally skipped

Previous verification (73140e2)

  • deterministic post-authorization activation regression with blocked probe cleanup: passed
  • focused OAuth, MCP, WebUI, and connection suite: 51 passed
  • live Linear browser OAuth, actual tool call, forced-401 refresh, and cold-restart persistence: passed
  • WebUI production build and isolated Gateway/Apps browser smoke: passed; 0 console errors
  • Ruff on changed files: passed
  • BasedPyright on changed files: 0 errors
  • GitHub Actions: 8/8 jobs passed

@chengyongru chengyongru added bug Something isn't working fix priority: p2 Normal backlog: minor bug, enhancement, docs, cleanup, edge case, or unvalidated proposal. provider test labels Aug 27, 2026
@chengyongru
chengyongru force-pushed the codex/mcp-oauth-refresh branch from 40169c4 to 30a3f9b Compare September 5, 2026 16:37
@chengyongru
chengyongru merged commit 55093dd into HKUDS:main Sep 10, 2026
8 checks passed
@chengyongru
chengyongru deleted the codex/mcp-oauth-refresh branch September 10, 2026 05:27
tertua pushed a commit to tertua/nanobot that referenced this pull request Sep 10, 2026
* fix(mcp): refresh expired OAuth tokens

* fix(mcp): bind refreshed tokens to OAuth issuer

* fix(mcp): activate OAuth tools before probe cleanup

* fix(webui): preserve failed MCP OAuth status

* fix(mcp): preserve OAuth refresh across discovery retries

* test(mcp): align OAuth issuer fixture with SDK validation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working fix priority: p2 Normal backlog: minor bug, enhancement, docs, cleanup, edge case, or unvalidated proposal. provider test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant