@ai-sdk/mcp 2.0.30 → 2.0.32
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 +13 -0
- package/dist/index.js +51 -19
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/tool/mcp-http-transport.ts +20 -6
- package/src/tool/mcp-sse-transport.ts +9 -3
- package/src/tool/oauth.ts +51 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @ai-sdk/mcp
|
|
2
2
|
|
|
3
|
+
## 2.0.32
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 1011e33: Select MCP OAuth authorization scopes from `WWW-Authenticate` challenges or Protected Resource Metadata.
|
|
8
|
+
|
|
9
|
+
## 2.0.31
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [7fbfc6d]
|
|
14
|
+
- @ai-sdk/provider-utils@5.0.27
|
|
15
|
+
|
|
3
16
|
## 2.0.30
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -631,26 +631,41 @@ function assertAuthorizationServerInformationMatches({
|
|
|
631
631
|
});
|
|
632
632
|
}
|
|
633
633
|
}
|
|
634
|
-
function
|
|
635
|
-
var _a3;
|
|
634
|
+
function extractWWWAuthenticateParams(response) {
|
|
635
|
+
var _a3, _b3;
|
|
636
636
|
const header = (_a3 = response.headers.get("www-authenticate")) != null ? _a3 : response.headers.get("WWW-Authenticate");
|
|
637
637
|
if (!header) {
|
|
638
|
-
return
|
|
638
|
+
return {};
|
|
639
639
|
}
|
|
640
640
|
const [type, scheme] = header.split(" ");
|
|
641
641
|
if (type.toLowerCase() !== "bearer" || !scheme) {
|
|
642
|
-
return
|
|
643
|
-
}
|
|
644
|
-
const regex = /resource_metadata="([^"]*)"/;
|
|
645
|
-
const match = header.match(regex);
|
|
646
|
-
if (!match) {
|
|
647
|
-
return void 0;
|
|
642
|
+
return {};
|
|
648
643
|
}
|
|
644
|
+
const resourceMetadataMatch = header.match(
|
|
645
|
+
/(?:^|[,\s])resource_metadata="([^"]*)"/i
|
|
646
|
+
);
|
|
647
|
+
const scope = (_b3 = header.match(/(?:^|[,\s])scope="([^"]*)"/i)) == null ? void 0 : _b3[1];
|
|
648
|
+
let resourceMetadataUrl;
|
|
649
649
|
try {
|
|
650
|
-
|
|
650
|
+
resourceMetadataUrl = resourceMetadataMatch ? new URL(resourceMetadataMatch[1]) : void 0;
|
|
651
651
|
} catch (e) {
|
|
652
|
-
return void 0;
|
|
653
652
|
}
|
|
653
|
+
return { resourceMetadataUrl, scope };
|
|
654
|
+
}
|
|
655
|
+
function selectScope({
|
|
656
|
+
scope,
|
|
657
|
+
resourceMetadata,
|
|
658
|
+
clientMetadata
|
|
659
|
+
}) {
|
|
660
|
+
var _a3;
|
|
661
|
+
if (scope) {
|
|
662
|
+
return scope;
|
|
663
|
+
}
|
|
664
|
+
const resourceScopes = (_a3 = resourceMetadata == null ? void 0 : resourceMetadata.scopes_supported) == null ? void 0 : _a3.join(" ");
|
|
665
|
+
if (resourceScopes) {
|
|
666
|
+
return resourceScopes;
|
|
667
|
+
}
|
|
668
|
+
return clientMetadata.scope;
|
|
654
669
|
}
|
|
655
670
|
function buildWellKnownPath(wellKnownPrefix, pathname = "", options = {}) {
|
|
656
671
|
if (pathname.endsWith("/")) {
|
|
@@ -1279,7 +1294,11 @@ async function authInternal(provider, {
|
|
|
1279
1294
|
clientInformation,
|
|
1280
1295
|
state,
|
|
1281
1296
|
redirectUrl: provider.redirectUrl,
|
|
1282
|
-
scope:
|
|
1297
|
+
scope: selectScope({
|
|
1298
|
+
scope,
|
|
1299
|
+
resourceMetadata,
|
|
1300
|
+
clientMetadata: provider.clientMetadata
|
|
1301
|
+
}),
|
|
1283
1302
|
resource
|
|
1284
1303
|
}
|
|
1285
1304
|
);
|
|
@@ -1357,11 +1376,13 @@ var SseMCPTransport = class {
|
|
|
1357
1376
|
redirect: this.redirectMode
|
|
1358
1377
|
});
|
|
1359
1378
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1360
|
-
|
|
1379
|
+
const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
|
|
1380
|
+
this.resourceMetadataUrl = resourceMetadataUrl;
|
|
1361
1381
|
try {
|
|
1362
1382
|
const result = await auth(this.authProvider, {
|
|
1363
1383
|
serverUrl: this.url,
|
|
1364
1384
|
resourceMetadataUrl: this.resourceMetadataUrl,
|
|
1385
|
+
scope,
|
|
1365
1386
|
fetchFn: this.fetchFn
|
|
1366
1387
|
});
|
|
1367
1388
|
if (result !== "AUTHORIZED") {
|
|
@@ -1490,11 +1511,13 @@ var SseMCPTransport = class {
|
|
|
1490
1511
|
};
|
|
1491
1512
|
const response = await this.fetchFn(endpoint.href, init);
|
|
1492
1513
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1493
|
-
|
|
1514
|
+
const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
|
|
1515
|
+
this.resourceMetadataUrl = resourceMetadataUrl;
|
|
1494
1516
|
try {
|
|
1495
1517
|
const result = await auth(this.authProvider, {
|
|
1496
1518
|
serverUrl: this.url,
|
|
1497
1519
|
resourceMetadataUrl: this.resourceMetadataUrl,
|
|
1520
|
+
scope,
|
|
1498
1521
|
fetchFn: this.fetchFn
|
|
1499
1522
|
});
|
|
1500
1523
|
if (result !== "AUTHORIZED") {
|
|
@@ -1620,7 +1643,7 @@ var HttpMCPTransport = class {
|
|
|
1620
1643
|
/**
|
|
1621
1644
|
* Runs a single OAuth recovery flow for concurrent 401 responses.
|
|
1622
1645
|
*/
|
|
1623
|
-
authorizeOnce(resourceMetadataUrl) {
|
|
1646
|
+
authorizeOnce(resourceMetadataUrl, scope) {
|
|
1624
1647
|
if (!this.authProvider) {
|
|
1625
1648
|
return Promise.resolve("REDIRECT");
|
|
1626
1649
|
}
|
|
@@ -1628,6 +1651,7 @@ var HttpMCPTransport = class {
|
|
|
1628
1651
|
this.authPromise = auth(this.authProvider, {
|
|
1629
1652
|
serverUrl: this.url,
|
|
1630
1653
|
resourceMetadataUrl,
|
|
1654
|
+
scope,
|
|
1631
1655
|
fetchFn: this.fetchFn
|
|
1632
1656
|
}).finally(() => {
|
|
1633
1657
|
this.authPromise = void 0;
|
|
@@ -1691,9 +1715,13 @@ var HttpMCPTransport = class {
|
|
|
1691
1715
|
const response = await this.fetchFn(this.url.href, init);
|
|
1692
1716
|
this.applySessionIdFromResponse(response);
|
|
1693
1717
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1694
|
-
|
|
1718
|
+
const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
|
|
1719
|
+
this.resourceMetadataUrl = resourceMetadataUrl;
|
|
1695
1720
|
try {
|
|
1696
|
-
const result = await this.authorizeOnce(
|
|
1721
|
+
const result = await this.authorizeOnce(
|
|
1722
|
+
this.resourceMetadataUrl,
|
|
1723
|
+
scope
|
|
1724
|
+
);
|
|
1697
1725
|
if (result !== "AUTHORIZED") {
|
|
1698
1726
|
const error2 = new UnauthorizedError();
|
|
1699
1727
|
throw error2;
|
|
@@ -1869,9 +1897,13 @@ var HttpMCPTransport = class {
|
|
|
1869
1897
|
});
|
|
1870
1898
|
this.applySessionIdFromResponse(response);
|
|
1871
1899
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1872
|
-
|
|
1900
|
+
const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
|
|
1901
|
+
this.resourceMetadataUrl = resourceMetadataUrl;
|
|
1873
1902
|
try {
|
|
1874
|
-
const result = await this.authorizeOnce(
|
|
1903
|
+
const result = await this.authorizeOnce(
|
|
1904
|
+
this.resourceMetadataUrl,
|
|
1905
|
+
scope
|
|
1906
|
+
);
|
|
1875
1907
|
if (result !== "AUTHORIZED") {
|
|
1876
1908
|
const error = new UnauthorizedError();
|
|
1877
1909
|
(_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);
|