Skip to content

Server SDK support for signaling token expiry (401) from tool handlers #1294

@domdomegg

Description

@domdomegg

Summary

Tool handlers that call upstream APIs with delegated OAuth tokens have no way to signal that the token has expired and needs refresh. When an upstream API returns 401, the tool handler can only throw an error, which the SDK wraps in a JSON-RPC error response with HTTP 200. The client never sees HTTP 401 and therefore never triggers token refresh.

Use Case

Consider an MCP server that wraps Gmail's API:

  1. User authenticates via OAuth, server receives access token
  2. User calls gmail_search_messages tool
  3. Server makes request to Gmail API with the access token
  4. Gmail API returns 401 (token expired)
  5. Tool handler throws an error
  6. Problem: SDK catches this and returns JSON-RPC error with HTTP 200
  7. Client receives the error but doesn't know it's an auth error that requires token refresh

The MCP client SDK only triggers token refresh when it sees HTTP 401 responses. Since tool errors are always wrapped in HTTP 200 JSON-RPC responses, the client never refreshes.

Proposed Solution

Similar to #1151 (scope challenges with 403), tool handlers should be able to signal auth errors that result in HTTP 401:

server.registerTool(
  'gmail_search',
  { ... },
  async (args, context) => {
    const response = await callGmailAPI(args);
    
    if (response.status === 401) {
      // Signal that upstream auth failed - should result in HTTP 401
      throw new TokenExpiredError();
      // or: context.signalTokenExpired();
    }
    
    return { content: [...] };
  }
);

This would allow the SDK to return HTTP 401 instead of wrapping in a JSON-RPC error, triggering the client's token refresh flow.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions