@ai-sdk/mcp 1.0.70 → 1.0.71

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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # @ai-sdk/mcp
2
2
 
3
+ ## 1.0.71
4
+
5
+ ### Patch Changes
6
+
7
+ - b0e77c0: Select MCP OAuth authorization scopes from `WWW-Authenticate` challenges or Protected Resource Metadata.
8
+ - Updated dependencies [31205a4]
9
+ - @ai-sdk/provider-utils@4.0.46
10
+
3
11
  ## 1.0.70
4
12
 
5
13
  ### Patch Changes
package/dist/index.js CHANGED
@@ -661,26 +661,41 @@ function assertAuthorizationServerInformationMatches({
661
661
  });
662
662
  }
663
663
  }
664
- function extractResourceMetadataUrl(response) {
665
- var _a3;
664
+ function extractWWWAuthenticateParams(response) {
665
+ var _a3, _b3;
666
666
  const header = (_a3 = response.headers.get("www-authenticate")) != null ? _a3 : response.headers.get("WWW-Authenticate");
667
667
  if (!header) {
668
- return void 0;
668
+ return {};
669
669
  }
670
670
  const [type, scheme] = header.split(" ");
671
- if (type.toLowerCase() !== "bearer" || !scheme) {
672
- return void 0;
673
- }
674
- const regex = /resource_metadata="([^"]*)"/;
675
- const match = header.match(regex);
676
- if (!match) {
677
- return void 0;
671
+ if (type.replace(/,$/, "").toLowerCase() !== "bearer" || !scheme) {
672
+ return {};
678
673
  }
674
+ const resourceMetadataMatch = header.match(
675
+ /(?:^|[,\s])resource_metadata="([^"]*)"/i
676
+ );
677
+ const scope = (_b3 = header.match(/(?:^|[,\s])scope="([^"]*)"/i)) == null ? void 0 : _b3[1];
678
+ let resourceMetadataUrl;
679
679
  try {
680
- return new URL(match[1]);
680
+ resourceMetadataUrl = resourceMetadataMatch ? new URL(resourceMetadataMatch[1]) : void 0;
681
681
  } catch (e) {
682
- return void 0;
683
682
  }
683
+ return { resourceMetadataUrl, scope };
684
+ }
685
+ function selectScope({
686
+ scope,
687
+ resourceMetadata,
688
+ clientMetadata
689
+ }) {
690
+ var _a3;
691
+ if (scope) {
692
+ return scope;
693
+ }
694
+ const resourceScopes = (_a3 = resourceMetadata == null ? void 0 : resourceMetadata.scopes_supported) == null ? void 0 : _a3.join(" ");
695
+ if (resourceScopes) {
696
+ return resourceScopes;
697
+ }
698
+ return clientMetadata.scope;
684
699
  }
685
700
  function buildWellKnownPath(wellKnownPrefix, pathname = "", options = {}) {
686
701
  if (pathname.endsWith("/")) {
@@ -1309,7 +1324,11 @@ async function authInternal(provider, {
1309
1324
  clientInformation,
1310
1325
  state,
1311
1326
  redirectUrl: provider.redirectUrl,
1312
- scope: scope || provider.clientMetadata.scope,
1327
+ scope: selectScope({
1328
+ scope,
1329
+ resourceMetadata,
1330
+ clientMetadata: provider.clientMetadata
1331
+ }),
1313
1332
  resource
1314
1333
  }
1315
1334
  );
@@ -1387,11 +1406,13 @@ var SseMCPTransport = class {
1387
1406
  redirect: this.redirectMode
1388
1407
  });
1389
1408
  if (response.status === 401 && this.authProvider && !triedAuth) {
1390
- this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1409
+ const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
1410
+ this.resourceMetadataUrl = resourceMetadataUrl;
1391
1411
  try {
1392
1412
  const result = await auth(this.authProvider, {
1393
1413
  serverUrl: this.url,
1394
1414
  resourceMetadataUrl: this.resourceMetadataUrl,
1415
+ scope,
1395
1416
  fetchFn: this.fetchFn
1396
1417
  });
1397
1418
  if (result !== "AUTHORIZED") {
@@ -1520,11 +1541,13 @@ var SseMCPTransport = class {
1520
1541
  };
1521
1542
  const response = await this.fetchFn(endpoint.href, init);
1522
1543
  if (response.status === 401 && this.authProvider && !triedAuth) {
1523
- this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1544
+ const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
1545
+ this.resourceMetadataUrl = resourceMetadataUrl;
1524
1546
  try {
1525
1547
  const result = await auth(this.authProvider, {
1526
1548
  serverUrl: this.url,
1527
1549
  resourceMetadataUrl: this.resourceMetadataUrl,
1550
+ scope,
1528
1551
  fetchFn: this.fetchFn
1529
1552
  });
1530
1553
  if (result !== "AUTHORIZED") {
@@ -1612,7 +1635,7 @@ var HttpMCPTransport = class {
1612
1635
  /**
1613
1636
  * Runs a single OAuth recovery flow for concurrent 401 responses.
1614
1637
  */
1615
- authorizeOnce(resourceMetadataUrl) {
1638
+ authorizeOnce(resourceMetadataUrl, scope) {
1616
1639
  if (!this.authProvider) {
1617
1640
  return Promise.resolve("REDIRECT");
1618
1641
  }
@@ -1620,6 +1643,7 @@ var HttpMCPTransport = class {
1620
1643
  this.authPromise = auth(this.authProvider, {
1621
1644
  serverUrl: this.url,
1622
1645
  resourceMetadataUrl,
1646
+ scope,
1623
1647
  fetchFn: this.fetchFn
1624
1648
  }).finally(() => {
1625
1649
  this.authPromise = void 0;
@@ -1681,9 +1705,13 @@ var HttpMCPTransport = class {
1681
1705
  this.sessionId = sessionId;
1682
1706
  }
1683
1707
  if (response.status === 401 && this.authProvider && !triedAuth) {
1684
- this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1708
+ const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
1709
+ this.resourceMetadataUrl = resourceMetadataUrl;
1685
1710
  try {
1686
- const result = await this.authorizeOnce(this.resourceMetadataUrl);
1711
+ const result = await this.authorizeOnce(
1712
+ this.resourceMetadataUrl,
1713
+ scope
1714
+ );
1687
1715
  if (result !== "AUTHORIZED") {
1688
1716
  const error2 = new UnauthorizedError();
1689
1717
  throw error2;
@@ -1854,9 +1882,13 @@ var HttpMCPTransport = class {
1854
1882
  this.sessionId = sessionId;
1855
1883
  }
1856
1884
  if (response.status === 401 && this.authProvider && !triedAuth) {
1857
- this.resourceMetadataUrl = extractResourceMetadataUrl(response);
1885
+ const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
1886
+ this.resourceMetadataUrl = resourceMetadataUrl;
1858
1887
  try {
1859
- const result = await this.authorizeOnce(this.resourceMetadataUrl);
1888
+ const result = await this.authorizeOnce(
1889
+ this.resourceMetadataUrl,
1890
+ scope
1891
+ );
1860
1892
  if (result !== "AUTHORIZED") {
1861
1893
  const error = new UnauthorizedError();
1862
1894
  (_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);