@mcp-ts/sdk 2.4.3 → 2.4.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/dist/adapters/agui-adapter.d.mts +3 -3
- package/dist/adapters/agui-adapter.d.ts +3 -3
- package/dist/adapters/agui-middleware.d.mts +3 -3
- package/dist/adapters/agui-middleware.d.ts +3 -3
- package/dist/adapters/ai-adapter.d.mts +3 -3
- package/dist/adapters/ai-adapter.d.ts +3 -3
- package/dist/adapters/langchain-adapter.d.mts +3 -3
- package/dist/adapters/langchain-adapter.d.ts +3 -3
- package/dist/adapters/mastra-adapter.d.mts +2 -2
- package/dist/adapters/mastra-adapter.d.ts +2 -2
- package/dist/client/index.d.mts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/client/react.d.mts +4 -5
- package/dist/client/react.d.ts +4 -5
- package/dist/client/react.js.map +1 -1
- package/dist/client/react.mjs.map +1 -1
- package/dist/client/vue.d.mts +4 -5
- package/dist/client/vue.d.ts +4 -5
- package/dist/client/vue.js.map +1 -1
- package/dist/client/vue.mjs.map +1 -1
- package/dist/{index-B8kJSrBJ.d.ts → index-CZk2gu2E.d.ts} +1 -1
- package/dist/{index-DiJsm_lK.d.mts → index-CkM3p0eE.d.mts} +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +36 -56
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +36 -56
- package/dist/index.mjs.map +1 -1
- package/dist/{multi-session-client-DOBvtaQV.d.ts → multi-session-client-ChQrBZhF.d.mts} +4 -5
- package/dist/{multi-session-client-B6hsYO8V.d.mts → multi-session-client-QOOPdEVp.d.ts} +4 -5
- package/dist/server/index.d.mts +4 -4
- package/dist/server/index.d.ts +4 -4
- package/dist/server/index.js +36 -56
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +36 -56
- package/dist/server/index.mjs.map +1 -1
- package/dist/shared/index.d.mts +4 -4
- package/dist/shared/index.d.ts +4 -4
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs.map +1 -1
- package/dist/{tool-router-CbG4Tum6.d.mts → tool-router-CGs3IDOJ.d.mts} +1 -1
- package/dist/{tool-router-ChIhPwgP.d.ts → tool-router-DQ-HrD7W.d.ts} +1 -1
- package/dist/{types-CjczQwNX.d.mts → types-Bf-7GOLW.d.mts} +0 -2
- package/dist/{types-CjczQwNX.d.ts → types-Bf-7GOLW.d.ts} +0 -2
- package/package.json +1 -1
- package/src/client/react/use-mcp.ts +0 -1
- package/src/client/vue/use-mcp.ts +0 -1
- package/src/server/mcp/oauth-client.ts +41 -76
- package/src/shared/events.ts +0 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
-
import { A as ToolClientProvider, T as ToolClient } from './types-
|
|
2
|
+
import { A as ToolClientProvider, T as ToolClient } from './types-Bf-7GOLW.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* ToolIndex — Lightweight in-memory search index for MCP tool discovery.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
-
import { A as ToolClientProvider, T as ToolClient } from './types-
|
|
2
|
+
import { A as ToolClientProvider, T as ToolClient } from './types-Bf-7GOLW.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* ToolIndex — Lightweight in-memory search index for MCP tool discovery.
|
|
@@ -2,7 +2,6 @@ import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Simple event emitter pattern for MCP connection events
|
|
5
|
-
* Inspired by Cloudflare's agents pattern but adapted for serverless
|
|
6
5
|
*/
|
|
7
6
|
type Disposable = {
|
|
8
7
|
dispose(): void;
|
|
@@ -10,7 +9,6 @@ type Disposable = {
|
|
|
10
9
|
type Event<T> = (listener: (event: T) => void) => Disposable;
|
|
11
10
|
/**
|
|
12
11
|
* Event emitter class for type-safe event handling
|
|
13
|
-
* Similar to Cloudflare's Emitter but simplified for our use case
|
|
14
12
|
*/
|
|
15
13
|
declare class Emitter<T> {
|
|
16
14
|
private listeners;
|
|
@@ -2,7 +2,6 @@ import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Simple event emitter pattern for MCP connection events
|
|
5
|
-
* Inspired by Cloudflare's agents pattern but adapted for serverless
|
|
6
5
|
*/
|
|
7
6
|
type Disposable = {
|
|
8
7
|
dispose(): void;
|
|
@@ -10,7 +9,6 @@ type Disposable = {
|
|
|
10
9
|
type Event<T> = (listener: (event: T) => void) => Disposable;
|
|
11
10
|
/**
|
|
12
11
|
* Event emitter class for type-safe event handling
|
|
13
|
-
* Similar to Cloudflare's Emitter but simplified for our use case
|
|
14
12
|
*/
|
|
15
13
|
declare class Emitter<T> {
|
|
16
14
|
private listeners;
|
package/package.json
CHANGED
|
@@ -79,7 +79,7 @@ export interface MCPOAuthClientOptions {
|
|
|
79
79
|
* Emits connection lifecycle events for observability
|
|
80
80
|
*/
|
|
81
81
|
export class MCPClient {
|
|
82
|
-
private client: Client
|
|
82
|
+
private client: Client;
|
|
83
83
|
public oauthProvider: AgentsOAuthProvider | null = null;
|
|
84
84
|
private transport: StreamableHTTPClientTransport | SSEClientTransport | null = null;
|
|
85
85
|
private userId: string;
|
|
@@ -131,6 +131,22 @@ export class MCPClient {
|
|
|
131
131
|
this.clientUri = options.clientUri;
|
|
132
132
|
this.logoUri = options.logoUri;
|
|
133
133
|
this.policyUri = options.policyUri;
|
|
134
|
+
|
|
135
|
+
this.client = new Client(
|
|
136
|
+
{
|
|
137
|
+
name: MCP_CLIENT_NAME,
|
|
138
|
+
version: MCP_CLIENT_VERSION,
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
capabilities: {
|
|
142
|
+
extensions: {
|
|
143
|
+
'io.modelcontextprotocol/ui': {
|
|
144
|
+
mimeTypes: ['text/html+mcp'],
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
} as McpAppClientCapabilities,
|
|
148
|
+
}
|
|
149
|
+
);
|
|
134
150
|
}
|
|
135
151
|
|
|
136
152
|
/**
|
|
@@ -275,13 +291,12 @@ export class MCPClient {
|
|
|
275
291
|
}
|
|
276
292
|
|
|
277
293
|
/**
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
* This method is idempotent and safe to call multiple times
|
|
294
|
+
* Ensures session metadata and OAuth provider are loaded.
|
|
295
|
+
* Does NOT create the SDK Client — callers that need one create it themselves.
|
|
281
296
|
* @private
|
|
282
297
|
*/
|
|
283
|
-
private async
|
|
284
|
-
if (this.
|
|
298
|
+
private async ensureSession(): Promise<void> {
|
|
299
|
+
if (this.oauthProvider) {
|
|
285
300
|
return;
|
|
286
301
|
}
|
|
287
302
|
|
|
@@ -336,24 +351,6 @@ export class MCPClient {
|
|
|
336
351
|
});
|
|
337
352
|
}
|
|
338
353
|
|
|
339
|
-
if (!this.client) {
|
|
340
|
-
this.client = new Client(
|
|
341
|
-
{
|
|
342
|
-
name: MCP_CLIENT_NAME,
|
|
343
|
-
version: MCP_CLIENT_VERSION,
|
|
344
|
-
},
|
|
345
|
-
{
|
|
346
|
-
capabilities: {
|
|
347
|
-
extensions: {
|
|
348
|
-
'io.modelcontextprotocol/ui': {
|
|
349
|
-
mimeTypes: ['text/html+mcp'],
|
|
350
|
-
},
|
|
351
|
-
},
|
|
352
|
-
} as McpAppClientCapabilities
|
|
353
|
-
}
|
|
354
|
-
);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
354
|
// Create session in the session store if it doesn't exist yet
|
|
358
355
|
// This is needed BEFORE OAuth flow starts because the OAuth provider
|
|
359
356
|
// will call saveCodeVerifier() which requires the session to exist
|
|
@@ -380,6 +377,8 @@ export class MCPClient {
|
|
|
380
377
|
}
|
|
381
378
|
}
|
|
382
379
|
|
|
380
|
+
|
|
381
|
+
|
|
383
382
|
/**
|
|
384
383
|
* Saves current session state to the session store
|
|
385
384
|
* Creates new session if it doesn't exist, updates if it does
|
|
@@ -509,31 +508,21 @@ export class MCPClient {
|
|
|
509
508
|
* @throws {Error} When connection fails for other reasons
|
|
510
509
|
*/
|
|
511
510
|
async connect(): Promise<void> {
|
|
512
|
-
//
|
|
513
|
-
//
|
|
514
|
-
//
|
|
515
|
-
//
|
|
516
|
-
|
|
517
|
-
// causing "Session not found. Reconnect without session header." errors.
|
|
518
|
-
//
|
|
519
|
-
// We also null out this.client so that initialize() creates a fresh Client
|
|
520
|
-
// instance with a clean transport slot, rather than reusing the old one.
|
|
521
|
-
// The oauthProvider is intentionally preserved — OAuth tokens remain valid
|
|
522
|
-
// across reconnects; only the transport session needs to be renegotiated.
|
|
523
|
-
if (this.client?.transport) {
|
|
511
|
+
// Close any existing transport so we can negotiate a fresh session.
|
|
512
|
+
// The SDK Client throws if asked to connect() while a transport is
|
|
513
|
+
// already attached; close() detaches it cleanly so the same Client
|
|
514
|
+
// instance can be reused.
|
|
515
|
+
if (this.client.transport) {
|
|
524
516
|
this.transport = null;
|
|
525
|
-
try {
|
|
526
|
-
await this.client.close();
|
|
527
|
-
} catch {
|
|
517
|
+
try { await this.client.close(); } catch {
|
|
528
518
|
// Closing a transport that may have already failed is best-effort.
|
|
529
519
|
}
|
|
530
|
-
this.client = null;
|
|
531
520
|
}
|
|
532
521
|
|
|
533
|
-
await this.
|
|
522
|
+
await this.ensureSession();
|
|
534
523
|
|
|
535
|
-
if (!this.
|
|
536
|
-
const error = '
|
|
524
|
+
if (!this.oauthProvider) {
|
|
525
|
+
const error = 'OAuth provider not initialized';
|
|
537
526
|
this.emitError(error, 'connection');
|
|
538
527
|
this.emitStateChange('FAILED');
|
|
539
528
|
throw new Error(error);
|
|
@@ -643,7 +632,7 @@ export class MCPClient {
|
|
|
643
632
|
this.emitStateChange('AUTHENTICATING');
|
|
644
633
|
this.emitProgress('Exchanging authorization code for tokens...');
|
|
645
634
|
|
|
646
|
-
await this.
|
|
635
|
+
await this.ensureSession();
|
|
647
636
|
|
|
648
637
|
if (!this.oauthProvider) {
|
|
649
638
|
const error = 'OAuth provider not initialized';
|
|
@@ -1013,10 +1002,9 @@ export class MCPClient {
|
|
|
1013
1002
|
return await fn();
|
|
1014
1003
|
} catch (error) {
|
|
1015
1004
|
if (!(error instanceof Error && error.message.includes('MCP_SESSION_EXPIRED'))) throw error;
|
|
1016
|
-
if (this.client) {
|
|
1005
|
+
if (this.client.transport) {
|
|
1017
1006
|
try { await this.client.close(); } catch {}
|
|
1018
1007
|
this.transport = null;
|
|
1019
|
-
this.client = null;
|
|
1020
1008
|
}
|
|
1021
1009
|
await this.reconnect();
|
|
1022
1010
|
return await fn();
|
|
@@ -1030,31 +1018,9 @@ export class MCPClient {
|
|
|
1030
1018
|
* @throws {Error} When OAuth provider is not initialized
|
|
1031
1019
|
*/
|
|
1032
1020
|
async reconnect(): Promise<void> {
|
|
1033
|
-
await this.
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
throw new Error('OAuth provider not initialized');
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
// Close the client initialize() may have created — we need a fresh
|
|
1040
|
-
// client that will negotiate a new transport session.
|
|
1041
|
-
if (this.client) {
|
|
1042
|
-
try { await this.client.close(); } catch {}
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
this.client = new Client(
|
|
1046
|
-
{
|
|
1047
|
-
name: MCP_CLIENT_NAME,
|
|
1048
|
-
version: MCP_CLIENT_VERSION,
|
|
1049
|
-
},
|
|
1050
|
-
{ capabilities: {} }
|
|
1051
|
-
);
|
|
1052
|
-
|
|
1053
|
-
// Use default logic to get transport, defaulting to what's stored or auto
|
|
1054
|
-
const tt = this.transportType || 'streamable-http';
|
|
1055
|
-
this.transport = this.getTransport(tt);
|
|
1056
|
-
|
|
1057
|
-
await this.client.connect(this.transport);
|
|
1021
|
+
await this.ensureSession();
|
|
1022
|
+
if (!this.oauthProvider) throw new Error('OAuth provider not initialized');
|
|
1023
|
+
await this.connect();
|
|
1058
1024
|
}
|
|
1059
1025
|
|
|
1060
1026
|
/**
|
|
@@ -1063,7 +1029,7 @@ export class MCPClient {
|
|
|
1063
1029
|
*/
|
|
1064
1030
|
async clearSession(): Promise<void> {
|
|
1065
1031
|
try {
|
|
1066
|
-
await this.
|
|
1032
|
+
await this.ensureSession();
|
|
1067
1033
|
} catch (error) {
|
|
1068
1034
|
console.warn('[MCPClient] Initialization failed during clearSession:', error);
|
|
1069
1035
|
}
|
|
@@ -1081,7 +1047,7 @@ export class MCPClient {
|
|
|
1081
1047
|
* @returns True if connected, false otherwise
|
|
1082
1048
|
*/
|
|
1083
1049
|
isConnected(): boolean {
|
|
1084
|
-
return this.client !==
|
|
1050
|
+
return this.client.transport !== undefined;
|
|
1085
1051
|
}
|
|
1086
1052
|
|
|
1087
1053
|
/**
|
|
@@ -1108,10 +1074,9 @@ export class MCPClient {
|
|
|
1108
1074
|
}
|
|
1109
1075
|
}
|
|
1110
1076
|
|
|
1111
|
-
if (this.client) {
|
|
1112
|
-
this.client.close();
|
|
1077
|
+
if (this.client.transport) {
|
|
1078
|
+
try { await this.client.close(); } catch {}
|
|
1113
1079
|
}
|
|
1114
|
-
this.client = null;
|
|
1115
1080
|
this.oauthProvider = null;
|
|
1116
1081
|
this.transport = null;
|
|
1117
1082
|
|
package/src/shared/events.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Simple event emitter pattern for MCP connection events
|
|
3
|
-
* Inspired by Cloudflare's agents pattern but adapted for serverless
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
5
|
export type Disposable = {
|
|
@@ -11,7 +10,6 @@ export type Event<T> = (listener: (event: T) => void) => Disposable;
|
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* Event emitter class for type-safe event handling
|
|
14
|
-
* Similar to Cloudflare's Emitter but simplified for our use case
|
|
15
13
|
*/
|
|
16
14
|
export class Emitter<T> {
|
|
17
15
|
private listeners: Set<(event: T) => void> = new Set();
|