@mcp-ts/sdk 1.5.0 → 1.5.2
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.
- package/dist/adapters/agui-adapter.d.mts +1 -1
- package/dist/adapters/agui-adapter.d.ts +1 -1
- package/dist/adapters/agui-adapter.js +43 -9
- package/dist/adapters/agui-adapter.js.map +1 -1
- package/dist/adapters/agui-adapter.mjs +43 -9
- package/dist/adapters/agui-adapter.mjs.map +1 -1
- package/dist/adapters/agui-middleware.d.mts +1 -1
- package/dist/adapters/agui-middleware.d.ts +1 -1
- package/dist/adapters/agui-middleware.js.map +1 -1
- package/dist/adapters/agui-middleware.mjs.map +1 -1
- package/dist/adapters/ai-adapter.d.mts +1 -1
- package/dist/adapters/ai-adapter.d.ts +1 -1
- package/dist/adapters/ai-adapter.js +42 -8
- package/dist/adapters/ai-adapter.js.map +1 -1
- package/dist/adapters/ai-adapter.mjs +42 -8
- package/dist/adapters/ai-adapter.mjs.map +1 -1
- package/dist/adapters/langchain-adapter.d.mts +1 -1
- package/dist/adapters/langchain-adapter.d.ts +1 -1
- package/dist/adapters/langchain-adapter.js +42 -8
- package/dist/adapters/langchain-adapter.js.map +1 -1
- package/dist/adapters/langchain-adapter.mjs +42 -8
- package/dist/adapters/langchain-adapter.mjs.map +1 -1
- package/dist/client/react.d.mts +91 -2
- package/dist/client/react.d.ts +91 -2
- package/dist/client/react.js +339 -3
- package/dist/client/react.js.map +1 -1
- package/dist/client/react.mjs +335 -4
- package/dist/client/react.mjs.map +1 -1
- package/dist/client/vue.d.mts +10 -0
- package/dist/client/vue.d.ts +10 -0
- package/dist/client/vue.js +28 -2
- package/dist/client/vue.js.map +1 -1
- package/dist/client/vue.mjs +28 -2
- package/dist/client/vue.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +170 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +170 -37
- package/dist/index.mjs.map +1 -1
- package/dist/server/index.js +55 -11
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +55 -11
- package/dist/server/index.mjs.map +1 -1
- package/dist/shared/index.d.mts +2 -2
- package/dist/shared/index.d.ts +2 -2
- package/dist/shared/index.js +115 -26
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +115 -26
- package/dist/shared/index.mjs.map +1 -1
- package/dist/{tool-router-XnWVxPzv.d.mts → tool-router-DK0RJblO.d.mts} +3 -0
- package/dist/{tool-router-Bo8qZbsD.d.ts → tool-router-DsKhRmJm.d.ts} +3 -0
- package/package.json +1 -1
- package/src/adapters/agui-adapter.ts +7 -7
- package/src/adapters/ai-adapter.ts +5 -5
- package/src/adapters/langchain-adapter.ts +5 -5
- package/src/client/react/index.ts +14 -0
- package/src/client/react/oauth-popup.tsx +446 -0
- package/src/client/react/use-mcp.ts +84 -3
- package/src/client/vue/use-mcp.ts +80 -3
- package/src/server/handlers/sse-handler.ts +39 -0
- package/src/server/mcp/oauth-client.ts +32 -14
- package/src/shared/meta-tools.ts +62 -13
- package/src/shared/tool-index.ts +85 -12
- package/src/shared/tool-router.ts +8 -7
- package/supabase/migrations/20260421010000_add_session_cleanup_cron.sql +32 -0
package/dist/index.mjs
CHANGED
|
@@ -1716,13 +1716,8 @@ var MCPClient = class _MCPClient {
|
|
|
1716
1716
|
this.transportType = transportType;
|
|
1717
1717
|
this.emitStateChange("CONNECTED");
|
|
1718
1718
|
this.emitProgress("Connected successfully");
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
const needsTtlPromotion = !existingSession || existingSession.active !== true;
|
|
1722
|
-
if (needsTransportUpdate || needsTtlPromotion) {
|
|
1723
|
-
console.log(`[MCPClient] Saving session ${this.sessionId} with 12hr TTL (connect success)`);
|
|
1724
|
-
await this.saveSession(SESSION_TTL_SECONDS, true);
|
|
1725
|
-
}
|
|
1719
|
+
console.log(`[MCPClient] Saving session ${this.sessionId} with 12hr TTL (connect success)`);
|
|
1720
|
+
await this.saveSession(SESSION_TTL_SECONDS, true);
|
|
1726
1721
|
} catch (error) {
|
|
1727
1722
|
if (error instanceof UnauthorizedError$1 || error instanceof Error && error.message.toLowerCase().includes("unauthorized")) {
|
|
1728
1723
|
let authUrl = "";
|
|
@@ -1760,6 +1755,13 @@ var MCPClient = class _MCPClient {
|
|
|
1760
1755
|
const errorMessage = error instanceof Error ? error.message : "Connection failed";
|
|
1761
1756
|
this.emitError(errorMessage, "connection");
|
|
1762
1757
|
this.emitStateChange("FAILED");
|
|
1758
|
+
try {
|
|
1759
|
+
const existingSession = await storage.getSession(this.identity, this.sessionId);
|
|
1760
|
+
if (!existingSession || existingSession.active !== true) {
|
|
1761
|
+
await storage.removeSession(this.identity, this.sessionId);
|
|
1762
|
+
}
|
|
1763
|
+
} catch {
|
|
1764
|
+
}
|
|
1763
1765
|
throw error;
|
|
1764
1766
|
}
|
|
1765
1767
|
}
|
|
@@ -1783,6 +1785,7 @@ var MCPClient = class _MCPClient {
|
|
|
1783
1785
|
const transportsToTry = this.transportType ? [this.transportType] : ["streamable_http", "sse"];
|
|
1784
1786
|
let lastError;
|
|
1785
1787
|
let tokensExchanged = false;
|
|
1788
|
+
let authenticatedStateEmitted = false;
|
|
1786
1789
|
for (const currentType of transportsToTry) {
|
|
1787
1790
|
const isLastAttempt = currentType === transportsToTry[transportsToTry.length - 1];
|
|
1788
1791
|
try {
|
|
@@ -1794,8 +1797,10 @@ var MCPClient = class _MCPClient {
|
|
|
1794
1797
|
} else {
|
|
1795
1798
|
this.emitProgress(`Tokens already exchanged, skipping auth step for ${currentType}...`);
|
|
1796
1799
|
}
|
|
1797
|
-
|
|
1798
|
-
|
|
1800
|
+
if (!authenticatedStateEmitted) {
|
|
1801
|
+
this.emitStateChange("AUTHENTICATED");
|
|
1802
|
+
authenticatedStateEmitted = true;
|
|
1803
|
+
}
|
|
1799
1804
|
this.emitProgress("Creating authenticated client...");
|
|
1800
1805
|
this.client = new Client(
|
|
1801
1806
|
{
|
|
@@ -1814,6 +1819,7 @@ var MCPClient = class _MCPClient {
|
|
|
1814
1819
|
);
|
|
1815
1820
|
this.emitStateChange("CONNECTING");
|
|
1816
1821
|
await this.client.connect(this.transport);
|
|
1822
|
+
this.transportType = currentType;
|
|
1817
1823
|
this.emitStateChange("CONNECTED");
|
|
1818
1824
|
console.log(`[MCPClient] Updating session ${this.sessionId} to 12hr TTL (OAuth complete)`);
|
|
1819
1825
|
await this.saveSession(SESSION_TTL_SECONDS, true);
|
|
@@ -2680,9 +2686,23 @@ var SSEConnectionManager = class {
|
|
|
2680
2686
|
if (existing) {
|
|
2681
2687
|
return existing;
|
|
2682
2688
|
}
|
|
2689
|
+
const session = await storage.getSession(this.identity, sessionId);
|
|
2690
|
+
if (!session) {
|
|
2691
|
+
throw new Error("Session not found");
|
|
2692
|
+
}
|
|
2683
2693
|
const client = new MCPClient({
|
|
2684
2694
|
identity: this.identity,
|
|
2685
|
-
sessionId
|
|
2695
|
+
sessionId,
|
|
2696
|
+
// These fields are optional in MCPClient, but when rehydrating a known
|
|
2697
|
+
// stored session on the server we pass them explicitly to preserve the
|
|
2698
|
+
// original transport/connection metadata instead of relying on lazy
|
|
2699
|
+
// reloading during initialize().
|
|
2700
|
+
serverId: session.serverId,
|
|
2701
|
+
serverName: session.serverName,
|
|
2702
|
+
serverUrl: session.serverUrl,
|
|
2703
|
+
callbackUrl: session.callbackUrl,
|
|
2704
|
+
transportType: session.transportType,
|
|
2705
|
+
headers: session.headers
|
|
2686
2706
|
});
|
|
2687
2707
|
client.onConnectionEvent((event) => this.emitConnectionEvent(event));
|
|
2688
2708
|
client.onObservabilityEvent((event) => this.sendEvent(event));
|
|
@@ -2739,6 +2759,16 @@ var SSEConnectionManager = class {
|
|
|
2739
2759
|
const client = new MCPClient({
|
|
2740
2760
|
identity: this.identity,
|
|
2741
2761
|
sessionId,
|
|
2762
|
+
// These fields are optional in MCPClient, but when rehydrating a known
|
|
2763
|
+
// stored session on the server we pass them explicitly to preserve the
|
|
2764
|
+
// original transport/connection metadata instead of relying on lazy
|
|
2765
|
+
// reloading during initialize().
|
|
2766
|
+
serverId: session.serverId,
|
|
2767
|
+
serverName: session.serverName,
|
|
2768
|
+
serverUrl: session.serverUrl,
|
|
2769
|
+
callbackUrl: session.callbackUrl,
|
|
2770
|
+
transportType: session.transportType,
|
|
2771
|
+
headers: session.headers,
|
|
2742
2772
|
...clientMetadata
|
|
2743
2773
|
});
|
|
2744
2774
|
client.onConnectionEvent((event) => this.emitConnectionEvent(event));
|
|
@@ -2771,7 +2801,21 @@ var SSEConnectionManager = class {
|
|
|
2771
2801
|
try {
|
|
2772
2802
|
const client = new MCPClient({
|
|
2773
2803
|
identity: this.identity,
|
|
2774
|
-
sessionId
|
|
2804
|
+
sessionId,
|
|
2805
|
+
// These fields are optional in MCPClient, but when rehydrating a known
|
|
2806
|
+
// stored session on the server we pass them explicitly to preserve the
|
|
2807
|
+
// original connection metadata instead of relying on lazy
|
|
2808
|
+
// reloading during initialize().
|
|
2809
|
+
serverId: session.serverId,
|
|
2810
|
+
serverName: session.serverName,
|
|
2811
|
+
serverUrl: session.serverUrl,
|
|
2812
|
+
callbackUrl: session.callbackUrl,
|
|
2813
|
+
// NOTE: transportType is intentionally omitted here.
|
|
2814
|
+
// The session's stored transportType is a placeholder ('streamable_http')
|
|
2815
|
+
// set before transport negotiation. Omitting it lets MCPClient auto-negotiate
|
|
2816
|
+
// (try streamable_http → SSE fallback), which is critical for servers like
|
|
2817
|
+
// Neon that only support SSE transport.
|
|
2818
|
+
headers: session.headers
|
|
2775
2819
|
});
|
|
2776
2820
|
client.onConnectionEvent((event) => this.emitConnectionEvent(event));
|
|
2777
2821
|
await client.finishAuth(code);
|
|
@@ -3840,6 +3884,7 @@ var ToolIndex = class _ToolIndex {
|
|
|
3840
3884
|
name: tool.name,
|
|
3841
3885
|
description: tool.description ?? "",
|
|
3842
3886
|
serverName: tool.serverName,
|
|
3887
|
+
serverId: tool.serverId,
|
|
3843
3888
|
sessionId: tool.sessionId,
|
|
3844
3889
|
estimatedTokens
|
|
3845
3890
|
});
|
|
@@ -3902,12 +3947,50 @@ var ToolIndex = class _ToolIndex {
|
|
|
3902
3947
|
*/
|
|
3903
3948
|
async search(query, topK = 5) {
|
|
3904
3949
|
if (this.tools.size === 0) return [];
|
|
3905
|
-
const queryLower = query.toLowerCase();
|
|
3906
|
-
const
|
|
3950
|
+
const queryLower = query.toLowerCase().trim();
|
|
3951
|
+
const exactMatches = [...this.toolSummaries.values()].filter(
|
|
3952
|
+
(summary) => summary.name.toLowerCase() === queryLower
|
|
3953
|
+
);
|
|
3954
|
+
if (exactMatches.length > 0) {
|
|
3955
|
+
return exactMatches.slice(0, topK);
|
|
3956
|
+
}
|
|
3957
|
+
if (queryLower.startsWith("mcp__") && queryLower.length > 5) {
|
|
3958
|
+
const prefixMatches = [...this.toolSummaries.values()].filter((t) => t.name.toLowerCase().startsWith(queryLower)).slice(0, topK);
|
|
3959
|
+
if (prefixMatches.length > 0) return prefixMatches;
|
|
3960
|
+
}
|
|
3961
|
+
const queryTermsRaw = queryLower.split(/\s+/).filter((t) => t.length > 0);
|
|
3962
|
+
const requiredTerms = [];
|
|
3963
|
+
const optionalTerms = [];
|
|
3964
|
+
for (const term of queryTermsRaw) {
|
|
3965
|
+
if (term.startsWith("+") && term.length > 1) {
|
|
3966
|
+
requiredTerms.push(term.slice(1));
|
|
3967
|
+
} else {
|
|
3968
|
+
optionalTerms.push(term);
|
|
3969
|
+
}
|
|
3970
|
+
}
|
|
3971
|
+
const allScoringTerms = requiredTerms.length > 0 ? [...requiredTerms, ...optionalTerms] : queryTermsRaw;
|
|
3972
|
+
const normalizedQueryText = allScoringTerms.join(" ").trim();
|
|
3973
|
+
const queryTokens = this.tokenize(allScoringTerms.join(" "));
|
|
3974
|
+
const candidateKeys = /* @__PURE__ */ new Set();
|
|
3975
|
+
for (const docKey of this.toolSummaries.keys()) {
|
|
3976
|
+
if (requiredTerms.length > 0) {
|
|
3977
|
+
const text = this.searchTexts.get(docKey) || "";
|
|
3978
|
+
const summary = this.toolSummaries.get(docKey);
|
|
3979
|
+
const nameLower = summary.name.toLowerCase();
|
|
3980
|
+
const matchesAll = requiredTerms.every(
|
|
3981
|
+
(term) => text.includes(term) || nameLower.includes(term)
|
|
3982
|
+
);
|
|
3983
|
+
if (!matchesAll) continue;
|
|
3984
|
+
}
|
|
3985
|
+
candidateKeys.add(docKey);
|
|
3986
|
+
}
|
|
3907
3987
|
const keywordScores = /* @__PURE__ */ new Map();
|
|
3908
3988
|
const k1 = 1.2;
|
|
3909
3989
|
const b = 0.75;
|
|
3910
|
-
for (const
|
|
3990
|
+
for (const docKey of candidateKeys) {
|
|
3991
|
+
const docTf = this.tfVectors.get(docKey);
|
|
3992
|
+
if (!docTf) continue;
|
|
3993
|
+
const summary = this.toolSummaries.get(docKey);
|
|
3911
3994
|
let score = 0;
|
|
3912
3995
|
const docLen = this.docLengths.get(docKey) ?? 0;
|
|
3913
3996
|
for (const tok of queryTokens) {
|
|
@@ -3918,16 +4001,31 @@ var ToolIndex = class _ToolIndex {
|
|
|
3918
4001
|
const denominator = tfVal + k1 * (1 - b + b * (docLen / this.avgDocLength));
|
|
3919
4002
|
score += idf * (numerator / denominator);
|
|
3920
4003
|
}
|
|
3921
|
-
|
|
4004
|
+
const serverLower = (summary.serverName || summary.serverId || "").toLowerCase();
|
|
4005
|
+
const toolLower = summary.name.toLowerCase();
|
|
4006
|
+
for (const term of allScoringTerms) {
|
|
4007
|
+
if (serverLower.includes(term)) {
|
|
4008
|
+
score += 10;
|
|
4009
|
+
}
|
|
4010
|
+
if (toolLower.includes(term)) {
|
|
4011
|
+
score += 5;
|
|
4012
|
+
}
|
|
4013
|
+
}
|
|
4014
|
+
if (score > 0) {
|
|
4015
|
+
keywordScores.set(docKey, score);
|
|
4016
|
+
}
|
|
3922
4017
|
}
|
|
3923
4018
|
let embeddingScores = null;
|
|
3924
4019
|
if (this.options.embedFn && this.embeddings.size > 0) {
|
|
3925
4020
|
try {
|
|
3926
|
-
const [queryEmbedding] = await this.options.embedFn([
|
|
4021
|
+
const [queryEmbedding] = await this.options.embedFn([normalizedQueryText]);
|
|
3927
4022
|
if (queryEmbedding) {
|
|
3928
4023
|
embeddingScores = /* @__PURE__ */ new Map();
|
|
3929
|
-
for (const
|
|
3930
|
-
|
|
4024
|
+
for (const docKey of candidateKeys) {
|
|
4025
|
+
const vec = this.embeddings.get(docKey);
|
|
4026
|
+
if (vec) {
|
|
4027
|
+
embeddingScores.set(docKey, this.cosineSimilarity(queryEmbedding, vec));
|
|
4028
|
+
}
|
|
3931
4029
|
}
|
|
3932
4030
|
}
|
|
3933
4031
|
} catch {
|
|
@@ -3935,7 +4033,7 @@ var ToolIndex = class _ToolIndex {
|
|
|
3935
4033
|
}
|
|
3936
4034
|
const kw = this.options.keywordWeight;
|
|
3937
4035
|
const finalScores = [];
|
|
3938
|
-
for (const docKey of
|
|
4036
|
+
for (const docKey of candidateKeys) {
|
|
3939
4037
|
const kwScore = keywordScores.get(docKey) ?? 0;
|
|
3940
4038
|
const embScore = embeddingScores?.get(docKey) ?? 0;
|
|
3941
4039
|
const score = embeddingScores ? kw * kwScore + (1 - kw) * embScore : kwScore;
|
|
@@ -3993,7 +4091,7 @@ var ToolIndex = class _ToolIndex {
|
|
|
3993
4091
|
getTool(name, namespace) {
|
|
3994
4092
|
const list = this.tools.get(name) ?? [];
|
|
3995
4093
|
if (!namespace) return list;
|
|
3996
|
-
return list.filter((t) => t.sessionId === namespace || t.
|
|
4094
|
+
return list.filter((t) => t.sessionId === namespace || t.serverId === namespace);
|
|
3997
4095
|
}
|
|
3998
4096
|
/** All indexed tool names. */
|
|
3999
4097
|
getToolNames() {
|
|
@@ -4053,7 +4151,7 @@ var ToolIndex = class _ToolIndex {
|
|
|
4053
4151
|
return parts.join(" ");
|
|
4054
4152
|
}
|
|
4055
4153
|
getDocumentKey(tool) {
|
|
4056
|
-
return `${tool.sessionId}::${tool.
|
|
4154
|
+
return `${tool.sessionId}::${tool.serverId}::${tool.name}`;
|
|
4057
4155
|
}
|
|
4058
4156
|
/** Simple whitespace + camelCase + snake_case tokenizer. */
|
|
4059
4157
|
tokenize(text) {
|
|
@@ -4139,13 +4237,13 @@ var SchemaCompressor = class _SchemaCompressor {
|
|
|
4139
4237
|
function createSearchToolDefinition() {
|
|
4140
4238
|
return {
|
|
4141
4239
|
name: "mcp_search_tool_bm25",
|
|
4142
|
-
description: 'Search the catalog of available tools
|
|
4240
|
+
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',
|
|
4143
4241
|
inputSchema: {
|
|
4144
4242
|
type: "object",
|
|
4145
4243
|
properties: {
|
|
4146
4244
|
query: {
|
|
4147
4245
|
type: "string",
|
|
4148
|
-
description: "
|
|
4246
|
+
description: 'Query to find tools. Use "select:<tool_name>" for direct selection, or keywords to search. Prefix keywords with + to require them.'
|
|
4149
4247
|
},
|
|
4150
4248
|
limit: {
|
|
4151
4249
|
type: "number",
|
|
@@ -4187,9 +4285,9 @@ function createGetSchemaToolDefinition() {
|
|
|
4187
4285
|
type: "string",
|
|
4188
4286
|
description: "The exact tool name returned by mcp_search_tool_bm25."
|
|
4189
4287
|
},
|
|
4190
|
-
|
|
4288
|
+
serverId: {
|
|
4191
4289
|
type: "string",
|
|
4192
|
-
description: "Optional: The server
|
|
4290
|
+
description: "Optional: The server ID provided in mcp_search_tool_bm25. Required if multiple tools have the same name."
|
|
4193
4291
|
}
|
|
4194
4292
|
},
|
|
4195
4293
|
required: ["toolName"]
|
|
@@ -4207,9 +4305,9 @@ function createExecuteToolDefinition() {
|
|
|
4207
4305
|
type: "string",
|
|
4208
4306
|
description: "The exact tool name from mcp_search_tool_bm25 results."
|
|
4209
4307
|
},
|
|
4210
|
-
|
|
4308
|
+
serverId: {
|
|
4211
4309
|
type: "string",
|
|
4212
|
-
description: "Optional: The server
|
|
4310
|
+
description: "Optional: The server ID provided in mcp_search_tool_bm25. Required if multiple tools have the same name."
|
|
4213
4311
|
},
|
|
4214
4312
|
args: {
|
|
4215
4313
|
type: "object",
|
|
@@ -4239,9 +4337,43 @@ async function executeMetaTool(toolName, args, router, callToolFn) {
|
|
|
4239
4337
|
case "mcp_search_tool_bm25": {
|
|
4240
4338
|
const query = String(args.query ?? "");
|
|
4241
4339
|
const limit = Math.min(Number(args.limit) || 5, 20);
|
|
4340
|
+
const selectMatch = query.match(/^select:(.+)$/i);
|
|
4341
|
+
if (selectMatch) {
|
|
4342
|
+
const requested = selectMatch[1].split(",").map((s) => s.trim()).filter(Boolean);
|
|
4343
|
+
const found = [];
|
|
4344
|
+
const errors = [];
|
|
4345
|
+
for (const requestedToolName of requested) {
|
|
4346
|
+
const { tool, error } = resolveToolSchema(requestedToolName);
|
|
4347
|
+
if (error) {
|
|
4348
|
+
const errorMsg = error.content[0]?.type === "text" ? error.content[0].text : "Unknown error";
|
|
4349
|
+
errors.push(`- **${requestedToolName}**: ${errorMsg}`);
|
|
4350
|
+
} else if (tool) {
|
|
4351
|
+
found.push(tool);
|
|
4352
|
+
} else {
|
|
4353
|
+
errors.push(`- **${requestedToolName}**: Tool not found. Try searching with mcp_search_tool_bm25.`);
|
|
4354
|
+
}
|
|
4355
|
+
}
|
|
4356
|
+
const lines = [];
|
|
4357
|
+
if (found.length > 0) {
|
|
4358
|
+
lines.push(...found.map(
|
|
4359
|
+
(t, i) => `${i + 1}. **${t.name}** (server: ${t.serverName}, serverId: ${t.serverId})
|
|
4360
|
+
${t.description}`
|
|
4361
|
+
));
|
|
4362
|
+
}
|
|
4363
|
+
if (errors.length > 0) {
|
|
4364
|
+
if (lines.length > 0) lines.push("");
|
|
4365
|
+
lines.push("Errors resolving some tools:");
|
|
4366
|
+
lines.push(...errors);
|
|
4367
|
+
}
|
|
4368
|
+
const text2 = lines.length > 0 ? lines.join("\n") : `No tools found matching select query: ${requested.join(", ")}`;
|
|
4369
|
+
return {
|
|
4370
|
+
content: [{ type: "text", text: text2 }],
|
|
4371
|
+
isError: found.length === 0
|
|
4372
|
+
};
|
|
4373
|
+
}
|
|
4242
4374
|
const results = await router.searchTools(query, limit);
|
|
4243
4375
|
const text = results.length === 0 ? "No tools found matching your query. Try different keywords." : results.map(
|
|
4244
|
-
(t, i) => `${i + 1}. **${t.name}** (server: ${t.serverName})
|
|
4376
|
+
(t, i) => `${i + 1}. **${t.name}** (server: ${t.serverName}, serverId: ${t.serverId})
|
|
4245
4377
|
${t.description}
|
|
4246
4378
|
Estimated tokens: ${t.estimatedTokens}`
|
|
4247
4379
|
).join("\n");
|
|
@@ -4255,7 +4387,7 @@ async function executeMetaTool(toolName, args, router, callToolFn) {
|
|
|
4255
4387
|
const limit = Math.min(Number(args.limit) || 5, 20);
|
|
4256
4388
|
const results = await router.searchToolsRegex(pattern, limit);
|
|
4257
4389
|
const text = results.length === 0 ? "No tools matched your regex pattern. Try a broader pattern." : results.map(
|
|
4258
|
-
(t, i) => `${i + 1}. **${t.name}** (server: ${t.serverName})
|
|
4390
|
+
(t, i) => `${i + 1}. **${t.name}** (server: ${t.serverName}, serverId: ${t.serverId})
|
|
4259
4391
|
${t.description}
|
|
4260
4392
|
Estimated tokens: ${t.estimatedTokens}`
|
|
4261
4393
|
).join("\n");
|
|
@@ -4266,7 +4398,7 @@ async function executeMetaTool(toolName, args, router, callToolFn) {
|
|
|
4266
4398
|
}
|
|
4267
4399
|
case "mcp_get_tool_schema": {
|
|
4268
4400
|
const name = String(args.toolName ?? "");
|
|
4269
|
-
const namespace = String(args.
|
|
4401
|
+
const namespace = String(args.serverId ?? "") || void 0;
|
|
4270
4402
|
const { tool, error } = resolveToolSchema(name, namespace);
|
|
4271
4403
|
if (error) {
|
|
4272
4404
|
return error;
|
|
@@ -4294,7 +4426,7 @@ async function executeMetaTool(toolName, args, router, callToolFn) {
|
|
|
4294
4426
|
}
|
|
4295
4427
|
case "mcp_execute_tool": {
|
|
4296
4428
|
const targetToolName = String(args.toolName ?? "");
|
|
4297
|
-
const namespace = String(args.
|
|
4429
|
+
const namespace = String(args.serverId ?? "") || void 0;
|
|
4298
4430
|
const toolArgs = args.args ?? {};
|
|
4299
4431
|
if (!targetToolName) {
|
|
4300
4432
|
return {
|
|
@@ -4443,9 +4575,9 @@ var ToolRouter = class {
|
|
|
4443
4575
|
const matches = this.index.getTool(toolName, namespace);
|
|
4444
4576
|
if (matches.length === 0) return void 0;
|
|
4445
4577
|
if (matches.length > 1) {
|
|
4446
|
-
const servers = matches.map((m) => m.
|
|
4578
|
+
const servers = matches.map((m) => m.serverId).join(", ");
|
|
4447
4579
|
throw new Error(
|
|
4448
|
-
`Tool "${toolName}" is provided by multiple servers: [${servers}]. Please specify the desired "
|
|
4580
|
+
`Tool "${toolName}" is provided by multiple servers: [${servers}]. Please specify the desired "serverId" as a namespace.`
|
|
4449
4581
|
);
|
|
4450
4582
|
}
|
|
4451
4583
|
return matches[0];
|
|
@@ -4556,6 +4688,7 @@ var ToolRouter = class {
|
|
|
4556
4688
|
for (const tool of tools) {
|
|
4557
4689
|
result.push({
|
|
4558
4690
|
...tool,
|
|
4691
|
+
serverId,
|
|
4559
4692
|
serverName,
|
|
4560
4693
|
sessionId
|
|
4561
4694
|
});
|
|
@@ -4589,16 +4722,16 @@ var ToolRouter = class {
|
|
|
4589
4722
|
} else {
|
|
4590
4723
|
const serverTools = /* @__PURE__ */ new Map();
|
|
4591
4724
|
for (const tool of this.allTools) {
|
|
4592
|
-
const group = tool.
|
|
4725
|
+
const group = tool.serverId;
|
|
4593
4726
|
if (!serverTools.has(group)) {
|
|
4594
4727
|
serverTools.set(group, []);
|
|
4595
4728
|
}
|
|
4596
4729
|
serverTools.get(group).push(tool.name);
|
|
4597
4730
|
}
|
|
4598
|
-
for (const [
|
|
4599
|
-
this.groupsMap.set(
|
|
4731
|
+
for (const [serverId, tools] of serverTools) {
|
|
4732
|
+
this.groupsMap.set(serverId, {
|
|
4600
4733
|
tools,
|
|
4601
|
-
active: this.activeGroups.size === 0 || this.activeGroups.has(
|
|
4734
|
+
active: this.activeGroups.size === 0 || this.activeGroups.has(serverId)
|
|
4602
4735
|
});
|
|
4603
4736
|
}
|
|
4604
4737
|
}
|