@ai-sdk/mcp 2.0.32 → 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,7 +659,7 @@ 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
  });
@@ -1074,6 +1108,7 @@ async function registerClient(authorizationServerUrl, {
1074
1108
  clientMetadata,
1075
1109
  fetchFn
1076
1110
  }) {
1111
+ var _a3;
1077
1112
  let registrationUrl;
1078
1113
  if (metadata) {
1079
1114
  if (!metadata.registration_endpoint) {
@@ -1085,18 +1120,29 @@ async function registerClient(authorizationServerUrl, {
1085
1120
  } else {
1086
1121
  registrationUrl = new URL("/register", authorizationServerUrl);
1087
1122
  }
1123
+ const applicationType = (_a3 = clientMetadata.application_type) != null ? _a3 : inferOAuthApplicationType(clientMetadata.redirect_uris);
1088
1124
  const response = await (fetchFn != null ? fetchFn : fetch)(registrationUrl, {
1089
1125
  method: "POST",
1090
1126
  headers: {
1091
1127
  "Content-Type": "application/json"
1092
1128
  },
1093
- body: JSON.stringify(clientMetadata)
1129
+ body: JSON.stringify({
1130
+ ...clientMetadata,
1131
+ application_type: applicationType
1132
+ })
1094
1133
  });
1095
1134
  if (!response.ok) {
1096
1135
  throw await parseErrorResponse(response);
1097
1136
  }
1098
1137
  return OAuthClientInformationFullSchema.parse(await response.json());
1099
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
+ }
1100
1146
  async function auth(provider, options) {
1101
1147
  var _a3, _b3;
1102
1148
  try {
@@ -1137,11 +1183,12 @@ async function authInternal(provider, {
1137
1183
  serverUrl,
1138
1184
  authorizationCode,
1139
1185
  callbackState,
1186
+ callbackIssuer,
1140
1187
  scope,
1141
1188
  resourceMetadataUrl,
1142
1189
  fetchFn
1143
1190
  }) {
1144
- var _a3, _b3;
1191
+ var _a3, _b3, _c, _d;
1145
1192
  let resourceMetadata;
1146
1193
  let authorizationServerUrl;
1147
1194
  assertResourceMetadataUrlSameOrigin(serverUrl, resourceMetadataUrl);
@@ -1177,6 +1224,18 @@ async function authInternal(provider, {
1177
1224
  );
1178
1225
  const currentAuthorizationServerInformation = createAuthorizationServerInformation(authorizationServerUrl, metadata);
1179
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
+ }
1180
1239
  if (!clientInformation) {
1181
1240
  if (authorizationCode !== void 0) {
1182
1241
  throw new Error(
@@ -1217,6 +1276,10 @@ async function authInternal(provider, {
1217
1276
  message: "Stored OAuth authorization server metadata is required when exchanging an authorization code"
1218
1277
  });
1219
1278
  }
1279
+ validateAuthorizationResponseIssuer({
1280
+ callbackIssuer,
1281
+ expectedIssuer: (_c = (_b3 = storedAuthorizationServerInformation.issuer) != null ? _b3 : metadata == null ? void 0 : metadata.issuer) != null ? _c : String(authorizationServerUrl)
1282
+ });
1220
1283
  assertAuthorizationServerInformationMatches({
1221
1284
  storedAuthorizationServerInformation,
1222
1285
  currentAuthorizationServerInformation
@@ -1253,7 +1316,7 @@ async function authInternal(provider, {
1253
1316
  currentAuthorizationServerInformation
1254
1317
  });
1255
1318
  } else {
1256
- await ((_b3 = provider.invalidateCredentials) == null ? void 0 : _b3.call(provider, "tokens"));
1319
+ await ((_d = provider.invalidateCredentials) == null ? void 0 : _d.call(provider, "tokens"));
1257
1320
  }
1258
1321
  try {
1259
1322
  if (storedAuthorizationServerInformation) {
@@ -1344,7 +1407,7 @@ var SseMCPTransport = class {
1344
1407
  const headers = {
1345
1408
  ...this.headers,
1346
1409
  ...base,
1347
- "mcp-protocol-version": (_a3 = this.protocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION
1410
+ "mcp-protocol-version": (_a3 = this.protocolVersion) != null ? _a3 : LATEST_LEGACY_PROTOCOL_VERSION
1348
1411
  };
1349
1412
  if (this.authProvider) {
1350
1413
  const tokens = await this.authProvider.tokens();
@@ -1557,6 +1620,107 @@ import {
1557
1620
  withUserAgentSuffix as withUserAgentSuffix2,
1558
1621
  getRuntimeEnvironmentUserAgent as getRuntimeEnvironmentUserAgent2
1559
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
1560
1724
  function isMessageEvent2(event) {
1561
1725
  return event === void 0 || event === "message";
1562
1726
  }
@@ -1573,6 +1737,8 @@ var HttpMCPTransport = class {
1573
1737
  terminateSessionOnClose = true,
1574
1738
  fetch: fetchFn
1575
1739
  }) {
1740
+ this.supportsProtocolVersionDiscovery = true;
1741
+ this.supportsMcpToolParameterHeaders = true;
1576
1742
  this.inboundReconnectAttempts = 0;
1577
1743
  this.reconnectionOptions = {
1578
1744
  initialReconnectionDelay: 1e3,
@@ -1585,14 +1751,30 @@ var HttpMCPTransport = class {
1585
1751
  this.authProvider = authProvider;
1586
1752
  this.redirectMode = redirect;
1587
1753
  this.sessionId = initialSessionId;
1588
- this.protocolVersion = initialProtocolVersion;
1754
+ this.protocolVersion = initialProtocolVersion != null ? initialProtocolVersion : LATEST_LEGACY_PROTOCOL_VERSION;
1589
1755
  this.onSessionIdChange = onSessionIdChange;
1590
1756
  this.onSessionExpired = onSessionExpired;
1591
1757
  this.terminateSessionOnClose = terminateSessionOnClose;
1592
1758
  this.fetchFn = fetchFn != null ? fetchFn : globalThis.fetch;
1593
1759
  }
1594
1760
  setProtocolVersion(version) {
1761
+ var _a3;
1595
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;
1596
1778
  }
1597
1779
  async commonHeaders({
1598
1780
  base,
@@ -1602,9 +1784,9 @@ var HttpMCPTransport = class {
1602
1784
  const headers = {
1603
1785
  ...this.headers,
1604
1786
  ...base,
1605
- "mcp-protocol-version": (_a3 = this.protocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION
1787
+ "mcp-protocol-version": (_a3 = this.protocolVersion) != null ? _a3 : LATEST_LEGACY_PROTOCOL_VERSION
1606
1788
  };
1607
- if (includeSessionId && this.sessionId) {
1789
+ if (!this.isModernProtocol() && includeSessionId && this.sessionId) {
1608
1790
  headers["mcp-session-id"] = this.sessionId;
1609
1791
  }
1610
1792
  if (this.authProvider) {
@@ -1628,6 +1810,9 @@ var HttpMCPTransport = class {
1628
1810
  (_a3 = this.onSessionIdChange) == null ? void 0 : _a3.call(this, sessionId);
1629
1811
  }
1630
1812
  applySessionIdFromResponse(response) {
1813
+ if (this.isModernProtocol()) {
1814
+ return;
1815
+ }
1631
1816
  const sessionId = response.headers.get("mcp-session-id");
1632
1817
  if (sessionId) {
1633
1818
  this.setSessionId(sessionId);
@@ -1666,14 +1851,16 @@ var HttpMCPTransport = class {
1666
1851
  });
1667
1852
  }
1668
1853
  this.abortController = new AbortController();
1669
- this.startInboundSse();
1854
+ if (this.protocolVersion != null && this.protocolVersion !== LATEST_PROTOCOL_VERSION) {
1855
+ this.startInboundSse();
1856
+ }
1670
1857
  }
1671
1858
  async close(options) {
1672
1859
  var _a3, _b3, _c, _d, _e;
1673
1860
  (_a3 = this.inboundSseConnection) == null ? void 0 : _a3.close();
1674
1861
  (_b3 = this.abortController) == null ? void 0 : _b3.abort();
1675
1862
  try {
1676
- if (this.sessionId && this.terminateSessionOnClose && this.abortController) {
1863
+ if (!this.isModernProtocol() && this.sessionId && this.terminateSessionOnClose && this.abortController) {
1677
1864
  (_c = options == null ? void 0 : options.signal) == null ? void 0 : _c.throwIfAborted();
1678
1865
  const headers = await this.commonHeaders({ base: {} });
1679
1866
  (_d = options == null ? void 0 : options.signal) == null ? void 0 : _d.throwIfAborted();
@@ -1694,14 +1881,16 @@ var HttpMCPTransport = class {
1694
1881
  const transportSignal = (_b3 = this.abortController) == null ? void 0 : _b3.signal;
1695
1882
  const requestSignal = (options == null ? void 0 : options.signal) == null ? transportSignal : transportSignal == null ? options.signal : AbortSignal.any([transportSignal, options.signal]);
1696
1883
  const attempt = async (triedAuth = false) => {
1697
- var _a4, _b4, _c, _d, _e, _f, _g;
1884
+ var _a4, _b4, _c, _d, _e, _f, _g, _h;
1698
1885
  try {
1699
1886
  const isInitializeRequest = "method" in message && message.method === "initialize";
1700
1887
  const sessionIdForRequest = isInitializeRequest ? void 0 : this.sessionId;
1701
1888
  const headers = await this.commonHeaders({
1702
1889
  base: {
1703
1890
  "Content-Type": "application/json",
1704
- 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) : {}
1705
1894
  },
1706
1895
  includeSessionId: !isInitializeRequest
1707
1896
  });
@@ -1733,19 +1922,31 @@ var HttpMCPTransport = class {
1733
1922
  return attempt(true);
1734
1923
  }
1735
1924
  if (response.status === 202) {
1736
- if (!this.inboundSseConnection) {
1925
+ if (!this.isModernProtocol() && !this.inboundSseConnection) {
1737
1926
  this.startInboundSse();
1738
1927
  }
1739
1928
  return;
1740
1929
  }
1741
1930
  if (!response.ok) {
1742
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
+ }
1743
1944
  let errorMessage = `MCP HTTP Transport Error: POSTing to endpoint (HTTP ${response.status}): ${text}`;
1744
1945
  if (response.status === 404) {
1745
- if (sessionIdForRequest) {
1946
+ if (!this.isModernProtocol() && sessionIdForRequest) {
1746
1947
  this.expireSessionId(sessionIdForRequest);
1747
1948
  errorMessage += ". The MCP session expired. Create a new client without `initialSessionId` to start a fresh session";
1748
- } else {
1949
+ } else if (!this.isModernProtocol()) {
1749
1950
  errorMessage += ". This server does not support HTTP transport. Try using `sse` transport instead";
1750
1951
  }
1751
1952
  }
@@ -1755,7 +1956,7 @@ var HttpMCPTransport = class {
1755
1956
  url: this.url.href,
1756
1957
  responseBody: text != null ? text : void 0
1757
1958
  });
1758
- (_b4 = this.onerror) == null ? void 0 : _b4.call(this, error2);
1959
+ (_c = this.onerror) == null ? void 0 : _c.call(this, error2);
1759
1960
  throw error2;
1760
1961
  }
1761
1962
  const isNotification = !("id" in message);
@@ -1767,7 +1968,7 @@ var HttpMCPTransport = class {
1767
1968
  const data = await response.json();
1768
1969
  const messages = Array.isArray(data) ? data.map((message2) => validateJSONRPCMessage(message2)) : [validateJSONRPCMessage(data)];
1769
1970
  for (const jsonRpcMessage of messages) {
1770
- (_c = this.onmessage) == null ? void 0 : _c.call(this, jsonRpcMessage);
1971
+ (_d = this.onmessage) == null ? void 0 : _d.call(this, jsonRpcMessage);
1771
1972
  }
1772
1973
  return;
1773
1974
  }
@@ -1778,7 +1979,7 @@ var HttpMCPTransport = class {
1778
1979
  statusCode: response.status,
1779
1980
  url: this.url.href
1780
1981
  });
1781
- (_d = this.onerror) == null ? void 0 : _d.call(this, error2);
1982
+ (_e = this.onerror) == null ? void 0 : _e.call(this, error2);
1782
1983
  throw error2;
1783
1984
  }
1784
1985
  const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream2());
@@ -1824,18 +2025,29 @@ var HttpMCPTransport = class {
1824
2025
  statusCode: response.status,
1825
2026
  url: this.url.href
1826
2027
  });
1827
- (_e = this.onerror) == null ? void 0 : _e.call(this, error);
2028
+ (_f = this.onerror) == null ? void 0 : _f.call(this, error);
1828
2029
  throw error;
1829
2030
  } catch (error) {
1830
- 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) {
1831
2032
  throw error;
1832
2033
  }
1833
- (_g = this.onerror) == null ? void 0 : _g.call(this, error);
2034
+ (_h = this.onerror) == null ? void 0 : _h.call(this, error);
1834
2035
  throw error;
1835
2036
  }
1836
2037
  };
1837
2038
  await attempt();
1838
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
+ }
1839
2051
  getNextReconnectionDelay(attempt) {
1840
2052
  const {
1841
2053
  initialReconnectionDelay,
@@ -1868,6 +2080,9 @@ var HttpMCPTransport = class {
1868
2080
  }, delay);
1869
2081
  }
1870
2082
  startInboundSse(triedAuth = false, resumeToken) {
2083
+ if (this.isModernProtocol()) {
2084
+ return;
2085
+ }
1871
2086
  void this.openInboundSse(triedAuth, resumeToken).catch((error) => {
1872
2087
  var _a3;
1873
2088
  if (error instanceof Error && error.name === "AbortError") {
@@ -1879,6 +2094,9 @@ var HttpMCPTransport = class {
1879
2094
  // Open optional inbound SSE stream; best-effort and resumable
1880
2095
  async openInboundSse(triedAuth = false, resumeToken) {
1881
2096
  var _a3, _b3, _c, _d, _e, _f;
2097
+ if (this.isModernProtocol()) {
2098
+ return;
2099
+ }
1882
2100
  try {
1883
2101
  const sessionIdForRequest = this.sessionId;
1884
2102
  const headers = await this.commonHeaders({
@@ -2001,11 +2219,15 @@ var HttpMCPTransport = class {
2001
2219
 
2002
2220
  // src/tool/mcp-transport.ts
2003
2221
  function createMcpTransport(config) {
2222
+ var _a3;
2004
2223
  switch (config.type) {
2005
2224
  case "sse":
2006
2225
  return new SseMCPTransport(config);
2007
2226
  case "http":
2008
- return new HttpMCPTransport(config);
2227
+ return new HttpMCPTransport({
2228
+ ...config,
2229
+ initialProtocolVersion: (_a3 = config.initialProtocolVersion) != null ? _a3 : LATEST_PROTOCOL_VERSION
2230
+ });
2009
2231
  default:
2010
2232
  throw new MCPClientError({
2011
2233
  message: "Unsupported or invalid transport configuration. If you are using a custom transport, make sure it implements the MCPTransport interface."
@@ -2140,6 +2362,8 @@ async function readMCPAppResource({
2140
2362
  // src/tool/mcp-client.ts
2141
2363
  var CLIENT_VERSION = "1.0.0";
2142
2364
  var DEFAULT_MAX_TOOL_CALL_RETRIES = 0;
2365
+ var DEFAULT_PROTOCOL_DISCOVERY_TIMEOUT = 1e3;
2366
+ var MODERN_PROTOCOL_ERROR_CODES = [-32020, -32021, -32022];
2143
2367
  var DEFAULT_RETRY_ERROR_CODES = [
2144
2368
  "ConnectionRefused",
2145
2369
  "ConnectionClosed",
@@ -2265,23 +2489,28 @@ var DefaultMCPClient = class {
2265
2489
  maxRetries,
2266
2490
  capabilities,
2267
2491
  initialInitializeResult,
2268
- initializationOptions
2492
+ initializationOptions,
2493
+ protocolVersionDiscovery = true
2269
2494
  }) {
2270
2495
  this.requestMessageId = 0;
2271
2496
  this.responseHandlers = /* @__PURE__ */ new Map();
2272
2497
  this.serverCapabilities = {};
2273
2498
  this._serverInfo = { name: "", version: "" };
2274
2499
  this._initializeResult = {
2275
- protocolVersion: LATEST_PROTOCOL_VERSION,
2500
+ protocolVersion: LATEST_LEGACY_PROTOCOL_VERSION,
2276
2501
  capabilities: {},
2277
2502
  serverInfo: this._serverInfo
2278
2503
  };
2504
+ this.protocolEra = "legacy";
2505
+ this.protocolVersion = LATEST_LEGACY_PROTOCOL_VERSION;
2506
+ this.toolHeaderBindings = /* @__PURE__ */ new Map();
2279
2507
  this.isClosed = true;
2280
2508
  this.onUncaughtError = onUncaughtError;
2281
2509
  this.maxRetries = prepareMaxRetries(maxRetries);
2282
2510
  this.clientCapabilities = capabilities != null ? capabilities : {};
2283
2511
  this.initialInitializeResult = initialInitializeResult;
2284
2512
  this.initializationOptions = initializationOptions;
2513
+ this.protocolVersionDiscovery = protocolVersionDiscovery;
2285
2514
  if (isCustomMcpTransport(transportConfig)) {
2286
2515
  this.transport = transportConfig;
2287
2516
  } else {
@@ -2345,11 +2574,20 @@ var DefaultMCPClient = class {
2345
2574
  this.applyInitializeResult(result2);
2346
2575
  return this;
2347
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);
2348
2586
  const result = await this.request({
2349
2587
  request: {
2350
2588
  method: "initialize",
2351
2589
  params: {
2352
- protocolVersion: LATEST_PROTOCOL_VERSION,
2590
+ protocolVersion: LATEST_LEGACY_PROTOCOL_VERSION,
2353
2591
  capabilities: this.clientCapabilities,
2354
2592
  clientInfo: this.clientInfo
2355
2593
  }
@@ -2392,6 +2630,55 @@ var DefaultMCPClient = class {
2392
2630
  }
2393
2631
  }
2394
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
+ }
2395
2682
  applyInitializeResult(result) {
2396
2683
  if (!SUPPORTED_PROTOCOL_VERSIONS.includes(result.protocolVersion)) {
2397
2684
  throw new MCPClientError({
@@ -2399,13 +2686,11 @@ var DefaultMCPClient = class {
2399
2686
  });
2400
2687
  }
2401
2688
  this.serverCapabilities = result.capabilities;
2689
+ this.protocolEra = "legacy";
2690
+ this.protocolVersion = result.protocolVersion;
2402
2691
  this._serverInfo = result.serverInfo;
2403
2692
  this._initializeResult = result;
2404
- if (this.transport.setProtocolVersion) {
2405
- this.transport.setProtocolVersion(result.protocolVersion);
2406
- } else {
2407
- this.transport.protocolVersion = result.protocolVersion;
2408
- }
2693
+ this.setTransportProtocolVersion(result.protocolVersion);
2409
2694
  this._serverInstructions = result.instructions;
2410
2695
  }
2411
2696
  async close() {
@@ -2414,15 +2699,13 @@ var DefaultMCPClient = class {
2414
2699
  await ((_a3 = this.transport) == null ? void 0 : _a3.close());
2415
2700
  this.onClose();
2416
2701
  }
2417
- send(message, signal) {
2418
- return this.transport.send(
2419
- message,
2420
- signal == null ? void 0 : { signal }
2421
- );
2702
+ send(message, options) {
2703
+ return options == null ? this.transport.send(message) : this.transport.send(message, options);
2422
2704
  }
2423
2705
  assertCapability(method) {
2424
2706
  switch (method) {
2425
2707
  case "initialize":
2708
+ case "server/discover":
2426
2709
  break;
2427
2710
  case "completion/complete":
2428
2711
  if (!this.serverCapabilities.completions) {
@@ -2468,6 +2751,7 @@ var DefaultMCPClient = class {
2468
2751
  options
2469
2752
  }) {
2470
2753
  return new Promise((resolve, reject) => {
2754
+ var _a3;
2471
2755
  if (this.isClosed) {
2472
2756
  return reject(
2473
2757
  new MCPClientError({
@@ -2483,11 +2767,24 @@ var DefaultMCPClient = class {
2483
2767
  const transportSignal = signal == null ? timeoutController == null ? void 0 : timeoutController.signal : timeoutController == null ? signal : AbortSignal.any([signal, timeoutController.signal]);
2484
2768
  let timeoutId;
2485
2769
  const messageId = this.requestMessageId++;
2486
- const jsonrpcRequest = {
2770
+ const preparedRequest = this.protocolEra === "modern" ? {
2487
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,
2488
2784
  jsonrpc: "2.0",
2489
2785
  id: messageId
2490
2786
  };
2787
+ const headers = this.getToolRequestHeaders(preparedRequest);
2491
2788
  const rejectWithAbortError = () => {
2492
2789
  reject(
2493
2790
  new MCPClientError({
@@ -2527,11 +2824,21 @@ var DefaultMCPClient = class {
2527
2824
  return rejectAndCleanup(response);
2528
2825
  }
2529
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
+ }
2530
2837
  const result = resultSchema.parse(response.result);
2531
2838
  cleanup();
2532
2839
  resolve(result);
2533
2840
  } catch (error) {
2534
- const parseError = new MCPClientError({
2841
+ const parseError = MCPClientError.isInstance(error) ? error : new MCPClientError({
2535
2842
  message: "Failed to parse server response",
2536
2843
  cause: error
2537
2844
  });
@@ -2542,7 +2849,11 @@ var DefaultMCPClient = class {
2542
2849
  if (timeout != null) {
2543
2850
  timeoutId = setTimeout(onTimeout, timeout);
2544
2851
  }
2545
- 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);
2546
2857
  sendPromise.catch((error) => {
2547
2858
  rejectAndCleanup(error);
2548
2859
  });
@@ -2552,11 +2863,59 @@ var DefaultMCPClient = class {
2552
2863
  params,
2553
2864
  options
2554
2865
  } = {}) {
2555
- return this.request({
2866
+ const result = await this.request({
2556
2867
  request: { method: "tools/list", params },
2557
2868
  resultSchema: ListToolsResultSchema,
2558
2869
  options
2559
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
+ }
2560
2919
  }
2561
2920
  async callToolWithRetry({
2562
2921
  options,
@@ -2682,7 +3041,10 @@ var DefaultMCPClient = class {
2682
3041
  jsonrpc: "2.0"
2683
3042
  };
2684
3043
  await waitForAbort(
2685
- 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
+ ),
2686
3048
  options == null ? void 0 : options.signal
2687
3049
  );
2688
3050
  }
@@ -2704,6 +3066,7 @@ var DefaultMCPClient = class {
2704
3066
  */
2705
3067
  toolsFromDefinitions(definitions, { schemas = "automatic" } = {}) {
2706
3068
  var _a3, _b3;
3069
+ definitions = this.prepareToolDefinitions(definitions);
2707
3070
  const tools = {};
2708
3071
  for (const {
2709
3072
  name: name3,
@@ -2937,6 +3300,16 @@ var DefaultMCPClient = class {
2937
3300
  }
2938
3301
  }
2939
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
+ }
2940
3313
  const messageId = Number(response.id);
2941
3314
  const handler = this.responseHandlers.get(messageId);
2942
3315
  if (handler === void 0) {
@@ -2959,7 +3332,7 @@ var DefaultMCPClient = class {
2959
3332
  };
2960
3333
 
2961
3334
  // src/tool/mcp-app-fingerprint.ts
2962
- import { convertUint8ArrayToBase64 } from "@ai-sdk/provider-utils";
3335
+ import { convertUint8ArrayToBase64 as convertUint8ArrayToBase642 } from "@ai-sdk/provider-utils";
2963
3336
  var encoder = new TextEncoder();
2964
3337
  function canonicalJSON(value) {
2965
3338
  if (value == null || typeof value !== "object") {
@@ -2973,7 +3346,7 @@ function canonicalJSON(value) {
2973
3346
  return `{${entries.join(",")}}`;
2974
3347
  }
2975
3348
  function toBase64url(bytes) {
2976
- return convertUint8ArrayToBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
3349
+ return convertUint8ArrayToBase642(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
2977
3350
  }
2978
3351
  async function fingerprintMCPAppResource(resource) {
2979
3352
  var _a3, _b3, _c, _d;