@ai-sdk/mcp 1.0.45 → 1.0.47
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 +12 -0
- package/dist/index.d.mts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +193 -25
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +193 -25
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +4 -1
- package/src/tool/oauth-types.ts +18 -14
- package/src/tool/oauth.ts +263 -21
package/dist/index.mjs
CHANGED
|
@@ -312,15 +312,6 @@ import pkceChallenge from "pkce-challenge";
|
|
|
312
312
|
|
|
313
313
|
// src/tool/oauth-types.ts
|
|
314
314
|
import { z as z3 } from "zod/v4";
|
|
315
|
-
var OAuthTokensSchema = z3.object({
|
|
316
|
-
access_token: z3.string(),
|
|
317
|
-
id_token: z3.string().optional(),
|
|
318
|
-
// Optional for OAuth 2.1, but necessary in OpenID Connect
|
|
319
|
-
token_type: z3.string(),
|
|
320
|
-
expires_in: z3.number().optional(),
|
|
321
|
-
scope: z3.string().optional(),
|
|
322
|
-
refresh_token: z3.string().optional()
|
|
323
|
-
}).strip();
|
|
324
315
|
var SafeUrlSchema = z3.string().url().superRefine((val, ctx) => {
|
|
325
316
|
if (!URL.canParse(val)) {
|
|
326
317
|
ctx.addIssue({
|
|
@@ -337,6 +328,17 @@ var SafeUrlSchema = z3.string().url().superRefine((val, ctx) => {
|
|
|
337
328
|
},
|
|
338
329
|
{ message: "URL cannot use javascript:, data:, or vbscript: scheme" }
|
|
339
330
|
);
|
|
331
|
+
var OAuthTokensSchema = z3.object({
|
|
332
|
+
access_token: z3.string(),
|
|
333
|
+
id_token: z3.string().optional(),
|
|
334
|
+
// Optional for OAuth 2.1, but necessary in OpenID Connect
|
|
335
|
+
token_type: z3.string(),
|
|
336
|
+
expires_in: z3.number().optional(),
|
|
337
|
+
scope: z3.string().optional(),
|
|
338
|
+
refresh_token: z3.string().optional(),
|
|
339
|
+
authorization_server: SafeUrlSchema.optional(),
|
|
340
|
+
token_endpoint: SafeUrlSchema.optional()
|
|
341
|
+
}).strip();
|
|
340
342
|
var OAuthProtectedResourceMetadataSchema = z3.object({
|
|
341
343
|
resource: z3.string().url(),
|
|
342
344
|
authorization_servers: z3.array(SafeUrlSchema).optional(),
|
|
@@ -389,7 +391,9 @@ var OAuthClientInformationSchema = z3.object({
|
|
|
389
391
|
client_id: z3.string(),
|
|
390
392
|
client_secret: z3.string().optional(),
|
|
391
393
|
client_id_issued_at: z3.number().optional(),
|
|
392
|
-
client_secret_expires_at: z3.number().optional()
|
|
394
|
+
client_secret_expires_at: z3.number().optional(),
|
|
395
|
+
authorization_server: SafeUrlSchema.optional(),
|
|
396
|
+
token_endpoint: SafeUrlSchema.optional()
|
|
393
397
|
}).strip();
|
|
394
398
|
var OAuthClientMetadataSchema = z3.object({
|
|
395
399
|
redirect_uris: z3.array(SafeUrlSchema),
|
|
@@ -494,6 +498,106 @@ var UnauthorizedError = class extends Error {
|
|
|
494
498
|
this.name = "UnauthorizedError";
|
|
495
499
|
}
|
|
496
500
|
};
|
|
501
|
+
function normalizeUrl(url) {
|
|
502
|
+
return new URL(url).href;
|
|
503
|
+
}
|
|
504
|
+
function createAuthorizationServerInformation(authorizationServerUrl, metadata) {
|
|
505
|
+
return {
|
|
506
|
+
authorizationServerUrl: normalizeUrl(authorizationServerUrl),
|
|
507
|
+
tokenEndpoint: normalizeUrl(
|
|
508
|
+
(metadata == null ? void 0 : metadata.token_endpoint) ? new URL(metadata.token_endpoint) : new URL("/token", authorizationServerUrl)
|
|
509
|
+
)
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
function addAuthorizationServerInformationToTokens(tokens, authorizationServerInformation) {
|
|
513
|
+
return {
|
|
514
|
+
...tokens,
|
|
515
|
+
authorization_server: authorizationServerInformation.authorizationServerUrl,
|
|
516
|
+
token_endpoint: authorizationServerInformation.tokenEndpoint
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
function addAuthorizationServerInformationToClientInformation(clientInformation, authorizationServerInformation) {
|
|
520
|
+
return {
|
|
521
|
+
...clientInformation,
|
|
522
|
+
authorization_server: authorizationServerInformation.authorizationServerUrl,
|
|
523
|
+
token_endpoint: authorizationServerInformation.tokenEndpoint
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
function getAuthorizationServerInformationFromCredentials(credentials) {
|
|
527
|
+
if (!(credentials == null ? void 0 : credentials.authorization_server) || !credentials.token_endpoint) {
|
|
528
|
+
return void 0;
|
|
529
|
+
}
|
|
530
|
+
return {
|
|
531
|
+
authorizationServerUrl: normalizeUrl(credentials.authorization_server),
|
|
532
|
+
tokenEndpoint: normalizeUrl(credentials.token_endpoint)
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
async function getStoredAuthorizationServerInformation({
|
|
536
|
+
provider,
|
|
537
|
+
clientInformation,
|
|
538
|
+
tokens
|
|
539
|
+
}) {
|
|
540
|
+
var _a3;
|
|
541
|
+
const tokenAuthorizationServerInformation = getAuthorizationServerInformationFromCredentials(tokens);
|
|
542
|
+
if (tokenAuthorizationServerInformation) {
|
|
543
|
+
return tokenAuthorizationServerInformation;
|
|
544
|
+
}
|
|
545
|
+
const providerAuthorizationServerInformation = await ((_a3 = provider.authorizationServerInformation) == null ? void 0 : _a3.call(provider));
|
|
546
|
+
if (providerAuthorizationServerInformation) {
|
|
547
|
+
return {
|
|
548
|
+
authorizationServerUrl: normalizeUrl(
|
|
549
|
+
providerAuthorizationServerInformation.authorizationServerUrl
|
|
550
|
+
),
|
|
551
|
+
tokenEndpoint: normalizeUrl(
|
|
552
|
+
providerAuthorizationServerInformation.tokenEndpoint
|
|
553
|
+
)
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
return getAuthorizationServerInformationFromCredentials(clientInformation);
|
|
557
|
+
}
|
|
558
|
+
async function saveAuthorizationServerInformation({
|
|
559
|
+
provider,
|
|
560
|
+
clientInformation,
|
|
561
|
+
authorizationServerInformation
|
|
562
|
+
}) {
|
|
563
|
+
if (provider.saveAuthorizationServerInformation) {
|
|
564
|
+
await provider.saveAuthorizationServerInformation(
|
|
565
|
+
authorizationServerInformation
|
|
566
|
+
);
|
|
567
|
+
return true;
|
|
568
|
+
}
|
|
569
|
+
if (provider.saveClientInformation) {
|
|
570
|
+
await provider.saveClientInformation(
|
|
571
|
+
addAuthorizationServerInformationToClientInformation(
|
|
572
|
+
clientInformation,
|
|
573
|
+
authorizationServerInformation
|
|
574
|
+
)
|
|
575
|
+
);
|
|
576
|
+
return true;
|
|
577
|
+
}
|
|
578
|
+
return false;
|
|
579
|
+
}
|
|
580
|
+
function assertResourceMetadataUrlSameOrigin(serverUrl, resourceMetadataUrl) {
|
|
581
|
+
if (!resourceMetadataUrl) {
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
const expectedOrigin = new URL(serverUrl).origin;
|
|
585
|
+
if (resourceMetadataUrl.origin !== expectedOrigin) {
|
|
586
|
+
throw new MCPClientOAuthError({
|
|
587
|
+
message: `OAuth protected resource metadata URL ${resourceMetadataUrl.href} must have the same origin as the MCP server URL ${expectedOrigin}`
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
function assertAuthorizationServerInformationMatches({
|
|
592
|
+
storedAuthorizationServerInformation,
|
|
593
|
+
currentAuthorizationServerInformation
|
|
594
|
+
}) {
|
|
595
|
+
if (storedAuthorizationServerInformation.authorizationServerUrl !== currentAuthorizationServerInformation.authorizationServerUrl || storedAuthorizationServerInformation.tokenEndpoint !== currentAuthorizationServerInformation.tokenEndpoint) {
|
|
596
|
+
throw new MCPClientOAuthError({
|
|
597
|
+
message: "OAuth authorization server metadata does not match the metadata that issued the stored credentials"
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
}
|
|
497
601
|
function extractResourceMetadataUrl(response) {
|
|
498
602
|
var _a3;
|
|
499
603
|
const header = (_a3 = response.headers.get("www-authenticate")) != null ? _a3 : response.headers.get("WWW-Authenticate");
|
|
@@ -812,7 +916,12 @@ async function exchangeAuthorization(authorizationServerUrl, {
|
|
|
812
916
|
redirect_uri: String(redirectUri)
|
|
813
917
|
});
|
|
814
918
|
if (addClientAuthentication) {
|
|
815
|
-
addClientAuthentication(
|
|
919
|
+
await addClientAuthentication(
|
|
920
|
+
headers,
|
|
921
|
+
params,
|
|
922
|
+
authorizationServerUrl,
|
|
923
|
+
metadata
|
|
924
|
+
);
|
|
816
925
|
} else {
|
|
817
926
|
const supportedMethods = (_a3 = metadata == null ? void 0 : metadata.token_endpoint_auth_methods_supported) != null ? _a3 : [];
|
|
818
927
|
const authMethod = selectClientAuthMethod(
|
|
@@ -864,7 +973,12 @@ async function refreshAuthorization(authorizationServerUrl, {
|
|
|
864
973
|
refresh_token: refreshToken
|
|
865
974
|
});
|
|
866
975
|
if (addClientAuthentication) {
|
|
867
|
-
addClientAuthentication(
|
|
976
|
+
await addClientAuthentication(
|
|
977
|
+
headers,
|
|
978
|
+
params,
|
|
979
|
+
authorizationServerUrl,
|
|
980
|
+
metadata
|
|
981
|
+
);
|
|
868
982
|
} else {
|
|
869
983
|
const supportedMethods = (_a3 = metadata == null ? void 0 : metadata.token_endpoint_auth_methods_supported) != null ? _a3 : [];
|
|
870
984
|
const authMethod = selectClientAuthMethod(
|
|
@@ -961,8 +1075,10 @@ async function authInternal(provider, {
|
|
|
961
1075
|
resourceMetadataUrl,
|
|
962
1076
|
fetchFn
|
|
963
1077
|
}) {
|
|
1078
|
+
var _a3;
|
|
964
1079
|
let resourceMetadata;
|
|
965
1080
|
let authorizationServerUrl;
|
|
1081
|
+
assertResourceMetadataUrlSameOrigin(serverUrl, resourceMetadataUrl);
|
|
966
1082
|
try {
|
|
967
1083
|
resourceMetadata = await discoverOAuthProtectedResourceMetadata(
|
|
968
1084
|
serverUrl,
|
|
@@ -988,6 +1104,7 @@ async function authInternal(provider, {
|
|
|
988
1104
|
fetchFn
|
|
989
1105
|
}
|
|
990
1106
|
);
|
|
1107
|
+
const currentAuthorizationServerInformation = createAuthorizationServerInformation(authorizationServerUrl, metadata);
|
|
991
1108
|
let clientInformation = await Promise.resolve(provider.clientInformation());
|
|
992
1109
|
if (!clientInformation) {
|
|
993
1110
|
if (authorizationCode !== void 0) {
|
|
@@ -1005,8 +1122,11 @@ async function authInternal(provider, {
|
|
|
1005
1122
|
clientMetadata: provider.clientMetadata,
|
|
1006
1123
|
fetchFn
|
|
1007
1124
|
});
|
|
1008
|
-
|
|
1009
|
-
|
|
1125
|
+
clientInformation = addAuthorizationServerInformationToClientInformation(
|
|
1126
|
+
fullInformation,
|
|
1127
|
+
currentAuthorizationServerInformation
|
|
1128
|
+
);
|
|
1129
|
+
await provider.saveClientInformation(clientInformation);
|
|
1010
1130
|
}
|
|
1011
1131
|
if (authorizationCode !== void 0) {
|
|
1012
1132
|
if (provider.storedState) {
|
|
@@ -1017,6 +1137,19 @@ async function authInternal(provider, {
|
|
|
1017
1137
|
);
|
|
1018
1138
|
}
|
|
1019
1139
|
}
|
|
1140
|
+
const storedAuthorizationServerInformation = await getStoredAuthorizationServerInformation({
|
|
1141
|
+
provider,
|
|
1142
|
+
clientInformation
|
|
1143
|
+
});
|
|
1144
|
+
if (!storedAuthorizationServerInformation) {
|
|
1145
|
+
throw new MCPClientOAuthError({
|
|
1146
|
+
message: "Stored OAuth authorization server metadata is required when exchanging an authorization code"
|
|
1147
|
+
});
|
|
1148
|
+
}
|
|
1149
|
+
assertAuthorizationServerInformationMatches({
|
|
1150
|
+
storedAuthorizationServerInformation,
|
|
1151
|
+
currentAuthorizationServerInformation
|
|
1152
|
+
});
|
|
1020
1153
|
const codeVerifier2 = await provider.codeVerifier();
|
|
1021
1154
|
const tokens2 = await exchangeAuthorization(authorizationServerUrl, {
|
|
1022
1155
|
metadata,
|
|
@@ -1028,22 +1161,47 @@ async function authInternal(provider, {
|
|
|
1028
1161
|
addClientAuthentication: provider.addClientAuthentication,
|
|
1029
1162
|
fetchFn
|
|
1030
1163
|
});
|
|
1031
|
-
await provider.saveTokens(
|
|
1164
|
+
await provider.saveTokens(
|
|
1165
|
+
addAuthorizationServerInformationToTokens(
|
|
1166
|
+
tokens2,
|
|
1167
|
+
currentAuthorizationServerInformation
|
|
1168
|
+
)
|
|
1169
|
+
);
|
|
1032
1170
|
return "AUTHORIZED";
|
|
1033
1171
|
}
|
|
1034
1172
|
const tokens = await provider.tokens();
|
|
1035
1173
|
if (tokens == null ? void 0 : tokens.refresh_token) {
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1174
|
+
const storedAuthorizationServerInformation = await getStoredAuthorizationServerInformation({
|
|
1175
|
+
provider,
|
|
1176
|
+
clientInformation,
|
|
1177
|
+
tokens
|
|
1178
|
+
});
|
|
1179
|
+
if (storedAuthorizationServerInformation) {
|
|
1180
|
+
assertAuthorizationServerInformationMatches({
|
|
1181
|
+
storedAuthorizationServerInformation,
|
|
1182
|
+
currentAuthorizationServerInformation
|
|
1044
1183
|
});
|
|
1045
|
-
|
|
1046
|
-
|
|
1184
|
+
} else {
|
|
1185
|
+
await ((_a3 = provider.invalidateCredentials) == null ? void 0 : _a3.call(provider, "tokens"));
|
|
1186
|
+
}
|
|
1187
|
+
try {
|
|
1188
|
+
if (storedAuthorizationServerInformation) {
|
|
1189
|
+
const newTokens = await refreshAuthorization(authorizationServerUrl, {
|
|
1190
|
+
metadata,
|
|
1191
|
+
clientInformation,
|
|
1192
|
+
refreshToken: tokens.refresh_token,
|
|
1193
|
+
resource,
|
|
1194
|
+
addClientAuthentication: provider.addClientAuthentication,
|
|
1195
|
+
fetchFn
|
|
1196
|
+
});
|
|
1197
|
+
await provider.saveTokens(
|
|
1198
|
+
addAuthorizationServerInformationToTokens(
|
|
1199
|
+
newTokens,
|
|
1200
|
+
currentAuthorizationServerInformation
|
|
1201
|
+
)
|
|
1202
|
+
);
|
|
1203
|
+
return "AUTHORIZED";
|
|
1204
|
+
}
|
|
1047
1205
|
} catch (error) {
|
|
1048
1206
|
if (
|
|
1049
1207
|
// If this is a ServerError, or an unknown type, log it out and try to continue. Otherwise, escalate so we can fix things and retry.
|
|
@@ -1069,6 +1227,16 @@ async function authInternal(provider, {
|
|
|
1069
1227
|
resource
|
|
1070
1228
|
}
|
|
1071
1229
|
);
|
|
1230
|
+
const savedAuthorizationServerInformation = await saveAuthorizationServerInformation({
|
|
1231
|
+
provider,
|
|
1232
|
+
clientInformation,
|
|
1233
|
+
authorizationServerInformation: currentAuthorizationServerInformation
|
|
1234
|
+
});
|
|
1235
|
+
if (!savedAuthorizationServerInformation) {
|
|
1236
|
+
throw new MCPClientOAuthError({
|
|
1237
|
+
message: "OAuth authorization server metadata must be saveable before starting authorization"
|
|
1238
|
+
});
|
|
1239
|
+
}
|
|
1072
1240
|
await provider.saveCodeVerifier(codeVerifier);
|
|
1073
1241
|
await provider.redirectToAuthorization(authorizationUrl);
|
|
1074
1242
|
return "REDIRECT";
|