@mcp-ts/sdk 2.0.0 → 2.2.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 (53) hide show
  1. package/dist/adapters/agui-adapter.d.mts +2 -2
  2. package/dist/adapters/agui-adapter.d.ts +2 -2
  3. package/dist/adapters/agui-adapter.js +1 -0
  4. package/dist/adapters/agui-adapter.js.map +1 -1
  5. package/dist/adapters/agui-adapter.mjs +1 -0
  6. package/dist/adapters/agui-adapter.mjs.map +1 -1
  7. package/dist/adapters/agui-middleware.d.mts +2 -2
  8. package/dist/adapters/agui-middleware.d.ts +2 -2
  9. package/dist/adapters/ai-adapter.d.mts +2 -2
  10. package/dist/adapters/ai-adapter.d.ts +2 -2
  11. package/dist/adapters/ai-adapter.js +1 -0
  12. package/dist/adapters/ai-adapter.js.map +1 -1
  13. package/dist/adapters/ai-adapter.mjs +1 -0
  14. package/dist/adapters/ai-adapter.mjs.map +1 -1
  15. package/dist/adapters/langchain-adapter.d.mts +2 -2
  16. package/dist/adapters/langchain-adapter.d.ts +2 -2
  17. package/dist/adapters/langchain-adapter.js +1 -0
  18. package/dist/adapters/langchain-adapter.js.map +1 -1
  19. package/dist/adapters/langchain-adapter.mjs +1 -0
  20. package/dist/adapters/langchain-adapter.mjs.map +1 -1
  21. package/dist/client/index.d.mts +2 -2
  22. package/dist/client/index.d.ts +2 -2
  23. package/dist/client/react.d.mts +4 -4
  24. package/dist/client/react.d.ts +4 -4
  25. package/dist/client/react.js.map +1 -1
  26. package/dist/client/react.mjs.map +1 -1
  27. package/dist/client/vue.d.mts +4 -4
  28. package/dist/client/vue.d.ts +4 -4
  29. package/dist/{index-eaH14_5u.d.mts → index-Cfjsme-a.d.mts} +1 -1
  30. package/dist/{index-C9gvpxy5.d.ts → index-CmjMd2ac.d.ts} +1 -1
  31. package/dist/index.d.mts +3 -3
  32. package/dist/index.d.ts +3 -3
  33. package/dist/index.js +47 -7
  34. package/dist/index.js.map +1 -1
  35. package/dist/index.mjs +47 -7
  36. package/dist/index.mjs.map +1 -1
  37. package/dist/server/index.d.mts +2 -2
  38. package/dist/server/index.d.ts +2 -2
  39. package/dist/shared/index.d.mts +6 -6
  40. package/dist/shared/index.d.ts +6 -6
  41. package/dist/shared/index.js +47 -7
  42. package/dist/shared/index.js.map +1 -1
  43. package/dist/shared/index.mjs +47 -7
  44. package/dist/shared/index.mjs.map +1 -1
  45. package/dist/{tool-router-Dnd6IOKC.d.mts → tool-router-C8hIA-tg.d.mts} +26 -1
  46. package/dist/{tool-router-Ddtybmr0.d.ts → tool-router-CdX8e9bk.d.ts} +26 -1
  47. package/dist/{types-BCAG20P6.d.mts → types-CxFaaZrM.d.mts} +2 -1
  48. package/dist/{types-BCAG20P6.d.ts → types-CxFaaZrM.d.ts} +2 -1
  49. package/package.json +1 -1
  50. package/src/shared/meta-tools.ts +5 -4
  51. package/src/shared/tool-index.ts +1 -0
  52. package/src/shared/tool-router.ts +69 -6
  53. package/src/shared/types.ts +2 -1
@@ -1,5 +1,5 @@
1
1
  import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
- import { u as ToolClientProvider, T as ToolClient } from './types-BCAG20P6.mjs';
2
+ import { u as ToolClientProvider, T as ToolClient } from './types-CxFaaZrM.mjs';
3
3
 
4
4
  /**
5
5
  * ToolIndex — Lightweight in-memory search index for MCP tool discovery.
@@ -64,6 +64,7 @@ interface IndexedTool extends Tool {
64
64
  sessionId: string;
65
65
  serverId: string;
66
66
  serverName: string;
67
+ outputSchema?: Tool['outputSchema'];
67
68
  }
68
69
  /**
69
70
  * An optional embedding function supplied by the consumer.
@@ -268,6 +269,20 @@ interface ToolRouterOptions {
268
269
  * @default false
269
270
  */
270
271
  compactSchemas?: boolean;
272
+ /**
273
+ * Tool names to expose directly when using `search` strategy.
274
+ * Pinned tools are removed from discovery results and should be called directly.
275
+ */
276
+ pinnedTools?: string[];
277
+ /**
278
+ * Tool names to omit from direct exposure while keeping them indexed for
279
+ * search/schema lookup/calls through meta-tools.
280
+ */
281
+ deferredTools?: string[];
282
+ /**
283
+ * Tool names or glob-style patterns to omit entirely from the router catalog.
284
+ */
285
+ excludeTools?: string[];
271
286
  /**
272
287
  * Optional embedding function for semantic search.
273
288
  * When not provided, keyword TF-IDF matching is used.
@@ -295,12 +310,18 @@ declare class ToolRouter {
295
310
  private options;
296
311
  private index;
297
312
  private allTools;
313
+ private pinnedTools;
314
+ private deferredTools;
315
+ private discoverableTools;
298
316
  private groupsMap;
299
317
  private strategy;
300
318
  private maxTools;
301
319
  private compactSchemas;
302
320
  private activeGroups;
303
321
  private customGroups?;
322
+ private pinnedToolNames;
323
+ private deferredToolNames;
324
+ private excludeToolMatchers;
304
325
  private initialized;
305
326
  constructor(client: ToolRouterClientInput, options?: ToolRouterOptions);
306
327
  /**
@@ -370,6 +391,10 @@ declare class ToolRouter {
370
391
  private getGroupFilteredTools;
371
392
  /** The 4 meta-tool definitions exposed in `search` strategy. */
372
393
  private getMetaToolDefinitions;
394
+ private matchesPinnedTool;
395
+ private matchesDeferredTool;
396
+ private matchesExcludedTool;
397
+ private getDirectlyVisibleTools;
373
398
  }
374
399
 
375
400
  export { type CompactTool as C, type EmbedFn as E, type IndexedTool as I, SchemaCompressor as S, type ToolGroupInfo as T, ToolIndex as a, type ToolIndexOptions as b, type ToolListResult as c, ToolRouter as d, type ToolRouterClientInput as e, type ToolRouterOptions as f, type ToolRouterStrategy as g, type ToolSearchOptions as h, type ToolServerSummary as i, type ToolSummary as j };
@@ -1,5 +1,5 @@
1
1
  import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
- import { u as ToolClientProvider, T as ToolClient } from './types-BCAG20P6.js';
2
+ import { u as ToolClientProvider, T as ToolClient } from './types-CxFaaZrM.js';
3
3
 
4
4
  /**
5
5
  * ToolIndex — Lightweight in-memory search index for MCP tool discovery.
@@ -64,6 +64,7 @@ interface IndexedTool extends Tool {
64
64
  sessionId: string;
65
65
  serverId: string;
66
66
  serverName: string;
67
+ outputSchema?: Tool['outputSchema'];
67
68
  }
68
69
  /**
69
70
  * An optional embedding function supplied by the consumer.
@@ -268,6 +269,20 @@ interface ToolRouterOptions {
268
269
  * @default false
269
270
  */
270
271
  compactSchemas?: boolean;
272
+ /**
273
+ * Tool names to expose directly when using `search` strategy.
274
+ * Pinned tools are removed from discovery results and should be called directly.
275
+ */
276
+ pinnedTools?: string[];
277
+ /**
278
+ * Tool names to omit from direct exposure while keeping them indexed for
279
+ * search/schema lookup/calls through meta-tools.
280
+ */
281
+ deferredTools?: string[];
282
+ /**
283
+ * Tool names or glob-style patterns to omit entirely from the router catalog.
284
+ */
285
+ excludeTools?: string[];
271
286
  /**
272
287
  * Optional embedding function for semantic search.
273
288
  * When not provided, keyword TF-IDF matching is used.
@@ -295,12 +310,18 @@ declare class ToolRouter {
295
310
  private options;
296
311
  private index;
297
312
  private allTools;
313
+ private pinnedTools;
314
+ private deferredTools;
315
+ private discoverableTools;
298
316
  private groupsMap;
299
317
  private strategy;
300
318
  private maxTools;
301
319
  private compactSchemas;
302
320
  private activeGroups;
303
321
  private customGroups?;
322
+ private pinnedToolNames;
323
+ private deferredToolNames;
324
+ private excludeToolMatchers;
304
325
  private initialized;
305
326
  constructor(client: ToolRouterClientInput, options?: ToolRouterOptions);
306
327
  /**
@@ -370,6 +391,10 @@ declare class ToolRouter {
370
391
  private getGroupFilteredTools;
371
392
  /** The 4 meta-tool definitions exposed in `search` strategy. */
372
393
  private getMetaToolDefinitions;
394
+ private matchesPinnedTool;
395
+ private matchesDeferredTool;
396
+ private matchesExcludedTool;
397
+ private getDirectlyVisibleTools;
373
398
  }
374
399
 
375
400
  export { type CompactTool as C, type EmbedFn as E, type IndexedTool as I, SchemaCompressor as S, type ToolGroupInfo as T, ToolIndex as a, type ToolIndexOptions as b, type ToolListResult as c, ToolRouter as d, type ToolRouterClientInput as e, type ToolRouterOptions as f, type ToolRouterStrategy as g, type ToolSearchOptions as h, type ToolServerSummary as i, type ToolSummary as j };
@@ -79,7 +79,8 @@ declare function isCallToolSuccess(response: CallToolResponse): response is Call
79
79
  type ToolInfo = {
80
80
  name: string;
81
81
  description?: string;
82
- inputSchema?: unknown;
82
+ inputSchema?: Tool['inputSchema'];
83
+ outputSchema?: Tool['outputSchema'];
83
84
  };
84
85
  type TransportType = 'sse' | 'streamable-http';
85
86
  type McpRpcMethod = 'connect' | 'disconnect' | 'listTools' | 'callTool' | 'listSessions' | 'getSession' | 'finishAuth' | 'listPrompts' | 'getPrompt' | 'listResources' | 'readResource';
@@ -79,7 +79,8 @@ declare function isCallToolSuccess(response: CallToolResponse): response is Call
79
79
  type ToolInfo = {
80
80
  name: string;
81
81
  description?: string;
82
- inputSchema?: unknown;
82
+ inputSchema?: Tool['inputSchema'];
83
+ outputSchema?: Tool['outputSchema'];
83
84
  };
84
85
  type TransportType = 'sse' | 'streamable-http';
85
86
  type McpRpcMethod = 'connect' | 'disconnect' | 'listTools' | 'callTool' | 'listSessions' | 'getSession' | 'finishAuth' | 'listPrompts' | 'getPrompt' | 'listResources' | 'readResource';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-ts/sdk",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -135,16 +135,16 @@ export function createRegexSearchToolDefinition(): Tool {
135
135
  *
136
136
  * After discovering tools via `mcp_search_tools` or
137
137
  * `mcp_search_tool_regex`, the LLM calls this to load the full
138
- * inputSchema for a specific tool so it can construct the correct
139
- * arguments.
138
+ * input and output schemas for a specific tool so it can construct the
139
+ * correct arguments and plan around the result shape.
140
140
  */
141
141
  export function createGetSchemaToolDefinition(): Tool {
142
142
  return {
143
143
  name: 'mcp_get_tool_schema',
144
144
  description:
145
- 'Get the full input schema (parameters) for a specific tool. ' +
145
+ 'Get the full input schema (parameters) and output schema (result shape) for a specific tool. ' +
146
146
  'Call this after mcp_search_tools to get the parameter details ' +
147
- 'needed to call a tool correctly. ' +
147
+ 'needed to call a tool correctly and understand what it returns. ' +
148
148
  'Do NOT call the discovered tool directly; after reading the schema, call mcp_execute_tool.',
149
149
  inputSchema: {
150
150
  type: 'object' as const,
@@ -432,6 +432,7 @@ export async function executeMetaTool(
432
432
  name: tool.name,
433
433
  description: tool.description,
434
434
  inputSchema: tool.inputSchema,
435
+ outputSchema: tool.outputSchema,
435
436
  executionInstructions: {
436
437
  nextTool: 'mcp_execute_tool',
437
438
  toolName: tool.name,
@@ -72,6 +72,7 @@ export interface IndexedTool extends Tool {
72
72
  sessionId: string;
73
73
  serverId: string;
74
74
  serverName: string;
75
+ outputSchema?: Tool['outputSchema'];
75
76
  }
76
77
 
77
78
  /**
@@ -99,6 +99,23 @@ export interface ToolRouterOptions {
99
99
  */
100
100
  compactSchemas?: boolean;
101
101
 
102
+ /**
103
+ * Tool names to expose directly when using `search` strategy.
104
+ * Pinned tools are removed from discovery results and should be called directly.
105
+ */
106
+ pinnedTools?: string[];
107
+
108
+ /**
109
+ * Tool names to omit from direct exposure while keeping them indexed for
110
+ * search/schema lookup/calls through meta-tools.
111
+ */
112
+ deferredTools?: string[];
113
+
114
+ /**
115
+ * Tool names or glob-style patterns to omit entirely from the router catalog.
116
+ */
117
+ excludeTools?: string[];
118
+
102
119
  /**
103
120
  * Optional embedding function for semantic search.
104
121
  * When not provided, keyword TF-IDF matching is used.
@@ -136,12 +153,18 @@ export type ToolRouterClientInput = ToolClientProvider | ToolClient[];
136
153
  export class ToolRouter {
137
154
  private index: ToolIndex;
138
155
  private allTools: IndexedTool[] = [];
156
+ private pinnedTools: IndexedTool[] = [];
157
+ private deferredTools: IndexedTool[] = [];
158
+ private discoverableTools: IndexedTool[] = [];
139
159
  private groupsMap = new Map<string, ToolGroupInfo>();
140
160
  private strategy: ToolRouterStrategy;
141
161
  private maxTools: number;
142
162
  private compactSchemas: boolean;
143
163
  private activeGroups: Set<string>;
144
164
  private customGroups?: Record<string, string[]>;
165
+ private pinnedToolNames: Set<string>;
166
+ private deferredToolNames: Set<string>;
167
+ private excludeToolMatchers: RegExp[];
145
168
  private initialized = false;
146
169
 
147
170
  constructor(
@@ -153,6 +176,11 @@ export class ToolRouter {
153
176
  this.compactSchemas = options.compactSchemas ?? false;
154
177
  this.activeGroups = new Set(options.activeGroups ?? []);
155
178
  this.customGroups = options.groups;
179
+ this.pinnedToolNames = new Set(options.pinnedTools ?? []);
180
+ this.deferredToolNames = new Set(options.deferredTools ?? []);
181
+ this.excludeToolMatchers = (options.excludeTools ?? []).map((pattern) =>
182
+ globToRegExp(pattern)
183
+ );
156
184
 
157
185
  this.index = new ToolIndex({
158
186
  embedFn: options.embedFn,
@@ -177,16 +205,17 @@ export class ToolRouter {
177
205
 
178
206
  switch (this.strategy) {
179
207
  case 'search':
180
- return this.getMetaToolDefinitions();
208
+ return [...this.getMetaToolDefinitions(), ...this.pinnedTools];
181
209
 
182
210
  case 'groups':
183
211
  return this.getGroupFilteredTools();
184
212
 
185
213
  case 'all':
186
214
  default:
215
+ const directlyVisibleTools = this.getDirectlyVisibleTools();
187
216
  if (this.compactSchemas) {
188
217
  // Return tools with inputSchema stripped
189
- return this.allTools.map((t) => {
218
+ return directlyVisibleTools.map((t) => {
190
219
  const compact = SchemaCompressor.toCompact(t);
191
220
  return {
192
221
  name: compact.name,
@@ -197,7 +226,7 @@ export class ToolRouter {
197
226
  };
198
227
  });
199
228
  }
200
- return [...this.allTools];
229
+ return [...directlyVisibleTools];
201
230
  }
202
231
  }
203
232
 
@@ -352,8 +381,14 @@ export class ToolRouter {
352
381
  private async ensureInitialized(): Promise<void> {
353
382
  if (this.initialized) return;
354
383
 
355
- this.allTools = await this.fetchAllTools();
356
- await this.index.buildIndex(this.allTools);
384
+ const fetchedTools = await this.fetchAllTools();
385
+ this.allTools = fetchedTools.filter((tool) => !this.matchesExcludedTool(tool.name));
386
+ this.pinnedTools = this.allTools.filter((tool) => this.matchesPinnedTool(tool.name));
387
+ this.deferredTools = this.allTools.filter(
388
+ (tool) => !this.matchesPinnedTool(tool.name) && this.matchesDeferredTool(tool)
389
+ );
390
+ this.discoverableTools = this.allTools.filter((tool) => !this.matchesPinnedTool(tool.name));
391
+ await this.index.buildIndex(this.discoverableTools);
357
392
  this.buildGroups();
358
393
  this.initialized = true;
359
394
  }
@@ -447,7 +482,7 @@ export class ToolRouter {
447
482
  }
448
483
  }
449
484
 
450
- const filtered = this.allTools.filter((t) => activeToolNames.has(t.name));
485
+ const filtered = this.getDirectlyVisibleTools().filter((t) => activeToolNames.has(t.name));
451
486
 
452
487
  if (this.compactSchemas) {
453
488
  return filtered.slice(0, this.maxTools).map((t) => {
@@ -476,4 +511,32 @@ export class ToolRouter {
476
511
  ];
477
512
  }
478
513
 
514
+ private matchesPinnedTool(toolName: string): boolean {
515
+ return this.pinnedToolNames.has(toolName);
516
+ }
517
+
518
+ private matchesDeferredTool(tool: Tool): boolean {
519
+ if (this.deferredToolNames.has(tool.name)) {
520
+ return true;
521
+ }
522
+
523
+ const meta = (tool as Tool & {
524
+ _meta?: { toolRouter?: { deferred?: boolean } };
525
+ })._meta;
526
+ return meta?.toolRouter?.deferred === true;
527
+ }
528
+
529
+ private matchesExcludedTool(toolName: string): boolean {
530
+ return this.excludeToolMatchers.some((matcher) => matcher.test(toolName));
531
+ }
532
+
533
+ private getDirectlyVisibleTools(): IndexedTool[] {
534
+ return this.allTools.filter((tool) => !this.matchesDeferredTool(tool) || this.matchesPinnedTool(tool.name));
535
+ }
536
+ }
537
+
538
+ function globToRegExp(pattern: string): RegExp {
539
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&');
540
+ const regexPattern = `^${escaped.replace(/\*/g, '.*')}$`;
541
+ return new RegExp(regexPattern);
479
542
  }
@@ -162,7 +162,8 @@ export function isCallToolSuccess(
162
162
  export type ToolInfo = {
163
163
  name: string;
164
164
  description?: string;
165
- inputSchema?: unknown;
165
+ inputSchema?: Tool['inputSchema'];
166
+ outputSchema?: Tool['outputSchema'];
166
167
  };
167
168
 
168
169
  // Transport type