mcp-use 1.3.4-canary.1 → 1.4.0-canary.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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/{chunk-6EHM3S3M.js → chunk-35A6O3YH.js} +52 -10
- package/dist/chunk-DSBKVAWD.js +263 -0
- package/dist/{chunk-TIUSJAAE.js → chunk-GRLCLVAK.js} +3 -254
- package/dist/{chunk-QKPVHYJU.js → chunk-RE7EYFDV.js} +1 -1
- package/dist/chunk-WERYJ6PF.js +209 -0
- package/dist/chunk-ZFZPZ4GE.js +21 -0
- package/dist/display-LIYVTGEU.js +350 -0
- package/dist/index.cjs +1539 -284
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +673 -9
- package/dist/src/agents/display.d.ts +54 -0
- package/dist/src/agents/display.d.ts.map +1 -0
- package/dist/src/agents/index.cjs +504 -10
- package/dist/src/agents/index.d.ts +1 -0
- package/dist/src/agents/index.d.ts.map +1 -1
- package/dist/src/agents/index.js +10 -18
- package/dist/src/agents/mcp_agent.d.ts +5 -0
- package/dist/src/agents/mcp_agent.d.ts.map +1 -1
- package/dist/src/browser.cjs +406 -10
- package/dist/src/browser.js +5 -3
- package/dist/src/client/codeExecutor.d.ts +6 -0
- package/dist/src/client/codeExecutor.d.ts.map +1 -0
- package/dist/src/client/connectors/codeMode.d.ts +27 -0
- package/dist/src/client/connectors/codeMode.d.ts.map +1 -0
- package/dist/src/client/executors/base.d.ts +56 -0
- package/dist/src/client/executors/base.d.ts.map +1 -0
- package/dist/src/client/executors/e2b.d.ts +46 -0
- package/dist/src/client/executors/e2b.d.ts.map +1 -0
- package/dist/src/client/executors/vm.d.ts +30 -0
- package/dist/src/client/executors/vm.d.ts.map +1 -0
- package/dist/src/client/prompts.cjs +401 -0
- package/dist/src/client/prompts.d.ts +13 -0
- package/dist/src/client/prompts.d.ts.map +1 -0
- package/dist/src/client/prompts.js +9 -0
- package/dist/src/client.d.ts +51 -4
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/react/index.js +3 -2
- package/dist/tsup.config.d.ts.map +1 -1
- package/package.json +14 -4
|
@@ -1578,18 +1578,35 @@ var MCPAgent = class {
|
|
|
1578
1578
|
logger.info(
|
|
1579
1579
|
`\u{1F50C} Found ${Object.keys(this.sessions).length} existing sessions`
|
|
1580
1580
|
);
|
|
1581
|
-
|
|
1581
|
+
const nonCodeModeSessions = Object.keys(this.sessions).filter(
|
|
1582
|
+
(name) => name !== "code_mode"
|
|
1583
|
+
);
|
|
1584
|
+
if (nonCodeModeSessions.length === 0) {
|
|
1582
1585
|
logger.info("\u{1F504} No active sessions found, creating new ones...");
|
|
1583
1586
|
this.sessions = await this.client.createAllSessions();
|
|
1584
1587
|
logger.info(
|
|
1585
1588
|
`\u2705 Created ${Object.keys(this.sessions).length} new sessions`
|
|
1586
1589
|
);
|
|
1587
1590
|
}
|
|
1588
|
-
|
|
1591
|
+
if (this.client.codeMode) {
|
|
1592
|
+
const codeModeSession = this.sessions["code_mode"];
|
|
1593
|
+
if (codeModeSession) {
|
|
1594
|
+
this._tools = await this.adapter.createToolsFromConnectors([
|
|
1595
|
+
codeModeSession.connector
|
|
1596
|
+
]);
|
|
1597
|
+
logger.info(`\u{1F6E0}\uFE0F Created ${this._tools.length} code mode tools`);
|
|
1598
|
+
} else {
|
|
1599
|
+
throw new Error(
|
|
1600
|
+
"Code mode enabled but code_mode session not found"
|
|
1601
|
+
);
|
|
1602
|
+
}
|
|
1603
|
+
} else {
|
|
1604
|
+
this._tools = await LangChainAdapter.createTools(this.client);
|
|
1605
|
+
logger.info(
|
|
1606
|
+
`\u{1F6E0}\uFE0F Created ${this._tools.length} LangChain tools from client`
|
|
1607
|
+
);
|
|
1608
|
+
}
|
|
1589
1609
|
this._tools.push(...this.additionalTools);
|
|
1590
|
-
logger.info(
|
|
1591
|
-
`\u{1F6E0}\uFE0F Created ${this._tools.length} LangChain tools from client`
|
|
1592
|
-
);
|
|
1593
1610
|
} else {
|
|
1594
1611
|
logger.info(
|
|
1595
1612
|
`\u{1F517} Connecting to ${this.connectors.length} direct connectors...`
|
|
@@ -2154,6 +2171,8 @@ var MCPAgent = class {
|
|
|
2154
2171
|
tags: this.getTags(),
|
|
2155
2172
|
// Set trace name for LangChain/Langfuse
|
|
2156
2173
|
runName: this.metadata.trace_name || "mcp-use-agent",
|
|
2174
|
+
// Set recursion limit to 3x maxSteps to account for model calls + tool executions
|
|
2175
|
+
recursionLimit: this.maxSteps * 3,
|
|
2157
2176
|
// Pass sessionId for Langfuse if present in metadata
|
|
2158
2177
|
...this.metadata.session_id && {
|
|
2159
2178
|
sessionId: this.metadata.session_id
|
|
@@ -2367,8 +2386,8 @@ var MCPAgent = class {
|
|
|
2367
2386
|
this._agentExecutor = null;
|
|
2368
2387
|
this._tools = [];
|
|
2369
2388
|
if (this.client) {
|
|
2370
|
-
logger.info("\u{1F504} Closing
|
|
2371
|
-
await this.client.
|
|
2389
|
+
logger.info("\u{1F504} Closing client and cleaning up resources");
|
|
2390
|
+
await this.client.close();
|
|
2372
2391
|
this.sessions = {};
|
|
2373
2392
|
} else {
|
|
2374
2393
|
for (const connector of this.connectors) {
|
|
@@ -2384,6 +2403,26 @@ var MCPAgent = class {
|
|
|
2384
2403
|
logger.info("\u{1F44B} Agent closed successfully");
|
|
2385
2404
|
}
|
|
2386
2405
|
}
|
|
2406
|
+
/**
|
|
2407
|
+
* Yields with pretty-printed output for code mode.
|
|
2408
|
+
* This method formats and displays tool executions in a user-friendly way with syntax highlighting.
|
|
2409
|
+
*/
|
|
2410
|
+
async *prettyStreamEvents(query, maxSteps, manageConnector = true, externalHistory, outputSchema) {
|
|
2411
|
+
const { prettyStreamEvents: prettyStream } = await import("./display-LIYVTGEU.js");
|
|
2412
|
+
const finalResponse = "";
|
|
2413
|
+
for await (const _ of prettyStream(
|
|
2414
|
+
this.streamEvents(
|
|
2415
|
+
query,
|
|
2416
|
+
maxSteps,
|
|
2417
|
+
manageConnector,
|
|
2418
|
+
externalHistory,
|
|
2419
|
+
outputSchema
|
|
2420
|
+
)
|
|
2421
|
+
)) {
|
|
2422
|
+
yield;
|
|
2423
|
+
}
|
|
2424
|
+
return finalResponse;
|
|
2425
|
+
}
|
|
2387
2426
|
/**
|
|
2388
2427
|
* Yields LangChain StreamEvent objects from the underlying streamEvents() method.
|
|
2389
2428
|
* This provides token-level streaming and fine-grained event updates.
|
|
@@ -2411,11 +2450,11 @@ var MCPAgent = class {
|
|
|
2411
2450
|
throw new Error("MCP agent failed to initialize");
|
|
2412
2451
|
}
|
|
2413
2452
|
this.maxSteps = maxSteps ?? this.maxSteps;
|
|
2414
|
-
const display_query = query.length > 50 ? `${query.slice(0, 50).replace(/\n/g, " ")}...` : query.replace(/\n/g, " ");
|
|
2453
|
+
const display_query = typeof query === "string" && query.length > 50 ? `${query.slice(0, 50).replace(/\n/g, " ")}...` : typeof query === "string" ? query.replace(/\n/g, " ") : String(query);
|
|
2415
2454
|
logger.info(`\u{1F4AC} Received query for streamEvents: '${display_query}'`);
|
|
2416
2455
|
if (this.memoryEnabled) {
|
|
2417
|
-
logger.info(`\u{1F504} Adding user message to history: ${
|
|
2418
|
-
this.addToHistory(new HumanMessage(query));
|
|
2456
|
+
logger.info(`\u{1F504} Adding user message to history: ${display_query}`);
|
|
2457
|
+
this.addToHistory(new HumanMessage({ content: query }));
|
|
2419
2458
|
}
|
|
2420
2459
|
const historyToUse = externalHistory ?? this.conversationHistory;
|
|
2421
2460
|
const langchainHistory = [];
|
|
@@ -2443,6 +2482,8 @@ var MCPAgent = class {
|
|
|
2443
2482
|
tags: this.getTags(),
|
|
2444
2483
|
// Set trace name for LangChain/Langfuse
|
|
2445
2484
|
runName: this.metadata.trace_name || "mcp-use-agent",
|
|
2485
|
+
// Set recursion limit to 3x maxSteps to account for model calls + tool executions
|
|
2486
|
+
recursionLimit: this.maxSteps * 3,
|
|
2446
2487
|
// Pass sessionId for Langfuse if present in metadata
|
|
2447
2488
|
...this.metadata.session_id && {
|
|
2448
2489
|
sessionId: this.metadata.session_id
|
|
@@ -2542,6 +2583,7 @@ var MCPAgent = class {
|
|
|
2542
2583
|
} else if (this.memoryEnabled && finalResponse) {
|
|
2543
2584
|
this.addToHistory(new AIMessage(finalResponse));
|
|
2544
2585
|
}
|
|
2586
|
+
console.log("\n\n");
|
|
2545
2587
|
logger.info(`\u{1F389} StreamEvents complete - ${eventCount} events emitted`);
|
|
2546
2588
|
success = true;
|
|
2547
2589
|
} catch (e) {
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import {
|
|
2
|
+
logger
|
|
3
|
+
} from "./chunk-34R6SIER.js";
|
|
4
|
+
import {
|
|
5
|
+
__name
|
|
6
|
+
} from "./chunk-3GQAWCBQ.js";
|
|
7
|
+
|
|
8
|
+
// src/connectors/base.ts
|
|
9
|
+
var BaseConnector = class {
|
|
10
|
+
static {
|
|
11
|
+
__name(this, "BaseConnector");
|
|
12
|
+
}
|
|
13
|
+
client = null;
|
|
14
|
+
connectionManager = null;
|
|
15
|
+
toolsCache = null;
|
|
16
|
+
capabilitiesCache = null;
|
|
17
|
+
serverInfoCache = null;
|
|
18
|
+
connected = false;
|
|
19
|
+
opts;
|
|
20
|
+
constructor(opts = {}) {
|
|
21
|
+
this.opts = opts;
|
|
22
|
+
}
|
|
23
|
+
/** Disconnect and release resources. */
|
|
24
|
+
async disconnect() {
|
|
25
|
+
if (!this.connected) {
|
|
26
|
+
logger.debug("Not connected to MCP implementation");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
logger.debug("Disconnecting from MCP implementation");
|
|
30
|
+
await this.cleanupResources();
|
|
31
|
+
this.connected = false;
|
|
32
|
+
logger.debug("Disconnected from MCP implementation");
|
|
33
|
+
}
|
|
34
|
+
/** Check if the client is connected */
|
|
35
|
+
get isClientConnected() {
|
|
36
|
+
return this.client != null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Initialise the MCP session **after** `connect()` has succeeded.
|
|
40
|
+
*
|
|
41
|
+
* In the SDK, `Client.connect(transport)` automatically performs the
|
|
42
|
+
* protocol‑level `initialize` handshake, so we only need to cache the list of
|
|
43
|
+
* tools and expose some server info.
|
|
44
|
+
*/
|
|
45
|
+
async initialize(defaultRequestOptions = this.opts.defaultRequestOptions ?? {}) {
|
|
46
|
+
if (!this.client) {
|
|
47
|
+
throw new Error("MCP client is not connected");
|
|
48
|
+
}
|
|
49
|
+
logger.debug("Caching server capabilities & tools");
|
|
50
|
+
const capabilities = this.client.getServerCapabilities();
|
|
51
|
+
this.capabilitiesCache = capabilities;
|
|
52
|
+
const serverInfo = this.client.getServerVersion();
|
|
53
|
+
this.serverInfoCache = serverInfo || null;
|
|
54
|
+
const listToolsRes = await this.client.listTools(
|
|
55
|
+
void 0,
|
|
56
|
+
defaultRequestOptions
|
|
57
|
+
);
|
|
58
|
+
this.toolsCache = listToolsRes.tools ?? [];
|
|
59
|
+
logger.debug(`Fetched ${this.toolsCache.length} tools from server`);
|
|
60
|
+
logger.debug("Server capabilities:", capabilities);
|
|
61
|
+
logger.debug("Server info:", serverInfo);
|
|
62
|
+
return capabilities;
|
|
63
|
+
}
|
|
64
|
+
/** Lazily expose the cached tools list. */
|
|
65
|
+
get tools() {
|
|
66
|
+
if (!this.toolsCache) {
|
|
67
|
+
throw new Error("MCP client is not initialized; call initialize() first");
|
|
68
|
+
}
|
|
69
|
+
return this.toolsCache;
|
|
70
|
+
}
|
|
71
|
+
/** Expose cached server capabilities. */
|
|
72
|
+
get serverCapabilities() {
|
|
73
|
+
return this.capabilitiesCache;
|
|
74
|
+
}
|
|
75
|
+
/** Expose cached server info. */
|
|
76
|
+
get serverInfo() {
|
|
77
|
+
return this.serverInfoCache;
|
|
78
|
+
}
|
|
79
|
+
/** Call a tool on the server. */
|
|
80
|
+
async callTool(name, args, options) {
|
|
81
|
+
if (!this.client) {
|
|
82
|
+
throw new Error("MCP client is not connected");
|
|
83
|
+
}
|
|
84
|
+
logger.debug(`Calling tool '${name}' with args`, args);
|
|
85
|
+
const res = await this.client.callTool(
|
|
86
|
+
{ name, arguments: args },
|
|
87
|
+
void 0,
|
|
88
|
+
options
|
|
89
|
+
);
|
|
90
|
+
logger.debug(`Tool '${name}' returned`, res);
|
|
91
|
+
return res;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* List resources from the server with optional pagination
|
|
95
|
+
*
|
|
96
|
+
* @param cursor - Optional cursor for pagination
|
|
97
|
+
* @param options - Request options
|
|
98
|
+
* @returns Resource list with optional nextCursor for pagination
|
|
99
|
+
*/
|
|
100
|
+
async listResources(cursor, options) {
|
|
101
|
+
if (!this.client) {
|
|
102
|
+
throw new Error("MCP client is not connected");
|
|
103
|
+
}
|
|
104
|
+
logger.debug("Listing resources", cursor ? `with cursor: ${cursor}` : "");
|
|
105
|
+
return await this.client.listResources({ cursor }, options);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* List all resources from the server, automatically handling pagination
|
|
109
|
+
*
|
|
110
|
+
* @param options - Request options
|
|
111
|
+
* @returns Complete list of all resources
|
|
112
|
+
*/
|
|
113
|
+
async listAllResources(options) {
|
|
114
|
+
if (!this.client) {
|
|
115
|
+
throw new Error("MCP client is not connected");
|
|
116
|
+
}
|
|
117
|
+
if (!this.capabilitiesCache?.resources) {
|
|
118
|
+
logger.debug("Server does not advertise resources capability, skipping");
|
|
119
|
+
return { resources: [] };
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
logger.debug("Listing all resources (with auto-pagination)");
|
|
123
|
+
const allResources = [];
|
|
124
|
+
let cursor = void 0;
|
|
125
|
+
do {
|
|
126
|
+
const result = await this.client.listResources({ cursor }, options);
|
|
127
|
+
allResources.push(...result.resources || []);
|
|
128
|
+
cursor = result.nextCursor;
|
|
129
|
+
} while (cursor);
|
|
130
|
+
return { resources: allResources };
|
|
131
|
+
} catch (err) {
|
|
132
|
+
if (err.code === -32601) {
|
|
133
|
+
logger.debug("Server advertised resources but method not found");
|
|
134
|
+
return { resources: [] };
|
|
135
|
+
}
|
|
136
|
+
throw err;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* List resource templates from the server
|
|
141
|
+
*
|
|
142
|
+
* @param options - Request options
|
|
143
|
+
* @returns List of available resource templates
|
|
144
|
+
*/
|
|
145
|
+
async listResourceTemplates(options) {
|
|
146
|
+
if (!this.client) {
|
|
147
|
+
throw new Error("MCP client is not connected");
|
|
148
|
+
}
|
|
149
|
+
logger.debug("Listing resource templates");
|
|
150
|
+
return await this.client.listResourceTemplates(void 0, options);
|
|
151
|
+
}
|
|
152
|
+
/** Read a resource by URI. */
|
|
153
|
+
async readResource(uri, options) {
|
|
154
|
+
if (!this.client) {
|
|
155
|
+
throw new Error("MCP client is not connected");
|
|
156
|
+
}
|
|
157
|
+
logger.debug(`Reading resource ${uri}`);
|
|
158
|
+
const res = await this.client.readResource({ uri }, options);
|
|
159
|
+
return res;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Subscribe to resource updates
|
|
163
|
+
*
|
|
164
|
+
* @param uri - URI of the resource to subscribe to
|
|
165
|
+
* @param options - Request options
|
|
166
|
+
*/
|
|
167
|
+
async subscribeToResource(uri, options) {
|
|
168
|
+
if (!this.client) {
|
|
169
|
+
throw new Error("MCP client is not connected");
|
|
170
|
+
}
|
|
171
|
+
logger.debug(`Subscribing to resource: ${uri}`);
|
|
172
|
+
return await this.client.subscribeResource({ uri }, options);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Unsubscribe from resource updates
|
|
176
|
+
*
|
|
177
|
+
* @param uri - URI of the resource to unsubscribe from
|
|
178
|
+
* @param options - Request options
|
|
179
|
+
*/
|
|
180
|
+
async unsubscribeFromResource(uri, options) {
|
|
181
|
+
if (!this.client) {
|
|
182
|
+
throw new Error("MCP client is not connected");
|
|
183
|
+
}
|
|
184
|
+
logger.debug(`Unsubscribing from resource: ${uri}`);
|
|
185
|
+
return await this.client.unsubscribeResource({ uri }, options);
|
|
186
|
+
}
|
|
187
|
+
async listPrompts() {
|
|
188
|
+
if (!this.client) {
|
|
189
|
+
throw new Error("MCP client is not connected");
|
|
190
|
+
}
|
|
191
|
+
if (!this.capabilitiesCache?.prompts) {
|
|
192
|
+
logger.debug("Server does not advertise prompts capability, skipping");
|
|
193
|
+
return { prompts: [] };
|
|
194
|
+
}
|
|
195
|
+
try {
|
|
196
|
+
logger.debug("Listing prompts");
|
|
197
|
+
return await this.client.listPrompts();
|
|
198
|
+
} catch (err) {
|
|
199
|
+
if (err.code === -32601) {
|
|
200
|
+
logger.debug("Server advertised prompts but method not found");
|
|
201
|
+
return { prompts: [] };
|
|
202
|
+
}
|
|
203
|
+
throw err;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
async getPrompt(name, args) {
|
|
207
|
+
if (!this.client) {
|
|
208
|
+
throw new Error("MCP client is not connected");
|
|
209
|
+
}
|
|
210
|
+
logger.debug(`Getting prompt ${name}`);
|
|
211
|
+
return await this.client.getPrompt({ name, arguments: args });
|
|
212
|
+
}
|
|
213
|
+
/** Send a raw request through the client. */
|
|
214
|
+
async request(method, params = null, options) {
|
|
215
|
+
if (!this.client) {
|
|
216
|
+
throw new Error("MCP client is not connected");
|
|
217
|
+
}
|
|
218
|
+
logger.debug(`Sending raw request '${method}' with params`, params);
|
|
219
|
+
return await this.client.request(
|
|
220
|
+
{ method, params: params ?? {} },
|
|
221
|
+
void 0,
|
|
222
|
+
options
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Helper to tear down the client & connection manager safely.
|
|
227
|
+
*/
|
|
228
|
+
async cleanupResources() {
|
|
229
|
+
const issues = [];
|
|
230
|
+
if (this.client) {
|
|
231
|
+
try {
|
|
232
|
+
if (typeof this.client.close === "function") {
|
|
233
|
+
await this.client.close();
|
|
234
|
+
}
|
|
235
|
+
} catch (e) {
|
|
236
|
+
const msg = `Error closing client: ${e}`;
|
|
237
|
+
logger.warn(msg);
|
|
238
|
+
issues.push(msg);
|
|
239
|
+
} finally {
|
|
240
|
+
this.client = null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (this.connectionManager) {
|
|
244
|
+
try {
|
|
245
|
+
await this.connectionManager.stop();
|
|
246
|
+
} catch (e) {
|
|
247
|
+
const msg = `Error stopping connection manager: ${e}`;
|
|
248
|
+
logger.warn(msg);
|
|
249
|
+
issues.push(msg);
|
|
250
|
+
} finally {
|
|
251
|
+
this.connectionManager = null;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
this.toolsCache = null;
|
|
255
|
+
if (issues.length) {
|
|
256
|
+
logger.warn(`Resource cleanup finished with ${issues.length} issue(s)`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
export {
|
|
262
|
+
BaseConnector
|
|
263
|
+
};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseConnector
|
|
3
|
+
} from "./chunk-DSBKVAWD.js";
|
|
1
4
|
import {
|
|
2
5
|
logger
|
|
3
6
|
} from "./chunk-34R6SIER.js";
|
|
@@ -33,259 +36,6 @@ var MCPSession = class {
|
|
|
33
36
|
}
|
|
34
37
|
};
|
|
35
38
|
|
|
36
|
-
// src/connectors/base.ts
|
|
37
|
-
var BaseConnector = class {
|
|
38
|
-
static {
|
|
39
|
-
__name(this, "BaseConnector");
|
|
40
|
-
}
|
|
41
|
-
client = null;
|
|
42
|
-
connectionManager = null;
|
|
43
|
-
toolsCache = null;
|
|
44
|
-
capabilitiesCache = null;
|
|
45
|
-
serverInfoCache = null;
|
|
46
|
-
connected = false;
|
|
47
|
-
opts;
|
|
48
|
-
constructor(opts = {}) {
|
|
49
|
-
this.opts = opts;
|
|
50
|
-
}
|
|
51
|
-
/** Disconnect and release resources. */
|
|
52
|
-
async disconnect() {
|
|
53
|
-
if (!this.connected) {
|
|
54
|
-
logger.debug("Not connected to MCP implementation");
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
logger.debug("Disconnecting from MCP implementation");
|
|
58
|
-
await this.cleanupResources();
|
|
59
|
-
this.connected = false;
|
|
60
|
-
logger.debug("Disconnected from MCP implementation");
|
|
61
|
-
}
|
|
62
|
-
/** Check if the client is connected */
|
|
63
|
-
get isClientConnected() {
|
|
64
|
-
return this.client != null;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Initialise the MCP session **after** `connect()` has succeeded.
|
|
68
|
-
*
|
|
69
|
-
* In the SDK, `Client.connect(transport)` automatically performs the
|
|
70
|
-
* protocol‑level `initialize` handshake, so we only need to cache the list of
|
|
71
|
-
* tools and expose some server info.
|
|
72
|
-
*/
|
|
73
|
-
async initialize(defaultRequestOptions = this.opts.defaultRequestOptions ?? {}) {
|
|
74
|
-
if (!this.client) {
|
|
75
|
-
throw new Error("MCP client is not connected");
|
|
76
|
-
}
|
|
77
|
-
logger.debug("Caching server capabilities & tools");
|
|
78
|
-
const capabilities = this.client.getServerCapabilities();
|
|
79
|
-
this.capabilitiesCache = capabilities;
|
|
80
|
-
const serverInfo = this.client.getServerVersion();
|
|
81
|
-
this.serverInfoCache = serverInfo || null;
|
|
82
|
-
const listToolsRes = await this.client.listTools(
|
|
83
|
-
void 0,
|
|
84
|
-
defaultRequestOptions
|
|
85
|
-
);
|
|
86
|
-
this.toolsCache = listToolsRes.tools ?? [];
|
|
87
|
-
logger.debug(`Fetched ${this.toolsCache.length} tools from server`);
|
|
88
|
-
logger.debug("Server capabilities:", capabilities);
|
|
89
|
-
logger.debug("Server info:", serverInfo);
|
|
90
|
-
return capabilities;
|
|
91
|
-
}
|
|
92
|
-
/** Lazily expose the cached tools list. */
|
|
93
|
-
get tools() {
|
|
94
|
-
if (!this.toolsCache) {
|
|
95
|
-
throw new Error("MCP client is not initialized; call initialize() first");
|
|
96
|
-
}
|
|
97
|
-
return this.toolsCache;
|
|
98
|
-
}
|
|
99
|
-
/** Expose cached server capabilities. */
|
|
100
|
-
get serverCapabilities() {
|
|
101
|
-
return this.capabilitiesCache;
|
|
102
|
-
}
|
|
103
|
-
/** Expose cached server info. */
|
|
104
|
-
get serverInfo() {
|
|
105
|
-
return this.serverInfoCache;
|
|
106
|
-
}
|
|
107
|
-
/** Call a tool on the server. */
|
|
108
|
-
async callTool(name, args, options) {
|
|
109
|
-
if (!this.client) {
|
|
110
|
-
throw new Error("MCP client is not connected");
|
|
111
|
-
}
|
|
112
|
-
logger.debug(`Calling tool '${name}' with args`, args);
|
|
113
|
-
const res = await this.client.callTool(
|
|
114
|
-
{ name, arguments: args },
|
|
115
|
-
void 0,
|
|
116
|
-
options
|
|
117
|
-
);
|
|
118
|
-
logger.debug(`Tool '${name}' returned`, res);
|
|
119
|
-
return res;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* List resources from the server with optional pagination
|
|
123
|
-
*
|
|
124
|
-
* @param cursor - Optional cursor for pagination
|
|
125
|
-
* @param options - Request options
|
|
126
|
-
* @returns Resource list with optional nextCursor for pagination
|
|
127
|
-
*/
|
|
128
|
-
async listResources(cursor, options) {
|
|
129
|
-
if (!this.client) {
|
|
130
|
-
throw new Error("MCP client is not connected");
|
|
131
|
-
}
|
|
132
|
-
logger.debug("Listing resources", cursor ? `with cursor: ${cursor}` : "");
|
|
133
|
-
return await this.client.listResources({ cursor }, options);
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* List all resources from the server, automatically handling pagination
|
|
137
|
-
*
|
|
138
|
-
* @param options - Request options
|
|
139
|
-
* @returns Complete list of all resources
|
|
140
|
-
*/
|
|
141
|
-
async listAllResources(options) {
|
|
142
|
-
if (!this.client) {
|
|
143
|
-
throw new Error("MCP client is not connected");
|
|
144
|
-
}
|
|
145
|
-
if (!this.capabilitiesCache?.resources) {
|
|
146
|
-
logger.debug("Server does not advertise resources capability, skipping");
|
|
147
|
-
return { resources: [] };
|
|
148
|
-
}
|
|
149
|
-
try {
|
|
150
|
-
logger.debug("Listing all resources (with auto-pagination)");
|
|
151
|
-
const allResources = [];
|
|
152
|
-
let cursor = void 0;
|
|
153
|
-
do {
|
|
154
|
-
const result = await this.client.listResources({ cursor }, options);
|
|
155
|
-
allResources.push(...result.resources || []);
|
|
156
|
-
cursor = result.nextCursor;
|
|
157
|
-
} while (cursor);
|
|
158
|
-
return { resources: allResources };
|
|
159
|
-
} catch (err) {
|
|
160
|
-
if (err.code === -32601) {
|
|
161
|
-
logger.debug("Server advertised resources but method not found");
|
|
162
|
-
return { resources: [] };
|
|
163
|
-
}
|
|
164
|
-
throw err;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* List resource templates from the server
|
|
169
|
-
*
|
|
170
|
-
* @param options - Request options
|
|
171
|
-
* @returns List of available resource templates
|
|
172
|
-
*/
|
|
173
|
-
async listResourceTemplates(options) {
|
|
174
|
-
if (!this.client) {
|
|
175
|
-
throw new Error("MCP client is not connected");
|
|
176
|
-
}
|
|
177
|
-
logger.debug("Listing resource templates");
|
|
178
|
-
return await this.client.listResourceTemplates(void 0, options);
|
|
179
|
-
}
|
|
180
|
-
/** Read a resource by URI. */
|
|
181
|
-
async readResource(uri, options) {
|
|
182
|
-
if (!this.client) {
|
|
183
|
-
throw new Error("MCP client is not connected");
|
|
184
|
-
}
|
|
185
|
-
logger.debug(`Reading resource ${uri}`);
|
|
186
|
-
const res = await this.client.readResource({ uri }, options);
|
|
187
|
-
return res;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Subscribe to resource updates
|
|
191
|
-
*
|
|
192
|
-
* @param uri - URI of the resource to subscribe to
|
|
193
|
-
* @param options - Request options
|
|
194
|
-
*/
|
|
195
|
-
async subscribeToResource(uri, options) {
|
|
196
|
-
if (!this.client) {
|
|
197
|
-
throw new Error("MCP client is not connected");
|
|
198
|
-
}
|
|
199
|
-
logger.debug(`Subscribing to resource: ${uri}`);
|
|
200
|
-
return await this.client.subscribeResource({ uri }, options);
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Unsubscribe from resource updates
|
|
204
|
-
*
|
|
205
|
-
* @param uri - URI of the resource to unsubscribe from
|
|
206
|
-
* @param options - Request options
|
|
207
|
-
*/
|
|
208
|
-
async unsubscribeFromResource(uri, options) {
|
|
209
|
-
if (!this.client) {
|
|
210
|
-
throw new Error("MCP client is not connected");
|
|
211
|
-
}
|
|
212
|
-
logger.debug(`Unsubscribing from resource: ${uri}`);
|
|
213
|
-
return await this.client.unsubscribeResource({ uri }, options);
|
|
214
|
-
}
|
|
215
|
-
async listPrompts() {
|
|
216
|
-
if (!this.client) {
|
|
217
|
-
throw new Error("MCP client is not connected");
|
|
218
|
-
}
|
|
219
|
-
if (!this.capabilitiesCache?.prompts) {
|
|
220
|
-
logger.debug("Server does not advertise prompts capability, skipping");
|
|
221
|
-
return { prompts: [] };
|
|
222
|
-
}
|
|
223
|
-
try {
|
|
224
|
-
logger.debug("Listing prompts");
|
|
225
|
-
return await this.client.listPrompts();
|
|
226
|
-
} catch (err) {
|
|
227
|
-
if (err.code === -32601) {
|
|
228
|
-
logger.debug("Server advertised prompts but method not found");
|
|
229
|
-
return { prompts: [] };
|
|
230
|
-
}
|
|
231
|
-
throw err;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
async getPrompt(name, args) {
|
|
235
|
-
if (!this.client) {
|
|
236
|
-
throw new Error("MCP client is not connected");
|
|
237
|
-
}
|
|
238
|
-
logger.debug(`Getting prompt ${name}`);
|
|
239
|
-
return await this.client.getPrompt({ name, arguments: args });
|
|
240
|
-
}
|
|
241
|
-
/** Send a raw request through the client. */
|
|
242
|
-
async request(method, params = null, options) {
|
|
243
|
-
if (!this.client) {
|
|
244
|
-
throw new Error("MCP client is not connected");
|
|
245
|
-
}
|
|
246
|
-
logger.debug(`Sending raw request '${method}' with params`, params);
|
|
247
|
-
return await this.client.request(
|
|
248
|
-
{ method, params: params ?? {} },
|
|
249
|
-
void 0,
|
|
250
|
-
options
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Helper to tear down the client & connection manager safely.
|
|
255
|
-
*/
|
|
256
|
-
async cleanupResources() {
|
|
257
|
-
const issues = [];
|
|
258
|
-
if (this.client) {
|
|
259
|
-
try {
|
|
260
|
-
if (typeof this.client.close === "function") {
|
|
261
|
-
await this.client.close();
|
|
262
|
-
}
|
|
263
|
-
} catch (e) {
|
|
264
|
-
const msg = `Error closing client: ${e}`;
|
|
265
|
-
logger.warn(msg);
|
|
266
|
-
issues.push(msg);
|
|
267
|
-
} finally {
|
|
268
|
-
this.client = null;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
if (this.connectionManager) {
|
|
272
|
-
try {
|
|
273
|
-
await this.connectionManager.stop();
|
|
274
|
-
} catch (e) {
|
|
275
|
-
const msg = `Error stopping connection manager: ${e}`;
|
|
276
|
-
logger.warn(msg);
|
|
277
|
-
issues.push(msg);
|
|
278
|
-
} finally {
|
|
279
|
-
this.connectionManager = null;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
this.toolsCache = null;
|
|
283
|
-
if (issues.length) {
|
|
284
|
-
logger.warn(`Resource cleanup finished with ${issues.length} issue(s)`);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
|
|
289
39
|
// src/connectors/http.ts
|
|
290
40
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
291
41
|
import { StreamableHTTPError } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
@@ -1414,7 +1164,6 @@ export {
|
|
|
1414
1164
|
MCPSession,
|
|
1415
1165
|
BaseMCPClient,
|
|
1416
1166
|
ConnectionManager,
|
|
1417
|
-
BaseConnector,
|
|
1418
1167
|
HttpConnector,
|
|
1419
1168
|
WebSocketConnector,
|
|
1420
1169
|
BrowserOAuthClientProvider,
|