@mcp-ts/sdk 2.3.3 → 2.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
2
  import { customAlphabet, nanoid } from 'nanoid';
3
3
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
4
4
  import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
5
- import { UnauthorizedError as UnauthorizedError$1, discoverOAuthProtectedResourceMetadata, discoverAuthorizationServerMetadata, refreshAuthorization } from '@modelcontextprotocol/sdk/client/auth.js';
5
+ import { UnauthorizedError as UnauthorizedError$1 } from '@modelcontextprotocol/sdk/client/auth.js';
6
6
  import { ListToolsResultSchema, CallToolResultSchema, ListPromptsResultSchema, GetPromptResultSchema, ListResourcesResultSchema, ReadResourceResultSchema } from '@modelcontextprotocol/sdk/types.js';
7
7
  import * as fs2 from 'fs';
8
8
  import { promises } from 'fs';
@@ -859,7 +859,7 @@ var SupabaseStorageBackend = class {
859
859
  if ("active" in data) updateData.active = data.active;
860
860
  if ("headers" in data) updateData.headers = encryptObject(data.headers);
861
861
  if ("clientInformation" in data) updateData.client_information = data.clientInformation;
862
- if ("tokens" in data) updateData.tokens = encryptObject(data.tokens);
862
+ if ("tokens" in data) updateData.tokens = data.tokens === void 0 ? null : encryptObject(data.tokens);
863
863
  if ("codeVerifier" in data) updateData.code_verifier = data.codeVerifier;
864
864
  if ("clientId" in data) updateData.client_id = data.clientId;
865
865
  const { data: updatedRows, error } = await this.supabase.from("mcp_sessions").update(updateData).eq("user_id", userId).eq("session_id", sessionId).select("id");
@@ -1061,7 +1061,7 @@ var NeonStorageBackend = class {
1061
1061
  updatedSession.active ?? false,
1062
1062
  encryptObject(updatedSession.headers),
1063
1063
  updatedSession.clientInformation,
1064
- encryptObject(updatedSession.tokens),
1064
+ updatedSession.tokens === void 0 ? null : encryptObject(updatedSession.tokens),
1065
1065
  updatedSession.codeVerifier,
1066
1066
  updatedSession.clientId,
1067
1067
  expiresAt,
@@ -1642,14 +1642,7 @@ var RpcErrorCodes = {
1642
1642
  EXECUTION_ERROR: "EXECUTION_ERROR"};
1643
1643
 
1644
1644
  // src/server/mcp/oauth-client.ts
1645
- function isInvalidRefreshTokenError(error) {
1646
- if (!(error instanceof Error)) {
1647
- return false;
1648
- }
1649
- const text = `${error.name} ${error.message}`.toLowerCase();
1650
- return text.includes("invalidgrant") || text.includes("invalid_grant") || text.includes("invalid refresh token") || /refresh\s+token\s+(?:is\s+)?(?:invalid|expired|revoked)/i.test(text);
1651
- }
1652
- var MCPClient = class _MCPClient {
1645
+ var MCPClient = class {
1653
1646
  /**
1654
1647
  * Creates a new MCP client instance
1655
1648
  * Can be initialized with minimal options (userId + sessionId) for session restoration
@@ -1983,8 +1976,6 @@ var MCPClient = class _MCPClient {
1983
1976
  throw new Error(error);
1984
1977
  }
1985
1978
  try {
1986
- this.emitProgress("Validating OAuth tokens...");
1987
- await this.getValidTokens();
1988
1979
  this.emitStateChange("CONNECTING");
1989
1980
  const { transportType } = await this.tryConnect();
1990
1981
  this.transportType = transportType;
@@ -2309,67 +2300,6 @@ var MCPClient = class _MCPClient {
2309
2300
  };
2310
2301
  return await this.client.request(request, ReadResourceResultSchema);
2311
2302
  }
2312
- /**
2313
- * Refreshes the OAuth access token using the refresh token
2314
- * Discovers OAuth metadata from server and exchanges refresh token for new access token
2315
- * @returns True if refresh was successful, false otherwise
2316
- */
2317
- async refreshToken() {
2318
- await this.initialize();
2319
- if (!this.oauthProvider) {
2320
- return false;
2321
- }
2322
- const tokens = await this.oauthProvider.tokens();
2323
- if (!tokens || !tokens.refresh_token) {
2324
- return false;
2325
- }
2326
- const clientInformation = await this.oauthProvider.clientInformation();
2327
- if (!clientInformation) {
2328
- return false;
2329
- }
2330
- try {
2331
- const resourceMetadata = await discoverOAuthProtectedResourceMetadata(this.serverUrl);
2332
- const authServerUrl = resourceMetadata?.authorization_servers?.[0] || this.serverUrl;
2333
- const authMetadata = await discoverAuthorizationServerMetadata(authServerUrl);
2334
- const newTokens = await refreshAuthorization(authServerUrl, {
2335
- metadata: authMetadata,
2336
- clientInformation,
2337
- refreshToken: tokens.refresh_token
2338
- });
2339
- await this.oauthProvider.saveTokens(newTokens);
2340
- return true;
2341
- } catch (error) {
2342
- console.error("[OAuth] Token refresh failed:", error);
2343
- if (isInvalidRefreshTokenError(error)) {
2344
- try {
2345
- await this.oauthProvider.invalidateCredentials?.("tokens");
2346
- this.emitProgress("OAuth refresh token is invalid; requesting reauthorization...");
2347
- } catch (invalidateError) {
2348
- console.warn("[OAuth] Failed to invalidate stale refresh token credentials:", invalidateError);
2349
- }
2350
- }
2351
- return false;
2352
- }
2353
- }
2354
- /**
2355
- * Ensures OAuth tokens are valid, refreshing them if expired
2356
- * Called automatically by connect() - rarely needs to be called manually
2357
- * @returns True if valid tokens are available, false otherwise
2358
- */
2359
- async getValidTokens() {
2360
- await this.initialize();
2361
- if (!this.oauthProvider) {
2362
- return false;
2363
- }
2364
- const tokens = await this.oauthProvider.tokens();
2365
- if (!tokens) {
2366
- return false;
2367
- }
2368
- if (this.oauthProvider.isTokenExpired()) {
2369
- return await this.refreshToken();
2370
- }
2371
- return true;
2372
- }
2373
2303
  /**
2374
2304
  * Reconnects to MCP server using existing OAuth provider from Redis
2375
2305
  * Used for session restoration in serverless environments
@@ -2501,10 +2431,14 @@ var MCPClient = class _MCPClient {
2501
2431
  }
2502
2432
  /**
2503
2433
  * Gets MCP server configuration for all active user sessions
2504
- * Loads sessions from Redis, validates OAuth tokens, refreshes if expired
2505
- * Returns ready-to-use configuration with valid auth headers
2434
+ * Loads sessions from storage and returns server connection metadata.
2435
+ * OAuth refresh is handled by SDK transports through their authProvider.
2436
+ * @deprecated This returns legacy connection metadata only and does not
2437
+ * include OAuth tokens or generated Authorization headers. Prefer
2438
+ * MultiSessionClient or explicit MCPClient instances so SDK transports can
2439
+ * own OAuth refresh and reauthorization.
2506
2440
  * @param userId - User ID to fetch sessions for
2507
- * @returns Object keyed by sanitized server labels containing transport, url, headers, etc.
2441
+ * @returns Object keyed by sanitized server labels containing transport and url.
2508
2442
  * @static
2509
2443
  */
2510
2444
  static async getMcpServerConfig(userId) {
@@ -2518,29 +2452,6 @@ var MCPClient = class _MCPClient {
2518
2452
  await sessions.delete(userId, sessionId);
2519
2453
  return;
2520
2454
  }
2521
- let headers;
2522
- try {
2523
- const client = new _MCPClient({
2524
- userId,
2525
- sessionId,
2526
- serverId: sessionData.serverId,
2527
- serverUrl: sessionData.serverUrl,
2528
- callbackUrl: sessionData.callbackUrl,
2529
- serverName: sessionData.serverName,
2530
- transportType: sessionData.transportType,
2531
- headers: sessionData.headers
2532
- });
2533
- await client.initialize();
2534
- const hasValidTokens = await client.getValidTokens();
2535
- if (hasValidTokens && client.oauthProvider) {
2536
- const tokens = await client.oauthProvider.tokens();
2537
- if (tokens?.access_token) {
2538
- headers = { Authorization: `Bearer ${tokens.access_token}` };
2539
- }
2540
- }
2541
- } catch (error) {
2542
- console.warn(`[MCP] Failed to get OAuth tokens for ${sessionId}:`, error);
2543
- }
2544
2455
  const label = sanitizeServerLabel(
2545
2456
  sessionData.serverName || sessionData.serverId || "server"
2546
2457
  );
@@ -2550,8 +2461,7 @@ var MCPClient = class _MCPClient {
2550
2461
  ...sessionData.serverName && {
2551
2462
  serverName: sessionData.serverName,
2552
2463
  serverLabel: label
2553
- },
2554
- ...headers && { headers }
2464
+ }
2555
2465
  };
2556
2466
  } catch (error) {
2557
2467
  await sessions.delete(userId, sessionId);