@ai-sdk/mcp 1.0.80 → 1.0.82

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.82
4
+
5
+ ### Patch Changes
6
+
7
+ - 1620182: fix(mcp): avoid duplicate legacy SSE OAuth refreshes for stale 401 responses
8
+
9
+ ## 1.0.81
10
+
11
+ ### Patch Changes
12
+
13
+ - 5246507: fix(mcp): use the stored authorization server for OAuth callbacks when protected resource metadata rediscovery fails
14
+
3
15
  ## 1.0.80
4
16
 
5
17
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1199,9 +1199,11 @@ async function authInternal(provider, {
1199
1199
  resourceMetadataUrl,
1200
1200
  fetchFn
1201
1201
  }) {
1202
- var _a3, _b3;
1202
+ var _a3, _b3, _c;
1203
1203
  let resourceMetadata;
1204
1204
  let authorizationServerUrl;
1205
+ let clientInformation;
1206
+ let callbackAuthorizationServerInformation;
1205
1207
  assertResourceMetadataUrlSameOrigin(serverUrl, resourceMetadataUrl);
1206
1208
  try {
1207
1209
  resourceMetadata = await discoverOAuthProtectedResourceMetadata(
@@ -1214,15 +1216,24 @@ async function authInternal(provider, {
1214
1216
  }
1215
1217
  } catch (e) {
1216
1218
  }
1219
+ if (authorizationCode !== void 0) {
1220
+ clientInformation = await Promise.resolve(provider.clientInformation());
1221
+ if (clientInformation) {
1222
+ callbackAuthorizationServerInformation = await getStoredAuthorizationServerInformation({
1223
+ provider,
1224
+ clientInformation
1225
+ });
1226
+ }
1227
+ }
1217
1228
  if (!authorizationServerUrl) {
1218
- authorizationServerUrl = serverUrl;
1229
+ authorizationServerUrl = (_a3 = callbackAuthorizationServerInformation == null ? void 0 : callbackAuthorizationServerInformation.authorizationServerUrl) != null ? _a3 : serverUrl;
1219
1230
  }
1220
1231
  const resource = await selectResourceURL(
1221
1232
  serverUrl,
1222
1233
  provider,
1223
1234
  resourceMetadata
1224
1235
  );
1225
- await ((_a3 = provider.validateAuthorizationServerURL) == null ? void 0 : _a3.call(
1236
+ await ((_b3 = provider.validateAuthorizationServerURL) == null ? void 0 : _b3.call(
1226
1237
  provider,
1227
1238
  serverUrl,
1228
1239
  authorizationServerUrl
@@ -1240,7 +1251,9 @@ async function authInternal(provider, {
1240
1251
  resourceMetadata,
1241
1252
  clientMetadata
1242
1253
  });
1243
- let clientInformation = await Promise.resolve(provider.clientInformation());
1254
+ if (authorizationCode === void 0) {
1255
+ clientInformation = await Promise.resolve(provider.clientInformation());
1256
+ }
1244
1257
  if (!clientInformation) {
1245
1258
  if (authorizationCode !== void 0) {
1246
1259
  throw new Error(
@@ -1275,7 +1288,7 @@ async function authInternal(provider, {
1275
1288
  );
1276
1289
  }
1277
1290
  }
1278
- const storedAuthorizationServerInformation = await getStoredAuthorizationServerInformation({
1291
+ const storedAuthorizationServerInformation = callbackAuthorizationServerInformation != null ? callbackAuthorizationServerInformation : await getStoredAuthorizationServerInformation({
1279
1292
  provider,
1280
1293
  clientInformation
1281
1294
  });
@@ -1320,7 +1333,7 @@ async function authInternal(provider, {
1320
1333
  currentAuthorizationServerInformation
1321
1334
  });
1322
1335
  } else {
1323
- await ((_b3 = provider.invalidateCredentials) == null ? void 0 : _b3.call(provider, "tokens"));
1336
+ await ((_c = provider.invalidateCredentials) == null ? void 0 : _c.call(provider, "tokens"));
1324
1337
  }
1325
1338
  try {
1326
1339
  if (storedAuthorizationServerInformation) {
@@ -1421,6 +1434,30 @@ var SseMCPTransport = class {
1421
1434
  (0, import_provider_utils3.getRuntimeEnvironmentUserAgent)()
1422
1435
  );
1423
1436
  }
1437
+ /**
1438
+ * Runs a single OAuth recovery flow for concurrent 401 responses.
1439
+ */
1440
+ authorizeOnce(resourceMetadataUrl, scope) {
1441
+ if (!this.authProvider) {
1442
+ return Promise.resolve("REDIRECT");
1443
+ }
1444
+ if (!this.authPromise) {
1445
+ this.authPromise = auth(this.authProvider, {
1446
+ serverUrl: this.url,
1447
+ resourceMetadataUrl,
1448
+ scope,
1449
+ fetchFn: this.fetchFn
1450
+ }).finally(() => {
1451
+ this.authPromise = void 0;
1452
+ });
1453
+ }
1454
+ return this.authPromise;
1455
+ }
1456
+ async accessTokenChanged(requestAuthorization) {
1457
+ var _a3, _b3;
1458
+ const accessToken = (_b3 = await ((_a3 = this.authProvider) == null ? void 0 : _a3.tokens())) == null ? void 0 : _b3.access_token;
1459
+ return accessToken != null && requestAuthorization !== `Bearer ${accessToken}`;
1460
+ }
1424
1461
  async start() {
1425
1462
  return new Promise((resolve, reject) => {
1426
1463
  if (this.connected) {
@@ -1442,12 +1479,10 @@ var SseMCPTransport = class {
1442
1479
  const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
1443
1480
  this.resourceMetadataUrl = resourceMetadataUrl;
1444
1481
  try {
1445
- const result = await auth(this.authProvider, {
1446
- serverUrl: this.url,
1447
- resourceMetadataUrl: this.resourceMetadataUrl,
1448
- scope,
1449
- fetchFn: this.fetchFn
1450
- });
1482
+ const result = await this.authorizeOnce(
1483
+ this.resourceMetadataUrl,
1484
+ scope
1485
+ );
1451
1486
  if (result !== "AUTHORIZED") {
1452
1487
  const error = new UnauthorizedError();
1453
1488
  (_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);
@@ -1560,7 +1595,7 @@ var SseMCPTransport = class {
1560
1595
  const transportSignal = (_b3 = this.abortController) == null ? void 0 : _b3.signal;
1561
1596
  const requestSignal = (options == null ? void 0 : options.signal) == null ? transportSignal : transportSignal == null ? options.signal : AbortSignal.any([transportSignal, options.signal]);
1562
1597
  const attempt = async (triedAuth = false) => {
1563
- var _a4, _b4;
1598
+ var _a4, _b4, _c;
1564
1599
  try {
1565
1600
  const headers = await this.commonHeaders({
1566
1601
  "Content-Type": "application/json"
@@ -1574,14 +1609,17 @@ var SseMCPTransport = class {
1574
1609
  };
1575
1610
  const response = await this.fetchFn(endpoint.href, init);
1576
1611
  if (response.status === 401 && this.authProvider && !triedAuth) {
1612
+ if (await this.accessTokenChanged(
1613
+ (_a4 = new Headers(headers).get("authorization")) != null ? _a4 : void 0
1614
+ )) {
1615
+ return attempt(true);
1616
+ }
1577
1617
  const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
1578
1618
  this.resourceMetadataUrl = resourceMetadataUrl;
1579
- const result = await auth(this.authProvider, {
1580
- serverUrl: this.url,
1581
- resourceMetadataUrl: this.resourceMetadataUrl,
1582
- scope,
1583
- fetchFn: this.fetchFn
1584
- });
1619
+ const result = await this.authorizeOnce(
1620
+ this.resourceMetadataUrl,
1621
+ scope
1622
+ );
1585
1623
  if (result !== "AUTHORIZED") {
1586
1624
  throw new UnauthorizedError();
1587
1625
  }
@@ -1598,10 +1636,10 @@ var SseMCPTransport = class {
1598
1636
  throw error;
1599
1637
  }
1600
1638
  } catch (error) {
1601
- if ((_a4 = options == null ? void 0 : options.signal) == null ? void 0 : _a4.aborted) {
1639
+ if ((_b4 = options == null ? void 0 : options.signal) == null ? void 0 : _b4.aborted) {
1602
1640
  throw error;
1603
1641
  }
1604
- (_b4 = this.onerror) == null ? void 0 : _b4.call(this, error);
1642
+ (_c = this.onerror) == null ? void 0 : _c.call(this, error);
1605
1643
  throw error;
1606
1644
  }
1607
1645
  };