@ai-sdk/mcp 2.0.0-beta.3 → 2.0.0-beta.30

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/index.mjs DELETED
@@ -1,2128 +0,0 @@
1
- // src/tool/mcp-client.ts
2
- import {
3
- asSchema,
4
- dynamicTool,
5
- jsonSchema,
6
- safeParseJSON,
7
- safeValidateTypes,
8
- tool
9
- } from "@ai-sdk/provider-utils";
10
-
11
- // src/error/mcp-client-error.ts
12
- import { AISDKError } from "@ai-sdk/provider";
13
- var name = "AI_MCPClientError";
14
- var marker = `vercel.ai.error.${name}`;
15
- var symbol = Symbol.for(marker);
16
- var _a, _b;
17
- var MCPClientError = class extends (_b = AISDKError, _a = symbol, _b) {
18
- constructor({
19
- name: name3 = "MCPClientError",
20
- message,
21
- cause,
22
- data,
23
- code
24
- }) {
25
- super({ name: name3, message, cause });
26
- this[_a] = true;
27
- this.data = data;
28
- this.code = code;
29
- }
30
- static isInstance(error) {
31
- return AISDKError.hasMarker(error, marker);
32
- }
33
- };
34
-
35
- // src/tool/mcp-sse-transport.ts
36
- import {
37
- EventSourceParserStream,
38
- withUserAgentSuffix,
39
- getRuntimeEnvironmentUserAgent
40
- } from "@ai-sdk/provider-utils";
41
-
42
- // src/tool/json-rpc-message.ts
43
- import { z as z2 } from "zod/v4";
44
-
45
- // src/tool/types.ts
46
- import { z } from "zod/v4";
47
- var LATEST_PROTOCOL_VERSION = "2025-11-25";
48
- var SUPPORTED_PROTOCOL_VERSIONS = [
49
- LATEST_PROTOCOL_VERSION,
50
- "2025-06-18",
51
- "2025-03-26",
52
- "2024-11-05"
53
- ];
54
- var ToolMetaSchema = z.optional(z.record(z.string(), z.unknown()));
55
- var ClientOrServerImplementationSchema = z.looseObject({
56
- name: z.string(),
57
- version: z.string()
58
- });
59
- var BaseParamsSchema = z.looseObject({
60
- _meta: z.optional(z.object({}).loose())
61
- });
62
- var ResultSchema = BaseParamsSchema;
63
- var RequestSchema = z.object({
64
- method: z.string(),
65
- params: z.optional(BaseParamsSchema)
66
- });
67
- var ElicitationCapabilitySchema = z.object({
68
- applyDefaults: z.optional(z.boolean())
69
- }).loose();
70
- var ServerCapabilitiesSchema = z.looseObject({
71
- experimental: z.optional(z.object({}).loose()),
72
- logging: z.optional(z.object({}).loose()),
73
- prompts: z.optional(
74
- z.looseObject({
75
- listChanged: z.optional(z.boolean())
76
- })
77
- ),
78
- resources: z.optional(
79
- z.looseObject({
80
- subscribe: z.optional(z.boolean()),
81
- listChanged: z.optional(z.boolean())
82
- })
83
- ),
84
- tools: z.optional(
85
- z.looseObject({
86
- listChanged: z.optional(z.boolean())
87
- })
88
- ),
89
- elicitation: z.optional(ElicitationCapabilitySchema)
90
- });
91
- var ClientCapabilitiesSchema = z.object({
92
- elicitation: z.optional(ElicitationCapabilitySchema)
93
- }).loose();
94
- var InitializeResultSchema = ResultSchema.extend({
95
- protocolVersion: z.string(),
96
- capabilities: ServerCapabilitiesSchema,
97
- serverInfo: ClientOrServerImplementationSchema,
98
- instructions: z.optional(z.string())
99
- });
100
- var PaginatedResultSchema = ResultSchema.extend({
101
- nextCursor: z.optional(z.string())
102
- });
103
- var ToolSchema = z.object({
104
- name: z.string(),
105
- /**
106
- * @see https://modelcontextprotocol.io/specification/2025-11-25/server/tools#tool
107
- */
108
- title: z.optional(z.string()),
109
- description: z.optional(z.string()),
110
- inputSchema: z.object({
111
- type: z.literal("object"),
112
- properties: z.optional(z.object({}).loose())
113
- }).loose(),
114
- /**
115
- * @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools#output-schema
116
- */
117
- outputSchema: z.optional(z.object({}).loose()),
118
- annotations: z.optional(
119
- z.object({
120
- title: z.optional(z.string())
121
- }).loose()
122
- ),
123
- _meta: ToolMetaSchema
124
- }).loose();
125
- var ListToolsResultSchema = PaginatedResultSchema.extend({
126
- tools: z.array(ToolSchema)
127
- });
128
- var TextContentSchema = z.object({
129
- type: z.literal("text"),
130
- text: z.string()
131
- }).loose();
132
- var ImageContentSchema = z.object({
133
- type: z.literal("image"),
134
- data: z.base64(),
135
- mimeType: z.string()
136
- }).loose();
137
- var ResourceSchema = z.object({
138
- uri: z.string(),
139
- name: z.string(),
140
- title: z.optional(z.string()),
141
- description: z.optional(z.string()),
142
- mimeType: z.optional(z.string()),
143
- size: z.optional(z.number())
144
- }).loose();
145
- var ListResourcesResultSchema = PaginatedResultSchema.extend({
146
- resources: z.array(ResourceSchema)
147
- });
148
- var ResourceContentsSchema = z.object({
149
- /**
150
- * The URI of this resource.
151
- */
152
- uri: z.string(),
153
- /**
154
- * Optional display name of the resource content.
155
- */
156
- name: z.optional(z.string()),
157
- /**
158
- * Optional human readable title.
159
- */
160
- title: z.optional(z.string()),
161
- /**
162
- * The MIME type of this resource, if known.
163
- */
164
- mimeType: z.optional(z.string())
165
- }).loose();
166
- var TextResourceContentsSchema = ResourceContentsSchema.extend({
167
- text: z.string()
168
- });
169
- var BlobResourceContentsSchema = ResourceContentsSchema.extend({
170
- blob: z.base64()
171
- });
172
- var EmbeddedResourceSchema = z.object({
173
- type: z.literal("resource"),
174
- resource: z.union([TextResourceContentsSchema, BlobResourceContentsSchema])
175
- }).loose();
176
- var CallToolResultSchema = ResultSchema.extend({
177
- content: z.array(
178
- z.union([TextContentSchema, ImageContentSchema, EmbeddedResourceSchema])
179
- ),
180
- /**
181
- * @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools#structured-content
182
- */
183
- structuredContent: z.optional(z.unknown()),
184
- isError: z.boolean().default(false).optional()
185
- }).or(
186
- ResultSchema.extend({
187
- toolResult: z.unknown()
188
- })
189
- );
190
- var ResourceTemplateSchema = z.object({
191
- uriTemplate: z.string(),
192
- name: z.string(),
193
- title: z.optional(z.string()),
194
- description: z.optional(z.string()),
195
- mimeType: z.optional(z.string())
196
- }).loose();
197
- var ListResourceTemplatesResultSchema = ResultSchema.extend({
198
- resourceTemplates: z.array(ResourceTemplateSchema)
199
- });
200
- var ReadResourceResultSchema = ResultSchema.extend({
201
- contents: z.array(
202
- z.union([TextResourceContentsSchema, BlobResourceContentsSchema])
203
- )
204
- });
205
- var PromptArgumentSchema = z.object({
206
- name: z.string(),
207
- description: z.optional(z.string()),
208
- required: z.optional(z.boolean())
209
- }).loose();
210
- var PromptSchema = z.object({
211
- name: z.string(),
212
- title: z.optional(z.string()),
213
- description: z.optional(z.string()),
214
- arguments: z.optional(z.array(PromptArgumentSchema))
215
- }).loose();
216
- var ListPromptsResultSchema = PaginatedResultSchema.extend({
217
- prompts: z.array(PromptSchema)
218
- });
219
- var PromptMessageSchema = z.object({
220
- role: z.union([z.literal("user"), z.literal("assistant")]),
221
- content: z.union([
222
- TextContentSchema,
223
- ImageContentSchema,
224
- EmbeddedResourceSchema
225
- ])
226
- }).loose();
227
- var GetPromptResultSchema = ResultSchema.extend({
228
- description: z.optional(z.string()),
229
- messages: z.array(PromptMessageSchema)
230
- });
231
- var ElicitationRequestParamsSchema = BaseParamsSchema.extend({
232
- message: z.string(),
233
- requestedSchema: z.unknown()
234
- });
235
- var ElicitationRequestSchema = RequestSchema.extend({
236
- method: z.literal("elicitation/create"),
237
- params: ElicitationRequestParamsSchema
238
- });
239
- var ElicitResultSchema = ResultSchema.extend({
240
- action: z.union([
241
- z.literal("accept"),
242
- z.literal("decline"),
243
- z.literal("cancel")
244
- ]),
245
- content: z.optional(z.record(z.string(), z.unknown()))
246
- });
247
-
248
- // src/tool/json-rpc-message.ts
249
- var JSONRPC_VERSION = "2.0";
250
- var JSONRPCRequestSchema = z2.object({
251
- jsonrpc: z2.literal(JSONRPC_VERSION),
252
- id: z2.union([z2.string(), z2.number().int()])
253
- }).merge(RequestSchema).strict();
254
- var JSONRPCResponseSchema = z2.object({
255
- jsonrpc: z2.literal(JSONRPC_VERSION),
256
- id: z2.union([z2.string(), z2.number().int()]),
257
- result: ResultSchema
258
- }).strict();
259
- var JSONRPCErrorSchema = z2.object({
260
- jsonrpc: z2.literal(JSONRPC_VERSION),
261
- id: z2.union([z2.string(), z2.number().int()]),
262
- error: z2.object({
263
- code: z2.number().int(),
264
- message: z2.string(),
265
- data: z2.optional(z2.unknown())
266
- })
267
- }).strict();
268
- var JSONRPCNotificationSchema = z2.object({
269
- jsonrpc: z2.literal(JSONRPC_VERSION)
270
- }).merge(
271
- z2.object({
272
- method: z2.string(),
273
- params: z2.optional(BaseParamsSchema)
274
- })
275
- ).strict();
276
- var JSONRPCMessageSchema = z2.union([
277
- JSONRPCRequestSchema,
278
- JSONRPCNotificationSchema,
279
- JSONRPCResponseSchema,
280
- JSONRPCErrorSchema
281
- ]);
282
-
283
- // src/version.ts
284
- var VERSION = typeof __PACKAGE_VERSION__ !== "undefined" ? __PACKAGE_VERSION__ : "0.0.0-test";
285
-
286
- // src/tool/oauth.ts
287
- import pkceChallenge from "pkce-challenge";
288
-
289
- // src/tool/oauth-types.ts
290
- import { z as z3 } from "zod/v4";
291
- var OAuthTokensSchema = z3.object({
292
- access_token: z3.string(),
293
- id_token: z3.string().optional(),
294
- // Optional for OAuth 2.1, but necessary in OpenID Connect
295
- token_type: z3.string(),
296
- expires_in: z3.number().optional(),
297
- scope: z3.string().optional(),
298
- refresh_token: z3.string().optional()
299
- }).strip();
300
- var SafeUrlSchema = z3.string().url().superRefine((val, ctx) => {
301
- if (!URL.canParse(val)) {
302
- ctx.addIssue({
303
- code: z3.ZodIssueCode.custom,
304
- message: "URL must be parseable",
305
- fatal: true
306
- });
307
- return z3.NEVER;
308
- }
309
- }).refine(
310
- (url) => {
311
- const u = new URL(url);
312
- return u.protocol !== "javascript:" && u.protocol !== "data:" && u.protocol !== "vbscript:";
313
- },
314
- { message: "URL cannot use javascript:, data:, or vbscript: scheme" }
315
- );
316
- var OAuthProtectedResourceMetadataSchema = z3.object({
317
- resource: z3.string().url(),
318
- authorization_servers: z3.array(SafeUrlSchema).optional(),
319
- jwks_uri: z3.string().url().optional(),
320
- scopes_supported: z3.array(z3.string()).optional(),
321
- bearer_methods_supported: z3.array(z3.string()).optional(),
322
- resource_signing_alg_values_supported: z3.array(z3.string()).optional(),
323
- resource_name: z3.string().optional(),
324
- resource_documentation: z3.string().optional(),
325
- resource_policy_uri: z3.string().url().optional(),
326
- resource_tos_uri: z3.string().url().optional(),
327
- tls_client_certificate_bound_access_tokens: z3.boolean().optional(),
328
- authorization_details_types_supported: z3.array(z3.string()).optional(),
329
- dpop_signing_alg_values_supported: z3.array(z3.string()).optional(),
330
- dpop_bound_access_tokens_required: z3.boolean().optional()
331
- }).passthrough();
332
- var OAuthMetadataSchema = z3.object({
333
- issuer: z3.string(),
334
- authorization_endpoint: SafeUrlSchema,
335
- token_endpoint: SafeUrlSchema,
336
- registration_endpoint: SafeUrlSchema.optional(),
337
- scopes_supported: z3.array(z3.string()).optional(),
338
- response_types_supported: z3.array(z3.string()),
339
- grant_types_supported: z3.array(z3.string()).optional(),
340
- code_challenge_methods_supported: z3.array(z3.string()),
341
- token_endpoint_auth_methods_supported: z3.array(z3.string()).optional(),
342
- token_endpoint_auth_signing_alg_values_supported: z3.array(z3.string()).optional()
343
- }).passthrough();
344
- var OpenIdProviderMetadataSchema = z3.object({
345
- issuer: z3.string(),
346
- authorization_endpoint: SafeUrlSchema,
347
- token_endpoint: SafeUrlSchema,
348
- userinfo_endpoint: SafeUrlSchema.optional(),
349
- jwks_uri: SafeUrlSchema,
350
- registration_endpoint: SafeUrlSchema.optional(),
351
- scopes_supported: z3.array(z3.string()).optional(),
352
- response_types_supported: z3.array(z3.string()),
353
- grant_types_supported: z3.array(z3.string()).optional(),
354
- subject_types_supported: z3.array(z3.string()),
355
- id_token_signing_alg_values_supported: z3.array(z3.string()),
356
- claims_supported: z3.array(z3.string()).optional(),
357
- token_endpoint_auth_methods_supported: z3.array(z3.string()).optional()
358
- }).passthrough();
359
- var OpenIdProviderDiscoveryMetadataSchema = OpenIdProviderMetadataSchema.merge(
360
- OAuthMetadataSchema.pick({
361
- code_challenge_methods_supported: true
362
- })
363
- );
364
- var OAuthClientInformationSchema = z3.object({
365
- client_id: z3.string(),
366
- client_secret: z3.string().optional(),
367
- client_id_issued_at: z3.number().optional(),
368
- client_secret_expires_at: z3.number().optional()
369
- }).strip();
370
- var OAuthClientMetadataSchema = z3.object({
371
- redirect_uris: z3.array(SafeUrlSchema),
372
- token_endpoint_auth_method: z3.string().optional(),
373
- grant_types: z3.array(z3.string()).optional(),
374
- response_types: z3.array(z3.string()).optional(),
375
- client_name: z3.string().optional(),
376
- client_uri: SafeUrlSchema.optional(),
377
- logo_uri: SafeUrlSchema.optional(),
378
- scope: z3.string().optional(),
379
- contacts: z3.array(z3.string()).optional(),
380
- tos_uri: SafeUrlSchema.optional(),
381
- policy_uri: z3.string().optional(),
382
- jwks_uri: SafeUrlSchema.optional(),
383
- jwks: z3.any().optional(),
384
- software_id: z3.string().optional(),
385
- software_version: z3.string().optional(),
386
- software_statement: z3.string().optional()
387
- }).strip();
388
- var OAuthErrorResponseSchema = z3.object({
389
- error: z3.string(),
390
- error_description: z3.string().optional(),
391
- error_uri: z3.string().optional()
392
- });
393
- var OAuthClientInformationFullSchema = OAuthClientMetadataSchema.merge(
394
- OAuthClientInformationSchema
395
- );
396
-
397
- // src/error/oauth-error.ts
398
- import { AISDKError as AISDKError2 } from "@ai-sdk/provider";
399
- var name2 = "AI_MCPClientOAuthError";
400
- var marker2 = `vercel.ai.error.${name2}`;
401
- var symbol2 = Symbol.for(marker2);
402
- var _a2, _b2;
403
- var MCPClientOAuthError = class extends (_b2 = AISDKError2, _a2 = symbol2, _b2) {
404
- constructor({
405
- name: name3 = "MCPClientOAuthError",
406
- message,
407
- cause
408
- }) {
409
- super({ name: name3, message, cause });
410
- this[_a2] = true;
411
- }
412
- static isInstance(error) {
413
- return AISDKError2.hasMarker(error, marker2);
414
- }
415
- };
416
- var ServerError = class extends MCPClientOAuthError {
417
- };
418
- ServerError.errorCode = "server_error";
419
- var InvalidClientError = class extends MCPClientOAuthError {
420
- };
421
- InvalidClientError.errorCode = "invalid_client";
422
- var InvalidGrantError = class extends MCPClientOAuthError {
423
- };
424
- InvalidGrantError.errorCode = "invalid_grant";
425
- var UnauthorizedClientError = class extends MCPClientOAuthError {
426
- };
427
- UnauthorizedClientError.errorCode = "unauthorized_client";
428
- var OAUTH_ERRORS = {
429
- [ServerError.errorCode]: ServerError,
430
- [InvalidClientError.errorCode]: InvalidClientError,
431
- [InvalidGrantError.errorCode]: InvalidGrantError,
432
- [UnauthorizedClientError.errorCode]: UnauthorizedClientError
433
- };
434
-
435
- // src/util/oauth-util.ts
436
- function resourceUrlFromServerUrl(url) {
437
- const resourceURL = typeof url === "string" ? new URL(url) : new URL(url.href);
438
- resourceURL.hash = "";
439
- return resourceURL;
440
- }
441
- function checkResourceAllowed({
442
- requestedResource,
443
- configuredResource
444
- }) {
445
- const requested = typeof requestedResource === "string" ? new URL(requestedResource) : new URL(requestedResource.href);
446
- const configured = typeof configuredResource === "string" ? new URL(configuredResource) : new URL(configuredResource.href);
447
- if (requested.origin !== configured.origin) {
448
- return false;
449
- }
450
- if (requested.pathname.length < configured.pathname.length) {
451
- return false;
452
- }
453
- const requestedPath = requested.pathname.endsWith("/") ? requested.pathname : requested.pathname + "/";
454
- const configuredPath = configured.pathname.endsWith("/") ? configured.pathname : configured.pathname + "/";
455
- return requestedPath.startsWith(configuredPath);
456
- }
457
-
458
- // src/tool/oauth.ts
459
- var UnauthorizedError = class extends Error {
460
- constructor(message = "Unauthorized") {
461
- super(message);
462
- this.name = "UnauthorizedError";
463
- }
464
- };
465
- function extractResourceMetadataUrl(response) {
466
- var _a3;
467
- const header = (_a3 = response.headers.get("www-authenticate")) != null ? _a3 : response.headers.get("WWW-Authenticate");
468
- if (!header) {
469
- return void 0;
470
- }
471
- const [type, scheme] = header.split(" ");
472
- if (type.toLowerCase() !== "bearer" || !scheme) {
473
- return void 0;
474
- }
475
- const regex = /resource_metadata="([^"]*)"/;
476
- const match = header.match(regex);
477
- if (!match) {
478
- return void 0;
479
- }
480
- try {
481
- return new URL(match[1]);
482
- } catch (e) {
483
- return void 0;
484
- }
485
- }
486
- function buildWellKnownPath(wellKnownPrefix, pathname = "", options = {}) {
487
- if (pathname.endsWith("/")) {
488
- pathname = pathname.slice(0, -1);
489
- }
490
- return options.prependPathname ? `${pathname}/.well-known/${wellKnownPrefix}` : `/.well-known/${wellKnownPrefix}${pathname}`;
491
- }
492
- async function fetchWithCorsRetry(url, headers, fetchFn = fetch) {
493
- try {
494
- return await fetchFn(url, { headers });
495
- } catch (error) {
496
- if (error instanceof TypeError) {
497
- if (headers) {
498
- return fetchWithCorsRetry(url, void 0, fetchFn);
499
- } else {
500
- return void 0;
501
- }
502
- }
503
- throw error;
504
- }
505
- }
506
- async function tryMetadataDiscovery(url, protocolVersion, fetchFn = fetch) {
507
- const headers = {
508
- "MCP-Protocol-Version": protocolVersion
509
- };
510
- return await fetchWithCorsRetry(url, headers, fetchFn);
511
- }
512
- function shouldAttemptFallback(response, pathname) {
513
- return !response || response.status >= 400 && response.status < 500 && pathname !== "/";
514
- }
515
- async function discoverMetadataWithFallback(serverUrl, wellKnownType, fetchFn, opts) {
516
- var _a3, _b3;
517
- const issuer = new URL(serverUrl);
518
- const protocolVersion = (_a3 = opts == null ? void 0 : opts.protocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION;
519
- let url;
520
- if (opts == null ? void 0 : opts.metadataUrl) {
521
- url = new URL(opts.metadataUrl);
522
- } else {
523
- const wellKnownPath = buildWellKnownPath(wellKnownType, issuer.pathname);
524
- url = new URL(wellKnownPath, (_b3 = opts == null ? void 0 : opts.metadataServerUrl) != null ? _b3 : issuer);
525
- url.search = issuer.search;
526
- }
527
- let response = await tryMetadataDiscovery(url, protocolVersion, fetchFn);
528
- if (!(opts == null ? void 0 : opts.metadataUrl) && shouldAttemptFallback(response, issuer.pathname)) {
529
- const rootUrl = new URL(`/.well-known/${wellKnownType}`, issuer);
530
- response = await tryMetadataDiscovery(rootUrl, protocolVersion, fetchFn);
531
- }
532
- return response;
533
- }
534
- async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn = fetch) {
535
- const response = await discoverMetadataWithFallback(
536
- serverUrl,
537
- "oauth-protected-resource",
538
- fetchFn,
539
- {
540
- protocolVersion: opts == null ? void 0 : opts.protocolVersion,
541
- metadataUrl: opts == null ? void 0 : opts.resourceMetadataUrl
542
- }
543
- );
544
- if (!response || response.status === 404) {
545
- throw new Error(
546
- `Resource server does not implement OAuth 2.0 Protected Resource Metadata.`
547
- );
548
- }
549
- if (!response.ok) {
550
- throw new Error(
551
- `HTTP ${response.status} trying to load well-known OAuth protected resource metadata.`
552
- );
553
- }
554
- return OAuthProtectedResourceMetadataSchema.parse(await response.json());
555
- }
556
- function buildDiscoveryUrls(authorizationServerUrl) {
557
- const url = typeof authorizationServerUrl === "string" ? new URL(authorizationServerUrl) : authorizationServerUrl;
558
- const hasPath = url.pathname !== "/";
559
- const urlsToTry = [];
560
- if (!hasPath) {
561
- urlsToTry.push({
562
- url: new URL("/.well-known/oauth-authorization-server", url.origin),
563
- type: "oauth"
564
- });
565
- urlsToTry.push({
566
- url: new URL("/.well-known/openid-configuration", url.origin),
567
- type: "oidc"
568
- });
569
- return urlsToTry;
570
- }
571
- let pathname = url.pathname;
572
- if (pathname.endsWith("/")) {
573
- pathname = pathname.slice(0, -1);
574
- }
575
- urlsToTry.push({
576
- url: new URL(
577
- `/.well-known/oauth-authorization-server${pathname}`,
578
- url.origin
579
- ),
580
- type: "oauth"
581
- });
582
- urlsToTry.push({
583
- url: new URL("/.well-known/oauth-authorization-server", url.origin),
584
- type: "oauth"
585
- });
586
- urlsToTry.push({
587
- url: new URL(`/.well-known/openid-configuration${pathname}`, url.origin),
588
- type: "oidc"
589
- });
590
- urlsToTry.push({
591
- url: new URL(`${pathname}/.well-known/openid-configuration`, url.origin),
592
- type: "oidc"
593
- });
594
- return urlsToTry;
595
- }
596
- async function discoverAuthorizationServerMetadata(authorizationServerUrl, {
597
- fetchFn = fetch,
598
- protocolVersion = LATEST_PROTOCOL_VERSION
599
- } = {}) {
600
- var _a3;
601
- const headers = { "MCP-Protocol-Version": protocolVersion };
602
- const urlsToTry = buildDiscoveryUrls(authorizationServerUrl);
603
- for (const { url: endpointUrl, type } of urlsToTry) {
604
- const response = await fetchWithCorsRetry(endpointUrl, headers, fetchFn);
605
- if (!response) {
606
- continue;
607
- }
608
- if (!response.ok) {
609
- if (response.status >= 400 && response.status < 500) {
610
- continue;
611
- }
612
- throw new Error(
613
- `HTTP ${response.status} trying to load ${type === "oauth" ? "OAuth" : "OpenID provider"} metadata from ${endpointUrl}`
614
- );
615
- }
616
- if (type === "oauth") {
617
- return OAuthMetadataSchema.parse(await response.json());
618
- } else {
619
- const metadata = OpenIdProviderDiscoveryMetadataSchema.parse(
620
- await response.json()
621
- );
622
- if (!((_a3 = metadata.code_challenge_methods_supported) == null ? void 0 : _a3.includes("S256"))) {
623
- throw new Error(
624
- `Incompatible OIDC provider at ${endpointUrl}: does not support S256 code challenge method required by MCP specification`
625
- );
626
- }
627
- return metadata;
628
- }
629
- }
630
- return void 0;
631
- }
632
- async function startAuthorization(authorizationServerUrl, {
633
- metadata,
634
- clientInformation,
635
- redirectUrl,
636
- scope,
637
- state,
638
- resource
639
- }) {
640
- const responseType = "code";
641
- const codeChallengeMethod = "S256";
642
- let authorizationUrl;
643
- if (metadata) {
644
- authorizationUrl = new URL(metadata.authorization_endpoint);
645
- if (!metadata.response_types_supported.includes(responseType)) {
646
- throw new Error(
647
- `Incompatible auth server: does not support response type ${responseType}`
648
- );
649
- }
650
- if (!metadata.code_challenge_methods_supported || !metadata.code_challenge_methods_supported.includes(codeChallengeMethod)) {
651
- throw new Error(
652
- `Incompatible auth server: does not support code challenge method ${codeChallengeMethod}`
653
- );
654
- }
655
- } else {
656
- authorizationUrl = new URL("/authorize", authorizationServerUrl);
657
- }
658
- const challenge = await pkceChallenge();
659
- const codeVerifier = challenge.code_verifier;
660
- const codeChallenge = challenge.code_challenge;
661
- authorizationUrl.searchParams.set("response_type", responseType);
662
- authorizationUrl.searchParams.set("client_id", clientInformation.client_id);
663
- authorizationUrl.searchParams.set("code_challenge", codeChallenge);
664
- authorizationUrl.searchParams.set(
665
- "code_challenge_method",
666
- codeChallengeMethod
667
- );
668
- authorizationUrl.searchParams.set("redirect_uri", String(redirectUrl));
669
- if (state) {
670
- authorizationUrl.searchParams.set("state", state);
671
- }
672
- if (scope) {
673
- authorizationUrl.searchParams.set("scope", scope);
674
- }
675
- if (scope == null ? void 0 : scope.includes("offline_access")) {
676
- authorizationUrl.searchParams.append("prompt", "consent");
677
- }
678
- if (resource) {
679
- authorizationUrl.searchParams.set("resource", resource.href);
680
- }
681
- return { authorizationUrl, codeVerifier };
682
- }
683
- function selectClientAuthMethod(clientInformation, supportedMethods) {
684
- const hasClientSecret = clientInformation.client_secret !== void 0;
685
- if (supportedMethods.length === 0) {
686
- return hasClientSecret ? "client_secret_post" : "none";
687
- }
688
- if (hasClientSecret && supportedMethods.includes("client_secret_basic")) {
689
- return "client_secret_basic";
690
- }
691
- if (hasClientSecret && supportedMethods.includes("client_secret_post")) {
692
- return "client_secret_post";
693
- }
694
- if (supportedMethods.includes("none")) {
695
- return "none";
696
- }
697
- return hasClientSecret ? "client_secret_post" : "none";
698
- }
699
- function applyClientAuthentication(method, clientInformation, headers, params) {
700
- const { client_id, client_secret } = clientInformation;
701
- switch (method) {
702
- case "client_secret_basic":
703
- applyBasicAuth(client_id, client_secret, headers);
704
- return;
705
- case "client_secret_post":
706
- applyPostAuth(client_id, client_secret, params);
707
- return;
708
- case "none":
709
- applyPublicAuth(client_id, params);
710
- return;
711
- default:
712
- throw new Error(`Unsupported client authentication method: ${method}`);
713
- }
714
- }
715
- function applyBasicAuth(clientId, clientSecret, headers) {
716
- if (!clientSecret) {
717
- throw new Error(
718
- "client_secret_basic authentication requires a client_secret"
719
- );
720
- }
721
- const credentials = btoa(`${clientId}:${clientSecret}`);
722
- headers.set("Authorization", `Basic ${credentials}`);
723
- }
724
- function applyPostAuth(clientId, clientSecret, params) {
725
- params.set("client_id", clientId);
726
- if (clientSecret) {
727
- params.set("client_secret", clientSecret);
728
- }
729
- }
730
- function applyPublicAuth(clientId, params) {
731
- params.set("client_id", clientId);
732
- }
733
- async function parseErrorResponse(input) {
734
- const statusCode = input instanceof Response ? input.status : void 0;
735
- const body = input instanceof Response ? await input.text() : input;
736
- try {
737
- const result = OAuthErrorResponseSchema.parse(JSON.parse(body));
738
- const { error, error_description, error_uri } = result;
739
- const errorClass = OAUTH_ERRORS[error] || ServerError;
740
- return new errorClass({
741
- message: error_description || "",
742
- cause: error_uri
743
- });
744
- } catch (error) {
745
- const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ""}Invalid OAuth error response: ${error}. Raw body: ${body}`;
746
- return new ServerError({ message: errorMessage });
747
- }
748
- }
749
- async function exchangeAuthorization(authorizationServerUrl, {
750
- metadata,
751
- clientInformation,
752
- authorizationCode,
753
- codeVerifier,
754
- redirectUri,
755
- resource,
756
- addClientAuthentication,
757
- fetchFn
758
- }) {
759
- var _a3;
760
- const grantType = "authorization_code";
761
- const tokenUrl = (metadata == null ? void 0 : metadata.token_endpoint) ? new URL(metadata.token_endpoint) : new URL("/token", authorizationServerUrl);
762
- if ((metadata == null ? void 0 : metadata.grant_types_supported) && !metadata.grant_types_supported.includes(grantType)) {
763
- throw new Error(
764
- `Incompatible auth server: does not support grant type ${grantType}`
765
- );
766
- }
767
- const headers = new Headers({
768
- "Content-Type": "application/x-www-form-urlencoded",
769
- Accept: "application/json"
770
- });
771
- const params = new URLSearchParams({
772
- grant_type: grantType,
773
- code: authorizationCode,
774
- code_verifier: codeVerifier,
775
- redirect_uri: String(redirectUri)
776
- });
777
- if (addClientAuthentication) {
778
- addClientAuthentication(headers, params, authorizationServerUrl, metadata);
779
- } else {
780
- const supportedMethods = (_a3 = metadata == null ? void 0 : metadata.token_endpoint_auth_methods_supported) != null ? _a3 : [];
781
- const authMethod = selectClientAuthMethod(
782
- clientInformation,
783
- supportedMethods
784
- );
785
- applyClientAuthentication(authMethod, clientInformation, headers, params);
786
- }
787
- if (resource) {
788
- params.set("resource", resource.href);
789
- }
790
- const response = await (fetchFn != null ? fetchFn : fetch)(tokenUrl, {
791
- method: "POST",
792
- headers,
793
- body: params
794
- });
795
- if (!response.ok) {
796
- throw await parseErrorResponse(response);
797
- }
798
- return OAuthTokensSchema.parse(await response.json());
799
- }
800
- async function refreshAuthorization(authorizationServerUrl, {
801
- metadata,
802
- clientInformation,
803
- refreshToken,
804
- resource,
805
- addClientAuthentication,
806
- fetchFn
807
- }) {
808
- var _a3;
809
- const grantType = "refresh_token";
810
- let tokenUrl;
811
- if (metadata) {
812
- tokenUrl = new URL(metadata.token_endpoint);
813
- if (metadata.grant_types_supported && !metadata.grant_types_supported.includes(grantType)) {
814
- throw new Error(
815
- `Incompatible auth server: does not support grant type ${grantType}`
816
- );
817
- }
818
- } else {
819
- tokenUrl = new URL("/token", authorizationServerUrl);
820
- }
821
- const headers = new Headers({
822
- "Content-Type": "application/x-www-form-urlencoded",
823
- Accept: "application/json"
824
- });
825
- const params = new URLSearchParams({
826
- grant_type: grantType,
827
- refresh_token: refreshToken
828
- });
829
- if (addClientAuthentication) {
830
- addClientAuthentication(headers, params, authorizationServerUrl, metadata);
831
- } else {
832
- const supportedMethods = (_a3 = metadata == null ? void 0 : metadata.token_endpoint_auth_methods_supported) != null ? _a3 : [];
833
- const authMethod = selectClientAuthMethod(
834
- clientInformation,
835
- supportedMethods
836
- );
837
- applyClientAuthentication(authMethod, clientInformation, headers, params);
838
- }
839
- if (resource) {
840
- params.set("resource", resource.href);
841
- }
842
- const response = await (fetchFn != null ? fetchFn : fetch)(tokenUrl, {
843
- method: "POST",
844
- headers,
845
- body: params
846
- });
847
- if (!response.ok) {
848
- throw await parseErrorResponse(response);
849
- }
850
- return OAuthTokensSchema.parse({
851
- refresh_token: refreshToken,
852
- ...await response.json()
853
- });
854
- }
855
- async function registerClient(authorizationServerUrl, {
856
- metadata,
857
- clientMetadata,
858
- fetchFn
859
- }) {
860
- let registrationUrl;
861
- if (metadata) {
862
- if (!metadata.registration_endpoint) {
863
- throw new Error(
864
- "Incompatible auth server: does not support dynamic client registration"
865
- );
866
- }
867
- registrationUrl = new URL(metadata.registration_endpoint);
868
- } else {
869
- registrationUrl = new URL("/register", authorizationServerUrl);
870
- }
871
- const response = await (fetchFn != null ? fetchFn : fetch)(registrationUrl, {
872
- method: "POST",
873
- headers: {
874
- "Content-Type": "application/json"
875
- },
876
- body: JSON.stringify(clientMetadata)
877
- });
878
- if (!response.ok) {
879
- throw await parseErrorResponse(response);
880
- }
881
- return OAuthClientInformationFullSchema.parse(await response.json());
882
- }
883
- async function auth(provider, options) {
884
- var _a3, _b3;
885
- try {
886
- return await authInternal(provider, options);
887
- } catch (error) {
888
- if (error instanceof InvalidClientError || error instanceof UnauthorizedClientError) {
889
- await ((_a3 = provider.invalidateCredentials) == null ? void 0 : _a3.call(provider, "all"));
890
- return await authInternal(provider, options);
891
- } else if (error instanceof InvalidGrantError) {
892
- await ((_b3 = provider.invalidateCredentials) == null ? void 0 : _b3.call(provider, "tokens"));
893
- return await authInternal(provider, options);
894
- }
895
- throw error;
896
- }
897
- }
898
- async function selectResourceURL(serverUrl, provider, resourceMetadata) {
899
- const defaultResource = resourceUrlFromServerUrl(serverUrl);
900
- if (provider.validateResourceURL) {
901
- return await provider.validateResourceURL(
902
- defaultResource,
903
- resourceMetadata == null ? void 0 : resourceMetadata.resource
904
- );
905
- }
906
- if (!resourceMetadata) {
907
- return void 0;
908
- }
909
- if (!checkResourceAllowed({
910
- requestedResource: defaultResource,
911
- configuredResource: resourceMetadata.resource
912
- })) {
913
- throw new Error(
914
- `Protected resource ${resourceMetadata.resource} does not match expected ${defaultResource} (or origin)`
915
- );
916
- }
917
- return new URL(resourceMetadata.resource);
918
- }
919
- async function authInternal(provider, {
920
- serverUrl,
921
- authorizationCode,
922
- callbackState,
923
- scope,
924
- resourceMetadataUrl,
925
- fetchFn
926
- }) {
927
- let resourceMetadata;
928
- let authorizationServerUrl;
929
- try {
930
- resourceMetadata = await discoverOAuthProtectedResourceMetadata(
931
- serverUrl,
932
- { resourceMetadataUrl },
933
- fetchFn
934
- );
935
- if (resourceMetadata.authorization_servers && resourceMetadata.authorization_servers.length > 0) {
936
- authorizationServerUrl = resourceMetadata.authorization_servers[0];
937
- }
938
- } catch (e) {
939
- }
940
- if (!authorizationServerUrl) {
941
- authorizationServerUrl = serverUrl;
942
- }
943
- const resource = await selectResourceURL(
944
- serverUrl,
945
- provider,
946
- resourceMetadata
947
- );
948
- const metadata = await discoverAuthorizationServerMetadata(
949
- authorizationServerUrl,
950
- {
951
- fetchFn
952
- }
953
- );
954
- let clientInformation = await Promise.resolve(provider.clientInformation());
955
- if (!clientInformation) {
956
- if (authorizationCode !== void 0) {
957
- throw new Error(
958
- "Existing OAuth client information is required when exchanging an authorization code"
959
- );
960
- }
961
- if (!provider.saveClientInformation) {
962
- throw new Error(
963
- "OAuth client information must be saveable for dynamic registration"
964
- );
965
- }
966
- const fullInformation = await registerClient(authorizationServerUrl, {
967
- metadata,
968
- clientMetadata: provider.clientMetadata,
969
- fetchFn
970
- });
971
- await provider.saveClientInformation(fullInformation);
972
- clientInformation = fullInformation;
973
- }
974
- if (authorizationCode !== void 0) {
975
- if (provider.storedState) {
976
- const expectedState = await provider.storedState();
977
- if (expectedState !== void 0 && expectedState !== callbackState) {
978
- throw new Error(
979
- "OAuth state parameter mismatch - possible CSRF attack"
980
- );
981
- }
982
- }
983
- const codeVerifier2 = await provider.codeVerifier();
984
- const tokens2 = await exchangeAuthorization(authorizationServerUrl, {
985
- metadata,
986
- clientInformation,
987
- authorizationCode,
988
- codeVerifier: codeVerifier2,
989
- redirectUri: provider.redirectUrl,
990
- resource,
991
- addClientAuthentication: provider.addClientAuthentication,
992
- fetchFn
993
- });
994
- await provider.saveTokens(tokens2);
995
- return "AUTHORIZED";
996
- }
997
- const tokens = await provider.tokens();
998
- if (tokens == null ? void 0 : tokens.refresh_token) {
999
- try {
1000
- const newTokens = await refreshAuthorization(authorizationServerUrl, {
1001
- metadata,
1002
- clientInformation,
1003
- refreshToken: tokens.refresh_token,
1004
- resource,
1005
- addClientAuthentication: provider.addClientAuthentication,
1006
- fetchFn
1007
- });
1008
- await provider.saveTokens(newTokens);
1009
- return "AUTHORIZED";
1010
- } catch (error) {
1011
- if (
1012
- // If this is a ServerError, or an unknown type, log it out and try to continue. Otherwise, escalate so we can fix things and retry.
1013
- !(error instanceof MCPClientOAuthError) || error instanceof ServerError
1014
- ) {
1015
- } else {
1016
- throw error;
1017
- }
1018
- }
1019
- }
1020
- const state = provider.state ? await provider.state() : void 0;
1021
- if (state && provider.saveState) {
1022
- await provider.saveState(state);
1023
- }
1024
- const { authorizationUrl, codeVerifier } = await startAuthorization(
1025
- authorizationServerUrl,
1026
- {
1027
- metadata,
1028
- clientInformation,
1029
- state,
1030
- redirectUrl: provider.redirectUrl,
1031
- scope: scope || provider.clientMetadata.scope,
1032
- resource
1033
- }
1034
- );
1035
- await provider.saveCodeVerifier(codeVerifier);
1036
- await provider.redirectToAuthorization(authorizationUrl);
1037
- return "REDIRECT";
1038
- }
1039
-
1040
- // src/tool/mcp-sse-transport.ts
1041
- var SseMCPTransport = class {
1042
- constructor({
1043
- url,
1044
- headers,
1045
- authProvider
1046
- }) {
1047
- this.connected = false;
1048
- this.url = new URL(url);
1049
- this.headers = headers;
1050
- this.authProvider = authProvider;
1051
- }
1052
- async commonHeaders(base) {
1053
- const headers = {
1054
- ...this.headers,
1055
- ...base,
1056
- "mcp-protocol-version": LATEST_PROTOCOL_VERSION
1057
- };
1058
- if (this.authProvider) {
1059
- const tokens = await this.authProvider.tokens();
1060
- if (tokens == null ? void 0 : tokens.access_token) {
1061
- headers["Authorization"] = `Bearer ${tokens.access_token}`;
1062
- }
1063
- }
1064
- return withUserAgentSuffix(
1065
- headers,
1066
- `ai-sdk/${VERSION}`,
1067
- getRuntimeEnvironmentUserAgent()
1068
- );
1069
- }
1070
- async start() {
1071
- return new Promise((resolve, reject) => {
1072
- if (this.connected) {
1073
- return resolve();
1074
- }
1075
- this.abortController = new AbortController();
1076
- const establishConnection = async (triedAuth = false) => {
1077
- var _a3, _b3, _c, _d, _e;
1078
- try {
1079
- const headers = await this.commonHeaders({
1080
- Accept: "text/event-stream"
1081
- });
1082
- const response = await fetch(this.url.href, {
1083
- headers,
1084
- signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
1085
- });
1086
- if (response.status === 401 && this.authProvider && !triedAuth) {
1087
- this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1088
- try {
1089
- const result = await auth(this.authProvider, {
1090
- serverUrl: this.url,
1091
- resourceMetadataUrl: this.resourceMetadataUrl
1092
- });
1093
- if (result !== "AUTHORIZED") {
1094
- const error = new UnauthorizedError();
1095
- (_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);
1096
- return reject(error);
1097
- }
1098
- } catch (error) {
1099
- (_c = this.onerror) == null ? void 0 : _c.call(this, error);
1100
- return reject(error);
1101
- }
1102
- return establishConnection(true);
1103
- }
1104
- if (!response.ok || !response.body) {
1105
- let errorMessage = `MCP SSE Transport Error: ${response.status} ${response.statusText}`;
1106
- if (response.status === 405) {
1107
- errorMessage += ". This server does not support SSE transport. Try using `http` transport instead";
1108
- }
1109
- const error = new MCPClientError({
1110
- message: errorMessage
1111
- });
1112
- (_d = this.onerror) == null ? void 0 : _d.call(this, error);
1113
- return reject(error);
1114
- }
1115
- const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream());
1116
- const reader = stream.getReader();
1117
- const processEvents = async () => {
1118
- var _a4, _b4, _c2;
1119
- try {
1120
- while (true) {
1121
- const { done, value } = await reader.read();
1122
- if (done) {
1123
- if (this.connected) {
1124
- this.connected = false;
1125
- throw new MCPClientError({
1126
- message: "MCP SSE Transport Error: Connection closed unexpectedly"
1127
- });
1128
- }
1129
- return;
1130
- }
1131
- const { event, data } = value;
1132
- if (event === "endpoint") {
1133
- this.endpoint = new URL(data, this.url);
1134
- if (this.endpoint.origin !== this.url.origin) {
1135
- throw new MCPClientError({
1136
- message: `MCP SSE Transport Error: Endpoint origin does not match connection origin: ${this.endpoint.origin}`
1137
- });
1138
- }
1139
- this.connected = true;
1140
- resolve();
1141
- } else if (event === "message") {
1142
- try {
1143
- const message = JSONRPCMessageSchema.parse(
1144
- JSON.parse(data)
1145
- );
1146
- (_a4 = this.onmessage) == null ? void 0 : _a4.call(this, message);
1147
- } catch (error) {
1148
- const e = new MCPClientError({
1149
- message: "MCP SSE Transport Error: Failed to parse message",
1150
- cause: error
1151
- });
1152
- (_b4 = this.onerror) == null ? void 0 : _b4.call(this, e);
1153
- }
1154
- }
1155
- }
1156
- } catch (error) {
1157
- if (error instanceof Error && error.name === "AbortError") {
1158
- return;
1159
- }
1160
- (_c2 = this.onerror) == null ? void 0 : _c2.call(this, error);
1161
- reject(error);
1162
- }
1163
- };
1164
- this.sseConnection = {
1165
- close: () => reader.cancel()
1166
- };
1167
- processEvents();
1168
- } catch (error) {
1169
- if (error instanceof Error && error.name === "AbortError") {
1170
- return;
1171
- }
1172
- (_e = this.onerror) == null ? void 0 : _e.call(this, error);
1173
- reject(error);
1174
- }
1175
- };
1176
- void establishConnection();
1177
- });
1178
- }
1179
- async close() {
1180
- var _a3, _b3, _c;
1181
- this.connected = false;
1182
- (_a3 = this.sseConnection) == null ? void 0 : _a3.close();
1183
- (_b3 = this.abortController) == null ? void 0 : _b3.abort();
1184
- (_c = this.onclose) == null ? void 0 : _c.call(this);
1185
- }
1186
- async send(message) {
1187
- if (!this.endpoint || !this.connected) {
1188
- throw new MCPClientError({
1189
- message: "MCP SSE Transport Error: Not connected"
1190
- });
1191
- }
1192
- const endpoint = this.endpoint;
1193
- const attempt = async (triedAuth = false) => {
1194
- var _a3, _b3, _c, _d, _e;
1195
- try {
1196
- const headers = await this.commonHeaders({
1197
- "Content-Type": "application/json"
1198
- });
1199
- const init = {
1200
- method: "POST",
1201
- headers,
1202
- body: JSON.stringify(message),
1203
- signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
1204
- };
1205
- const response = await fetch(endpoint, init);
1206
- if (response.status === 401 && this.authProvider && !triedAuth) {
1207
- this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1208
- try {
1209
- const result = await auth(this.authProvider, {
1210
- serverUrl: this.url,
1211
- resourceMetadataUrl: this.resourceMetadataUrl
1212
- });
1213
- if (result !== "AUTHORIZED") {
1214
- const error = new UnauthorizedError();
1215
- (_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);
1216
- return;
1217
- }
1218
- } catch (error) {
1219
- (_c = this.onerror) == null ? void 0 : _c.call(this, error);
1220
- return;
1221
- }
1222
- return attempt(true);
1223
- }
1224
- if (!response.ok) {
1225
- const text = await response.text().catch(() => null);
1226
- const error = new MCPClientError({
1227
- message: `MCP SSE Transport Error: POSTing to endpoint (HTTP ${response.status}): ${text}`
1228
- });
1229
- (_d = this.onerror) == null ? void 0 : _d.call(this, error);
1230
- return;
1231
- }
1232
- } catch (error) {
1233
- (_e = this.onerror) == null ? void 0 : _e.call(this, error);
1234
- return;
1235
- }
1236
- };
1237
- await attempt();
1238
- }
1239
- };
1240
-
1241
- // src/tool/mcp-http-transport.ts
1242
- import {
1243
- EventSourceParserStream as EventSourceParserStream2,
1244
- withUserAgentSuffix as withUserAgentSuffix2,
1245
- getRuntimeEnvironmentUserAgent as getRuntimeEnvironmentUserAgent2
1246
- } from "@ai-sdk/provider-utils";
1247
- var HttpMCPTransport = class {
1248
- constructor({
1249
- url,
1250
- headers,
1251
- authProvider
1252
- }) {
1253
- this.inboundReconnectAttempts = 0;
1254
- this.reconnectionOptions = {
1255
- initialReconnectionDelay: 1e3,
1256
- maxReconnectionDelay: 3e4,
1257
- reconnectionDelayGrowFactor: 1.5,
1258
- maxRetries: 2
1259
- };
1260
- this.url = new URL(url);
1261
- this.headers = headers;
1262
- this.authProvider = authProvider;
1263
- }
1264
- async commonHeaders(base) {
1265
- const headers = {
1266
- ...this.headers,
1267
- ...base,
1268
- "mcp-protocol-version": LATEST_PROTOCOL_VERSION
1269
- };
1270
- if (this.sessionId) {
1271
- headers["mcp-session-id"] = this.sessionId;
1272
- }
1273
- if (this.authProvider) {
1274
- const tokens = await this.authProvider.tokens();
1275
- if (tokens == null ? void 0 : tokens.access_token) {
1276
- headers["Authorization"] = `Bearer ${tokens.access_token}`;
1277
- }
1278
- }
1279
- return withUserAgentSuffix2(
1280
- headers,
1281
- `ai-sdk/${VERSION}`,
1282
- getRuntimeEnvironmentUserAgent2()
1283
- );
1284
- }
1285
- async start() {
1286
- if (this.abortController) {
1287
- throw new MCPClientError({
1288
- message: "MCP HTTP Transport Error: Transport already started. Note: client.connect() calls start() automatically."
1289
- });
1290
- }
1291
- this.abortController = new AbortController();
1292
- void this.openInboundSse();
1293
- }
1294
- async close() {
1295
- var _a3, _b3, _c;
1296
- (_a3 = this.inboundSseConnection) == null ? void 0 : _a3.close();
1297
- try {
1298
- if (this.sessionId && this.abortController && !this.abortController.signal.aborted) {
1299
- const headers = await this.commonHeaders({});
1300
- await fetch(this.url, {
1301
- method: "DELETE",
1302
- headers,
1303
- signal: this.abortController.signal
1304
- }).catch(() => void 0);
1305
- }
1306
- } catch (e) {
1307
- }
1308
- (_b3 = this.abortController) == null ? void 0 : _b3.abort();
1309
- (_c = this.onclose) == null ? void 0 : _c.call(this);
1310
- }
1311
- async send(message) {
1312
- const attempt = async (triedAuth = false) => {
1313
- var _a3, _b3, _c, _d, _e, _f, _g;
1314
- try {
1315
- const headers = await this.commonHeaders({
1316
- "Content-Type": "application/json",
1317
- Accept: "application/json, text/event-stream"
1318
- });
1319
- const init = {
1320
- method: "POST",
1321
- headers,
1322
- body: JSON.stringify(message),
1323
- signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
1324
- };
1325
- const response = await fetch(this.url, init);
1326
- const sessionId = response.headers.get("mcp-session-id");
1327
- if (sessionId) {
1328
- this.sessionId = sessionId;
1329
- }
1330
- if (response.status === 401 && this.authProvider && !triedAuth) {
1331
- this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1332
- try {
1333
- const result = await auth(this.authProvider, {
1334
- serverUrl: this.url,
1335
- resourceMetadataUrl: this.resourceMetadataUrl
1336
- });
1337
- if (result !== "AUTHORIZED") {
1338
- const error2 = new UnauthorizedError();
1339
- throw error2;
1340
- }
1341
- } catch (error2) {
1342
- (_b3 = this.onerror) == null ? void 0 : _b3.call(this, error2);
1343
- throw error2;
1344
- }
1345
- return attempt(true);
1346
- }
1347
- if (response.status === 202) {
1348
- if (!this.inboundSseConnection) {
1349
- void this.openInboundSse();
1350
- }
1351
- return;
1352
- }
1353
- if (!response.ok) {
1354
- const text = await response.text().catch(() => null);
1355
- let errorMessage = `MCP HTTP Transport Error: POSTing to endpoint (HTTP ${response.status}): ${text}`;
1356
- if (response.status === 404) {
1357
- errorMessage += ". This server does not support HTTP transport. Try using `sse` transport instead";
1358
- }
1359
- const error2 = new MCPClientError({
1360
- message: errorMessage
1361
- });
1362
- (_c = this.onerror) == null ? void 0 : _c.call(this, error2);
1363
- throw error2;
1364
- }
1365
- const isNotification = !("id" in message);
1366
- if (isNotification) {
1367
- return;
1368
- }
1369
- const contentType = response.headers.get("content-type") || "";
1370
- if (contentType.includes("application/json")) {
1371
- const data = await response.json();
1372
- const messages = Array.isArray(data) ? data.map((m) => JSONRPCMessageSchema.parse(m)) : [JSONRPCMessageSchema.parse(data)];
1373
- for (const m of messages) (_d = this.onmessage) == null ? void 0 : _d.call(this, m);
1374
- return;
1375
- }
1376
- if (contentType.includes("text/event-stream")) {
1377
- if (!response.body) {
1378
- const error2 = new MCPClientError({
1379
- message: "MCP HTTP Transport Error: text/event-stream response without body"
1380
- });
1381
- (_e = this.onerror) == null ? void 0 : _e.call(this, error2);
1382
- throw error2;
1383
- }
1384
- const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream2());
1385
- const reader = stream.getReader();
1386
- const processEvents = async () => {
1387
- var _a4, _b4, _c2;
1388
- try {
1389
- while (true) {
1390
- const { done, value } = await reader.read();
1391
- if (done) return;
1392
- const { event, data } = value;
1393
- if (event === "message") {
1394
- try {
1395
- const msg = JSONRPCMessageSchema.parse(JSON.parse(data));
1396
- (_a4 = this.onmessage) == null ? void 0 : _a4.call(this, msg);
1397
- } catch (error2) {
1398
- const e = new MCPClientError({
1399
- message: "MCP HTTP Transport Error: Failed to parse message",
1400
- cause: error2
1401
- });
1402
- (_b4 = this.onerror) == null ? void 0 : _b4.call(this, e);
1403
- }
1404
- }
1405
- }
1406
- } catch (error2) {
1407
- if (error2 instanceof Error && error2.name === "AbortError") {
1408
- return;
1409
- }
1410
- (_c2 = this.onerror) == null ? void 0 : _c2.call(this, error2);
1411
- }
1412
- };
1413
- processEvents();
1414
- return;
1415
- }
1416
- const error = new MCPClientError({
1417
- message: `MCP HTTP Transport Error: Unexpected content type: ${contentType}`
1418
- });
1419
- (_f = this.onerror) == null ? void 0 : _f.call(this, error);
1420
- throw error;
1421
- } catch (error) {
1422
- (_g = this.onerror) == null ? void 0 : _g.call(this, error);
1423
- throw error;
1424
- }
1425
- };
1426
- await attempt();
1427
- }
1428
- getNextReconnectionDelay(attempt) {
1429
- const {
1430
- initialReconnectionDelay,
1431
- reconnectionDelayGrowFactor,
1432
- maxReconnectionDelay
1433
- } = this.reconnectionOptions;
1434
- return Math.min(
1435
- initialReconnectionDelay * Math.pow(reconnectionDelayGrowFactor, attempt),
1436
- maxReconnectionDelay
1437
- );
1438
- }
1439
- scheduleInboundSseReconnection() {
1440
- var _a3;
1441
- const { maxRetries } = this.reconnectionOptions;
1442
- if (maxRetries > 0 && this.inboundReconnectAttempts >= maxRetries) {
1443
- (_a3 = this.onerror) == null ? void 0 : _a3.call(
1444
- this,
1445
- new MCPClientError({
1446
- message: `MCP HTTP Transport Error: Maximum reconnection attempts (${maxRetries}) exceeded.`
1447
- })
1448
- );
1449
- return;
1450
- }
1451
- const delay = this.getNextReconnectionDelay(this.inboundReconnectAttempts);
1452
- this.inboundReconnectAttempts += 1;
1453
- setTimeout(async () => {
1454
- var _a4;
1455
- if ((_a4 = this.abortController) == null ? void 0 : _a4.signal.aborted) return;
1456
- await this.openInboundSse(false, this.lastInboundEventId);
1457
- }, delay);
1458
- }
1459
- // Open optional inbound SSE stream; best-effort and resumable
1460
- async openInboundSse(triedAuth = false, resumeToken) {
1461
- var _a3, _b3, _c, _d, _e, _f;
1462
- try {
1463
- const headers = await this.commonHeaders({
1464
- Accept: "text/event-stream"
1465
- });
1466
- if (resumeToken) {
1467
- headers["last-event-id"] = resumeToken;
1468
- }
1469
- const response = await fetch(this.url.href, {
1470
- method: "GET",
1471
- headers,
1472
- signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
1473
- });
1474
- const sessionId = response.headers.get("mcp-session-id");
1475
- if (sessionId) {
1476
- this.sessionId = sessionId;
1477
- }
1478
- if (response.status === 401 && this.authProvider && !triedAuth) {
1479
- this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1480
- try {
1481
- const result = await auth(this.authProvider, {
1482
- serverUrl: this.url,
1483
- resourceMetadataUrl: this.resourceMetadataUrl
1484
- });
1485
- if (result !== "AUTHORIZED") {
1486
- const error = new UnauthorizedError();
1487
- (_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);
1488
- return;
1489
- }
1490
- } catch (error) {
1491
- (_c = this.onerror) == null ? void 0 : _c.call(this, error);
1492
- return;
1493
- }
1494
- return this.openInboundSse(true, resumeToken);
1495
- }
1496
- if (response.status === 405) {
1497
- return;
1498
- }
1499
- if (!response.ok || !response.body) {
1500
- const error = new MCPClientError({
1501
- message: `MCP HTTP Transport Error: GET SSE failed: ${response.status} ${response.statusText}`
1502
- });
1503
- (_d = this.onerror) == null ? void 0 : _d.call(this, error);
1504
- return;
1505
- }
1506
- const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream2());
1507
- const reader = stream.getReader();
1508
- const processEvents = async () => {
1509
- var _a4, _b4, _c2, _d2;
1510
- try {
1511
- while (true) {
1512
- const { done, value } = await reader.read();
1513
- if (done) return;
1514
- const { event, data, id } = value;
1515
- if (id) {
1516
- this.lastInboundEventId = id;
1517
- }
1518
- if (event === "message") {
1519
- try {
1520
- const msg = JSONRPCMessageSchema.parse(JSON.parse(data));
1521
- (_a4 = this.onmessage) == null ? void 0 : _a4.call(this, msg);
1522
- } catch (error) {
1523
- const e = new MCPClientError({
1524
- message: "MCP HTTP Transport Error: Failed to parse message",
1525
- cause: error
1526
- });
1527
- (_b4 = this.onerror) == null ? void 0 : _b4.call(this, e);
1528
- }
1529
- }
1530
- }
1531
- } catch (error) {
1532
- if (error instanceof Error && error.name === "AbortError") {
1533
- return;
1534
- }
1535
- (_c2 = this.onerror) == null ? void 0 : _c2.call(this, error);
1536
- if (!((_d2 = this.abortController) == null ? void 0 : _d2.signal.aborted)) {
1537
- this.scheduleInboundSseReconnection();
1538
- }
1539
- }
1540
- };
1541
- this.inboundSseConnection = {
1542
- close: () => reader.cancel()
1543
- };
1544
- this.inboundReconnectAttempts = 0;
1545
- processEvents();
1546
- } catch (error) {
1547
- if (error instanceof Error && error.name === "AbortError") {
1548
- return;
1549
- }
1550
- (_e = this.onerror) == null ? void 0 : _e.call(this, error);
1551
- if (!((_f = this.abortController) == null ? void 0 : _f.signal.aborted)) {
1552
- this.scheduleInboundSseReconnection();
1553
- }
1554
- }
1555
- }
1556
- };
1557
-
1558
- // src/tool/mcp-transport.ts
1559
- function createMcpTransport(config) {
1560
- switch (config.type) {
1561
- case "sse":
1562
- return new SseMCPTransport(config);
1563
- case "http":
1564
- return new HttpMCPTransport(config);
1565
- default:
1566
- throw new MCPClientError({
1567
- message: "Unsupported or invalid transport configuration. If you are using a custom transport, make sure it implements the MCPTransport interface."
1568
- });
1569
- }
1570
- }
1571
- function isCustomMcpTransport(transport) {
1572
- return "start" in transport && typeof transport.start === "function" && "send" in transport && typeof transport.send === "function" && "close" in transport && typeof transport.close === "function";
1573
- }
1574
-
1575
- // src/tool/mcp-client.ts
1576
- var CLIENT_VERSION = "1.0.0";
1577
- function mcpToModelOutput({
1578
- output
1579
- }) {
1580
- const result = output;
1581
- if (!("content" in result) || !Array.isArray(result.content)) {
1582
- return { type: "json", value: result };
1583
- }
1584
- const convertedContent = result.content.map(
1585
- (part) => {
1586
- if (part.type === "text" && "text" in part) {
1587
- return { type: "text", text: part.text };
1588
- }
1589
- if (part.type === "image" && "data" in part && "mimeType" in part) {
1590
- return {
1591
- type: "image-data",
1592
- data: part.data,
1593
- mediaType: part.mimeType
1594
- };
1595
- }
1596
- return { type: "text", text: JSON.stringify(part) };
1597
- }
1598
- );
1599
- return { type: "content", value: convertedContent };
1600
- }
1601
- async function createMCPClient(config) {
1602
- const client = new DefaultMCPClient(config);
1603
- await client.init();
1604
- return client;
1605
- }
1606
- var DefaultMCPClient = class {
1607
- constructor({
1608
- transport: transportConfig,
1609
- name: name3 = "ai-sdk-mcp-client",
1610
- version = CLIENT_VERSION,
1611
- onUncaughtError,
1612
- capabilities
1613
- }) {
1614
- this.requestMessageId = 0;
1615
- this.responseHandlers = /* @__PURE__ */ new Map();
1616
- this.serverCapabilities = {};
1617
- this.isClosed = true;
1618
- this.onUncaughtError = onUncaughtError;
1619
- this.clientCapabilities = capabilities != null ? capabilities : {};
1620
- if (isCustomMcpTransport(transportConfig)) {
1621
- this.transport = transportConfig;
1622
- } else {
1623
- this.transport = createMcpTransport(transportConfig);
1624
- }
1625
- this.transport.onclose = () => this.onClose();
1626
- this.transport.onerror = (error) => this.onError(error);
1627
- this.transport.onmessage = (message) => {
1628
- if ("method" in message) {
1629
- if ("id" in message) {
1630
- this.onRequestMessage(message);
1631
- } else {
1632
- this.onError(
1633
- new MCPClientError({
1634
- message: "Unsupported message type"
1635
- })
1636
- );
1637
- }
1638
- return;
1639
- }
1640
- this.onResponse(message);
1641
- };
1642
- this.clientInfo = {
1643
- name: name3,
1644
- version
1645
- };
1646
- }
1647
- async init() {
1648
- try {
1649
- await this.transport.start();
1650
- this.isClosed = false;
1651
- const result = await this.request({
1652
- request: {
1653
- method: "initialize",
1654
- params: {
1655
- protocolVersion: LATEST_PROTOCOL_VERSION,
1656
- capabilities: this.clientCapabilities,
1657
- clientInfo: this.clientInfo
1658
- }
1659
- },
1660
- resultSchema: InitializeResultSchema
1661
- });
1662
- if (result === void 0) {
1663
- throw new MCPClientError({
1664
- message: "Server sent invalid initialize result"
1665
- });
1666
- }
1667
- if (!SUPPORTED_PROTOCOL_VERSIONS.includes(result.protocolVersion)) {
1668
- throw new MCPClientError({
1669
- message: `Server's protocol version is not supported: ${result.protocolVersion}`
1670
- });
1671
- }
1672
- this.serverCapabilities = result.capabilities;
1673
- await this.notification({
1674
- method: "notifications/initialized"
1675
- });
1676
- return this;
1677
- } catch (error) {
1678
- await this.close();
1679
- throw error;
1680
- }
1681
- }
1682
- async close() {
1683
- var _a3;
1684
- if (this.isClosed) return;
1685
- await ((_a3 = this.transport) == null ? void 0 : _a3.close());
1686
- this.onClose();
1687
- }
1688
- assertCapability(method) {
1689
- switch (method) {
1690
- case "initialize":
1691
- break;
1692
- case "tools/list":
1693
- case "tools/call":
1694
- if (!this.serverCapabilities.tools) {
1695
- throw new MCPClientError({
1696
- message: `Server does not support tools`
1697
- });
1698
- }
1699
- break;
1700
- case "resources/list":
1701
- case "resources/read":
1702
- case "resources/templates/list":
1703
- if (!this.serverCapabilities.resources) {
1704
- throw new MCPClientError({
1705
- message: `Server does not support resources`
1706
- });
1707
- }
1708
- break;
1709
- case "prompts/list":
1710
- case "prompts/get":
1711
- if (!this.serverCapabilities.prompts) {
1712
- throw new MCPClientError({
1713
- message: `Server does not support prompts`
1714
- });
1715
- }
1716
- break;
1717
- default:
1718
- throw new MCPClientError({
1719
- message: `Unsupported method: ${method}`
1720
- });
1721
- }
1722
- }
1723
- async request({
1724
- request,
1725
- resultSchema,
1726
- options
1727
- }) {
1728
- return new Promise((resolve, reject) => {
1729
- if (this.isClosed) {
1730
- return reject(
1731
- new MCPClientError({
1732
- message: "Attempted to send a request from a closed client"
1733
- })
1734
- );
1735
- }
1736
- this.assertCapability(request.method);
1737
- const signal = options == null ? void 0 : options.signal;
1738
- signal == null ? void 0 : signal.throwIfAborted();
1739
- const messageId = this.requestMessageId++;
1740
- const jsonrpcRequest = {
1741
- ...request,
1742
- jsonrpc: "2.0",
1743
- id: messageId
1744
- };
1745
- const cleanup = () => {
1746
- this.responseHandlers.delete(messageId);
1747
- };
1748
- this.responseHandlers.set(messageId, (response) => {
1749
- if (signal == null ? void 0 : signal.aborted) {
1750
- return reject(
1751
- new MCPClientError({
1752
- message: "Request was aborted",
1753
- cause: signal.reason
1754
- })
1755
- );
1756
- }
1757
- if (response instanceof Error) {
1758
- return reject(response);
1759
- }
1760
- try {
1761
- const result = resultSchema.parse(response.result);
1762
- resolve(result);
1763
- } catch (error) {
1764
- const parseError = new MCPClientError({
1765
- message: "Failed to parse server response",
1766
- cause: error
1767
- });
1768
- reject(parseError);
1769
- }
1770
- });
1771
- this.transport.send(jsonrpcRequest).catch((error) => {
1772
- cleanup();
1773
- reject(error);
1774
- });
1775
- });
1776
- }
1777
- async listTools({
1778
- params,
1779
- options
1780
- } = {}) {
1781
- return this.request({
1782
- request: { method: "tools/list", params },
1783
- resultSchema: ListToolsResultSchema,
1784
- options
1785
- });
1786
- }
1787
- async callTool({
1788
- name: name3,
1789
- args,
1790
- options
1791
- }) {
1792
- try {
1793
- return this.request({
1794
- request: { method: "tools/call", params: { name: name3, arguments: args } },
1795
- resultSchema: CallToolResultSchema,
1796
- options: {
1797
- signal: options == null ? void 0 : options.abortSignal
1798
- }
1799
- });
1800
- } catch (error) {
1801
- throw error;
1802
- }
1803
- }
1804
- async listResourcesInternal({
1805
- params,
1806
- options
1807
- } = {}) {
1808
- try {
1809
- return this.request({
1810
- request: { method: "resources/list", params },
1811
- resultSchema: ListResourcesResultSchema,
1812
- options
1813
- });
1814
- } catch (error) {
1815
- throw error;
1816
- }
1817
- }
1818
- async readResourceInternal({
1819
- uri,
1820
- options
1821
- }) {
1822
- try {
1823
- return this.request({
1824
- request: { method: "resources/read", params: { uri } },
1825
- resultSchema: ReadResourceResultSchema,
1826
- options
1827
- });
1828
- } catch (error) {
1829
- throw error;
1830
- }
1831
- }
1832
- async listResourceTemplatesInternal({
1833
- options
1834
- } = {}) {
1835
- try {
1836
- return this.request({
1837
- request: { method: "resources/templates/list" },
1838
- resultSchema: ListResourceTemplatesResultSchema,
1839
- options
1840
- });
1841
- } catch (error) {
1842
- throw error;
1843
- }
1844
- }
1845
- async listPromptsInternal({
1846
- params,
1847
- options
1848
- } = {}) {
1849
- try {
1850
- return this.request({
1851
- request: { method: "prompts/list", params },
1852
- resultSchema: ListPromptsResultSchema,
1853
- options
1854
- });
1855
- } catch (error) {
1856
- throw error;
1857
- }
1858
- }
1859
- async getPromptInternal({
1860
- name: name3,
1861
- args,
1862
- options
1863
- }) {
1864
- try {
1865
- return this.request({
1866
- request: { method: "prompts/get", params: { name: name3, arguments: args } },
1867
- resultSchema: GetPromptResultSchema,
1868
- options
1869
- });
1870
- } catch (error) {
1871
- throw error;
1872
- }
1873
- }
1874
- async notification(notification) {
1875
- const jsonrpcNotification = {
1876
- ...notification,
1877
- jsonrpc: "2.0"
1878
- };
1879
- await this.transport.send(jsonrpcNotification);
1880
- }
1881
- /**
1882
- * Returns a set of AI SDK tools from the MCP server.
1883
- * This fetches tool definitions and wraps them with execute functions.
1884
- * @returns A record of tool names to their implementations
1885
- */
1886
- async tools({
1887
- schemas = "automatic"
1888
- } = {}) {
1889
- const definitions = await this.listTools();
1890
- return this.toolsFromDefinitions(definitions, {
1891
- schemas
1892
- });
1893
- }
1894
- /**
1895
- * Creates AI SDK tools from tool definitions without fetching from the server.
1896
- */
1897
- toolsFromDefinitions(definitions, { schemas = "automatic" } = {}) {
1898
- var _a3, _b3;
1899
- const tools = {};
1900
- for (const {
1901
- name: name3,
1902
- title,
1903
- description,
1904
- inputSchema,
1905
- annotations,
1906
- _meta
1907
- } of definitions.tools) {
1908
- const resolvedTitle = title != null ? title : annotations == null ? void 0 : annotations.title;
1909
- if (schemas !== "automatic" && !(name3 in schemas)) {
1910
- continue;
1911
- }
1912
- const self = this;
1913
- const outputSchema = schemas !== "automatic" ? (_a3 = schemas[name3]) == null ? void 0 : _a3.outputSchema : void 0;
1914
- const execute = async (args, options) => {
1915
- var _a4;
1916
- (_a4 = options == null ? void 0 : options.abortSignal) == null ? void 0 : _a4.throwIfAborted();
1917
- const result = await self.callTool({ name: name3, args, options });
1918
- if (outputSchema != null) {
1919
- return self.extractStructuredContent(result, outputSchema, name3);
1920
- }
1921
- return result;
1922
- };
1923
- const toolWithExecute = schemas === "automatic" ? dynamicTool({
1924
- description,
1925
- title: resolvedTitle,
1926
- inputSchema: jsonSchema({
1927
- ...inputSchema,
1928
- properties: (_b3 = inputSchema.properties) != null ? _b3 : {},
1929
- additionalProperties: false
1930
- }),
1931
- execute,
1932
- toModelOutput: mcpToModelOutput
1933
- }) : tool({
1934
- description,
1935
- title: resolvedTitle,
1936
- inputSchema: schemas[name3].inputSchema,
1937
- ...outputSchema != null ? { outputSchema } : {},
1938
- execute,
1939
- toModelOutput: mcpToModelOutput
1940
- });
1941
- tools[name3] = { ...toolWithExecute, _meta };
1942
- }
1943
- return tools;
1944
- }
1945
- /**
1946
- * Extracts and validates structuredContent from a tool result.
1947
- */
1948
- async extractStructuredContent(result, outputSchema, toolName) {
1949
- if ("structuredContent" in result && result.structuredContent != null) {
1950
- const validationResult = await safeValidateTypes({
1951
- value: result.structuredContent,
1952
- schema: asSchema(outputSchema)
1953
- });
1954
- if (!validationResult.success) {
1955
- throw new MCPClientError({
1956
- message: `Tool "${toolName}" returned structuredContent that does not match the expected outputSchema`,
1957
- cause: validationResult.error
1958
- });
1959
- }
1960
- return validationResult.value;
1961
- }
1962
- if ("content" in result && Array.isArray(result.content)) {
1963
- const textContent = result.content.find((c) => c.type === "text");
1964
- if (textContent && "text" in textContent) {
1965
- const parseResult = await safeParseJSON({
1966
- text: textContent.text,
1967
- schema: outputSchema
1968
- });
1969
- if (!parseResult.success) {
1970
- throw new MCPClientError({
1971
- message: `Tool "${toolName}" returned content that does not match the expected outputSchema`,
1972
- cause: parseResult.error
1973
- });
1974
- }
1975
- return parseResult.value;
1976
- }
1977
- }
1978
- throw new MCPClientError({
1979
- message: `Tool "${toolName}" did not return structuredContent or parseable text content`
1980
- });
1981
- }
1982
- listResources({
1983
- params,
1984
- options
1985
- } = {}) {
1986
- return this.listResourcesInternal({ params, options });
1987
- }
1988
- readResource({
1989
- uri,
1990
- options
1991
- }) {
1992
- return this.readResourceInternal({ uri, options });
1993
- }
1994
- listResourceTemplates({
1995
- options
1996
- } = {}) {
1997
- return this.listResourceTemplatesInternal({ options });
1998
- }
1999
- experimental_listPrompts({
2000
- params,
2001
- options
2002
- } = {}) {
2003
- return this.listPromptsInternal({ params, options });
2004
- }
2005
- experimental_getPrompt({
2006
- name: name3,
2007
- arguments: args,
2008
- options
2009
- }) {
2010
- return this.getPromptInternal({ name: name3, args, options });
2011
- }
2012
- onElicitationRequest(schema, handler) {
2013
- if (schema !== ElicitationRequestSchema) {
2014
- throw new MCPClientError({
2015
- message: "Unsupported request schema. Only ElicitationRequestSchema is supported."
2016
- });
2017
- }
2018
- this.elicitationRequestHandler = handler;
2019
- }
2020
- async onRequestMessage(request) {
2021
- try {
2022
- if (request.method !== "elicitation/create") {
2023
- await this.transport.send({
2024
- jsonrpc: "2.0",
2025
- id: request.id,
2026
- error: {
2027
- code: -32601,
2028
- message: `Unsupported request method: ${request.method}`
2029
- }
2030
- });
2031
- return;
2032
- }
2033
- if (!this.elicitationRequestHandler) {
2034
- await this.transport.send({
2035
- jsonrpc: "2.0",
2036
- id: request.id,
2037
- error: {
2038
- code: -32601,
2039
- message: "No elicitation handler registered on client"
2040
- }
2041
- });
2042
- return;
2043
- }
2044
- const parsedRequest = ElicitationRequestSchema.safeParse({
2045
- method: request.method,
2046
- params: request.params
2047
- });
2048
- if (!parsedRequest.success) {
2049
- await this.transport.send({
2050
- jsonrpc: "2.0",
2051
- id: request.id,
2052
- error: {
2053
- code: -32602,
2054
- message: `Invalid elicitation request: ${parsedRequest.error.message}`,
2055
- data: parsedRequest.error.issues
2056
- }
2057
- });
2058
- return;
2059
- }
2060
- try {
2061
- const result = await this.elicitationRequestHandler(parsedRequest.data);
2062
- const validatedResult = ElicitResultSchema.parse(result);
2063
- await this.transport.send({
2064
- jsonrpc: "2.0",
2065
- id: request.id,
2066
- result: validatedResult
2067
- });
2068
- } catch (error) {
2069
- await this.transport.send({
2070
- jsonrpc: "2.0",
2071
- id: request.id,
2072
- error: {
2073
- code: -32603,
2074
- message: error instanceof Error ? error.message : "Failed to handle elicitation request"
2075
- }
2076
- });
2077
- this.onError(error);
2078
- }
2079
- } catch (error) {
2080
- this.onError(error);
2081
- }
2082
- }
2083
- onClose() {
2084
- if (this.isClosed) return;
2085
- this.isClosed = true;
2086
- const error = new MCPClientError({
2087
- message: "Connection closed"
2088
- });
2089
- for (const handler of this.responseHandlers.values()) {
2090
- handler(error);
2091
- }
2092
- this.responseHandlers.clear();
2093
- }
2094
- onError(error) {
2095
- if (this.onUncaughtError) {
2096
- this.onUncaughtError(error);
2097
- }
2098
- }
2099
- onResponse(response) {
2100
- const messageId = Number(response.id);
2101
- const handler = this.responseHandlers.get(messageId);
2102
- if (handler === void 0) {
2103
- throw new MCPClientError({
2104
- message: `Protocol error: Received a response for an unknown message ID: ${JSON.stringify(
2105
- response
2106
- )}`
2107
- });
2108
- }
2109
- this.responseHandlers.delete(messageId);
2110
- handler(
2111
- "result" in response ? response : new MCPClientError({
2112
- message: response.error.message,
2113
- code: response.error.code,
2114
- data: response.error.data,
2115
- cause: response.error
2116
- })
2117
- );
2118
- }
2119
- };
2120
- export {
2121
- ElicitResultSchema,
2122
- ElicitationRequestSchema,
2123
- UnauthorizedError,
2124
- auth,
2125
- createMCPClient,
2126
- createMCPClient as experimental_createMCPClient
2127
- };
2128
- //# sourceMappingURL=index.mjs.map