@mcp-use/cli 2.21.5-canary.2 → 3.0.0-canary.3
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/commands/auth.d.ts +7 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/index.cjs +158 -332
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +158 -334
- package/dist/index.js.map +1 -1
- package/dist/utils/api.d.ts +5 -9
- package/dist/utils/api.d.ts.map +1 -1
- package/dist/utils/config.d.ts +7 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/commands/auth.d.ts
CHANGED
|
@@ -5,10 +5,16 @@ import type { ProfileInfo } from "../utils/api.js";
|
|
|
5
5
|
*/
|
|
6
6
|
export declare function promptOrgSelection(profiles: ProfileInfo[], defaultProfileId?: string | null): Promise<ProfileInfo | null>;
|
|
7
7
|
/**
|
|
8
|
-
* Login command
|
|
8
|
+
* Login command using OAuth 2.0 Device Authorization Grant (RFC 8628).
|
|
9
|
+
*
|
|
10
|
+
* Supports three modes:
|
|
11
|
+
* - Interactive device flow (default): opens browser, user enters a code
|
|
12
|
+
* - --api-key <key>: non-interactive, stores the given key directly
|
|
13
|
+
* - MCP_USE_API_KEY env var: same as --api-key (for CI/CD)
|
|
9
14
|
*/
|
|
10
15
|
export declare function loginCommand(options?: {
|
|
11
16
|
silent?: boolean;
|
|
17
|
+
apiKey?: string;
|
|
12
18
|
}): Promise<void>;
|
|
13
19
|
/**
|
|
14
20
|
* Logout command - revokes API key and deletes config
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAoGnD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,WAAW,EAAE,EACvB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,GAC/B,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CA6C7B;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,OAAO,CAAC,EAAE;IAC3C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyJhB;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CA8BnD;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAwEnD"}
|
package/dist/index.cjs
CHANGED
|
@@ -1150,10 +1150,6 @@ var open_default = open;
|
|
|
1150
1150
|
var import_vite_plugin_singlefile = require("vite-plugin-singlefile");
|
|
1151
1151
|
var import_zod = require("zod");
|
|
1152
1152
|
|
|
1153
|
-
// src/commands/auth.ts
|
|
1154
|
-
var import_node_crypto = __toESM(require("crypto"), 1);
|
|
1155
|
-
var import_node_http = require("http");
|
|
1156
|
-
|
|
1157
1153
|
// src/utils/config.ts
|
|
1158
1154
|
var import_node_fs4 = require("fs");
|
|
1159
1155
|
var import_node_os3 = __toESM(require("os"), 1);
|
|
@@ -1205,6 +1201,10 @@ async function getProfileId() {
|
|
|
1205
1201
|
async function getWebUrl() {
|
|
1206
1202
|
return DEFAULT_WEB_URL;
|
|
1207
1203
|
}
|
|
1204
|
+
async function getAuthBaseUrl() {
|
|
1205
|
+
const apiUrl = await getApiUrl();
|
|
1206
|
+
return apiUrl.replace(/\/api\/v1$/, "");
|
|
1207
|
+
}
|
|
1208
1208
|
|
|
1209
1209
|
// src/utils/api.ts
|
|
1210
1210
|
var McpUseAPI = class _McpUseAPI {
|
|
@@ -1256,6 +1256,13 @@ var McpUseAPI = class _McpUseAPI {
|
|
|
1256
1256
|
signal: controller.signal
|
|
1257
1257
|
});
|
|
1258
1258
|
clearTimeout(timeoutId);
|
|
1259
|
+
if (response.status === 401) {
|
|
1260
|
+
const err = new Error(
|
|
1261
|
+
"Your session has expired or your API key is invalid."
|
|
1262
|
+
);
|
|
1263
|
+
err.status = 401;
|
|
1264
|
+
throw err;
|
|
1265
|
+
}
|
|
1259
1266
|
if (!response.ok) {
|
|
1260
1267
|
const error = await response.text();
|
|
1261
1268
|
throw new Error(`API request failed: ${response.status} ${error}`);
|
|
@@ -1272,17 +1279,19 @@ var McpUseAPI = class _McpUseAPI {
|
|
|
1272
1279
|
}
|
|
1273
1280
|
}
|
|
1274
1281
|
/**
|
|
1275
|
-
* Create API key using
|
|
1282
|
+
* Create a persistent API key using a Better Auth access token.
|
|
1283
|
+
* Calls Better Auth's built-in POST /api/auth/api-key/create endpoint.
|
|
1276
1284
|
*/
|
|
1277
|
-
async
|
|
1278
|
-
const
|
|
1285
|
+
async createApiKeyWithAccessToken(accessToken, name = "CLI") {
|
|
1286
|
+
const authBase = await getAuthBaseUrl();
|
|
1287
|
+
const url = `${authBase}/api/auth/api-key/create`;
|
|
1279
1288
|
const response = await fetch(url, {
|
|
1280
1289
|
method: "POST",
|
|
1281
1290
|
headers: {
|
|
1282
1291
|
"Content-Type": "application/json",
|
|
1283
|
-
Authorization: `Bearer ${
|
|
1292
|
+
Authorization: `Bearer ${accessToken}`
|
|
1284
1293
|
},
|
|
1285
|
-
body: JSON.stringify({ name })
|
|
1294
|
+
body: JSON.stringify({ name, prefix: "mcp_" })
|
|
1286
1295
|
});
|
|
1287
1296
|
if (!response.ok) {
|
|
1288
1297
|
const error = await response.text();
|
|
@@ -1543,273 +1552,65 @@ var McpUseAPI = class _McpUseAPI {
|
|
|
1543
1552
|
};
|
|
1544
1553
|
|
|
1545
1554
|
// src/commands/auth.ts
|
|
1546
|
-
var
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1555
|
+
var DEVICE_CLIENT_ID = "mcp-use-cli";
|
|
1556
|
+
var DEVICE_POLL_TIMEOUT = 18e5;
|
|
1557
|
+
async function requestDeviceCode(authBaseUrl) {
|
|
1558
|
+
const url = `${authBaseUrl}/api/auth/device/code`;
|
|
1559
|
+
const response = await fetch(url, {
|
|
1560
|
+
method: "POST",
|
|
1561
|
+
headers: { "Content-Type": "application/json" },
|
|
1562
|
+
body: JSON.stringify({
|
|
1563
|
+
client_id: DEVICE_CLIENT_ID,
|
|
1564
|
+
scope: "openid profile email"
|
|
1565
|
+
})
|
|
1566
|
+
});
|
|
1567
|
+
if (!response.ok) {
|
|
1568
|
+
const error = await response.text();
|
|
1569
|
+
throw new Error(
|
|
1570
|
+
`Failed to request device code: ${response.status} ${error}`
|
|
1571
|
+
);
|
|
1563
1572
|
}
|
|
1564
|
-
|
|
1573
|
+
return response.json();
|
|
1565
1574
|
}
|
|
1566
|
-
async function
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1575
|
+
async function pollForDeviceToken(authBaseUrl, deviceCode, intervalSeconds) {
|
|
1576
|
+
let pollingInterval = intervalSeconds;
|
|
1577
|
+
const deadline = Date.now() + DEVICE_POLL_TIMEOUT;
|
|
1578
|
+
while (Date.now() < deadline) {
|
|
1579
|
+
const delayMs = pollingInterval * 1e3;
|
|
1580
|
+
await new Promise((r) => setTimeout(r, delayMs));
|
|
1581
|
+
const url = `${authBaseUrl}/api/auth/device/token`;
|
|
1582
|
+
const response = await fetch(url, {
|
|
1583
|
+
method: "POST",
|
|
1584
|
+
headers: { "Content-Type": "application/json" },
|
|
1585
|
+
body: JSON.stringify({
|
|
1586
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
1587
|
+
device_code: deviceCode,
|
|
1588
|
+
client_id: DEVICE_CLIENT_ID
|
|
1589
|
+
})
|
|
1571
1590
|
});
|
|
1572
|
-
const
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
(
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
body {
|
|
1592
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
1593
|
-
display: flex;
|
|
1594
|
-
justify-content: center;
|
|
1595
|
-
align-items: center;
|
|
1596
|
-
min-height: 100vh;
|
|
1597
|
-
background: #000;
|
|
1598
|
-
padding: 1rem;
|
|
1599
|
-
margin: 0;
|
|
1600
|
-
}
|
|
1601
|
-
.container {
|
|
1602
|
-
max-width: 28rem;
|
|
1603
|
-
padding: 3rem;
|
|
1604
|
-
text-align: center;
|
|
1605
|
-
background: rgba(255, 255, 255, 0.1);
|
|
1606
|
-
backdrop-filter: blur(40px);
|
|
1607
|
-
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
1608
|
-
border-radius: 1.5rem;
|
|
1609
|
-
}
|
|
1610
|
-
h1 { color: #fff; font-size: 2rem; margin-bottom: 1rem; }
|
|
1611
|
-
p { color: rgba(255, 255, 255, 0.8); font-size: 1rem; }
|
|
1612
|
-
</style>
|
|
1613
|
-
</head>
|
|
1614
|
-
<body>
|
|
1615
|
-
<div class="container">
|
|
1616
|
-
<h1>Security Error</h1>
|
|
1617
|
-
<p>Invalid state parameter. Please try logging in again.</p>
|
|
1618
|
-
</div>
|
|
1619
|
-
</body>
|
|
1620
|
-
</html>
|
|
1621
|
-
`);
|
|
1622
|
-
return;
|
|
1623
|
-
}
|
|
1624
|
-
if (token && tokenResolver) {
|
|
1625
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
1626
|
-
res.end(`
|
|
1627
|
-
<!DOCTYPE html>
|
|
1628
|
-
<html>
|
|
1629
|
-
<head>
|
|
1630
|
-
<title>Login Successful</title>
|
|
1631
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1632
|
-
<style>
|
|
1633
|
-
* {
|
|
1634
|
-
margin: 0;
|
|
1635
|
-
padding: 0;
|
|
1636
|
-
box-sizing: border-box;
|
|
1637
|
-
}
|
|
1638
|
-
body {
|
|
1639
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
1640
|
-
display: flex;
|
|
1641
|
-
justify-content: center;
|
|
1642
|
-
align-items: center;
|
|
1643
|
-
min-height: 100vh;
|
|
1644
|
-
background: #000;
|
|
1645
|
-
padding: 1rem;
|
|
1646
|
-
}
|
|
1647
|
-
.container {
|
|
1648
|
-
width: 100%;
|
|
1649
|
-
max-width: 28rem;
|
|
1650
|
-
padding: 3rem;
|
|
1651
|
-
text-align: center;
|
|
1652
|
-
-webkit-backdrop-filter: blur(40px);
|
|
1653
|
-
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
1654
|
-
border-radius: 1.5rem;
|
|
1655
|
-
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
|
|
1656
|
-
}
|
|
1657
|
-
.icon-container {
|
|
1658
|
-
display: inline-flex;
|
|
1659
|
-
align-items: center;
|
|
1660
|
-
justify-content: center;
|
|
1661
|
-
width: 6rem;
|
|
1662
|
-
height: 6rem;
|
|
1663
|
-
margin-bottom: 2rem;
|
|
1664
|
-
background: rgba(255, 255, 255, 0.1);
|
|
1665
|
-
backdrop-filter: blur(10px);
|
|
1666
|
-
-webkit-backdrop-filter: blur(10px);
|
|
1667
|
-
border-radius: 50%;
|
|
1668
|
-
}
|
|
1669
|
-
.checkmark {
|
|
1670
|
-
font-size: 4rem;
|
|
1671
|
-
color: #fff;
|
|
1672
|
-
line-height: 1;
|
|
1673
|
-
animation: scaleIn 0.5s ease-out;
|
|
1674
|
-
}
|
|
1675
|
-
@keyframes scaleIn {
|
|
1676
|
-
from {
|
|
1677
|
-
transform: scale(0);
|
|
1678
|
-
opacity: 0;
|
|
1679
|
-
}
|
|
1680
|
-
to {
|
|
1681
|
-
transform: scale(1);
|
|
1682
|
-
opacity: 1;
|
|
1683
|
-
}
|
|
1684
|
-
}
|
|
1685
|
-
h1 {
|
|
1686
|
-
color: #fff;
|
|
1687
|
-
margin: 0 0 1rem 0;
|
|
1688
|
-
font-size: 2.5rem;
|
|
1689
|
-
font-weight: 700;
|
|
1690
|
-
letter-spacing: -0.025em;
|
|
1691
|
-
}
|
|
1692
|
-
p {
|
|
1693
|
-
color: rgba(255, 255, 255, 0.8);
|
|
1694
|
-
margin: 0 0 2rem 0;
|
|
1695
|
-
font-size: 1.125rem;
|
|
1696
|
-
line-height: 1.5;
|
|
1697
|
-
}
|
|
1698
|
-
.spinner {
|
|
1699
|
-
display: inline-block;
|
|
1700
|
-
width: 2rem;
|
|
1701
|
-
height: 2rem;
|
|
1702
|
-
border: 3px solid rgba(255, 255, 255, 0.3);
|
|
1703
|
-
border-top-color: #fff;
|
|
1704
|
-
border-radius: 50%;
|
|
1705
|
-
animation: spin 0.8s linear infinite;
|
|
1706
|
-
}
|
|
1707
|
-
@keyframes spin {
|
|
1708
|
-
to { transform: rotate(360deg); }
|
|
1709
|
-
}
|
|
1710
|
-
.footer {
|
|
1711
|
-
margin-top: 2rem;
|
|
1712
|
-
color: rgba(255, 255, 255, 0.6);
|
|
1713
|
-
font-size: 0.875rem;
|
|
1714
|
-
}
|
|
1715
|
-
</style>
|
|
1716
|
-
</head>
|
|
1717
|
-
<body>
|
|
1718
|
-
<div class="container">
|
|
1719
|
-
<h1>Authentication Successful!</h1>
|
|
1720
|
-
<p>You can now close this window and return to the CLI.</p>
|
|
1721
|
-
</div>
|
|
1722
|
-
</body>
|
|
1723
|
-
</html>
|
|
1724
|
-
`);
|
|
1725
|
-
tokenResolver(token);
|
|
1726
|
-
} else {
|
|
1727
|
-
res.writeHead(400, { "Content-Type": "text/html" });
|
|
1728
|
-
res.end(`
|
|
1729
|
-
<!DOCTYPE html>
|
|
1730
|
-
<html>
|
|
1731
|
-
<head>
|
|
1732
|
-
<title>Login Failed</title>
|
|
1733
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1734
|
-
<style>
|
|
1735
|
-
* {
|
|
1736
|
-
margin: 0;
|
|
1737
|
-
padding: 0;
|
|
1738
|
-
box-sizing: border-box;
|
|
1739
|
-
}
|
|
1740
|
-
body {
|
|
1741
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
1742
|
-
display: flex;
|
|
1743
|
-
justify-content: center;
|
|
1744
|
-
align-items: center;
|
|
1745
|
-
min-height: 100vh;
|
|
1746
|
-
background: #000;
|
|
1747
|
-
padding: 1rem;
|
|
1748
|
-
}
|
|
1749
|
-
.container {
|
|
1750
|
-
width: 100%;
|
|
1751
|
-
max-width: 28rem;
|
|
1752
|
-
padding: 3rem;
|
|
1753
|
-
text-align: center;
|
|
1754
|
-
background: rgba(255, 255, 255, 0.1);
|
|
1755
|
-
backdrop-filter: blur(40px);
|
|
1756
|
-
-webkit-backdrop-filter: blur(40px);
|
|
1757
|
-
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
1758
|
-
border-radius: 1.5rem;
|
|
1759
|
-
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
|
|
1760
|
-
}
|
|
1761
|
-
.icon-container {
|
|
1762
|
-
display: inline-flex;
|
|
1763
|
-
align-items: center;
|
|
1764
|
-
justify-content: center;
|
|
1765
|
-
width: 6rem;
|
|
1766
|
-
height: 6rem;
|
|
1767
|
-
margin-bottom: 2rem;
|
|
1768
|
-
background: rgba(255, 255, 255, 0.1);
|
|
1769
|
-
backdrop-filter: blur(10px);
|
|
1770
|
-
-webkit-backdrop-filter: blur(10px);
|
|
1771
|
-
border-radius: 50%;
|
|
1772
|
-
}
|
|
1773
|
-
.cross {
|
|
1774
|
-
font-size: 4rem;
|
|
1775
|
-
color: #fff;
|
|
1776
|
-
line-height: 1;
|
|
1777
|
-
}
|
|
1778
|
-
h1 {
|
|
1779
|
-
color: #fff;
|
|
1780
|
-
margin: 0 0 1rem 0;
|
|
1781
|
-
font-size: 2.5rem;
|
|
1782
|
-
font-weight: 700;
|
|
1783
|
-
letter-spacing: -0.025em;
|
|
1784
|
-
}
|
|
1785
|
-
p {
|
|
1786
|
-
color: rgba(255, 255, 255, 0.8);
|
|
1787
|
-
margin: 0;
|
|
1788
|
-
font-size: 1.125rem;
|
|
1789
|
-
line-height: 1.5;
|
|
1790
|
-
}
|
|
1791
|
-
</style>
|
|
1792
|
-
</head>
|
|
1793
|
-
<body>
|
|
1794
|
-
<div class="container">
|
|
1795
|
-
<div class="icon-container">
|
|
1796
|
-
<div class="cross">\u2717</div>
|
|
1797
|
-
</div>
|
|
1798
|
-
<h1>Login Failed</h1>
|
|
1799
|
-
<p>No token received. Please try again.</p>
|
|
1800
|
-
</div>
|
|
1801
|
-
</body>
|
|
1802
|
-
</html>
|
|
1803
|
-
`);
|
|
1804
|
-
}
|
|
1805
|
-
}
|
|
1591
|
+
const data = await response.json();
|
|
1592
|
+
if (data.access_token) {
|
|
1593
|
+
return data.access_token;
|
|
1594
|
+
}
|
|
1595
|
+
if (data.error) {
|
|
1596
|
+
switch (data.error) {
|
|
1597
|
+
case "authorization_pending":
|
|
1598
|
+
break;
|
|
1599
|
+
case "slow_down":
|
|
1600
|
+
pollingInterval += 5;
|
|
1601
|
+
break;
|
|
1602
|
+
case "access_denied":
|
|
1603
|
+
throw new Error("Authorization was denied by the user.");
|
|
1604
|
+
case "expired_token":
|
|
1605
|
+
throw new Error("The device code has expired. Please try again.");
|
|
1606
|
+
default:
|
|
1607
|
+
throw new Error(
|
|
1608
|
+
data.error_description || `Device auth error: ${data.error}`
|
|
1609
|
+
);
|
|
1806
1610
|
}
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
});
|
|
1811
|
-
server.on("error", reject);
|
|
1812
|
-
});
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
throw new Error("Login timed out. Please try again.");
|
|
1813
1614
|
}
|
|
1814
1615
|
async function promptOrgSelection(profiles, defaultProfileId) {
|
|
1815
1616
|
if (profiles.length === 0) return null;
|
|
@@ -1852,64 +1653,76 @@ Enter number [${defaultDisplay}]: `),
|
|
|
1852
1653
|
}
|
|
1853
1654
|
async function loginCommand(options) {
|
|
1854
1655
|
try {
|
|
1656
|
+
const directKey = options?.apiKey || process.env.MCP_USE_API_KEY;
|
|
1657
|
+
if (directKey) {
|
|
1658
|
+
await writeConfig({ apiKey: directKey });
|
|
1659
|
+
if (!options?.silent) {
|
|
1660
|
+
console.log(source_default.green.bold("\u2713 API key saved."));
|
|
1661
|
+
try {
|
|
1662
|
+
const api2 = await McpUseAPI.create();
|
|
1663
|
+
const authInfo = await api2.testAuth();
|
|
1664
|
+
console.log(source_default.gray(` Authenticated as ${authInfo.email}`));
|
|
1665
|
+
} catch {
|
|
1666
|
+
console.log(
|
|
1667
|
+
source_default.gray(
|
|
1668
|
+
" (could not verify key \u2014 will be checked on next command)"
|
|
1669
|
+
)
|
|
1670
|
+
);
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
return;
|
|
1674
|
+
}
|
|
1855
1675
|
if (await isLoggedIn()) {
|
|
1856
1676
|
if (!options?.silent) {
|
|
1857
1677
|
console.log(
|
|
1858
1678
|
source_default.yellow(
|
|
1859
|
-
"
|
|
1679
|
+
"You are already logged in. Run 'npx mcp-use logout' first if you want to login with a different account."
|
|
1860
1680
|
)
|
|
1861
1681
|
);
|
|
1862
1682
|
}
|
|
1863
1683
|
return;
|
|
1864
1684
|
}
|
|
1865
|
-
console.log(source_default.cyan.bold("
|
|
1866
|
-
const
|
|
1867
|
-
const
|
|
1868
|
-
const
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
source_default.gray("
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
)
|
|
1891
|
-
)
|
|
1892
|
-
]);
|
|
1893
|
-
server.close();
|
|
1894
|
-
console.log(
|
|
1895
|
-
source_default.gray("Received authentication token, creating API key...")
|
|
1685
|
+
console.log(source_default.cyan.bold("Logging in to mcp-use cloud...\n"));
|
|
1686
|
+
const authBaseUrl = await getAuthBaseUrl();
|
|
1687
|
+
const deviceResp = await requestDeviceCode(authBaseUrl);
|
|
1688
|
+
const {
|
|
1689
|
+
device_code,
|
|
1690
|
+
user_code,
|
|
1691
|
+
verification_uri,
|
|
1692
|
+
verification_uri_complete,
|
|
1693
|
+
interval
|
|
1694
|
+
} = deviceResp;
|
|
1695
|
+
const displayCode = user_code.length === 8 ? `${user_code.slice(0, 4)}-${user_code.slice(4)}` : user_code;
|
|
1696
|
+
console.log(source_default.white(" Visit: ") + source_default.cyan(verification_uri));
|
|
1697
|
+
console.log(source_default.white(" Code: ") + source_default.bold.white(displayCode));
|
|
1698
|
+
console.log();
|
|
1699
|
+
const urlToOpen = verification_uri_complete || verification_uri;
|
|
1700
|
+
try {
|
|
1701
|
+
await open_default(urlToOpen);
|
|
1702
|
+
console.log(source_default.gray(" Browser opened. Waiting for approval..."));
|
|
1703
|
+
} catch {
|
|
1704
|
+
console.log(source_default.gray(" Open the URL above in your browser."));
|
|
1705
|
+
}
|
|
1706
|
+
const accessToken = await pollForDeviceToken(
|
|
1707
|
+
authBaseUrl,
|
|
1708
|
+
device_code,
|
|
1709
|
+
interval || 5
|
|
1896
1710
|
);
|
|
1711
|
+
console.log(source_default.gray("\n Creating persistent API key..."));
|
|
1897
1712
|
const api = await McpUseAPI.create();
|
|
1898
|
-
const
|
|
1899
|
-
await writeConfig({
|
|
1900
|
-
apiKey: apiKeyResponse.api_key
|
|
1901
|
-
});
|
|
1713
|
+
const keyResp = await api.createApiKeyWithAccessToken(accessToken, "CLI");
|
|
1714
|
+
await writeConfig({ apiKey: keyResp.key });
|
|
1902
1715
|
console.log(source_default.green.bold("\n\u2713 Successfully logged in!"));
|
|
1903
1716
|
try {
|
|
1904
|
-
const
|
|
1905
|
-
const authInfo = await
|
|
1906
|
-
console.log(source_default.cyan.bold("\
|
|
1907
|
-
console.log(source_default.white("Email: ") + source_default.cyan(authInfo.email));
|
|
1908
|
-
console.log(source_default.white("User ID: ") + source_default.gray(authInfo.user_id));
|
|
1909
|
-
const
|
|
1910
|
-
if (
|
|
1911
|
-
const masked =
|
|
1912
|
-
console.log(source_default.white("API Key: ") + source_default.gray(masked));
|
|
1717
|
+
const freshApi = await McpUseAPI.create();
|
|
1718
|
+
const authInfo = await freshApi.testAuth();
|
|
1719
|
+
console.log(source_default.cyan.bold("\nCurrent user:\n"));
|
|
1720
|
+
console.log(source_default.white(" Email: ") + source_default.cyan(authInfo.email));
|
|
1721
|
+
console.log(source_default.white(" User ID: ") + source_default.gray(authInfo.user_id));
|
|
1722
|
+
const storedKey = await getApiKey();
|
|
1723
|
+
if (storedKey) {
|
|
1724
|
+
const masked = storedKey.substring(0, 8) + "...";
|
|
1725
|
+
console.log(source_default.white(" API Key: ") + source_default.gray(masked));
|
|
1913
1726
|
}
|
|
1914
1727
|
const profiles = authInfo.profiles ?? [];
|
|
1915
1728
|
if (profiles.length > 0) {
|
|
@@ -1932,25 +1745,25 @@ async function loginCommand(options) {
|
|
|
1932
1745
|
});
|
|
1933
1746
|
const slug = selectedProfile.slug ? source_default.gray(` (${selectedProfile.slug})`) : "";
|
|
1934
1747
|
console.log(
|
|
1935
|
-
source_default.white("Org: ") + source_default.cyan(selectedProfile.profile_name) + slug
|
|
1748
|
+
source_default.white(" Org: ") + source_default.cyan(selectedProfile.profile_name) + slug
|
|
1936
1749
|
);
|
|
1937
1750
|
}
|
|
1938
1751
|
}
|
|
1939
|
-
} catch
|
|
1752
|
+
} catch {
|
|
1940
1753
|
console.log(
|
|
1941
1754
|
source_default.gray(
|
|
1942
1755
|
`
|
|
1943
|
-
Your API key has been saved to ${source_default.white("~/.mcp-use/config.json")}`
|
|
1756
|
+
Your API key has been saved to ${source_default.white("~/.mcp-use/config.json")}`
|
|
1944
1757
|
)
|
|
1945
1758
|
);
|
|
1946
1759
|
}
|
|
1947
1760
|
console.log(
|
|
1948
1761
|
source_default.gray(
|
|
1949
|
-
"\
|
|
1762
|
+
"\n Deploy your MCP servers with " + source_default.white("npx mcp-use deploy")
|
|
1950
1763
|
)
|
|
1951
1764
|
);
|
|
1952
1765
|
console.log(
|
|
1953
|
-
source_default.gray("To logout
|
|
1766
|
+
source_default.gray(" To logout, run " + source_default.white("npx mcp-use logout"))
|
|
1954
1767
|
);
|
|
1955
1768
|
} catch (error) {
|
|
1956
1769
|
throw new Error(
|
|
@@ -2023,10 +1836,20 @@ async function whoamiCommand() {
|
|
|
2023
1836
|
}
|
|
2024
1837
|
}
|
|
2025
1838
|
} catch (error) {
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
1839
|
+
if (error?.status === 401) {
|
|
1840
|
+
console.error(
|
|
1841
|
+
source_default.red("\nYour session has expired or your API key is invalid.")
|
|
1842
|
+
);
|
|
1843
|
+
console.log(
|
|
1844
|
+
source_default.gray(`Run ${source_default.white("mcp-use login")} to re-authenticate.
|
|
1845
|
+
`)
|
|
1846
|
+
);
|
|
1847
|
+
} else {
|
|
1848
|
+
console.error(
|
|
1849
|
+
source_default.red.bold("\n\u2717 Failed to get user info:"),
|
|
1850
|
+
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
1851
|
+
);
|
|
1852
|
+
}
|
|
2030
1853
|
process.exit(1);
|
|
2031
1854
|
}
|
|
2032
1855
|
}
|
|
@@ -5187,7 +5010,7 @@ async function isPortAvailable(port, host = "localhost") {
|
|
|
5187
5010
|
return true;
|
|
5188
5011
|
}
|
|
5189
5012
|
}
|
|
5190
|
-
async function
|
|
5013
|
+
async function findAvailablePort(startPort, host = "localhost") {
|
|
5191
5014
|
for (let port = startPort; port < startPort + 100; port++) {
|
|
5192
5015
|
if (await isPortAvailable(port, host)) {
|
|
5193
5016
|
return port;
|
|
@@ -5478,7 +5301,7 @@ if (container && Component) {
|
|
|
5478
5301
|
`${widgetName}-metadata`
|
|
5479
5302
|
);
|
|
5480
5303
|
await fs10.mkdir(metadataTempDir, { recursive: true });
|
|
5481
|
-
const { createServer
|
|
5304
|
+
const { createServer } = await import("vite");
|
|
5482
5305
|
const nodeStubsPlugin = {
|
|
5483
5306
|
name: "node-stubs",
|
|
5484
5307
|
enforce: "pre",
|
|
@@ -5505,7 +5328,7 @@ export default PostHog;
|
|
|
5505
5328
|
return null;
|
|
5506
5329
|
}
|
|
5507
5330
|
};
|
|
5508
|
-
const metadataServer = await
|
|
5331
|
+
const metadataServer = await createServer({
|
|
5509
5332
|
root: metadataTempDir,
|
|
5510
5333
|
cacheDir: import_node_path8.default.join(metadataTempDir, ".vite-cache"),
|
|
5511
5334
|
plugins: [nodeStubsPlugin, tailwindcss(), react()],
|
|
@@ -6070,7 +5893,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
6070
5893
|
displayPackageVersions(projectPath);
|
|
6071
5894
|
if (!await isPortAvailable(port, host)) {
|
|
6072
5895
|
console.log(source_default.yellow.bold(`\u26A0\uFE0F Port ${port} is already in use`));
|
|
6073
|
-
const availablePort = await
|
|
5896
|
+
const availablePort = await findAvailablePort(port, host);
|
|
6074
5897
|
console.log(source_default.green.bold(`\u2713 Using port ${availablePort} instead`));
|
|
6075
5898
|
port = availablePort;
|
|
6076
5899
|
}
|
|
@@ -6905,9 +6728,12 @@ Looked for:
|
|
|
6905
6728
|
process.exit(1);
|
|
6906
6729
|
}
|
|
6907
6730
|
});
|
|
6908
|
-
program.command("login").description("Login to
|
|
6731
|
+
program.command("login").description("Login to mcp-use cloud").option(
|
|
6732
|
+
"--api-key <key>",
|
|
6733
|
+
"Login with an API key directly (non-interactive, for CI/CD)"
|
|
6734
|
+
).action(async (opts) => {
|
|
6909
6735
|
try {
|
|
6910
|
-
await loginCommand();
|
|
6736
|
+
await loginCommand({ apiKey: opts.apiKey });
|
|
6911
6737
|
process.exit(0);
|
|
6912
6738
|
} catch (error) {
|
|
6913
6739
|
console.error(
|