@ai-sdk/mcp 1.0.90 → 1.0.92
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 +14 -0
- package/dist/index.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +22 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/tool/oauth.ts +34 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @ai-sdk/mcp
|
|
2
2
|
|
|
3
|
+
## 1.0.92
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ff05827: fix(mcp): authorization server paths beginning with repeated slashes should not bypass authorization server validation
|
|
8
|
+
|
|
9
|
+
## 1.0.91
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 5267a7a: Preserve stored OAuth credentials when an authorization-code exchange returns `invalid_grant`, without retrying the rejected code.
|
|
14
|
+
|
|
15
|
+
Add optional token context to `OAuthClientProvider.invalidateCredentials` so providers sharing storage can atomically delete only the rejected token generation and preserve tokens saved by a concurrent refresh.
|
|
16
|
+
|
|
3
17
|
## 1.0.90
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -184,8 +184,15 @@ interface OAuthClientProvider {
|
|
|
184
184
|
* If implemented, provides a way for the client to invalidate (e.g. delete) the specified
|
|
185
185
|
* credentials, in the case where the server has indicated that they are no longer valid.
|
|
186
186
|
* This avoids requiring the user to intervene manually.
|
|
187
|
+
*
|
|
188
|
+
* For token invalidation, context identifies the token generation being invalidated
|
|
189
|
+
* when available. Providers sharing storage must atomically compare and delete
|
|
190
|
+
* that generation so a concurrent refresh's tokens are preserved. Omitting or
|
|
191
|
+
* ignoring context retains unconditional invalidation.
|
|
187
192
|
*/
|
|
188
|
-
invalidateCredentials?(scope: 'all' | 'client' | 'tokens' | 'verifier'
|
|
193
|
+
invalidateCredentials?(scope: 'all' | 'client' | 'tokens' | 'verifier', context?: {
|
|
194
|
+
tokens: OAuthTokens;
|
|
195
|
+
}): void | Promise<void>;
|
|
189
196
|
get redirectUrl(): string | URL;
|
|
190
197
|
get clientMetadata(): OAuthClientMetadata;
|
|
191
198
|
clientInformation(): OAuthClientInformation | undefined | Promise<OAuthClientInformation | undefined>;
|
package/dist/index.d.ts
CHANGED
|
@@ -184,8 +184,15 @@ interface OAuthClientProvider {
|
|
|
184
184
|
* If implemented, provides a way for the client to invalidate (e.g. delete) the specified
|
|
185
185
|
* credentials, in the case where the server has indicated that they are no longer valid.
|
|
186
186
|
* This avoids requiring the user to intervene manually.
|
|
187
|
+
*
|
|
188
|
+
* For token invalidation, context identifies the token generation being invalidated
|
|
189
|
+
* when available. Providers sharing storage must atomically compare and delete
|
|
190
|
+
* that generation so a concurrent refresh's tokens are preserved. Omitting or
|
|
191
|
+
* ignoring context retains unconditional invalidation.
|
|
187
192
|
*/
|
|
188
|
-
invalidateCredentials?(scope: 'all' | 'client' | 'tokens' | 'verifier'
|
|
193
|
+
invalidateCredentials?(scope: 'all' | 'client' | 'tokens' | 'verifier', context?: {
|
|
194
|
+
tokens: OAuthTokens;
|
|
195
|
+
}): void | Promise<void>;
|
|
189
196
|
get redirectUrl(): string | URL;
|
|
190
197
|
get clientMetadata(): OAuthClientMetadata;
|
|
191
198
|
clientInformation(): OAuthClientInformation | undefined | Promise<OAuthClientInformation | undefined>;
|
package/dist/index.js
CHANGED
|
@@ -860,8 +860,10 @@ function buildDiscoveryUrls(authorizationServerUrl) {
|
|
|
860
860
|
type: "oidc",
|
|
861
861
|
expectedIssuer: pathIssuer
|
|
862
862
|
});
|
|
863
|
+
const oidcDiscoveryUrl = new URL(url.origin);
|
|
864
|
+
oidcDiscoveryUrl.pathname = `${pathname}/.well-known/openid-configuration`;
|
|
863
865
|
urlsToTry.push({
|
|
864
|
-
url:
|
|
866
|
+
url: oidcDiscoveryUrl,
|
|
865
867
|
type: "oidc",
|
|
866
868
|
expectedIssuer: pathIssuer
|
|
867
869
|
});
|
|
@@ -882,7 +884,13 @@ async function discoverAuthorizationServerMetadata(authorizationServerUrl, {
|
|
|
882
884
|
} = {}) {
|
|
883
885
|
var _a3;
|
|
884
886
|
const headers = { "MCP-Protocol-Version": protocolVersion };
|
|
887
|
+
const authorizationServerOrigin = new URL(authorizationServerUrl).origin;
|
|
885
888
|
const urlsToTry = buildDiscoveryUrls(authorizationServerUrl);
|
|
889
|
+
if (urlsToTry.some(({ url }) => url.origin !== authorizationServerOrigin)) {
|
|
890
|
+
throw new MCPClientOAuthError({
|
|
891
|
+
message: "OAuth discovery URL changed authorization-server origin"
|
|
892
|
+
});
|
|
893
|
+
}
|
|
886
894
|
for (const { url: endpointUrl, type, expectedIssuer } of urlsToTry) {
|
|
887
895
|
const response = await fetchWithCorsRetry(
|
|
888
896
|
endpointUrl,
|
|
@@ -1215,8 +1223,9 @@ async function registerClient(authorizationServerUrl, {
|
|
|
1215
1223
|
}
|
|
1216
1224
|
async function auth(provider, options) {
|
|
1217
1225
|
var _a3, _b3, _c;
|
|
1226
|
+
const refreshAttempt = {};
|
|
1218
1227
|
try {
|
|
1219
|
-
return await authInternal(provider, options);
|
|
1228
|
+
return await authInternal(provider, options, refreshAttempt);
|
|
1220
1229
|
} catch (error) {
|
|
1221
1230
|
if (error instanceof InvalidClientError || error instanceof UnauthorizedClientError) {
|
|
1222
1231
|
if (options.authorizationCode !== void 0 || !await ((_a3 = provider.isClientInformationDynamicallyRegistered) == null ? void 0 : _a3.call(provider))) {
|
|
@@ -1224,8 +1233,10 @@ async function auth(provider, options) {
|
|
|
1224
1233
|
}
|
|
1225
1234
|
await ((_b3 = provider.invalidateCredentials) == null ? void 0 : _b3.call(provider, "all"));
|
|
1226
1235
|
return await authInternal(provider, options);
|
|
1227
|
-
} else if (error instanceof InvalidGrantError) {
|
|
1228
|
-
await ((_c = provider.invalidateCredentials) == null ? void 0 : _c.call(provider, "tokens"
|
|
1236
|
+
} else if (error instanceof InvalidGrantError && refreshAttempt.tokens) {
|
|
1237
|
+
await ((_c = provider.invalidateCredentials) == null ? void 0 : _c.call(provider, "tokens", {
|
|
1238
|
+
tokens: refreshAttempt.tokens
|
|
1239
|
+
}));
|
|
1229
1240
|
return await authInternal(provider, options);
|
|
1230
1241
|
}
|
|
1231
1242
|
throw error;
|
|
@@ -1259,7 +1270,7 @@ async function authInternal(provider, {
|
|
|
1259
1270
|
scope,
|
|
1260
1271
|
resourceMetadataUrl,
|
|
1261
1272
|
fetchFn
|
|
1262
|
-
}) {
|
|
1273
|
+
}, refreshAttempt) {
|
|
1263
1274
|
var _a3, _b3, _c;
|
|
1264
1275
|
let resourceMetadata;
|
|
1265
1276
|
let authorizationServerUrl;
|
|
@@ -1403,10 +1414,15 @@ async function authInternal(provider, {
|
|
|
1403
1414
|
currentAuthorizationServerInformation
|
|
1404
1415
|
});
|
|
1405
1416
|
} else {
|
|
1406
|
-
await ((_c = provider.invalidateCredentials) == null ? void 0 : _c.call(provider, "tokens"
|
|
1417
|
+
await ((_c = provider.invalidateCredentials) == null ? void 0 : _c.call(provider, "tokens", {
|
|
1418
|
+
tokens: { ...tokens }
|
|
1419
|
+
}));
|
|
1407
1420
|
}
|
|
1408
1421
|
try {
|
|
1409
1422
|
if (storedAuthorizationServerInformation) {
|
|
1423
|
+
if (refreshAttempt) {
|
|
1424
|
+
refreshAttempt.tokens = { ...tokens };
|
|
1425
|
+
}
|
|
1410
1426
|
const newTokens = await refreshAuthorization(authorizationServerUrl, {
|
|
1411
1427
|
metadata,
|
|
1412
1428
|
clientInformation,
|