You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A saved OAuth-backed remote MCP connection can be rejected by the upstream MCP endpoint before its locally stored expiry. During remote tool catalog refresh, Executor turns the resulting McpOAuthReauthorizationRequired into { tools: [], incomplete: true }.
The deployed 1.6.0 core then preserves the previous catalog and logs only plugin returned an incomplete tool catalog. Current main improved the detail in #1563 by carrying incompleteReason, but it still classifies the connection as degraded, not expired. When the connection has never produced tools, users still see zero tools without the reconnect state added by #1316.
The MCP SDK also performs Dynamic Client Registration before requesting an authorization redirect because the plugin's OAuthClientProvider returns no saved client information. A noninteractive catalog refresh cannot complete that redirect, so the refresh can register a fresh OAuth client and abandon it.
PR #1316 fixed the adjacent human reconnect handoff and expired health rendering. Current main still catches this typed failure in packages/plugins/mcp/src/sdk/plugin.ts inside resolveTools and returns it as an incomplete catalog with degraded health.
Reproduction
Observed on self-host 1.6.0 with a saved PostHog MCP OAuth connection:
Complete the PostHog OAuth connection successfully.
Have the upstream endpoint reject the saved bearer while Executor still considers it unexpired.
Refresh the connection's tools.
Executor returns an empty catalog with degraded health and logs plugin returned an incomplete tool catalog.
Temporary instrumentation around the real Executor 1.6.0 MCP transport produced this sanitized sequence:
POST https://mcp.posthog.com/mcp -> 401
GET https://mcp.posthog.com/.well-known/oauth-protected-resource/mcp -> 200
GET https://oauth.posthog.com/.well-known/oauth-authorization-server -> 200
POST https://oauth.posthog.com/oauth/register/ -> 201
McpToolDiscoveryError: Failed connecting to MCP server: MCP OAuth re-authorization required
The initial 401 had no WWW-Authenticate header and no insufficient_scope indication. Executor never sent tools/list.
Current code path
discoverTools preserves the connector failure as McpToolDiscoveryError. On current main, mcpPlugin().resolveTools catches every discovery error and returns an incomplete result with a human-readable reason:
Core's tool-sync health path maps every incomplete result to status: "degraded", so the typed reconnect condition is still lost even though its message now survives.
Bug description
A saved OAuth-backed remote MCP connection can be rejected by the upstream MCP endpoint before its locally stored expiry. During remote tool catalog refresh, Executor turns the resulting
McpOAuthReauthorizationRequiredinto{ tools: [], incomplete: true }.The deployed 1.6.0 core then preserves the previous catalog and logs only
plugin returned an incomplete tool catalog. Currentmainimproved the detail in #1563 by carryingincompleteReason, but it still classifies the connection asdegraded, notexpired. When the connection has never produced tools, users still see zero tools without the reconnect state added by #1316.The MCP SDK also performs Dynamic Client Registration before requesting an authorization redirect because the plugin's
OAuthClientProviderreturns no saved client information. A noninteractive catalog refresh cannot complete that redirect, so the refresh can register a fresh OAuth client and abandon it.PR #1316 fixed the adjacent human reconnect handoff and expired health rendering. Current
mainstill catches this typed failure inpackages/plugins/mcp/src/sdk/plugin.tsinsideresolveToolsand returns it as an incomplete catalog with degraded health.Reproduction
Observed on self-host 1.6.0 with a saved PostHog MCP OAuth connection:
plugin returned an incomplete tool catalog.Temporary instrumentation around the real Executor 1.6.0 MCP transport produced this sanitized sequence:
The initial 401 had no
WWW-Authenticateheader and noinsufficient_scopeindication. Executor never senttools/list.Current code path
discoverToolspreserves the connector failure asMcpToolDiscoveryError. On currentmain,mcpPlugin().resolveToolscatches every discovery error and returns an incomplete result with a human-readable reason:Core's tool-sync health path maps every incomplete result to
status: "degraded", so the typed reconnect condition is still lost even though its message now survives.The plugin's
makeOAuthProvideralso implements:That makes the SDK dynamically register again after the saved bearer is rejected, even though the saved connection already references an OAuth client.
Expected behavior
Suggested regression coverage
Use the repository OAuth/MCP emulators with a server that:
initialize,Assert that refresh:
tools/list,/register,Environment
🤖 This content was generated with AI assistance using GPT-5.6 Sol.