@mcp-ts/sdk 2.3.4 → 2.4.1
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/README.md +161 -39
- package/dist/adapters/agui-adapter.d.mts +4 -4
- package/dist/adapters/agui-adapter.d.ts +4 -4
- package/dist/adapters/agui-middleware.d.mts +4 -4
- package/dist/adapters/agui-middleware.d.ts +4 -4
- package/dist/adapters/ai-adapter.d.mts +4 -4
- package/dist/adapters/ai-adapter.d.ts +4 -4
- package/dist/adapters/langchain-adapter.d.mts +4 -4
- package/dist/adapters/langchain-adapter.d.ts +4 -4
- package/dist/adapters/mastra-adapter.d.mts +2 -2
- package/dist/adapters/mastra-adapter.d.ts +2 -2
- package/dist/client/index.d.mts +3 -3
- package/dist/client/index.d.ts +3 -3
- package/dist/client/index.js +2 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +2 -2
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/react.d.mts +11 -10
- package/dist/client/react.d.ts +11 -10
- package/dist/client/react.js +66 -26
- package/dist/client/react.js.map +1 -1
- package/dist/client/react.mjs +67 -27
- package/dist/client/react.mjs.map +1 -1
- package/dist/client/vue.d.mts +8 -7
- package/dist/client/vue.d.ts +8 -7
- package/dist/client/vue.js +27 -17
- package/dist/client/vue.js.map +1 -1
- package/dist/client/vue.mjs +27 -17
- package/dist/client/vue.mjs.map +1 -1
- package/dist/{events-CK3N--3g.d.mts → events-C4m7tK1U.d.mts} +0 -1
- package/dist/{events-CK3N--3g.d.ts → events-C4m7tK1U.d.ts} +0 -1
- package/dist/{index-CmjMd2ac.d.ts → index-Ch7ouNSa.d.ts} +3 -3
- package/dist/{index-Cfjsme-a.d.mts → index-L5XoXgsb.d.mts} +3 -3
- package/dist/index.d.mts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +799 -326
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +793 -324
- package/dist/index.mjs.map +1 -1
- package/dist/{multi-session-client-C_kPHpD5.d.ts → multi-session-client-Bwm-efqg.d.ts} +43 -38
- package/dist/{multi-session-client-C7hGqzgM.d.mts → multi-session-client-k-9RvWvi.d.mts} +43 -38
- package/dist/server/index.d.mts +48 -20
- package/dist/server/index.d.ts +48 -20
- package/dist/server/index.js +791 -320
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +787 -319
- package/dist/server/index.mjs.map +1 -1
- package/dist/shared/index.d.mts +10 -9
- package/dist/shared/index.d.ts +10 -9
- package/dist/shared/index.js +7 -5
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +5 -4
- package/dist/shared/index.mjs.map +1 -1
- package/dist/{tool-router-BMzhoNYt.d.ts → tool-router-CZMrOG8J.d.ts} +1 -1
- package/dist/{tool-router-BhHsvBfP.d.mts → tool-router-CuApsDiV.d.mts} +1 -1
- package/dist/{types-CxFaaZrM.d.mts → types-DCk_IF4L.d.mts} +5 -3
- package/dist/{types-CxFaaZrM.d.ts → types-DCk_IF4L.d.ts} +5 -3
- package/migrations/neon/20260513010000_install_mcp_sessions.sql +40 -3
- package/migrations/neon/20260513020000_add_session_cleanup_cron.sql +4 -4
- package/migrations/supabase/20260330195700_install_mcp_sessions.sql +67 -3
- package/migrations/supabase/20260421010000_add_session_cleanup_cron.sql +6 -6
- package/migrations/v2.3.4/neon/20260513010000_install_mcp_sessions.sql +69 -0
- package/migrations/v2.3.4/neon/20260513020000_add_session_cleanup_cron.sql +35 -0
- package/migrations/v2.3.4/supabase/20260330195700_install_mcp_sessions.sql +82 -0
- package/migrations/v2.3.4/supabase/20260421010000_add_session_cleanup_cron.sql +32 -0
- package/package.json +13 -3
- package/src/client/core/sse-client.ts +2 -2
- package/src/client/react/index.ts +1 -1
- package/src/client/react/oauth-popup.tsx +34 -13
- package/src/client/react/use-mcp.ts +19 -45
- package/src/client/utils/session-state.ts +43 -0
- package/src/client/vue/use-mcp.ts +18 -47
- package/src/server/handlers/sse-handler.ts +16 -9
- package/src/server/mcp/multi-session-client.ts +48 -11
- package/src/server/mcp/oauth-client.ts +133 -111
- package/src/server/mcp/storage-oauth-provider.ts +79 -50
- package/src/server/storage/file-backend.ts +74 -18
- package/src/server/storage/index.ts +2 -4
- package/src/server/storage/memory-backend.ts +49 -13
- package/src/server/storage/neon-backend.ts +201 -68
- package/src/server/storage/redis-backend.ts +81 -23
- package/src/server/storage/session-lifecycle.ts +78 -0
- package/src/server/storage/sqlite-backend.ts +89 -15
- package/src/server/storage/supabase-backend.ts +188 -63
- package/src/server/storage/types.ts +49 -16
- package/src/shared/constants.ts +5 -6
- package/src/shared/events.ts +0 -1
- package/src/shared/types.ts +5 -3
- package/src/shared/utils.ts +26 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as Event, M as McpConnectionEvent, d as McpObservabilityEvent, c as McpConnectionState } from './events-
|
|
1
|
+
import { b as Event, M as McpConnectionEvent, d as McpObservabilityEvent, c as McpConnectionState } from './events-C4m7tK1U.js';
|
|
2
2
|
import { ListToolsResult, CallToolResult, ListPromptsResult, GetPromptResult, ListResourcesResult, ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';
|
|
3
3
|
import { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
|
|
4
4
|
import { OAuthClientMetadata, OAuthClientInformationMixed, OAuthClientInformationFull, OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';
|
|
@@ -18,8 +18,6 @@ interface AgentsOAuthProvider extends OAuthClientProvider {
|
|
|
18
18
|
}>;
|
|
19
19
|
consumeState(state: string): Promise<void>;
|
|
20
20
|
deleteCodeVerifier(): Promise<void>;
|
|
21
|
-
isTokenExpired(): boolean;
|
|
22
|
-
setTokenExpiresAt(expiresAt: number): void;
|
|
23
21
|
}
|
|
24
22
|
interface StorageOAuthClientProviderOptions {
|
|
25
23
|
userId: string;
|
|
@@ -51,7 +49,6 @@ declare class StorageOAuthClientProvider implements AgentsOAuthProvider {
|
|
|
51
49
|
private _authUrl;
|
|
52
50
|
private _clientId;
|
|
53
51
|
private onRedirectCallback?;
|
|
54
|
-
private tokenExpiresAt?;
|
|
55
52
|
/**
|
|
56
53
|
* Creates a new session-backed OAuth provider
|
|
57
54
|
* @param options - Provider configuration
|
|
@@ -61,17 +58,17 @@ declare class StorageOAuthClientProvider implements AgentsOAuthProvider {
|
|
|
61
58
|
get clientId(): string | undefined;
|
|
62
59
|
set clientId(clientId_: string | undefined);
|
|
63
60
|
/**
|
|
64
|
-
* Loads OAuth
|
|
61
|
+
* Loads OAuth credentials from the session store
|
|
65
62
|
* @private
|
|
66
63
|
*/
|
|
67
|
-
private
|
|
64
|
+
private getCredentials;
|
|
68
65
|
/**
|
|
69
|
-
* Saves OAuth
|
|
70
|
-
* @param data - Partial OAuth
|
|
66
|
+
* Saves OAuth credentials to the session store
|
|
67
|
+
* @param data - Partial OAuth credentials to save
|
|
71
68
|
* @private
|
|
72
69
|
* @throws Error if session doesn't exist (session must be created by controller layer)
|
|
73
70
|
*/
|
|
74
|
-
private
|
|
71
|
+
private patchCredentials;
|
|
75
72
|
/**
|
|
76
73
|
* Retrieves stored OAuth client information
|
|
77
74
|
*/
|
|
@@ -86,20 +83,18 @@ declare class StorageOAuthClientProvider implements AgentsOAuthProvider {
|
|
|
86
83
|
saveTokens(tokens: OAuthTokens): Promise<void>;
|
|
87
84
|
get authUrl(): string | undefined;
|
|
88
85
|
state(): Promise<string>;
|
|
89
|
-
checkState(
|
|
86
|
+
checkState(state: string): Promise<{
|
|
90
87
|
valid: boolean;
|
|
91
88
|
serverId?: string;
|
|
92
89
|
error?: string;
|
|
93
90
|
}>;
|
|
94
|
-
consumeState(
|
|
91
|
+
consumeState(state: string): Promise<void>;
|
|
95
92
|
redirectToAuthorization(authUrl: URL): Promise<void>;
|
|
96
93
|
invalidateCredentials(scope: "all" | "client" | "tokens" | "verifier"): Promise<void>;
|
|
97
94
|
saveCodeVerifier(verifier: string): Promise<void>;
|
|
98
95
|
codeVerifier(): Promise<string>;
|
|
99
96
|
deleteCodeVerifier(): Promise<void>;
|
|
100
97
|
tokens(): Promise<OAuthTokens | undefined>;
|
|
101
|
-
isTokenExpired(): boolean;
|
|
102
|
-
setTokenExpiresAt(expiresAt: number): void;
|
|
103
98
|
}
|
|
104
99
|
|
|
105
100
|
/**
|
|
@@ -198,11 +193,15 @@ declare class MCPClient {
|
|
|
198
193
|
/**
|
|
199
194
|
* Saves current session state to the session store
|
|
200
195
|
* Creates new session if it doesn't exist, updates if it does
|
|
201
|
-
* @param
|
|
202
|
-
* @param active - Session status marker used to avoid unnecessary TTL rewrites
|
|
196
|
+
* @param status - Session lifecycle status used by storage cleanup
|
|
203
197
|
* @private
|
|
204
198
|
*/
|
|
205
199
|
private saveSession;
|
|
200
|
+
/**
|
|
201
|
+
* Removes transient setup/auth sessions without masking the original error.
|
|
202
|
+
* @private
|
|
203
|
+
*/
|
|
204
|
+
private deleteTransientSession;
|
|
206
205
|
/**
|
|
207
206
|
* Try to connect using available transports
|
|
208
207
|
* @returns The corrected transport type object if successful
|
|
@@ -223,7 +222,7 @@ declare class MCPClient {
|
|
|
223
222
|
* Saves active session to Redis after successful authentication
|
|
224
223
|
* @param authCode - Authorization code received from OAuth callback
|
|
225
224
|
*/
|
|
226
|
-
finishAuth(authCode: string): Promise<void>;
|
|
225
|
+
finishAuth(authCode: string, state?: string): Promise<void>;
|
|
227
226
|
/**
|
|
228
227
|
* Lists all available tools from the connected MCP server
|
|
229
228
|
* @returns List of tools with their schemas and descriptions
|
|
@@ -283,10 +282,15 @@ declare class MCPClient {
|
|
|
283
282
|
*/
|
|
284
283
|
isConnected(): boolean;
|
|
285
284
|
/**
|
|
286
|
-
* Disconnects from the MCP server and cleans up resources
|
|
287
|
-
* Does not remove session from Redis
|
|
285
|
+
* Disconnects from the MCP server and cleans up resources.
|
|
286
|
+
* Does not remove session from Redis — use clearSession() for that.
|
|
287
|
+
*
|
|
288
|
+
* For Streamable HTTP sessions, sends an HTTP DELETE to the MCP endpoint
|
|
289
|
+
* before closing, as recommended by the MCP Streamable HTTP spec
|
|
290
|
+
* (section "Session Management", rule 5). This is best-effort — errors
|
|
291
|
+
* (e.g. server already restarted, 404/405 responses) are silently ignored.
|
|
288
292
|
*/
|
|
289
|
-
disconnect(
|
|
293
|
+
disconnect(): Promise<void>;
|
|
290
294
|
/**
|
|
291
295
|
* Dispose of all event emitters
|
|
292
296
|
* Call this when the client is no longer needed
|
|
@@ -322,19 +326,6 @@ declare class MCPClient {
|
|
|
322
326
|
* @returns Session ID
|
|
323
327
|
*/
|
|
324
328
|
getSessionId(): string;
|
|
325
|
-
/**
|
|
326
|
-
* Gets MCP server configuration for all active user sessions
|
|
327
|
-
* Loads sessions from storage and returns server connection metadata.
|
|
328
|
-
* OAuth refresh is handled by SDK transports through their authProvider.
|
|
329
|
-
* @deprecated This returns legacy connection metadata only and does not
|
|
330
|
-
* include OAuth tokens or generated Authorization headers. Prefer
|
|
331
|
-
* MultiSessionClient or explicit MCPClient instances so SDK transports can
|
|
332
|
-
* own OAuth refresh and reauthorization.
|
|
333
|
-
* @param userId - User ID to fetch sessions for
|
|
334
|
-
* @returns Object keyed by sanitized server labels containing transport and url.
|
|
335
|
-
* @static
|
|
336
|
-
*/
|
|
337
|
-
static getMcpServerConfig(userId: string): Promise<Record<string, any>>;
|
|
338
329
|
}
|
|
339
330
|
|
|
340
331
|
/**
|
|
@@ -384,12 +375,8 @@ declare class MultiSessionClient {
|
|
|
384
375
|
*
|
|
385
376
|
* A session is considered connectable when:
|
|
386
377
|
* - It has a `serverId`, `serverUrl`, and `callbackUrl` (i.e. it was fully initialized)
|
|
387
|
-
* - Its
|
|
388
|
-
* either mid-OAuth flow, auth-pending, or previously failed. We skip those here
|
|
378
|
+
* - Its status is `active`. Pending sessions are skipped here
|
|
389
379
|
* and let the OAuth flow complete separately before we try to reconnect them.
|
|
390
|
-
*
|
|
391
|
-
* Note: Sessions where `active` is `undefined` (legacy records) are included
|
|
392
|
-
* for backwards compatibility.
|
|
393
380
|
*/
|
|
394
381
|
private getActiveSessions;
|
|
395
382
|
/**
|
|
@@ -405,6 +392,9 @@ declare class MultiSessionClient {
|
|
|
405
392
|
* Connects a single session, with built-in deduplication to prevent race conditions.
|
|
406
393
|
*
|
|
407
394
|
* - If a client for this session already exists and is connected, returns immediately.
|
|
395
|
+
* - If the existing client entry is no longer connected (e.g. it was explicitly
|
|
396
|
+
* disconnected), it is evicted so that `establishConnectionWithRetries` creates a
|
|
397
|
+
* fresh transport — preventing "Client already connected" errors from the SDK.
|
|
408
398
|
* - If a connection attempt for this session is already in-flight (e.g. from a
|
|
409
399
|
* concurrent call), it joins the existing promise instead of starting a new one.
|
|
410
400
|
* This is the key concurrency lock — the `connectionPromises` map acts as a
|
|
@@ -436,6 +426,17 @@ declare class MultiSessionClient {
|
|
|
436
426
|
* re-fetching and re-connecting on every request.
|
|
437
427
|
*/
|
|
438
428
|
connect(): Promise<void>;
|
|
429
|
+
/**
|
|
430
|
+
* Drops all cached `MCPClient` instances and reconnects fresh from storage.
|
|
431
|
+
*
|
|
432
|
+
* Call this when downstream MCP servers have expired their transport sessions
|
|
433
|
+
* (e.g. after a remote server restart) and subsequent tool calls return
|
|
434
|
+
* "Session not found. Reconnect without session header." errors.
|
|
435
|
+
*
|
|
436
|
+
* OAuth tokens are preserved in the storage backend — no re-authentication
|
|
437
|
+
* is required. Only the in-memory transport sessions are cleared.
|
|
438
|
+
*/
|
|
439
|
+
reconnect(): Promise<void>;
|
|
439
440
|
/**
|
|
440
441
|
* Returns all currently connected `MCPClient` instances.
|
|
441
442
|
*
|
|
@@ -446,10 +447,14 @@ declare class MultiSessionClient {
|
|
|
446
447
|
/**
|
|
447
448
|
* Gracefully disconnects all active MCP clients and clears the internal client list.
|
|
448
449
|
*
|
|
450
|
+
* For Streamable HTTP sessions, each client sends an HTTP DELETE to its MCP
|
|
451
|
+
* endpoint per the spec before closing locally. All disconnects run in
|
|
452
|
+
* parallel so shutdown is not serialised across many sessions.
|
|
453
|
+
*
|
|
449
454
|
* Call this during server shutdown or when a user logs out to free up
|
|
450
455
|
* underlying transport resources (SSE streams, HTTP connections, etc.).
|
|
451
456
|
*/
|
|
452
|
-
disconnect(): void
|
|
457
|
+
disconnect(): Promise<void>;
|
|
453
458
|
}
|
|
454
459
|
|
|
455
460
|
export { MCPClient as M, StorageOAuthClientProvider as S, MultiSessionClient as a };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as Event, M as McpConnectionEvent, d as McpObservabilityEvent, c as McpConnectionState } from './events-
|
|
1
|
+
import { b as Event, M as McpConnectionEvent, d as McpObservabilityEvent, c as McpConnectionState } from './events-C4m7tK1U.mjs';
|
|
2
2
|
import { ListToolsResult, CallToolResult, ListPromptsResult, GetPromptResult, ListResourcesResult, ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';
|
|
3
3
|
import { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
|
|
4
4
|
import { OAuthClientMetadata, OAuthClientInformationMixed, OAuthClientInformationFull, OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';
|
|
@@ -18,8 +18,6 @@ interface AgentsOAuthProvider extends OAuthClientProvider {
|
|
|
18
18
|
}>;
|
|
19
19
|
consumeState(state: string): Promise<void>;
|
|
20
20
|
deleteCodeVerifier(): Promise<void>;
|
|
21
|
-
isTokenExpired(): boolean;
|
|
22
|
-
setTokenExpiresAt(expiresAt: number): void;
|
|
23
21
|
}
|
|
24
22
|
interface StorageOAuthClientProviderOptions {
|
|
25
23
|
userId: string;
|
|
@@ -51,7 +49,6 @@ declare class StorageOAuthClientProvider implements AgentsOAuthProvider {
|
|
|
51
49
|
private _authUrl;
|
|
52
50
|
private _clientId;
|
|
53
51
|
private onRedirectCallback?;
|
|
54
|
-
private tokenExpiresAt?;
|
|
55
52
|
/**
|
|
56
53
|
* Creates a new session-backed OAuth provider
|
|
57
54
|
* @param options - Provider configuration
|
|
@@ -61,17 +58,17 @@ declare class StorageOAuthClientProvider implements AgentsOAuthProvider {
|
|
|
61
58
|
get clientId(): string | undefined;
|
|
62
59
|
set clientId(clientId_: string | undefined);
|
|
63
60
|
/**
|
|
64
|
-
* Loads OAuth
|
|
61
|
+
* Loads OAuth credentials from the session store
|
|
65
62
|
* @private
|
|
66
63
|
*/
|
|
67
|
-
private
|
|
64
|
+
private getCredentials;
|
|
68
65
|
/**
|
|
69
|
-
* Saves OAuth
|
|
70
|
-
* @param data - Partial OAuth
|
|
66
|
+
* Saves OAuth credentials to the session store
|
|
67
|
+
* @param data - Partial OAuth credentials to save
|
|
71
68
|
* @private
|
|
72
69
|
* @throws Error if session doesn't exist (session must be created by controller layer)
|
|
73
70
|
*/
|
|
74
|
-
private
|
|
71
|
+
private patchCredentials;
|
|
75
72
|
/**
|
|
76
73
|
* Retrieves stored OAuth client information
|
|
77
74
|
*/
|
|
@@ -86,20 +83,18 @@ declare class StorageOAuthClientProvider implements AgentsOAuthProvider {
|
|
|
86
83
|
saveTokens(tokens: OAuthTokens): Promise<void>;
|
|
87
84
|
get authUrl(): string | undefined;
|
|
88
85
|
state(): Promise<string>;
|
|
89
|
-
checkState(
|
|
86
|
+
checkState(state: string): Promise<{
|
|
90
87
|
valid: boolean;
|
|
91
88
|
serverId?: string;
|
|
92
89
|
error?: string;
|
|
93
90
|
}>;
|
|
94
|
-
consumeState(
|
|
91
|
+
consumeState(state: string): Promise<void>;
|
|
95
92
|
redirectToAuthorization(authUrl: URL): Promise<void>;
|
|
96
93
|
invalidateCredentials(scope: "all" | "client" | "tokens" | "verifier"): Promise<void>;
|
|
97
94
|
saveCodeVerifier(verifier: string): Promise<void>;
|
|
98
95
|
codeVerifier(): Promise<string>;
|
|
99
96
|
deleteCodeVerifier(): Promise<void>;
|
|
100
97
|
tokens(): Promise<OAuthTokens | undefined>;
|
|
101
|
-
isTokenExpired(): boolean;
|
|
102
|
-
setTokenExpiresAt(expiresAt: number): void;
|
|
103
98
|
}
|
|
104
99
|
|
|
105
100
|
/**
|
|
@@ -198,11 +193,15 @@ declare class MCPClient {
|
|
|
198
193
|
/**
|
|
199
194
|
* Saves current session state to the session store
|
|
200
195
|
* Creates new session if it doesn't exist, updates if it does
|
|
201
|
-
* @param
|
|
202
|
-
* @param active - Session status marker used to avoid unnecessary TTL rewrites
|
|
196
|
+
* @param status - Session lifecycle status used by storage cleanup
|
|
203
197
|
* @private
|
|
204
198
|
*/
|
|
205
199
|
private saveSession;
|
|
200
|
+
/**
|
|
201
|
+
* Removes transient setup/auth sessions without masking the original error.
|
|
202
|
+
* @private
|
|
203
|
+
*/
|
|
204
|
+
private deleteTransientSession;
|
|
206
205
|
/**
|
|
207
206
|
* Try to connect using available transports
|
|
208
207
|
* @returns The corrected transport type object if successful
|
|
@@ -223,7 +222,7 @@ declare class MCPClient {
|
|
|
223
222
|
* Saves active session to Redis after successful authentication
|
|
224
223
|
* @param authCode - Authorization code received from OAuth callback
|
|
225
224
|
*/
|
|
226
|
-
finishAuth(authCode: string): Promise<void>;
|
|
225
|
+
finishAuth(authCode: string, state?: string): Promise<void>;
|
|
227
226
|
/**
|
|
228
227
|
* Lists all available tools from the connected MCP server
|
|
229
228
|
* @returns List of tools with their schemas and descriptions
|
|
@@ -283,10 +282,15 @@ declare class MCPClient {
|
|
|
283
282
|
*/
|
|
284
283
|
isConnected(): boolean;
|
|
285
284
|
/**
|
|
286
|
-
* Disconnects from the MCP server and cleans up resources
|
|
287
|
-
* Does not remove session from Redis
|
|
285
|
+
* Disconnects from the MCP server and cleans up resources.
|
|
286
|
+
* Does not remove session from Redis — use clearSession() for that.
|
|
287
|
+
*
|
|
288
|
+
* For Streamable HTTP sessions, sends an HTTP DELETE to the MCP endpoint
|
|
289
|
+
* before closing, as recommended by the MCP Streamable HTTP spec
|
|
290
|
+
* (section "Session Management", rule 5). This is best-effort — errors
|
|
291
|
+
* (e.g. server already restarted, 404/405 responses) are silently ignored.
|
|
288
292
|
*/
|
|
289
|
-
disconnect(
|
|
293
|
+
disconnect(): Promise<void>;
|
|
290
294
|
/**
|
|
291
295
|
* Dispose of all event emitters
|
|
292
296
|
* Call this when the client is no longer needed
|
|
@@ -322,19 +326,6 @@ declare class MCPClient {
|
|
|
322
326
|
* @returns Session ID
|
|
323
327
|
*/
|
|
324
328
|
getSessionId(): string;
|
|
325
|
-
/**
|
|
326
|
-
* Gets MCP server configuration for all active user sessions
|
|
327
|
-
* Loads sessions from storage and returns server connection metadata.
|
|
328
|
-
* OAuth refresh is handled by SDK transports through their authProvider.
|
|
329
|
-
* @deprecated This returns legacy connection metadata only and does not
|
|
330
|
-
* include OAuth tokens or generated Authorization headers. Prefer
|
|
331
|
-
* MultiSessionClient or explicit MCPClient instances so SDK transports can
|
|
332
|
-
* own OAuth refresh and reauthorization.
|
|
333
|
-
* @param userId - User ID to fetch sessions for
|
|
334
|
-
* @returns Object keyed by sanitized server labels containing transport and url.
|
|
335
|
-
* @static
|
|
336
|
-
*/
|
|
337
|
-
static getMcpServerConfig(userId: string): Promise<Record<string, any>>;
|
|
338
329
|
}
|
|
339
330
|
|
|
340
331
|
/**
|
|
@@ -384,12 +375,8 @@ declare class MultiSessionClient {
|
|
|
384
375
|
*
|
|
385
376
|
* A session is considered connectable when:
|
|
386
377
|
* - It has a `serverId`, `serverUrl`, and `callbackUrl` (i.e. it was fully initialized)
|
|
387
|
-
* - Its
|
|
388
|
-
* either mid-OAuth flow, auth-pending, or previously failed. We skip those here
|
|
378
|
+
* - Its status is `active`. Pending sessions are skipped here
|
|
389
379
|
* and let the OAuth flow complete separately before we try to reconnect them.
|
|
390
|
-
*
|
|
391
|
-
* Note: Sessions where `active` is `undefined` (legacy records) are included
|
|
392
|
-
* for backwards compatibility.
|
|
393
380
|
*/
|
|
394
381
|
private getActiveSessions;
|
|
395
382
|
/**
|
|
@@ -405,6 +392,9 @@ declare class MultiSessionClient {
|
|
|
405
392
|
* Connects a single session, with built-in deduplication to prevent race conditions.
|
|
406
393
|
*
|
|
407
394
|
* - If a client for this session already exists and is connected, returns immediately.
|
|
395
|
+
* - If the existing client entry is no longer connected (e.g. it was explicitly
|
|
396
|
+
* disconnected), it is evicted so that `establishConnectionWithRetries` creates a
|
|
397
|
+
* fresh transport — preventing "Client already connected" errors from the SDK.
|
|
408
398
|
* - If a connection attempt for this session is already in-flight (e.g. from a
|
|
409
399
|
* concurrent call), it joins the existing promise instead of starting a new one.
|
|
410
400
|
* This is the key concurrency lock — the `connectionPromises` map acts as a
|
|
@@ -436,6 +426,17 @@ declare class MultiSessionClient {
|
|
|
436
426
|
* re-fetching and re-connecting on every request.
|
|
437
427
|
*/
|
|
438
428
|
connect(): Promise<void>;
|
|
429
|
+
/**
|
|
430
|
+
* Drops all cached `MCPClient` instances and reconnects fresh from storage.
|
|
431
|
+
*
|
|
432
|
+
* Call this when downstream MCP servers have expired their transport sessions
|
|
433
|
+
* (e.g. after a remote server restart) and subsequent tool calls return
|
|
434
|
+
* "Session not found. Reconnect without session header." errors.
|
|
435
|
+
*
|
|
436
|
+
* OAuth tokens are preserved in the storage backend — no re-authentication
|
|
437
|
+
* is required. Only the in-memory transport sessions are cleared.
|
|
438
|
+
*/
|
|
439
|
+
reconnect(): Promise<void>;
|
|
439
440
|
/**
|
|
440
441
|
* Returns all currently connected `MCPClient` instances.
|
|
441
442
|
*
|
|
@@ -446,10 +447,14 @@ declare class MultiSessionClient {
|
|
|
446
447
|
/**
|
|
447
448
|
* Gracefully disconnects all active MCP clients and clears the internal client list.
|
|
448
449
|
*
|
|
450
|
+
* For Streamable HTTP sessions, each client sends an HTTP DELETE to its MCP
|
|
451
|
+
* endpoint per the spec before closing locally. All disconnects run in
|
|
452
|
+
* parallel so shutdown is not serialised across many sessions.
|
|
453
|
+
*
|
|
449
454
|
* Call this during server shutdown or when a user logs out to free up
|
|
450
455
|
* underlying transport resources (SSE streams, HTTP connections, etc.).
|
|
451
456
|
*/
|
|
452
|
-
disconnect(): void
|
|
457
|
+
disconnect(): Promise<void>;
|
|
453
458
|
}
|
|
454
459
|
|
|
455
460
|
export { MCPClient as M, StorageOAuthClientProvider as S, MultiSessionClient as a };
|
package/dist/server/index.d.mts
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
export { M as MCPClient, a as MultiSessionClient, S as StorageOAuthClientProvider } from '../multi-session-client-
|
|
1
|
+
export { M as MCPClient, a as MultiSessionClient, S as StorageOAuthClientProvider } from '../multi-session-client-k-9RvWvi.mjs';
|
|
2
2
|
export { U as UnauthorizedError, s as sanitizeServerLabel } from '../utils-DELRKQPU.mjs';
|
|
3
3
|
import { OAuthClientInformationMixed, OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';
|
|
4
4
|
export { OAuthClientInformation, OAuthClientInformationFull, OAuthClientMetadata, OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';
|
|
5
|
-
import { M as McpConnectionEvent, d as McpObservabilityEvent } from '../events-
|
|
6
|
-
export { D as Disposable, E as Emitter, b as Event, c as McpConnectionState } from '../events-
|
|
7
|
-
import { r as McpRpcResponse, q as McpRpcRequest } from '../types-
|
|
8
|
-
export { a as CallToolRequest, b as CallToolResponse, f as ConnectRequest, g as ConnectResponse, n as ListToolsResponse, T as ToolClient, u as ToolClientProvider, v as ToolInfo } from '../types-
|
|
5
|
+
import { M as McpConnectionEvent, d as McpObservabilityEvent } from '../events-C4m7tK1U.mjs';
|
|
6
|
+
export { D as Disposable, E as Emitter, b as Event, c as McpConnectionState } from '../events-C4m7tK1U.mjs';
|
|
7
|
+
import { r as McpRpcResponse, q as McpRpcRequest } from '../types-DCk_IF4L.mjs';
|
|
8
|
+
export { a as CallToolRequest, b as CallToolResponse, f as ConnectRequest, g as ConnectResponse, n as ListToolsResponse, T as ToolClient, u as ToolClientProvider, v as ToolInfo } from '../types-DCk_IF4L.mjs';
|
|
9
9
|
export { CallToolResult, ListToolsResult, Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
10
10
|
import '@modelcontextprotocol/sdk/client/auth.js';
|
|
11
11
|
|
|
12
|
+
interface OAuthState {
|
|
13
|
+
nonce: string;
|
|
14
|
+
sessionId: string;
|
|
15
|
+
serverId: string;
|
|
16
|
+
createdAt: number;
|
|
17
|
+
}
|
|
18
|
+
type SessionStatus = 'pending' | 'active';
|
|
12
19
|
interface Session {
|
|
13
20
|
sessionId: string;
|
|
14
21
|
serverId?: string;
|
|
@@ -17,19 +24,30 @@ interface Session {
|
|
|
17
24
|
transportType: 'sse' | 'streamable-http';
|
|
18
25
|
callbackUrl: string;
|
|
19
26
|
createdAt: number;
|
|
27
|
+
updatedAt?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Storage-owned expiration timestamp for pending/inactive sessions.
|
|
30
|
+
* Active sessions use updatedAt-based dormancy cleanup instead.
|
|
31
|
+
*/
|
|
32
|
+
expiresAt?: number | null;
|
|
20
33
|
userId: string;
|
|
21
34
|
headers?: Record<string, string>;
|
|
35
|
+
authUrl?: string | null;
|
|
22
36
|
/**
|
|
23
|
-
* Session status marker used for
|
|
24
|
-
* -
|
|
25
|
-
*
|
|
26
|
-
* - true: active long-lived session state after successful connection/auth completion
|
|
37
|
+
* Session status marker used for lifecycle cleanup:
|
|
38
|
+
* - pending: short-lived intermediate/auth-pending session state
|
|
39
|
+
* - active: restorable session after successful connection/auth completion
|
|
27
40
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
status?: SessionStatus;
|
|
42
|
+
}
|
|
43
|
+
interface SessionCredentials {
|
|
44
|
+
sessionId: string;
|
|
45
|
+
userId: string;
|
|
46
|
+
clientInformation?: OAuthClientInformationMixed | null;
|
|
47
|
+
tokens?: OAuthTokens | null;
|
|
48
|
+
codeVerifier?: string | null;
|
|
49
|
+
clientId?: string | null;
|
|
50
|
+
oauthState?: OAuthState | null;
|
|
33
51
|
}
|
|
34
52
|
type SessionMutationType = 'create' | 'update' | 'delete';
|
|
35
53
|
interface SessionMutationEvent {
|
|
@@ -39,7 +57,6 @@ interface SessionMutationEvent {
|
|
|
39
57
|
timestamp: number;
|
|
40
58
|
session?: Session;
|
|
41
59
|
patch?: Partial<Session>;
|
|
42
|
-
ttl?: number;
|
|
43
60
|
}
|
|
44
61
|
type SessionMutationListener = (event: SessionMutationEvent) => void | Promise<void>;
|
|
45
62
|
/**
|
|
@@ -57,21 +74,32 @@ interface SessionStore {
|
|
|
57
74
|
/**
|
|
58
75
|
* Creates a new session. Throws if session already exists.
|
|
59
76
|
* @param session - Session data to create
|
|
60
|
-
* @param ttl - Optional TTL in seconds (defaults to backend's default)
|
|
61
77
|
*/
|
|
62
|
-
create(session: Session
|
|
78
|
+
create(session: Session): Promise<void>;
|
|
63
79
|
/**
|
|
64
80
|
* Updates an existing session with partial data. Throws if session does not exist.
|
|
65
81
|
* @param userId - User identifier
|
|
66
82
|
* @param sessionId - Session identifier
|
|
67
83
|
* @param data - Partial session data to update
|
|
68
|
-
* @param ttl - Optional TTL in seconds (defaults to backend's default)
|
|
69
84
|
*/
|
|
70
|
-
update(userId: string, sessionId: string, data: Partial<Session
|
|
85
|
+
update(userId: string, sessionId: string, data: Partial<Session>): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Patches runtime credentials for an existing session.
|
|
88
|
+
* These values are separated from connection metadata in durable SQL stores.
|
|
89
|
+
*/
|
|
90
|
+
patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void>;
|
|
71
91
|
/**
|
|
72
92
|
* Retrieves a session
|
|
73
93
|
*/
|
|
74
94
|
get(userId: string, sessionId: string): Promise<Session | null>;
|
|
95
|
+
/**
|
|
96
|
+
* Retrieves runtime credentials for a session.
|
|
97
|
+
*/
|
|
98
|
+
getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null>;
|
|
99
|
+
/**
|
|
100
|
+
* Clears runtime credentials without removing connection metadata.
|
|
101
|
+
*/
|
|
102
|
+
clearCredentials(userId: string, sessionId: string): Promise<void>;
|
|
75
103
|
/**
|
|
76
104
|
* Gets full session data for all sessions owned by a user
|
|
77
105
|
*/
|
|
@@ -221,7 +249,7 @@ declare class SSEConnectionManager {
|
|
|
221
249
|
/**
|
|
222
250
|
* Cleanup and close all connections
|
|
223
251
|
*/
|
|
224
|
-
dispose(): void
|
|
252
|
+
dispose(): Promise<void>;
|
|
225
253
|
}
|
|
226
254
|
/**
|
|
227
255
|
* Create an SSE endpoint handler compatible with Node.js HTTP frameworks.
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
export { M as MCPClient, a as MultiSessionClient, S as StorageOAuthClientProvider } from '../multi-session-client-
|
|
1
|
+
export { M as MCPClient, a as MultiSessionClient, S as StorageOAuthClientProvider } from '../multi-session-client-Bwm-efqg.js';
|
|
2
2
|
export { U as UnauthorizedError, s as sanitizeServerLabel } from '../utils-DELRKQPU.js';
|
|
3
3
|
import { OAuthClientInformationMixed, OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';
|
|
4
4
|
export { OAuthClientInformation, OAuthClientInformationFull, OAuthClientMetadata, OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';
|
|
5
|
-
import { M as McpConnectionEvent, d as McpObservabilityEvent } from '../events-
|
|
6
|
-
export { D as Disposable, E as Emitter, b as Event, c as McpConnectionState } from '../events-
|
|
7
|
-
import { r as McpRpcResponse, q as McpRpcRequest } from '../types-
|
|
8
|
-
export { a as CallToolRequest, b as CallToolResponse, f as ConnectRequest, g as ConnectResponse, n as ListToolsResponse, T as ToolClient, u as ToolClientProvider, v as ToolInfo } from '../types-
|
|
5
|
+
import { M as McpConnectionEvent, d as McpObservabilityEvent } from '../events-C4m7tK1U.js';
|
|
6
|
+
export { D as Disposable, E as Emitter, b as Event, c as McpConnectionState } from '../events-C4m7tK1U.js';
|
|
7
|
+
import { r as McpRpcResponse, q as McpRpcRequest } from '../types-DCk_IF4L.js';
|
|
8
|
+
export { a as CallToolRequest, b as CallToolResponse, f as ConnectRequest, g as ConnectResponse, n as ListToolsResponse, T as ToolClient, u as ToolClientProvider, v as ToolInfo } from '../types-DCk_IF4L.js';
|
|
9
9
|
export { CallToolResult, ListToolsResult, Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
10
10
|
import '@modelcontextprotocol/sdk/client/auth.js';
|
|
11
11
|
|
|
12
|
+
interface OAuthState {
|
|
13
|
+
nonce: string;
|
|
14
|
+
sessionId: string;
|
|
15
|
+
serverId: string;
|
|
16
|
+
createdAt: number;
|
|
17
|
+
}
|
|
18
|
+
type SessionStatus = 'pending' | 'active';
|
|
12
19
|
interface Session {
|
|
13
20
|
sessionId: string;
|
|
14
21
|
serverId?: string;
|
|
@@ -17,19 +24,30 @@ interface Session {
|
|
|
17
24
|
transportType: 'sse' | 'streamable-http';
|
|
18
25
|
callbackUrl: string;
|
|
19
26
|
createdAt: number;
|
|
27
|
+
updatedAt?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Storage-owned expiration timestamp for pending/inactive sessions.
|
|
30
|
+
* Active sessions use updatedAt-based dormancy cleanup instead.
|
|
31
|
+
*/
|
|
32
|
+
expiresAt?: number | null;
|
|
20
33
|
userId: string;
|
|
21
34
|
headers?: Record<string, string>;
|
|
35
|
+
authUrl?: string | null;
|
|
22
36
|
/**
|
|
23
|
-
* Session status marker used for
|
|
24
|
-
* -
|
|
25
|
-
*
|
|
26
|
-
* - true: active long-lived session state after successful connection/auth completion
|
|
37
|
+
* Session status marker used for lifecycle cleanup:
|
|
38
|
+
* - pending: short-lived intermediate/auth-pending session state
|
|
39
|
+
* - active: restorable session after successful connection/auth completion
|
|
27
40
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
status?: SessionStatus;
|
|
42
|
+
}
|
|
43
|
+
interface SessionCredentials {
|
|
44
|
+
sessionId: string;
|
|
45
|
+
userId: string;
|
|
46
|
+
clientInformation?: OAuthClientInformationMixed | null;
|
|
47
|
+
tokens?: OAuthTokens | null;
|
|
48
|
+
codeVerifier?: string | null;
|
|
49
|
+
clientId?: string | null;
|
|
50
|
+
oauthState?: OAuthState | null;
|
|
33
51
|
}
|
|
34
52
|
type SessionMutationType = 'create' | 'update' | 'delete';
|
|
35
53
|
interface SessionMutationEvent {
|
|
@@ -39,7 +57,6 @@ interface SessionMutationEvent {
|
|
|
39
57
|
timestamp: number;
|
|
40
58
|
session?: Session;
|
|
41
59
|
patch?: Partial<Session>;
|
|
42
|
-
ttl?: number;
|
|
43
60
|
}
|
|
44
61
|
type SessionMutationListener = (event: SessionMutationEvent) => void | Promise<void>;
|
|
45
62
|
/**
|
|
@@ -57,21 +74,32 @@ interface SessionStore {
|
|
|
57
74
|
/**
|
|
58
75
|
* Creates a new session. Throws if session already exists.
|
|
59
76
|
* @param session - Session data to create
|
|
60
|
-
* @param ttl - Optional TTL in seconds (defaults to backend's default)
|
|
61
77
|
*/
|
|
62
|
-
create(session: Session
|
|
78
|
+
create(session: Session): Promise<void>;
|
|
63
79
|
/**
|
|
64
80
|
* Updates an existing session with partial data. Throws if session does not exist.
|
|
65
81
|
* @param userId - User identifier
|
|
66
82
|
* @param sessionId - Session identifier
|
|
67
83
|
* @param data - Partial session data to update
|
|
68
|
-
* @param ttl - Optional TTL in seconds (defaults to backend's default)
|
|
69
84
|
*/
|
|
70
|
-
update(userId: string, sessionId: string, data: Partial<Session
|
|
85
|
+
update(userId: string, sessionId: string, data: Partial<Session>): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Patches runtime credentials for an existing session.
|
|
88
|
+
* These values are separated from connection metadata in durable SQL stores.
|
|
89
|
+
*/
|
|
90
|
+
patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void>;
|
|
71
91
|
/**
|
|
72
92
|
* Retrieves a session
|
|
73
93
|
*/
|
|
74
94
|
get(userId: string, sessionId: string): Promise<Session | null>;
|
|
95
|
+
/**
|
|
96
|
+
* Retrieves runtime credentials for a session.
|
|
97
|
+
*/
|
|
98
|
+
getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null>;
|
|
99
|
+
/**
|
|
100
|
+
* Clears runtime credentials without removing connection metadata.
|
|
101
|
+
*/
|
|
102
|
+
clearCredentials(userId: string, sessionId: string): Promise<void>;
|
|
75
103
|
/**
|
|
76
104
|
* Gets full session data for all sessions owned by a user
|
|
77
105
|
*/
|
|
@@ -221,7 +249,7 @@ declare class SSEConnectionManager {
|
|
|
221
249
|
/**
|
|
222
250
|
* Cleanup and close all connections
|
|
223
251
|
*/
|
|
224
|
-
dispose(): void
|
|
252
|
+
dispose(): Promise<void>;
|
|
225
253
|
}
|
|
226
254
|
/**
|
|
227
255
|
* Create an SSE endpoint handler compatible with Node.js HTTP frameworks.
|