@ai-sdk/mcp 2.0.0-beta.0 → 2.0.0-beta.10

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/CHANGELOG.md CHANGED
@@ -1,5 +1,75 @@
1
1
  # @ai-sdk/mcp
2
2
 
3
+ ## 2.0.0-beta.10
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [3887c70]
8
+ - @ai-sdk/provider-utils@5.0.0-beta.6
9
+ - @ai-sdk/provider@4.0.0-beta.4
10
+
11
+ ## 2.0.0-beta.9
12
+
13
+ ### Patch Changes
14
+
15
+ - Updated dependencies [776b617]
16
+ - @ai-sdk/provider-utils@5.0.0-beta.5
17
+ - @ai-sdk/provider@4.0.0-beta.3
18
+
19
+ ## 2.0.0-beta.8
20
+
21
+ ### Patch Changes
22
+
23
+ - Updated dependencies [61753c3]
24
+ - @ai-sdk/provider-utils@5.0.0-beta.4
25
+
26
+ ## 2.0.0-beta.7
27
+
28
+ ### Major Changes
29
+
30
+ - 23fa161: fix(mcp): setting redirect: error for MCP transport
31
+
32
+ ## 2.0.0-beta.6
33
+
34
+ ### Patch Changes
35
+
36
+ - 58c9eb1: feat(mcp): add `redirect` option to `MCPTransportConfig` for controlling HTTP redirect behavior
37
+
38
+ ## 2.0.0-beta.5
39
+
40
+ ### Patch Changes
41
+
42
+ - Updated dependencies [f7d4f01]
43
+ - @ai-sdk/provider-utils@5.0.0-beta.3
44
+ - @ai-sdk/provider@4.0.0-beta.2
45
+
46
+ ## 2.0.0-beta.4
47
+
48
+ ### Patch Changes
49
+
50
+ - Updated dependencies [5c2a5a2]
51
+ - @ai-sdk/provider@4.0.0-beta.1
52
+ - @ai-sdk/provider-utils@5.0.0-beta.2
53
+
54
+ ## 2.0.0-beta.3
55
+
56
+ ### Patch Changes
57
+
58
+ - b9b3899: fix(mcp): validate state param in oauth flow
59
+
60
+ ## 2.0.0-beta.2
61
+
62
+ ### Patch Changes
63
+
64
+ - 9ecd8ae: fix(mcp): add MCP protocol version 2025-11-25 to supported versions
65
+
66
+ ## 2.0.0-beta.1
67
+
68
+ ### Patch Changes
69
+
70
+ - Updated dependencies [531251e]
71
+ - @ai-sdk/provider-utils@5.0.0-beta.1
72
+
3
73
  ## 2.0.0-beta.0
4
74
 
5
75
  ### Major Changes
@@ -200,15 +270,15 @@
200
270
  This change replaces
201
271
 
202
272
  ```ts
203
- import { experimental_createMCPClient } from 'ai';
204
- import { Experimental_StdioMCPTransport } from 'ai/mcp-stdio';
273
+ import { experimental_createMCPClient } from "ai";
274
+ import { Experimental_StdioMCPTransport } from "ai/mcp-stdio";
205
275
  ```
206
276
 
207
277
  with
208
278
 
209
279
  ```ts
210
- import { experimental_createMCPClient } from '@ai-sdk/mcp';
211
- import { Experimental_StdioMCPTransport } from '@ai-sdk/mcp/mcp-stdio';
280
+ import { experimental_createMCPClient } from "@ai-sdk/mcp";
281
+ import { Experimental_StdioMCPTransport } from "@ai-sdk/mcp/mcp-stdio";
212
282
  ```
213
283
 
214
284
  ### Patch Changes
@@ -574,13 +644,13 @@
574
644
  This change replaces
575
645
 
576
646
  ```ts
577
- import { experimental_createMCPClient } from 'ai';
578
- import { Experimental_StdioMCPTransport } from 'ai/mcp-stdio';
647
+ import { experimental_createMCPClient } from "ai";
648
+ import { Experimental_StdioMCPTransport } from "ai/mcp-stdio";
579
649
  ```
580
650
 
581
651
  with
582
652
 
583
653
  ```ts
584
- import { experimental_createMCPClient } from '@ai-sdk/mcp';
585
- import { Experimental_StdioMCPTransport } from '@ai-sdk/mcp/mcp-stdio';
654
+ import { experimental_createMCPClient } from "@ai-sdk/mcp";
655
+ import { Experimental_StdioMCPTransport } from "@ai-sdk/mcp/mcp-stdio";
586
656
  ```
package/dist/index.d.mts CHANGED
@@ -182,6 +182,8 @@ interface OAuthClientProvider {
182
182
  clientInformation(): OAuthClientInformation | undefined | Promise<OAuthClientInformation | undefined>;
183
183
  saveClientInformation?(clientInformation: OAuthClientInformation): void | Promise<void>;
184
184
  state?(): string | Promise<string>;
185
+ saveState?(state: string): void | Promise<void>;
186
+ storedState?(): string | undefined | Promise<string | undefined>;
185
187
  validateResourceURL?(serverUrl: string | URL, resource?: string): Promise<URL | undefined>;
186
188
  }
187
189
  declare class UnauthorizedError extends Error {
@@ -190,6 +192,7 @@ declare class UnauthorizedError extends Error {
190
192
  declare function auth(provider: OAuthClientProvider, options: {
191
193
  serverUrl: string | URL;
192
194
  authorizationCode?: string;
195
+ callbackState?: string;
193
196
  scope?: string;
194
197
  resourceMetadataUrl?: URL;
195
198
  fetchFn?: FetchFunction;
@@ -240,6 +243,13 @@ type MCPTransportConfig = {
240
243
  * An optional OAuth client provider to use for authentication for MCP servers.
241
244
  */
242
245
  authProvider?: OAuthClientProvider;
246
+ /**
247
+ * Controls how HTTP redirects are handled for transport requests.
248
+ * - `'follow'`: Follow redirects automatically (standard fetch behavior).
249
+ * - `'error'`: Reject any redirect response with an error.
250
+ * @default 'error'
251
+ */
252
+ redirect?: 'follow' | 'error';
243
253
  };
244
254
 
245
255
  /** MCP tool metadata - keys should follow MCP _meta key format specification */
package/dist/index.d.ts CHANGED
@@ -182,6 +182,8 @@ interface OAuthClientProvider {
182
182
  clientInformation(): OAuthClientInformation | undefined | Promise<OAuthClientInformation | undefined>;
183
183
  saveClientInformation?(clientInformation: OAuthClientInformation): void | Promise<void>;
184
184
  state?(): string | Promise<string>;
185
+ saveState?(state: string): void | Promise<void>;
186
+ storedState?(): string | undefined | Promise<string | undefined>;
185
187
  validateResourceURL?(serverUrl: string | URL, resource?: string): Promise<URL | undefined>;
186
188
  }
187
189
  declare class UnauthorizedError extends Error {
@@ -190,6 +192,7 @@ declare class UnauthorizedError extends Error {
190
192
  declare function auth(provider: OAuthClientProvider, options: {
191
193
  serverUrl: string | URL;
192
194
  authorizationCode?: string;
195
+ callbackState?: string;
193
196
  scope?: string;
194
197
  resourceMetadataUrl?: URL;
195
198
  fetchFn?: FetchFunction;
@@ -240,6 +243,13 @@ type MCPTransportConfig = {
240
243
  * An optional OAuth client provider to use for authentication for MCP servers.
241
244
  */
242
245
  authProvider?: OAuthClientProvider;
246
+ /**
247
+ * Controls how HTTP redirects are handled for transport requests.
248
+ * - `'follow'`: Follow redirects automatically (standard fetch behavior).
249
+ * - `'error'`: Reject any redirect response with an error.
250
+ * @default 'error'
251
+ */
252
+ redirect?: 'follow' | 'error';
243
253
  };
244
254
 
245
255
  /** MCP tool metadata - keys should follow MCP _meta key format specification */
package/dist/index.js CHANGED
@@ -28,8 +28,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
30
  // src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
33
  ElicitResultSchema: () => ElicitResultSchema,
34
34
  ElicitationRequestSchema: () => ElicitationRequestSchema,
35
35
  UnauthorizedError: () => UnauthorizedError,
@@ -37,7 +37,7 @@ __export(src_exports, {
37
37
  createMCPClient: () => createMCPClient,
38
38
  experimental_createMCPClient: () => createMCPClient
39
39
  });
40
- module.exports = __toCommonJS(src_exports);
40
+ module.exports = __toCommonJS(index_exports);
41
41
 
42
42
  // src/tool/mcp-client.ts
43
43
  var import_provider_utils3 = require("@ai-sdk/provider-utils");
@@ -74,9 +74,10 @@ var import_v42 = require("zod/v4");
74
74
 
75
75
  // src/tool/types.ts
76
76
  var import_v4 = require("zod/v4");
77
- var LATEST_PROTOCOL_VERSION = "2025-06-18";
77
+ var LATEST_PROTOCOL_VERSION = "2025-11-25";
78
78
  var SUPPORTED_PROTOCOL_VERSIONS = [
79
79
  LATEST_PROTOCOL_VERSION,
80
+ "2025-06-18",
80
81
  "2025-03-26",
81
82
  "2024-11-05"
82
83
  ];
@@ -948,6 +949,7 @@ async function selectResourceURL(serverUrl, provider, resourceMetadata) {
948
949
  async function authInternal(provider, {
949
950
  serverUrl,
950
951
  authorizationCode,
952
+ callbackState,
951
953
  scope,
952
954
  resourceMetadataUrl,
953
955
  fetchFn
@@ -1000,6 +1002,14 @@ async function authInternal(provider, {
1000
1002
  clientInformation = fullInformation;
1001
1003
  }
1002
1004
  if (authorizationCode !== void 0) {
1005
+ if (provider.storedState) {
1006
+ const expectedState = await provider.storedState();
1007
+ if (expectedState !== void 0 && expectedState !== callbackState) {
1008
+ throw new Error(
1009
+ "OAuth state parameter mismatch - possible CSRF attack"
1010
+ );
1011
+ }
1012
+ }
1003
1013
  const codeVerifier2 = await provider.codeVerifier();
1004
1014
  const tokens2 = await exchangeAuthorization(authorizationServerUrl, {
1005
1015
  metadata,
@@ -1038,6 +1048,9 @@ async function authInternal(provider, {
1038
1048
  }
1039
1049
  }
1040
1050
  const state = provider.state ? await provider.state() : void 0;
1051
+ if (state && provider.saveState) {
1052
+ await provider.saveState(state);
1053
+ }
1041
1054
  const { authorizationUrl, codeVerifier } = await startAuthorization(
1042
1055
  authorizationServerUrl,
1043
1056
  {
@@ -1059,12 +1072,14 @@ var SseMCPTransport = class {
1059
1072
  constructor({
1060
1073
  url,
1061
1074
  headers,
1062
- authProvider
1075
+ authProvider,
1076
+ redirect = "error"
1063
1077
  }) {
1064
1078
  this.connected = false;
1065
1079
  this.url = new URL(url);
1066
1080
  this.headers = headers;
1067
1081
  this.authProvider = authProvider;
1082
+ this.redirectMode = redirect;
1068
1083
  }
1069
1084
  async commonHeaders(base) {
1070
1085
  const headers = {
@@ -1098,7 +1113,8 @@ var SseMCPTransport = class {
1098
1113
  });
1099
1114
  const response = await fetch(this.url.href, {
1100
1115
  headers,
1101
- signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
1116
+ signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
1117
+ redirect: this.redirectMode
1102
1118
  });
1103
1119
  if (response.status === 401 && this.authProvider && !triedAuth) {
1104
1120
  this.resourceMetadataUrl = extractResourceMetadataUrl(response);
@@ -1217,7 +1233,8 @@ var SseMCPTransport = class {
1217
1233
  method: "POST",
1218
1234
  headers,
1219
1235
  body: JSON.stringify(message),
1220
- signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
1236
+ signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
1237
+ redirect: this.redirectMode
1221
1238
  };
1222
1239
  const response = await fetch(endpoint, init);
1223
1240
  if (response.status === 401 && this.authProvider && !triedAuth) {
@@ -1261,7 +1278,8 @@ var HttpMCPTransport = class {
1261
1278
  constructor({
1262
1279
  url,
1263
1280
  headers,
1264
- authProvider
1281
+ authProvider,
1282
+ redirect = "error"
1265
1283
  }) {
1266
1284
  this.inboundReconnectAttempts = 0;
1267
1285
  this.reconnectionOptions = {
@@ -1273,6 +1291,7 @@ var HttpMCPTransport = class {
1273
1291
  this.url = new URL(url);
1274
1292
  this.headers = headers;
1275
1293
  this.authProvider = authProvider;
1294
+ this.redirectMode = redirect;
1276
1295
  }
1277
1296
  async commonHeaders(base) {
1278
1297
  const headers = {
@@ -1313,7 +1332,8 @@ var HttpMCPTransport = class {
1313
1332
  await fetch(this.url, {
1314
1333
  method: "DELETE",
1315
1334
  headers,
1316
- signal: this.abortController.signal
1335
+ signal: this.abortController.signal,
1336
+ redirect: this.redirectMode
1317
1337
  }).catch(() => void 0);
1318
1338
  }
1319
1339
  } catch (e) {
@@ -1333,7 +1353,8 @@ var HttpMCPTransport = class {
1333
1353
  method: "POST",
1334
1354
  headers,
1335
1355
  body: JSON.stringify(message),
1336
- signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
1356
+ signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
1357
+ redirect: this.redirectMode
1337
1358
  };
1338
1359
  const response = await fetch(this.url, init);
1339
1360
  const sessionId = response.headers.get("mcp-session-id");
@@ -1482,7 +1503,8 @@ var HttpMCPTransport = class {
1482
1503
  const response = await fetch(this.url.href, {
1483
1504
  method: "GET",
1484
1505
  headers,
1485
- signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal
1506
+ signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
1507
+ redirect: this.redirectMode
1486
1508
  });
1487
1509
  const sessionId = response.headers.get("mcp-session-id");
1488
1510
  if (sessionId) {