@mcp-ts/sdk 1.3.4 → 1.3.6

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.
Files changed (70) hide show
  1. package/README.md +404 -400
  2. package/dist/adapters/agui-adapter.d.mts +1 -1
  3. package/dist/adapters/agui-adapter.d.ts +1 -1
  4. package/dist/adapters/agui-middleware.d.mts +1 -1
  5. package/dist/adapters/agui-middleware.d.ts +1 -1
  6. package/dist/adapters/ai-adapter.d.mts +1 -1
  7. package/dist/adapters/ai-adapter.d.ts +1 -1
  8. package/dist/adapters/langchain-adapter.d.mts +1 -1
  9. package/dist/adapters/langchain-adapter.d.ts +1 -1
  10. package/dist/adapters/mastra-adapter.d.mts +1 -1
  11. package/dist/adapters/mastra-adapter.d.ts +1 -1
  12. package/dist/bin/mcp-ts.d.mts +1 -0
  13. package/dist/bin/mcp-ts.d.ts +1 -0
  14. package/dist/bin/mcp-ts.js +105 -0
  15. package/dist/bin/mcp-ts.js.map +1 -0
  16. package/dist/bin/mcp-ts.mjs +82 -0
  17. package/dist/bin/mcp-ts.mjs.map +1 -0
  18. package/dist/client/index.d.mts +1 -0
  19. package/dist/client/index.d.ts +1 -0
  20. package/dist/client/index.js +14 -5
  21. package/dist/client/index.js.map +1 -1
  22. package/dist/client/index.mjs +14 -5
  23. package/dist/client/index.mjs.map +1 -1
  24. package/dist/client/react.js +15 -6
  25. package/dist/client/react.js.map +1 -1
  26. package/dist/client/react.mjs +15 -6
  27. package/dist/client/react.mjs.map +1 -1
  28. package/dist/client/vue.js +15 -6
  29. package/dist/client/vue.js.map +1 -1
  30. package/dist/client/vue.mjs +15 -6
  31. package/dist/client/vue.mjs.map +1 -1
  32. package/dist/index.d.mts +1 -1
  33. package/dist/index.d.ts +1 -1
  34. package/dist/index.js +480 -179
  35. package/dist/index.js.map +1 -1
  36. package/dist/index.mjs +418 -179
  37. package/dist/index.mjs.map +1 -1
  38. package/dist/{multi-session-client-FAFpUzZ4.d.ts → multi-session-client-BYLarghq.d.ts} +29 -19
  39. package/dist/{multi-session-client-DzjmT7FX.d.mts → multi-session-client-CzhMkE0k.d.mts} +29 -19
  40. package/dist/server/index.d.mts +1 -1
  41. package/dist/server/index.d.ts +1 -1
  42. package/dist/server/index.js +455 -172
  43. package/dist/server/index.js.map +1 -1
  44. package/dist/server/index.mjs +410 -172
  45. package/dist/server/index.mjs.map +1 -1
  46. package/dist/shared/index.d.mts +2 -2
  47. package/dist/shared/index.d.ts +2 -2
  48. package/dist/shared/index.js +2 -2
  49. package/dist/shared/index.js.map +1 -1
  50. package/dist/shared/index.mjs +2 -2
  51. package/dist/shared/index.mjs.map +1 -1
  52. package/package.json +19 -6
  53. package/src/bin/mcp-ts.ts +102 -0
  54. package/src/client/core/sse-client.ts +371 -354
  55. package/src/client/react/use-mcp.ts +31 -31
  56. package/src/client/vue/use-mcp.ts +77 -77
  57. package/src/server/handlers/nextjs-handler.ts +204 -207
  58. package/src/server/handlers/sse-handler.ts +14 -63
  59. package/src/server/mcp/oauth-client.ts +67 -79
  60. package/src/server/mcp/storage-oauth-provider.ts +71 -38
  61. package/src/server/storage/file-backend.ts +1 -0
  62. package/src/server/storage/index.ts +82 -38
  63. package/src/server/storage/memory-backend.ts +4 -0
  64. package/src/server/storage/redis-backend.ts +102 -23
  65. package/src/server/storage/sqlite-backend.ts +1 -0
  66. package/src/server/storage/supabase-backend.ts +227 -0
  67. package/src/server/storage/types.ts +12 -12
  68. package/src/shared/constants.ts +2 -2
  69. package/src/shared/event-routing.ts +28 -0
  70. package/supabase/migrations/20260330195700_install_mcp_sessions.sql +84 -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?.state === 'CONNECTED';
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?.state === 'CONNECTED';
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
+ }