Skip to content

fix(mcp): handle transient session endpoint failures without invalidating token - #1558

Open
Sruhvx-jpg wants to merge 1 commit into
supermemoryai:mainfrom
Sruhvx-jpg:fix/mcp-transient-session-error
Open

fix(mcp): handle transient session endpoint failures without invalidating token#1558
Sruhvx-jpg wants to merge 1 commit into
supermemoryai:mainfrom
Sruhvx-jpg:fix/mcp-transient-session-error

Conversation

@Sruhvx-jpg

Copy link
Copy Markdown

Description

Fixes #1551

Previously, validateApiKey collapsed all errors from fetchSession into null, which caused handleMcpRequest to return 401 Unauthorized with WWW-Authenticate: Bearer error="invalid_token". This misled MCP clients into discarding valid API keys during transient backend errors (e.g. 500s, Hyperdrive blips, or timeouts) and forcing users through a browser re-auth flow.

Changes

  1. apps/mcp/src/server/auth/index.ts:
    • Only return null when the session endpoint returns an explicit rejection (401 or 403).
    • Propagate transient errors (5xx, timeouts, network issues).
  2. apps/mcp/src/server/index.ts:
    • Added authUnavailableResponse() returning 503 Service Unavailable with JSON-RPC error code -32000 and message "Authentication service unavailable" (without error="invalid_token").
    • Caught transient authentication failures in handleMcpRequest and returned the 503 response so MCP clients know to retry instead of clearing credentials.
  3. apps/mcp/src/server/auth/index.test.ts:
    • Added unit test cases verifying 403 status returns null and 500 status propagates the error.

Verification

  • Ran bun run test:unit in apps/mcp (all 23 tests passing).
  • Ran bun run check-types (clean, no type errors).
  • Ran bunx biome check apps/mcp (clean, no formatting or lint errors).

Comment thread apps/mcp/src/server/index.ts Outdated
const authUser = isApiKey(token)
? await validateApiKey(token, apiUrl)
: await validateOAuthToken(token, apiUrl, mcpResource)
let authUser: AuthUser | null

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This line uses let to declare authUser, but the variable is only assigned once (inside the try block) and never reassigned afterward. According to the Variables and constants rule, you should use const by default and only use let when reassignment is needed. Since authUser is not reassigned after its initial assignment, it should be declared with const. However, because the assignment happens inside a try block, you may need to restructure the code — for example, by extracting the auth logic into a helper that returns the value, allowing const authUser = await resolveAuthUser(...) at the call site.

Spotted by Graphite (based on custom rule: TypeScript style guide (Google))

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

👍

…ting token

- Distinguish 401/403 explicit rejection from 5xx and network failures in validateApiKey
- Return 503 Service Unavailable with JSON-RPC error when authentication service is temporarily unreachable
- Prevent MCP clients from dropping valid API keys during transient outages
- Add unit tests for 403 status rejection and 500 error propagation

Fixes supermemoryai#1551
@Sruhvx-jpg
Sruhvx-jpg force-pushed the fix/mcp-transient-session-error branch from c9f3201 to 212216f Compare August 19, 2026 09:19
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.

MCP: a transient /v3/session failure is reported to the client as an invalid token

1 participant