@ai-sdk/mcp 1.0.90 → 1.0.91

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": "1.0.90",
3
+ "version": "1.0.91",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
package/src/tool/oauth.ts CHANGED
@@ -80,9 +80,15 @@ export interface OAuthClientProvider {
80
80
  * If implemented, provides a way for the client to invalidate (e.g. delete) the specified
81
81
  * credentials, in the case where the server has indicated that they are no longer valid.
82
82
  * This avoids requiring the user to intervene manually.
83
+ *
84
+ * For token invalidation, context identifies the token generation being invalidated
85
+ * when available. Providers sharing storage must atomically compare and delete
86
+ * that generation so a concurrent refresh's tokens are preserved. Omitting or
87
+ * ignoring context retains unconditional invalidation.
83
88
  */
84
89
  invalidateCredentials?(
85
90
  scope: 'all' | 'client' | 'tokens' | 'verifier',
91
+ context?: { tokens: OAuthTokens },
86
92
  ): void | Promise<void>;
87
93
  get redirectUrl(): string | URL;
88
94
  get clientMetadata(): OAuthClientMetadata;
@@ -1214,8 +1220,9 @@ export async function auth(
1214
1220
  fetchFn?: FetchFunction;
1215
1221
  },
1216
1222
  ): Promise<AuthResult> {
1223
+ const refreshAttempt: { tokens?: OAuthTokens } = {};
1217
1224
  try {
1218
- return await authInternal(provider, options);
1225
+ return await authInternal(provider, options, refreshAttempt);
1219
1226
  } catch (error) {
1220
1227
  if (
1221
1228
  error instanceof InvalidClientError ||
@@ -1230,8 +1237,11 @@ export async function auth(
1230
1237
 
1231
1238
  await provider.invalidateCredentials?.('all');
1232
1239
  return await authInternal(provider, options);
1233
- } else if (error instanceof InvalidGrantError) {
1234
- await provider.invalidateCredentials?.('tokens');
1240
+ } else if (error instanceof InvalidGrantError && refreshAttempt.tokens) {
1241
+ // Only invalidate the tokens used by a failed refresh.
1242
+ await provider.invalidateCredentials?.('tokens', {
1243
+ tokens: refreshAttempt.tokens,
1244
+ });
1235
1245
  return await authInternal(provider, options);
1236
1246
  }
1237
1247
 
@@ -1287,6 +1297,7 @@ async function authInternal(
1287
1297
  resourceMetadataUrl?: URL;
1288
1298
  fetchFn?: FetchFunction;
1289
1299
  },
1300
+ refreshAttempt?: { tokens?: OAuthTokens },
1290
1301
  ): Promise<AuthResult> {
1291
1302
  let resourceMetadata: OAuthProtectedResourceMetadata | undefined;
1292
1303
  let authorizationServerUrl: string | URL | undefined;
@@ -1483,11 +1494,16 @@ async function authInternal(
1483
1494
  currentAuthorizationServerInformation,
1484
1495
  });
1485
1496
  } else {
1486
- await provider.invalidateCredentials?.('tokens');
1497
+ await provider.invalidateCredentials?.('tokens', {
1498
+ tokens: { ...tokens },
1499
+ });
1487
1500
  }
1488
1501
 
1489
1502
  try {
1490
1503
  if (storedAuthorizationServerInformation) {
1504
+ if (refreshAttempt) {
1505
+ refreshAttempt.tokens = { ...tokens };
1506
+ }
1491
1507
  // Attempt to refresh the token
1492
1508
  const newTokens = await refreshAuthorization(authorizationServerUrl, {
1493
1509
  metadata,