@ai-sdk/mcp 1.0.64 → 1.0.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1464,15 +1464,19 @@ var SseMCPTransport = class {
1464
1464
  (_b3 = this.abortController) == null ? void 0 : _b3.abort();
1465
1465
  (_c = this.onclose) == null ? void 0 : _c.call(this);
1466
1466
  }
1467
- async send(message) {
1467
+ async send(message, options) {
1468
+ var _a3, _b3;
1469
+ (_a3 = options == null ? void 0 : options.signal) == null ? void 0 : _a3.throwIfAborted();
1468
1470
  if (!this.endpoint || !this.connected) {
1469
1471
  throw new MCPClientError({
1470
1472
  message: "MCP SSE Transport Error: Not connected"
1471
1473
  });
1472
1474
  }
1473
1475
  const endpoint = this.endpoint;
1476
+ const transportSignal = (_b3 = this.abortController) == null ? void 0 : _b3.signal;
1477
+ const requestSignal = (options == null ? void 0 : options.signal) == null ? transportSignal : transportSignal == null ? options.signal : AbortSignal.any([transportSignal, options.signal]);
1474
1478
  const attempt = async (triedAuth = false) => {
1475
- var _a3, _b3, _c, _d, _e;
1479
+ var _a4, _b4, _c, _d, _e;
1476
1480
  try {
1477
1481
  const headers = await this.commonHeaders({
1478
1482
  "Content-Type": "application/json"
@@ -1481,7 +1485,7 @@ var SseMCPTransport = class {
1481
1485
  method: "POST",
1482
1486
  headers,
1483
1487
  body: JSON.stringify(message),
1484
- signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
1488
+ signal: requestSignal,
1485
1489
  redirect: this.redirectMode
1486
1490
  };
1487
1491
  const response = await this.fetchFn(endpoint.href, init);
@@ -1495,11 +1499,11 @@ var SseMCPTransport = class {
1495
1499
  });
1496
1500
  if (result !== "AUTHORIZED") {
1497
1501
  const error = new UnauthorizedError();
1498
- (_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);
1502
+ (_a4 = this.onerror) == null ? void 0 : _a4.call(this, error);
1499
1503
  return;
1500
1504
  }
1501
1505
  } catch (error) {
1502
- (_c = this.onerror) == null ? void 0 : _c.call(this, error);
1506
+ (_b4 = this.onerror) == null ? void 0 : _b4.call(this, error);
1503
1507
  return;
1504
1508
  }
1505
1509
  return attempt(true);
@@ -1509,10 +1513,13 @@ var SseMCPTransport = class {
1509
1513
  const error = new MCPClientError({
1510
1514
  message: `MCP SSE Transport Error: POSTing to endpoint (HTTP ${response.status}): ${text}`
1511
1515
  });
1512
- (_d = this.onerror) == null ? void 0 : _d.call(this, error);
1516
+ (_c = this.onerror) == null ? void 0 : _c.call(this, error);
1513
1517
  return;
1514
1518
  }
1515
1519
  } catch (error) {
1520
+ if ((_d = options == null ? void 0 : options.signal) == null ? void 0 : _d.aborted) {
1521
+ throw error;
1522
+ }
1516
1523
  (_e = this.onerror) == null ? void 0 : _e.call(this, error);
1517
1524
  return;
1518
1525
  }
@@ -1603,27 +1610,33 @@ var HttpMCPTransport = class {
1603
1610
  this.abortController = new AbortController();
1604
1611
  this.startInboundSse();
1605
1612
  }
1606
- async close() {
1607
- var _a3, _b3, _c;
1613
+ async close(options) {
1614
+ var _a3, _b3, _c, _d, _e;
1608
1615
  (_a3 = this.inboundSseConnection) == null ? void 0 : _a3.close();
1616
+ (_b3 = this.abortController) == null ? void 0 : _b3.abort();
1609
1617
  try {
1610
- if (this.sessionId && this.abortController && !this.abortController.signal.aborted) {
1618
+ if (this.sessionId && this.abortController) {
1619
+ (_c = options == null ? void 0 : options.signal) == null ? void 0 : _c.throwIfAborted();
1611
1620
  const headers = await this.commonHeaders({});
1621
+ (_d = options == null ? void 0 : options.signal) == null ? void 0 : _d.throwIfAborted();
1612
1622
  await this.fetchFn(this.url.href, {
1613
1623
  method: "DELETE",
1614
1624
  headers,
1615
- signal: this.abortController.signal,
1625
+ signal: options == null ? void 0 : options.signal,
1616
1626
  redirect: this.redirectMode
1617
1627
  }).catch(() => void 0);
1618
1628
  }
1619
1629
  } catch (e) {
1620
1630
  }
1621
- (_b3 = this.abortController) == null ? void 0 : _b3.abort();
1622
- (_c = this.onclose) == null ? void 0 : _c.call(this);
1631
+ (_e = this.onclose) == null ? void 0 : _e.call(this);
1623
1632
  }
1624
- async send(message) {
1633
+ async send(message, options) {
1634
+ var _a3, _b3;
1635
+ (_a3 = options == null ? void 0 : options.signal) == null ? void 0 : _a3.throwIfAborted();
1636
+ const transportSignal = (_b3 = this.abortController) == null ? void 0 : _b3.signal;
1637
+ const requestSignal = (options == null ? void 0 : options.signal) == null ? transportSignal : transportSignal == null ? options.signal : AbortSignal.any([transportSignal, options.signal]);
1625
1638
  const attempt = async (triedAuth = false) => {
1626
- var _a3, _b3, _c, _d, _e, _f, _g;
1639
+ var _a4, _b4, _c, _d, _e, _f, _g;
1627
1640
  try {
1628
1641
  const headers = await this.commonHeaders({
1629
1642
  "Content-Type": "application/json",
@@ -1633,7 +1646,7 @@ var HttpMCPTransport = class {
1633
1646
  method: "POST",
1634
1647
  headers,
1635
1648
  body: JSON.stringify(message),
1636
- signal: (_a3 = this.abortController) == null ? void 0 : _a3.signal,
1649
+ signal: requestSignal,
1637
1650
  redirect: this.redirectMode
1638
1651
  };
1639
1652
  const response = await this.fetchFn(this.url.href, init);
@@ -1650,7 +1663,7 @@ var HttpMCPTransport = class {
1650
1663
  throw error2;
1651
1664
  }
1652
1665
  } catch (error2) {
1653
- (_b3 = this.onerror) == null ? void 0 : _b3.call(this, error2);
1666
+ (_a4 = this.onerror) == null ? void 0 : _a4.call(this, error2);
1654
1667
  throw error2;
1655
1668
  }
1656
1669
  return attempt(true);
@@ -1673,7 +1686,7 @@ var HttpMCPTransport = class {
1673
1686
  url: this.url.href,
1674
1687
  responseBody: text != null ? text : void 0
1675
1688
  });
1676
- (_c = this.onerror) == null ? void 0 : _c.call(this, error2);
1689
+ (_b4 = this.onerror) == null ? void 0 : _b4.call(this, error2);
1677
1690
  throw error2;
1678
1691
  }
1679
1692
  const isNotification = !("id" in message);
@@ -1685,7 +1698,7 @@ var HttpMCPTransport = class {
1685
1698
  const data = await response.json();
1686
1699
  const messages = Array.isArray(data) ? data.map((message2) => validateJSONRPCMessage(message2)) : [validateJSONRPCMessage(data)];
1687
1700
  for (const jsonRpcMessage of messages) {
1688
- (_d = this.onmessage) == null ? void 0 : _d.call(this, jsonRpcMessage);
1701
+ (_c = this.onmessage) == null ? void 0 : _c.call(this, jsonRpcMessage);
1689
1702
  }
1690
1703
  return;
1691
1704
  }
@@ -1696,13 +1709,13 @@ var HttpMCPTransport = class {
1696
1709
  statusCode: response.status,
1697
1710
  url: this.url.href
1698
1711
  });
1699
- (_e = this.onerror) == null ? void 0 : _e.call(this, error2);
1712
+ (_d = this.onerror) == null ? void 0 : _d.call(this, error2);
1700
1713
  throw error2;
1701
1714
  }
1702
1715
  const stream = response.body.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream2());
1703
1716
  const reader = stream.getReader();
1704
1717
  const processEvents = async () => {
1705
- var _a4, _b4, _c2;
1718
+ var _a5, _b5, _c2, _d2;
1706
1719
  try {
1707
1720
  while (true) {
1708
1721
  const { done, value } = await reader.read();
@@ -1711,29 +1724,29 @@ var HttpMCPTransport = class {
1711
1724
  if (isMessageEvent2(event)) {
1712
1725
  try {
1713
1726
  const msg = await parseJSONRPCMessage(data);
1714
- (_a4 = this.onmessage) == null ? void 0 : _a4.call(this, msg);
1727
+ (_a5 = this.onmessage) == null ? void 0 : _a5.call(this, msg);
1715
1728
  } catch (error2) {
1716
1729
  const e = new MCPClientError({
1717
1730
  message: "MCP HTTP Transport Error: Failed to parse message",
1718
1731
  cause: error2
1719
1732
  });
1720
- (_b4 = this.onerror) == null ? void 0 : _b4.call(this, e);
1733
+ (_b5 = this.onerror) == null ? void 0 : _b5.call(this, e);
1721
1734
  }
1722
1735
  }
1723
1736
  }
1724
1737
  } catch (error2) {
1725
- if (error2 instanceof Error && error2.name === "AbortError") {
1738
+ if (((_c2 = options == null ? void 0 : options.signal) == null ? void 0 : _c2.aborted) || error2 instanceof Error && error2.name === "AbortError") {
1726
1739
  return;
1727
1740
  }
1728
- (_c2 = this.onerror) == null ? void 0 : _c2.call(this, error2);
1741
+ (_d2 = this.onerror) == null ? void 0 : _d2.call(this, error2);
1729
1742
  }
1730
1743
  };
1731
1744
  void processEvents().catch((error2) => {
1732
- var _a4;
1733
- if (error2 instanceof Error && error2.name === "AbortError") {
1745
+ var _a5, _b5;
1746
+ if (((_a5 = options == null ? void 0 : options.signal) == null ? void 0 : _a5.aborted) || error2 instanceof Error && error2.name === "AbortError") {
1734
1747
  return;
1735
1748
  }
1736
- (_a4 = this.onerror) == null ? void 0 : _a4.call(this, error2);
1749
+ (_b5 = this.onerror) == null ? void 0 : _b5.call(this, error2);
1737
1750
  });
1738
1751
  return;
1739
1752
  }
@@ -1742,9 +1755,12 @@ var HttpMCPTransport = class {
1742
1755
  statusCode: response.status,
1743
1756
  url: this.url.href
1744
1757
  });
1745
- (_f = this.onerror) == null ? void 0 : _f.call(this, error);
1758
+ (_e = this.onerror) == null ? void 0 : _e.call(this, error);
1746
1759
  throw error;
1747
1760
  } catch (error) {
1761
+ if ((_f = options == null ? void 0 : options.signal) == null ? void 0 : _f.aborted) {
1762
+ throw error;
1763
+ }
1748
1764
  (_g = this.onerror) == null ? void 0 : _g.call(this, error);
1749
1765
  throw error;
1750
1766
  }
@@ -1975,6 +1991,44 @@ function prepareMaxRetries(maxRetries) {
1975
1991
  }
1976
1992
  return maxRetries;
1977
1993
  }
1994
+ function getEffectiveTimeout({
1995
+ timeout,
1996
+ maxTotalTimeout
1997
+ }) {
1998
+ if (timeout == null) {
1999
+ return maxTotalTimeout;
2000
+ }
2001
+ if (maxTotalTimeout == null) {
2002
+ return timeout;
2003
+ }
2004
+ return Math.min(timeout, maxTotalTimeout);
2005
+ }
2006
+ function waitForAbort(promise, signal) {
2007
+ if (signal == null) {
2008
+ return promise;
2009
+ }
2010
+ return new Promise((resolve, reject) => {
2011
+ const cleanup = () => {
2012
+ signal.removeEventListener("abort", onAbort);
2013
+ };
2014
+ const onAbort = () => {
2015
+ cleanup();
2016
+ reject(signal.reason);
2017
+ };
2018
+ if (signal.aborted) {
2019
+ onAbort();
2020
+ return;
2021
+ }
2022
+ signal.addEventListener("abort", onAbort, { once: true });
2023
+ promise.then((value) => {
2024
+ cleanup();
2025
+ resolve(value);
2026
+ }).catch((error) => {
2027
+ cleanup();
2028
+ reject(error);
2029
+ });
2030
+ });
2031
+ }
1978
2032
  function mcpToModelOutput({
1979
2033
  output
1980
2034
  }) {
@@ -2012,7 +2066,8 @@ var DefaultMCPClient = class {
2012
2066
  version = CLIENT_VERSION,
2013
2067
  onUncaughtError,
2014
2068
  maxRetries,
2015
- capabilities
2069
+ capabilities,
2070
+ initializationOptions
2016
2071
  }) {
2017
2072
  this.requestMessageId = 0;
2018
2073
  this.responseHandlers = /* @__PURE__ */ new Map();
@@ -2022,6 +2077,7 @@ var DefaultMCPClient = class {
2022
2077
  this.onUncaughtError = onUncaughtError;
2023
2078
  this.maxRetries = prepareMaxRetries(maxRetries);
2024
2079
  this.clientCapabilities = capabilities != null ? capabilities : {};
2080
+ this.initializationOptions = initializationOptions;
2025
2081
  if (isCustomMcpTransport(transportConfig)) {
2026
2082
  this.transport = transportConfig;
2027
2083
  } else {
@@ -2056,9 +2112,25 @@ var DefaultMCPClient = class {
2056
2112
  return this._serverInstructions;
2057
2113
  }
2058
2114
  async init() {
2115
+ var _a3;
2116
+ const externalSignal = (_a3 = this.initializationOptions) == null ? void 0 : _a3.signal;
2117
+ const timeout = this.initializationOptions ? getEffectiveTimeout(this.initializationOptions) : void 0;
2118
+ const timeoutController = timeout == null ? void 0 : new AbortController();
2119
+ const signal = externalSignal == null ? timeoutController == null ? void 0 : timeoutController.signal : timeoutController == null ? externalSignal : AbortSignal.any([externalSignal, timeoutController.signal]);
2120
+ let timeoutId;
2121
+ let timeoutError;
2122
+ if (timeout != null) {
2123
+ timeoutId = setTimeout(() => {
2124
+ timeoutError = new MCPClientError({
2125
+ message: `MCP client initialization timed out after ${timeout}ms`
2126
+ });
2127
+ timeoutController == null ? void 0 : timeoutController.abort(timeoutError);
2128
+ }, timeout);
2129
+ }
2059
2130
  try {
2060
- await this.transport.start();
2061
2131
  this.isClosed = false;
2132
+ signal == null ? void 0 : signal.throwIfAborted();
2133
+ await waitForAbort(this.transport.start(), signal);
2062
2134
  const result = await this.request({
2063
2135
  request: {
2064
2136
  method: "initialize",
@@ -2068,7 +2140,8 @@ var DefaultMCPClient = class {
2068
2140
  clientInfo: this.clientInfo
2069
2141
  }
2070
2142
  },
2071
- resultSchema: InitializeResultSchema
2143
+ resultSchema: InitializeResultSchema,
2144
+ options: { signal }
2072
2145
  });
2073
2146
  if (result === void 0) {
2074
2147
  throw new MCPClientError({
@@ -2088,13 +2161,33 @@ var DefaultMCPClient = class {
2088
2161
  this.transport.protocolVersion = result.protocolVersion;
2089
2162
  }
2090
2163
  this._serverInstructions = result.instructions;
2091
- await this.notification({
2092
- method: "notifications/initialized"
2093
- });
2164
+ await this.notification(
2165
+ {
2166
+ method: "notifications/initialized"
2167
+ },
2168
+ { signal }
2169
+ );
2094
2170
  return this;
2095
2171
  } catch (error) {
2096
- await this.close();
2172
+ try {
2173
+ await waitForAbort(this.transport.close({ signal }), signal);
2174
+ } catch (e) {
2175
+ }
2176
+ this.onClose();
2177
+ if (timeoutError != null) {
2178
+ throw timeoutError;
2179
+ }
2180
+ if (externalSignal == null ? void 0 : externalSignal.aborted) {
2181
+ throw new MCPClientError({
2182
+ message: "MCP client initialization was aborted",
2183
+ cause: externalSignal.reason
2184
+ });
2185
+ }
2097
2186
  throw error;
2187
+ } finally {
2188
+ if (timeoutId != null) {
2189
+ clearTimeout(timeoutId);
2190
+ }
2098
2191
  }
2099
2192
  }
2100
2193
  async close() {
@@ -2103,6 +2196,12 @@ var DefaultMCPClient = class {
2103
2196
  await ((_a3 = this.transport) == null ? void 0 : _a3.close());
2104
2197
  this.onClose();
2105
2198
  }
2199
+ send(message, signal) {
2200
+ return this.transport.send(
2201
+ message,
2202
+ signal == null ? void 0 : { signal }
2203
+ );
2204
+ }
2106
2205
  assertCapability(method) {
2107
2206
  switch (method) {
2108
2207
  case "initialize":
@@ -2161,6 +2260,10 @@ var DefaultMCPClient = class {
2161
2260
  this.assertCapability(request.method);
2162
2261
  const signal = options == null ? void 0 : options.signal;
2163
2262
  signal == null ? void 0 : signal.throwIfAborted();
2263
+ const timeout = options == null ? void 0 : getEffectiveTimeout(options);
2264
+ const timeoutController = timeout == null ? void 0 : new AbortController();
2265
+ const transportSignal = signal == null ? timeoutController == null ? void 0 : timeoutController.signal : timeoutController == null ? signal : AbortSignal.any([signal, timeoutController.signal]);
2266
+ let timeoutId;
2164
2267
  const messageId = this.requestMessageId++;
2165
2268
  const jsonrpcRequest = {
2166
2269
  ...request,
@@ -2178,6 +2281,9 @@ var DefaultMCPClient = class {
2178
2281
  const cleanup = () => {
2179
2282
  this.responseHandlers.delete(messageId);
2180
2283
  signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
2284
+ if (timeoutId != null) {
2285
+ clearTimeout(timeoutId);
2286
+ }
2181
2287
  };
2182
2288
  const rejectAndCleanup = (error) => {
2183
2289
  cleanup();
@@ -2187,6 +2293,13 @@ var DefaultMCPClient = class {
2187
2293
  cleanup();
2188
2294
  rejectWithAbortError();
2189
2295
  };
2296
+ const onTimeout = () => {
2297
+ const error = new MCPClientError({
2298
+ message: `Request timed out after ${timeout}ms`
2299
+ });
2300
+ timeoutController == null ? void 0 : timeoutController.abort(error);
2301
+ rejectAndCleanup(error);
2302
+ };
2190
2303
  this.responseHandlers.set(messageId, (response) => {
2191
2304
  if (signal == null ? void 0 : signal.aborted) {
2192
2305
  cleanup();
@@ -2208,7 +2321,11 @@ var DefaultMCPClient = class {
2208
2321
  }
2209
2322
  });
2210
2323
  signal == null ? void 0 : signal.addEventListener("abort", onAbort, { once: true });
2211
- this.transport.send(jsonrpcRequest).catch((error) => {
2324
+ if (timeout != null) {
2325
+ timeoutId = setTimeout(onTimeout, timeout);
2326
+ }
2327
+ const sendPromise = transportSignal == null ? this.transport.send(jsonrpcRequest) : this.send(jsonrpcRequest, transportSignal);
2328
+ sendPromise.catch((error) => {
2212
2329
  rejectAndCleanup(error);
2213
2330
  });
2214
2331
  });
@@ -2343,12 +2460,15 @@ var DefaultMCPClient = class {
2343
2460
  options
2344
2461
  });
2345
2462
  }
2346
- async notification(notification) {
2463
+ async notification(notification, options) {
2347
2464
  const jsonrpcNotification = {
2348
2465
  ...notification,
2349
2466
  jsonrpc: "2.0"
2350
2467
  };
2351
- await this.transport.send(jsonrpcNotification);
2468
+ await waitForAbort(
2469
+ this.send(jsonrpcNotification, options == null ? void 0 : options.signal),
2470
+ options == null ? void 0 : options.signal
2471
+ );
2352
2472
  }
2353
2473
  /**
2354
2474
  * Returns a set of AI SDK tools from the MCP server.