@ai-sdk/mcp 2.0.31 → 2.0.33

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.js CHANGED
@@ -4,9 +4,11 @@ import { z as z2 } from "zod/v4";
4
4
 
5
5
  // src/tool/types.ts
6
6
  import { z } from "zod/v4";
7
- var LATEST_PROTOCOL_VERSION = "2025-11-25";
7
+ var LATEST_PROTOCOL_VERSION = "2026-07-28";
8
+ var LATEST_LEGACY_PROTOCOL_VERSION = "2025-11-25";
8
9
  var SUPPORTED_PROTOCOL_VERSIONS = [
9
10
  LATEST_PROTOCOL_VERSION,
11
+ LATEST_LEGACY_PROTOCOL_VERSION,
10
12
  "2025-06-18",
11
13
  "2025-03-26",
12
14
  "2024-11-05"
@@ -20,7 +22,9 @@ var ClientOrServerImplementationSchema = z.looseObject({
20
22
  var BaseParamsSchema = z.looseObject({
21
23
  _meta: z.optional(z.object({}).loose())
22
24
  });
23
- var ResultSchema = BaseParamsSchema;
25
+ var ResultSchema = BaseParamsSchema.extend({
26
+ resultType: z.optional(z.string())
27
+ });
24
28
  var RequestSchema = z.object({
25
29
  method: z.string(),
26
30
  params: z.optional(BaseParamsSchema)
@@ -53,6 +57,13 @@ var ServerCapabilitiesSchema = z.looseObject({
53
57
  var ClientCapabilitiesSchema = z.object({
54
58
  elicitation: z.optional(ElicitationCapabilitySchema)
55
59
  }).loose();
60
+ var DiscoverResultSchema = ResultSchema.extend({
61
+ supportedVersions: z.array(z.string()),
62
+ capabilities: ServerCapabilitiesSchema,
63
+ instructions: z.optional(z.string()),
64
+ ttlMs: z.optional(z.number()),
65
+ cacheScope: z.optional(z.union([z.literal("public"), z.literal("private")]))
66
+ });
56
67
  var InitializeResultSchema = ResultSchema.extend({
57
68
  protocolVersion: z.string(),
58
69
  capabilities: ServerCapabilitiesSchema,
@@ -69,10 +80,10 @@ var ToolSchema = z.object({
69
80
  */
70
81
  title: z.optional(z.string()),
71
82
  description: z.optional(z.string()),
72
- inputSchema: z.object({
73
- type: z.literal("object"),
83
+ inputSchema: z.looseObject({
84
+ type: z.optional(z.unknown()),
74
85
  properties: z.optional(z.object({}).loose())
75
- }).loose(),
86
+ }),
76
87
  /**
77
88
  * @see https://modelcontextprotocol.io/specification/2025-06-18/server/tools#output-schema
78
89
  */
@@ -261,7 +272,7 @@ var JSONRPCResponseSchema = z2.object({
261
272
  }).strict();
262
273
  var JSONRPCErrorSchema = z2.object({
263
274
  jsonrpc: z2.literal(JSONRPC_VERSION),
264
- id: z2.union([z2.string(), z2.number().int()]),
275
+ id: z2.optional(z2.union([z2.string(), z2.number().int()])),
265
276
  error: z2.object({
266
277
  code: z2.number().int(),
267
278
  message: z2.string(),
@@ -369,6 +380,7 @@ var OAuthTokensSchema = z3.object({
369
380
  expires_in: z3.number().optional(),
370
381
  scope: z3.string().optional(),
371
382
  refresh_token: z3.string().optional(),
383
+ issuer: SafeUrlSchema.optional(),
372
384
  authorization_server: SafeUrlSchema.optional(),
373
385
  token_endpoint: SafeUrlSchema.optional()
374
386
  }).strip();
@@ -393,6 +405,8 @@ var OAuthMetadataSchema = z3.looseObject({
393
405
  authorization_endpoint: SafeUrlSchema,
394
406
  token_endpoint: SafeUrlSchema,
395
407
  registration_endpoint: SafeUrlSchema.optional(),
408
+ authorization_response_iss_parameter_supported: z3.boolean().optional(),
409
+ client_id_metadata_document_supported: z3.boolean().optional(),
396
410
  scopes_supported: z3.array(z3.string()).optional(),
397
411
  response_types_supported: z3.array(z3.string()),
398
412
  grant_types_supported: z3.array(z3.string()).optional(),
@@ -407,6 +421,8 @@ var OpenIdProviderMetadataSchema = z3.looseObject({
407
421
  userinfo_endpoint: SafeUrlSchema.optional(),
408
422
  jwks_uri: SafeUrlSchema,
409
423
  registration_endpoint: SafeUrlSchema.optional(),
424
+ authorization_response_iss_parameter_supported: z3.boolean().optional(),
425
+ client_id_metadata_document_supported: z3.boolean().optional(),
410
426
  scopes_supported: z3.array(z3.string()).optional(),
411
427
  response_types_supported: z3.array(z3.string()),
412
428
  grant_types_supported: z3.array(z3.string()).optional(),
@@ -425,11 +441,13 @@ var OAuthClientInformationSchema = z3.object({
425
441
  client_secret: z3.string().optional(),
426
442
  client_id_issued_at: z3.number().optional(),
427
443
  client_secret_expires_at: z3.number().optional(),
444
+ issuer: SafeUrlSchema.optional(),
428
445
  authorization_server: SafeUrlSchema.optional(),
429
446
  token_endpoint: SafeUrlSchema.optional()
430
447
  }).strip();
431
448
  var OAuthClientMetadataSchema = z3.object({
432
449
  redirect_uris: z3.array(SafeUrlSchema),
450
+ application_type: z3.union([z3.literal("native"), z3.literal("web")]).optional(),
433
451
  token_endpoint_auth_method: z3.string().optional(),
434
452
  grant_types: z3.array(z3.string()).optional(),
435
453
  response_types: z3.array(z3.string()).optional(),
@@ -534,8 +552,20 @@ var UnauthorizedError = class extends Error {
534
552
  function normalizeUrl(url) {
535
553
  return new URL(url).href;
536
554
  }
555
+ function validateAuthorizationResponseIssuer({
556
+ callbackIssuer,
557
+ expectedIssuer
558
+ }) {
559
+ if (callbackIssuer != null && callbackIssuer !== expectedIssuer) {
560
+ throw new MCPClientOAuthError({
561
+ message: `OAuth authorization response issuer ${callbackIssuer} does not match expected issuer ${expectedIssuer}`
562
+ });
563
+ }
564
+ }
537
565
  function createAuthorizationServerInformation(authorizationServerUrl, metadata) {
566
+ var _a3;
538
567
  return {
568
+ issuer: (_a3 = metadata == null ? void 0 : metadata.issuer) != null ? _a3 : String(authorizationServerUrl),
539
569
  authorizationServerUrl: normalizeUrl(authorizationServerUrl),
540
570
  tokenEndpoint: normalizeUrl(
541
571
  (metadata == null ? void 0 : metadata.token_endpoint) ? new URL(metadata.token_endpoint) : new URL("/token", authorizationServerUrl)
@@ -545,6 +575,7 @@ function createAuthorizationServerInformation(authorizationServerUrl, metadata)
545
575
  function addAuthorizationServerInformationToTokens(tokens, authorizationServerInformation) {
546
576
  return {
547
577
  ...tokens,
578
+ issuer: authorizationServerInformation.issuer,
548
579
  authorization_server: authorizationServerInformation.authorizationServerUrl,
549
580
  token_endpoint: authorizationServerInformation.tokenEndpoint
550
581
  };
@@ -552,6 +583,7 @@ function addAuthorizationServerInformationToTokens(tokens, authorizationServerIn
552
583
  function addAuthorizationServerInformationToClientInformation(clientInformation, authorizationServerInformation) {
553
584
  return {
554
585
  ...clientInformation,
586
+ issuer: authorizationServerInformation.issuer,
555
587
  authorization_server: authorizationServerInformation.authorizationServerUrl,
556
588
  token_endpoint: authorizationServerInformation.tokenEndpoint
557
589
  };
@@ -561,6 +593,7 @@ function getAuthorizationServerInformationFromCredentials(credentials) {
561
593
  return void 0;
562
594
  }
563
595
  return {
596
+ issuer: credentials.issuer,
564
597
  authorizationServerUrl: normalizeUrl(credentials.authorization_server),
565
598
  tokenEndpoint: normalizeUrl(credentials.token_endpoint)
566
599
  };
@@ -578,6 +611,7 @@ async function getStoredAuthorizationServerInformation({
578
611
  const providerAuthorizationServerInformation = await ((_a3 = provider.authorizationServerInformation) == null ? void 0 : _a3.call(provider));
579
612
  if (providerAuthorizationServerInformation) {
580
613
  return {
614
+ issuer: providerAuthorizationServerInformation.issuer,
581
615
  authorizationServerUrl: normalizeUrl(
582
616
  providerAuthorizationServerInformation.authorizationServerUrl
583
617
  ),
@@ -625,32 +659,47 @@ function assertAuthorizationServerInformationMatches({
625
659
  storedAuthorizationServerInformation,
626
660
  currentAuthorizationServerInformation
627
661
  }) {
628
- if (storedAuthorizationServerInformation.authorizationServerUrl !== currentAuthorizationServerInformation.authorizationServerUrl || storedAuthorizationServerInformation.tokenEndpoint !== currentAuthorizationServerInformation.tokenEndpoint) {
662
+ if (storedAuthorizationServerInformation.issuer != null && currentAuthorizationServerInformation.issuer != null && storedAuthorizationServerInformation.issuer !== currentAuthorizationServerInformation.issuer || storedAuthorizationServerInformation.authorizationServerUrl !== currentAuthorizationServerInformation.authorizationServerUrl || storedAuthorizationServerInformation.tokenEndpoint !== currentAuthorizationServerInformation.tokenEndpoint) {
629
663
  throw new MCPClientOAuthError({
630
664
  message: "OAuth authorization server metadata does not match the metadata that issued the stored credentials"
631
665
  });
632
666
  }
633
667
  }
634
- function extractResourceMetadataUrl(response) {
635
- var _a3;
668
+ function extractWWWAuthenticateParams(response) {
669
+ var _a3, _b3;
636
670
  const header = (_a3 = response.headers.get("www-authenticate")) != null ? _a3 : response.headers.get("WWW-Authenticate");
637
671
  if (!header) {
638
- return void 0;
672
+ return {};
639
673
  }
640
674
  const [type, scheme] = header.split(" ");
641
675
  if (type.toLowerCase() !== "bearer" || !scheme) {
642
- return void 0;
643
- }
644
- const regex = /resource_metadata="([^"]*)"/;
645
- const match = header.match(regex);
646
- if (!match) {
647
- return void 0;
676
+ return {};
648
677
  }
678
+ const resourceMetadataMatch = header.match(
679
+ /(?:^|[,\s])resource_metadata="([^"]*)"/i
680
+ );
681
+ const scope = (_b3 = header.match(/(?:^|[,\s])scope="([^"]*)"/i)) == null ? void 0 : _b3[1];
682
+ let resourceMetadataUrl;
649
683
  try {
650
- return new URL(match[1]);
684
+ resourceMetadataUrl = resourceMetadataMatch ? new URL(resourceMetadataMatch[1]) : void 0;
651
685
  } catch (e) {
652
- return void 0;
653
686
  }
687
+ return { resourceMetadataUrl, scope };
688
+ }
689
+ function selectScope({
690
+ scope,
691
+ resourceMetadata,
692
+ clientMetadata
693
+ }) {
694
+ var _a3;
695
+ if (scope) {
696
+ return scope;
697
+ }
698
+ const resourceScopes = (_a3 = resourceMetadata == null ? void 0 : resourceMetadata.scopes_supported) == null ? void 0 : _a3.join(" ");
699
+ if (resourceScopes) {
700
+ return resourceScopes;
701
+ }
702
+ return clientMetadata.scope;
654
703
  }
655
704
  function buildWellKnownPath(wellKnownPrefix, pathname = "", options = {}) {
656
705
  if (pathname.endsWith("/")) {
@@ -1059,6 +1108,7 @@ async function registerClient(authorizationServerUrl, {
1059
1108
  clientMetadata,
1060
1109
  fetchFn
1061
1110
  }) {
1111
+ var _a3;
1062
1112
  let registrationUrl;
1063
1113
  if (metadata) {
1064
1114
  if (!metadata.registration_endpoint) {
@@ -1070,18 +1120,29 @@ async function registerClient(authorizationServerUrl, {
1070
1120
  } else {
1071
1121
  registrationUrl = new URL("/register", authorizationServerUrl);
1072
1122
  }
1123
+ const applicationType = (_a3 = clientMetadata.application_type) != null ? _a3 : inferOAuthApplicationType(clientMetadata.redirect_uris);
1073
1124
  const response = await (fetchFn != null ? fetchFn : fetch)(registrationUrl, {
1074
1125
  method: "POST",
1075
1126
  headers: {
1076
1127
  "Content-Type": "application/json"
1077
1128
  },
1078
- body: JSON.stringify(clientMetadata)
1129
+ body: JSON.stringify({
1130
+ ...clientMetadata,
1131
+ application_type: applicationType
1132
+ })
1079
1133
  });
1080
1134
  if (!response.ok) {
1081
1135
  throw await parseErrorResponse(response);
1082
1136
  }
1083
1137
  return OAuthClientInformationFullSchema.parse(await response.json());
1084
1138
  }
1139
+ function inferOAuthApplicationType(redirectUris) {
1140
+ const isNativeRedirectUri = (redirectUri) => {
1141
+ const url = new URL(redirectUri);
1142
+ return (url.protocol === "http:" || url.protocol === "https:") && (url.hostname === "localhost" || url.hostname.endsWith(".localhost") || url.hostname === "127.0.0.1" || url.hostname === "[::1]") || url.protocol !== "http:" && url.protocol !== "https:";
1143
+ };
1144
+ return redirectUris.every(isNativeRedirectUri) ? "native" : "web";
1145
+ }
1085
1146
  async function auth(provider, options) {
1086
1147
  var _a3, _b3;
1087
1148
  try {
@@ -1122,11 +1183,12 @@ async function authInternal(provider, {
1122
1183
  serverUrl,
1123
1184
  authorizationCode,
1124
1185
  callbackState,
1186
+ callbackIssuer,
1125
1187
  scope,
1126
1188
  resourceMetadataUrl,
1127
1189
  fetchFn
1128
1190
  }) {
1129
- var _a3, _b3;
1191
+ var _a3, _b3, _c, _d;
1130
1192
  let resourceMetadata;
1131
1193
  let authorizationServerUrl;
1132
1194
  assertResourceMetadataUrlSameOrigin(serverUrl, resourceMetadataUrl);
@@ -1162,6 +1224,18 @@ async function authInternal(provider, {
1162
1224
  );
1163
1225
  const currentAuthorizationServerInformation = createAuthorizationServerInformation(authorizationServerUrl, metadata);
1164
1226
  let clientInformation = await Promise.resolve(provider.clientInformation());
1227
+ if ((clientInformation == null ? void 0 : clientInformation.issuer) != null) {
1228
+ const storedAuthorizationServerInformation = await getStoredAuthorizationServerInformation({
1229
+ provider,
1230
+ clientInformation
1231
+ });
1232
+ if (storedAuthorizationServerInformation) {
1233
+ assertAuthorizationServerInformationMatches({
1234
+ storedAuthorizationServerInformation,
1235
+ currentAuthorizationServerInformation
1236
+ });
1237
+ }
1238
+ }
1165
1239
  if (!clientInformation) {
1166
1240
  if (authorizationCode !== void 0) {
1167
1241
  throw new Error(
@@ -1202,6 +1276,10 @@ async function authInternal(provider, {
1202
1276
  message: "Stored OAuth authorization server metadata is required when exchanging an authorization code"
1203
1277
  });
1204
1278
  }
1279
+ validateAuthorizationResponseIssuer({
1280
+ callbackIssuer,
1281
+ expectedIssuer: (_c = (_b3 = storedAuthorizationServerInformation.issuer) != null ? _b3 : metadata == null ? void 0 : metadata.issuer) != null ? _c : String(authorizationServerUrl)
1282
+ });
1205
1283
  assertAuthorizationServerInformationMatches({
1206
1284
  storedAuthorizationServerInformation,
1207
1285
  currentAuthorizationServerInformation
@@ -1238,7 +1316,7 @@ async function authInternal(provider, {
1238
1316
  currentAuthorizationServerInformation
1239
1317
  });
1240
1318
  } else {
1241
- await ((_b3 = provider.invalidateCredentials) == null ? void 0 : _b3.call(provider, "tokens"));
1319
+ await ((_d = provider.invalidateCredentials) == null ? void 0 : _d.call(provider, "tokens"));
1242
1320
  }
1243
1321
  try {
1244
1322
  if (storedAuthorizationServerInformation) {
@@ -1279,7 +1357,11 @@ async function authInternal(provider, {
1279
1357
  clientInformation,
1280
1358
  state,
1281
1359
  redirectUrl: provider.redirectUrl,
1282
- scope: scope || provider.clientMetadata.scope,
1360
+ scope: selectScope({
1361
+ scope,
1362
+ resourceMetadata,
1363
+ clientMetadata: provider.clientMetadata
1364
+ }),
1283
1365
  resource
1284
1366
  }
1285
1367
  );
@@ -1325,7 +1407,7 @@ var SseMCPTransport = class {
1325
1407
  const headers = {
1326
1408
  ...this.headers,
1327
1409
  ...base,
1328
- "mcp-protocol-version": (_a3 = this.protocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION
1410
+ "mcp-protocol-version": (_a3 = this.protocolVersion) != null ? _a3 : LATEST_LEGACY_PROTOCOL_VERSION
1329
1411
  };
1330
1412
  if (this.authProvider) {
1331
1413
  const tokens = await this.authProvider.tokens();
@@ -1357,11 +1439,13 @@ var SseMCPTransport = class {
1357
1439
  redirect: this.redirectMode
1358
1440
  });
1359
1441
  if (response.status === 401 && this.authProvider && !triedAuth) {
1360
- this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1442
+ const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
1443
+ this.resourceMetadataUrl = resourceMetadataUrl;
1361
1444
  try {
1362
1445
  const result = await auth(this.authProvider, {
1363
1446
  serverUrl: this.url,
1364
1447
  resourceMetadataUrl: this.resourceMetadataUrl,
1448
+ scope,
1365
1449
  fetchFn: this.fetchFn
1366
1450
  });
1367
1451
  if (result !== "AUTHORIZED") {
@@ -1490,11 +1574,13 @@ var SseMCPTransport = class {
1490
1574
  };
1491
1575
  const response = await this.fetchFn(endpoint.href, init);
1492
1576
  if (response.status === 401 && this.authProvider && !triedAuth) {
1493
- this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1577
+ const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
1578
+ this.resourceMetadataUrl = resourceMetadataUrl;
1494
1579
  try {
1495
1580
  const result = await auth(this.authProvider, {
1496
1581
  serverUrl: this.url,
1497
1582
  resourceMetadataUrl: this.resourceMetadataUrl,
1583
+ scope,
1498
1584
  fetchFn: this.fetchFn
1499
1585
  });
1500
1586
  if (result !== "AUTHORIZED") {
@@ -1534,6 +1620,107 @@ import {
1534
1620
  withUserAgentSuffix as withUserAgentSuffix2,
1535
1621
  getRuntimeEnvironmentUserAgent as getRuntimeEnvironmentUserAgent2
1536
1622
  } from "@ai-sdk/provider-utils";
1623
+
1624
+ // src/tool/mcp-http-headers.ts
1625
+ import { convertUint8ArrayToBase64, isRecord } from "@ai-sdk/provider-utils";
1626
+ var HTTP_TOKEN_PATTERN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
1627
+ var BASE64_SENTINEL_PATTERN = /^=\?base64\?.*\?=$/;
1628
+ function encodeMCPHeaderValue(value) {
1629
+ const isPlainAscii = [...value].every((character) => {
1630
+ const code = character.charCodeAt(0);
1631
+ return code === 9 || code >= 32 && code <= 126;
1632
+ });
1633
+ if (isPlainAscii && value.trim() === value && !BASE64_SENTINEL_PATTERN.test(value)) {
1634
+ return value;
1635
+ }
1636
+ return `=?base64?${convertUint8ArrayToBase64(new TextEncoder().encode(value))}?=`;
1637
+ }
1638
+ function getMCPToolHeaderBindings(inputSchema) {
1639
+ if (!isRecord(inputSchema)) {
1640
+ return {
1641
+ success: false,
1642
+ error: "inputSchema must be a JSON Schema object"
1643
+ };
1644
+ }
1645
+ const bindings = [];
1646
+ const headerNames = /* @__PURE__ */ new Set();
1647
+ let error;
1648
+ const visit = (value, path, staticallyReachable) => {
1649
+ if (error != null || !isRecord(value)) {
1650
+ return;
1651
+ }
1652
+ if ("x-mcp-header" in value) {
1653
+ if (!staticallyReachable || path.length === 0) {
1654
+ error = "x-mcp-header is not on a statically reachable property";
1655
+ return;
1656
+ }
1657
+ const headerName = value["x-mcp-header"];
1658
+ if (typeof headerName !== "string" || !HTTP_TOKEN_PATTERN.test(headerName)) {
1659
+ error = "x-mcp-header must be a non-empty HTTP token";
1660
+ return;
1661
+ }
1662
+ const normalizedHeaderName = headerName.toLowerCase();
1663
+ if (headerNames.has(normalizedHeaderName)) {
1664
+ error = `x-mcp-header value "${headerName}" is not unique`;
1665
+ return;
1666
+ }
1667
+ const valueType = value.type;
1668
+ if (valueType !== "boolean" && valueType !== "integer" && valueType !== "string") {
1669
+ error = "x-mcp-header can only annotate boolean, integer, or string properties";
1670
+ return;
1671
+ }
1672
+ headerNames.add(normalizedHeaderName);
1673
+ bindings.push({ headerName, path, valueType });
1674
+ }
1675
+ for (const [key, child] of Object.entries(value)) {
1676
+ if (key === "x-mcp-header") {
1677
+ continue;
1678
+ }
1679
+ if (key === "properties" && isRecord(child)) {
1680
+ for (const [propertyName, propertySchema] of Object.entries(child)) {
1681
+ visit(propertySchema, [...path, propertyName], staticallyReachable);
1682
+ }
1683
+ } else {
1684
+ visit(child, path, false);
1685
+ }
1686
+ }
1687
+ };
1688
+ visit(inputSchema, [], true);
1689
+ return error == null ? { success: true, bindings } : { success: false, error };
1690
+ }
1691
+ function getValueAtPath(value, path) {
1692
+ let current = value;
1693
+ for (const segment of path) {
1694
+ if (!isRecord(current)) {
1695
+ return void 0;
1696
+ }
1697
+ current = current[segment];
1698
+ }
1699
+ return current;
1700
+ }
1701
+ function createMCPToolHeaders({
1702
+ bindings,
1703
+ args
1704
+ }) {
1705
+ const headers = {};
1706
+ for (const binding of bindings) {
1707
+ const value = getValueAtPath(args, binding.path);
1708
+ if (value == null) {
1709
+ continue;
1710
+ }
1711
+ if (binding.valueType === "string" && typeof value !== "string" || binding.valueType === "boolean" && typeof value !== "boolean" || binding.valueType === "integer" && !Number.isSafeInteger(value)) {
1712
+ throw new TypeError(
1713
+ `Tool argument "${binding.path.join(".")}" does not match its x-mcp-header type`
1714
+ );
1715
+ }
1716
+ headers[`Mcp-Param-${binding.headerName}`] = encodeMCPHeaderValue(
1717
+ String(value)
1718
+ );
1719
+ }
1720
+ return headers;
1721
+ }
1722
+
1723
+ // src/tool/mcp-http-transport.ts
1537
1724
  function isMessageEvent2(event) {
1538
1725
  return event === void 0 || event === "message";
1539
1726
  }
@@ -1550,6 +1737,8 @@ var HttpMCPTransport = class {
1550
1737
  terminateSessionOnClose = true,
1551
1738
  fetch: fetchFn
1552
1739
  }) {
1740
+ this.supportsProtocolVersionDiscovery = true;
1741
+ this.supportsMcpToolParameterHeaders = true;
1553
1742
  this.inboundReconnectAttempts = 0;
1554
1743
  this.reconnectionOptions = {
1555
1744
  initialReconnectionDelay: 1e3,
@@ -1562,14 +1751,30 @@ var HttpMCPTransport = class {
1562
1751
  this.authProvider = authProvider;
1563
1752
  this.redirectMode = redirect;
1564
1753
  this.sessionId = initialSessionId;
1565
- this.protocolVersion = initialProtocolVersion;
1754
+ this.protocolVersion = initialProtocolVersion != null ? initialProtocolVersion : LATEST_LEGACY_PROTOCOL_VERSION;
1566
1755
  this.onSessionIdChange = onSessionIdChange;
1567
1756
  this.onSessionExpired = onSessionExpired;
1568
1757
  this.terminateSessionOnClose = terminateSessionOnClose;
1569
1758
  this.fetchFn = fetchFn != null ? fetchFn : globalThis.fetch;
1570
1759
  }
1571
1760
  setProtocolVersion(version) {
1761
+ var _a3;
1572
1762
  this.protocolVersion = version;
1763
+ if (!this.abortController) {
1764
+ return;
1765
+ }
1766
+ if (this.isModernProtocol()) {
1767
+ (_a3 = this.inboundSseConnection) == null ? void 0 : _a3.close();
1768
+ this.inboundSseConnection = void 0;
1769
+ return;
1770
+ }
1771
+ if (!this.inboundSseConnection) {
1772
+ this.startInboundSse();
1773
+ }
1774
+ }
1775
+ isModernProtocol() {
1776
+ var _a3;
1777
+ return ((_a3 = this.protocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION) === LATEST_PROTOCOL_VERSION;
1573
1778
  }
1574
1779
  async commonHeaders({
1575
1780
  base,
@@ -1579,9 +1784,9 @@ var HttpMCPTransport = class {
1579
1784
  const headers = {
1580
1785
  ...this.headers,
1581
1786
  ...base,
1582
- "mcp-protocol-version": (_a3 = this.protocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION
1787
+ "mcp-protocol-version": (_a3 = this.protocolVersion) != null ? _a3 : LATEST_LEGACY_PROTOCOL_VERSION
1583
1788
  };
1584
- if (includeSessionId && this.sessionId) {
1789
+ if (!this.isModernProtocol() && includeSessionId && this.sessionId) {
1585
1790
  headers["mcp-session-id"] = this.sessionId;
1586
1791
  }
1587
1792
  if (this.authProvider) {
@@ -1605,6 +1810,9 @@ var HttpMCPTransport = class {
1605
1810
  (_a3 = this.onSessionIdChange) == null ? void 0 : _a3.call(this, sessionId);
1606
1811
  }
1607
1812
  applySessionIdFromResponse(response) {
1813
+ if (this.isModernProtocol()) {
1814
+ return;
1815
+ }
1608
1816
  const sessionId = response.headers.get("mcp-session-id");
1609
1817
  if (sessionId) {
1610
1818
  this.setSessionId(sessionId);
@@ -1620,7 +1828,7 @@ var HttpMCPTransport = class {
1620
1828
  /**
1621
1829
  * Runs a single OAuth recovery flow for concurrent 401 responses.
1622
1830
  */
1623
- authorizeOnce(resourceMetadataUrl) {
1831
+ authorizeOnce(resourceMetadataUrl, scope) {
1624
1832
  if (!this.authProvider) {
1625
1833
  return Promise.resolve("REDIRECT");
1626
1834
  }
@@ -1628,6 +1836,7 @@ var HttpMCPTransport = class {
1628
1836
  this.authPromise = auth(this.authProvider, {
1629
1837
  serverUrl: this.url,
1630
1838
  resourceMetadataUrl,
1839
+ scope,
1631
1840
  fetchFn: this.fetchFn
1632
1841
  }).finally(() => {
1633
1842
  this.authPromise = void 0;
@@ -1642,14 +1851,16 @@ var HttpMCPTransport = class {
1642
1851
  });
1643
1852
  }
1644
1853
  this.abortController = new AbortController();
1645
- this.startInboundSse();
1854
+ if (this.protocolVersion != null && this.protocolVersion !== LATEST_PROTOCOL_VERSION) {
1855
+ this.startInboundSse();
1856
+ }
1646
1857
  }
1647
1858
  async close(options) {
1648
1859
  var _a3, _b3, _c, _d, _e;
1649
1860
  (_a3 = this.inboundSseConnection) == null ? void 0 : _a3.close();
1650
1861
  (_b3 = this.abortController) == null ? void 0 : _b3.abort();
1651
1862
  try {
1652
- if (this.sessionId && this.terminateSessionOnClose && this.abortController) {
1863
+ if (!this.isModernProtocol() && this.sessionId && this.terminateSessionOnClose && this.abortController) {
1653
1864
  (_c = options == null ? void 0 : options.signal) == null ? void 0 : _c.throwIfAborted();
1654
1865
  const headers = await this.commonHeaders({ base: {} });
1655
1866
  (_d = options == null ? void 0 : options.signal) == null ? void 0 : _d.throwIfAborted();
@@ -1670,14 +1881,16 @@ var HttpMCPTransport = class {
1670
1881
  const transportSignal = (_b3 = this.abortController) == null ? void 0 : _b3.signal;
1671
1882
  const requestSignal = (options == null ? void 0 : options.signal) == null ? transportSignal : transportSignal == null ? options.signal : AbortSignal.any([transportSignal, options.signal]);
1672
1883
  const attempt = async (triedAuth = false) => {
1673
- var _a4, _b4, _c, _d, _e, _f, _g;
1884
+ var _a4, _b4, _c, _d, _e, _f, _g, _h;
1674
1885
  try {
1675
1886
  const isInitializeRequest = "method" in message && message.method === "initialize";
1676
1887
  const sessionIdForRequest = isInitializeRequest ? void 0 : this.sessionId;
1677
1888
  const headers = await this.commonHeaders({
1678
1889
  base: {
1679
1890
  "Content-Type": "application/json",
1680
- Accept: "application/json, text/event-stream"
1891
+ Accept: "application/json, text/event-stream",
1892
+ ...this.isModernProtocol() ? options == null ? void 0 : options.headers : {},
1893
+ ...this.isModernProtocol() && "method" in message && "id" in message ? this.getStandardRequestHeaders(message) : {}
1681
1894
  },
1682
1895
  includeSessionId: !isInitializeRequest
1683
1896
  });
@@ -1691,9 +1904,13 @@ var HttpMCPTransport = class {
1691
1904
  const response = await this.fetchFn(this.url.href, init);
1692
1905
  this.applySessionIdFromResponse(response);
1693
1906
  if (response.status === 401 && this.authProvider && !triedAuth) {
1694
- this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1907
+ const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
1908
+ this.resourceMetadataUrl = resourceMetadataUrl;
1695
1909
  try {
1696
- const result = await this.authorizeOnce(this.resourceMetadataUrl);
1910
+ const result = await this.authorizeOnce(
1911
+ this.resourceMetadataUrl,
1912
+ scope
1913
+ );
1697
1914
  if (result !== "AUTHORIZED") {
1698
1915
  const error2 = new UnauthorizedError();
1699
1916
  throw error2;
@@ -1705,19 +1922,31 @@ var HttpMCPTransport = class {
1705
1922
  return attempt(true);
1706
1923
  }
1707
1924
  if (response.status === 202) {
1708
- if (!this.inboundSseConnection) {
1925
+ if (!this.isModernProtocol() && !this.inboundSseConnection) {
1709
1926
  this.startInboundSse();
1710
1927
  }
1711
1928
  return;
1712
1929
  }
1713
1930
  if (!response.ok) {
1714
1931
  const text = await response.text().catch(() => null);
1932
+ if ("id" in message && text != null) {
1933
+ const jsonRpcMessage = await parseJSONRPCMessage(text).catch(
1934
+ () => void 0
1935
+ );
1936
+ if (jsonRpcMessage != null && "error" in jsonRpcMessage) {
1937
+ (_b4 = this.onmessage) == null ? void 0 : _b4.call(
1938
+ this,
1939
+ jsonRpcMessage.id == null ? { ...jsonRpcMessage, id: message.id } : jsonRpcMessage
1940
+ );
1941
+ return;
1942
+ }
1943
+ }
1715
1944
  let errorMessage = `MCP HTTP Transport Error: POSTing to endpoint (HTTP ${response.status}): ${text}`;
1716
1945
  if (response.status === 404) {
1717
- if (sessionIdForRequest) {
1946
+ if (!this.isModernProtocol() && sessionIdForRequest) {
1718
1947
  this.expireSessionId(sessionIdForRequest);
1719
1948
  errorMessage += ". The MCP session expired. Create a new client without `initialSessionId` to start a fresh session";
1720
- } else {
1949
+ } else if (!this.isModernProtocol()) {
1721
1950
  errorMessage += ". This server does not support HTTP transport. Try using `sse` transport instead";
1722
1951
  }
1723
1952
  }
@@ -1727,7 +1956,7 @@ var HttpMCPTransport = class {
1727
1956
  url: this.url.href,
1728
1957
  responseBody: text != null ? text : void 0
1729
1958
  });
1730
- (_b4 = this.onerror) == null ? void 0 : _b4.call(this, error2);
1959
+ (_c = this.onerror) == null ? void 0 : _c.call(this, error2);
1731
1960
  throw error2;
1732
1961
  }
1733
1962
  const isNotification = !("id" in message);
@@ -1739,7 +1968,7 @@ var HttpMCPTransport = class {
1739
1968
  const data = await response.json();
1740
1969
  const messages = Array.isArray(data) ? data.map((message2) => validateJSONRPCMessage(message2)) : [validateJSONRPCMessage(data)];
1741
1970
  for (const jsonRpcMessage of messages) {
1742
- (_c = this.onmessage) == null ? void 0 : _c.call(this, jsonRpcMessage);
1971
+ (_d = this.onmessage) == null ? void 0 : _d.call(this, jsonRpcMessage);
1743
1972
  }
1744
1973
  return;
1745
1974
  }
@@ -1750,7 +1979,7 @@ var HttpMCPTransport = class {
1750
1979
  statusCode: response.status,
1751
1980
  url: this.url.href
1752
1981
  });
1753
- (_d = this.onerror) == null ? void 0 : _d.call(this, error2);
1982
+ (_e = this.onerror) == null ? void 0 : _e.call(this, error2);
1754
1983
  throw error2;
1755
1984
  }
1756
1985
  const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream2());
@@ -1796,18 +2025,29 @@ var HttpMCPTransport = class {
1796
2025
  statusCode: response.status,
1797
2026
  url: this.url.href
1798
2027
  });
1799
- (_e = this.onerror) == null ? void 0 : _e.call(this, error);
2028
+ (_f = this.onerror) == null ? void 0 : _f.call(this, error);
1800
2029
  throw error;
1801
2030
  } catch (error) {
1802
- if ((_f = options == null ? void 0 : options.signal) == null ? void 0 : _f.aborted) {
2031
+ if ((_g = options == null ? void 0 : options.signal) == null ? void 0 : _g.aborted) {
1803
2032
  throw error;
1804
2033
  }
1805
- (_g = this.onerror) == null ? void 0 : _g.call(this, error);
2034
+ (_h = this.onerror) == null ? void 0 : _h.call(this, error);
1806
2035
  throw error;
1807
2036
  }
1808
2037
  };
1809
2038
  await attempt();
1810
2039
  }
2040
+ getStandardRequestHeaders(message) {
2041
+ const headers = {
2042
+ "Mcp-Method": message.method
2043
+ };
2044
+ const params = message.params;
2045
+ const name3 = message.method === "resources/read" ? params == null ? void 0 : params.uri : message.method === "tools/call" || message.method === "prompts/get" ? params == null ? void 0 : params.name : void 0;
2046
+ if (typeof name3 === "string") {
2047
+ headers["Mcp-Name"] = encodeMCPHeaderValue(name3);
2048
+ }
2049
+ return headers;
2050
+ }
1811
2051
  getNextReconnectionDelay(attempt) {
1812
2052
  const {
1813
2053
  initialReconnectionDelay,
@@ -1840,6 +2080,9 @@ var HttpMCPTransport = class {
1840
2080
  }, delay);
1841
2081
  }
1842
2082
  startInboundSse(triedAuth = false, resumeToken) {
2083
+ if (this.isModernProtocol()) {
2084
+ return;
2085
+ }
1843
2086
  void this.openInboundSse(triedAuth, resumeToken).catch((error) => {
1844
2087
  var _a3;
1845
2088
  if (error instanceof Error && error.name === "AbortError") {
@@ -1851,6 +2094,9 @@ var HttpMCPTransport = class {
1851
2094
  // Open optional inbound SSE stream; best-effort and resumable
1852
2095
  async openInboundSse(triedAuth = false, resumeToken) {
1853
2096
  var _a3, _b3, _c, _d, _e, _f;
2097
+ if (this.isModernProtocol()) {
2098
+ return;
2099
+ }
1854
2100
  try {
1855
2101
  const sessionIdForRequest = this.sessionId;
1856
2102
  const headers = await this.commonHeaders({
@@ -1869,9 +2115,13 @@ var HttpMCPTransport = class {
1869
2115
  });
1870
2116
  this.applySessionIdFromResponse(response);
1871
2117
  if (response.status === 401 && this.authProvider && !triedAuth) {
1872
- this.resourceMetadataUrl = extractResourceMetadataUrl(response);
2118
+ const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
2119
+ this.resourceMetadataUrl = resourceMetadataUrl;
1873
2120
  try {
1874
- const result = await this.authorizeOnce(this.resourceMetadataUrl);
2121
+ const result = await this.authorizeOnce(
2122
+ this.resourceMetadataUrl,
2123
+ scope
2124
+ );
1875
2125
  if (result !== "AUTHORIZED") {
1876
2126
  const error = new UnauthorizedError();
1877
2127
  (_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);
@@ -1969,11 +2219,15 @@ var HttpMCPTransport = class {
1969
2219
 
1970
2220
  // src/tool/mcp-transport.ts
1971
2221
  function createMcpTransport(config) {
2222
+ var _a3;
1972
2223
  switch (config.type) {
1973
2224
  case "sse":
1974
2225
  return new SseMCPTransport(config);
1975
2226
  case "http":
1976
- return new HttpMCPTransport(config);
2227
+ return new HttpMCPTransport({
2228
+ ...config,
2229
+ initialProtocolVersion: (_a3 = config.initialProtocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION
2230
+ });
1977
2231
  default:
1978
2232
  throw new MCPClientError({
1979
2233
  message: "Unsupported or invalid transport configuration. If you are using a custom transport, make sure it implements the MCPTransport interface."
@@ -2108,6 +2362,8 @@ async function readMCPAppResource({
2108
2362
  // src/tool/mcp-client.ts
2109
2363
  var CLIENT_VERSION = "1.0.0";
2110
2364
  var DEFAULT_MAX_TOOL_CALL_RETRIES = 0;
2365
+ var DEFAULT_PROTOCOL_DISCOVERY_TIMEOUT = 1e3;
2366
+ var MODERN_PROTOCOL_ERROR_CODES = [-32020, -32021, -32022];
2111
2367
  var DEFAULT_RETRY_ERROR_CODES = [
2112
2368
  "ConnectionRefused",
2113
2369
  "ConnectionClosed",
@@ -2233,23 +2489,28 @@ var DefaultMCPClient = class {
2233
2489
  maxRetries,
2234
2490
  capabilities,
2235
2491
  initialInitializeResult,
2236
- initializationOptions
2492
+ initializationOptions,
2493
+ protocolVersionDiscovery = true
2237
2494
  }) {
2238
2495
  this.requestMessageId = 0;
2239
2496
  this.responseHandlers = /* @__PURE__ */ new Map();
2240
2497
  this.serverCapabilities = {};
2241
2498
  this._serverInfo = { name: "", version: "" };
2242
2499
  this._initializeResult = {
2243
- protocolVersion: LATEST_PROTOCOL_VERSION,
2500
+ protocolVersion: LATEST_LEGACY_PROTOCOL_VERSION,
2244
2501
  capabilities: {},
2245
2502
  serverInfo: this._serverInfo
2246
2503
  };
2504
+ this.protocolEra = "legacy";
2505
+ this.protocolVersion = LATEST_LEGACY_PROTOCOL_VERSION;
2506
+ this.toolHeaderBindings = /* @__PURE__ */ new Map();
2247
2507
  this.isClosed = true;
2248
2508
  this.onUncaughtError = onUncaughtError;
2249
2509
  this.maxRetries = prepareMaxRetries(maxRetries);
2250
2510
  this.clientCapabilities = capabilities != null ? capabilities : {};
2251
2511
  this.initialInitializeResult = initialInitializeResult;
2252
2512
  this.initializationOptions = initializationOptions;
2513
+ this.protocolVersionDiscovery = protocolVersionDiscovery;
2253
2514
  if (isCustomMcpTransport(transportConfig)) {
2254
2515
  this.transport = transportConfig;
2255
2516
  } else {
@@ -2313,11 +2574,20 @@ var DefaultMCPClient = class {
2313
2574
  this.applyInitializeResult(result2);
2314
2575
  return this;
2315
2576
  }
2577
+ if (this.protocolVersionDiscovery && this.transport.supportsProtocolVersionDiscovery) {
2578
+ const discovered = await this.tryProtocolDiscovery(signal);
2579
+ if (discovered) {
2580
+ return this;
2581
+ }
2582
+ }
2583
+ this.protocolEra = "legacy";
2584
+ this.protocolVersion = LATEST_LEGACY_PROTOCOL_VERSION;
2585
+ this.setTransportProtocolVersion(this.protocolVersion);
2316
2586
  const result = await this.request({
2317
2587
  request: {
2318
2588
  method: "initialize",
2319
2589
  params: {
2320
- protocolVersion: LATEST_PROTOCOL_VERSION,
2590
+ protocolVersion: LATEST_LEGACY_PROTOCOL_VERSION,
2321
2591
  capabilities: this.clientCapabilities,
2322
2592
  clientInfo: this.clientInfo
2323
2593
  }
@@ -2360,6 +2630,55 @@ var DefaultMCPClient = class {
2360
2630
  }
2361
2631
  }
2362
2632
  }
2633
+ async tryProtocolDiscovery(signal) {
2634
+ this.protocolEra = "modern";
2635
+ this.protocolVersion = LATEST_PROTOCOL_VERSION;
2636
+ this.setTransportProtocolVersion(this.protocolVersion);
2637
+ try {
2638
+ const result = await this.request({
2639
+ request: { method: "server/discover" },
2640
+ resultSchema: DiscoverResultSchema,
2641
+ options: {
2642
+ signal,
2643
+ timeout: DEFAULT_PROTOCOL_DISCOVERY_TIMEOUT
2644
+ }
2645
+ });
2646
+ this.applyDiscoverResult(result);
2647
+ return true;
2648
+ } catch (error) {
2649
+ if (MCPClientError.isInstance(error) && error.code != null && MODERN_PROTOCOL_ERROR_CODES.includes(error.code)) {
2650
+ throw error;
2651
+ }
2652
+ return false;
2653
+ }
2654
+ }
2655
+ applyDiscoverResult(result) {
2656
+ var _a3;
2657
+ if (!result.supportedVersions.includes(this.protocolVersion)) {
2658
+ throw new MCPClientError({
2659
+ message: `Server does not support the requested protocol version: ${this.protocolVersion}`
2660
+ });
2661
+ }
2662
+ const serverInfo = (_a3 = result._meta) == null ? void 0 : _a3["io.modelcontextprotocol/serverInfo"];
2663
+ if (serverInfo != null && typeof serverInfo === "object" && "name" in serverInfo && typeof serverInfo.name === "string" && "version" in serverInfo && typeof serverInfo.version === "string") {
2664
+ this._serverInfo = serverInfo;
2665
+ }
2666
+ this.serverCapabilities = result.capabilities;
2667
+ this._serverInstructions = result.instructions;
2668
+ this._initializeResult = {
2669
+ protocolVersion: this.protocolVersion,
2670
+ capabilities: result.capabilities,
2671
+ serverInfo: this._serverInfo,
2672
+ instructions: result.instructions
2673
+ };
2674
+ }
2675
+ setTransportProtocolVersion(version) {
2676
+ if (this.transport.setProtocolVersion) {
2677
+ this.transport.setProtocolVersion(version);
2678
+ } else {
2679
+ this.transport.protocolVersion = version;
2680
+ }
2681
+ }
2363
2682
  applyInitializeResult(result) {
2364
2683
  if (!SUPPORTED_PROTOCOL_VERSIONS.includes(result.protocolVersion)) {
2365
2684
  throw new MCPClientError({
@@ -2367,13 +2686,11 @@ var DefaultMCPClient = class {
2367
2686
  });
2368
2687
  }
2369
2688
  this.serverCapabilities = result.capabilities;
2689
+ this.protocolEra = "legacy";
2690
+ this.protocolVersion = result.protocolVersion;
2370
2691
  this._serverInfo = result.serverInfo;
2371
2692
  this._initializeResult = result;
2372
- if (this.transport.setProtocolVersion) {
2373
- this.transport.setProtocolVersion(result.protocolVersion);
2374
- } else {
2375
- this.transport.protocolVersion = result.protocolVersion;
2376
- }
2693
+ this.setTransportProtocolVersion(result.protocolVersion);
2377
2694
  this._serverInstructions = result.instructions;
2378
2695
  }
2379
2696
  async close() {
@@ -2382,15 +2699,13 @@ var DefaultMCPClient = class {
2382
2699
  await ((_a3 = this.transport) == null ? void 0 : _a3.close());
2383
2700
  this.onClose();
2384
2701
  }
2385
- send(message, signal) {
2386
- return this.transport.send(
2387
- message,
2388
- signal == null ? void 0 : { signal }
2389
- );
2702
+ send(message, options) {
2703
+ return options == null ? this.transport.send(message) : this.transport.send(message, options);
2390
2704
  }
2391
2705
  assertCapability(method) {
2392
2706
  switch (method) {
2393
2707
  case "initialize":
2708
+ case "server/discover":
2394
2709
  break;
2395
2710
  case "completion/complete":
2396
2711
  if (!this.serverCapabilities.completions) {
@@ -2436,6 +2751,7 @@ var DefaultMCPClient = class {
2436
2751
  options
2437
2752
  }) {
2438
2753
  return new Promise((resolve, reject) => {
2754
+ var _a3;
2439
2755
  if (this.isClosed) {
2440
2756
  return reject(
2441
2757
  new MCPClientError({
@@ -2451,11 +2767,24 @@ var DefaultMCPClient = class {
2451
2767
  const transportSignal = signal == null ? timeoutController == null ? void 0 : timeoutController.signal : timeoutController == null ? signal : AbortSignal.any([signal, timeoutController.signal]);
2452
2768
  let timeoutId;
2453
2769
  const messageId = this.requestMessageId++;
2454
- const jsonrpcRequest = {
2770
+ const preparedRequest = this.protocolEra === "modern" ? {
2455
2771
  ...request,
2772
+ params: {
2773
+ ...request.params,
2774
+ _meta: {
2775
+ ...(_a3 = request.params) == null ? void 0 : _a3._meta,
2776
+ "io.modelcontextprotocol/protocolVersion": this.protocolVersion,
2777
+ "io.modelcontextprotocol/clientCapabilities": this.clientCapabilities,
2778
+ "io.modelcontextprotocol/clientInfo": this.clientInfo
2779
+ }
2780
+ }
2781
+ } : request;
2782
+ const jsonrpcRequest = {
2783
+ ...preparedRequest,
2456
2784
  jsonrpc: "2.0",
2457
2785
  id: messageId
2458
2786
  };
2787
+ const headers = this.getToolRequestHeaders(preparedRequest);
2459
2788
  const rejectWithAbortError = () => {
2460
2789
  reject(
2461
2790
  new MCPClientError({
@@ -2495,11 +2824,21 @@ var DefaultMCPClient = class {
2495
2824
  return rejectAndCleanup(response);
2496
2825
  }
2497
2826
  try {
2827
+ if (this.protocolEra === "modern" && response.result.resultType == null) {
2828
+ throw new MCPClientError({
2829
+ message: "Modern MCP result is missing resultType"
2830
+ });
2831
+ }
2832
+ if (response.result.resultType === "input_required") {
2833
+ throw new MCPClientError({
2834
+ message: "Server requested additional input, but multi round-trip requests are not supported yet"
2835
+ });
2836
+ }
2498
2837
  const result = resultSchema.parse(response.result);
2499
2838
  cleanup();
2500
2839
  resolve(result);
2501
2840
  } catch (error) {
2502
- const parseError = new MCPClientError({
2841
+ const parseError = MCPClientError.isInstance(error) ? error : new MCPClientError({
2503
2842
  message: "Failed to parse server response",
2504
2843
  cause: error
2505
2844
  });
@@ -2510,7 +2849,11 @@ var DefaultMCPClient = class {
2510
2849
  if (timeout != null) {
2511
2850
  timeoutId = setTimeout(onTimeout, timeout);
2512
2851
  }
2513
- const sendPromise = transportSignal == null ? this.transport.send(jsonrpcRequest) : this.send(jsonrpcRequest, transportSignal);
2852
+ const sendOptions = {
2853
+ ...transportSignal == null ? {} : { signal: transportSignal },
2854
+ ...headers == null ? {} : { headers }
2855
+ };
2856
+ const sendPromise = Object.keys(sendOptions).length === 0 ? this.send(jsonrpcRequest) : this.send(jsonrpcRequest, sendOptions);
2514
2857
  sendPromise.catch((error) => {
2515
2858
  rejectAndCleanup(error);
2516
2859
  });
@@ -2520,11 +2863,59 @@ var DefaultMCPClient = class {
2520
2863
  params,
2521
2864
  options
2522
2865
  } = {}) {
2523
- return this.request({
2866
+ const result = await this.request({
2524
2867
  request: { method: "tools/list", params },
2525
2868
  resultSchema: ListToolsResultSchema,
2526
2869
  options
2527
2870
  });
2871
+ return this.prepareToolDefinitions(result, (params == null ? void 0 : params.cursor) == null);
2872
+ }
2873
+ prepareToolDefinitions(definitions, resetHeaderBindings = false) {
2874
+ if (this.protocolEra !== "modern" || !this.transport.supportsMcpToolParameterHeaders) {
2875
+ return definitions;
2876
+ }
2877
+ if (resetHeaderBindings) {
2878
+ this.toolHeaderBindings.clear();
2879
+ }
2880
+ const tools = definitions.tools.filter((toolDefinition) => {
2881
+ const result = getMCPToolHeaderBindings(toolDefinition.inputSchema);
2882
+ if (!result.success) {
2883
+ this.onError(
2884
+ new MCPClientError({
2885
+ message: `Ignoring MCP tool "${toolDefinition.name}": ${result.error}`
2886
+ })
2887
+ );
2888
+ return false;
2889
+ }
2890
+ this.toolHeaderBindings.set(toolDefinition.name, result.bindings);
2891
+ return true;
2892
+ });
2893
+ return { ...definitions, tools };
2894
+ }
2895
+ getToolRequestHeaders(request) {
2896
+ var _a3;
2897
+ if (this.protocolEra !== "modern" || request.method !== "tools/call" || typeof ((_a3 = request.params) == null ? void 0 : _a3.name) !== "string") {
2898
+ return void 0;
2899
+ }
2900
+ const bindings = this.toolHeaderBindings.get(request.params.name);
2901
+ if (bindings == null || bindings.length === 0) {
2902
+ return void 0;
2903
+ }
2904
+ const args = request.params.arguments;
2905
+ if (args == null || typeof args !== "object" || Array.isArray(args)) {
2906
+ return void 0;
2907
+ }
2908
+ try {
2909
+ return createMCPToolHeaders({
2910
+ bindings,
2911
+ args
2912
+ });
2913
+ } catch (error) {
2914
+ throw new MCPClientError({
2915
+ message: `Failed to create MCP headers for tool "${request.params.name}"`,
2916
+ cause: error
2917
+ });
2918
+ }
2528
2919
  }
2529
2920
  async callToolWithRetry({
2530
2921
  options,
@@ -2650,7 +3041,10 @@ var DefaultMCPClient = class {
2650
3041
  jsonrpc: "2.0"
2651
3042
  };
2652
3043
  await waitForAbort(
2653
- this.send(jsonrpcNotification, options == null ? void 0 : options.signal),
3044
+ this.send(
3045
+ jsonrpcNotification,
3046
+ (options == null ? void 0 : options.signal) == null ? void 0 : { signal: options.signal }
3047
+ ),
2654
3048
  options == null ? void 0 : options.signal
2655
3049
  );
2656
3050
  }
@@ -2672,6 +3066,7 @@ var DefaultMCPClient = class {
2672
3066
  */
2673
3067
  toolsFromDefinitions(definitions, { schemas = "automatic" } = {}) {
2674
3068
  var _a3, _b3;
3069
+ definitions = this.prepareToolDefinitions(definitions);
2675
3070
  const tools = {};
2676
3071
  for (const {
2677
3072
  name: name3,
@@ -2905,6 +3300,16 @@ var DefaultMCPClient = class {
2905
3300
  }
2906
3301
  }
2907
3302
  onResponse(response) {
3303
+ if (response.id == null) {
3304
+ this.onError(
3305
+ new MCPClientError({
3306
+ message: `Protocol error: Received a response without a message ID: ${JSON.stringify(
3307
+ response
3308
+ )}`
3309
+ })
3310
+ );
3311
+ return;
3312
+ }
2908
3313
  const messageId = Number(response.id);
2909
3314
  const handler = this.responseHandlers.get(messageId);
2910
3315
  if (handler === void 0) {
@@ -2927,7 +3332,7 @@ var DefaultMCPClient = class {
2927
3332
  };
2928
3333
 
2929
3334
  // src/tool/mcp-app-fingerprint.ts
2930
- import { convertUint8ArrayToBase64 } from "@ai-sdk/provider-utils";
3335
+ import { convertUint8ArrayToBase64 as convertUint8ArrayToBase642 } from "@ai-sdk/provider-utils";
2931
3336
  var encoder = new TextEncoder();
2932
3337
  function canonicalJSON(value) {
2933
3338
  if (value == null || typeof value !== "object") {
@@ -2941,7 +3346,7 @@ function canonicalJSON(value) {
2941
3346
  return `{${entries.join(",")}}`;
2942
3347
  }
2943
3348
  function toBase64url(bytes) {
2944
- return convertUint8ArrayToBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
3349
+ return convertUint8ArrayToBase642(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
2945
3350
  }
2946
3351
  async function fingerprintMCPAppResource(resource) {
2947
3352
  var _a3, _b3, _c, _d;