@mcp-ts/sdk 2.3.2 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-ts/sdk",
3
- "version": "2.3.2",
3
+ "version": "2.3.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -4,9 +4,6 @@ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/
4
4
  import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
5
5
  import {
6
6
  UnauthorizedError as SDKUnauthorizedError,
7
- refreshAuthorization,
8
- discoverOAuthProtectedResourceMetadata,
9
- discoverAuthorizationServerMetadata,
10
7
  } from '@modelcontextprotocol/sdk/client/auth.js';
11
8
  import {
12
9
  ListToolsRequest,
@@ -28,7 +25,6 @@ import {
28
25
  ReadResourceResult,
29
26
  ReadResourceResultSchema,
30
27
  } from '@modelcontextprotocol/sdk/types.js';
31
- import type { OAuthTokens, OAuthClientInformationFull } from '@modelcontextprotocol/sdk/shared/auth.js';
32
28
  import { StorageOAuthClientProvider, type AgentsOAuthProvider } from './storage-oauth-provider.js';
33
29
  import { sanitizeServerLabel } from '../../shared/utils.js';
34
30
  import { Emitter, type McpConnectionEvent, type McpObservabilityEvent, type McpConnectionState } from '../../shared/events.js';
@@ -490,9 +486,6 @@ export class MCPClient {
490
486
  }
491
487
 
492
488
  try {
493
- this.emitProgress('Validating OAuth tokens...');
494
- await this.getValidTokens();
495
-
496
489
  this.emitStateChange('CONNECTING');
497
490
 
498
491
  /** Use the tryConnect loop to handle transport fallbacks */
@@ -933,71 +926,6 @@ export class MCPClient {
933
926
  return await this.client.request(request, ReadResourceResultSchema);
934
927
  }
935
928
 
936
- /**
937
- * Refreshes the OAuth access token using the refresh token
938
- * Discovers OAuth metadata from server and exchanges refresh token for new access token
939
- * @returns True if refresh was successful, false otherwise
940
- */
941
- async refreshToken(): Promise<boolean> {
942
- await this.initialize();
943
-
944
- if (!this.oauthProvider) {
945
- return false;
946
- }
947
-
948
- const tokens = await this.oauthProvider.tokens();
949
- if (!tokens || !tokens.refresh_token) {
950
- return false;
951
- }
952
-
953
- const clientInformation = await this.oauthProvider.clientInformation();
954
- if (!clientInformation) {
955
- return false;
956
- }
957
-
958
- try {
959
- const resourceMetadata = await discoverOAuthProtectedResourceMetadata(this.serverUrl!);
960
- const authServerUrl = resourceMetadata?.authorization_servers?.[0] || this.serverUrl!;
961
- const authMetadata = await discoverAuthorizationServerMetadata(authServerUrl);
962
-
963
- const newTokens = await refreshAuthorization(authServerUrl, {
964
- metadata: authMetadata,
965
- clientInformation,
966
- refreshToken: tokens.refresh_token,
967
- });
968
-
969
- await this.oauthProvider.saveTokens(newTokens);
970
- return true;
971
- } catch (error) {
972
- console.error('[OAuth] Token refresh failed:', error);
973
- return false;
974
- }
975
- }
976
-
977
- /**
978
- * Ensures OAuth tokens are valid, refreshing them if expired
979
- * Called automatically by connect() - rarely needs to be called manually
980
- * @returns True if valid tokens are available, false otherwise
981
- */
982
- async getValidTokens(): Promise<boolean> {
983
- await this.initialize();
984
-
985
- if (!this.oauthProvider) {
986
- return false;
987
- }
988
-
989
- const tokens = await this.oauthProvider.tokens();
990
- if (!tokens) {
991
- return false;
992
- }
993
-
994
- if (this.oauthProvider.isTokenExpired()) {
995
- return await this.refreshToken();
996
- }
997
-
998
- return true;
999
- }
1000
-
1001
929
  /**
1002
930
  * Reconnects to MCP server using existing OAuth provider from Redis
1003
931
  * Used for session restoration in serverless environments
@@ -1154,10 +1082,14 @@ export class MCPClient {
1154
1082
 
1155
1083
  /**
1156
1084
  * Gets MCP server configuration for all active user sessions
1157
- * Loads sessions from Redis, validates OAuth tokens, refreshes if expired
1158
- * Returns ready-to-use configuration with valid auth headers
1085
+ * Loads sessions from storage and returns server connection metadata.
1086
+ * OAuth refresh is handled by SDK transports through their authProvider.
1087
+ * @deprecated This returns legacy connection metadata only and does not
1088
+ * include OAuth tokens or generated Authorization headers. Prefer
1089
+ * MultiSessionClient or explicit MCPClient instances so SDK transports can
1090
+ * own OAuth refresh and reauthorization.
1159
1091
  * @param userId - User ID to fetch sessions for
1160
- * @returns Object keyed by sanitized server labels containing transport, url, headers, etc.
1092
+ * @returns Object keyed by sanitized server labels containing transport and url.
1161
1093
  * @static
1162
1094
  */
1163
1095
  static async getMcpServerConfig(userId: string): Promise<Record<string, any>> {
@@ -1180,34 +1112,6 @@ export class MCPClient {
1180
1112
  return;
1181
1113
  }
1182
1114
 
1183
- // Get OAuth headers if session requires authentication
1184
- let headers: Record<string, string> | undefined;
1185
- try {
1186
- // Inject existing session data to avoid redundant session store reads in initialize()
1187
- const client = new MCPClient({
1188
- userId,
1189
- sessionId,
1190
- serverId: sessionData.serverId,
1191
- serverUrl: sessionData.serverUrl,
1192
- callbackUrl: sessionData.callbackUrl,
1193
- serverName: sessionData.serverName,
1194
- transportType: sessionData.transportType,
1195
- headers: sessionData.headers,
1196
- });
1197
-
1198
- await client.initialize();
1199
-
1200
- const hasValidTokens = await client.getValidTokens();
1201
- if (hasValidTokens && client.oauthProvider) {
1202
- const tokens = await client.oauthProvider.tokens();
1203
- if (tokens?.access_token) {
1204
- headers = { Authorization: `Bearer ${tokens.access_token}` };
1205
- }
1206
- }
1207
- } catch (error) {
1208
- console.warn(`[MCP] Failed to get OAuth tokens for ${sessionId}:`, error);
1209
- }
1210
-
1211
1115
  // Build server config
1212
1116
  const label = sanitizeServerLabel(
1213
1117
  sessionData.serverName || sessionData.serverId || 'server'
@@ -1220,7 +1124,6 @@ export class MCPClient {
1220
1124
  serverName: sessionData.serverName,
1221
1125
  serverLabel: label,
1222
1126
  }),
1223
- ...(headers && { headers }),
1224
1127
  };
1225
1128
  } catch (error) {
1226
1129
  await sessions.delete(userId, sessionId);
@@ -180,7 +180,7 @@ export class NeonStorageBackend implements SessionStore {
180
180
  updatedSession.active ?? false,
181
181
  encryptObject(updatedSession.headers),
182
182
  updatedSession.clientInformation,
183
- encryptObject(updatedSession.tokens),
183
+ updatedSession.tokens === undefined ? null : encryptObject(updatedSession.tokens),
184
184
  updatedSession.codeVerifier,
185
185
  updatedSession.clientId,
186
186
  expiresAt,
@@ -107,7 +107,7 @@ export class SupabaseStorageBackend implements SessionStore {
107
107
  if ('active' in data) updateData.active = data.active;
108
108
  if ('headers' in data) updateData.headers = encryptObject(data.headers);
109
109
  if ('clientInformation' in data) updateData.client_information = data.clientInformation;
110
- if ('tokens' in data) updateData.tokens = encryptObject(data.tokens);
110
+ if ('tokens' in data) updateData.tokens = data.tokens === undefined ? null : encryptObject(data.tokens);
111
111
  if ('codeVerifier' in data) updateData.code_verifier = data.codeVerifier;
112
112
  if ('clientId' in data) updateData.client_id = data.clientId;
113
113