@ai-sdk/mcp 1.0.73 → 1.0.75

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/dist/index.mjs CHANGED
@@ -524,7 +524,10 @@ function checkResourceAllowed({
524
524
  }
525
525
 
526
526
  // src/tool/oauth.ts
527
- import { parseJSON as parseJSON2 } from "@ai-sdk/provider-utils";
527
+ import {
528
+ parseJSON as parseJSON2,
529
+ validateDownloadUrl
530
+ } from "@ai-sdk/provider-utils";
528
531
  var UnauthorizedError = class extends Error {
529
532
  constructor(message = "Unauthorized") {
530
533
  super(message);
@@ -534,6 +537,23 @@ var UnauthorizedError = class extends Error {
534
537
  function normalizeUrl(url) {
535
538
  return new URL(url).href;
536
539
  }
540
+ function isOAuthLoopbackHost(hostname) {
541
+ const normalized = hostname.toLowerCase().replace(/\.+$/, "");
542
+ return normalized === "localhost" || normalized.endsWith(".localhost") || normalized === "127.0.0.1" || normalized === "[::1]" || normalized === "::1";
543
+ }
544
+ function assertSafeOAuthEndpoint(endpointUrl) {
545
+ if ((endpointUrl.protocol === "http:" || endpointUrl.protocol === "https:") && isOAuthLoopbackHost(endpointUrl.hostname)) {
546
+ return;
547
+ }
548
+ try {
549
+ validateDownloadUrl(endpointUrl.href);
550
+ } catch (error) {
551
+ throw new MCPClientOAuthError({
552
+ message: `OAuth endpoint URL is not allowed: ${endpointUrl.href}`,
553
+ cause: error
554
+ });
555
+ }
556
+ }
537
557
  function createAuthorizationServerInformation(authorizationServerUrl, metadata) {
538
558
  return {
539
559
  authorizationServerUrl: normalizeUrl(authorizationServerUrl),
@@ -966,6 +986,7 @@ async function exchangeAuthorization(authorizationServerUrl, {
966
986
  var _a3;
967
987
  const grantType = "authorization_code";
968
988
  const tokenUrl = (metadata == null ? void 0 : metadata.token_endpoint) ? new URL(metadata.token_endpoint) : new URL("/token", authorizationServerUrl);
989
+ assertSafeOAuthEndpoint(tokenUrl);
969
990
  if ((metadata == null ? void 0 : metadata.grant_types_supported) && !metadata.grant_types_supported.includes(grantType)) {
970
991
  throw new Error(
971
992
  `Incompatible auth server: does not support grant type ${grantType}`
@@ -1002,7 +1023,8 @@ async function exchangeAuthorization(authorizationServerUrl, {
1002
1023
  const response = await (fetchFn != null ? fetchFn : fetch)(tokenUrl, {
1003
1024
  method: "POST",
1004
1025
  headers,
1005
- body: params
1026
+ body: params,
1027
+ redirect: "error"
1006
1028
  });
1007
1029
  if (!response.ok) {
1008
1030
  throw await parseErrorResponse(response);
@@ -1030,6 +1052,7 @@ async function refreshAuthorization(authorizationServerUrl, {
1030
1052
  } else {
1031
1053
  tokenUrl = new URL("/token", authorizationServerUrl);
1032
1054
  }
1055
+ assertSafeOAuthEndpoint(tokenUrl);
1033
1056
  const headers = new Headers({
1034
1057
  "Content-Type": "application/x-www-form-urlencoded",
1035
1058
  Accept: "application/json"
@@ -1059,7 +1082,8 @@ async function refreshAuthorization(authorizationServerUrl, {
1059
1082
  const response = await (fetchFn != null ? fetchFn : fetch)(tokenUrl, {
1060
1083
  method: "POST",
1061
1084
  headers,
1062
- body: params
1085
+ body: params,
1086
+ redirect: "error"
1063
1087
  });
1064
1088
  if (!response.ok) {
1065
1089
  throw await parseErrorResponse(response);
@@ -1085,12 +1109,14 @@ async function registerClient(authorizationServerUrl, {
1085
1109
  } else {
1086
1110
  registrationUrl = new URL("/register", authorizationServerUrl);
1087
1111
  }
1112
+ assertSafeOAuthEndpoint(registrationUrl);
1088
1113
  const response = await (fetchFn != null ? fetchFn : fetch)(registrationUrl, {
1089
1114
  method: "POST",
1090
1115
  headers: {
1091
1116
  "Content-Type": "application/json"
1092
1117
  },
1093
- body: JSON.stringify(clientMetadata)
1118
+ body: JSON.stringify(clientMetadata),
1119
+ redirect: "error"
1094
1120
  });
1095
1121
  if (!response.ok) {
1096
1122
  throw await parseErrorResponse(response);
@@ -1176,6 +1202,12 @@ async function authInternal(provider, {
1176
1202
  }
1177
1203
  );
1178
1204
  const currentAuthorizationServerInformation = createAuthorizationServerInformation(authorizationServerUrl, metadata);
1205
+ const clientMetadata = provider.clientMetadata;
1206
+ const selectedScope = selectScope({
1207
+ scope,
1208
+ resourceMetadata,
1209
+ clientMetadata
1210
+ });
1179
1211
  let clientInformation = await Promise.resolve(provider.clientInformation());
1180
1212
  if (!clientInformation) {
1181
1213
  if (authorizationCode !== void 0) {
@@ -1190,7 +1222,10 @@ async function authInternal(provider, {
1190
1222
  }
1191
1223
  const fullInformation = await registerClient(authorizationServerUrl, {
1192
1224
  metadata,
1193
- clientMetadata: provider.clientMetadata,
1225
+ clientMetadata: {
1226
+ ...clientMetadata,
1227
+ scope: selectedScope
1228
+ },
1194
1229
  fetchFn
1195
1230
  });
1196
1231
  clientInformation = addAuthorizationServerInformationToClientInformation(
@@ -1294,11 +1329,7 @@ async function authInternal(provider, {
1294
1329
  clientInformation,
1295
1330
  state,
1296
1331
  redirectUrl: provider.redirectUrl,
1297
- scope: selectScope({
1298
- scope,
1299
- resourceMetadata,
1300
- clientMetadata: provider.clientMetadata
1301
- }),
1332
+ scope: selectedScope,
1302
1333
  resource
1303
1334
  }
1304
1335
  );
@@ -2505,8 +2536,15 @@ var DefaultMCPClient = class {
2505
2536
  async tools({
2506
2537
  schemas = "automatic"
2507
2538
  } = {}) {
2508
- const definitions = await this.listTools();
2509
- return this.toolsFromDefinitions(definitions, {
2539
+ let definitions = await this.listTools();
2540
+ const tools = [...definitions.tools];
2541
+ while (definitions.nextCursor != null) {
2542
+ definitions = await this.listTools({
2543
+ params: { cursor: definitions.nextCursor }
2544
+ });
2545
+ tools.push(...definitions.tools);
2546
+ }
2547
+ return this.toolsFromDefinitions({ ...definitions, tools }, {
2510
2548
  schemas
2511
2549
  });
2512
2550
  }