@ai-sdk/mcp 1.0.46 → 1.0.48
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 +15 -0
- package/dist/index.d.mts +20 -1
- package/dist/index.d.ts +20 -1
- package/dist/index.js +197 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +197 -24
- package/dist/index.mjs.map +1 -1
- package/dist/mcp-stdio/index.d.mts +4 -0
- package/dist/mcp-stdio/index.d.ts +4 -0
- package/package.json +4 -4
- package/src/index.ts +4 -1
- package/src/tool/mcp-client.ts +5 -1
- package/src/tool/mcp-http-transport.ts +4 -0
- package/src/tool/mcp-sse-transport.ts +4 -0
- package/src/tool/mcp-transport.ts +5 -0
- package/src/tool/oauth-types.ts +18 -14
- package/src/tool/oauth.ts +265 -19
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");
|
|
@@ -971,8 +1075,10 @@ async function authInternal(provider, {
|
|
|
971
1075
|
resourceMetadataUrl,
|
|
972
1076
|
fetchFn
|
|
973
1077
|
}) {
|
|
1078
|
+
var _a3, _b3;
|
|
974
1079
|
let resourceMetadata;
|
|
975
1080
|
let authorizationServerUrl;
|
|
1081
|
+
assertResourceMetadataUrlSameOrigin(serverUrl, resourceMetadataUrl);
|
|
976
1082
|
try {
|
|
977
1083
|
resourceMetadata = await discoverOAuthProtectedResourceMetadata(
|
|
978
1084
|
serverUrl,
|
|
@@ -992,12 +1098,18 @@ async function authInternal(provider, {
|
|
|
992
1098
|
provider,
|
|
993
1099
|
resourceMetadata
|
|
994
1100
|
);
|
|
1101
|
+
await ((_a3 = provider.validateAuthorizationServerURL) == null ? void 0 : _a3.call(
|
|
1102
|
+
provider,
|
|
1103
|
+
serverUrl,
|
|
1104
|
+
authorizationServerUrl
|
|
1105
|
+
));
|
|
995
1106
|
const metadata = await discoverAuthorizationServerMetadata(
|
|
996
1107
|
authorizationServerUrl,
|
|
997
1108
|
{
|
|
998
1109
|
fetchFn
|
|
999
1110
|
}
|
|
1000
1111
|
);
|
|
1112
|
+
const currentAuthorizationServerInformation = createAuthorizationServerInformation(authorizationServerUrl, metadata);
|
|
1001
1113
|
let clientInformation = await Promise.resolve(provider.clientInformation());
|
|
1002
1114
|
if (!clientInformation) {
|
|
1003
1115
|
if (authorizationCode !== void 0) {
|
|
@@ -1015,8 +1127,11 @@ async function authInternal(provider, {
|
|
|
1015
1127
|
clientMetadata: provider.clientMetadata,
|
|
1016
1128
|
fetchFn
|
|
1017
1129
|
});
|
|
1018
|
-
|
|
1019
|
-
|
|
1130
|
+
clientInformation = addAuthorizationServerInformationToClientInformation(
|
|
1131
|
+
fullInformation,
|
|
1132
|
+
currentAuthorizationServerInformation
|
|
1133
|
+
);
|
|
1134
|
+
await provider.saveClientInformation(clientInformation);
|
|
1020
1135
|
}
|
|
1021
1136
|
if (authorizationCode !== void 0) {
|
|
1022
1137
|
if (provider.storedState) {
|
|
@@ -1027,6 +1142,19 @@ async function authInternal(provider, {
|
|
|
1027
1142
|
);
|
|
1028
1143
|
}
|
|
1029
1144
|
}
|
|
1145
|
+
const storedAuthorizationServerInformation = await getStoredAuthorizationServerInformation({
|
|
1146
|
+
provider,
|
|
1147
|
+
clientInformation
|
|
1148
|
+
});
|
|
1149
|
+
if (!storedAuthorizationServerInformation) {
|
|
1150
|
+
throw new MCPClientOAuthError({
|
|
1151
|
+
message: "Stored OAuth authorization server metadata is required when exchanging an authorization code"
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
assertAuthorizationServerInformationMatches({
|
|
1155
|
+
storedAuthorizationServerInformation,
|
|
1156
|
+
currentAuthorizationServerInformation
|
|
1157
|
+
});
|
|
1030
1158
|
const codeVerifier2 = await provider.codeVerifier();
|
|
1031
1159
|
const tokens2 = await exchangeAuthorization(authorizationServerUrl, {
|
|
1032
1160
|
metadata,
|
|
@@ -1038,22 +1166,47 @@ async function authInternal(provider, {
|
|
|
1038
1166
|
addClientAuthentication: provider.addClientAuthentication,
|
|
1039
1167
|
fetchFn
|
|
1040
1168
|
});
|
|
1041
|
-
await provider.saveTokens(
|
|
1169
|
+
await provider.saveTokens(
|
|
1170
|
+
addAuthorizationServerInformationToTokens(
|
|
1171
|
+
tokens2,
|
|
1172
|
+
currentAuthorizationServerInformation
|
|
1173
|
+
)
|
|
1174
|
+
);
|
|
1042
1175
|
return "AUTHORIZED";
|
|
1043
1176
|
}
|
|
1044
1177
|
const tokens = await provider.tokens();
|
|
1045
1178
|
if (tokens == null ? void 0 : tokens.refresh_token) {
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1179
|
+
const storedAuthorizationServerInformation = await getStoredAuthorizationServerInformation({
|
|
1180
|
+
provider,
|
|
1181
|
+
clientInformation,
|
|
1182
|
+
tokens
|
|
1183
|
+
});
|
|
1184
|
+
if (storedAuthorizationServerInformation) {
|
|
1185
|
+
assertAuthorizationServerInformationMatches({
|
|
1186
|
+
storedAuthorizationServerInformation,
|
|
1187
|
+
currentAuthorizationServerInformation
|
|
1054
1188
|
});
|
|
1055
|
-
|
|
1056
|
-
|
|
1189
|
+
} else {
|
|
1190
|
+
await ((_b3 = provider.invalidateCredentials) == null ? void 0 : _b3.call(provider, "tokens"));
|
|
1191
|
+
}
|
|
1192
|
+
try {
|
|
1193
|
+
if (storedAuthorizationServerInformation) {
|
|
1194
|
+
const newTokens = await refreshAuthorization(authorizationServerUrl, {
|
|
1195
|
+
metadata,
|
|
1196
|
+
clientInformation,
|
|
1197
|
+
refreshToken: tokens.refresh_token,
|
|
1198
|
+
resource,
|
|
1199
|
+
addClientAuthentication: provider.addClientAuthentication,
|
|
1200
|
+
fetchFn
|
|
1201
|
+
});
|
|
1202
|
+
await provider.saveTokens(
|
|
1203
|
+
addAuthorizationServerInformationToTokens(
|
|
1204
|
+
newTokens,
|
|
1205
|
+
currentAuthorizationServerInformation
|
|
1206
|
+
)
|
|
1207
|
+
);
|
|
1208
|
+
return "AUTHORIZED";
|
|
1209
|
+
}
|
|
1057
1210
|
} catch (error) {
|
|
1058
1211
|
if (
|
|
1059
1212
|
// 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.
|
|
@@ -1079,6 +1232,16 @@ async function authInternal(provider, {
|
|
|
1079
1232
|
resource
|
|
1080
1233
|
}
|
|
1081
1234
|
);
|
|
1235
|
+
const savedAuthorizationServerInformation = await saveAuthorizationServerInformation({
|
|
1236
|
+
provider,
|
|
1237
|
+
clientInformation,
|
|
1238
|
+
authorizationServerInformation: currentAuthorizationServerInformation
|
|
1239
|
+
});
|
|
1240
|
+
if (!savedAuthorizationServerInformation) {
|
|
1241
|
+
throw new MCPClientOAuthError({
|
|
1242
|
+
message: "OAuth authorization server metadata must be saveable before starting authorization"
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1082
1245
|
await provider.saveCodeVerifier(codeVerifier);
|
|
1083
1246
|
await provider.redirectToAuthorization(authorizationUrl);
|
|
1084
1247
|
return "REDIRECT";
|
|
@@ -1100,6 +1263,9 @@ var SseMCPTransport = class {
|
|
|
1100
1263
|
this.redirectMode = redirect;
|
|
1101
1264
|
this.fetchFn = fetchFn != null ? fetchFn : globalThis.fetch;
|
|
1102
1265
|
}
|
|
1266
|
+
setProtocolVersion(version) {
|
|
1267
|
+
this.protocolVersion = version;
|
|
1268
|
+
}
|
|
1103
1269
|
async commonHeaders(base) {
|
|
1104
1270
|
var _a3;
|
|
1105
1271
|
const headers = {
|
|
@@ -1319,6 +1485,9 @@ var HttpMCPTransport = class {
|
|
|
1319
1485
|
this.redirectMode = redirect;
|
|
1320
1486
|
this.fetchFn = fetchFn != null ? fetchFn : globalThis.fetch;
|
|
1321
1487
|
}
|
|
1488
|
+
setProtocolVersion(version) {
|
|
1489
|
+
this.protocolVersion = version;
|
|
1490
|
+
}
|
|
1322
1491
|
async commonHeaders(base) {
|
|
1323
1492
|
var _a3;
|
|
1324
1493
|
const headers = {
|
|
@@ -1762,8 +1931,12 @@ var DefaultMCPClient = class {
|
|
|
1762
1931
|
}
|
|
1763
1932
|
this.serverCapabilities = result.capabilities;
|
|
1764
1933
|
this._serverInfo = result.serverInfo;
|
|
1934
|
+
if (this.transport.setProtocolVersion) {
|
|
1935
|
+
this.transport.setProtocolVersion(result.protocolVersion);
|
|
1936
|
+
} else {
|
|
1937
|
+
this.transport.protocolVersion = result.protocolVersion;
|
|
1938
|
+
}
|
|
1765
1939
|
this._serverInstructions = result.instructions;
|
|
1766
|
-
this.transport.protocolVersion = result.protocolVersion;
|
|
1767
1940
|
await this.notification({
|
|
1768
1941
|
method: "notifications/initialized"
|
|
1769
1942
|
});
|