@mcp-ts/sdk 1.5.1 → 1.5.3

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 (61) hide show
  1. package/README.md +89 -27
  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-adapter.js +50 -10
  5. package/dist/adapters/agui-adapter.js.map +1 -1
  6. package/dist/adapters/agui-adapter.mjs +50 -10
  7. package/dist/adapters/agui-adapter.mjs.map +1 -1
  8. package/dist/adapters/agui-middleware.d.mts +5 -1
  9. package/dist/adapters/agui-middleware.d.ts +5 -1
  10. package/dist/adapters/agui-middleware.js +116 -49
  11. package/dist/adapters/agui-middleware.js.map +1 -1
  12. package/dist/adapters/agui-middleware.mjs +117 -50
  13. package/dist/adapters/agui-middleware.mjs.map +1 -1
  14. package/dist/adapters/ai-adapter.d.mts +1 -1
  15. package/dist/adapters/ai-adapter.d.ts +1 -1
  16. package/dist/adapters/ai-adapter.js +49 -9
  17. package/dist/adapters/ai-adapter.js.map +1 -1
  18. package/dist/adapters/ai-adapter.mjs +49 -9
  19. package/dist/adapters/ai-adapter.mjs.map +1 -1
  20. package/dist/adapters/langchain-adapter.d.mts +1 -1
  21. package/dist/adapters/langchain-adapter.d.ts +1 -1
  22. package/dist/adapters/langchain-adapter.js +49 -9
  23. package/dist/adapters/langchain-adapter.js.map +1 -1
  24. package/dist/adapters/langchain-adapter.mjs +49 -9
  25. package/dist/adapters/langchain-adapter.mjs.map +1 -1
  26. package/dist/client/react.d.mts +10 -0
  27. package/dist/client/react.d.ts +10 -0
  28. package/dist/client/react.js +23 -0
  29. package/dist/client/react.js.map +1 -1
  30. package/dist/client/react.mjs +23 -0
  31. package/dist/client/react.mjs.map +1 -1
  32. package/dist/client/vue.d.mts +10 -0
  33. package/dist/client/vue.d.ts +10 -0
  34. package/dist/client/vue.js +17 -0
  35. package/dist/client/vue.js.map +1 -1
  36. package/dist/client/vue.mjs +17 -0
  37. package/dist/client/vue.mjs.map +1 -1
  38. package/dist/index.d.mts +1 -1
  39. package/dist/index.d.ts +1 -1
  40. package/dist/index.js +123 -28
  41. package/dist/index.js.map +1 -1
  42. package/dist/index.mjs +123 -28
  43. package/dist/index.mjs.map +1 -1
  44. package/dist/shared/index.d.mts +2 -2
  45. package/dist/shared/index.d.ts +2 -2
  46. package/dist/shared/index.js +123 -28
  47. package/dist/shared/index.js.map +1 -1
  48. package/dist/shared/index.mjs +123 -28
  49. package/dist/shared/index.mjs.map +1 -1
  50. package/dist/{tool-router-XnWVxPzv.d.mts → tool-router-DK0RJblO.d.mts} +3 -0
  51. package/dist/{tool-router-Bo8qZbsD.d.ts → tool-router-DsKhRmJm.d.ts} +3 -0
  52. package/package.json +3 -3
  53. package/src/adapters/agui-adapter.ts +7 -7
  54. package/src/adapters/agui-middleware.ts +163 -59
  55. package/src/adapters/ai-adapter.ts +5 -5
  56. package/src/adapters/langchain-adapter.ts +5 -5
  57. package/src/client/react/use-mcp.ts +48 -0
  58. package/src/client/vue/use-mcp.ts +42 -0
  59. package/src/shared/meta-tools.ts +73 -15
  60. package/src/shared/tool-index.ts +85 -12
  61. package/src/shared/tool-router.ts +8 -7
@@ -277,6 +277,7 @@ var ToolIndex = class _ToolIndex {
277
277
  name: tool.name,
278
278
  description: tool.description ?? "",
279
279
  serverName: tool.serverName,
280
+ serverId: tool.serverId,
280
281
  sessionId: tool.sessionId,
281
282
  estimatedTokens
282
283
  });
@@ -339,12 +340,50 @@ var ToolIndex = class _ToolIndex {
339
340
  */
340
341
  async search(query, topK = 5) {
341
342
  if (this.tools.size === 0) return [];
342
- const queryLower = query.toLowerCase();
343
- const queryTokens = this.tokenize(queryLower);
343
+ const queryLower = query.toLowerCase().trim();
344
+ const exactMatches = [...this.toolSummaries.values()].filter(
345
+ (summary) => summary.name.toLowerCase() === queryLower
346
+ );
347
+ if (exactMatches.length > 0) {
348
+ return exactMatches.slice(0, topK);
349
+ }
350
+ if (queryLower.startsWith("mcp__") && queryLower.length > 5) {
351
+ const prefixMatches = [...this.toolSummaries.values()].filter((t) => t.name.toLowerCase().startsWith(queryLower)).slice(0, topK);
352
+ if (prefixMatches.length > 0) return prefixMatches;
353
+ }
354
+ const queryTermsRaw = queryLower.split(/\s+/).filter((t) => t.length > 0);
355
+ const requiredTerms = [];
356
+ const optionalTerms = [];
357
+ for (const term of queryTermsRaw) {
358
+ if (term.startsWith("+") && term.length > 1) {
359
+ requiredTerms.push(term.slice(1));
360
+ } else {
361
+ optionalTerms.push(term);
362
+ }
363
+ }
364
+ const allScoringTerms = requiredTerms.length > 0 ? [...requiredTerms, ...optionalTerms] : queryTermsRaw;
365
+ const normalizedQueryText = allScoringTerms.join(" ").trim();
366
+ const queryTokens = this.tokenize(allScoringTerms.join(" "));
367
+ const candidateKeys = /* @__PURE__ */ new Set();
368
+ for (const docKey of this.toolSummaries.keys()) {
369
+ if (requiredTerms.length > 0) {
370
+ const text = this.searchTexts.get(docKey) || "";
371
+ const summary = this.toolSummaries.get(docKey);
372
+ const nameLower = summary.name.toLowerCase();
373
+ const matchesAll = requiredTerms.every(
374
+ (term) => text.includes(term) || nameLower.includes(term)
375
+ );
376
+ if (!matchesAll) continue;
377
+ }
378
+ candidateKeys.add(docKey);
379
+ }
344
380
  const keywordScores = /* @__PURE__ */ new Map();
345
381
  const k1 = 1.2;
346
382
  const b = 0.75;
347
- for (const [docKey, docTf] of this.tfVectors) {
383
+ for (const docKey of candidateKeys) {
384
+ const docTf = this.tfVectors.get(docKey);
385
+ if (!docTf) continue;
386
+ const summary = this.toolSummaries.get(docKey);
348
387
  let score = 0;
349
388
  const docLen = this.docLengths.get(docKey) ?? 0;
350
389
  for (const tok of queryTokens) {
@@ -355,16 +394,31 @@ var ToolIndex = class _ToolIndex {
355
394
  const denominator = tfVal + k1 * (1 - b + b * (docLen / this.avgDocLength));
356
395
  score += idf * (numerator / denominator);
357
396
  }
358
- keywordScores.set(docKey, score);
397
+ const serverLower = (summary.serverName || summary.serverId || "").toLowerCase();
398
+ const toolLower = summary.name.toLowerCase();
399
+ for (const term of allScoringTerms) {
400
+ if (serverLower.includes(term)) {
401
+ score += 10;
402
+ }
403
+ if (toolLower.includes(term)) {
404
+ score += 5;
405
+ }
406
+ }
407
+ if (score > 0) {
408
+ keywordScores.set(docKey, score);
409
+ }
359
410
  }
360
411
  let embeddingScores = null;
361
412
  if (this.options.embedFn && this.embeddings.size > 0) {
362
413
  try {
363
- const [queryEmbedding] = await this.options.embedFn([queryLower]);
414
+ const [queryEmbedding] = await this.options.embedFn([normalizedQueryText]);
364
415
  if (queryEmbedding) {
365
416
  embeddingScores = /* @__PURE__ */ new Map();
366
- for (const [docKey, vec] of this.embeddings) {
367
- embeddingScores.set(docKey, this.cosineSimilarity(queryEmbedding, vec));
417
+ for (const docKey of candidateKeys) {
418
+ const vec = this.embeddings.get(docKey);
419
+ if (vec) {
420
+ embeddingScores.set(docKey, this.cosineSimilarity(queryEmbedding, vec));
421
+ }
368
422
  }
369
423
  }
370
424
  } catch {
@@ -372,7 +426,7 @@ var ToolIndex = class _ToolIndex {
372
426
  }
373
427
  const kw = this.options.keywordWeight;
374
428
  const finalScores = [];
375
- for (const docKey of this.toolSummaries.keys()) {
429
+ for (const docKey of candidateKeys) {
376
430
  const kwScore = keywordScores.get(docKey) ?? 0;
377
431
  const embScore = embeddingScores?.get(docKey) ?? 0;
378
432
  const score = embeddingScores ? kw * kwScore + (1 - kw) * embScore : kwScore;
@@ -430,7 +484,7 @@ var ToolIndex = class _ToolIndex {
430
484
  getTool(name, namespace) {
431
485
  const list = this.tools.get(name) ?? [];
432
486
  if (!namespace) return list;
433
- return list.filter((t) => t.sessionId === namespace || t.serverName === namespace);
487
+ return list.filter((t) => t.sessionId === namespace || t.serverId === namespace);
434
488
  }
435
489
  /** All indexed tool names. */
436
490
  getToolNames() {
@@ -490,7 +544,7 @@ var ToolIndex = class _ToolIndex {
490
544
  return parts.join(" ");
491
545
  }
492
546
  getDocumentKey(tool) {
493
- return `${tool.sessionId}::${tool.serverName}::${tool.name}`;
547
+ return `${tool.sessionId}::${tool.serverId}::${tool.name}`;
494
548
  }
495
549
  /** Simple whitespace + camelCase + snake_case tokenizer. */
496
550
  tokenize(text) {
@@ -576,13 +630,13 @@ var SchemaCompressor = class _SchemaCompressor {
576
630
  function createSearchToolDefinition() {
577
631
  return {
578
632
  name: "mcp_search_tool_bm25",
579
- description: 'Search the catalog of available tools using BM25 natural language ranking. Returns tool names, descriptions, and server info. Use this FIRST to find relevant tools before calling them. Example queries: "database query", "send email", "github pull request".',
633
+ description: 'Search the catalog of available tools. Returns tool names, descriptions, and server info. Use this FIRST to find relevant tools before calling them.\n\nQuery forms:\n- "select:Read,Edit,Grep" \u2014 fetch these exact tools by name\n- "notebook jupyter" \u2014 keyword search, up to limit best matches\n- "+slack send" \u2014 require "slack" in the name, rank by remaining terms',
580
634
  inputSchema: {
581
635
  type: "object",
582
636
  properties: {
583
637
  query: {
584
638
  type: "string",
585
- description: "Natural language description of the capability you need."
639
+ description: 'Query to find tools. Use "select:<tool_name>" for direct selection, or keywords to search. Prefix keywords with + to require them.'
586
640
  },
587
641
  limit: {
588
642
  type: "number",
@@ -616,7 +670,7 @@ function createRegexSearchToolDefinition() {
616
670
  function createGetSchemaToolDefinition() {
617
671
  return {
618
672
  name: "mcp_get_tool_schema",
619
- description: "Get the full input schema (parameters) for a specific tool. Call this after mcp_search_tool_bm25 to get the parameter details needed to call a tool correctly.",
673
+ description: "Get the full input schema (parameters) for a specific tool. Call this after mcp_search_tool_bm25 to get the parameter details needed to call a tool correctly. Do NOT call the discovered tool directly; after reading the schema, call mcp_execute_tool.",
620
674
  inputSchema: {
621
675
  type: "object",
622
676
  properties: {
@@ -624,9 +678,9 @@ function createGetSchemaToolDefinition() {
624
678
  type: "string",
625
679
  description: "The exact tool name returned by mcp_search_tool_bm25."
626
680
  },
627
- serverName: {
681
+ serverId: {
628
682
  type: "string",
629
- description: "Optional: The server name provided in mcp_search_tool_bm25. Required if multiple tools have the same name."
683
+ description: "Optional: The server ID provided in mcp_search_tool_bm25. Required if multiple tools have the same name."
630
684
  }
631
685
  },
632
686
  required: ["toolName"]
@@ -644,9 +698,9 @@ function createExecuteToolDefinition() {
644
698
  type: "string",
645
699
  description: "The exact tool name from mcp_search_tool_bm25 results."
646
700
  },
647
- serverName: {
701
+ serverId: {
648
702
  type: "string",
649
- description: "Optional: The server name provided in mcp_search_tool_bm25. Required if multiple tools have the same name."
703
+ description: "Optional: The server ID provided in mcp_search_tool_bm25. Required if multiple tools have the same name."
650
704
  },
651
705
  args: {
652
706
  type: "object",
@@ -676,9 +730,43 @@ async function executeMetaTool(toolName, args, router, callToolFn) {
676
730
  case "mcp_search_tool_bm25": {
677
731
  const query = String(args.query ?? "");
678
732
  const limit = Math.min(Number(args.limit) || 5, 20);
733
+ const selectMatch = query.match(/^select:(.+)$/i);
734
+ if (selectMatch) {
735
+ const requested = selectMatch[1].split(",").map((s) => s.trim()).filter(Boolean);
736
+ const found = [];
737
+ const errors = [];
738
+ for (const requestedToolName of requested) {
739
+ const { tool, error } = resolveToolSchema(requestedToolName);
740
+ if (error) {
741
+ const errorMsg = error.content[0]?.type === "text" ? error.content[0].text : "Unknown error";
742
+ errors.push(`- **${requestedToolName}**: ${errorMsg}`);
743
+ } else if (tool) {
744
+ found.push(tool);
745
+ } else {
746
+ errors.push(`- **${requestedToolName}**: Tool not found. Try searching with mcp_search_tool_bm25.`);
747
+ }
748
+ }
749
+ const lines = [];
750
+ if (found.length > 0) {
751
+ lines.push(...found.map(
752
+ (t, i) => `${i + 1}. **${t.name}** (server: ${t.serverName}, serverId: ${t.serverId})
753
+ ${t.description}`
754
+ ));
755
+ }
756
+ if (errors.length > 0) {
757
+ if (lines.length > 0) lines.push("");
758
+ lines.push("Errors resolving some tools:");
759
+ lines.push(...errors);
760
+ }
761
+ const text2 = lines.length > 0 ? lines.join("\n") : `No tools found matching select query: ${requested.join(", ")}`;
762
+ return {
763
+ content: [{ type: "text", text: text2 }],
764
+ isError: found.length === 0
765
+ };
766
+ }
679
767
  const results = await router.searchTools(query, limit);
680
768
  const text = results.length === 0 ? "No tools found matching your query. Try different keywords." : results.map(
681
- (t, i) => `${i + 1}. **${t.name}** (server: ${t.serverName})
769
+ (t, i) => `${i + 1}. **${t.name}** (server: ${t.serverName}, serverId: ${t.serverId})
682
770
  ${t.description}
683
771
  Estimated tokens: ${t.estimatedTokens}`
684
772
  ).join("\n");
@@ -692,7 +780,7 @@ async function executeMetaTool(toolName, args, router, callToolFn) {
692
780
  const limit = Math.min(Number(args.limit) || 5, 20);
693
781
  const results = await router.searchToolsRegex(pattern, limit);
694
782
  const text = results.length === 0 ? "No tools matched your regex pattern. Try a broader pattern." : results.map(
695
- (t, i) => `${i + 1}. **${t.name}** (server: ${t.serverName})
783
+ (t, i) => `${i + 1}. **${t.name}** (server: ${t.serverName}, serverId: ${t.serverId})
696
784
  ${t.description}
697
785
  Estimated tokens: ${t.estimatedTokens}`
698
786
  ).join("\n");
@@ -703,7 +791,7 @@ async function executeMetaTool(toolName, args, router, callToolFn) {
703
791
  }
704
792
  case "mcp_get_tool_schema": {
705
793
  const name = String(args.toolName ?? "");
706
- const namespace = String(args.serverName ?? "") || void 0;
794
+ const namespace = String(args.serverId ?? "") || void 0;
707
795
  const { tool, error } = resolveToolSchema(name, namespace);
708
796
  if (error) {
709
797
  return error;
@@ -722,7 +810,13 @@ async function executeMetaTool(toolName, args, router, callToolFn) {
722
810
  const schema = {
723
811
  name: tool.name,
724
812
  description: tool.description,
725
- inputSchema: tool.inputSchema
813
+ inputSchema: tool.inputSchema,
814
+ executionInstructions: {
815
+ nextTool: "mcp_execute_tool",
816
+ toolName: tool.name,
817
+ serverId: tool.serverId,
818
+ note: "Do not call this discovered tool directly unless it was explicitly registered as a runtime tool. Execute it via mcp_execute_tool and pass these parameters inside args."
819
+ }
726
820
  };
727
821
  return {
728
822
  content: [{ type: "text", text: JSON.stringify(schema, null, 2) }],
@@ -731,7 +825,7 @@ async function executeMetaTool(toolName, args, router, callToolFn) {
731
825
  }
732
826
  case "mcp_execute_tool": {
733
827
  const targetToolName = String(args.toolName ?? "");
734
- const namespace = String(args.serverName ?? "") || void 0;
828
+ const namespace = String(args.serverId ?? "") || void 0;
735
829
  const toolArgs = args.args ?? {};
736
830
  if (!targetToolName) {
737
831
  return {
@@ -880,9 +974,9 @@ var ToolRouter = class {
880
974
  const matches = this.index.getTool(toolName, namespace);
881
975
  if (matches.length === 0) return void 0;
882
976
  if (matches.length > 1) {
883
- const servers = matches.map((m) => m.serverName).join(", ");
977
+ const servers = matches.map((m) => m.serverId).join(", ");
884
978
  throw new Error(
885
- `Tool "${toolName}" is provided by multiple servers: [${servers}]. Please specify the desired "serverName" as a namespace.`
979
+ `Tool "${toolName}" is provided by multiple servers: [${servers}]. Please specify the desired "serverId" as a namespace.`
886
980
  );
887
981
  }
888
982
  return matches[0];
@@ -993,6 +1087,7 @@ var ToolRouter = class {
993
1087
  for (const tool of tools) {
994
1088
  result.push({
995
1089
  ...tool,
1090
+ serverId,
996
1091
  serverName,
997
1092
  sessionId
998
1093
  });
@@ -1026,16 +1121,16 @@ var ToolRouter = class {
1026
1121
  } else {
1027
1122
  const serverTools = /* @__PURE__ */ new Map();
1028
1123
  for (const tool of this.allTools) {
1029
- const group = tool.serverName;
1124
+ const group = tool.serverId;
1030
1125
  if (!serverTools.has(group)) {
1031
1126
  serverTools.set(group, []);
1032
1127
  }
1033
1128
  serverTools.get(group).push(tool.name);
1034
1129
  }
1035
- for (const [serverName, tools] of serverTools) {
1036
- this.groupsMap.set(serverName, {
1130
+ for (const [serverId, tools] of serverTools) {
1131
+ this.groupsMap.set(serverId, {
1037
1132
  tools,
1038
- active: this.activeGroups.size === 0 || this.activeGroups.has(serverName)
1133
+ active: this.activeGroups.size === 0 || this.activeGroups.has(serverId)
1039
1134
  });
1040
1135
  }
1041
1136
  }