agents 0.5.1 → 0.7.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.
- package/dist/agent-DnmmRjyv.d.ts +231 -0
- package/dist/{client-connection-CGMuV62J.js → client-connection-D3Wcd6Q6.js} +154 -23
- package/dist/client-connection-D3Wcd6Q6.js.map +1 -0
- package/dist/{client-storage-D633wI1S.d.ts → client-storage-tusTuoSF.d.ts} +262 -13
- package/dist/experimental/forever.d.ts +7 -18
- package/dist/experimental/forever.js +4 -38
- package/dist/experimental/forever.js.map +1 -1
- package/dist/experimental/memory/session/index.d.ts +251 -0
- package/dist/experimental/memory/session/index.js +385 -0
- package/dist/experimental/memory/session/index.js.map +1 -0
- package/dist/index.d.ts +84 -22
- package/dist/index.js +324 -250
- package/dist/index.js.map +1 -1
- package/dist/mcp/client.d.ts +51 -7
- package/dist/mcp/client.js +157 -32
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/do-oauth-client-provider.js +1 -1
- package/dist/mcp/do-oauth-client-provider.js.map +1 -1
- package/dist/mcp/index.d.ts +27 -165
- package/dist/mcp/index.js +50 -10
- package/dist/mcp/index.js.map +1 -1
- package/dist/observability/index.d.ts +72 -6
- package/dist/observability/index.js +61 -16
- package/dist/observability/index.js.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/workflows.d.ts +15 -1
- package/dist/workflows.js +36 -3
- package/dist/workflows.js.map +1 -1
- package/package.json +16 -11
- package/dist/agent-B4_kEsdK.d.ts +0 -60
- package/dist/client-connection-CGMuV62J.js.map +0 -1
- package/dist/mcp-DA0kDE7K.d.ts +0 -61
package/dist/mcp/client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RetryOptions } from "../retries.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { E as Event, T as Emitter, i as MCPTransportOptions, n as MCPClientConnection, r as MCPConnectionState, t as MCPServerRow, w as TransportType } from "../client-storage-tusTuoSF.js";
|
|
3
|
+
import { n as MCPObservabilityEvent } from "../agent-DnmmRjyv.js";
|
|
4
4
|
import { AgentMcpOAuthProvider } from "./do-oauth-client-provider.js";
|
|
5
5
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
6
6
|
import { CallToolRequest, CallToolResultSchema, CompatibilityCallToolResultSchema, GetPromptRequest, Prompt, ReadResourceRequest, Resource, ResourceTemplate, Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
@@ -39,7 +39,7 @@ type MCPOAuthCallbackResult = {
|
|
|
39
39
|
type RegisterServerOptions = {
|
|
40
40
|
url: string;
|
|
41
41
|
name: string;
|
|
42
|
-
callbackUrl
|
|
42
|
+
callbackUrl?: string;
|
|
43
43
|
client?: ConstructorParameters<typeof Client>[1];
|
|
44
44
|
transport?: MCPTransportOptions;
|
|
45
45
|
authUrl?: string;
|
|
@@ -102,6 +102,7 @@ declare class MCPClientManager {
|
|
|
102
102
|
private _storage;
|
|
103
103
|
private _createAuthProviderFn?;
|
|
104
104
|
private _isRestored;
|
|
105
|
+
private _pendingConnections;
|
|
105
106
|
/** @internal Protected for testing purposes. */
|
|
106
107
|
protected readonly _onObservabilityEvent: Emitter<MCPObservabilityEvent>;
|
|
107
108
|
readonly onObservabilityEvent: Event<MCPObservabilityEvent>;
|
|
@@ -133,13 +134,46 @@ declare class MCPClientManager {
|
|
|
133
134
|
* @internal
|
|
134
135
|
*/
|
|
135
136
|
private createAuthProvider;
|
|
137
|
+
/**
|
|
138
|
+
* Get saved RPC servers from storage (servers with rpc:// URLs).
|
|
139
|
+
* These are restored separately by the Agent class since they need env bindings.
|
|
140
|
+
*/
|
|
141
|
+
getRpcServersFromStorage(): MCPServerRow[];
|
|
142
|
+
/**
|
|
143
|
+
* Save an RPC server to storage for hibernation recovery.
|
|
144
|
+
* The bindingName is stored in server_options so the Agent can look up
|
|
145
|
+
* the namespace from env during restore.
|
|
146
|
+
*/
|
|
147
|
+
saveRpcServerToStorage(id: string, name: string, normalizedName: string, bindingName: string, props?: Record<string, unknown>): void;
|
|
136
148
|
/**
|
|
137
149
|
* Restore MCP server connections from storage
|
|
138
|
-
* This method is called on Agent initialization to restore previously connected servers
|
|
150
|
+
* This method is called on Agent initialization to restore previously connected servers.
|
|
151
|
+
* RPC servers (rpc:// URLs) are skipped here -- they are restored by the Agent class
|
|
152
|
+
* which has access to env bindings.
|
|
139
153
|
*
|
|
140
154
|
* @param clientName Name to use for OAuth client (typically the agent instance name)
|
|
141
155
|
*/
|
|
142
156
|
restoreConnectionsFromStorage(clientName: string): Promise<void>;
|
|
157
|
+
/**
|
|
158
|
+
* Track a pending connection promise for a server.
|
|
159
|
+
* The promise is removed from the map when it settles.
|
|
160
|
+
*/
|
|
161
|
+
private _trackConnection;
|
|
162
|
+
/**
|
|
163
|
+
* Wait for all in-flight connection and discovery operations to settle.
|
|
164
|
+
* This is useful when you need MCP tools to be available before proceeding,
|
|
165
|
+
* e.g. before calling getAITools() after the agent wakes from hibernation.
|
|
166
|
+
*
|
|
167
|
+
* Returns once every pending connection has either connected and discovered,
|
|
168
|
+
* failed, or timed out. Never rejects.
|
|
169
|
+
*
|
|
170
|
+
* @param options.timeout - Maximum time in milliseconds to wait.
|
|
171
|
+
* `0` returns immediately without waiting.
|
|
172
|
+
* `undefined` (default) waits indefinitely.
|
|
173
|
+
*/
|
|
174
|
+
waitForConnections(options?: {
|
|
175
|
+
timeout?: number;
|
|
176
|
+
}): Promise<void>;
|
|
143
177
|
/**
|
|
144
178
|
* Internal method to restore a single server connection and discovery
|
|
145
179
|
*/
|
|
@@ -218,11 +252,14 @@ declare class MCPClientManager {
|
|
|
218
252
|
timeoutMs?: number;
|
|
219
253
|
}): Promise<MCPDiscoverResult | undefined>;
|
|
220
254
|
/**
|
|
221
|
-
* Establish connection in the background after OAuth completion
|
|
222
|
-
* This method connects to the server and discovers its capabilities
|
|
255
|
+
* Establish connection in the background after OAuth completion.
|
|
256
|
+
* This method connects to the server and discovers its capabilities.
|
|
257
|
+
* The connection is automatically tracked so that `waitForConnections()`
|
|
258
|
+
* will include it.
|
|
223
259
|
* @param serverId The server ID to establish connection for
|
|
224
260
|
*/
|
|
225
261
|
establishConnection(serverId: string): Promise<void>;
|
|
262
|
+
private _doEstablishConnection;
|
|
226
263
|
/**
|
|
227
264
|
* Configure OAuth callback handling
|
|
228
265
|
* @param config OAuth callback configuration
|
|
@@ -333,7 +370,14 @@ declare class MCPClientManager {
|
|
|
333
370
|
priority?: number | undefined;
|
|
334
371
|
lastModified?: string | undefined;
|
|
335
372
|
} | undefined;
|
|
336
|
-
_meta
|
|
373
|
+
_meta
|
|
374
|
+
/**
|
|
375
|
+
* We need to delay loading ai sdk, because putting it in module scope is
|
|
376
|
+
* causing issues with startup time.
|
|
377
|
+
* The only place it's used is in getAITools, which only matters after
|
|
378
|
+
* .connect() is called on at least one server.
|
|
379
|
+
* So it's safe to delay loading it until .connect() is called.
|
|
380
|
+
*/?: Record<string, unknown> | undefined;
|
|
337
381
|
} | {
|
|
338
382
|
type: "resource";
|
|
339
383
|
resource: {
|
package/dist/mcp/client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { tryN } from "../retries.js";
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as RPC_DO_PREFIX, c as Emitter, n as MCPConnectionState, o as toErrorMessage, s as DisposableStore, t as MCPClientConnection } from "../client-connection-D3Wcd6Q6.js";
|
|
3
3
|
import { DurableObjectOAuthClientProvider } from "./do-oauth-client-provider.js";
|
|
4
4
|
import { nanoid } from "nanoid";
|
|
5
5
|
import { CfWorkerJsonSchemaValidator } from "@modelcontextprotocol/sdk/validation/cfworker-provider.js";
|
|
@@ -7,6 +7,47 @@ import { CfWorkerJsonSchemaValidator } from "@modelcontextprotocol/sdk/validatio
|
|
|
7
7
|
//#region src/mcp/client.ts
|
|
8
8
|
const defaultClientOptions = { jsonSchemaValidator: new CfWorkerJsonSchemaValidator() };
|
|
9
9
|
/**
|
|
10
|
+
* Blocked hostname patterns for SSRF protection.
|
|
11
|
+
* Prevents MCP client from connecting to internal/private network addresses.
|
|
12
|
+
*/
|
|
13
|
+
const BLOCKED_HOSTNAMES = new Set([
|
|
14
|
+
"localhost",
|
|
15
|
+
"0.0.0.0",
|
|
16
|
+
"[::1]",
|
|
17
|
+
"[::]",
|
|
18
|
+
"metadata.google.internal"
|
|
19
|
+
]);
|
|
20
|
+
/**
|
|
21
|
+
* Check whether a hostname looks like a private/internal IP address.
|
|
22
|
+
* Blocks RFC 1918, link-local, loopback, and cloud metadata endpoints.
|
|
23
|
+
*/
|
|
24
|
+
function isBlockedUrl(url) {
|
|
25
|
+
let parsed;
|
|
26
|
+
try {
|
|
27
|
+
parsed = new URL(url);
|
|
28
|
+
} catch {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
const hostname = parsed.hostname;
|
|
32
|
+
if (BLOCKED_HOSTNAMES.has(hostname)) return true;
|
|
33
|
+
const ipv4Parts = hostname.split(".");
|
|
34
|
+
if (ipv4Parts.length === 4 && ipv4Parts.every((p) => /^\d{1,3}$/.test(p))) {
|
|
35
|
+
const [a, b] = ipv4Parts.map(Number);
|
|
36
|
+
if (a === 10) return true;
|
|
37
|
+
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
38
|
+
if (a === 192 && b === 168) return true;
|
|
39
|
+
if (a === 127) return true;
|
|
40
|
+
if (a === 169 && b === 254) return true;
|
|
41
|
+
if (a === 0) return true;
|
|
42
|
+
}
|
|
43
|
+
if (hostname.startsWith("[") && hostname.endsWith("]")) {
|
|
44
|
+
const addr = hostname.slice(1, -1).toLowerCase();
|
|
45
|
+
if (addr.startsWith("fc") || addr.startsWith("fd")) return true;
|
|
46
|
+
if (addr.startsWith("fe80")) return true;
|
|
47
|
+
}
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
10
51
|
* Utility class that aggregates multiple MCP clients into one
|
|
11
52
|
*/
|
|
12
53
|
var MCPClientManager = class {
|
|
@@ -22,6 +63,7 @@ var MCPClientManager = class {
|
|
|
22
63
|
this._didWarnAboutUnstableGetAITools = false;
|
|
23
64
|
this._connectionDisposables = /* @__PURE__ */ new Map();
|
|
24
65
|
this._isRestored = false;
|
|
66
|
+
this._pendingConnections = /* @__PURE__ */ new Map();
|
|
25
67
|
this._onObservabilityEvent = new Emitter();
|
|
26
68
|
this.onObservabilityEvent = this._onObservabilityEvent.event;
|
|
27
69
|
this._onServerStateChanged = new Emitter();
|
|
@@ -80,8 +122,36 @@ var MCPClientManager = class {
|
|
|
80
122
|
return authProvider;
|
|
81
123
|
}
|
|
82
124
|
/**
|
|
125
|
+
* Get saved RPC servers from storage (servers with rpc:// URLs).
|
|
126
|
+
* These are restored separately by the Agent class since they need env bindings.
|
|
127
|
+
*/
|
|
128
|
+
getRpcServersFromStorage() {
|
|
129
|
+
return this.getServersFromStorage().filter((s) => s.server_url.startsWith(RPC_DO_PREFIX));
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Save an RPC server to storage for hibernation recovery.
|
|
133
|
+
* The bindingName is stored in server_options so the Agent can look up
|
|
134
|
+
* the namespace from env during restore.
|
|
135
|
+
*/
|
|
136
|
+
saveRpcServerToStorage(id, name, normalizedName, bindingName, props) {
|
|
137
|
+
this.saveServerToStorage({
|
|
138
|
+
id,
|
|
139
|
+
name,
|
|
140
|
+
server_url: `${RPC_DO_PREFIX}${normalizedName}`,
|
|
141
|
+
client_id: null,
|
|
142
|
+
auth_url: null,
|
|
143
|
+
callback_url: "",
|
|
144
|
+
server_options: JSON.stringify({
|
|
145
|
+
bindingName,
|
|
146
|
+
props
|
|
147
|
+
})
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
83
151
|
* Restore MCP server connections from storage
|
|
84
|
-
* This method is called on Agent initialization to restore previously connected servers
|
|
152
|
+
* This method is called on Agent initialization to restore previously connected servers.
|
|
153
|
+
* RPC servers (rpc:// URLs) are skipped here -- they are restored by the Agent class
|
|
154
|
+
* which has access to env bindings.
|
|
85
155
|
*
|
|
86
156
|
* @param clientName Name to use for OAuth client (typically the agent instance name)
|
|
87
157
|
*/
|
|
@@ -93,6 +163,7 @@ var MCPClientManager = class {
|
|
|
93
163
|
return;
|
|
94
164
|
}
|
|
95
165
|
for (const server of servers) {
|
|
166
|
+
if (server.server_url.startsWith(RPC_DO_PREFIX)) continue;
|
|
96
167
|
const existingConn = this.mcpConnections[server.id];
|
|
97
168
|
if (existingConn) {
|
|
98
169
|
if (existingConn.connectionState === MCPConnectionState.READY) {
|
|
@@ -112,9 +183,12 @@ var MCPClientManager = class {
|
|
|
112
183
|
}
|
|
113
184
|
}
|
|
114
185
|
const parsedOptions = server.server_options ? JSON.parse(server.server_options) : null;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
186
|
+
let authProvider;
|
|
187
|
+
if (server.callback_url) {
|
|
188
|
+
authProvider = this._createAuthProviderFn ? this._createAuthProviderFn(server.callback_url) : this.createAuthProvider(server.id, server.callback_url, clientName, server.client_id ?? void 0);
|
|
189
|
+
authProvider.serverId = server.id;
|
|
190
|
+
if (server.client_id) authProvider.clientId = server.client_id;
|
|
191
|
+
}
|
|
118
192
|
const conn = this.createConnection(server.id, server.server_url, {
|
|
119
193
|
client: parsedOptions?.client ?? {},
|
|
120
194
|
transport: {
|
|
@@ -127,11 +201,46 @@ var MCPClientManager = class {
|
|
|
127
201
|
conn.connectionState = MCPConnectionState.AUTHENTICATING;
|
|
128
202
|
continue;
|
|
129
203
|
}
|
|
130
|
-
this._restoreServer(server.id, parsedOptions?.retry);
|
|
204
|
+
this._trackConnection(server.id, this._restoreServer(server.id, parsedOptions?.retry));
|
|
131
205
|
}
|
|
132
206
|
this._isRestored = true;
|
|
133
207
|
}
|
|
134
208
|
/**
|
|
209
|
+
* Track a pending connection promise for a server.
|
|
210
|
+
* The promise is removed from the map when it settles.
|
|
211
|
+
*/
|
|
212
|
+
_trackConnection(serverId, promise) {
|
|
213
|
+
const tracked = promise.finally(() => {
|
|
214
|
+
if (this._pendingConnections.get(serverId) === tracked) this._pendingConnections.delete(serverId);
|
|
215
|
+
});
|
|
216
|
+
this._pendingConnections.set(serverId, tracked);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Wait for all in-flight connection and discovery operations to settle.
|
|
220
|
+
* This is useful when you need MCP tools to be available before proceeding,
|
|
221
|
+
* e.g. before calling getAITools() after the agent wakes from hibernation.
|
|
222
|
+
*
|
|
223
|
+
* Returns once every pending connection has either connected and discovered,
|
|
224
|
+
* failed, or timed out. Never rejects.
|
|
225
|
+
*
|
|
226
|
+
* @param options.timeout - Maximum time in milliseconds to wait.
|
|
227
|
+
* `0` returns immediately without waiting.
|
|
228
|
+
* `undefined` (default) waits indefinitely.
|
|
229
|
+
*/
|
|
230
|
+
async waitForConnections(options) {
|
|
231
|
+
if (this._pendingConnections.size === 0) return;
|
|
232
|
+
if (options?.timeout != null && options.timeout <= 0) return;
|
|
233
|
+
const settled = Promise.allSettled(this._pendingConnections.values());
|
|
234
|
+
if (options?.timeout != null && options.timeout > 0) {
|
|
235
|
+
let timerId;
|
|
236
|
+
const timer = new Promise((resolve) => {
|
|
237
|
+
timerId = setTimeout(resolve, options.timeout);
|
|
238
|
+
});
|
|
239
|
+
await Promise.race([settled, timer]);
|
|
240
|
+
clearTimeout(timerId);
|
|
241
|
+
} else await settled;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
135
244
|
* Internal method to restore a single server connection and discovery
|
|
136
245
|
*/
|
|
137
246
|
async _restoreServer(serverId, retry) {
|
|
@@ -171,6 +280,7 @@ var MCPClientManager = class {
|
|
|
171
280
|
options.transport.authProvider.serverId = id;
|
|
172
281
|
if (options.reconnect?.oauthClientId) options.transport.authProvider.clientId = options.reconnect?.oauthClientId;
|
|
173
282
|
}
|
|
283
|
+
if (isBlockedUrl(url)) throw new Error(`Blocked URL: ${url} — MCP client connections to private/internal addresses are not allowed`);
|
|
174
284
|
if (!options.reconnect?.oauthCode || !this.mcpConnections[id]) {
|
|
175
285
|
const normalizedTransport = {
|
|
176
286
|
...options.transport,
|
|
@@ -198,15 +308,13 @@ var MCPClientManager = class {
|
|
|
198
308
|
} catch (error) {
|
|
199
309
|
this._onObservabilityEvent.fire({
|
|
200
310
|
type: "mcp:client:connect",
|
|
201
|
-
displayMessage: `Failed to complete OAuth reconnection for ${id} for ${url}`,
|
|
202
311
|
payload: {
|
|
203
312
|
url,
|
|
204
313
|
transport: options.transport?.type ?? "auto",
|
|
205
314
|
state: this.mcpConnections[id].connectionState,
|
|
206
315
|
error: toErrorMessage(error)
|
|
207
316
|
},
|
|
208
|
-
timestamp: Date.now()
|
|
209
|
-
id
|
|
317
|
+
timestamp: Date.now()
|
|
210
318
|
});
|
|
211
319
|
throw error;
|
|
212
320
|
}
|
|
@@ -259,6 +367,7 @@ var MCPClientManager = class {
|
|
|
259
367
|
* @returns Server ID
|
|
260
368
|
*/
|
|
261
369
|
async registerServer(id, options) {
|
|
370
|
+
if (isBlockedUrl(options.url)) throw new Error(`Blocked URL: ${options.url} — MCP client connections to private/internal addresses are not allowed`);
|
|
262
371
|
this.createConnection(id, options.url, {
|
|
263
372
|
client: options.client,
|
|
264
373
|
transport: {
|
|
@@ -271,7 +380,7 @@ var MCPClientManager = class {
|
|
|
271
380
|
id,
|
|
272
381
|
name: options.name,
|
|
273
382
|
server_url: options.url,
|
|
274
|
-
callback_url: options.callbackUrl,
|
|
383
|
+
callback_url: options.callbackUrl ?? "",
|
|
275
384
|
client_id: options.clientId ?? null,
|
|
276
385
|
auth_url: options.authUrl ?? null,
|
|
277
386
|
server_options: JSON.stringify({
|
|
@@ -324,6 +433,15 @@ var MCPClientManager = class {
|
|
|
324
433
|
});
|
|
325
434
|
this._onServerStateChanged.fire();
|
|
326
435
|
}
|
|
436
|
+
this._onObservabilityEvent.fire({
|
|
437
|
+
type: "mcp:client:authorize",
|
|
438
|
+
payload: {
|
|
439
|
+
serverId: id,
|
|
440
|
+
authUrl,
|
|
441
|
+
clientId
|
|
442
|
+
},
|
|
443
|
+
timestamp: Date.now()
|
|
444
|
+
});
|
|
327
445
|
return {
|
|
328
446
|
state: conn.connectionState,
|
|
329
447
|
authUrl,
|
|
@@ -459,10 +577,8 @@ var MCPClientManager = class {
|
|
|
459
577
|
if (!conn) {
|
|
460
578
|
this._onObservabilityEvent.fire({
|
|
461
579
|
type: "mcp:client:discover",
|
|
462
|
-
displayMessage: `Connection not found for ${serverId}`,
|
|
463
580
|
payload: {},
|
|
464
|
-
timestamp: Date.now()
|
|
465
|
-
id: nanoid()
|
|
581
|
+
timestamp: Date.now()
|
|
466
582
|
});
|
|
467
583
|
return;
|
|
468
584
|
}
|
|
@@ -474,33 +590,36 @@ var MCPClientManager = class {
|
|
|
474
590
|
};
|
|
475
591
|
}
|
|
476
592
|
/**
|
|
477
|
-
* Establish connection in the background after OAuth completion
|
|
478
|
-
* This method connects to the server and discovers its capabilities
|
|
593
|
+
* Establish connection in the background after OAuth completion.
|
|
594
|
+
* This method connects to the server and discovers its capabilities.
|
|
595
|
+
* The connection is automatically tracked so that `waitForConnections()`
|
|
596
|
+
* will include it.
|
|
479
597
|
* @param serverId The server ID to establish connection for
|
|
480
598
|
*/
|
|
481
599
|
async establishConnection(serverId) {
|
|
600
|
+
const promise = this._doEstablishConnection(serverId);
|
|
601
|
+
this._trackConnection(serverId, promise);
|
|
602
|
+
return promise;
|
|
603
|
+
}
|
|
604
|
+
async _doEstablishConnection(serverId) {
|
|
482
605
|
const conn = this.mcpConnections[serverId];
|
|
483
606
|
if (!conn) {
|
|
484
607
|
this._onObservabilityEvent.fire({
|
|
485
608
|
type: "mcp:client:preconnect",
|
|
486
|
-
displayMessage: `Connection not found for serverId: ${serverId}`,
|
|
487
609
|
payload: { serverId },
|
|
488
|
-
timestamp: Date.now()
|
|
489
|
-
id: nanoid()
|
|
610
|
+
timestamp: Date.now()
|
|
490
611
|
});
|
|
491
612
|
return;
|
|
492
613
|
}
|
|
493
614
|
if (conn.connectionState === MCPConnectionState.DISCOVERING || conn.connectionState === MCPConnectionState.READY) {
|
|
494
615
|
this._onObservabilityEvent.fire({
|
|
495
616
|
type: "mcp:client:connect",
|
|
496
|
-
displayMessage: `establishConnection skipped for ${serverId}, already in ${conn.connectionState} state`,
|
|
497
617
|
payload: {
|
|
498
618
|
url: conn.url.toString(),
|
|
499
619
|
transport: conn.options.transport.type || "unknown",
|
|
500
620
|
state: conn.connectionState
|
|
501
621
|
},
|
|
502
|
-
timestamp: Date.now()
|
|
503
|
-
id: nanoid()
|
|
622
|
+
timestamp: Date.now()
|
|
504
623
|
});
|
|
505
624
|
return;
|
|
506
625
|
}
|
|
@@ -513,14 +632,12 @@ var MCPClientManager = class {
|
|
|
513
632
|
if (connectResult.state === MCPConnectionState.CONNECTED) await this.discoverIfConnected(serverId);
|
|
514
633
|
this._onObservabilityEvent.fire({
|
|
515
634
|
type: "mcp:client:connect",
|
|
516
|
-
displayMessage: `establishConnection completed for ${serverId}, final state: ${conn.connectionState}`,
|
|
517
635
|
payload: {
|
|
518
636
|
url: conn.url.toString(),
|
|
519
637
|
transport: conn.options.transport.type || "unknown",
|
|
520
638
|
state: conn.connectionState
|
|
521
639
|
},
|
|
522
|
-
timestamp: Date.now()
|
|
523
|
-
id: nanoid()
|
|
640
|
+
timestamp: Date.now()
|
|
524
641
|
});
|
|
525
642
|
}
|
|
526
643
|
/**
|
|
@@ -566,8 +683,10 @@ var MCPClientManager = class {
|
|
|
566
683
|
getAITools() {
|
|
567
684
|
if (!this.jsonSchema) throw new Error("jsonSchema not initialized.");
|
|
568
685
|
for (const [id, conn] of Object.entries(this.mcpConnections)) if (conn.connectionState !== MCPConnectionState.READY && conn.connectionState !== MCPConnectionState.AUTHENTICATING) console.warn(`[getAITools] WARNING: Reading tools from connection ${id} in state "${conn.connectionState}". Tools may not be loaded yet.`);
|
|
569
|
-
|
|
570
|
-
|
|
686
|
+
const entries = [];
|
|
687
|
+
for (const tool of getNamespacedData(this.mcpConnections, "tools")) try {
|
|
688
|
+
const toolKey = `tool_${tool.serverId.replace(/-/g, "")}_${tool.name}`;
|
|
689
|
+
entries.push([toolKey, {
|
|
571
690
|
description: tool.description,
|
|
572
691
|
execute: async (args) => {
|
|
573
692
|
const result = await this.callTool({
|
|
@@ -582,10 +701,13 @@ var MCPClientManager = class {
|
|
|
582
701
|
}
|
|
583
702
|
return result;
|
|
584
703
|
},
|
|
585
|
-
inputSchema: this.jsonSchema(tool.inputSchema),
|
|
704
|
+
inputSchema: tool.inputSchema ? this.jsonSchema(tool.inputSchema) : this.jsonSchema({ type: "object" }),
|
|
586
705
|
outputSchema: tool.outputSchema ? this.jsonSchema(tool.outputSchema) : void 0
|
|
587
|
-
}];
|
|
588
|
-
})
|
|
706
|
+
}]);
|
|
707
|
+
} catch (e) {
|
|
708
|
+
console.warn(`[getAITools] Skipping tool "${tool.name}" from "${tool.serverId}": ${e}`);
|
|
709
|
+
}
|
|
710
|
+
return Object.fromEntries(entries);
|
|
589
711
|
}
|
|
590
712
|
/**
|
|
591
713
|
* @deprecated this has been renamed to getAITools(), and unstable_getAITools will be removed in the next major version
|
|
@@ -610,6 +732,7 @@ var MCPClientManager = class {
|
|
|
610
732
|
*/
|
|
611
733
|
async closeAllConnections() {
|
|
612
734
|
const ids = Object.keys(this.mcpConnections);
|
|
735
|
+
this._pendingConnections.clear();
|
|
613
736
|
for (const id of ids) this.mcpConnections[id].cancelDiscovery();
|
|
614
737
|
await Promise.all(ids.map(async (id) => {
|
|
615
738
|
await this.mcpConnections[id].client.close();
|
|
@@ -628,6 +751,7 @@ var MCPClientManager = class {
|
|
|
628
751
|
async closeConnection(id) {
|
|
629
752
|
if (!this.mcpConnections[id]) throw new Error(`Connection with id "${id}" does not exist.`);
|
|
630
753
|
this.mcpConnections[id].cancelDiscovery();
|
|
754
|
+
this._pendingConnections.delete(id);
|
|
631
755
|
await this.mcpConnections[id].client.close();
|
|
632
756
|
delete this.mcpConnections[id];
|
|
633
757
|
const store = this._connectionDisposables.get(id);
|
|
@@ -683,9 +807,10 @@ var MCPClientManager = class {
|
|
|
683
807
|
* Namespaced version of callTool
|
|
684
808
|
*/
|
|
685
809
|
async callTool(params, resultSchema, options) {
|
|
686
|
-
const
|
|
687
|
-
|
|
688
|
-
|
|
810
|
+
const { serverId, ...mcpParams } = params;
|
|
811
|
+
const unqualifiedName = mcpParams.name.replace(`${serverId}.`, "");
|
|
812
|
+
return this.mcpConnections[serverId].client.callTool({
|
|
813
|
+
...mcpParams,
|
|
689
814
|
name: unqualifiedName
|
|
690
815
|
}, resultSchema, options);
|
|
691
816
|
}
|