@ai-sdk/mcp 1.0.70 → 1.0.72
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 +14 -0
- package/dist/index.js +68 -41
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +68 -41
- package/dist/index.mjs.map +1 -1
- package/dist/mcp-stdio/index.js.map +1 -1
- package/dist/mcp-stdio/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/error/mcp-client-error.ts +1 -1
- package/src/tool/mcp-http-transport.ts +20 -6
- package/src/tool/mcp-sse-transport.ts +21 -20
- package/src/tool/oauth.ts +52 -20
package/dist/index.mjs
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
|
-
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;
|
|
641
|
+
if (type.replace(/,$/, "").toLowerCase() !== "bearer" || !scheme) {
|
|
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") {
|
|
@@ -1476,7 +1497,7 @@ var SseMCPTransport = class {
|
|
|
1476
1497
|
const transportSignal = (_b3 = this.abortController) == null ? void 0 : _b3.signal;
|
|
1477
1498
|
const requestSignal = (options == null ? void 0 : options.signal) == null ? transportSignal : transportSignal == null ? options.signal : AbortSignal.any([transportSignal, options.signal]);
|
|
1478
1499
|
const attempt = async (triedAuth = false) => {
|
|
1479
|
-
var _a4, _b4
|
|
1500
|
+
var _a4, _b4;
|
|
1480
1501
|
try {
|
|
1481
1502
|
const headers = await this.commonHeaders({
|
|
1482
1503
|
"Content-Type": "application/json"
|
|
@@ -1490,38 +1511,35 @@ 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
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
return;
|
|
1504
|
-
}
|
|
1505
|
-
} catch (error) {
|
|
1506
|
-
(_b4 = this.onerror) == null ? void 0 : _b4.call(this, error);
|
|
1507
|
-
return;
|
|
1514
|
+
const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
|
|
1515
|
+
this.resourceMetadataUrl = resourceMetadataUrl;
|
|
1516
|
+
const result = await auth(this.authProvider, {
|
|
1517
|
+
serverUrl: this.url,
|
|
1518
|
+
resourceMetadataUrl: this.resourceMetadataUrl,
|
|
1519
|
+
scope,
|
|
1520
|
+
fetchFn: this.fetchFn
|
|
1521
|
+
});
|
|
1522
|
+
if (result !== "AUTHORIZED") {
|
|
1523
|
+
throw new UnauthorizedError();
|
|
1508
1524
|
}
|
|
1509
1525
|
return attempt(true);
|
|
1510
1526
|
}
|
|
1511
1527
|
if (!response.ok) {
|
|
1512
1528
|
const text = await response.text().catch(() => null);
|
|
1513
1529
|
const error = new MCPClientError({
|
|
1514
|
-
message: `MCP SSE Transport Error: POSTing to endpoint (HTTP ${response.status}): ${text}
|
|
1530
|
+
message: `MCP SSE Transport Error: POSTing to endpoint (HTTP ${response.status}): ${text}`,
|
|
1531
|
+
statusCode: response.status,
|
|
1532
|
+
url: endpoint.href,
|
|
1533
|
+
responseBody: text != null ? text : void 0
|
|
1515
1534
|
});
|
|
1516
|
-
|
|
1517
|
-
return;
|
|
1535
|
+
throw error;
|
|
1518
1536
|
}
|
|
1519
1537
|
} catch (error) {
|
|
1520
|
-
if ((
|
|
1538
|
+
if ((_a4 = options == null ? void 0 : options.signal) == null ? void 0 : _a4.aborted) {
|
|
1521
1539
|
throw error;
|
|
1522
1540
|
}
|
|
1523
|
-
(
|
|
1524
|
-
|
|
1541
|
+
(_b4 = this.onerror) == null ? void 0 : _b4.call(this, error);
|
|
1542
|
+
throw error;
|
|
1525
1543
|
}
|
|
1526
1544
|
};
|
|
1527
1545
|
await attempt();
|
|
@@ -1586,7 +1604,7 @@ var HttpMCPTransport = class {
|
|
|
1586
1604
|
/**
|
|
1587
1605
|
* Runs a single OAuth recovery flow for concurrent 401 responses.
|
|
1588
1606
|
*/
|
|
1589
|
-
authorizeOnce(resourceMetadataUrl) {
|
|
1607
|
+
authorizeOnce(resourceMetadataUrl, scope) {
|
|
1590
1608
|
if (!this.authProvider) {
|
|
1591
1609
|
return Promise.resolve("REDIRECT");
|
|
1592
1610
|
}
|
|
@@ -1594,6 +1612,7 @@ var HttpMCPTransport = class {
|
|
|
1594
1612
|
this.authPromise = auth(this.authProvider, {
|
|
1595
1613
|
serverUrl: this.url,
|
|
1596
1614
|
resourceMetadataUrl,
|
|
1615
|
+
scope,
|
|
1597
1616
|
fetchFn: this.fetchFn
|
|
1598
1617
|
}).finally(() => {
|
|
1599
1618
|
this.authPromise = void 0;
|
|
@@ -1655,9 +1674,13 @@ var HttpMCPTransport = class {
|
|
|
1655
1674
|
this.sessionId = sessionId;
|
|
1656
1675
|
}
|
|
1657
1676
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1658
|
-
|
|
1677
|
+
const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
|
|
1678
|
+
this.resourceMetadataUrl = resourceMetadataUrl;
|
|
1659
1679
|
try {
|
|
1660
|
-
const result = await this.authorizeOnce(
|
|
1680
|
+
const result = await this.authorizeOnce(
|
|
1681
|
+
this.resourceMetadataUrl,
|
|
1682
|
+
scope
|
|
1683
|
+
);
|
|
1661
1684
|
if (result !== "AUTHORIZED") {
|
|
1662
1685
|
const error2 = new UnauthorizedError();
|
|
1663
1686
|
throw error2;
|
|
@@ -1828,9 +1851,13 @@ var HttpMCPTransport = class {
|
|
|
1828
1851
|
this.sessionId = sessionId;
|
|
1829
1852
|
}
|
|
1830
1853
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
1831
|
-
|
|
1854
|
+
const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
|
|
1855
|
+
this.resourceMetadataUrl = resourceMetadataUrl;
|
|
1832
1856
|
try {
|
|
1833
|
-
const result = await this.authorizeOnce(
|
|
1857
|
+
const result = await this.authorizeOnce(
|
|
1858
|
+
this.resourceMetadataUrl,
|
|
1859
|
+
scope
|
|
1860
|
+
);
|
|
1834
1861
|
if (result !== "AUTHORIZED") {
|
|
1835
1862
|
const error = new UnauthorizedError();
|
|
1836
1863
|
(_b3 = this.onerror) == null ? void 0 : _b3.call(this, error);
|