@mcp-ts/sdk 2.4.5 → 2.5.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.
Files changed (86) hide show
  1. package/dist/adapters/agui-adapter.d.mts +3 -3
  2. package/dist/adapters/agui-adapter.d.ts +3 -3
  3. package/dist/adapters/agui-adapter.js.map +1 -1
  4. package/dist/adapters/agui-adapter.mjs.map +1 -1
  5. package/dist/adapters/agui-middleware.d.mts +3 -3
  6. package/dist/adapters/agui-middleware.d.ts +3 -3
  7. package/dist/adapters/agui-middleware.js.map +1 -1
  8. package/dist/adapters/agui-middleware.mjs.map +1 -1
  9. package/dist/adapters/ai-adapter.d.mts +3 -3
  10. package/dist/adapters/ai-adapter.d.ts +3 -3
  11. package/dist/adapters/ai-adapter.js.map +1 -1
  12. package/dist/adapters/ai-adapter.mjs.map +1 -1
  13. package/dist/adapters/langchain-adapter.d.mts +3 -3
  14. package/dist/adapters/langchain-adapter.d.ts +3 -3
  15. package/dist/adapters/langchain-adapter.js +2 -2
  16. package/dist/adapters/langchain-adapter.js.map +1 -1
  17. package/dist/adapters/langchain-adapter.mjs +2 -2
  18. package/dist/adapters/langchain-adapter.mjs.map +1 -1
  19. package/dist/adapters/mastra-adapter.d.mts +2 -2
  20. package/dist/adapters/mastra-adapter.d.ts +2 -2
  21. package/dist/adapters/mastra-adapter.js +2 -2
  22. package/dist/adapters/mastra-adapter.js.map +1 -1
  23. package/dist/adapters/mastra-adapter.mjs +2 -2
  24. package/dist/adapters/mastra-adapter.mjs.map +1 -1
  25. package/dist/client/index.d.mts +2 -2
  26. package/dist/client/index.d.ts +2 -2
  27. package/dist/client/index.js +9 -0
  28. package/dist/client/index.js.map +1 -1
  29. package/dist/client/index.mjs +9 -0
  30. package/dist/client/index.mjs.map +1 -1
  31. package/dist/client/react.d.mts +15 -4
  32. package/dist/client/react.d.ts +15 -4
  33. package/dist/client/react.js +56 -37
  34. package/dist/client/react.js.map +1 -1
  35. package/dist/client/react.mjs +56 -37
  36. package/dist/client/react.mjs.map +1 -1
  37. package/dist/client/vue.d.mts +4 -4
  38. package/dist/client/vue.d.ts +4 -4
  39. package/dist/client/vue.js +9 -0
  40. package/dist/client/vue.js.map +1 -1
  41. package/dist/client/vue.mjs +9 -0
  42. package/dist/client/vue.mjs.map +1 -1
  43. package/dist/{index-CZk2gu2E.d.ts → index-BEdyuz1M.d.ts} +6 -1
  44. package/dist/{index-CkM3p0eE.d.mts → index-C99wE2Zf.d.mts} +6 -1
  45. package/dist/index.d.mts +4 -4
  46. package/dist/index.d.ts +4 -4
  47. package/dist/index.js +380 -82
  48. package/dist/index.js.map +1 -1
  49. package/dist/index.mjs +376 -82
  50. package/dist/index.mjs.map +1 -1
  51. package/dist/{multi-session-client-QOOPdEVp.d.ts → multi-session-client-CclWRxTD.d.mts} +14 -2
  52. package/dist/{multi-session-client-ChQrBZhF.d.mts → multi-session-client-DzvZD6Tt.d.ts} +14 -2
  53. package/dist/server/index.d.mts +18 -4
  54. package/dist/server/index.d.ts +18 -4
  55. package/dist/server/index.js +371 -82
  56. package/dist/server/index.js.map +1 -1
  57. package/dist/server/index.mjs +367 -82
  58. package/dist/server/index.mjs.map +1 -1
  59. package/dist/shared/index.d.mts +4 -4
  60. package/dist/shared/index.d.ts +4 -4
  61. package/dist/shared/index.js.map +1 -1
  62. package/dist/shared/index.mjs.map +1 -1
  63. package/dist/{tool-router-CGs3IDOJ.d.mts → tool-router-C9ECn3FX.d.mts} +1 -1
  64. package/dist/{tool-router-DQ-HrD7W.d.ts → tool-router-CUSSk6lT.d.ts} +1 -1
  65. package/dist/{types-Bf-7GOLW.d.mts → types-CbFbPkfQ.d.mts} +38 -3
  66. package/dist/{types-Bf-7GOLW.d.ts → types-CbFbPkfQ.d.ts} +38 -3
  67. package/migrations/neon/20260513010000_install_mcp_sessions.sql +1 -0
  68. package/migrations/supabase/20260330195700_install_mcp_sessions.sql +1 -0
  69. package/package.json +2 -2
  70. package/src/adapters/agui-adapter.ts +6 -2
  71. package/src/adapters/ai-adapter.ts +3 -1
  72. package/src/adapters/langchain-adapter.ts +5 -3
  73. package/src/adapters/mastra-adapter.ts +5 -3
  74. package/src/client/core/sse-client.ts +21 -0
  75. package/src/client/react/oauth-popup.tsx +17 -24
  76. package/src/client/react/use-mcp.ts +69 -15
  77. package/src/server/handlers/sse-handler.ts +202 -9
  78. package/src/server/mcp/multi-session-client.ts +7 -3
  79. package/src/server/mcp/oauth-client.ts +25 -10
  80. package/src/server/mcp/tool-policy-gateway.ts +90 -0
  81. package/src/server/storage/neon-backend.ts +65 -60
  82. package/src/server/storage/session-lifecycle.ts +5 -0
  83. package/src/server/storage/supabase-backend.ts +27 -15
  84. package/src/server/storage/tool-policy.ts +89 -0
  85. package/src/server/storage/types.ts +11 -0
  86. package/src/shared/types.ts +52 -1
@@ -1,5 +1,5 @@
1
1
  import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
- import { A as ToolClientProvider, T as ToolClient } from './types-Bf-7GOLW.mjs';
2
+ import { A as ToolClientProvider, T as ToolClient } from './types-CbFbPkfQ.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-Bf-7GOLW.js';
2
+ import { A as ToolClientProvider, T as ToolClient } from './types-CbFbPkfQ.js';
3
3
 
4
4
  /**
5
5
  * ToolIndex — Lightweight in-memory search index for MCP tool discovery.
@@ -138,6 +138,7 @@ interface ToolClient {
138
138
  callTool(name: string, args: Record<string, unknown>): Promise<any>;
139
139
  getServerId?(): string | undefined;
140
140
  getServerName?(): string | undefined;
141
+ getServerUrl?(): string | undefined;
141
142
  getSessionId?(): string;
142
143
  }
143
144
  /**
@@ -203,7 +204,13 @@ type ToolInfo = {
203
204
  };
204
205
  type TransportType = 'sse' | 'streamable-http';
205
206
  type SessionStatus = 'pending' | 'active';
206
- type McpRpcMethod = 'connect' | 'disconnect' | 'listTools' | 'callTool' | 'listSessions' | 'getSession' | 'finishAuth' | 'listPrompts' | 'getPrompt' | 'listResources' | 'readResource';
207
+ type ToolPolicyMode = 'all' | 'allowlist' | 'denylist';
208
+ interface ToolPolicy {
209
+ mode: ToolPolicyMode;
210
+ toolIds: string[];
211
+ updatedAt: number;
212
+ }
213
+ type McpRpcMethod = 'connect' | 'disconnect' | 'reconnect' | 'listTools' | 'callTool' | 'listSessions' | 'getSession' | 'finishAuth' | 'listPrompts' | 'getPrompt' | 'listResources' | 'readResource' | 'setToolPolicy' | 'getToolPolicy';
207
214
  interface McpRpcRequest {
208
215
  id: string;
209
216
  method: McpRpcMethod;
@@ -228,6 +235,7 @@ interface ConnectParams {
228
235
  interface DisconnectParams {
229
236
  sessionId: string;
230
237
  }
238
+ type ReconnectParams = ConnectParams;
231
239
  interface SessionParams {
232
240
  sessionId: string;
233
241
  }
@@ -249,7 +257,17 @@ interface FinishAuthParams {
249
257
  state: string;
250
258
  code: string;
251
259
  }
252
- type McpRpcParams = ConnectParams | DisconnectParams | SessionParams | CallToolParams | GetPromptParams | ReadResourceParams | FinishAuthParams | undefined;
260
+ interface SetToolPolicyParams {
261
+ sessionId: string;
262
+ toolPolicy: {
263
+ mode: ToolPolicyMode;
264
+ toolIds?: string[];
265
+ };
266
+ }
267
+ interface GetToolPolicyParams {
268
+ sessionId: string;
269
+ }
270
+ type McpRpcParams = ConnectParams | DisconnectParams | ReconnectParams | SessionParams | CallToolParams | GetPromptParams | ReadResourceParams | FinishAuthParams | SetToolPolicyParams | GetToolPolicyParams | undefined;
253
271
  interface SessionInfo {
254
272
  sessionId: string;
255
273
  serverId?: string;
@@ -263,6 +281,7 @@ interface SessionInfo {
263
281
  * `pending` means auth is in progress and should be resumed explicitly by user action.
264
282
  */
265
283
  status: SessionStatus;
284
+ toolPolicy?: ToolPolicy;
266
285
  }
267
286
  interface SessionListResult {
268
287
  sessions: SessionInfo[];
@@ -285,6 +304,22 @@ interface FinishAuthResult {
285
304
  interface ListToolsRpcResult {
286
305
  tools: Tool[];
287
306
  }
307
+ interface SetToolPolicyResult {
308
+ success: boolean;
309
+ toolPolicy: ToolPolicy;
310
+ tools: Tool[];
311
+ toolCount: number;
312
+ }
313
+ type ToolAccessInfo = Tool & {
314
+ toolId: string;
315
+ allowed: boolean;
316
+ };
317
+ interface GetToolPolicyResult {
318
+ toolPolicy: ToolPolicy;
319
+ tools: ToolAccessInfo[];
320
+ toolCount: number;
321
+ allowedToolCount: number;
322
+ }
288
323
  interface ListPromptsResult {
289
324
  prompts: Array<{
290
325
  name: string;
@@ -305,4 +340,4 @@ interface ListResourcesResult {
305
340
  }>;
306
341
  }
307
342
 
308
- export { type ToolClientProvider as A, type ToolInfo as B, type CallToolParams as C, type DisconnectParams as D, Emitter as E, type FinishAuthParams as F, type GetPromptParams as G, type TransportType as H, isCallToolSuccess as I, isConnectAuthRequired as J, isConnectError as K, type ListPromptsResult as L, type McpConnectionEvent as M, isConnectSuccess as N, isListToolsSuccess as O, type McpAppsUIEvent as P, type ReadResourceParams as R, type SessionInfo as S, type ToolClient as T, type CallToolRequest as a, type CallToolResponse as b, type ConnectAuthRequiredResponse as c, type ConnectErrorResponse as d, type ConnectParams as e, type ConnectRequest as f, type ConnectResponse as g, type ConnectResult as h, type ConnectSuccessResponse as i, type DisconnectResult as j, type Disposable as k, DisposableStore as l, type Event as m, type FinishAuthResult as n, type GetSessionResult as o, type ListResourcesResult as p, type ListToolsResponse as q, type ListToolsRpcResult as r, type McpConnectionState as s, type McpObservabilityEvent as t, type McpRpcMethod as u, type McpRpcParams as v, type McpRpcRequest as w, type McpRpcResponse as x, type SessionListResult as y, type SessionParams as z };
343
+ export { type ToolClientProvider as A, type ToolInfo as B, type CallToolParams as C, type DisconnectParams as D, Emitter as E, type FinishAuthParams as F, type GetPromptParams as G, type TransportType as H, isCallToolSuccess as I, isConnectAuthRequired as J, isConnectError as K, type ListPromptsResult as L, type McpConnectionEvent as M, isConnectSuccess as N, isListToolsSuccess as O, type ToolPolicy as P, type SetToolPolicyResult as Q, type ReadResourceParams as R, type SessionInfo as S, type ToolClient as T, type GetToolPolicyResult as U, type McpAppsUIEvent as V, type CallToolRequest as a, type CallToolResponse as b, type ConnectAuthRequiredResponse as c, type ConnectErrorResponse as d, type ConnectParams as e, type ConnectRequest as f, type ConnectResponse as g, type ConnectResult as h, type ConnectSuccessResponse as i, type DisconnectResult as j, type Disposable as k, DisposableStore as l, type Event as m, type FinishAuthResult as n, type GetSessionResult as o, type ListResourcesResult as p, type ListToolsResponse as q, type ListToolsRpcResult as r, type McpConnectionState as s, type McpObservabilityEvent as t, type McpRpcMethod as u, type McpRpcParams as v, type McpRpcRequest as w, type McpRpcResponse as x, type SessionListResult as y, type SessionParams as z };
@@ -138,6 +138,7 @@ interface ToolClient {
138
138
  callTool(name: string, args: Record<string, unknown>): Promise<any>;
139
139
  getServerId?(): string | undefined;
140
140
  getServerName?(): string | undefined;
141
+ getServerUrl?(): string | undefined;
141
142
  getSessionId?(): string;
142
143
  }
143
144
  /**
@@ -203,7 +204,13 @@ type ToolInfo = {
203
204
  };
204
205
  type TransportType = 'sse' | 'streamable-http';
205
206
  type SessionStatus = 'pending' | 'active';
206
- type McpRpcMethod = 'connect' | 'disconnect' | 'listTools' | 'callTool' | 'listSessions' | 'getSession' | 'finishAuth' | 'listPrompts' | 'getPrompt' | 'listResources' | 'readResource';
207
+ type ToolPolicyMode = 'all' | 'allowlist' | 'denylist';
208
+ interface ToolPolicy {
209
+ mode: ToolPolicyMode;
210
+ toolIds: string[];
211
+ updatedAt: number;
212
+ }
213
+ type McpRpcMethod = 'connect' | 'disconnect' | 'reconnect' | 'listTools' | 'callTool' | 'listSessions' | 'getSession' | 'finishAuth' | 'listPrompts' | 'getPrompt' | 'listResources' | 'readResource' | 'setToolPolicy' | 'getToolPolicy';
207
214
  interface McpRpcRequest {
208
215
  id: string;
209
216
  method: McpRpcMethod;
@@ -228,6 +235,7 @@ interface ConnectParams {
228
235
  interface DisconnectParams {
229
236
  sessionId: string;
230
237
  }
238
+ type ReconnectParams = ConnectParams;
231
239
  interface SessionParams {
232
240
  sessionId: string;
233
241
  }
@@ -249,7 +257,17 @@ interface FinishAuthParams {
249
257
  state: string;
250
258
  code: string;
251
259
  }
252
- type McpRpcParams = ConnectParams | DisconnectParams | SessionParams | CallToolParams | GetPromptParams | ReadResourceParams | FinishAuthParams | undefined;
260
+ interface SetToolPolicyParams {
261
+ sessionId: string;
262
+ toolPolicy: {
263
+ mode: ToolPolicyMode;
264
+ toolIds?: string[];
265
+ };
266
+ }
267
+ interface GetToolPolicyParams {
268
+ sessionId: string;
269
+ }
270
+ type McpRpcParams = ConnectParams | DisconnectParams | ReconnectParams | SessionParams | CallToolParams | GetPromptParams | ReadResourceParams | FinishAuthParams | SetToolPolicyParams | GetToolPolicyParams | undefined;
253
271
  interface SessionInfo {
254
272
  sessionId: string;
255
273
  serverId?: string;
@@ -263,6 +281,7 @@ interface SessionInfo {
263
281
  * `pending` means auth is in progress and should be resumed explicitly by user action.
264
282
  */
265
283
  status: SessionStatus;
284
+ toolPolicy?: ToolPolicy;
266
285
  }
267
286
  interface SessionListResult {
268
287
  sessions: SessionInfo[];
@@ -285,6 +304,22 @@ interface FinishAuthResult {
285
304
  interface ListToolsRpcResult {
286
305
  tools: Tool[];
287
306
  }
307
+ interface SetToolPolicyResult {
308
+ success: boolean;
309
+ toolPolicy: ToolPolicy;
310
+ tools: Tool[];
311
+ toolCount: number;
312
+ }
313
+ type ToolAccessInfo = Tool & {
314
+ toolId: string;
315
+ allowed: boolean;
316
+ };
317
+ interface GetToolPolicyResult {
318
+ toolPolicy: ToolPolicy;
319
+ tools: ToolAccessInfo[];
320
+ toolCount: number;
321
+ allowedToolCount: number;
322
+ }
288
323
  interface ListPromptsResult {
289
324
  prompts: Array<{
290
325
  name: string;
@@ -305,4 +340,4 @@ interface ListResourcesResult {
305
340
  }>;
306
341
  }
307
342
 
308
- export { type ToolClientProvider as A, type ToolInfo as B, type CallToolParams as C, type DisconnectParams as D, Emitter as E, type FinishAuthParams as F, type GetPromptParams as G, type TransportType as H, isCallToolSuccess as I, isConnectAuthRequired as J, isConnectError as K, type ListPromptsResult as L, type McpConnectionEvent as M, isConnectSuccess as N, isListToolsSuccess as O, type McpAppsUIEvent as P, type ReadResourceParams as R, type SessionInfo as S, type ToolClient as T, type CallToolRequest as a, type CallToolResponse as b, type ConnectAuthRequiredResponse as c, type ConnectErrorResponse as d, type ConnectParams as e, type ConnectRequest as f, type ConnectResponse as g, type ConnectResult as h, type ConnectSuccessResponse as i, type DisconnectResult as j, type Disposable as k, DisposableStore as l, type Event as m, type FinishAuthResult as n, type GetSessionResult as o, type ListResourcesResult as p, type ListToolsResponse as q, type ListToolsRpcResult as r, type McpConnectionState as s, type McpObservabilityEvent as t, type McpRpcMethod as u, type McpRpcParams as v, type McpRpcRequest as w, type McpRpcResponse as x, type SessionListResult as y, type SessionParams as z };
343
+ export { type ToolClientProvider as A, type ToolInfo as B, type CallToolParams as C, type DisconnectParams as D, Emitter as E, type FinishAuthParams as F, type GetPromptParams as G, type TransportType as H, isCallToolSuccess as I, isConnectAuthRequired as J, isConnectError as K, type ListPromptsResult as L, type McpConnectionEvent as M, isConnectSuccess as N, isListToolsSuccess as O, type ToolPolicy as P, type SetToolPolicyResult as Q, type ReadResourceParams as R, type SessionInfo as S, type ToolClient as T, type GetToolPolicyResult as U, type McpAppsUIEvent as V, type CallToolRequest as a, type CallToolResponse as b, type ConnectAuthRequiredResponse as c, type ConnectErrorResponse as d, type ConnectParams as e, type ConnectRequest as f, type ConnectResponse as g, type ConnectResult as h, type ConnectSuccessResponse as i, type DisconnectResult as j, type Disposable as k, DisposableStore as l, type Event as m, type FinishAuthResult as n, type GetSessionResult as o, type ListResourcesResult as p, type ListToolsResponse as q, type ListToolsRpcResult as r, type McpConnectionState as s, type McpObservabilityEvent as t, type McpRpcMethod as u, type McpRpcParams as v, type McpRpcRequest as w, type McpRpcResponse as x, type SessionListResult as y, type SessionParams as z };
@@ -17,6 +17,7 @@ CREATE TABLE IF NOT EXISTS public.mcp_sessions (
17
17
  CHECK (status IN ('pending', 'active')),
18
18
  headers JSONB,
19
19
  auth_url TEXT,
20
+ -- tool_policy JSONB -- optional, see docs/tool-policy
20
21
  CONSTRAINT mcp_sessions_user_session_unique
21
22
  UNIQUE (user_id, session_id)
22
23
  );
@@ -15,6 +15,7 @@ CREATE TABLE IF NOT EXISTS public.mcp_sessions (
15
15
  CHECK (status IN ('pending', 'active')),
16
16
  headers JSONB,
17
17
  auth_url TEXT,
18
+ -- tool_policy JSONB -- optional, see docs/tool-policy
18
19
  CONSTRAINT mcp_sessions_user_session_unique
19
20
  UNIQUE (user_id, session_id)
20
21
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-ts/sdk",
3
- "version": "2.4.5",
3
+ "version": "2.5.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -206,4 +206,4 @@
206
206
  "engines": {
207
207
  "node": ">=18.0.0"
208
208
  }
209
- }
209
+ }
@@ -29,6 +29,7 @@
29
29
  import { MCPClient } from '../server/mcp/oauth-client.js';
30
30
  import { MultiSessionClient } from '../server/mcp/multi-session-client.js';
31
31
  import { ToolRouter } from '../shared/tool-router.js';
32
+ import type { ToolClient } from '../shared/types.js';
32
33
  import { executeMetaTool, isMetaTool } from '../shared/meta-tools.js';
33
34
 
34
35
  /**
@@ -184,7 +185,7 @@ export class AguiAdapter {
184
185
  return typeof (this.client as any).getClients === 'function';
185
186
  }
186
187
 
187
- private async transformTools(client: MCPClient): Promise<AguiTool[]> {
188
+ private async transformTools(client: ToolClient): Promise<AguiTool[]> {
188
189
  if (!client.isConnected()) return [];
189
190
 
190
191
  const result = await client.listTools();
@@ -214,7 +215,7 @@ export class AguiAdapter {
214
215
  });
215
216
  }
216
217
 
217
- private async transformToolDefinitions(client: MCPClient): Promise<AguiToolDefinition[]> {
218
+ private async transformToolDefinitions(client: ToolClient): Promise<AguiToolDefinition[]> {
218
219
  if (!client.isConnected()) return [];
219
220
 
220
221
  const result = await client.listTools();
@@ -299,3 +300,6 @@ export class AguiAdapter {
299
300
  return `tool_${normalized}_${toolName}`;
300
301
  }
301
302
  }
303
+
304
+
305
+
@@ -3,6 +3,7 @@ import { MultiSessionClient } from '../server/mcp/multi-session-client';
3
3
  import type { JSONSchema7 } from 'json-schema';
4
4
  import type { ToolSet } from 'ai';
5
5
  import { ToolRouter } from '../shared/tool-router.js';
6
+ import type { ToolClient } from '../shared/types.js';
6
7
  import { executeMetaTool, isMetaTool } from '../shared/meta-tools.js';
7
8
 
8
9
  export interface AIAdapterOptions {
@@ -54,7 +55,7 @@ export class AIAdapter {
54
55
  }
55
56
  }
56
57
 
57
- private async transformTools(client: MCPClient): Promise<ToolSet> {
58
+ private async transformTools(client: ToolClient): Promise<ToolSet> {
58
59
  // Safe check for isConnected method (duck typing for bundler compatibility)
59
60
  const isConnected = typeof client.isConnected === 'function'
60
61
  ? client.isConnected()
@@ -217,3 +218,4 @@ export class AIAdapter {
217
218
  return new AIAdapter(client, options).getTools();
218
219
  }
219
220
  }
221
+
@@ -3,6 +3,7 @@ import { MultiSessionClient } from '../server/mcp/multi-session-client';
3
3
  import type { DynamicStructuredTool, StructuredTool } from '@langchain/core/tools';
4
4
  import type { z } from 'zod';
5
5
  import { ToolRouter } from '../shared/tool-router.js';
6
+ import type { ToolClient } from '../shared/types.js';
6
7
  import { executeMetaTool, isMetaTool } from '../shared/meta-tools.js';
7
8
 
8
9
  export interface LangChainAdapterOptions {
@@ -58,7 +59,7 @@ export class LangChainAdapter {
58
59
  }
59
60
  }
60
61
 
61
- private async transformTools(client: MCPClient): Promise<StructuredTool[]> {
62
+ private async transformTools(client: ToolClient): Promise<StructuredTool[]> {
62
63
  if (!client.isConnected()) {
63
64
  return [];
64
65
  }
@@ -66,7 +67,7 @@ export class LangChainAdapter {
66
67
  await this.ensureDependencies();
67
68
 
68
69
  const result = await client.listTools();
69
- const prefix = this.options.prefix ?? client.getServerId()?.replace(/-/g, '').substring(0, 8) ?? 'mcp';
70
+ const prefix = this.options.prefix ?? client.getServerId?.()?.replace(/-/g, '').substring(0, 8) ?? 'mcp';
70
71
 
71
72
  return result.tools.map((tool) => {
72
73
  // In a real implementation, you would use a library like 'json-schema-to-zod'
@@ -127,7 +128,7 @@ export class LangChainAdapter {
127
128
  try {
128
129
  return await this.transformTools(client);
129
130
  } catch (error) {
130
- console.error(`[LangChainAdapter] Failed to fetch tools from ${client.getServerId()}:`, error);
131
+ console.error(`[LangChainAdapter] Failed to fetch tools from ${client.getServerId?.() ?? "unknown"}:`, error);
131
132
  return [];
132
133
  }
133
134
  })
@@ -203,3 +204,4 @@ export class LangChainAdapter {
203
204
  return new LangChainAdapter(client, options).getTools();
204
205
  }
205
206
  }
207
+
@@ -1,5 +1,6 @@
1
1
  import { MCPClient } from '../server/mcp/oauth-client';
2
2
  import { MultiSessionClient } from '../server/mcp/multi-session-client';
3
+ import type { ToolClient } from '../shared/types.js';
3
4
  import type { z } from 'zod';
4
5
 
5
6
  export interface MastraAdapterOptions {
@@ -51,7 +52,7 @@ export class MastraAdapter {
51
52
 
52
53
 
53
54
 
54
- private async transformTools(client: MCPClient): Promise<Record<string, MastraTool>> {
55
+ private async transformTools(client: ToolClient): Promise<Record<string, MastraTool>> {
55
56
  if (!client.isConnected()) {
56
57
  return {};
57
58
  }
@@ -59,7 +60,7 @@ export class MastraAdapter {
59
60
  await this.ensureZod();
60
61
 
61
62
  const result = await client.listTools();
62
- const prefix = this.options.prefix ?? client.getServerId()?.replace(/-/g, '').substring(0, 8) ?? 'mcp';
63
+ const prefix = this.options.prefix ?? client.getServerId?.()?.replace(/-/g, '').substring(0, 8) ?? 'mcp';
63
64
  const tools: Record<string, MastraTool> = {};
64
65
 
65
66
  for (const tool of result.tools) {
@@ -113,7 +114,7 @@ export class MastraAdapter {
113
114
  try {
114
115
  return await this.transformTools(client);
115
116
  } catch (error) {
116
- console.error(`[MastraAdapter] Failed to fetch tools from ${client.getServerId()}:`, error);
117
+ console.error(`[MastraAdapter] Failed to fetch tools from ${client.getServerId?.() ?? "unknown"}:`, error);
117
118
  return {};
118
119
  }
119
120
  })
@@ -128,3 +129,4 @@ export class MastraAdapter {
128
129
  return new MastraAdapter(client, options).getTools();
129
130
  }
130
131
  }
132
+
@@ -25,6 +25,9 @@ import type {
25
25
  ListToolsRpcResult,
26
26
  ListPromptsResult,
27
27
  ListResourcesResult,
28
+ SetToolPolicyResult,
29
+ GetToolPolicyResult,
30
+ ToolPolicy,
28
31
  } from '../../shared/types.js';
29
32
 
30
33
  export interface SSEClientOptions {
@@ -99,6 +102,21 @@ export class SSEClient {
99
102
  return this.sendRequest<DisconnectResult>('disconnect', { sessionId });
100
103
  }
101
104
 
105
+ async reconnectToServer(params: ConnectParams): Promise<ConnectResult> {
106
+ return this.sendRequest<ConnectResult>('reconnect', params);
107
+ }
108
+
109
+ async setToolPolicy(
110
+ sessionId: string,
111
+ toolPolicy: Pick<ToolPolicy, 'mode'> & { toolIds?: string[] }
112
+ ): Promise<SetToolPolicyResult> {
113
+ return this.sendRequest<SetToolPolicyResult>('setToolPolicy', { sessionId, toolPolicy });
114
+ }
115
+
116
+ async getToolPolicy(sessionId: string): Promise<GetToolPolicyResult> {
117
+ return this.sendRequest<GetToolPolicyResult>('getToolPolicy', { sessionId });
118
+ }
119
+
102
120
  async listTools(sessionId: string): Promise<ListToolsRpcResult> {
103
121
  return this.sendRequest<ListToolsRpcResult>('listTools', { sessionId });
104
122
  }
@@ -367,3 +385,6 @@ export class SSEClient {
367
385
  }
368
386
  }
369
387
  }
388
+
389
+
390
+
@@ -135,7 +135,6 @@ export function createOAuthPopupRedirectHandler(
135
135
  openCenteredPopup(url, {
136
136
  ...options,
137
137
  onBlocked: options.onBlocked ?? ((blockedUrl) => {
138
- window.alert('Popup blocked! Allow popups for this site to complete authentication.');
139
138
  window.location.href = blockedUrl;
140
139
  }),
141
140
  });
@@ -179,30 +178,26 @@ export function useMcpOAuthPopup<TConnection extends OAuthPopupConnectionLike>(
179
178
  : '';
180
179
  const targetSessionId = rawState ? parseOAuthState(rawState)?.sessionId || rawState : '';
181
180
 
182
- if (popupWindow && targetSessionId) {
181
+ if (targetSessionId) {
183
182
  pendingPopupsRef.current.set(targetSessionId, { popupWindow, state: rawState });
184
183
  }
185
184
 
186
185
  if (!targetSessionId) {
187
- if (popupWindow) {
188
- postPopupResult(popupWindow, {
189
- success: false,
190
- error: 'Missing OAuth session identifier',
191
- });
192
- }
186
+ postPopupResult(popupWindow, {
187
+ success: false,
188
+ error: 'Missing OAuth session identifier',
189
+ });
193
190
  return;
194
191
  }
195
192
 
196
193
  const targetSession = connections.find((connection) => connection.sessionId === targetSessionId);
197
194
  if (!targetSession) {
198
- if (popupWindow) {
199
- postPopupResult(popupWindow, {
200
- sessionId: targetSessionId,
201
- state: rawState,
202
- success: false,
203
- error: 'OAuth session not found in the current client state',
204
- });
205
- }
195
+ postPopupResult(popupWindow, {
196
+ sessionId: targetSessionId,
197
+ state: rawState,
198
+ success: false,
199
+ error: 'OAuth session not found in the current client state',
200
+ });
206
201
  return;
207
202
  }
208
203
 
@@ -217,14 +212,12 @@ export function useMcpOAuthPopup<TConnection extends OAuthPopupConnectionLike>(
217
212
  } catch (error) {
218
213
  processingCodesRef.current.delete(codeKey);
219
214
  pendingPopupsRef.current.delete(targetSession.sessionId);
220
- if (popupWindow) {
221
- postPopupResult(popupWindow, {
222
- sessionId: rawState,
223
- state: rawState,
224
- success: false,
225
- error: error instanceof Error ? error.message : 'Failed to finish auth',
226
- });
227
- }
215
+ postPopupResult(popupWindow, {
216
+ sessionId: rawState,
217
+ state: rawState,
218
+ success: false,
219
+ error: error instanceof Error ? error.message : 'Failed to finish auth',
220
+ });
228
221
  }
229
222
  };
230
223
 
@@ -18,6 +18,9 @@ import type {
18
18
  ListPromptsResult,
19
19
  ListResourcesResult,
20
20
  SessionInfo,
21
+ ToolPolicy,
22
+ SetToolPolicyResult,
23
+ GetToolPolicyResult,
21
24
  } from '../../shared/types';
22
25
 
23
26
  export interface UseMcpOptions {
@@ -89,6 +92,7 @@ export interface McpConnection {
89
92
  error?: string;
90
93
  createdAt?: Date;
91
94
  updatedAt?: Date;
95
+ toolPolicy?: ToolPolicy;
92
96
  }
93
97
 
94
98
  export interface McpClient {
@@ -193,6 +197,19 @@ export interface McpClient {
193
197
  */
194
198
  listTools: (sessionId: string) => Promise<ListToolsRpcResult>;
195
199
 
200
+ /**
201
+ * Update per-session tool access policy
202
+ */
203
+ updateToolPolicy: (
204
+ sessionId: string,
205
+ toolPolicy: Pick<ToolPolicy, 'mode'> & { toolIds?: string[] }
206
+ ) => Promise<SetToolPolicyResult>;
207
+
208
+ /**
209
+ * Get all tools and effective policy state for access management
210
+ */
211
+ getToolAccess: (sessionId: string) => Promise<GetToolPolicyResult>;
212
+
196
213
  /**
197
214
  * List available prompts for a session
198
215
  */
@@ -428,6 +445,7 @@ export function useMcp(options: UseMcpOptions): McpClient {
428
445
  state: getInitialConnectionState(s.status),
429
446
  createdAt: new Date(s.createdAt),
430
447
  updatedAt: new Date(s.updatedAt ?? s.createdAt),
448
+ toolPolicy: s.toolPolicy,
431
449
  tools: [],
432
450
  }))
433
451
  );
@@ -498,24 +516,15 @@ export function useMcp(options: UseMcpOptions): McpClient {
498
516
  throw new Error('SSE client not initialized');
499
517
  }
500
518
 
501
- // Find and disconnect existing session for the same server
502
- const existing = connections.find(
503
- (c: McpConnection) => c.serverId === params.serverId || c.serverUrl === params.serverUrl
504
- );
505
- if (existing) {
506
- await clientRef.current.disconnectFromServer(existing.sessionId);
507
- if (isMountedRef.current) {
508
- setConnections((prev: McpConnection[]) =>
509
- prev.filter((c: McpConnection) => c.sessionId !== existing.sessionId)
510
- );
511
- }
512
- }
519
+ const result = await clientRef.current.reconnectToServer(params);
520
+
521
+ // The server emits connection events for the new session via SSE,
522
+ // so local state is kept in sync automatically. No manual removal
523
+ // of the old session or insertion of the new one needed here.
513
524
 
514
- // Connect fresh
515
- const result = await clientRef.current.connectToServer(params);
516
525
  return result.sessionId;
517
526
  },
518
- [connections]
527
+ []
519
528
  );
520
529
 
521
530
  /**
@@ -607,6 +616,42 @@ export function useMcp(options: UseMcpOptions): McpClient {
607
616
  return await clientRef.current.listTools(sessionId);
608
617
  }, []);
609
618
 
619
+ /**
620
+ * Update tool access policy for a session
621
+ */
622
+ const updateToolPolicy = useCallback(async (
623
+ sessionId: string,
624
+ toolPolicy: Pick<ToolPolicy, 'mode'> & { toolIds?: string[] }
625
+ ): Promise<SetToolPolicyResult> => {
626
+ if (!clientRef.current) {
627
+ throw new Error('SSE client not initialized');
628
+ }
629
+
630
+ const result = await clientRef.current.setToolPolicy(sessionId, toolPolicy);
631
+ if (isMountedRef.current) {
632
+ setConnections((prev: McpConnection[]) => prev.map((connection) =>
633
+ connection.sessionId === sessionId
634
+ ? {
635
+ ...connection,
636
+ toolPolicy: result.toolPolicy,
637
+ tools: result.tools,
638
+ updatedAt: new Date(),
639
+ }
640
+ : connection
641
+ ));
642
+ }
643
+ return result;
644
+ }, []);
645
+ /**
646
+ * Get all tools with effective access state for a session
647
+ */
648
+ const getToolAccess = useCallback(async (sessionId: string): Promise<GetToolPolicyResult> => {
649
+ if (!clientRef.current) {
650
+ throw new Error('SSE client not initialized');
651
+ }
652
+
653
+ return await clientRef.current.getToolPolicy(sessionId);
654
+ }, []);
610
655
  /**
611
656
  * List prompts
612
657
  */
@@ -700,6 +745,8 @@ export function useMcp(options: UseMcpOptions): McpClient {
700
745
  resumeAuth,
701
746
  callTool,
702
747
  listTools,
748
+ updateToolPolicy,
749
+ getToolAccess,
703
750
  listPrompts,
704
751
  getPrompt,
705
752
  listResources,
@@ -724,6 +771,8 @@ export function useMcp(options: UseMcpOptions): McpClient {
724
771
  resumeAuth,
725
772
  callTool,
726
773
  listTools,
774
+ updateToolPolicy,
775
+ getToolAccess,
727
776
  listPrompts,
728
777
  getPrompt,
729
778
  listResources,
@@ -732,3 +781,8 @@ export function useMcp(options: UseMcpOptions): McpClient {
732
781
  ]
733
782
  );
734
783
  }
784
+
785
+
786
+
787
+
788
+