@ai-sdk/mcp 2.0.63 → 2.0.65

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/mcp",
3
- "version": "2.0.63",
3
+ "version": "2.0.65",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -31,8 +31,8 @@
31
31
  }
32
32
  },
33
33
  "dependencies": {
34
- "@ai-sdk/provider": "4.0.20",
35
- "@ai-sdk/provider-utils": "5.0.52",
34
+ "@ai-sdk/provider": "4.0.21",
35
+ "@ai-sdk/provider-utils": "5.0.53",
36
36
  "cross-spawn": "^7.0.6",
37
37
  "pkce-challenge": "^5.0.1"
38
38
  },
package/src/tool/oauth.ts CHANGED
@@ -81,9 +81,15 @@ export interface OAuthClientProvider {
81
81
  * If implemented, provides a way for the client to invalidate (e.g. delete) the specified
82
82
  * credentials, in the case where the server has indicated that they are no longer valid.
83
83
  * This avoids requiring the user to intervene manually.
84
+ *
85
+ * For token invalidation, context identifies the token generation being invalidated
86
+ * when available. Providers sharing storage must atomically compare and delete
87
+ * that generation so a concurrent refresh's tokens are preserved. Omitting or
88
+ * ignoring context retains unconditional invalidation.
84
89
  */
85
90
  invalidateCredentials?(
86
91
  scope: 'all' | 'client' | 'tokens' | 'verifier',
92
+ context?: { tokens: OAuthTokens },
87
93
  ): void | Promise<void>;
88
94
  get redirectUrl(): string | URL;
89
95
  get clientMetadata(): OAuthClientMetadata;
@@ -1261,8 +1267,9 @@ export async function auth(
1261
1267
  fetchFn?: FetchFunction;
1262
1268
  },
1263
1269
  ): Promise<AuthResult> {
1270
+ const refreshAttempt: { tokens?: OAuthTokens } = {};
1264
1271
  try {
1265
- return await authInternal(provider, options);
1272
+ return await authInternal(provider, options, refreshAttempt);
1266
1273
  } catch (error) {
1267
1274
  if (
1268
1275
  error instanceof InvalidClientError ||
@@ -1278,7 +1285,13 @@ export async function auth(
1278
1285
  await provider.invalidateCredentials?.('all');
1279
1286
  return await authInternal(provider, options);
1280
1287
  } else if (error instanceof InvalidGrantError) {
1281
- await provider.invalidateCredentials?.('tokens');
1288
+ if (refreshAttempt.tokens) {
1289
+ await provider.invalidateCredentials?.('tokens', {
1290
+ tokens: refreshAttempt.tokens,
1291
+ });
1292
+ } else {
1293
+ await provider.invalidateCredentials?.('tokens');
1294
+ }
1282
1295
  return await authInternal(provider, options);
1283
1296
  }
1284
1297
 
@@ -1336,6 +1349,7 @@ async function authInternal(
1336
1349
  resourceMetadataUrl?: URL;
1337
1350
  fetchFn?: FetchFunction;
1338
1351
  },
1352
+ refreshAttempt?: { tokens?: OAuthTokens },
1339
1353
  ): Promise<AuthResult> {
1340
1354
  let resourceMetadata: OAuthProtectedResourceMetadata | undefined;
1341
1355
  let authorizationServerUrl: string | URL | undefined;
@@ -1554,11 +1568,16 @@ async function authInternal(
1554
1568
  currentAuthorizationServerInformation,
1555
1569
  });
1556
1570
  } else {
1557
- await provider.invalidateCredentials?.('tokens');
1571
+ await provider.invalidateCredentials?.('tokens', {
1572
+ tokens: { ...tokens },
1573
+ });
1558
1574
  }
1559
1575
 
1560
1576
  try {
1561
1577
  if (storedAuthorizationServerInformation) {
1578
+ if (refreshAttempt) {
1579
+ refreshAttempt.tokens = { ...tokens };
1580
+ }
1562
1581
  // Attempt to refresh the token
1563
1582
  const newTokens = await refreshAuthorization(authorizationServerUrl, {
1564
1583
  metadata,