agents 0.0.0-197e86a → 0.0.0-1bd0c75
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/README.md +129 -7
- package/dist/_esm-LV5FJ3HK.js +3922 -0
- package/dist/_esm-LV5FJ3HK.js.map +1 -0
- package/dist/ai-chat-agent.d.ts +10 -8
- package/dist/ai-chat-agent.js +444 -60
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-chat-v5-migration.d.ts +152 -0
- package/dist/ai-chat-v5-migration.js +20 -0
- package/dist/ai-chat-v5-migration.js.map +1 -0
- package/dist/ai-react.d.ts +66 -70
- package/dist/ai-react.js +252 -99
- package/dist/ai-react.js.map +1 -1
- package/dist/ai-types.d.ts +37 -19
- package/dist/ai-types.js +7 -0
- package/dist/ccip-CMBYN64O.js +15 -0
- package/dist/ccip-CMBYN64O.js.map +1 -0
- package/dist/chunk-5Y6BEZDY.js +276 -0
- package/dist/chunk-5Y6BEZDY.js.map +1 -0
- package/dist/chunk-BER7KXUJ.js +18 -0
- package/dist/chunk-BER7KXUJ.js.map +1 -0
- package/dist/{chunk-PVQZBKN7.js → chunk-C2OEBJZ2.js} +14 -7
- package/dist/chunk-C2OEBJZ2.js.map +1 -0
- package/dist/chunk-JJBFIGUC.js +5202 -0
- package/dist/chunk-JJBFIGUC.js.map +1 -0
- package/dist/chunk-PR4QN5HX.js +43 -0
- package/dist/chunk-PR4QN5HX.js.map +1 -0
- package/dist/{chunk-KUH345EY.js → chunk-QEVM4BVL.js} +5 -5
- package/dist/chunk-QEVM4BVL.js.map +1 -0
- package/dist/chunk-TYAY6AU6.js +159 -0
- package/dist/chunk-TYAY6AU6.js.map +1 -0
- package/dist/chunk-UJVEAURM.js +150 -0
- package/dist/chunk-UJVEAURM.js.map +1 -0
- package/dist/{chunk-JXN5WZFQ.js → chunk-XGMKNUJA.js} +173 -117
- package/dist/chunk-XGMKNUJA.js.map +1 -0
- package/dist/{chunk-HY7ZLHJB.js → chunk-ZMMHNOMZ.js} +415 -71
- package/dist/chunk-ZMMHNOMZ.js.map +1 -0
- package/dist/{client-DgyzBU_8.d.ts → client-DVoPb3-C.d.ts} +555 -36
- package/dist/client.js +3 -1
- package/dist/codemode/ai.d.ts +25 -0
- package/dist/codemode/ai.js +5109 -0
- package/dist/codemode/ai.js.map +1 -0
- package/dist/index.d.ts +548 -32
- package/dist/index.js +8 -4
- package/dist/mcp/client.d.ts +2 -1
- package/dist/mcp/client.js +2 -1
- package/dist/mcp/do-oauth-client-provider.d.ts +1 -0
- package/dist/mcp/do-oauth-client-provider.js +2 -1
- package/dist/mcp/index.d.ts +50 -83
- package/dist/mcp/index.js +904 -760
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/x402.d.ts +39 -0
- package/dist/mcp/x402.js +3195 -0
- package/dist/mcp/x402.js.map +1 -0
- package/dist/mcp-BH1fJeiU.d.ts +58 -0
- package/dist/observability/index.d.ts +34 -14
- package/dist/observability/index.js +6 -4
- package/dist/react.d.ts +13 -7
- package/dist/react.js +107 -7
- package/dist/react.js.map +1 -1
- package/dist/schedule.d.ts +79 -5
- package/dist/schedule.js +17 -2
- package/dist/schedule.js.map +1 -1
- package/dist/secp256k1-M22GZP2U.js +2193 -0
- package/dist/secp256k1-M22GZP2U.js.map +1 -0
- package/package.json +30 -7
- package/src/index.ts +251 -137
- package/dist/chunk-HY7ZLHJB.js.map +0 -1
- package/dist/chunk-JXN5WZFQ.js.map +0 -1
- package/dist/chunk-KUH345EY.js.map +0 -1
- package/dist/chunk-PVQZBKN7.js.map +0 -1
- package/dist/index-BCJclX6q.d.ts +0 -615
|
@@ -1,15 +1,72 @@
|
|
|
1
1
|
// src/mcp/client.ts
|
|
2
2
|
import { jsonSchema } from "ai";
|
|
3
|
-
import { nanoid } from "nanoid";
|
|
3
|
+
import { nanoid as nanoid2 } from "nanoid";
|
|
4
|
+
|
|
5
|
+
// src/core/events.ts
|
|
6
|
+
function toDisposable(fn) {
|
|
7
|
+
return { dispose: fn };
|
|
8
|
+
}
|
|
9
|
+
var DisposableStore = class {
|
|
10
|
+
constructor() {
|
|
11
|
+
this._items = [];
|
|
12
|
+
}
|
|
13
|
+
add(d) {
|
|
14
|
+
this._items.push(d);
|
|
15
|
+
return d;
|
|
16
|
+
}
|
|
17
|
+
dispose() {
|
|
18
|
+
while (this._items.length) {
|
|
19
|
+
try {
|
|
20
|
+
this._items.pop().dispose();
|
|
21
|
+
} catch {
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var Emitter = class {
|
|
27
|
+
constructor() {
|
|
28
|
+
this._listeners = /* @__PURE__ */ new Set();
|
|
29
|
+
this.event = (listener) => {
|
|
30
|
+
this._listeners.add(listener);
|
|
31
|
+
return toDisposable(() => this._listeners.delete(listener));
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
fire(data) {
|
|
35
|
+
for (const listener of [...this._listeners]) {
|
|
36
|
+
try {
|
|
37
|
+
listener(data);
|
|
38
|
+
} catch (err) {
|
|
39
|
+
console.error("Emitter listener error:", err);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
dispose() {
|
|
44
|
+
this._listeners.clear();
|
|
45
|
+
}
|
|
46
|
+
};
|
|
4
47
|
|
|
5
48
|
// src/mcp/client-connection.ts
|
|
6
49
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
7
50
|
import {
|
|
51
|
+
ElicitRequestSchema,
|
|
8
52
|
PromptListChangedNotificationSchema,
|
|
9
53
|
ResourceListChangedNotificationSchema,
|
|
10
|
-
ToolListChangedNotificationSchema
|
|
11
|
-
ElicitRequestSchema
|
|
54
|
+
ToolListChangedNotificationSchema
|
|
12
55
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
56
|
+
import { nanoid } from "nanoid";
|
|
57
|
+
|
|
58
|
+
// src/mcp/errors.ts
|
|
59
|
+
function toErrorMessage(error) {
|
|
60
|
+
return error instanceof Error ? error.message : String(error);
|
|
61
|
+
}
|
|
62
|
+
function isUnauthorized(error) {
|
|
63
|
+
const msg = toErrorMessage(error);
|
|
64
|
+
return msg.includes("Unauthorized") || msg.includes("401");
|
|
65
|
+
}
|
|
66
|
+
function isTransportNotImplemented(error) {
|
|
67
|
+
const msg = toErrorMessage(error);
|
|
68
|
+
return msg.includes("404") || msg.includes("405") || msg.includes("Not Implemented") || msg.includes("not implemented");
|
|
69
|
+
}
|
|
13
70
|
|
|
14
71
|
// src/mcp/sse-edge.ts
|
|
15
72
|
import {
|
|
@@ -118,6 +175,8 @@ var MCPClientConnection = class {
|
|
|
118
175
|
this.prompts = [];
|
|
119
176
|
this.resources = [];
|
|
120
177
|
this.resourceTemplates = [];
|
|
178
|
+
this._onObservabilityEvent = new Emitter();
|
|
179
|
+
this.onObservabilityEvent = this._onObservabilityEvent.event;
|
|
121
180
|
const clientOptions = {
|
|
122
181
|
...options.client,
|
|
123
182
|
capabilities: {
|
|
@@ -130,23 +189,112 @@ var MCPClientConnection = class {
|
|
|
130
189
|
/**
|
|
131
190
|
* Initialize a client connection
|
|
132
191
|
*
|
|
133
|
-
* @param code Optional OAuth code to initialize the connection with if auth hasn't been initialized
|
|
134
192
|
* @returns
|
|
135
193
|
*/
|
|
136
|
-
async init(
|
|
194
|
+
async init() {
|
|
195
|
+
const transportType = this.options.transport.type;
|
|
196
|
+
if (!transportType) {
|
|
197
|
+
throw new Error("Transport type must be specified");
|
|
198
|
+
}
|
|
137
199
|
try {
|
|
138
|
-
|
|
139
|
-
await this.tryConnect(transportType, code);
|
|
200
|
+
await this.tryConnect(transportType);
|
|
140
201
|
} catch (e) {
|
|
141
|
-
if (e
|
|
202
|
+
if (isUnauthorized(e)) {
|
|
142
203
|
this.connectionState = "authenticating";
|
|
143
204
|
return;
|
|
144
205
|
}
|
|
206
|
+
this._onObservabilityEvent.fire({
|
|
207
|
+
type: "mcp:client:connect",
|
|
208
|
+
displayMessage: `Connection initialization failed for ${this.url.toString()}`,
|
|
209
|
+
payload: {
|
|
210
|
+
url: this.url.toString(),
|
|
211
|
+
transport: transportType,
|
|
212
|
+
state: this.connectionState,
|
|
213
|
+
error: toErrorMessage(e)
|
|
214
|
+
},
|
|
215
|
+
timestamp: Date.now(),
|
|
216
|
+
id: nanoid()
|
|
217
|
+
});
|
|
145
218
|
this.connectionState = "failed";
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
await this.discoverAndRegister();
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Finish OAuth by probing transports based on configured type.
|
|
225
|
+
* - Explicit: finish on that transport
|
|
226
|
+
* - Auto: try streamable-http, then sse on 404/405/Not Implemented
|
|
227
|
+
*/
|
|
228
|
+
async finishAuthProbe(code) {
|
|
229
|
+
if (!this.options.transport.authProvider) {
|
|
230
|
+
throw new Error("No auth provider configured");
|
|
231
|
+
}
|
|
232
|
+
const configuredType = this.options.transport.type;
|
|
233
|
+
if (!configuredType) {
|
|
234
|
+
throw new Error("Transport type must be specified");
|
|
235
|
+
}
|
|
236
|
+
const finishAuth = async (base) => {
|
|
237
|
+
const transport = this.getTransport(base);
|
|
238
|
+
await transport.finishAuth(code);
|
|
239
|
+
};
|
|
240
|
+
if (configuredType === "sse" || configuredType === "streamable-http") {
|
|
241
|
+
await finishAuth(configuredType);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
try {
|
|
245
|
+
await finishAuth("streamable-http");
|
|
246
|
+
} catch (e) {
|
|
247
|
+
if (isTransportNotImplemented(e)) {
|
|
248
|
+
await finishAuth("sse");
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
146
251
|
throw e;
|
|
147
252
|
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Complete OAuth authorization
|
|
256
|
+
*/
|
|
257
|
+
async completeAuthorization(code) {
|
|
258
|
+
if (this.connectionState !== "authenticating") {
|
|
259
|
+
throw new Error(
|
|
260
|
+
"Connection must be in authenticating state to complete authorization"
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
try {
|
|
264
|
+
await this.finishAuthProbe(code);
|
|
265
|
+
this.connectionState = "connecting";
|
|
266
|
+
} catch (error) {
|
|
267
|
+
this.connectionState = "failed";
|
|
268
|
+
throw error;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Establish connection after successful authorization
|
|
273
|
+
*/
|
|
274
|
+
async establishConnection() {
|
|
275
|
+
if (this.connectionState !== "connecting") {
|
|
276
|
+
throw new Error(
|
|
277
|
+
"Connection must be in connecting state to establish connection"
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
try {
|
|
281
|
+
const transportType = this.options.transport.type;
|
|
282
|
+
if (!transportType) {
|
|
283
|
+
throw new Error("Transport type must be specified");
|
|
284
|
+
}
|
|
285
|
+
await this.tryConnect(transportType);
|
|
286
|
+
await this.discoverAndRegister();
|
|
287
|
+
} catch (error) {
|
|
288
|
+
this.connectionState = "failed";
|
|
289
|
+
throw error;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Discover server capabilities and register tools, resources, prompts, and templates
|
|
294
|
+
*/
|
|
295
|
+
async discoverAndRegister() {
|
|
148
296
|
this.connectionState = "discovering";
|
|
149
|
-
this.serverCapabilities =
|
|
297
|
+
this.serverCapabilities = this.client.getServerCapabilities();
|
|
150
298
|
if (!this.serverCapabilities) {
|
|
151
299
|
throw new Error("The MCP Server failed to return server capabilities");
|
|
152
300
|
}
|
|
@@ -172,7 +320,18 @@ var MCPClientConnection = class {
|
|
|
172
320
|
];
|
|
173
321
|
for (const { name, result } of operations) {
|
|
174
322
|
if (result.status === "rejected") {
|
|
175
|
-
|
|
323
|
+
const url = this.url.toString();
|
|
324
|
+
this._onObservabilityEvent.fire({
|
|
325
|
+
type: "mcp:client:discover",
|
|
326
|
+
displayMessage: `Failed to discover ${name} for ${url}`,
|
|
327
|
+
payload: {
|
|
328
|
+
url,
|
|
329
|
+
capability: name,
|
|
330
|
+
error: result.reason
|
|
331
|
+
},
|
|
332
|
+
timestamp: Date.now(),
|
|
333
|
+
id: nanoid()
|
|
334
|
+
});
|
|
176
335
|
}
|
|
177
336
|
}
|
|
178
337
|
this.instructions = instructionsResult.status === "fulfilled" ? instructionsResult.value : void 0;
|
|
@@ -239,7 +398,7 @@ var MCPClientConnection = class {
|
|
|
239
398
|
do {
|
|
240
399
|
toolsResult = await this.client.listTools({
|
|
241
400
|
cursor: toolsResult.nextCursor
|
|
242
|
-
}).catch(
|
|
401
|
+
}).catch(this._capabilityErrorHandler({ tools: [] }, "tools/list"));
|
|
243
402
|
toolsAgg = toolsAgg.concat(toolsResult.tools);
|
|
244
403
|
} while (toolsResult.nextCursor);
|
|
245
404
|
return toolsAgg;
|
|
@@ -250,7 +409,9 @@ var MCPClientConnection = class {
|
|
|
250
409
|
do {
|
|
251
410
|
resourcesResult = await this.client.listResources({
|
|
252
411
|
cursor: resourcesResult.nextCursor
|
|
253
|
-
}).catch(
|
|
412
|
+
}).catch(
|
|
413
|
+
this._capabilityErrorHandler({ resources: [] }, "resources/list")
|
|
414
|
+
);
|
|
254
415
|
resourcesAgg = resourcesAgg.concat(resourcesResult.resources);
|
|
255
416
|
} while (resourcesResult.nextCursor);
|
|
256
417
|
return resourcesAgg;
|
|
@@ -261,7 +422,7 @@ var MCPClientConnection = class {
|
|
|
261
422
|
do {
|
|
262
423
|
promptsResult = await this.client.listPrompts({
|
|
263
424
|
cursor: promptsResult.nextCursor
|
|
264
|
-
}).catch(
|
|
425
|
+
}).catch(this._capabilityErrorHandler({ prompts: [] }, "prompts/list"));
|
|
265
426
|
promptsAgg = promptsAgg.concat(promptsResult.prompts);
|
|
266
427
|
} while (promptsResult.nextCursor);
|
|
267
428
|
return promptsAgg;
|
|
@@ -275,7 +436,7 @@ var MCPClientConnection = class {
|
|
|
275
436
|
templatesResult = await this.client.listResourceTemplates({
|
|
276
437
|
cursor: templatesResult.nextCursor
|
|
277
438
|
}).catch(
|
|
278
|
-
|
|
439
|
+
this._capabilityErrorHandler(
|
|
279
440
|
{ resourceTemplates: [] },
|
|
280
441
|
"resources/templates/list"
|
|
281
442
|
)
|
|
@@ -314,21 +475,46 @@ var MCPClientConnection = class {
|
|
|
314
475
|
throw new Error(`Unsupported transport type: ${transportType}`);
|
|
315
476
|
}
|
|
316
477
|
}
|
|
317
|
-
async tryConnect(transportType
|
|
478
|
+
async tryConnect(transportType) {
|
|
318
479
|
const transports = transportType === "auto" ? ["streamable-http", "sse"] : [transportType];
|
|
319
480
|
for (const currentTransportType of transports) {
|
|
320
481
|
const isLastTransport = currentTransportType === transports[transports.length - 1];
|
|
321
482
|
const hasFallback = transportType === "auto" && currentTransportType === "streamable-http" && !isLastTransport;
|
|
322
|
-
const transport =
|
|
323
|
-
if (code) {
|
|
324
|
-
await transport.finishAuth(code);
|
|
325
|
-
}
|
|
483
|
+
const transport = this.getTransport(currentTransportType);
|
|
326
484
|
try {
|
|
327
485
|
await this.client.connect(transport);
|
|
486
|
+
this.lastConnectedTransport = currentTransportType;
|
|
487
|
+
const url = this.url.toString();
|
|
488
|
+
this._onObservabilityEvent.fire({
|
|
489
|
+
type: "mcp:client:connect",
|
|
490
|
+
displayMessage: `Connected successfully using ${currentTransportType} transport for ${url}`,
|
|
491
|
+
payload: {
|
|
492
|
+
url,
|
|
493
|
+
transport: currentTransportType,
|
|
494
|
+
state: this.connectionState
|
|
495
|
+
},
|
|
496
|
+
timestamp: Date.now(),
|
|
497
|
+
id: nanoid()
|
|
498
|
+
});
|
|
328
499
|
break;
|
|
329
500
|
} catch (e) {
|
|
330
501
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
331
|
-
if (
|
|
502
|
+
if (isUnauthorized(error)) {
|
|
503
|
+
throw e;
|
|
504
|
+
}
|
|
505
|
+
if (hasFallback && isTransportNotImplemented(error)) {
|
|
506
|
+
const url = this.url.toString();
|
|
507
|
+
this._onObservabilityEvent.fire({
|
|
508
|
+
type: "mcp:client:connect",
|
|
509
|
+
displayMessage: `${currentTransportType} transport not available, trying ${transports[transports.indexOf(currentTransportType) + 1]} for ${url}`,
|
|
510
|
+
payload: {
|
|
511
|
+
url,
|
|
512
|
+
transport: currentTransportType,
|
|
513
|
+
state: this.connectionState
|
|
514
|
+
},
|
|
515
|
+
timestamp: Date.now(),
|
|
516
|
+
id: nanoid()
|
|
517
|
+
});
|
|
332
518
|
continue;
|
|
333
519
|
}
|
|
334
520
|
throw e;
|
|
@@ -341,18 +527,27 @@ var MCPClientConnection = class {
|
|
|
341
527
|
}
|
|
342
528
|
);
|
|
343
529
|
}
|
|
530
|
+
_capabilityErrorHandler(empty, method) {
|
|
531
|
+
return (e) => {
|
|
532
|
+
if (e.code === -32601) {
|
|
533
|
+
const url = this.url.toString();
|
|
534
|
+
this._onObservabilityEvent.fire({
|
|
535
|
+
type: "mcp:client:discover",
|
|
536
|
+
displayMessage: `The server advertised support for the capability ${method.split("/")[0]}, but returned "Method not found" for '${method}' for ${url}`,
|
|
537
|
+
payload: {
|
|
538
|
+
url,
|
|
539
|
+
capability: method.split("/")[0],
|
|
540
|
+
error: toErrorMessage(e)
|
|
541
|
+
},
|
|
542
|
+
timestamp: Date.now(),
|
|
543
|
+
id: nanoid()
|
|
544
|
+
});
|
|
545
|
+
return empty;
|
|
546
|
+
}
|
|
547
|
+
throw e;
|
|
548
|
+
};
|
|
549
|
+
}
|
|
344
550
|
};
|
|
345
|
-
function capabilityErrorHandler(empty, method) {
|
|
346
|
-
return (e) => {
|
|
347
|
-
if (e.code === -32601) {
|
|
348
|
-
console.error(
|
|
349
|
-
`The server advertised support for the capability ${method.split("/")[0]}, but returned "Method not found" for '${method}'.`
|
|
350
|
-
);
|
|
351
|
-
return empty;
|
|
352
|
-
}
|
|
353
|
-
throw e;
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
551
|
|
|
357
552
|
// src/mcp/client.ts
|
|
358
553
|
var MCPClientManager = class {
|
|
@@ -366,6 +561,12 @@ var MCPClientManager = class {
|
|
|
366
561
|
this._version = _version;
|
|
367
562
|
this.mcpConnections = {};
|
|
368
563
|
this._callbackUrls = [];
|
|
564
|
+
this._didWarnAboutUnstableGetAITools = false;
|
|
565
|
+
this._connectionDisposables = /* @__PURE__ */ new Map();
|
|
566
|
+
this._onObservabilityEvent = new Emitter();
|
|
567
|
+
this.onObservabilityEvent = this._onObservabilityEvent.event;
|
|
568
|
+
this._onConnected = new Emitter();
|
|
569
|
+
this.onConnected = this._onConnected.event;
|
|
369
570
|
}
|
|
370
571
|
/**
|
|
371
572
|
* Connect to and register an MCP server
|
|
@@ -375,31 +576,64 @@ var MCPClientManager = class {
|
|
|
375
576
|
* @param capabilities Client capabilities (i.e. if the client supports roots/sampling)
|
|
376
577
|
*/
|
|
377
578
|
async connect(url, options = {}) {
|
|
378
|
-
const id = options.reconnect?.id ??
|
|
379
|
-
if (
|
|
380
|
-
console.warn(
|
|
381
|
-
"No authProvider provided in the transport options. This client will only support unauthenticated remote MCP Servers"
|
|
382
|
-
);
|
|
383
|
-
} else {
|
|
579
|
+
const id = options.reconnect?.id ?? nanoid2(8);
|
|
580
|
+
if (options.transport?.authProvider) {
|
|
384
581
|
options.transport.authProvider.serverId = id;
|
|
385
582
|
if (options.reconnect?.oauthClientId) {
|
|
386
583
|
options.transport.authProvider.clientId = options.reconnect?.oauthClientId;
|
|
387
584
|
}
|
|
388
585
|
}
|
|
389
|
-
this.mcpConnections[id]
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
586
|
+
if (!options.reconnect?.oauthCode || !this.mcpConnections[id]) {
|
|
587
|
+
const normalizedTransport = {
|
|
588
|
+
...options.transport,
|
|
589
|
+
type: options.transport?.type ?? "auto"
|
|
590
|
+
};
|
|
591
|
+
this.mcpConnections[id] = new MCPClientConnection(
|
|
592
|
+
new URL(url),
|
|
593
|
+
{
|
|
594
|
+
name: this._name,
|
|
595
|
+
version: this._version
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
client: options.client ?? {},
|
|
599
|
+
transport: normalizedTransport
|
|
600
|
+
}
|
|
601
|
+
);
|
|
602
|
+
const store = new DisposableStore();
|
|
603
|
+
const existing = this._connectionDisposables.get(id);
|
|
604
|
+
if (existing) existing.dispose();
|
|
605
|
+
this._connectionDisposables.set(id, store);
|
|
606
|
+
store.add(
|
|
607
|
+
this.mcpConnections[id].onObservabilityEvent((event) => {
|
|
608
|
+
this._onObservabilityEvent.fire(event);
|
|
609
|
+
})
|
|
610
|
+
);
|
|
611
|
+
}
|
|
612
|
+
await this.mcpConnections[id].init();
|
|
613
|
+
if (options.reconnect?.oauthCode) {
|
|
614
|
+
try {
|
|
615
|
+
await this.mcpConnections[id].completeAuthorization(
|
|
616
|
+
options.reconnect.oauthCode
|
|
617
|
+
);
|
|
618
|
+
await this.mcpConnections[id].establishConnection();
|
|
619
|
+
} catch (error) {
|
|
620
|
+
this._onObservabilityEvent.fire({
|
|
621
|
+
type: "mcp:client:connect",
|
|
622
|
+
displayMessage: `Failed to complete OAuth reconnection for ${id} for ${url}`,
|
|
623
|
+
payload: {
|
|
624
|
+
url,
|
|
625
|
+
transport: options.transport?.type ?? "auto",
|
|
626
|
+
state: this.mcpConnections[id].connectionState,
|
|
627
|
+
error: toErrorMessage(error)
|
|
628
|
+
},
|
|
629
|
+
timestamp: Date.now(),
|
|
630
|
+
id
|
|
631
|
+
});
|
|
632
|
+
throw error;
|
|
398
633
|
}
|
|
399
|
-
|
|
400
|
-
await this.mcpConnections[id].init(options.reconnect?.oauthCode);
|
|
634
|
+
}
|
|
401
635
|
const authUrl = options.transport?.authProvider?.authUrl;
|
|
402
|
-
if (authUrl && options.transport?.authProvider?.redirectUrl) {
|
|
636
|
+
if (this.mcpConnections[id].connectionState === "authenticating" && authUrl && options.transport?.authProvider?.redirectUrl) {
|
|
403
637
|
this._callbackUrls.push(
|
|
404
638
|
options.transport.authProvider.redirectUrl.toString()
|
|
405
639
|
);
|
|
@@ -429,13 +663,13 @@ var MCPClientManager = class {
|
|
|
429
663
|
);
|
|
430
664
|
}
|
|
431
665
|
const code = url.searchParams.get("code");
|
|
432
|
-
const
|
|
666
|
+
const state = url.searchParams.get("state");
|
|
433
667
|
const urlParams = urlMatch.split("/");
|
|
434
668
|
const serverId = urlParams[urlParams.length - 1];
|
|
435
669
|
if (!code) {
|
|
436
670
|
throw new Error("Unauthorized: no code provided");
|
|
437
671
|
}
|
|
438
|
-
if (!
|
|
672
|
+
if (!state) {
|
|
439
673
|
throw new Error("Unauthorized: no state provided");
|
|
440
674
|
}
|
|
441
675
|
if (this.mcpConnections[serverId] === void 0) {
|
|
@@ -452,21 +686,91 @@ var MCPClientManager = class {
|
|
|
452
686
|
"Trying to finalize authentication for a server connection without an authProvider"
|
|
453
687
|
);
|
|
454
688
|
}
|
|
689
|
+
const clientId = conn.options.transport.authProvider.clientId || state;
|
|
455
690
|
conn.options.transport.authProvider.clientId = clientId;
|
|
456
691
|
conn.options.transport.authProvider.serverId = serverId;
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
692
|
+
try {
|
|
693
|
+
await conn.completeAuthorization(code);
|
|
694
|
+
return {
|
|
695
|
+
serverId,
|
|
696
|
+
authSuccess: true
|
|
697
|
+
};
|
|
698
|
+
} catch (error) {
|
|
699
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
700
|
+
return {
|
|
701
|
+
serverId,
|
|
702
|
+
authSuccess: false,
|
|
703
|
+
authError: errorMessage
|
|
704
|
+
};
|
|
468
705
|
}
|
|
469
|
-
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Establish connection in the background after OAuth completion
|
|
709
|
+
* This method is called asynchronously and doesn't block the OAuth callback response
|
|
710
|
+
* @param serverId The server ID to establish connection for
|
|
711
|
+
*/
|
|
712
|
+
async establishConnection(serverId) {
|
|
713
|
+
const conn = this.mcpConnections[serverId];
|
|
714
|
+
if (!conn) {
|
|
715
|
+
this._onObservabilityEvent.fire({
|
|
716
|
+
type: "mcp:client:preconnect",
|
|
717
|
+
displayMessage: `Connection not found for serverId: ${serverId}`,
|
|
718
|
+
payload: { serverId },
|
|
719
|
+
timestamp: Date.now(),
|
|
720
|
+
id: nanoid2()
|
|
721
|
+
});
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
try {
|
|
725
|
+
await conn.establishConnection();
|
|
726
|
+
this._onConnected.fire(serverId);
|
|
727
|
+
} catch (error) {
|
|
728
|
+
const url = conn.url.toString();
|
|
729
|
+
this._onObservabilityEvent.fire({
|
|
730
|
+
type: "mcp:client:connect",
|
|
731
|
+
displayMessage: `Failed to establish connection to server ${serverId} with url ${url}`,
|
|
732
|
+
payload: {
|
|
733
|
+
url,
|
|
734
|
+
transport: conn.options.transport.type ?? "auto",
|
|
735
|
+
state: conn.connectionState,
|
|
736
|
+
error: toErrorMessage(error)
|
|
737
|
+
},
|
|
738
|
+
timestamp: Date.now(),
|
|
739
|
+
id: nanoid2()
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Register a callback URL for OAuth handling
|
|
745
|
+
* @param url The callback URL to register
|
|
746
|
+
*/
|
|
747
|
+
registerCallbackUrl(url) {
|
|
748
|
+
if (!this._callbackUrls.includes(url)) {
|
|
749
|
+
this._callbackUrls.push(url);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* Unregister a callback URL
|
|
754
|
+
* @param serverId The server ID whose callback URL should be removed
|
|
755
|
+
*/
|
|
756
|
+
unregisterCallbackUrl(serverId) {
|
|
757
|
+
this._callbackUrls = this._callbackUrls.filter(
|
|
758
|
+
(url) => !url.endsWith(`/${serverId}`)
|
|
759
|
+
);
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Configure OAuth callback handling
|
|
763
|
+
* @param config OAuth callback configuration
|
|
764
|
+
*/
|
|
765
|
+
configureOAuthCallback(config) {
|
|
766
|
+
this._oauthCallbackConfig = config;
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Get the current OAuth callback configuration
|
|
770
|
+
* @returns The current OAuth callback configuration
|
|
771
|
+
*/
|
|
772
|
+
getOAuthCallbackConfig() {
|
|
773
|
+
return this._oauthCallbackConfig;
|
|
470
774
|
}
|
|
471
775
|
/**
|
|
472
776
|
* @returns namespaced list of tools
|
|
@@ -477,11 +781,11 @@ var MCPClientManager = class {
|
|
|
477
781
|
/**
|
|
478
782
|
* @returns a set of tools that you can use with the AI SDK
|
|
479
783
|
*/
|
|
480
|
-
|
|
784
|
+
getAITools() {
|
|
481
785
|
return Object.fromEntries(
|
|
482
786
|
getNamespacedData(this.mcpConnections, "tools").map((tool) => {
|
|
483
787
|
return [
|
|
484
|
-
|
|
788
|
+
`tool_${tool.serverId.replace(/-/g, "")}_${tool.name}`,
|
|
485
789
|
{
|
|
486
790
|
description: tool.description,
|
|
487
791
|
execute: async (args) => {
|
|
@@ -495,21 +799,46 @@ var MCPClientManager = class {
|
|
|
495
799
|
}
|
|
496
800
|
return result;
|
|
497
801
|
},
|
|
498
|
-
|
|
802
|
+
// @ts-expect-error drift between ai and mcp types
|
|
803
|
+
inputSchema: jsonSchema(tool.inputSchema),
|
|
804
|
+
outputSchema: tool.outputSchema ? (
|
|
805
|
+
// @ts-expect-error drift between ai and mcp types
|
|
806
|
+
jsonSchema(tool.outputSchema)
|
|
807
|
+
) : void 0
|
|
499
808
|
}
|
|
500
809
|
];
|
|
501
810
|
})
|
|
502
811
|
);
|
|
503
812
|
}
|
|
813
|
+
/**
|
|
814
|
+
* @deprecated this has been renamed to getAITools(), and unstable_getAITools will be removed in the next major version
|
|
815
|
+
* @returns a set of tools that you can use with the AI SDK
|
|
816
|
+
*/
|
|
817
|
+
unstable_getAITools() {
|
|
818
|
+
if (!this._didWarnAboutUnstableGetAITools) {
|
|
819
|
+
this._didWarnAboutUnstableGetAITools = true;
|
|
820
|
+
console.warn(
|
|
821
|
+
"unstable_getAITools is deprecated, use getAITools instead. unstable_getAITools will be removed in the next major version."
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
return this.getAITools();
|
|
825
|
+
}
|
|
504
826
|
/**
|
|
505
827
|
* Closes all connections to MCP servers
|
|
506
828
|
*/
|
|
507
829
|
async closeAllConnections() {
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
830
|
+
const ids = Object.keys(this.mcpConnections);
|
|
831
|
+
await Promise.all(
|
|
832
|
+
ids.map(async (id) => {
|
|
833
|
+
await this.mcpConnections[id].client.close();
|
|
511
834
|
})
|
|
512
835
|
);
|
|
836
|
+
for (const id of ids) {
|
|
837
|
+
const store = this._connectionDisposables.get(id);
|
|
838
|
+
if (store) store.dispose();
|
|
839
|
+
this._connectionDisposables.delete(id);
|
|
840
|
+
delete this.mcpConnections[id];
|
|
841
|
+
}
|
|
513
842
|
}
|
|
514
843
|
/**
|
|
515
844
|
* Closes a connection to an MCP server
|
|
@@ -521,6 +850,20 @@ var MCPClientManager = class {
|
|
|
521
850
|
}
|
|
522
851
|
await this.mcpConnections[id].client.close();
|
|
523
852
|
delete this.mcpConnections[id];
|
|
853
|
+
const store = this._connectionDisposables.get(id);
|
|
854
|
+
if (store) store.dispose();
|
|
855
|
+
this._connectionDisposables.delete(id);
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* Dispose the manager and all resources.
|
|
859
|
+
*/
|
|
860
|
+
async dispose() {
|
|
861
|
+
try {
|
|
862
|
+
await this.closeAllConnections();
|
|
863
|
+
} finally {
|
|
864
|
+
this._onConnected.dispose();
|
|
865
|
+
this._onObservabilityEvent.dispose();
|
|
866
|
+
}
|
|
524
867
|
}
|
|
525
868
|
/**
|
|
526
869
|
* @returns namespaced list of prompts
|
|
@@ -543,7 +886,7 @@ var MCPClientManager = class {
|
|
|
543
886
|
/**
|
|
544
887
|
* Namespaced version of callTool
|
|
545
888
|
*/
|
|
546
|
-
callTool(params, resultSchema, options) {
|
|
889
|
+
async callTool(params, resultSchema, options) {
|
|
547
890
|
const unqualifiedName = params.name.replace(`${params.serverId}.`, "");
|
|
548
891
|
return this.mcpConnections[params.serverId].client.callTool(
|
|
549
892
|
{
|
|
@@ -590,9 +933,10 @@ function getNamespacedData(mcpClients, type) {
|
|
|
590
933
|
}
|
|
591
934
|
|
|
592
935
|
export {
|
|
936
|
+
DisposableStore,
|
|
593
937
|
SSEEdgeClientTransport,
|
|
594
938
|
StreamableHTTPEdgeClientTransport,
|
|
595
939
|
MCPClientManager,
|
|
596
940
|
getNamespacedData
|
|
597
941
|
};
|
|
598
|
-
//# sourceMappingURL=chunk-
|
|
942
|
+
//# sourceMappingURL=chunk-ZMMHNOMZ.js.map
|