@mcp-ts/sdk 2.3.4 → 2.4.0

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 (82) hide show
  1. package/README.md +113 -30
  2. package/dist/adapters/agui-adapter.d.mts +3 -3
  3. package/dist/adapters/agui-adapter.d.ts +3 -3
  4. package/dist/adapters/agui-middleware.d.mts +3 -3
  5. package/dist/adapters/agui-middleware.d.ts +3 -3
  6. package/dist/adapters/ai-adapter.d.mts +3 -3
  7. package/dist/adapters/ai-adapter.d.ts +3 -3
  8. package/dist/adapters/langchain-adapter.d.mts +3 -3
  9. package/dist/adapters/langchain-adapter.d.ts +3 -3
  10. package/dist/adapters/mastra-adapter.d.mts +1 -1
  11. package/dist/adapters/mastra-adapter.d.ts +1 -1
  12. package/dist/client/index.d.mts +2 -2
  13. package/dist/client/index.d.ts +2 -2
  14. package/dist/client/index.js +2 -2
  15. package/dist/client/index.js.map +1 -1
  16. package/dist/client/index.mjs +2 -2
  17. package/dist/client/index.mjs.map +1 -1
  18. package/dist/client/react.d.mts +9 -8
  19. package/dist/client/react.d.ts +9 -8
  20. package/dist/client/react.js +66 -26
  21. package/dist/client/react.js.map +1 -1
  22. package/dist/client/react.mjs +67 -27
  23. package/dist/client/react.mjs.map +1 -1
  24. package/dist/client/vue.d.mts +6 -5
  25. package/dist/client/vue.d.ts +6 -5
  26. package/dist/client/vue.js +27 -17
  27. package/dist/client/vue.js.map +1 -1
  28. package/dist/client/vue.mjs +27 -17
  29. package/dist/client/vue.mjs.map +1 -1
  30. package/dist/{index-Cfjsme-a.d.mts → index-ByIjEReo.d.mts} +2 -2
  31. package/dist/{index-CmjMd2ac.d.ts → index-CtXvKl8N.d.ts} +2 -2
  32. package/dist/index.d.mts +5 -5
  33. package/dist/index.d.ts +5 -5
  34. package/dist/index.js +728 -306
  35. package/dist/index.js.map +1 -1
  36. package/dist/index.mjs +722 -304
  37. package/dist/index.mjs.map +1 -1
  38. package/dist/{multi-session-client-C7hGqzgM.d.mts → multi-session-client-CIMUGF8S.d.mts} +15 -33
  39. package/dist/{multi-session-client-C_kPHpD5.d.ts → multi-session-client-CnvZEGPY.d.ts} +15 -33
  40. package/dist/server/index.d.mts +45 -17
  41. package/dist/server/index.d.ts +45 -17
  42. package/dist/server/index.js +720 -300
  43. package/dist/server/index.js.map +1 -1
  44. package/dist/server/index.mjs +716 -299
  45. package/dist/server/index.mjs.map +1 -1
  46. package/dist/shared/index.d.mts +9 -8
  47. package/dist/shared/index.d.ts +9 -8
  48. package/dist/shared/index.js +7 -5
  49. package/dist/shared/index.js.map +1 -1
  50. package/dist/shared/index.mjs +5 -4
  51. package/dist/shared/index.mjs.map +1 -1
  52. package/dist/{tool-router-BMzhoNYt.d.ts → tool-router-CZMrOG8J.d.ts} +1 -1
  53. package/dist/{tool-router-BhHsvBfP.d.mts → tool-router-CuApsDiV.d.mts} +1 -1
  54. package/dist/{types-CxFaaZrM.d.mts → types-DCk_IF4L.d.mts} +5 -3
  55. package/dist/{types-CxFaaZrM.d.ts → types-DCk_IF4L.d.ts} +5 -3
  56. package/migrations/neon/20260513010000_install_mcp_sessions.sql +40 -3
  57. package/migrations/neon/20260513020000_add_session_cleanup_cron.sql +4 -4
  58. package/migrations/supabase/20260330195700_install_mcp_sessions.sql +67 -3
  59. package/migrations/supabase/20260421010000_add_session_cleanup_cron.sql +6 -6
  60. package/package.json +13 -3
  61. package/src/client/core/sse-client.ts +2 -2
  62. package/src/client/react/index.ts +1 -1
  63. package/src/client/react/oauth-popup.tsx +34 -13
  64. package/src/client/react/use-mcp.ts +19 -45
  65. package/src/client/utils/session-state.ts +43 -0
  66. package/src/client/vue/use-mcp.ts +18 -47
  67. package/src/server/handlers/sse-handler.ts +9 -4
  68. package/src/server/mcp/multi-session-client.ts +2 -6
  69. package/src/server/mcp/oauth-client.ts +73 -101
  70. package/src/server/mcp/storage-oauth-provider.ts +79 -50
  71. package/src/server/storage/file-backend.ts +74 -18
  72. package/src/server/storage/index.ts +2 -4
  73. package/src/server/storage/memory-backend.ts +49 -13
  74. package/src/server/storage/neon-backend.ts +201 -68
  75. package/src/server/storage/redis-backend.ts +81 -23
  76. package/src/server/storage/session-lifecycle.ts +78 -0
  77. package/src/server/storage/sqlite-backend.ts +89 -15
  78. package/src/server/storage/supabase-backend.ts +188 -63
  79. package/src/server/storage/types.ts +49 -16
  80. package/src/shared/constants.ts +5 -6
  81. package/src/shared/types.ts +5 -3
  82. package/src/shared/utils.ts +26 -0
@@ -1,9 +1,9 @@
1
- import { c as SSEClient } from '../index-Cfjsme-a.mjs';
2
- export { A as APP_HOST_DEFAULTS, a as AppHost, D as DEFAULT_MCP_APP_CSP, S as SANDBOX_PROXY_READY_METHOD, b as SANDBOX_RESOURCE_READY_METHOD, d as SSEClientOptions } from '../index-Cfjsme-a.mjs';
1
+ import { c as SSEClient } from '../index-ByIjEReo.mjs';
2
+ export { A as APP_HOST_DEFAULTS, a as AppHost, D as DEFAULT_MCP_APP_CSP, S as SANDBOX_PROXY_READY_METHOD, b as SANDBOX_RESOURCE_READY_METHOD, d as SSEClientOptions } from '../index-ByIjEReo.mjs';
3
3
  import { c as McpConnectionState, M as McpConnectionEvent } from '../events-CK3N--3g.mjs';
4
4
  export { D as Disposable, a as DisposableStore, E as Emitter, b as Event, d as McpObservabilityEvent } from '../events-CK3N--3g.mjs';
5
- import { v as ToolInfo, k as FinishAuthResult, o as ListToolsRpcResult, L as ListPromptsResult, m as ListResourcesResult } from '../types-CxFaaZrM.mjs';
6
- export { q as McpRpcRequest, r as McpRpcResponse } from '../types-CxFaaZrM.mjs';
5
+ import { v as ToolInfo, k as FinishAuthResult, o as ListToolsRpcResult, L as ListPromptsResult, m as ListResourcesResult } from '../types-DCk_IF4L.mjs';
6
+ export { q as McpRpcRequest, r as McpRpcResponse } from '../types-DCk_IF4L.mjs';
7
7
  import '@modelcontextprotocol/ext-apps/app-bridge';
8
8
  import '@modelcontextprotocol/sdk/types.js';
9
9
 
@@ -71,6 +71,7 @@ interface McpConnection {
71
71
  authUrl?: string;
72
72
  error?: string;
73
73
  createdAt?: Date;
74
+ updatedAt?: Date;
74
75
  }
75
76
  interface McpClient {
76
77
  /**
@@ -146,7 +147,7 @@ interface McpClient {
146
147
  /**
147
148
  * Complete OAuth authorization
148
149
  */
149
- finishAuth: (sessionId: string, code: string) => Promise<FinishAuthResult>;
150
+ finishAuth: (state: string, code: string) => Promise<FinishAuthResult>;
150
151
  /**
151
152
  * Explicitly resume OAuth flow for an existing session
152
153
  */
@@ -1,9 +1,9 @@
1
- import { c as SSEClient } from '../index-CmjMd2ac.js';
2
- export { A as APP_HOST_DEFAULTS, a as AppHost, D as DEFAULT_MCP_APP_CSP, S as SANDBOX_PROXY_READY_METHOD, b as SANDBOX_RESOURCE_READY_METHOD, d as SSEClientOptions } from '../index-CmjMd2ac.js';
1
+ import { c as SSEClient } from '../index-CtXvKl8N.js';
2
+ export { A as APP_HOST_DEFAULTS, a as AppHost, D as DEFAULT_MCP_APP_CSP, S as SANDBOX_PROXY_READY_METHOD, b as SANDBOX_RESOURCE_READY_METHOD, d as SSEClientOptions } from '../index-CtXvKl8N.js';
3
3
  import { c as McpConnectionState, M as McpConnectionEvent } from '../events-CK3N--3g.js';
4
4
  export { D as Disposable, a as DisposableStore, E as Emitter, b as Event, d as McpObservabilityEvent } from '../events-CK3N--3g.js';
5
- import { v as ToolInfo, k as FinishAuthResult, o as ListToolsRpcResult, L as ListPromptsResult, m as ListResourcesResult } from '../types-CxFaaZrM.js';
6
- export { q as McpRpcRequest, r as McpRpcResponse } from '../types-CxFaaZrM.js';
5
+ import { v as ToolInfo, k as FinishAuthResult, o as ListToolsRpcResult, L as ListPromptsResult, m as ListResourcesResult } from '../types-DCk_IF4L.js';
6
+ export { q as McpRpcRequest, r as McpRpcResponse } from '../types-DCk_IF4L.js';
7
7
  import '@modelcontextprotocol/ext-apps/app-bridge';
8
8
  import '@modelcontextprotocol/sdk/types.js';
9
9
 
@@ -71,6 +71,7 @@ interface McpConnection {
71
71
  authUrl?: string;
72
72
  error?: string;
73
73
  createdAt?: Date;
74
+ updatedAt?: Date;
74
75
  }
75
76
  interface McpClient {
76
77
  /**
@@ -146,7 +147,7 @@ interface McpClient {
146
147
  /**
147
148
  * Complete OAuth authorization
148
149
  */
149
- finishAuth: (sessionId: string, code: string) => Promise<FinishAuthResult>;
150
+ finishAuth: (state: string, code: string) => Promise<FinishAuthResult>;
150
151
  /**
151
152
  * Explicitly resume OAuth flow for an existing session
152
153
  */
@@ -49,8 +49,8 @@ var SSEClient = class {
49
49
  async getSession(sessionId) {
50
50
  return this.sendRequest("getSession", { sessionId });
51
51
  }
52
- async finishAuth(sessionId, code) {
53
- return this.sendRequest("finishAuth", { sessionId, code });
52
+ async finishAuth(state, code) {
53
+ return this.sendRequest("finishAuth", { state, code });
54
54
  }
55
55
  async listPrompts(sessionId) {
56
56
  return this.sendRequest("listPrompts", { sessionId });
@@ -252,6 +252,20 @@ var SSEClient = class {
252
252
  }
253
253
  };
254
254
 
255
+ // src/client/utils/session-state.ts
256
+ function getInitialConnectionState(status) {
257
+ return status === "active" ? "VALIDATING" : "AUTHENTICATING";
258
+ }
259
+ function isTransientReconnectState(state) {
260
+ return state === "INITIALIZING" || state === "VALIDATING" || state === "RECONNECTING" || state === "CONNECTING" || state === "CONNECTED" || state === "DISCOVERING";
261
+ }
262
+ function getVisibleConnectionState(incomingState, existingState, previousState) {
263
+ if (incomingState === "INITIALIZING" && (existingState === "AUTHENTICATING" || existingState === "AUTHENTICATED" || previousState === "AUTHENTICATING" || previousState === "AUTHENTICATED")) {
264
+ return existingState === "AUTHENTICATED" || previousState === "AUTHENTICATED" ? "AUTHENTICATED" : "AUTHENTICATING";
265
+ }
266
+ return incomingState;
267
+ }
268
+
255
269
  // src/client/vue/use-mcp.ts
256
270
  function useMcp(options) {
257
271
  const {
@@ -272,25 +286,19 @@ function useMcp(options) {
272
286
  const isInitializing = vue.ref(false);
273
287
  const updateConnectionsFromEvent = (event) => {
274
288
  if (!isMountedRef.value) return;
275
- const isTransientReconnectState = (state) => state === "INITIALIZING" || state === "VALIDATING" || state === "RECONNECTING" || state === "CONNECTING" || state === "CONNECTED" || state === "DISCOVERING";
276
- const getVisibleState = (incomingState, existingState, previousState) => {
277
- if (incomingState === "INITIALIZING" && (existingState === "AUTHENTICATING" || existingState === "AUTHENTICATED" || previousState === "AUTHENTICATING" || previousState === "AUTHENTICATED")) {
278
- return existingState === "AUTHENTICATED" || previousState === "AUTHENTICATED" ? "AUTHENTICATED" : "AUTHENTICATING";
279
- }
280
- return incomingState;
281
- };
282
289
  switch (event.type) {
283
290
  case "state_changed": {
284
291
  const existing = connections.value.find((c) => c.sessionId === event.sessionId);
285
292
  if (existing) {
286
- const normalizedState = getVisibleState(event.state, existing.state, event.previousState);
293
+ const normalizedState = getVisibleConnectionState(event.state, existing.state, event.previousState);
287
294
  const nextState = existing.state === "READY" && isTransientReconnectState(normalizedState) ? existing.state : normalizedState;
288
295
  const index = connections.value.indexOf(existing);
289
296
  connections.value[index] = {
290
297
  ...existing,
291
298
  state: nextState,
292
299
  // update createdAt if present in event, otherwise keep existing
293
- createdAt: event.createdAt ? new Date(event.createdAt) : existing.createdAt
300
+ createdAt: event.createdAt ? new Date(event.createdAt) : existing.createdAt,
301
+ updatedAt: /* @__PURE__ */ new Date()
294
302
  };
295
303
  } else {
296
304
  if (event.state === "DISCONNECTED") {
@@ -302,8 +310,9 @@ function useMcp(options) {
302
310
  serverName: event.serverName,
303
311
  // New connections do not have prior local state, so we normalize
304
312
  // only against the server-reported previous state.
305
- state: getVisibleState(event.state, void 0, event.previousState),
313
+ state: getVisibleConnectionState(event.state, void 0, event.previousState),
306
314
  createdAt: event.createdAt ? new Date(event.createdAt) : void 0,
315
+ updatedAt: /* @__PURE__ */ new Date(),
307
316
  tools: []
308
317
  }];
309
318
  }
@@ -312,7 +321,7 @@ function useMcp(options) {
312
321
  case "tools_discovered": {
313
322
  const index = connections.value.findIndex((c) => c.sessionId === event.sessionId);
314
323
  if (index !== -1) {
315
- connections.value[index] = { ...connections.value[index], tools: event.tools, state: "READY" };
324
+ connections.value[index] = { ...connections.value[index], tools: event.tools, state: "READY", updatedAt: /* @__PURE__ */ new Date() };
316
325
  }
317
326
  break;
318
327
  }
@@ -371,8 +380,9 @@ function useMcp(options) {
371
380
  serverName: s.serverName ?? "Unknown Server",
372
381
  serverUrl: s.serverUrl,
373
382
  transport: s.transport,
374
- state: s.active === false ? "AUTHENTICATING" : "VALIDATING",
383
+ state: getInitialConnectionState(s.status),
375
384
  createdAt: new Date(s.createdAt),
385
+ updatedAt: new Date(s.updatedAt ?? s.createdAt),
376
386
  tools: []
377
387
  }));
378
388
  }
@@ -380,7 +390,7 @@ function useMcp(options) {
380
390
  sessions.map(async (session) => {
381
391
  if (clientRef.value) {
382
392
  try {
383
- if (session.active === false) {
393
+ if (session.status !== "active") {
384
394
  return;
385
395
  }
386
396
  suppressAuthRedirectSessions.value.add(session.sessionId);
@@ -482,11 +492,11 @@ function useMcp(options) {
482
492
  const disconnectSSE = () => {
483
493
  clientRef.value?.disconnect();
484
494
  };
485
- const finishAuth = async (sessionId, code) => {
495
+ const finishAuth = async (state, code) => {
486
496
  if (!clientRef.value) {
487
497
  throw new Error("SSE client not initialized");
488
498
  }
489
- return await clientRef.value.finishAuth(sessionId, code);
499
+ return await clientRef.value.finishAuth(state, code);
490
500
  };
491
501
  const resumeAuth = async (sessionId) => {
492
502
  if (!clientRef.value) {