@ai-sdk/mcp 1.0.33 → 1.0.35

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,17 @@
1
1
  # @ai-sdk/mcp
2
2
 
3
+ ## 1.0.35
4
+
5
+ ### Patch Changes
6
+
7
+ - 941ebf2: fix(mcp): bypass outputSchema validation when tool returns isError
8
+
9
+ ## 1.0.34
10
+
11
+ ### Patch Changes
12
+
13
+ - 1141b93: feat(mcp): allow custom fetch for HTTP and SSE transports
14
+
3
15
  ## 1.0.33
4
16
 
5
17
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -250,6 +250,12 @@ type MCPTransportConfig = {
250
250
  * @default 'follow'
251
251
  */
252
252
  redirect?: 'follow' | 'error';
253
+ /**
254
+ * Optional custom fetch implementation to use for HTTP requests.
255
+ * Useful for runtimes that need a request-local fetch.
256
+ * @default globalThis.fetch
257
+ */
258
+ fetch?: FetchFunction;
253
259
  };
254
260
 
255
261
  /** MCP tool metadata - keys should follow MCP _meta key format specification */
package/dist/index.d.ts CHANGED
@@ -250,6 +250,12 @@ type MCPTransportConfig = {
250
250
  * @default 'follow'
251
251
  */
252
252
  redirect?: 'follow' | 'error';
253
+ /**
254
+ * Optional custom fetch implementation to use for HTTP requests.
255
+ * Useful for runtimes that need a request-local fetch.
256
+ * @default globalThis.fetch
257
+ */
258
+ fetch?: FetchFunction;
253
259
  };
254
260
 
255
261
  /** MCP tool metadata - keys should follow MCP _meta key format specification */
package/dist/index.js CHANGED
@@ -1083,13 +1083,15 @@ var SseMCPTransport = class {
1083
1083
  url,
1084
1084
  headers,
1085
1085
  authProvider,
1086
- redirect = "follow"
1086
+ redirect = "follow",
1087
+ fetch: fetchFn
1087
1088
  }) {
1088
1089
  this.connected = false;
1089
1090
  this.url = new URL(url);
1090
1091
  this.headers = headers;
1091
1092
  this.authProvider = authProvider;
1092
1093
  this.redirectMode = redirect;
1094
+ this.fetchFn = fetchFn != null ? fetchFn : globalThis.fetch;
1093
1095
  }
1094
1096
  async commonHeaders(base) {
1095
1097
  const headers = {
@@ -1121,7 +1123,7 @@ var SseMCPTransport = class {
1121
1123
  const headers = await this.commonHeaders({
1122
1124
  Accept: "text/event-stream"
1123
1125
  });
1124
- const response = await fetch(this.url.href, {
1126
+ const response = await this.fetchFn(this.url.href, {
1125
1127
  headers,
1126
1128
  signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
1127
1129
  redirect: this.redirectMode
@@ -1131,7 +1133,8 @@ var SseMCPTransport = class {
1131
1133
  try {
1132
1134
  const result = await auth(this.authProvider, {
1133
1135
  serverUrl: this.url,
1134
- resourceMetadataUrl: this.resourceMetadataUrl
1136
+ resourceMetadataUrl: this.resourceMetadataUrl,
1137
+ fetchFn: this.fetchFn
1135
1138
  });
1136
1139
  if (result !== "AUTHORIZED") {
1137
1140
  const error = new UnauthorizedError();
@@ -1246,13 +1249,14 @@ var SseMCPTransport = class {
1246
1249
  signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
1247
1250
  redirect: this.redirectMode
1248
1251
  };
1249
- const response = await fetch(endpoint, init);
1252
+ const response = await this.fetchFn(endpoint.href, init);
1250
1253
  if (response.status === 401 && this.authProvider && !triedAuth) {
1251
1254
  this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1252
1255
  try {
1253
1256
  const result = await auth(this.authProvider, {
1254
1257
  serverUrl: this.url,
1255
- resourceMetadataUrl: this.resourceMetadataUrl
1258
+ resourceMetadataUrl: this.resourceMetadataUrl,
1259
+ fetchFn: this.fetchFn
1256
1260
  });
1257
1261
  if (result !== "AUTHORIZED") {
1258
1262
  const error = new UnauthorizedError();
@@ -1289,7 +1293,8 @@ var HttpMCPTransport = class {
1289
1293
  url,
1290
1294
  headers,
1291
1295
  authProvider,
1292
- redirect = "follow"
1296
+ redirect = "follow",
1297
+ fetch: fetchFn
1293
1298
  }) {
1294
1299
  this.inboundReconnectAttempts = 0;
1295
1300
  this.reconnectionOptions = {
@@ -1302,6 +1307,7 @@ var HttpMCPTransport = class {
1302
1307
  this.headers = headers;
1303
1308
  this.authProvider = authProvider;
1304
1309
  this.redirectMode = redirect;
1310
+ this.fetchFn = fetchFn != null ? fetchFn : globalThis.fetch;
1305
1311
  }
1306
1312
  async commonHeaders(base) {
1307
1313
  const headers = {
@@ -1339,7 +1345,7 @@ var HttpMCPTransport = class {
1339
1345
  try {
1340
1346
  if (this.sessionId && this.abortController && !this.abortController.signal.aborted) {
1341
1347
  const headers = await this.commonHeaders({});
1342
- await fetch(this.url, {
1348
+ await this.fetchFn(this.url.href, {
1343
1349
  method: "DELETE",
1344
1350
  headers,
1345
1351
  signal: this.abortController.signal,
@@ -1366,7 +1372,7 @@ var HttpMCPTransport = class {
1366
1372
  signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
1367
1373
  redirect: this.redirectMode
1368
1374
  };
1369
- const response = await fetch(this.url, init);
1375
+ const response = await this.fetchFn(this.url.href, init);
1370
1376
  const sessionId = response.headers.get("mcp-session-id");
1371
1377
  if (sessionId) {
1372
1378
  this.sessionId = sessionId;
@@ -1376,7 +1382,8 @@ var HttpMCPTransport = class {
1376
1382
  try {
1377
1383
  const result = await auth(this.authProvider, {
1378
1384
  serverUrl: this.url,
1379
- resourceMetadataUrl: this.resourceMetadataUrl
1385
+ resourceMetadataUrl: this.resourceMetadataUrl,
1386
+ fetchFn: this.fetchFn
1380
1387
  });
1381
1388
  if (result !== "AUTHORIZED") {
1382
1389
  const error2 = new UnauthorizedError();
@@ -1510,7 +1517,7 @@ var HttpMCPTransport = class {
1510
1517
  if (resumeToken) {
1511
1518
  headers["last-event-id"] = resumeToken;
1512
1519
  }
1513
- const response = await fetch(this.url.href, {
1520
+ const response = await this.fetchFn(this.url.href, {
1514
1521
  method: "GET",
1515
1522
  headers,
1516
1523
  signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
@@ -1525,7 +1532,8 @@ var HttpMCPTransport = class {
1525
1532
  try {
1526
1533
  const result = await auth(this.authProvider, {
1527
1534
  serverUrl: this.url,
1528
- resourceMetadataUrl: this.resourceMetadataUrl
1535
+ resourceMetadataUrl: this.resourceMetadataUrl,
1536
+ fetchFn: this.fetchFn
1529
1537
  });
1530
1538
  if (result !== "AUTHORIZED") {
1531
1539
  const error = new UnauthorizedError();
@@ -1960,6 +1968,9 @@ var DefaultMCPClient = class {
1960
1968
  var _a4;
1961
1969
  (_a4 = options == null ? void 0 : options.abortSignal) == null ? void 0 : _a4.throwIfAborted();
1962
1970
  const result = await self.callTool({ name: name3, args, options });
1971
+ if (result.isError) {
1972
+ return result;
1973
+ }
1963
1974
  if (outputSchema != null) {
1964
1975
  return self.extractStructuredContent(result, outputSchema, name3);
1965
1976
  }