@mcp-ts/sdk 1.3.4 → 1.3.5
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 +404 -400
- package/dist/adapters/agui-adapter.d.mts +1 -1
- package/dist/adapters/agui-adapter.d.ts +1 -1
- package/dist/adapters/agui-middleware.d.mts +1 -1
- package/dist/adapters/agui-middleware.d.ts +1 -1
- package/dist/adapters/ai-adapter.d.mts +1 -1
- package/dist/adapters/ai-adapter.d.ts +1 -1
- package/dist/adapters/langchain-adapter.d.mts +1 -1
- package/dist/adapters/langchain-adapter.d.ts +1 -1
- package/dist/adapters/mastra-adapter.d.mts +1 -1
- package/dist/adapters/mastra-adapter.d.ts +1 -1
- package/dist/client/index.d.mts +1 -0
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.js +14 -5
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +14 -5
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/react.js +15 -6
- package/dist/client/react.js.map +1 -1
- package/dist/client/react.mjs +15 -6
- package/dist/client/react.mjs.map +1 -1
- package/dist/client/vue.js +15 -6
- package/dist/client/vue.js.map +1 -1
- package/dist/client/vue.mjs +15 -6
- package/dist/client/vue.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +201 -158
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +201 -158
- package/dist/index.mjs.map +1 -1
- package/dist/{multi-session-client-FAFpUzZ4.d.ts → multi-session-client-BYLarghq.d.ts} +29 -19
- package/dist/{multi-session-client-DzjmT7FX.d.mts → multi-session-client-CzhMkE0k.d.mts} +29 -19
- package/dist/server/index.d.mts +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +193 -151
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +193 -151
- package/dist/server/index.mjs.map +1 -1
- package/dist/shared/index.d.mts +2 -2
- package/dist/shared/index.d.ts +2 -2
- package/dist/shared/index.js +2 -2
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +2 -2
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client/core/sse-client.ts +371 -354
- package/src/client/react/use-mcp.ts +31 -31
- package/src/client/vue/use-mcp.ts +77 -77
- package/src/server/handlers/nextjs-handler.ts +194 -197
- package/src/server/handlers/sse-handler.ts +62 -111
- package/src/server/mcp/oauth-client.ts +67 -79
- package/src/server/mcp/storage-oauth-provider.ts +71 -38
- package/src/server/storage/index.ts +15 -13
- package/src/server/storage/redis-backend.ts +93 -23
- package/src/server/storage/types.ts +12 -12
- package/src/shared/constants.ts +2 -2
- package/src/shared/event-routing.ts +28 -0
|
@@ -276,36 +276,36 @@ export function useMcp(options: UseMcpOptions): McpClient {
|
|
|
276
276
|
/**
|
|
277
277
|
* Update connections based on event
|
|
278
278
|
*/
|
|
279
|
-
const updateConnectionsFromEvent = useCallback((event: McpConnectionEvent) => {
|
|
280
|
-
if (!isMountedRef.current) return;
|
|
281
|
-
|
|
282
|
-
const isTransientReconnectState = (state: McpConnectionState): boolean =>
|
|
283
|
-
state === 'INITIALIZING' ||
|
|
284
|
-
state === 'VALIDATING' ||
|
|
285
|
-
state === 'RECONNECTING' ||
|
|
286
|
-
state === 'CONNECTING' ||
|
|
287
|
-
state === 'CONNECTED' ||
|
|
288
|
-
state === 'DISCOVERING';
|
|
289
|
-
|
|
290
|
-
setConnections((prev: McpConnection[]) => {
|
|
291
|
-
switch (event.type) {
|
|
292
|
-
case 'state_changed': {
|
|
293
|
-
const existing = prev.find((c: McpConnection) => c.sessionId === event.sessionId);
|
|
294
|
-
if (existing) {
|
|
295
|
-
// In stateless per-request transport, tool calls can emit transient reconnect states.
|
|
296
|
-
// Keep READY sticky to avoid UI flicker from READY -> CONNECTING -> CONNECTED.
|
|
297
|
-
const nextState =
|
|
298
|
-
existing.state === 'READY' && isTransientReconnectState(event.state)
|
|
299
|
-
? existing.state
|
|
300
|
-
: event.state;
|
|
301
|
-
|
|
302
|
-
return prev.map((c: McpConnection) =>
|
|
303
|
-
c.sessionId === event.sessionId ? {
|
|
304
|
-
...c,
|
|
305
|
-
state: nextState,
|
|
306
|
-
// update createdAt if present in event, otherwise keep existing
|
|
307
|
-
createdAt: event.createdAt ? new Date(event.createdAt) : c.createdAt
|
|
308
|
-
} : c
|
|
279
|
+
const updateConnectionsFromEvent = useCallback((event: McpConnectionEvent) => {
|
|
280
|
+
if (!isMountedRef.current) return;
|
|
281
|
+
|
|
282
|
+
const isTransientReconnectState = (state: McpConnectionState): boolean =>
|
|
283
|
+
state === 'INITIALIZING' ||
|
|
284
|
+
state === 'VALIDATING' ||
|
|
285
|
+
state === 'RECONNECTING' ||
|
|
286
|
+
state === 'CONNECTING' ||
|
|
287
|
+
state === 'CONNECTED' ||
|
|
288
|
+
state === 'DISCOVERING';
|
|
289
|
+
|
|
290
|
+
setConnections((prev: McpConnection[]) => {
|
|
291
|
+
switch (event.type) {
|
|
292
|
+
case 'state_changed': {
|
|
293
|
+
const existing = prev.find((c: McpConnection) => c.sessionId === event.sessionId);
|
|
294
|
+
if (existing) {
|
|
295
|
+
// In stateless per-request transport, tool calls can emit transient reconnect states.
|
|
296
|
+
// Keep READY sticky to avoid UI flicker from READY -> CONNECTING -> CONNECTED.
|
|
297
|
+
const nextState =
|
|
298
|
+
existing.state === 'READY' && isTransientReconnectState(event.state)
|
|
299
|
+
? existing.state
|
|
300
|
+
: event.state;
|
|
301
|
+
|
|
302
|
+
return prev.map((c: McpConnection) =>
|
|
303
|
+
c.sessionId === event.sessionId ? {
|
|
304
|
+
...c,
|
|
305
|
+
state: nextState,
|
|
306
|
+
// update createdAt if present in event, otherwise keep existing
|
|
307
|
+
createdAt: event.createdAt ? new Date(event.createdAt) : c.createdAt
|
|
308
|
+
} : c
|
|
309
309
|
);
|
|
310
310
|
} else {
|
|
311
311
|
// Fix: Don't add back disconnected sessions that were just removed
|
|
@@ -602,7 +602,7 @@ export function useMcp(options: UseMcpOptions): McpClient {
|
|
|
602
602
|
const isServerConnected = useCallback(
|
|
603
603
|
(serverId: string) => {
|
|
604
604
|
const conn = getConnectionByServerId(serverId);
|
|
605
|
-
return conn
|
|
605
|
+
return conn ? conn.state === 'CONNECTED' || conn.state === 'DISCOVERING' || conn.state === 'READY' : false;
|
|
606
606
|
},
|
|
607
607
|
[getConnectionByServerId]
|
|
608
608
|
);
|
|
@@ -16,7 +16,7 @@ import type {
|
|
|
16
16
|
SessionInfo,
|
|
17
17
|
} from '../../shared/types';
|
|
18
18
|
|
|
19
|
-
export interface UseMcpOptions {
|
|
19
|
+
export interface UseMcpOptions {
|
|
20
20
|
/**
|
|
21
21
|
* SSE endpoint URL
|
|
22
22
|
*/
|
|
@@ -53,24 +53,24 @@ export interface UseMcpOptions {
|
|
|
53
53
|
* Debug logging callback
|
|
54
54
|
*/
|
|
55
55
|
onLog?: (level: string, message: string, metadata?: Record<string, unknown>) => void;
|
|
56
|
-
/**
|
|
57
|
-
* Optional callback to handle OAuth redirects (e.g. for popup flow)
|
|
58
|
-
* If provided, this will be called instead of window.location.href assignment
|
|
59
|
-
*/
|
|
60
|
-
onRedirect?: (url: string) => void;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Request timeout in milliseconds
|
|
64
|
-
* @default 60000
|
|
65
|
-
*/
|
|
66
|
-
requestTimeout?: number;
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Enable client debug logs.
|
|
70
|
-
* @default false
|
|
71
|
-
*/
|
|
72
|
-
debug?: boolean;
|
|
73
|
-
}
|
|
56
|
+
/**
|
|
57
|
+
* Optional callback to handle OAuth redirects (e.g. for popup flow)
|
|
58
|
+
* If provided, this will be called instead of window.location.href assignment
|
|
59
|
+
*/
|
|
60
|
+
onRedirect?: (url: string) => void;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Request timeout in milliseconds
|
|
64
|
+
* @default 60000
|
|
65
|
+
*/
|
|
66
|
+
requestTimeout?: number;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Enable client debug logs.
|
|
70
|
+
* @default false
|
|
71
|
+
*/
|
|
72
|
+
debug?: boolean;
|
|
73
|
+
}
|
|
74
74
|
|
|
75
75
|
export interface McpConnection {
|
|
76
76
|
sessionId: string;
|
|
@@ -191,16 +191,16 @@ export interface McpClient {
|
|
|
191
191
|
*/
|
|
192
192
|
listResources: (sessionId: string) => Promise<ListResourcesResult>;
|
|
193
193
|
|
|
194
|
-
/**
|
|
195
|
-
* Read a specific resource
|
|
196
|
-
*/
|
|
197
|
-
readResource: (sessionId: string, uri: string) => Promise<unknown>;
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Access the underlying SSEClient instance (for advanced usage like AppHost)
|
|
201
|
-
*/
|
|
202
|
-
sseClient: SSEClient | null;
|
|
203
|
-
}
|
|
194
|
+
/**
|
|
195
|
+
* Read a specific resource
|
|
196
|
+
*/
|
|
197
|
+
readResource: (sessionId: string, uri: string) => Promise<unknown>;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Access the underlying SSEClient instance (for advanced usage like AppHost)
|
|
201
|
+
*/
|
|
202
|
+
sseClient: SSEClient | null;
|
|
203
|
+
}
|
|
204
204
|
|
|
205
205
|
/**
|
|
206
206
|
* Vue Composable for MCP connection management with SSE
|
|
@@ -229,35 +229,35 @@ export function useMcp(options: UseMcpOptions): McpClient {
|
|
|
229
229
|
/**
|
|
230
230
|
* Update connections based on event
|
|
231
231
|
*/
|
|
232
|
-
const updateConnectionsFromEvent = (event: McpConnectionEvent) => {
|
|
233
|
-
if (!isMountedRef.value) return;
|
|
234
|
-
|
|
235
|
-
const isTransientReconnectState = (state: McpConnectionState): boolean =>
|
|
236
|
-
state === 'INITIALIZING' ||
|
|
237
|
-
state === 'VALIDATING' ||
|
|
238
|
-
state === 'RECONNECTING' ||
|
|
239
|
-
state === 'CONNECTING' ||
|
|
240
|
-
state === 'CONNECTED' ||
|
|
241
|
-
state === 'DISCOVERING';
|
|
242
|
-
|
|
243
|
-
switch (event.type) {
|
|
244
|
-
case 'state_changed': {
|
|
245
|
-
const existing = connections.value.find((c) => c.sessionId === event.sessionId);
|
|
246
|
-
if (existing) {
|
|
247
|
-
// In stateless per-request transport, tool calls can emit transient reconnect states.
|
|
248
|
-
// Keep READY sticky to avoid UI flicker from READY -> CONNECTING -> CONNECTED.
|
|
249
|
-
const nextState =
|
|
250
|
-
existing.state === 'READY' && isTransientReconnectState(event.state)
|
|
251
|
-
? existing.state
|
|
252
|
-
: event.state;
|
|
253
|
-
|
|
254
|
-
const index = connections.value.indexOf(existing);
|
|
255
|
-
connections.value[index] = {
|
|
256
|
-
...existing,
|
|
257
|
-
state: nextState,
|
|
258
|
-
// update createdAt if present in event, otherwise keep existing
|
|
259
|
-
createdAt: event.createdAt ? new Date(event.createdAt) : existing.createdAt
|
|
260
|
-
};
|
|
232
|
+
const updateConnectionsFromEvent = (event: McpConnectionEvent) => {
|
|
233
|
+
if (!isMountedRef.value) return;
|
|
234
|
+
|
|
235
|
+
const isTransientReconnectState = (state: McpConnectionState): boolean =>
|
|
236
|
+
state === 'INITIALIZING' ||
|
|
237
|
+
state === 'VALIDATING' ||
|
|
238
|
+
state === 'RECONNECTING' ||
|
|
239
|
+
state === 'CONNECTING' ||
|
|
240
|
+
state === 'CONNECTED' ||
|
|
241
|
+
state === 'DISCOVERING';
|
|
242
|
+
|
|
243
|
+
switch (event.type) {
|
|
244
|
+
case 'state_changed': {
|
|
245
|
+
const existing = connections.value.find((c) => c.sessionId === event.sessionId);
|
|
246
|
+
if (existing) {
|
|
247
|
+
// In stateless per-request transport, tool calls can emit transient reconnect states.
|
|
248
|
+
// Keep READY sticky to avoid UI flicker from READY -> CONNECTING -> CONNECTED.
|
|
249
|
+
const nextState =
|
|
250
|
+
existing.state === 'READY' && isTransientReconnectState(event.state)
|
|
251
|
+
? existing.state
|
|
252
|
+
: event.state;
|
|
253
|
+
|
|
254
|
+
const index = connections.value.indexOf(existing);
|
|
255
|
+
connections.value[index] = {
|
|
256
|
+
...existing,
|
|
257
|
+
state: nextState,
|
|
258
|
+
// update createdAt if present in event, otherwise keep existing
|
|
259
|
+
createdAt: event.createdAt ? new Date(event.createdAt) : existing.createdAt
|
|
260
|
+
};
|
|
261
261
|
} else {
|
|
262
262
|
// Fix: Don't add back disconnected sessions that were just removed
|
|
263
263
|
if (event.state === 'DISCONNECTED') {
|
|
@@ -384,10 +384,10 @@ export function useMcp(options: UseMcpOptions): McpClient {
|
|
|
384
384
|
clientRef.value.disconnect();
|
|
385
385
|
}
|
|
386
386
|
|
|
387
|
-
const clientOptions: SSEClientOptions = {
|
|
388
|
-
url,
|
|
389
|
-
identity,
|
|
390
|
-
authToken,
|
|
387
|
+
const clientOptions: SSEClientOptions = {
|
|
388
|
+
url,
|
|
389
|
+
identity,
|
|
390
|
+
authToken,
|
|
391
391
|
onConnectionEvent: (event) => {
|
|
392
392
|
// Update local state based on event
|
|
393
393
|
updateConnectionsFromEvent(event);
|
|
@@ -398,13 +398,13 @@ export function useMcp(options: UseMcpOptions): McpClient {
|
|
|
398
398
|
onObservabilityEvent: (event) => {
|
|
399
399
|
onLog?.(event.level || 'info', event.message || event.displayMessage || 'No message', event.metadata);
|
|
400
400
|
},
|
|
401
|
-
onStatusChange: (newStatus) => {
|
|
402
|
-
if (isMountedRef.value) {
|
|
403
|
-
status.value = newStatus;
|
|
404
|
-
}
|
|
405
|
-
},
|
|
406
|
-
debug: options.debug,
|
|
407
|
-
};
|
|
401
|
+
onStatusChange: (newStatus) => {
|
|
402
|
+
if (isMountedRef.value) {
|
|
403
|
+
status.value = newStatus;
|
|
404
|
+
}
|
|
405
|
+
},
|
|
406
|
+
debug: options.debug,
|
|
407
|
+
};
|
|
408
408
|
|
|
409
409
|
const client = new SSEClient(clientOptions);
|
|
410
410
|
clientRef.value = client;
|
|
@@ -582,7 +582,7 @@ export function useMcp(options: UseMcpOptions): McpClient {
|
|
|
582
582
|
|
|
583
583
|
const isServerConnected = (serverId: string) => {
|
|
584
584
|
const conn = getConnectionByServerId(serverId);
|
|
585
|
-
return conn
|
|
585
|
+
return conn ? conn.state === 'CONNECTED' || conn.state === 'DISCOVERING' || conn.state === 'READY' : false;
|
|
586
586
|
};
|
|
587
587
|
|
|
588
588
|
const getTools = (sessionId: string) => {
|
|
@@ -608,10 +608,10 @@ export function useMcp(options: UseMcpOptions): McpClient {
|
|
|
608
608
|
resumeAuth,
|
|
609
609
|
callTool,
|
|
610
610
|
listTools,
|
|
611
|
-
listPrompts,
|
|
612
|
-
getPrompt,
|
|
613
|
-
listResources,
|
|
614
|
-
readResource,
|
|
615
|
-
sseClient: clientRef.value,
|
|
616
|
-
};
|
|
617
|
-
}
|
|
611
|
+
listPrompts,
|
|
612
|
+
getPrompt,
|
|
613
|
+
listResources,
|
|
614
|
+
readResource,
|
|
615
|
+
sseClient: clientRef.value,
|
|
616
|
+
};
|
|
617
|
+
}
|