@mcp-use/cli 3.0.0-canary.3 → 3.0.0-canary.5
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 +2 -8
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/deploy.d.ts +3 -4
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deployments.d.ts +0 -3
- package/dist/commands/deployments.d.ts.map +1 -1
- package/dist/commands/org.d.ts.map +1 -1
- package/dist/commands/servers.d.ts +3 -0
- package/dist/commands/servers.d.ts.map +1 -0
- package/dist/index.cjs +1229 -1185
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1228 -1184
- package/dist/index.js.map +1 -1
- package/dist/utils/api.d.ts +130 -144
- package/dist/utils/api.d.ts.map +1 -1
- package/dist/utils/cloud-urls.d.ts +14 -0
- package/dist/utils/cloud-urls.d.ts.map +1 -0
- package/dist/utils/config.d.ts +10 -4
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/git.d.ts +12 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -523,8 +523,8 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
|
523
523
|
var source_default = chalk;
|
|
524
524
|
|
|
525
525
|
// src/index.ts
|
|
526
|
-
var
|
|
527
|
-
var
|
|
526
|
+
var import_commander5 = require("commander");
|
|
527
|
+
var import_config7 = require("dotenv/config");
|
|
528
528
|
var import_node_child_process9 = require("child_process");
|
|
529
529
|
var import_node_fs10 = require("fs");
|
|
530
530
|
var import_promises7 = require("fs/promises");
|
|
@@ -1167,14 +1167,21 @@ async function ensureConfigDir() {
|
|
|
1167
1167
|
async function readConfig() {
|
|
1168
1168
|
try {
|
|
1169
1169
|
const content = await import_node_fs4.promises.readFile(CONFIG_FILE, "utf-8");
|
|
1170
|
-
|
|
1170
|
+
const raw = JSON.parse(content);
|
|
1171
|
+
return {
|
|
1172
|
+
...raw,
|
|
1173
|
+
orgId: raw.orgId ?? raw.profileId,
|
|
1174
|
+
orgName: raw.orgName ?? raw.profileName,
|
|
1175
|
+
orgSlug: raw.orgSlug ?? raw.profileSlug
|
|
1176
|
+
};
|
|
1171
1177
|
} catch (error) {
|
|
1172
1178
|
return {};
|
|
1173
1179
|
}
|
|
1174
1180
|
}
|
|
1175
1181
|
async function writeConfig(config) {
|
|
1176
1182
|
await ensureConfigDir();
|
|
1177
|
-
|
|
1183
|
+
const { profileId: _a, profileName: _b, profileSlug: _c, ...clean } = config;
|
|
1184
|
+
await import_node_fs4.promises.writeFile(CONFIG_FILE, JSON.stringify(clean, null, 2), "utf-8");
|
|
1178
1185
|
}
|
|
1179
1186
|
async function deleteConfig() {
|
|
1180
1187
|
try {
|
|
@@ -1194,9 +1201,9 @@ async function isLoggedIn() {
|
|
|
1194
1201
|
const apiKey = await getApiKey();
|
|
1195
1202
|
return !!apiKey;
|
|
1196
1203
|
}
|
|
1197
|
-
async function
|
|
1204
|
+
async function getOrgId() {
|
|
1198
1205
|
const config = await readConfig();
|
|
1199
|
-
return config.
|
|
1206
|
+
return config.orgId || null;
|
|
1200
1207
|
}
|
|
1201
1208
|
async function getWebUrl() {
|
|
1202
1209
|
return DEFAULT_WEB_URL;
|
|
@@ -1210,30 +1217,21 @@ async function getAuthBaseUrl() {
|
|
|
1210
1217
|
var McpUseAPI = class _McpUseAPI {
|
|
1211
1218
|
baseUrl;
|
|
1212
1219
|
apiKey;
|
|
1213
|
-
|
|
1214
|
-
constructor(baseUrl, apiKey,
|
|
1220
|
+
orgId;
|
|
1221
|
+
constructor(baseUrl, apiKey, orgId) {
|
|
1215
1222
|
this.baseUrl = baseUrl || "";
|
|
1216
1223
|
this.apiKey = apiKey;
|
|
1217
|
-
this.
|
|
1224
|
+
this.orgId = orgId;
|
|
1218
1225
|
}
|
|
1219
|
-
/**
|
|
1220
|
-
* Initialize API client with config
|
|
1221
|
-
*/
|
|
1222
1226
|
static async create() {
|
|
1223
1227
|
const baseUrl = await getApiUrl();
|
|
1224
1228
|
const apiKey = await getApiKey();
|
|
1225
|
-
const
|
|
1226
|
-
return new _McpUseAPI(baseUrl, apiKey ?? void 0,
|
|
1229
|
+
const orgId = await getOrgId();
|
|
1230
|
+
return new _McpUseAPI(baseUrl, apiKey ?? void 0, orgId ?? void 0);
|
|
1227
1231
|
}
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
*/
|
|
1231
|
-
setProfileId(profileId) {
|
|
1232
|
-
this.profileId = profileId;
|
|
1232
|
+
setOrgId(orgId) {
|
|
1233
|
+
this.orgId = orgId;
|
|
1233
1234
|
}
|
|
1234
|
-
/**
|
|
1235
|
-
* Make authenticated request
|
|
1236
|
-
*/
|
|
1237
1235
|
async request(endpoint, options = {}) {
|
|
1238
1236
|
const url = `${this.baseUrl}${endpoint}`;
|
|
1239
1237
|
const headers = {
|
|
@@ -1243,8 +1241,8 @@ var McpUseAPI = class _McpUseAPI {
|
|
|
1243
1241
|
if (this.apiKey) {
|
|
1244
1242
|
headers["x-api-key"] = this.apiKey;
|
|
1245
1243
|
}
|
|
1246
|
-
if (this.
|
|
1247
|
-
headers["x-profile-id"] = this.
|
|
1244
|
+
if (this.orgId) {
|
|
1245
|
+
headers["x-profile-id"] = this.orgId;
|
|
1248
1246
|
}
|
|
1249
1247
|
const timeout = options.timeout || 3e4;
|
|
1250
1248
|
const controller = new AbortController();
|
|
@@ -1271,16 +1269,13 @@ var McpUseAPI = class _McpUseAPI {
|
|
|
1271
1269
|
} catch (error) {
|
|
1272
1270
|
clearTimeout(timeoutId);
|
|
1273
1271
|
if (error.name === "AbortError") {
|
|
1274
|
-
throw new Error(
|
|
1275
|
-
`Request timeout after ${timeout / 1e3}s. Try using --follow flag to stream logs instead.`
|
|
1276
|
-
);
|
|
1272
|
+
throw new Error(`Request timeout after ${timeout / 1e3}s.`);
|
|
1277
1273
|
}
|
|
1278
1274
|
throw error;
|
|
1279
1275
|
}
|
|
1280
1276
|
}
|
|
1281
1277
|
/**
|
|
1282
1278
|
* 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.
|
|
1284
1279
|
*/
|
|
1285
1280
|
async createApiKeyWithAccessToken(accessToken, name = "CLI") {
|
|
1286
1281
|
const authBase = await getAuthBaseUrl();
|
|
@@ -1299,255 +1294,171 @@ var McpUseAPI = class _McpUseAPI {
|
|
|
1299
1294
|
}
|
|
1300
1295
|
return response.json();
|
|
1301
1296
|
}
|
|
1302
|
-
|
|
1303
|
-
* Test authentication
|
|
1304
|
-
*/
|
|
1297
|
+
// ── Auth ────────────────────────────────────────────────────────
|
|
1305
1298
|
async testAuth() {
|
|
1306
|
-
|
|
1299
|
+
const wire = await this.request("/test-auth");
|
|
1300
|
+
return {
|
|
1301
|
+
message: wire.message,
|
|
1302
|
+
user_id: wire.user_id,
|
|
1303
|
+
email: wire.email,
|
|
1304
|
+
default_org_id: wire.default_profile_id,
|
|
1305
|
+
orgs: (wire.profiles ?? []).map((p) => ({
|
|
1306
|
+
id: p.id,
|
|
1307
|
+
name: p.profile_name,
|
|
1308
|
+
slug: p.slug,
|
|
1309
|
+
role: p.role
|
|
1310
|
+
}))
|
|
1311
|
+
};
|
|
1307
1312
|
}
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
*/
|
|
1311
|
-
async setDefaultProfile(profileId) {
|
|
1312
|
-
await this.request(`/profiles/${profileId}/set-default`, {
|
|
1313
|
+
async setDefaultOrg(orgId) {
|
|
1314
|
+
await this.request(`/organizations/${orgId}/set-default`, {
|
|
1313
1315
|
method: "POST"
|
|
1314
1316
|
});
|
|
1315
1317
|
}
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1318
|
+
// ── Organization ID resolution ──────────────────────────────────
|
|
1319
|
+
async resolveOrganizationId() {
|
|
1320
|
+
if (this.orgId) return this.orgId;
|
|
1321
|
+
const auth = await this.testAuth();
|
|
1322
|
+
const id = auth.default_org_id;
|
|
1323
|
+
if (!id) {
|
|
1324
|
+
throw new Error(
|
|
1325
|
+
"No organization set. Run `mcp-use org switch` or use --org to specify one."
|
|
1326
|
+
);
|
|
1327
|
+
}
|
|
1328
|
+
return id;
|
|
1329
|
+
}
|
|
1330
|
+
// ── Servers ─────────────────────────────────────────────────────
|
|
1331
|
+
async createServer(body) {
|
|
1332
|
+
return this.request("/servers", {
|
|
1321
1333
|
method: "POST",
|
|
1322
|
-
body: JSON.stringify(
|
|
1334
|
+
body: JSON.stringify(body)
|
|
1323
1335
|
});
|
|
1324
1336
|
}
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
return this.request(`/deployments/${deploymentId}`);
|
|
1330
|
-
}
|
|
1331
|
-
/**
|
|
1332
|
-
* Stream deployment logs
|
|
1333
|
-
*/
|
|
1334
|
-
async *streamDeploymentLogs(deploymentId) {
|
|
1335
|
-
const url = `${this.baseUrl}/deployments/${deploymentId}/logs/stream`;
|
|
1336
|
-
const headers = {};
|
|
1337
|
-
if (this.apiKey) {
|
|
1338
|
-
headers["x-api-key"] = this.apiKey;
|
|
1339
|
-
}
|
|
1340
|
-
if (this.profileId) {
|
|
1341
|
-
headers["x-profile-id"] = this.profileId;
|
|
1337
|
+
async listServers(params) {
|
|
1338
|
+
const search = new URLSearchParams();
|
|
1339
|
+
if (params?.organizationId) {
|
|
1340
|
+
search.set("organizationId", params.organizationId);
|
|
1342
1341
|
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
throw new Error(`Failed to stream logs: ${response.status}`);
|
|
1342
|
+
if (params?.limit != null) {
|
|
1343
|
+
search.set("limit", String(params.limit));
|
|
1346
1344
|
}
|
|
1347
|
-
if (
|
|
1348
|
-
|
|
1345
|
+
if (params?.skip != null) {
|
|
1346
|
+
search.set("skip", String(params.skip));
|
|
1349
1347
|
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
let buffer = "";
|
|
1353
|
-
try {
|
|
1354
|
-
while (true) {
|
|
1355
|
-
const { done, value } = await reader.read();
|
|
1356
|
-
if (done) break;
|
|
1357
|
-
buffer += decoder.decode(value, { stream: true });
|
|
1358
|
-
const lines = buffer.split("\n");
|
|
1359
|
-
buffer = lines.pop() || "";
|
|
1360
|
-
for (const line of lines) {
|
|
1361
|
-
if (line.startsWith("data: ")) {
|
|
1362
|
-
const data = line.slice(6);
|
|
1363
|
-
try {
|
|
1364
|
-
const parsed = JSON.parse(data);
|
|
1365
|
-
if (parsed.log) {
|
|
1366
|
-
yield parsed.log;
|
|
1367
|
-
} else if (parsed.error) {
|
|
1368
|
-
throw new Error(parsed.error);
|
|
1369
|
-
}
|
|
1370
|
-
} catch (e) {
|
|
1371
|
-
}
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
} finally {
|
|
1376
|
-
reader.releaseLock();
|
|
1348
|
+
if (params?.sort) {
|
|
1349
|
+
search.set("sort", params.sort);
|
|
1377
1350
|
}
|
|
1351
|
+
const q = search.toString();
|
|
1352
|
+
return this.request(`/servers${q ? `?${q}` : ""}`);
|
|
1378
1353
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
if (stats.size > maxSize) {
|
|
1389
|
-
throw new Error(
|
|
1390
|
-
`File size (${(stats.size / 1024 / 1024).toFixed(2)}MB) exceeds maximum of 2MB`
|
|
1391
|
-
);
|
|
1392
|
-
}
|
|
1393
|
-
const fileBuffer = await readFile4(filePath);
|
|
1394
|
-
const filename = basename(filePath);
|
|
1395
|
-
const formData = new FormData();
|
|
1396
|
-
const blob = new Blob([fileBuffer], { type: "application/gzip" });
|
|
1397
|
-
formData.append("source_file", blob, filename);
|
|
1398
|
-
formData.append("name", request.name);
|
|
1399
|
-
formData.append("source_type", "upload");
|
|
1400
|
-
if (request.source.type === "upload") {
|
|
1401
|
-
formData.append("runtime", request.source.runtime || "node");
|
|
1402
|
-
formData.append("port", String(request.source.port || 3e3));
|
|
1403
|
-
if (request.source.startCommand) {
|
|
1404
|
-
formData.append("startCommand", request.source.startCommand);
|
|
1405
|
-
}
|
|
1406
|
-
if (request.source.buildCommand) {
|
|
1407
|
-
formData.append("buildCommand", request.source.buildCommand);
|
|
1408
|
-
}
|
|
1409
|
-
if (request.source.env && Object.keys(request.source.env).length > 0) {
|
|
1410
|
-
formData.append("env", JSON.stringify(request.source.env));
|
|
1354
|
+
async getServer(idOrSlug) {
|
|
1355
|
+
const path7 = encodeURIComponent(idOrSlug);
|
|
1356
|
+
return this.request(`/servers/${path7}`);
|
|
1357
|
+
}
|
|
1358
|
+
async deleteServer(id) {
|
|
1359
|
+
await this.request(
|
|
1360
|
+
`/servers/${encodeURIComponent(id)}`,
|
|
1361
|
+
{
|
|
1362
|
+
method: "DELETE"
|
|
1411
1363
|
}
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
formData.append("healthCheckPath", request.healthCheckPath);
|
|
1418
|
-
}
|
|
1419
|
-
const url = `${this.baseUrl}/deployments`;
|
|
1420
|
-
const headers = {};
|
|
1421
|
-
if (this.apiKey) {
|
|
1422
|
-
headers["x-api-key"] = this.apiKey;
|
|
1423
|
-
}
|
|
1424
|
-
if (this.profileId) {
|
|
1425
|
-
headers["x-profile-id"] = this.profileId;
|
|
1426
|
-
}
|
|
1427
|
-
const response = await fetch(url, {
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
// ── Deployments ─────────────────────────────────────────────────
|
|
1367
|
+
async createDeployment(input) {
|
|
1368
|
+
return this.request("/deployments", {
|
|
1428
1369
|
method: "POST",
|
|
1429
|
-
|
|
1430
|
-
body: formData
|
|
1370
|
+
body: JSON.stringify(input)
|
|
1431
1371
|
});
|
|
1432
|
-
if (!response.ok) {
|
|
1433
|
-
const error = await response.text();
|
|
1434
|
-
throw new Error(`Deployment failed: ${error}`);
|
|
1435
|
-
}
|
|
1436
|
-
return response.json();
|
|
1437
1372
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1373
|
+
async getDeployment(deploymentId) {
|
|
1374
|
+
return this.request(`/deployments/${deploymentId}`);
|
|
1375
|
+
}
|
|
1441
1376
|
async listDeployments() {
|
|
1442
|
-
|
|
1443
|
-
return response.deployments;
|
|
1377
|
+
return this.request("/deployments");
|
|
1444
1378
|
}
|
|
1445
|
-
/**
|
|
1446
|
-
* Delete deployment
|
|
1447
|
-
*/
|
|
1448
1379
|
async deleteDeployment(deploymentId) {
|
|
1449
1380
|
await this.request(`/deployments/${deploymentId}`, {
|
|
1450
1381
|
method: "DELETE"
|
|
1451
1382
|
});
|
|
1452
1383
|
}
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
async updateDeployment(deploymentId, updates) {
|
|
1457
|
-
return this.request(`/deployments/${deploymentId}`, {
|
|
1458
|
-
method: "PATCH",
|
|
1459
|
-
body: JSON.stringify(updates)
|
|
1460
|
-
});
|
|
1461
|
-
}
|
|
1462
|
-
/**
|
|
1463
|
-
* Redeploy deployment
|
|
1464
|
-
*
|
|
1465
|
-
* @param deploymentId - The deployment ID to redeploy
|
|
1466
|
-
* @param configOrFilePath - Either a RedeploymentConfig object with updated settings,
|
|
1467
|
-
* or a file path string for source code upload
|
|
1468
|
-
*/
|
|
1469
|
-
async redeployDeployment(deploymentId, configOrFilePath) {
|
|
1470
|
-
if (typeof configOrFilePath === "string") {
|
|
1471
|
-
const filePath = configOrFilePath;
|
|
1472
|
-
const { readFile: readFile4 } = await import("fs/promises");
|
|
1473
|
-
const { basename } = await import("path");
|
|
1474
|
-
const { stat } = await import("fs/promises");
|
|
1475
|
-
const stats = await stat(filePath);
|
|
1476
|
-
const maxSize = 2 * 1024 * 1024;
|
|
1477
|
-
if (stats.size > maxSize) {
|
|
1478
|
-
throw new Error(
|
|
1479
|
-
`File size (${(stats.size / 1024 / 1024).toFixed(2)}MB) exceeds maximum of 2MB`
|
|
1480
|
-
);
|
|
1481
|
-
}
|
|
1482
|
-
const fileBuffer = await readFile4(filePath);
|
|
1483
|
-
const formData = new FormData();
|
|
1484
|
-
const blob = new Blob([fileBuffer], { type: "application/gzip" });
|
|
1485
|
-
formData.append("source_file", blob, basename(filePath));
|
|
1486
|
-
const headers = {};
|
|
1487
|
-
if (this.apiKey) headers["x-api-key"] = this.apiKey;
|
|
1488
|
-
if (this.profileId) headers["x-profile-id"] = this.profileId;
|
|
1489
|
-
const response = await fetch(
|
|
1490
|
-
`${this.baseUrl}/deployments/${deploymentId}/redeploy`,
|
|
1491
|
-
{
|
|
1492
|
-
method: "POST",
|
|
1493
|
-
headers,
|
|
1494
|
-
body: formData
|
|
1495
|
-
}
|
|
1496
|
-
);
|
|
1497
|
-
if (!response.ok) {
|
|
1498
|
-
const error = await response.text();
|
|
1499
|
-
throw new Error(`Redeploy failed: ${error}`);
|
|
1500
|
-
}
|
|
1501
|
-
return response.json();
|
|
1502
|
-
}
|
|
1503
|
-
const config = configOrFilePath;
|
|
1504
|
-
return this.request(`/deployments/${deploymentId}/redeploy`, {
|
|
1505
|
-
method: "POST",
|
|
1506
|
-
body: config ? JSON.stringify(config) : void 0
|
|
1384
|
+
async stopDeployment(deploymentId) {
|
|
1385
|
+
await this.request(`/deployments/${deploymentId}/stop`, {
|
|
1386
|
+
method: "POST"
|
|
1507
1387
|
});
|
|
1508
1388
|
}
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
async getDeploymentLogs(deploymentId) {
|
|
1513
|
-
const response = await this.request(
|
|
1514
|
-
`/deployments/${deploymentId}/logs`,
|
|
1389
|
+
async getDeploymentLogs(deploymentId, lines = 500) {
|
|
1390
|
+
const resp = await this.request(
|
|
1391
|
+
`/deployments/${deploymentId}/logs?lines=${lines}`,
|
|
1515
1392
|
{ timeout: 6e4 }
|
|
1516
|
-
// 60 second timeout for logs
|
|
1517
1393
|
);
|
|
1518
|
-
return
|
|
1394
|
+
return resp.logs;
|
|
1519
1395
|
}
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
async getDeploymentBuildLogs(deploymentId) {
|
|
1524
|
-
const response = await this.request(
|
|
1525
|
-
`/deployments/${deploymentId}/logs/build`,
|
|
1396
|
+
async getDeploymentBuildLogs(deploymentId, offset = 0) {
|
|
1397
|
+
return this.request(
|
|
1398
|
+
`/deployments/${deploymentId}/build-logs?offset=${offset}`,
|
|
1526
1399
|
{ timeout: 6e4 }
|
|
1527
|
-
// 60 second timeout for logs
|
|
1528
1400
|
);
|
|
1529
|
-
return response.data.logs;
|
|
1530
1401
|
}
|
|
1531
|
-
|
|
1532
|
-
* Get GitHub connection status
|
|
1533
|
-
*/
|
|
1402
|
+
// ── GitHub ──────────────────────────────────────────────────────
|
|
1534
1403
|
async getGitHubConnectionStatus() {
|
|
1535
|
-
|
|
1404
|
+
const orgId = await this.resolveOrganizationId();
|
|
1405
|
+
const resp = await this.request(`/github/installations?organizationId=${orgId}`);
|
|
1406
|
+
return {
|
|
1407
|
+
is_connected: resp.installations.length > 0,
|
|
1408
|
+
installations: resp.installations.map((i) => ({
|
|
1409
|
+
id: i.id,
|
|
1410
|
+
installation_id: i.installationId,
|
|
1411
|
+
account_login: i.account?.login ?? "",
|
|
1412
|
+
account_type: i.account?.type ?? "User"
|
|
1413
|
+
}))
|
|
1414
|
+
};
|
|
1415
|
+
}
|
|
1416
|
+
async getGitHubRepos(_refresh) {
|
|
1417
|
+
const orgId = await this.resolveOrganizationId();
|
|
1418
|
+
const installResp = await this.request(`/github/installations?organizationId=${orgId}`);
|
|
1419
|
+
if (installResp.installations.length === 0) {
|
|
1420
|
+
return { user: { login: "", id: 0, avatar_url: "" }, repos: [] };
|
|
1421
|
+
}
|
|
1422
|
+
const inst = installResp.installations[0];
|
|
1423
|
+
const reposResp = await this.request(`/github/installations/${inst.installationId}/repos`);
|
|
1424
|
+
return {
|
|
1425
|
+
user: {
|
|
1426
|
+
login: inst.account?.login ?? "",
|
|
1427
|
+
id: 0,
|
|
1428
|
+
avatar_url: inst.account?.avatar_url ?? ""
|
|
1429
|
+
},
|
|
1430
|
+
repos: reposResp.repos.map((r) => ({
|
|
1431
|
+
id: r.id,
|
|
1432
|
+
name: r.name,
|
|
1433
|
+
full_name: r.fullName,
|
|
1434
|
+
private: r.private,
|
|
1435
|
+
owner: { login: r.fullName.split("/")[0] ?? "" }
|
|
1436
|
+
}))
|
|
1437
|
+
};
|
|
1536
1438
|
}
|
|
1537
|
-
/**
|
|
1538
|
-
* Get GitHub app name
|
|
1539
|
-
*/
|
|
1540
1439
|
async getGitHubAppName() {
|
|
1541
|
-
|
|
1542
|
-
return
|
|
1440
|
+
if (process.env.MCP_GITHUB_APP_NAME) return process.env.MCP_GITHUB_APP_NAME;
|
|
1441
|
+
if (this.baseUrl.includes("localhost")) return "mcp-use-local";
|
|
1442
|
+
if (this.baseUrl.includes(".dev.")) return "mcp-use-dev";
|
|
1443
|
+
return "mcp-use";
|
|
1543
1444
|
}
|
|
1544
1445
|
/**
|
|
1545
|
-
*
|
|
1446
|
+
* Returns the GitHub numeric installation ID (not the DB UUID) for the org.
|
|
1447
|
+
* Used for building direct installation settings URLs.
|
|
1546
1448
|
*/
|
|
1547
|
-
async
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1449
|
+
async getGitHubInstallationId() {
|
|
1450
|
+
const status = await this.getGitHubConnectionStatus();
|
|
1451
|
+
return status.installations?.[0]?.installation_id ?? null;
|
|
1452
|
+
}
|
|
1453
|
+
async createGitHubRepo(opts) {
|
|
1454
|
+
return this.request(`/github/installations/${opts.installationId}/repos`, {
|
|
1455
|
+
method: "POST",
|
|
1456
|
+
body: JSON.stringify({
|
|
1457
|
+
name: opts.name,
|
|
1458
|
+
private: opts.private ?? true,
|
|
1459
|
+
org: opts.org
|
|
1460
|
+
})
|
|
1461
|
+
});
|
|
1551
1462
|
}
|
|
1552
1463
|
};
|
|
1553
1464
|
|
|
@@ -1612,19 +1523,17 @@ async function pollForDeviceToken(authBaseUrl, deviceCode, intervalSeconds) {
|
|
|
1612
1523
|
}
|
|
1613
1524
|
throw new Error("Login timed out. Please try again.");
|
|
1614
1525
|
}
|
|
1615
|
-
async function promptOrgSelection(
|
|
1616
|
-
if (
|
|
1617
|
-
if (
|
|
1618
|
-
return
|
|
1526
|
+
async function promptOrgSelection(orgs, defaultOrgId) {
|
|
1527
|
+
if (orgs.length === 0) return null;
|
|
1528
|
+
if (orgs.length === 1) {
|
|
1529
|
+
return orgs[0];
|
|
1619
1530
|
}
|
|
1620
1531
|
console.log(source_default.cyan.bold("\n\u{1F3E2} Select an organization:\n"));
|
|
1621
|
-
for (let i = 0; i <
|
|
1622
|
-
const
|
|
1623
|
-
const marker =
|
|
1624
|
-
const slug =
|
|
1625
|
-
console.log(
|
|
1626
|
-
` ${source_default.white(`${i + 1}.`)} ${p.profile_name}${slug}${marker}`
|
|
1627
|
-
);
|
|
1532
|
+
for (let i = 0; i < orgs.length; i++) {
|
|
1533
|
+
const o = orgs[i];
|
|
1534
|
+
const marker = o.id === defaultOrgId ? source_default.green(" (current)") : "";
|
|
1535
|
+
const slug = o.slug ? source_default.gray(` (${o.slug})`) : "";
|
|
1536
|
+
console.log(` ${source_default.white(`${i + 1}.`)} ${o.name}${slug}${marker}`);
|
|
1628
1537
|
}
|
|
1629
1538
|
const readline = await import("readline");
|
|
1630
1539
|
const rl = readline.createInterface({
|
|
@@ -1632,7 +1541,7 @@ async function promptOrgSelection(profiles, defaultProfileId) {
|
|
|
1632
1541
|
output: process.stdout
|
|
1633
1542
|
});
|
|
1634
1543
|
return new Promise((resolve2) => {
|
|
1635
|
-
const defaultIdx =
|
|
1544
|
+
const defaultIdx = defaultOrgId ? orgs.findIndex((o) => o.id === defaultOrgId) : 0;
|
|
1636
1545
|
const defaultDisplay = defaultIdx >= 0 ? defaultIdx + 1 : 1;
|
|
1637
1546
|
rl.question(
|
|
1638
1547
|
source_default.gray(`
|
|
@@ -1641,11 +1550,11 @@ Enter number [${defaultDisplay}]: `),
|
|
|
1641
1550
|
rl.close();
|
|
1642
1551
|
const trimmed = answer.trim();
|
|
1643
1552
|
const idx = trimmed === "" ? defaultIdx : parseInt(trimmed, 10) - 1;
|
|
1644
|
-
if (idx >= 0 && idx <
|
|
1645
|
-
resolve2(
|
|
1553
|
+
if (idx >= 0 && idx < orgs.length) {
|
|
1554
|
+
resolve2(orgs[idx]);
|
|
1646
1555
|
} else {
|
|
1647
1556
|
console.log(source_default.yellow("Invalid selection, using default."));
|
|
1648
|
-
resolve2(
|
|
1557
|
+
resolve2(orgs[defaultIdx >= 0 ? defaultIdx : 0]);
|
|
1649
1558
|
}
|
|
1650
1559
|
}
|
|
1651
1560
|
);
|
|
@@ -1724,28 +1633,25 @@ async function loginCommand(options) {
|
|
|
1724
1633
|
const masked = storedKey.substring(0, 8) + "...";
|
|
1725
1634
|
console.log(source_default.white(" API Key: ") + source_default.gray(masked));
|
|
1726
1635
|
}
|
|
1727
|
-
const
|
|
1728
|
-
if (
|
|
1729
|
-
let
|
|
1730
|
-
if (
|
|
1731
|
-
|
|
1636
|
+
const orgs = authInfo.orgs ?? [];
|
|
1637
|
+
if (orgs.length > 0) {
|
|
1638
|
+
let selectedOrg = null;
|
|
1639
|
+
if (orgs.length === 1) {
|
|
1640
|
+
selectedOrg = orgs[0];
|
|
1732
1641
|
} else {
|
|
1733
|
-
|
|
1734
|
-
profiles,
|
|
1735
|
-
authInfo.default_profile_id
|
|
1736
|
-
);
|
|
1642
|
+
selectedOrg = await promptOrgSelection(orgs, authInfo.default_org_id);
|
|
1737
1643
|
}
|
|
1738
|
-
if (
|
|
1644
|
+
if (selectedOrg) {
|
|
1739
1645
|
const config = await readConfig();
|
|
1740
1646
|
await writeConfig({
|
|
1741
1647
|
...config,
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1648
|
+
orgId: selectedOrg.id,
|
|
1649
|
+
orgName: selectedOrg.name,
|
|
1650
|
+
orgSlug: selectedOrg.slug ?? void 0
|
|
1745
1651
|
});
|
|
1746
|
-
const slug =
|
|
1652
|
+
const slug = selectedOrg.slug ? source_default.gray(` (${selectedOrg.slug})`) : "";
|
|
1747
1653
|
console.log(
|
|
1748
|
-
source_default.white(" Org: ") + source_default.cyan(
|
|
1654
|
+
source_default.white(" Org: ") + source_default.cyan(selectedOrg.name) + slug
|
|
1749
1655
|
);
|
|
1750
1656
|
}
|
|
1751
1657
|
}
|
|
@@ -1815,22 +1721,22 @@ async function whoamiCommand() {
|
|
|
1815
1721
|
console.log(source_default.white("API Key: ") + source_default.gray(masked));
|
|
1816
1722
|
}
|
|
1817
1723
|
const config = await readConfig();
|
|
1818
|
-
const
|
|
1819
|
-
if (
|
|
1820
|
-
const
|
|
1821
|
-
(
|
|
1724
|
+
const orgs = authInfo.orgs ?? [];
|
|
1725
|
+
if (orgs.length > 0) {
|
|
1726
|
+
const activeOrg = orgs.find(
|
|
1727
|
+
(o) => o.id === (config.orgId || authInfo.default_org_id)
|
|
1822
1728
|
);
|
|
1823
|
-
if (
|
|
1824
|
-
const slug =
|
|
1729
|
+
if (activeOrg) {
|
|
1730
|
+
const slug = activeOrg.slug ? source_default.gray(` (${activeOrg.slug})`) : "";
|
|
1825
1731
|
console.log(
|
|
1826
|
-
source_default.white("Org: ") + source_default.cyan(
|
|
1732
|
+
source_default.white("Org: ") + source_default.cyan(activeOrg.name) + slug
|
|
1827
1733
|
);
|
|
1828
1734
|
}
|
|
1829
|
-
if (
|
|
1735
|
+
if (orgs.length > 1) {
|
|
1830
1736
|
console.log(
|
|
1831
1737
|
source_default.gray(
|
|
1832
1738
|
`
|
|
1833
|
-
${
|
|
1739
|
+
${orgs.length} organizations available. Use ` + source_default.white("npx mcp-use org list") + " to see all."
|
|
1834
1740
|
)
|
|
1835
1741
|
);
|
|
1836
1742
|
}
|
|
@@ -2607,9 +2513,9 @@ async function listPromptsCommand(options) {
|
|
|
2607
2513
|
}
|
|
2608
2514
|
console.log(formatHeader(`Available Prompts (${prompts.length}):`));
|
|
2609
2515
|
console.log("");
|
|
2610
|
-
const tableData = prompts.map((
|
|
2611
|
-
name: source_default.bold(
|
|
2612
|
-
description:
|
|
2516
|
+
const tableData = prompts.map((prompt4) => ({
|
|
2517
|
+
name: source_default.bold(prompt4.name),
|
|
2518
|
+
description: prompt4.description || source_default.gray("No description")
|
|
2613
2519
|
}));
|
|
2614
2520
|
console.log(
|
|
2615
2521
|
formatTable(tableData, [
|
|
@@ -2637,20 +2543,20 @@ async function getPromptCommand(promptName, argsJson, options) {
|
|
|
2637
2543
|
}
|
|
2638
2544
|
}
|
|
2639
2545
|
console.error(formatInfo(`Getting prompt '${promptName}'...`));
|
|
2640
|
-
const
|
|
2546
|
+
const prompt4 = await session.getPrompt(promptName, args);
|
|
2641
2547
|
if (options?.json) {
|
|
2642
|
-
console.log(formatJson(
|
|
2548
|
+
console.log(formatJson(prompt4));
|
|
2643
2549
|
} else {
|
|
2644
2550
|
console.log(formatHeader(`Prompt: ${promptName}`));
|
|
2645
2551
|
console.log("");
|
|
2646
|
-
if (
|
|
2647
|
-
console.log(
|
|
2552
|
+
if (prompt4.description) {
|
|
2553
|
+
console.log(prompt4.description);
|
|
2648
2554
|
console.log("");
|
|
2649
2555
|
}
|
|
2650
|
-
if (
|
|
2556
|
+
if (prompt4.messages) {
|
|
2651
2557
|
console.log(formatHeader("Messages:"));
|
|
2652
2558
|
console.log("");
|
|
2653
|
-
console.log(formatPromptMessages(
|
|
2559
|
+
console.log(formatPromptMessages(prompt4.messages));
|
|
2654
2560
|
}
|
|
2655
2561
|
}
|
|
2656
2562
|
} catch (error) {
|
|
@@ -2790,8 +2696,8 @@ async function interactiveCommand(options) {
|
|
|
2790
2696
|
async (argsInput) => {
|
|
2791
2697
|
try {
|
|
2792
2698
|
const args = argsInput.trim() ? JSON.parse(argsInput) : {};
|
|
2793
|
-
const
|
|
2794
|
-
console.log(formatPromptMessages(
|
|
2699
|
+
const prompt4 = await session.getPrompt(arg, args);
|
|
2700
|
+
console.log(formatPromptMessages(prompt4.messages));
|
|
2795
2701
|
} catch (error) {
|
|
2796
2702
|
console.error(formatError(error.message));
|
|
2797
2703
|
}
|
|
@@ -2957,6 +2863,20 @@ async function getGitInfo(cwd = process.cwd()) {
|
|
|
2957
2863
|
hasUncommittedChanges: uncommittedChanges
|
|
2958
2864
|
};
|
|
2959
2865
|
}
|
|
2866
|
+
async function gitInit(cwd, message = "Initial commit") {
|
|
2867
|
+
await gitCommand("git init", cwd);
|
|
2868
|
+
await gitCommand("git add .", cwd);
|
|
2869
|
+
await gitCommand(`git commit -m "${message}"`, cwd);
|
|
2870
|
+
}
|
|
2871
|
+
async function gitAddRemoteAndPush(cwd, cloneUrl, branch = "main") {
|
|
2872
|
+
await gitCommand(`git remote add origin ${cloneUrl}`, cwd);
|
|
2873
|
+
await gitCommand(`git push -u origin ${branch}`, cwd);
|
|
2874
|
+
}
|
|
2875
|
+
async function gitCommitAndPush(cwd, message, branch = "main") {
|
|
2876
|
+
await gitCommand("git add .", cwd);
|
|
2877
|
+
await gitCommand(`git commit -m "${message}"`, cwd);
|
|
2878
|
+
await gitCommand(`git push origin ${branch}`, cwd);
|
|
2879
|
+
}
|
|
2960
2880
|
function isGitHubUrl(url) {
|
|
2961
2881
|
try {
|
|
2962
2882
|
const parsedUrl = new URL(url);
|
|
@@ -2971,6 +2891,22 @@ function isGitHubUrl(url) {
|
|
|
2971
2891
|
return false;
|
|
2972
2892
|
}
|
|
2973
2893
|
|
|
2894
|
+
// src/utils/cloud-urls.ts
|
|
2895
|
+
var GATEWAY_DOMAIN = "run.mcp-use.com";
|
|
2896
|
+
function buildGatewayUrl(slugOrId) {
|
|
2897
|
+
return `https://${slugOrId}.${GATEWAY_DOMAIN}/mcp`;
|
|
2898
|
+
}
|
|
2899
|
+
function getMcpServerUrl(deployment) {
|
|
2900
|
+
if (deployment.mcpUrl) return deployment.mcpUrl;
|
|
2901
|
+
if (deployment.serverId) return buildGatewayUrl(deployment.serverId);
|
|
2902
|
+
return "";
|
|
2903
|
+
}
|
|
2904
|
+
function getMcpServerUrlForCloudServer(server) {
|
|
2905
|
+
if (server.mcpUrl) return server.mcpUrl;
|
|
2906
|
+
const hostKey = server.slug && server.slug.trim() || server.id;
|
|
2907
|
+
return buildGatewayUrl(hostKey);
|
|
2908
|
+
}
|
|
2909
|
+
|
|
2974
2910
|
// src/utils/project-link.ts
|
|
2975
2911
|
var import_node_fs6 = require("fs");
|
|
2976
2912
|
var import_node_path4 = __toESM(require("path"), 1);
|
|
@@ -3017,10 +2953,6 @@ ${MCP_USE_DIR}
|
|
|
3017
2953
|
}
|
|
3018
2954
|
|
|
3019
2955
|
// src/commands/deploy.ts
|
|
3020
|
-
var GATEWAY_DOMAIN = "run.mcp-use.com";
|
|
3021
|
-
function buildGatewayUrl(slugOrId) {
|
|
3022
|
-
return `https://${slugOrId}.${GATEWAY_DOMAIN}/mcp`;
|
|
3023
|
-
}
|
|
3024
2956
|
async function parseEnvFile(filePath) {
|
|
3025
2957
|
try {
|
|
3026
2958
|
const content = await import_node_fs7.promises.readFile(filePath, "utf-8");
|
|
@@ -3030,9 +2962,7 @@ async function parseEnvFile(filePath) {
|
|
|
3030
2962
|
let currentValue = "";
|
|
3031
2963
|
for (let line of lines) {
|
|
3032
2964
|
line = line.trim();
|
|
3033
|
-
if (!line || line.startsWith("#"))
|
|
3034
|
-
continue;
|
|
3035
|
-
}
|
|
2965
|
+
if (!line || line.startsWith("#")) continue;
|
|
3036
2966
|
if (currentKey && !line.includes("=")) {
|
|
3037
2967
|
currentValue += "\n" + line;
|
|
3038
2968
|
continue;
|
|
@@ -3043,20 +2973,15 @@ async function parseEnvFile(filePath) {
|
|
|
3043
2973
|
currentValue = "";
|
|
3044
2974
|
}
|
|
3045
2975
|
const equalIndex = line.indexOf("=");
|
|
3046
|
-
if (equalIndex === -1)
|
|
3047
|
-
continue;
|
|
3048
|
-
}
|
|
2976
|
+
if (equalIndex === -1) continue;
|
|
3049
2977
|
const key = line.substring(0, equalIndex).trim();
|
|
3050
|
-
|
|
2978
|
+
const value = line.substring(equalIndex + 1).trim();
|
|
3051
2979
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
3052
|
-
console.log(
|
|
3053
|
-
source_default.yellow(`\u26A0\uFE0F Skipping invalid environment variable key: ${key}`)
|
|
3054
|
-
);
|
|
2980
|
+
console.log(source_default.yellow(`\u26A0\uFE0F Skipping invalid env key: ${key}`));
|
|
3055
2981
|
continue;
|
|
3056
2982
|
}
|
|
3057
2983
|
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
3058
|
-
|
|
3059
|
-
envVars[key] = value;
|
|
2984
|
+
envVars[key] = value.slice(1, -1);
|
|
3060
2985
|
} else if (value.startsWith('"') || value.startsWith("'")) {
|
|
3061
2986
|
currentKey = key;
|
|
3062
2987
|
currentValue = value.slice(1);
|
|
@@ -3080,16 +3005,12 @@ async function parseEnvFile(filePath) {
|
|
|
3080
3005
|
function parseEnvVar(envStr) {
|
|
3081
3006
|
const equalIndex = envStr.indexOf("=");
|
|
3082
3007
|
if (equalIndex === -1) {
|
|
3083
|
-
throw new Error(
|
|
3084
|
-
`Invalid environment variable format: "${envStr}". Expected KEY=VALUE`
|
|
3085
|
-
);
|
|
3008
|
+
throw new Error(`Invalid env format: "${envStr}". Expected KEY=VALUE`);
|
|
3086
3009
|
}
|
|
3087
3010
|
const key = envStr.substring(0, equalIndex).trim();
|
|
3088
3011
|
const value = envStr.substring(equalIndex + 1);
|
|
3089
3012
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
3090
|
-
throw new Error(
|
|
3091
|
-
`Invalid environment variable key: "${key}". Keys must start with a letter or underscore and contain only letters, numbers, and underscores.`
|
|
3092
|
-
);
|
|
3013
|
+
throw new Error(`Invalid env key: "${key}".`);
|
|
3093
3014
|
}
|
|
3094
3015
|
return { key, value };
|
|
3095
3016
|
}
|
|
@@ -3132,72 +3053,48 @@ async function buildEnvVars(options) {
|
|
|
3132
3053
|
}
|
|
3133
3054
|
async function isMcpProject(cwd = process.cwd()) {
|
|
3134
3055
|
try {
|
|
3135
|
-
const
|
|
3136
|
-
const
|
|
3137
|
-
|
|
3138
|
-
const hasMcpDeps = packageJson2.dependencies?.["mcp-use"] || packageJson2.dependencies?.["@modelcontextprotocol/sdk"] || packageJson2.devDependencies?.["mcp-use"] || packageJson2.devDependencies?.["@modelcontextprotocol/sdk"];
|
|
3139
|
-
const hasMcpScripts = packageJson2.scripts?.mcp || packageJson2.scripts?.["mcp:dev"];
|
|
3140
|
-
return !!(hasMcpDeps || hasMcpScripts);
|
|
3056
|
+
const content = await import_node_fs7.promises.readFile(import_node_path5.default.join(cwd, "package.json"), "utf-8");
|
|
3057
|
+
const pkg = JSON.parse(content);
|
|
3058
|
+
return !!(pkg.dependencies?.["mcp-use"] || pkg.dependencies?.["@modelcontextprotocol/sdk"] || pkg.devDependencies?.["mcp-use"] || pkg.devDependencies?.["@modelcontextprotocol/sdk"]);
|
|
3141
3059
|
} catch {
|
|
3142
3060
|
return false;
|
|
3143
3061
|
}
|
|
3144
3062
|
}
|
|
3145
3063
|
async function getProjectName(cwd = process.cwd()) {
|
|
3146
3064
|
try {
|
|
3147
|
-
const
|
|
3148
|
-
const
|
|
3149
|
-
|
|
3150
|
-
if (packageJson2.name) {
|
|
3151
|
-
return packageJson2.name;
|
|
3152
|
-
}
|
|
3065
|
+
const content = await import_node_fs7.promises.readFile(import_node_path5.default.join(cwd, "package.json"), "utf-8");
|
|
3066
|
+
const pkg = JSON.parse(content);
|
|
3067
|
+
if (pkg.name) return pkg.name;
|
|
3153
3068
|
} catch {
|
|
3154
3069
|
}
|
|
3155
3070
|
return import_node_path5.default.basename(cwd);
|
|
3156
3071
|
}
|
|
3157
|
-
async function detectBuildCommand(cwd
|
|
3072
|
+
async function detectBuildCommand(cwd) {
|
|
3158
3073
|
try {
|
|
3159
|
-
const
|
|
3160
|
-
|
|
3161
|
-
const packageJson2 = JSON.parse(content);
|
|
3162
|
-
if (packageJson2.scripts?.build) {
|
|
3163
|
-
return "npm run build";
|
|
3164
|
-
}
|
|
3074
|
+
const content = await import_node_fs7.promises.readFile(import_node_path5.default.join(cwd, "package.json"), "utf-8");
|
|
3075
|
+
if (JSON.parse(content).scripts?.build) return "npm run build";
|
|
3165
3076
|
} catch {
|
|
3166
3077
|
}
|
|
3167
3078
|
return void 0;
|
|
3168
3079
|
}
|
|
3169
|
-
async function detectStartCommand(cwd
|
|
3080
|
+
async function detectStartCommand(cwd) {
|
|
3170
3081
|
try {
|
|
3171
|
-
const
|
|
3172
|
-
const
|
|
3173
|
-
|
|
3174
|
-
if (
|
|
3175
|
-
return "npm start";
|
|
3176
|
-
}
|
|
3177
|
-
if (packageJson2.main) {
|
|
3178
|
-
return `node ${packageJson2.main}`;
|
|
3179
|
-
}
|
|
3082
|
+
const content = await import_node_fs7.promises.readFile(import_node_path5.default.join(cwd, "package.json"), "utf-8");
|
|
3083
|
+
const pkg = JSON.parse(content);
|
|
3084
|
+
if (pkg.scripts?.start) return "npm start";
|
|
3085
|
+
if (pkg.main) return `node ${pkg.main}`;
|
|
3180
3086
|
} catch {
|
|
3181
3087
|
}
|
|
3182
3088
|
return void 0;
|
|
3183
3089
|
}
|
|
3184
|
-
async function detectRuntime(cwd
|
|
3185
|
-
|
|
3186
|
-
const pythonFiles = ["requirements.txt", "pyproject.toml", "setup.py"];
|
|
3187
|
-
for (const file of pythonFiles) {
|
|
3188
|
-
try {
|
|
3189
|
-
await import_node_fs7.promises.access(import_node_path5.default.join(cwd, file));
|
|
3190
|
-
return "python";
|
|
3191
|
-
} catch {
|
|
3192
|
-
continue;
|
|
3193
|
-
}
|
|
3194
|
-
}
|
|
3090
|
+
async function detectRuntime(cwd) {
|
|
3091
|
+
for (const f of ["requirements.txt", "pyproject.toml", "setup.py"]) {
|
|
3195
3092
|
try {
|
|
3196
|
-
await import_node_fs7.promises.access(import_node_path5.default.join(cwd,
|
|
3197
|
-
return "
|
|
3093
|
+
await import_node_fs7.promises.access(import_node_path5.default.join(cwd, f));
|
|
3094
|
+
return "python";
|
|
3198
3095
|
} catch {
|
|
3096
|
+
continue;
|
|
3199
3097
|
}
|
|
3200
|
-
} catch {
|
|
3201
3098
|
}
|
|
3202
3099
|
return "node";
|
|
3203
3100
|
}
|
|
@@ -3207,50 +3104,64 @@ async function prompt(question, defaultValue = "n") {
|
|
|
3207
3104
|
input: process.stdin,
|
|
3208
3105
|
output: process.stdout
|
|
3209
3106
|
});
|
|
3210
|
-
const
|
|
3211
|
-
const
|
|
3212
|
-
/(\(y\/n\):)/,
|
|
3213
|
-
`(${defaultIndicator}):`
|
|
3214
|
-
);
|
|
3107
|
+
const indicator = defaultValue === "y" ? "Y/n" : "y/N";
|
|
3108
|
+
const q = question.replace(/(\(y\/n\):)/, `(${indicator}):`);
|
|
3215
3109
|
return new Promise((resolve2) => {
|
|
3216
|
-
rl.question(
|
|
3110
|
+
rl.question(q, (answer) => {
|
|
3217
3111
|
rl.close();
|
|
3218
|
-
const
|
|
3219
|
-
if (
|
|
3220
|
-
|
|
3221
|
-
} else {
|
|
3222
|
-
resolve2(trimmedAnswer === "y" || trimmedAnswer === "yes");
|
|
3223
|
-
}
|
|
3112
|
+
const a = answer.trim().toLowerCase();
|
|
3113
|
+
if (a === "") resolve2(defaultValue === "y");
|
|
3114
|
+
else resolve2(a === "y" || a === "yes");
|
|
3224
3115
|
});
|
|
3225
3116
|
});
|
|
3226
3117
|
}
|
|
3227
|
-
function
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
}
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3118
|
+
async function promptText(question, defaultValue) {
|
|
3119
|
+
const readline = await import("readline");
|
|
3120
|
+
const rl = readline.createInterface({
|
|
3121
|
+
input: process.stdin,
|
|
3122
|
+
output: process.stdout
|
|
3123
|
+
});
|
|
3124
|
+
const suffix = defaultValue ? source_default.gray(` [${defaultValue}]`) : "";
|
|
3125
|
+
return new Promise((resolve2) => {
|
|
3126
|
+
rl.question(question + suffix + " ", (answer) => {
|
|
3127
|
+
rl.close();
|
|
3128
|
+
resolve2(answer.trim() || defaultValue || "");
|
|
3129
|
+
});
|
|
3130
|
+
});
|
|
3131
|
+
}
|
|
3132
|
+
var REQUIRED_IGNORES = [
|
|
3133
|
+
"node_modules",
|
|
3134
|
+
"dist",
|
|
3135
|
+
".env",
|
|
3136
|
+
".env.local",
|
|
3137
|
+
".mcp-use"
|
|
3138
|
+
];
|
|
3139
|
+
async function ensureGitignore(cwd) {
|
|
3140
|
+
const gitignorePath = import_node_path5.default.join(cwd, ".gitignore");
|
|
3141
|
+
let content = "";
|
|
3142
|
+
try {
|
|
3143
|
+
content = await import_node_fs7.promises.readFile(gitignorePath, "utf-8");
|
|
3144
|
+
} catch {
|
|
3145
|
+
}
|
|
3146
|
+
const missing = REQUIRED_IGNORES.filter((entry) => !content.includes(entry));
|
|
3147
|
+
if (missing.length > 0) {
|
|
3148
|
+
const additions = missing.join("\n");
|
|
3149
|
+
const newContent = content + (content.endsWith("\n") ? "" : "\n") + additions + "\n";
|
|
3150
|
+
await import_node_fs7.promises.writeFile(gitignorePath, newContent, "utf-8");
|
|
3236
3151
|
}
|
|
3237
3152
|
}
|
|
3238
|
-
async function displayDeploymentProgress(api,
|
|
3153
|
+
async function displayDeploymentProgress(api, deploymentId, progressOptions) {
|
|
3239
3154
|
const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
3240
3155
|
let frameIndex = 0;
|
|
3241
3156
|
let spinnerInterval = null;
|
|
3242
|
-
let lastStep = "";
|
|
3243
3157
|
const startSpinner = (message) => {
|
|
3244
|
-
if (spinnerInterval)
|
|
3245
|
-
clearInterval(spinnerInterval);
|
|
3246
|
-
}
|
|
3158
|
+
if (spinnerInterval) clearInterval(spinnerInterval);
|
|
3247
3159
|
process.stdout.write("\r\x1B[K");
|
|
3248
3160
|
spinnerInterval = setInterval(() => {
|
|
3249
|
-
const frame = frames[frameIndex];
|
|
3250
|
-
frameIndex = (frameIndex + 1) % frames.length;
|
|
3251
3161
|
process.stdout.write(
|
|
3252
|
-
"\r" + source_default.cyan(
|
|
3162
|
+
"\r" + source_default.cyan(frames[frameIndex]) + " " + source_default.gray(message)
|
|
3253
3163
|
);
|
|
3164
|
+
frameIndex = (frameIndex + 1) % frames.length;
|
|
3254
3165
|
}, 80);
|
|
3255
3166
|
};
|
|
3256
3167
|
const stopSpinner = () => {
|
|
@@ -3262,82 +3173,56 @@ async function displayDeploymentProgress(api, deployment, progressOptions) {
|
|
|
3262
3173
|
};
|
|
3263
3174
|
console.log();
|
|
3264
3175
|
startSpinner("Deploying...");
|
|
3265
|
-
try {
|
|
3266
|
-
for await (const log of api.streamDeploymentLogs(deployment.id)) {
|
|
3267
|
-
try {
|
|
3268
|
-
const logData = JSON.parse(log);
|
|
3269
|
-
if (logData.step && logData.step !== lastStep) {
|
|
3270
|
-
lastStep = logData.step;
|
|
3271
|
-
const stepMessages = {
|
|
3272
|
-
clone: "Preparing source code...",
|
|
3273
|
-
analyze: "Analyzing project...",
|
|
3274
|
-
build: "Building container image...",
|
|
3275
|
-
deploy: "Deploying to cloud..."
|
|
3276
|
-
};
|
|
3277
|
-
const message = stepMessages[logData.step] || "Deploying...";
|
|
3278
|
-
startSpinner(message);
|
|
3279
|
-
}
|
|
3280
|
-
if (logData.line) {
|
|
3281
|
-
stopSpinner();
|
|
3282
|
-
const levelColor = logData.level === "error" ? source_default.red : logData.level === "warn" ? source_default.yellow : source_default.gray;
|
|
3283
|
-
const stepPrefix = logData.step ? source_default.cyan(`[${logData.step}]`) + " " : "";
|
|
3284
|
-
console.log(stepPrefix + levelColor(logData.line));
|
|
3285
|
-
}
|
|
3286
|
-
} catch {
|
|
3287
|
-
}
|
|
3288
|
-
}
|
|
3289
|
-
} catch (error) {
|
|
3290
|
-
stopSpinner();
|
|
3291
|
-
}
|
|
3292
3176
|
let checkCount = 0;
|
|
3293
|
-
const maxChecks =
|
|
3294
|
-
let delay =
|
|
3177
|
+
const maxChecks = 120;
|
|
3178
|
+
let delay = 2e3;
|
|
3295
3179
|
const maxDelay = 1e4;
|
|
3296
|
-
let
|
|
3180
|
+
let buildLogOffset = 0;
|
|
3297
3181
|
while (checkCount < maxChecks) {
|
|
3298
|
-
const
|
|
3299
|
-
await new Promise((
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
const
|
|
3303
|
-
|
|
3182
|
+
const waitMs = delay;
|
|
3183
|
+
await new Promise((r) => setTimeout(r, waitMs));
|
|
3184
|
+
checkCount++;
|
|
3185
|
+
try {
|
|
3186
|
+
const resp = await api.getDeploymentBuildLogs(
|
|
3187
|
+
deploymentId,
|
|
3188
|
+
buildLogOffset
|
|
3304
3189
|
);
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3190
|
+
if (resp.logs.length > 0) {
|
|
3191
|
+
for (const line of resp.logs.split("\n").filter((l) => l.trim())) {
|
|
3192
|
+
try {
|
|
3193
|
+
const d = JSON.parse(line);
|
|
3194
|
+
if (d.line) {
|
|
3195
|
+
stopSpinner();
|
|
3196
|
+
const color = d.level === "error" ? source_default.red : d.level === "warn" ? source_default.yellow : source_default.gray;
|
|
3197
|
+
const prefix = d.step ? source_default.cyan(`[${d.step}]`) + " " : "";
|
|
3198
|
+
console.log(prefix + color(d.line));
|
|
3199
|
+
}
|
|
3200
|
+
} catch {
|
|
3310
3201
|
stopSpinner();
|
|
3311
|
-
|
|
3312
|
-
const stepPrefix = logData.step ? source_default.cyan(`[${logData.step}]`) + " " : "";
|
|
3313
|
-
console.log(stepPrefix + levelColor(logData.line));
|
|
3202
|
+
console.log(source_default.gray(line));
|
|
3314
3203
|
}
|
|
3315
|
-
} catch {
|
|
3316
3204
|
}
|
|
3205
|
+
buildLogOffset = resp.offset;
|
|
3317
3206
|
}
|
|
3318
|
-
|
|
3207
|
+
} catch {
|
|
3319
3208
|
}
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3209
|
+
const dep = await api.getDeployment(deploymentId);
|
|
3210
|
+
if (dep.status === "running") {
|
|
3211
|
+
stopSpinner();
|
|
3212
|
+
const mcpUrl = getMcpServerUrl(dep);
|
|
3323
3213
|
const webUrl = (await getWebUrl()).replace(/\/$/, "");
|
|
3324
3214
|
const config = await readConfig();
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
if (orgSlug) {
|
|
3329
|
-
dashboardUrl = `${webUrl}/cloud/${orgSlug}/servers/${serverRef}`;
|
|
3330
|
-
} else {
|
|
3331
|
-
dashboardUrl = `${webUrl}/cloud/servers/${serverRef}`;
|
|
3332
|
-
}
|
|
3215
|
+
let dashboardUrl = null;
|
|
3216
|
+
if (dep.serverId) {
|
|
3217
|
+
dashboardUrl = config.orgSlug ? `${webUrl}/cloud/${config.orgSlug}/servers/${dep.serverId}` : `${webUrl}/cloud/servers/${dep.serverId}`;
|
|
3333
3218
|
}
|
|
3334
|
-
const inspectorUrl = `https://inspector.manufact.com/inspector?autoConnect=${encodeURIComponent(
|
|
3335
|
-
mcpServerUrl
|
|
3336
|
-
)}`;
|
|
3219
|
+
const inspectorUrl = `https://inspector.manufact.com/inspector?autoConnect=${encodeURIComponent(mcpUrl)}`;
|
|
3337
3220
|
console.log(source_default.green.bold("\u2713 Deployment successful!\n"));
|
|
3338
|
-
|
|
3339
|
-
|
|
3221
|
+
if (mcpUrl) {
|
|
3222
|
+
console.log(source_default.white("\u{1F310} MCP Server URL:"));
|
|
3223
|
+
console.log(source_default.cyan.bold(` ${mcpUrl}
|
|
3340
3224
|
`));
|
|
3225
|
+
}
|
|
3341
3226
|
if (dashboardUrl) {
|
|
3342
3227
|
console.log(source_default.white("\u{1F4CA} Dashboard:"));
|
|
3343
3228
|
console.log(source_default.cyan.bold(` ${dashboardUrl}
|
|
@@ -3346,169 +3231,76 @@ async function displayDeploymentProgress(api, deployment, progressOptions) {
|
|
|
3346
3231
|
console.log(source_default.white("\u{1F50D} Inspector URL:"));
|
|
3347
3232
|
console.log(source_default.cyan.bold(` ${inspectorUrl}
|
|
3348
3233
|
`));
|
|
3349
|
-
console.log(
|
|
3350
|
-
source_default.gray("Deployment ID: ") + source_default.white(finalDeployment.id)
|
|
3351
|
-
);
|
|
3234
|
+
console.log(source_default.gray("Deployment ID: ") + source_default.white(dep.id));
|
|
3352
3235
|
return;
|
|
3353
|
-
} else if (
|
|
3236
|
+
} else if (dep.status === "failed") {
|
|
3354
3237
|
stopSpinner();
|
|
3355
3238
|
console.log(source_default.red.bold("\u2717 Deployment failed\n"));
|
|
3356
|
-
if (
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
)
|
|
3374
|
-
return;
|
|
3375
|
-
}
|
|
3376
|
-
} else if (finalDeployment.error.includes("Authenticated git clone failed")) {
|
|
3377
|
-
let repoName;
|
|
3378
|
-
const repoMatch = finalDeployment.error.match(
|
|
3379
|
-
/github\.com\/([^/]+\/[^/\s]+)/
|
|
3380
|
-
);
|
|
3381
|
-
if (repoMatch) {
|
|
3382
|
-
repoName = repoMatch[1].replace(/\.git$/, "");
|
|
3383
|
-
} else if (finalDeployment.source.type === "github") {
|
|
3384
|
-
repoName = finalDeployment.source.repo;
|
|
3385
|
-
}
|
|
3386
|
-
console.log();
|
|
3387
|
-
const retry = await promptGitHubInstallation(
|
|
3388
|
-
api,
|
|
3389
|
-
"no_access",
|
|
3390
|
-
repoName,
|
|
3391
|
-
{ yes: progressOptions?.yes }
|
|
3239
|
+
if (dep.error) {
|
|
3240
|
+
const internalPatterns = [
|
|
3241
|
+
"GraphQL",
|
|
3242
|
+
"authenticated",
|
|
3243
|
+
"INTERNAL",
|
|
3244
|
+
"Fly API",
|
|
3245
|
+
"token validation",
|
|
3246
|
+
"context deadline",
|
|
3247
|
+
"Bad gateway",
|
|
3248
|
+
"502",
|
|
3249
|
+
"503"
|
|
3250
|
+
];
|
|
3251
|
+
const isInternalError = internalPatterns.some(
|
|
3252
|
+
(p) => dep.error.includes(p)
|
|
3253
|
+
);
|
|
3254
|
+
if (isInternalError) {
|
|
3255
|
+
console.log(
|
|
3256
|
+
source_default.red("Error: ") + "An internal infrastructure error occurred. Please try again."
|
|
3392
3257
|
);
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
await displayDeploymentProgress(
|
|
3397
|
-
api,
|
|
3398
|
-
newDeployment,
|
|
3399
|
-
progressOptions
|
|
3400
|
-
);
|
|
3401
|
-
return;
|
|
3402
|
-
}
|
|
3403
|
-
}
|
|
3404
|
-
}
|
|
3405
|
-
if (finalDeployment.buildLogs) {
|
|
3406
|
-
console.log(source_default.gray("\nBuild logs:"));
|
|
3407
|
-
try {
|
|
3408
|
-
const logs = finalDeployment.buildLogs.split("\n").filter((l) => l.trim());
|
|
3409
|
-
for (const log of logs) {
|
|
3410
|
-
try {
|
|
3411
|
-
const logData = JSON.parse(log);
|
|
3412
|
-
if (logData.line) {
|
|
3413
|
-
console.log(source_default.gray(` ${logData.line}`));
|
|
3414
|
-
}
|
|
3415
|
-
} catch {
|
|
3416
|
-
console.log(source_default.gray(` ${log}`));
|
|
3417
|
-
}
|
|
3418
|
-
}
|
|
3419
|
-
} catch {
|
|
3420
|
-
console.log(source_default.gray(finalDeployment.buildLogs));
|
|
3258
|
+
console.log(source_default.gray(" Details: " + dep.error));
|
|
3259
|
+
} else {
|
|
3260
|
+
console.log(source_default.red("Error: ") + dep.error);
|
|
3421
3261
|
}
|
|
3422
3262
|
}
|
|
3423
3263
|
process.exit(1);
|
|
3424
|
-
} else if (
|
|
3264
|
+
} else if (dep.status === "building" || dep.status === "pending") {
|
|
3425
3265
|
startSpinner("Building and deploying...");
|
|
3426
|
-
checkCount++;
|
|
3427
3266
|
delay = Math.min(delay * 1.2, maxDelay);
|
|
3428
3267
|
} else {
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
);
|
|
3268
|
+
stopSpinner();
|
|
3269
|
+
console.log(source_default.yellow("\u26A0\uFE0F Deployment status: ") + dep.status);
|
|
3432
3270
|
return;
|
|
3433
3271
|
}
|
|
3434
3272
|
}
|
|
3435
3273
|
stopSpinner();
|
|
3436
3274
|
console.log(source_default.yellow("\u26A0\uFE0F Deployment is taking longer than expected."));
|
|
3437
3275
|
console.log(
|
|
3438
|
-
source_default.gray("Check status with: ") + source_default.white(`mcp-use
|
|
3276
|
+
source_default.gray("Check status with: ") + source_default.white(`mcp-use deployments get ${deploymentId}`)
|
|
3439
3277
|
);
|
|
3440
3278
|
}
|
|
3441
3279
|
async function checkRepoAccess(api, owner, repo) {
|
|
3442
3280
|
try {
|
|
3443
|
-
const
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
} catch (error) {
|
|
3447
|
-
console.log(source_default.gray("Could not verify repository access"));
|
|
3281
|
+
const resp = await api.getGitHubRepos(true);
|
|
3282
|
+
return resp.repos.some((r) => r.full_name === `${owner}/${repo}`);
|
|
3283
|
+
} catch {
|
|
3448
3284
|
return false;
|
|
3449
3285
|
}
|
|
3450
3286
|
}
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
if (
|
|
3455
|
-
console.log(source_default.
|
|
3456
|
-
|
|
3457
|
-
source_default.white("
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
while (Date.now() < deadline) {
|
|
3469
|
-
try {
|
|
3470
|
-
const status = await api.getGitHubConnectionStatus();
|
|
3471
|
-
if (!status.is_connected) {
|
|
3472
|
-
await new Promise((r) => setTimeout(r, GITHUB_SETUP_POLL_INTERVAL_MS));
|
|
3473
|
-
continue;
|
|
3474
|
-
}
|
|
3475
|
-
if (repoName) {
|
|
3476
|
-
const parts = repoName.split("/");
|
|
3477
|
-
const owner = parts[0];
|
|
3478
|
-
const repo = parts[1];
|
|
3479
|
-
if (owner && repo && await checkRepoAccess(api, owner, repo)) {
|
|
3480
|
-
return;
|
|
3481
|
-
}
|
|
3482
|
-
} else {
|
|
3483
|
-
return;
|
|
3484
|
-
}
|
|
3485
|
-
} catch {
|
|
3486
|
-
}
|
|
3487
|
-
await new Promise((r) => setTimeout(r, GITHUB_SETUP_POLL_INTERVAL_MS));
|
|
3488
|
-
}
|
|
3489
|
-
console.log(
|
|
3490
|
-
source_default.yellow(
|
|
3491
|
-
"\u26A0\uFE0F Timed out waiting for GitHub setup. Continuing with verification..."
|
|
3492
|
-
)
|
|
3493
|
-
);
|
|
3494
|
-
}
|
|
3495
|
-
async function promptGitHubInstallation(api, reason, repoName, opts) {
|
|
3496
|
-
const yes = !!opts?.yes;
|
|
3497
|
-
console.log();
|
|
3498
|
-
if (reason === "not_connected") {
|
|
3499
|
-
console.log(source_default.yellow("\u26A0\uFE0F GitHub account not connected"));
|
|
3500
|
-
console.log(
|
|
3501
|
-
source_default.white("Deployments require a connected GitHub account.\n")
|
|
3502
|
-
);
|
|
3503
|
-
} else {
|
|
3504
|
-
console.log(
|
|
3505
|
-
source_default.yellow("\u26A0\uFE0F GitHub App doesn't have access to this repository")
|
|
3506
|
-
);
|
|
3507
|
-
console.log(
|
|
3508
|
-
source_default.white(
|
|
3509
|
-
`The GitHub App needs permission to access ${source_default.cyan(repoName || "this repository")}.
|
|
3510
|
-
`
|
|
3511
|
-
)
|
|
3287
|
+
async function promptGitHubInstallation(api, reason, repoName, opts) {
|
|
3288
|
+
const yes = !!opts?.yes;
|
|
3289
|
+
console.log();
|
|
3290
|
+
if (reason === "not_connected") {
|
|
3291
|
+
console.log(source_default.yellow("\u26A0\uFE0F GitHub account not connected"));
|
|
3292
|
+
console.log(
|
|
3293
|
+
source_default.white("Deployments require a connected GitHub account.\n")
|
|
3294
|
+
);
|
|
3295
|
+
} else {
|
|
3296
|
+
console.log(
|
|
3297
|
+
source_default.yellow("\u26A0\uFE0F GitHub App doesn't have access to this repository")
|
|
3298
|
+
);
|
|
3299
|
+
console.log(
|
|
3300
|
+
source_default.white(
|
|
3301
|
+
`The GitHub App needs permission to access ${source_default.cyan(repoName || "this repository")}.
|
|
3302
|
+
`
|
|
3303
|
+
)
|
|
3512
3304
|
);
|
|
3513
3305
|
}
|
|
3514
3306
|
const shouldInstall = yes ? true : await prompt(
|
|
@@ -3517,96 +3309,48 @@ async function promptGitHubInstallation(api, reason, repoName, opts) {
|
|
|
3517
3309
|
),
|
|
3518
3310
|
"y"
|
|
3519
3311
|
);
|
|
3520
|
-
if (!shouldInstall)
|
|
3521
|
-
return false;
|
|
3522
|
-
}
|
|
3312
|
+
if (!shouldInstall) return false;
|
|
3523
3313
|
try {
|
|
3524
|
-
const appName =
|
|
3525
|
-
const installUrl =
|
|
3526
|
-
console.log(
|
|
3527
|
-
|
|
3528
|
-
`
|
|
3529
|
-
Opening browser to ${reason === "not_connected" ? "install" : "configure"} GitHub App...`
|
|
3530
|
-
)
|
|
3531
|
-
);
|
|
3314
|
+
const appName = await api.getGitHubAppName();
|
|
3315
|
+
const installUrl = `https://github.com/apps/${appName}/installations/new`;
|
|
3316
|
+
console.log(source_default.cyan(`
|
|
3317
|
+
Opening browser...`));
|
|
3532
3318
|
console.log(source_default.gray(`URL: ${installUrl}
|
|
3533
3319
|
`));
|
|
3534
3320
|
if (reason === "no_access") {
|
|
3535
|
-
console.log(source_default.white("Please:"));
|
|
3536
3321
|
console.log(
|
|
3537
|
-
source_default.cyan("
|
|
3322
|
+
source_default.white("Please add ") + source_default.cyan.bold(repoName || "your repository") + source_default.white(" to the app's repository access, then return here.\n")
|
|
3538
3323
|
);
|
|
3539
|
-
|
|
3324
|
+
} else {
|
|
3540
3325
|
console.log(
|
|
3541
|
-
source_default.
|
|
3542
|
-
` 3. Grant access to ${source_default.bold(repoName || "your repository")}`
|
|
3543
|
-
)
|
|
3326
|
+
source_default.white("Complete the GitHub App installation, then return here.\n")
|
|
3544
3327
|
);
|
|
3545
|
-
console.log(source_default.cyan(" 4. Save your changes"));
|
|
3546
|
-
console.log(source_default.cyan(" 5. Return here when done\n"));
|
|
3547
|
-
} else {
|
|
3548
|
-
console.log(source_default.white("Please:"));
|
|
3549
|
-
console.log(source_default.cyan(" 1. Select the repositories to grant access"));
|
|
3550
|
-
if (repoName) {
|
|
3551
|
-
console.log(
|
|
3552
|
-
source_default.cyan(` 2. Make sure to include ${source_default.bold(repoName)}`)
|
|
3553
|
-
);
|
|
3554
|
-
console.log(source_default.cyan(" 3. Complete the installation"));
|
|
3555
|
-
} else {
|
|
3556
|
-
console.log(source_default.cyan(" 2. Complete the installation"));
|
|
3557
|
-
}
|
|
3558
|
-
console.log();
|
|
3559
3328
|
}
|
|
3560
3329
|
await open_default(installUrl);
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
const
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
)
|
|
3577
|
-
);
|
|
3578
|
-
} else {
|
|
3579
|
-
console.log(source_default.green(`\u2713 Repository ${repoName} is accessible!
|
|
3580
|
-
`));
|
|
3581
|
-
verified = true;
|
|
3330
|
+
if (!yes) {
|
|
3331
|
+
await prompt(source_default.white("Press Enter when done..."), "y");
|
|
3332
|
+
} else {
|
|
3333
|
+
console.log(source_default.gray("Waiting for GitHub configuration (polling)..."));
|
|
3334
|
+
const deadline = Date.now() + 12e4;
|
|
3335
|
+
while (Date.now() < deadline) {
|
|
3336
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
3337
|
+
try {
|
|
3338
|
+
const status = await api.getGitHubConnectionStatus();
|
|
3339
|
+
if (status.is_connected) {
|
|
3340
|
+
if (!repoName) return true;
|
|
3341
|
+
const [o, r] = repoName.split("/");
|
|
3342
|
+
if (o && r && await checkRepoAccess(api, o, r)) return true;
|
|
3343
|
+
}
|
|
3344
|
+
} catch {
|
|
3582
3345
|
}
|
|
3583
|
-
} else {
|
|
3584
|
-
console.log(source_default.green("\u2713 GitHub connected successfully!\n"));
|
|
3585
|
-
verified = true;
|
|
3586
3346
|
}
|
|
3587
|
-
} catch (error) {
|
|
3588
|
-
console.log(
|
|
3589
|
-
source_default.yellow("\u26A0\uFE0F Could not verify GitHub connection (API issue)")
|
|
3590
|
-
);
|
|
3591
|
-
}
|
|
3592
|
-
if (!verified) {
|
|
3593
|
-
console.log(
|
|
3594
|
-
source_default.gray(
|
|
3595
|
-
"\nNote: If you completed the GitHub setup, the deployment may work now.\n"
|
|
3596
|
-
)
|
|
3597
|
-
);
|
|
3598
3347
|
}
|
|
3599
3348
|
return true;
|
|
3600
|
-
} catch
|
|
3601
|
-
console.log(
|
|
3602
|
-
source_default.yellow("\n\u26A0\uFE0F Unable to open GitHub installation automatically")
|
|
3603
|
-
);
|
|
3349
|
+
} catch {
|
|
3350
|
+
console.log(source_default.yellow("\n\u26A0\uFE0F Unable to open browser automatically"));
|
|
3604
3351
|
console.log(
|
|
3605
3352
|
source_default.white("Please visit: ") + source_default.cyan("https://manufact.com/cloud/settings")
|
|
3606
3353
|
);
|
|
3607
|
-
console.log(
|
|
3608
|
-
source_default.gray("Then connect your GitHub account and try again.\n")
|
|
3609
|
-
);
|
|
3610
3354
|
return false;
|
|
3611
3355
|
}
|
|
3612
3356
|
}
|
|
@@ -3614,47 +3358,139 @@ async function deployCommand(options) {
|
|
|
3614
3358
|
try {
|
|
3615
3359
|
const cwd = process.cwd();
|
|
3616
3360
|
if (!await isLoggedIn()) {
|
|
3617
|
-
console.log(source_default.
|
|
3361
|
+
console.log(source_default.cyan.bold("Welcome to Manufact Cloud!\n"));
|
|
3618
3362
|
if (options.yes) {
|
|
3619
3363
|
console.log(
|
|
3620
|
-
source_default.
|
|
3621
|
-
"Run " + source_default.white("npx mcp-use login") + " first.
|
|
3364
|
+
source_default.red(
|
|
3365
|
+
"\u2717 Not logged in. Run " + source_default.white("npx mcp-use login") + " first."
|
|
3622
3366
|
)
|
|
3623
3367
|
);
|
|
3624
3368
|
process.exit(1);
|
|
3625
3369
|
}
|
|
3626
3370
|
const shouldLogin = await prompt(
|
|
3627
|
-
source_default.white("
|
|
3371
|
+
source_default.white("You need to log in to deploy. Log in now? (Y/n): "),
|
|
3628
3372
|
"y"
|
|
3629
3373
|
);
|
|
3630
|
-
if (shouldLogin) {
|
|
3631
|
-
try {
|
|
3632
|
-
await loginCommand({ silent: false });
|
|
3633
|
-
if (!await isLoggedIn()) {
|
|
3634
|
-
console.log(
|
|
3635
|
-
source_default.red("\u2717 Login verification failed. Please try again.")
|
|
3636
|
-
);
|
|
3637
|
-
process.exit(1);
|
|
3638
|
-
}
|
|
3639
|
-
console.log(source_default.gray("\nContinuing with deployment...\n"));
|
|
3640
|
-
} catch (error) {
|
|
3641
|
-
console.error(
|
|
3642
|
-
source_default.red.bold("\u2717 Login failed:"),
|
|
3643
|
-
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
3644
|
-
);
|
|
3645
|
-
process.exit(1);
|
|
3646
|
-
}
|
|
3647
|
-
} else {
|
|
3374
|
+
if (!shouldLogin) {
|
|
3648
3375
|
console.log(
|
|
3649
3376
|
source_default.gray(
|
|
3650
3377
|
"Run " + source_default.white("npx mcp-use login") + " to get started."
|
|
3651
3378
|
)
|
|
3652
3379
|
);
|
|
3380
|
+
process.exit(0);
|
|
3381
|
+
}
|
|
3382
|
+
try {
|
|
3383
|
+
await loginCommand({ silent: false });
|
|
3384
|
+
if (!await isLoggedIn()) {
|
|
3385
|
+
console.log(source_default.red("\u2717 Login failed. Please try again."));
|
|
3386
|
+
process.exit(1);
|
|
3387
|
+
}
|
|
3388
|
+
console.log(source_default.gray("\nContinuing with deployment...\n"));
|
|
3389
|
+
} catch (error) {
|
|
3390
|
+
console.error(
|
|
3391
|
+
source_default.red.bold("\u2717 Login failed:"),
|
|
3392
|
+
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
3393
|
+
);
|
|
3394
|
+
process.exit(1);
|
|
3395
|
+
}
|
|
3396
|
+
}
|
|
3397
|
+
const api = await McpUseAPI.create();
|
|
3398
|
+
if (options.org) {
|
|
3399
|
+
const authInfo = await api.testAuth();
|
|
3400
|
+
const match = (authInfo.orgs ?? []).find(
|
|
3401
|
+
(o) => o.slug === options.org || o.id === options.org || o.name.toLowerCase() === options.org.toLowerCase()
|
|
3402
|
+
);
|
|
3403
|
+
if (match) {
|
|
3404
|
+
api.setOrgId(match.id);
|
|
3405
|
+
const slug = match.slug ? source_default.gray(` (${match.slug})`) : "";
|
|
3406
|
+
console.log(
|
|
3407
|
+
source_default.gray("Organization: ") + source_default.cyan(match.name) + slug
|
|
3408
|
+
);
|
|
3409
|
+
} else {
|
|
3410
|
+
console.error(
|
|
3411
|
+
source_default.red(
|
|
3412
|
+
`\u2717 Organization "${options.org}" not found. Run ${source_default.white("npx mcp-use org list")} to see available organizations.`
|
|
3413
|
+
)
|
|
3414
|
+
);
|
|
3415
|
+
process.exit(1);
|
|
3416
|
+
}
|
|
3417
|
+
} else {
|
|
3418
|
+
const config = await readConfig();
|
|
3419
|
+
if (!config.orgId) {
|
|
3420
|
+
const authInfo = await api.testAuth();
|
|
3421
|
+
if (authInfo.orgs.length === 0) {
|
|
3422
|
+
console.log(
|
|
3423
|
+
source_default.red(
|
|
3424
|
+
"\u2717 No organizations found. Please create one at manufact.com/cloud."
|
|
3425
|
+
)
|
|
3426
|
+
);
|
|
3427
|
+
process.exit(1);
|
|
3428
|
+
}
|
|
3429
|
+
let selectedOrg;
|
|
3430
|
+
if (authInfo.orgs.length === 1) {
|
|
3431
|
+
selectedOrg = authInfo.orgs[0];
|
|
3432
|
+
} else {
|
|
3433
|
+
selectedOrg = await promptOrgSelection(
|
|
3434
|
+
authInfo.orgs,
|
|
3435
|
+
authInfo.default_org_id
|
|
3436
|
+
);
|
|
3437
|
+
}
|
|
3438
|
+
if (!selectedOrg) {
|
|
3439
|
+
console.log(source_default.red("\u2717 No organization selected."));
|
|
3440
|
+
process.exit(1);
|
|
3441
|
+
}
|
|
3442
|
+
api.setOrgId(selectedOrg.id);
|
|
3443
|
+
await writeConfig({
|
|
3444
|
+
...config,
|
|
3445
|
+
orgId: selectedOrg.id,
|
|
3446
|
+
orgName: selectedOrg.name,
|
|
3447
|
+
orgSlug: selectedOrg.slug ?? void 0
|
|
3448
|
+
});
|
|
3449
|
+
console.log(
|
|
3450
|
+
source_default.gray("Organization: ") + source_default.cyan(selectedOrg.name)
|
|
3451
|
+
);
|
|
3452
|
+
} else {
|
|
3453
|
+
if (config.orgName) {
|
|
3454
|
+
const slug = config.orgSlug ? source_default.gray(` (${config.orgSlug})`) : "";
|
|
3455
|
+
console.log(
|
|
3456
|
+
source_default.gray("Organization: ") + source_default.cyan(config.orgName) + slug
|
|
3457
|
+
);
|
|
3458
|
+
}
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
console.log(source_default.cyan.bold("\n\u{1F680} Deploying to Manufact cloud...\n"));
|
|
3462
|
+
let connectionStatus = await api.getGitHubConnectionStatus().catch(() => null);
|
|
3463
|
+
if (!connectionStatus?.is_connected) {
|
|
3464
|
+
const installed = await promptGitHubInstallation(
|
|
3465
|
+
api,
|
|
3466
|
+
"not_connected",
|
|
3467
|
+
void 0,
|
|
3468
|
+
{ yes: options.yes }
|
|
3469
|
+
);
|
|
3470
|
+
if (!installed) {
|
|
3653
3471
|
console.log(source_default.gray("Deployment cancelled."));
|
|
3654
3472
|
process.exit(0);
|
|
3655
3473
|
}
|
|
3474
|
+
connectionStatus = await api.getGitHubConnectionStatus().catch(() => null);
|
|
3475
|
+
if (!connectionStatus?.is_connected) {
|
|
3476
|
+
console.log(source_default.red("\n\u2717 GitHub connection could not be verified."));
|
|
3477
|
+
console.log(
|
|
3478
|
+
source_default.cyan(
|
|
3479
|
+
" Visit https://manufact.com/cloud/settings to connect GitHub.\n"
|
|
3480
|
+
)
|
|
3481
|
+
);
|
|
3482
|
+
process.exit(1);
|
|
3483
|
+
}
|
|
3484
|
+
}
|
|
3485
|
+
const installations = connectionStatus.installations ?? [];
|
|
3486
|
+
if (installations.length === 0) {
|
|
3487
|
+
console.log(source_default.red("\u2717 No GitHub installations found."));
|
|
3488
|
+
process.exit(1);
|
|
3656
3489
|
}
|
|
3657
|
-
|
|
3490
|
+
const defaultInstallation = installations.find((i) => i.account_type === "Organization") ?? installations[0];
|
|
3491
|
+
const installationDbId = defaultInstallation.id;
|
|
3492
|
+
const githubInstallationId = defaultInstallation.installation_id;
|
|
3493
|
+
console.log(source_default.green("\u2713 GitHub connected\n"));
|
|
3658
3494
|
const projectDir = options.rootDir ? import_node_path5.default.resolve(cwd, options.rootDir) : cwd;
|
|
3659
3495
|
if (options.rootDir) {
|
|
3660
3496
|
try {
|
|
@@ -3665,381 +3501,383 @@ async function deployCommand(options) {
|
|
|
3665
3501
|
);
|
|
3666
3502
|
process.exit(1);
|
|
3667
3503
|
}
|
|
3668
|
-
console.log(source_default.gray(` Root dir: `) + source_default.cyan(options.rootDir));
|
|
3669
3504
|
}
|
|
3670
3505
|
const isMcp = await isMcpProject(projectDir);
|
|
3671
|
-
if (!isMcp) {
|
|
3506
|
+
if (!isMcp && !options.yes) {
|
|
3672
3507
|
console.log(
|
|
3673
|
-
source_default.yellow(
|
|
3674
|
-
|
|
3675
|
-
|
|
3508
|
+
source_default.yellow("\u26A0\uFE0F This doesn't look like an MCP server project.")
|
|
3509
|
+
);
|
|
3510
|
+
const shouldContinue = await prompt(
|
|
3511
|
+
source_default.white("Continue anyway? (y/n): ")
|
|
3676
3512
|
);
|
|
3677
|
-
if (!
|
|
3678
|
-
|
|
3679
|
-
|
|
3513
|
+
if (!shouldContinue) {
|
|
3514
|
+
process.exit(0);
|
|
3515
|
+
}
|
|
3516
|
+
console.log();
|
|
3517
|
+
}
|
|
3518
|
+
let gitInfo = await getGitInfo(cwd);
|
|
3519
|
+
let repoFullName;
|
|
3520
|
+
let branch = "main";
|
|
3521
|
+
if (!gitInfo.isGitRepo || !gitInfo.remoteUrl) {
|
|
3522
|
+
const projectName2 = options.name || await getProjectName(projectDir);
|
|
3523
|
+
console.log(source_default.yellow("\u26A0\uFE0F No GitHub remote found.\n"));
|
|
3524
|
+
if (options.yes) {
|
|
3525
|
+
console.log(source_default.gray("Creating GitHub repository automatically..."));
|
|
3526
|
+
} else {
|
|
3527
|
+
const shouldCreate = await prompt(
|
|
3528
|
+
source_default.white("Create a GitHub repository and push your code? (Y/n): "),
|
|
3529
|
+
"y"
|
|
3680
3530
|
);
|
|
3681
|
-
if (!
|
|
3682
|
-
console.log(
|
|
3531
|
+
if (!shouldCreate) {
|
|
3532
|
+
console.log(
|
|
3533
|
+
source_default.gray(
|
|
3534
|
+
"Deployment cancelled. Set up a GitHub remote and try again."
|
|
3535
|
+
)
|
|
3536
|
+
);
|
|
3683
3537
|
process.exit(0);
|
|
3684
3538
|
}
|
|
3685
3539
|
}
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3540
|
+
const defaultIdx = installations.findIndex(
|
|
3541
|
+
(i) => i.account_type === "Organization"
|
|
3542
|
+
);
|
|
3543
|
+
let selectedIdx = defaultIdx >= 0 ? defaultIdx : 0;
|
|
3544
|
+
if (installations.length > 1 && !options.yes) {
|
|
3545
|
+
console.log(
|
|
3546
|
+
source_default.cyan.bold("\u{1F419} Select a GitHub account for the repository:\n")
|
|
3547
|
+
);
|
|
3548
|
+
for (let i = 0; i < installations.length; i++) {
|
|
3549
|
+
const inst = installations[i];
|
|
3550
|
+
const typeLabel = inst.account_type === "Organization" ? source_default.gray(" (org)") : source_default.gray(" (personal)");
|
|
3551
|
+
const marker = i === selectedIdx ? source_default.green(" \u2190 default") : "";
|
|
3552
|
+
console.log(
|
|
3553
|
+
` ${source_default.white(`${i + 1}.`)} ${inst.account_login}${typeLabel}${marker}`
|
|
3554
|
+
);
|
|
3555
|
+
}
|
|
3556
|
+
console.log();
|
|
3557
|
+
const readline = await import("readline");
|
|
3558
|
+
const rl = readline.createInterface({
|
|
3559
|
+
input: process.stdin,
|
|
3560
|
+
output: process.stdout
|
|
3561
|
+
});
|
|
3562
|
+
const answer = await new Promise((resolve2) => {
|
|
3563
|
+
rl.question(
|
|
3564
|
+
source_default.gray(`Enter number [${selectedIdx + 1}]: `),
|
|
3565
|
+
(a) => {
|
|
3566
|
+
rl.close();
|
|
3567
|
+
resolve2(a.trim());
|
|
3568
|
+
}
|
|
3569
|
+
);
|
|
3570
|
+
});
|
|
3571
|
+
const parsed = answer === "" ? selectedIdx : parseInt(answer, 10) - 1;
|
|
3572
|
+
if (parsed >= 0 && parsed < installations.length) {
|
|
3573
|
+
selectedIdx = parsed;
|
|
3574
|
+
}
|
|
3575
|
+
}
|
|
3576
|
+
const repoInstallation = installations[selectedIdx];
|
|
3577
|
+
if (repoInstallation.account_type !== "Organization") {
|
|
3578
|
+
console.log(
|
|
3579
|
+
source_default.yellow(
|
|
3580
|
+
"\n\u26A0\uFE0F GitHub Apps cannot create repos on personal accounts.\n"
|
|
3581
|
+
)
|
|
3582
|
+
);
|
|
3583
|
+
console.log(
|
|
3584
|
+
source_default.white("To deploy from ") + source_default.cyan(repoInstallation.account_login) + source_default.white(", create a repository manually:\n")
|
|
3585
|
+
);
|
|
3586
|
+
console.log(
|
|
3587
|
+
source_default.cyan(" 1. ") + source_default.white("Go to ") + source_default.cyan("https://github.com/new")
|
|
3588
|
+
);
|
|
3589
|
+
console.log(
|
|
3590
|
+
source_default.cyan(" 2. ") + source_default.white("Create a repository (any name, can be private)")
|
|
3591
|
+
);
|
|
3592
|
+
console.log(source_default.cyan(" 3. ") + source_default.white("Add it as a remote:"));
|
|
3593
|
+
console.log(source_default.gray(" git init && git remote add origin <url>"));
|
|
3594
|
+
console.log(source_default.cyan(" 4. ") + source_default.white("Push your code:"));
|
|
3595
|
+
console.log(
|
|
3596
|
+
source_default.gray(
|
|
3597
|
+
" git add . && git commit -m 'Initial commit' && git push -u origin main"
|
|
3598
|
+
)
|
|
3599
|
+
);
|
|
3600
|
+
console.log(
|
|
3601
|
+
source_default.cyan(" 5. ") + source_default.white("Grant the GitHub App access to the repo:")
|
|
3602
|
+
);
|
|
3603
|
+
const appName = await api.getGitHubAppName();
|
|
3604
|
+
console.log(
|
|
3605
|
+
source_default.gray(
|
|
3606
|
+
` https://github.com/apps/${appName}/installations/new`
|
|
3607
|
+
)
|
|
3608
|
+
);
|
|
3609
|
+
console.log(
|
|
3610
|
+
source_default.cyan(" 6. ") + source_default.white("Run ") + source_default.cyan("mcp-use deploy") + source_default.white(" again\n")
|
|
3611
|
+
);
|
|
3612
|
+
process.exit(0);
|
|
3613
|
+
}
|
|
3614
|
+
const repoName = options.yes ? projectName2 : await promptText(source_default.gray("Repository name:"), projectName2);
|
|
3615
|
+
await ensureGitignore(cwd);
|
|
3616
|
+
console.log(
|
|
3617
|
+
source_default.gray(
|
|
3618
|
+
`Creating repository on ${repoInstallation.account_login}...`
|
|
3619
|
+
)
|
|
3620
|
+
);
|
|
3621
|
+
const repoResult = await api.createGitHubRepo({
|
|
3622
|
+
installationId: repoInstallation.installation_id,
|
|
3623
|
+
name: repoName,
|
|
3624
|
+
private: true,
|
|
3625
|
+
org: repoInstallation.account_login
|
|
3626
|
+
});
|
|
3627
|
+
console.log(source_default.green(`\u2713 Created ${source_default.cyan(repoResult.fullName)}`));
|
|
3628
|
+
if (!gitInfo.isGitRepo) {
|
|
3629
|
+
console.log(source_default.gray("Initializing git..."));
|
|
3630
|
+
await gitInit(cwd, "Initial commit");
|
|
3631
|
+
console.log(source_default.gray("Pushing to GitHub..."));
|
|
3632
|
+
await gitAddRemoteAndPush(cwd, repoResult.cloneUrl, "main");
|
|
3633
|
+
} else {
|
|
3634
|
+
console.log(source_default.gray("Adding remote and pushing..."));
|
|
3635
|
+
await gitAddRemoteAndPush(
|
|
3636
|
+
cwd,
|
|
3637
|
+
repoResult.cloneUrl,
|
|
3638
|
+
gitInfo.branch || "main"
|
|
3639
|
+
);
|
|
3640
|
+
}
|
|
3641
|
+
console.log(source_default.green("\u2713 Code pushed to GitHub\n"));
|
|
3642
|
+
gitInfo = await getGitInfo(cwd);
|
|
3643
|
+
repoFullName = repoResult.fullName;
|
|
3644
|
+
branch = gitInfo.branch || "main";
|
|
3645
|
+
} else if (!isGitHubUrl(gitInfo.remoteUrl)) {
|
|
3710
3646
|
console.log(source_default.red("\u2717 Remote is not a GitHub repository"));
|
|
3711
3647
|
console.log(source_default.yellow(` Current remote: ${gitInfo.remoteUrl}
|
|
3712
3648
|
`));
|
|
3713
|
-
console.log(source_default.white("Please add a GitHub remote to deploy."));
|
|
3714
3649
|
process.exit(1);
|
|
3715
|
-
}
|
|
3716
|
-
if (!gitInfo.owner || !gitInfo.repo) {
|
|
3650
|
+
} else if (!gitInfo.owner || !gitInfo.repo) {
|
|
3717
3651
|
console.log(source_default.red("\u2717 Could not parse GitHub repository information"));
|
|
3718
3652
|
process.exit(1);
|
|
3719
|
-
}
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3653
|
+
} else {
|
|
3654
|
+
repoFullName = `${gitInfo.owner}/${gitInfo.repo}`;
|
|
3655
|
+
branch = gitInfo.branch || "main";
|
|
3656
|
+
if (gitInfo.hasUncommittedChanges) {
|
|
3657
|
+
console.log(source_default.yellow("\u26A0\uFE0F You have uncommitted changes.\n"));
|
|
3658
|
+
if (!options.yes) {
|
|
3659
|
+
const shouldCommit = await prompt(
|
|
3660
|
+
source_default.white("Commit and push changes before deploying? (Y/n): "),
|
|
3661
|
+
"y"
|
|
3662
|
+
);
|
|
3663
|
+
if (shouldCommit) {
|
|
3664
|
+
await ensureGitignore(cwd);
|
|
3665
|
+
console.log(source_default.gray("Committing and pushing..."));
|
|
3666
|
+
await gitCommitAndPush(cwd, "Deploy changes", branch);
|
|
3667
|
+
gitInfo = await getGitInfo(cwd);
|
|
3668
|
+
console.log(source_default.green("\u2713 Changes pushed\n"));
|
|
3669
|
+
} else {
|
|
3670
|
+
console.log(source_default.gray("Deploying from last pushed commit.\n"));
|
|
3671
|
+
}
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3674
|
+
console.log(source_default.gray("Checking repository access..."));
|
|
3675
|
+
const hasAccess = await checkRepoAccess(
|
|
3676
|
+
api,
|
|
3677
|
+
gitInfo.owner,
|
|
3678
|
+
gitInfo.repo
|
|
3727
3679
|
);
|
|
3728
|
-
if (!
|
|
3729
|
-
|
|
3730
|
-
source_default.
|
|
3680
|
+
if (!hasAccess) {
|
|
3681
|
+
console.log(
|
|
3682
|
+
source_default.yellow(
|
|
3683
|
+
`\u26A0\uFE0F GitHub App doesn't have access to ${source_default.cyan(repoFullName)}`
|
|
3684
|
+
)
|
|
3685
|
+
);
|
|
3686
|
+
const configured = await promptGitHubInstallation(
|
|
3687
|
+
api,
|
|
3688
|
+
"no_access",
|
|
3689
|
+
repoFullName,
|
|
3690
|
+
{ yes: options.yes, installationId: githubInstallationId }
|
|
3731
3691
|
);
|
|
3732
|
-
if (!
|
|
3733
|
-
console.log(source_default.gray("Deployment cancelled."));
|
|
3692
|
+
if (!configured) {
|
|
3734
3693
|
process.exit(0);
|
|
3735
3694
|
}
|
|
3695
|
+
const retry = await checkRepoAccess(api, gitInfo.owner, gitInfo.repo);
|
|
3696
|
+
if (!retry) {
|
|
3697
|
+
const appName = await api.getGitHubAppName();
|
|
3698
|
+
console.log(
|
|
3699
|
+
source_default.red(
|
|
3700
|
+
`
|
|
3701
|
+
\u2717 Repository ${source_default.cyan(repoFullName)} is still not accessible.`
|
|
3702
|
+
)
|
|
3703
|
+
);
|
|
3704
|
+
console.log(
|
|
3705
|
+
source_default.cyan(
|
|
3706
|
+
` https://github.com/apps/${appName}/installations/new
|
|
3707
|
+
`
|
|
3708
|
+
)
|
|
3709
|
+
);
|
|
3710
|
+
process.exit(1);
|
|
3711
|
+
}
|
|
3736
3712
|
}
|
|
3737
|
-
console.log();
|
|
3738
|
-
}
|
|
3739
|
-
console.log(source_default.white("GitHub repository detected:"));
|
|
3740
|
-
console.log(
|
|
3741
|
-
source_default.gray(` Repository: `) + source_default.cyan(`${gitInfo.owner}/${gitInfo.repo}`)
|
|
3742
|
-
);
|
|
3743
|
-
console.log(
|
|
3744
|
-
source_default.gray(` Branch: `) + source_default.cyan(gitInfo.branch || "main")
|
|
3745
|
-
);
|
|
3746
|
-
if (gitInfo.commitSha) {
|
|
3747
|
-
console.log(
|
|
3748
|
-
source_default.gray(` Commit: `) + source_default.gray(gitInfo.commitSha.substring(0, 7))
|
|
3749
|
-
);
|
|
3750
|
-
}
|
|
3751
|
-
if (gitInfo.commitMessage) {
|
|
3752
|
-
console.log(
|
|
3753
|
-
source_default.gray(` Message: `) + source_default.gray(gitInfo.commitMessage.split("\n")[0])
|
|
3754
|
-
);
|
|
3755
|
-
}
|
|
3756
|
-
console.log();
|
|
3757
|
-
if (!options.yes) {
|
|
3758
|
-
const shouldDeploy = await prompt(
|
|
3759
|
-
source_default.white(
|
|
3760
|
-
`Deploy from GitHub repository ${gitInfo.owner}/${gitInfo.repo}? (Y/n): `
|
|
3761
|
-
),
|
|
3762
|
-
"y"
|
|
3763
|
-
);
|
|
3764
|
-
if (!shouldDeploy) {
|
|
3765
|
-
console.log(source_default.gray("Deployment cancelled."));
|
|
3766
|
-
process.exit(0);
|
|
3767
|
-
}
|
|
3713
|
+
console.log(source_default.green("\u2713 Repository access confirmed"));
|
|
3768
3714
|
}
|
|
3769
3715
|
const projectName = options.name || await getProjectName(projectDir);
|
|
3770
|
-
const runtime = options.runtime || await detectRuntime(projectDir);
|
|
3771
3716
|
const port = options.port || 3e3;
|
|
3772
3717
|
const buildCommand = await detectBuildCommand(projectDir);
|
|
3773
3718
|
const startCommand = await detectStartCommand(projectDir);
|
|
3719
|
+
const runtime = options.runtime || await detectRuntime(projectDir);
|
|
3774
3720
|
const envVars = await buildEnvVars(options);
|
|
3775
3721
|
console.log();
|
|
3776
3722
|
console.log(source_default.white("Deployment configuration:"));
|
|
3723
|
+
console.log(source_default.gray(` Repository: `) + source_default.cyan(repoFullName));
|
|
3724
|
+
console.log(source_default.gray(` Branch: `) + source_default.cyan(branch));
|
|
3777
3725
|
console.log(source_default.gray(` Name: `) + source_default.cyan(projectName));
|
|
3778
3726
|
console.log(source_default.gray(` Runtime: `) + source_default.cyan(runtime));
|
|
3779
3727
|
console.log(source_default.gray(` Port: `) + source_default.cyan(port));
|
|
3780
|
-
if (options.
|
|
3728
|
+
if (options.region)
|
|
3729
|
+
console.log(source_default.gray(` Region: `) + source_default.cyan(options.region));
|
|
3730
|
+
if (options.buildCommand)
|
|
3781
3731
|
console.log(
|
|
3782
|
-
source_default.gray(`
|
|
3732
|
+
source_default.gray(` Build command: `) + source_default.cyan(options.buildCommand)
|
|
3783
3733
|
);
|
|
3784
|
-
|
|
3785
|
-
if (buildCommand) {
|
|
3786
|
-
console.log(source_default.gray(` Build command: `) + source_default.cyan(buildCommand));
|
|
3787
|
-
}
|
|
3788
|
-
if (startCommand) {
|
|
3789
|
-
console.log(source_default.gray(` Start command: `) + source_default.cyan(startCommand));
|
|
3790
|
-
}
|
|
3791
|
-
if (envVars && Object.keys(envVars).length > 0) {
|
|
3734
|
+
else if (buildCommand)
|
|
3792
3735
|
console.log(
|
|
3793
|
-
source_default.gray(`
|
|
3736
|
+
source_default.gray(` Build command: `) + source_default.gray(buildCommand + " (auto-detected)")
|
|
3794
3737
|
);
|
|
3738
|
+
if (options.startCommand)
|
|
3795
3739
|
console.log(
|
|
3796
|
-
source_default.gray(`
|
|
3740
|
+
source_default.gray(` Start command: `) + source_default.cyan(options.startCommand)
|
|
3797
3741
|
);
|
|
3798
|
-
|
|
3799
|
-
console.log();
|
|
3800
|
-
const api = await McpUseAPI.create();
|
|
3801
|
-
if (options.org) {
|
|
3802
|
-
try {
|
|
3803
|
-
const authInfo = await api.testAuth();
|
|
3804
|
-
const match = (authInfo.profiles ?? []).find(
|
|
3805
|
-
(p) => p.slug === options.org || p.id === options.org || p.profile_name.toLowerCase() === options.org.toLowerCase()
|
|
3806
|
-
);
|
|
3807
|
-
if (match) {
|
|
3808
|
-
api.setProfileId(match.id);
|
|
3809
|
-
const slug = match.slug ? source_default.gray(` (${match.slug})`) : "";
|
|
3810
|
-
console.log(
|
|
3811
|
-
source_default.gray("Organization: ") + source_default.cyan(match.profile_name) + slug
|
|
3812
|
-
);
|
|
3813
|
-
} else {
|
|
3814
|
-
console.error(
|
|
3815
|
-
source_default.red(
|
|
3816
|
-
`\u2717 Organization "${options.org}" not found. Run ${source_default.white("npx mcp-use org list")} to see available organizations.`
|
|
3817
|
-
)
|
|
3818
|
-
);
|
|
3819
|
-
process.exit(1);
|
|
3820
|
-
}
|
|
3821
|
-
} catch (error) {
|
|
3822
|
-
console.error(
|
|
3823
|
-
source_default.red("\u2717 Failed to resolve organization:"),
|
|
3824
|
-
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
3825
|
-
);
|
|
3826
|
-
process.exit(1);
|
|
3827
|
-
}
|
|
3828
|
-
}
|
|
3829
|
-
let githubVerified = false;
|
|
3830
|
-
try {
|
|
3831
|
-
console.log(source_default.gray(`[DEBUG] API URL: ${api.baseUrl}`));
|
|
3832
|
-
const connectionStatus = await api.getGitHubConnectionStatus();
|
|
3833
|
-
if (!connectionStatus.is_connected) {
|
|
3834
|
-
const repoFullName = `${gitInfo.owner}/${gitInfo.repo}`;
|
|
3835
|
-
const installed = await promptGitHubInstallation(
|
|
3836
|
-
api,
|
|
3837
|
-
"not_connected",
|
|
3838
|
-
repoFullName,
|
|
3839
|
-
{ yes: options.yes }
|
|
3840
|
-
);
|
|
3841
|
-
if (!installed) {
|
|
3842
|
-
console.log(source_default.gray("Deployment cancelled."));
|
|
3843
|
-
process.exit(0);
|
|
3844
|
-
}
|
|
3845
|
-
const retryStatus = await api.getGitHubConnectionStatus();
|
|
3846
|
-
if (!retryStatus.is_connected) {
|
|
3847
|
-
console.log(
|
|
3848
|
-
source_default.red("\n\u2717 GitHub connection could not be verified.")
|
|
3849
|
-
);
|
|
3850
|
-
console.log(
|
|
3851
|
-
source_default.gray("Please try connecting GitHub from the web UI:")
|
|
3852
|
-
);
|
|
3853
|
-
console.log(source_default.cyan(" https://manufact.com/cloud/settings\n"));
|
|
3854
|
-
process.exit(1);
|
|
3855
|
-
}
|
|
3856
|
-
githubVerified = true;
|
|
3857
|
-
} else if (gitInfo.owner && gitInfo.repo) {
|
|
3858
|
-
console.log(source_default.gray("Checking repository access..."));
|
|
3859
|
-
const hasAccess = await checkRepoAccess(
|
|
3860
|
-
api,
|
|
3861
|
-
gitInfo.owner,
|
|
3862
|
-
gitInfo.repo
|
|
3863
|
-
);
|
|
3864
|
-
if (!hasAccess) {
|
|
3865
|
-
const repoFullName = `${gitInfo.owner}/${gitInfo.repo}`;
|
|
3866
|
-
console.log(
|
|
3867
|
-
source_default.yellow(
|
|
3868
|
-
`\u26A0\uFE0F GitHub App doesn't have access to ${source_default.cyan(repoFullName)}`
|
|
3869
|
-
)
|
|
3870
|
-
);
|
|
3871
|
-
const configured = await promptGitHubInstallation(
|
|
3872
|
-
api,
|
|
3873
|
-
"no_access",
|
|
3874
|
-
repoFullName,
|
|
3875
|
-
{ yes: options.yes }
|
|
3876
|
-
);
|
|
3877
|
-
if (!configured) {
|
|
3878
|
-
console.log(source_default.gray("Deployment cancelled."));
|
|
3879
|
-
process.exit(0);
|
|
3880
|
-
}
|
|
3881
|
-
const hasAccessRetry = await checkRepoAccess(
|
|
3882
|
-
api,
|
|
3883
|
-
gitInfo.owner,
|
|
3884
|
-
gitInfo.repo
|
|
3885
|
-
);
|
|
3886
|
-
if (!hasAccessRetry) {
|
|
3887
|
-
console.log(
|
|
3888
|
-
source_default.red(
|
|
3889
|
-
`
|
|
3890
|
-
\u2717 Repository ${source_default.cyan(repoFullName)} is still not accessible.`
|
|
3891
|
-
)
|
|
3892
|
-
);
|
|
3893
|
-
console.log(
|
|
3894
|
-
source_default.gray(
|
|
3895
|
-
"Please make sure the GitHub App has access to this repository."
|
|
3896
|
-
)
|
|
3897
|
-
);
|
|
3898
|
-
console.log(
|
|
3899
|
-
source_default.cyan(" https://github.com/settings/installations\n")
|
|
3900
|
-
);
|
|
3901
|
-
process.exit(1);
|
|
3902
|
-
}
|
|
3903
|
-
githubVerified = true;
|
|
3904
|
-
} else {
|
|
3905
|
-
console.log(source_default.green("\u2713 Repository access confirmed"));
|
|
3906
|
-
githubVerified = true;
|
|
3907
|
-
}
|
|
3908
|
-
}
|
|
3909
|
-
} catch (error) {
|
|
3910
|
-
console.log(source_default.red("\u2717 Could not verify GitHub connection"));
|
|
3911
|
-
console.log(
|
|
3912
|
-
source_default.gray(
|
|
3913
|
-
"Error: " + (error instanceof Error ? error.message : "Unknown error")
|
|
3914
|
-
)
|
|
3915
|
-
);
|
|
3916
|
-
console.log(source_default.gray("\nPlease ensure:"));
|
|
3742
|
+
else if (startCommand)
|
|
3917
3743
|
console.log(
|
|
3918
|
-
source_default.
|
|
3919
|
-
" 1. You have connected GitHub at https://manufact.com/cloud/settings"
|
|
3920
|
-
)
|
|
3744
|
+
source_default.gray(` Start command: `) + source_default.gray(startCommand + " (auto-detected)")
|
|
3921
3745
|
);
|
|
3746
|
+
if (Object.keys(envVars).length > 0) {
|
|
3922
3747
|
console.log(
|
|
3923
|
-
source_default.
|
|
3748
|
+
source_default.gray(` Environment: `) + source_default.cyan(`${Object.keys(envVars).length} variable(s)`)
|
|
3924
3749
|
);
|
|
3925
|
-
console.log(source_default.cyan(" 3. Your internet connection is stable\n"));
|
|
3926
|
-
process.exit(1);
|
|
3927
3750
|
}
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
)
|
|
3932
|
-
|
|
3751
|
+
console.log();
|
|
3752
|
+
if (!options.yes) {
|
|
3753
|
+
const shouldDeploy = await prompt(source_default.white(`Deploy? (Y/n): `), "y");
|
|
3754
|
+
if (!shouldDeploy) {
|
|
3755
|
+
console.log(source_default.gray("Deployment cancelled."));
|
|
3756
|
+
process.exit(0);
|
|
3757
|
+
}
|
|
3933
3758
|
}
|
|
3934
3759
|
const existingLink = !options.new ? await getProjectLink(cwd) : null;
|
|
3935
|
-
|
|
3936
|
-
if (existingLink) {
|
|
3760
|
+
let serverId = existingLink?.serverId;
|
|
3761
|
+
if (existingLink && serverId) {
|
|
3937
3762
|
try {
|
|
3938
|
-
const
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
if (existingDeployment && existingDeployment.status !== "failed") {
|
|
3942
|
-
console.log(source_default.green(`\u2713 Found linked deployment`));
|
|
3763
|
+
const existingDep = await api.getDeployment(existingLink.deploymentId);
|
|
3764
|
+
if (existingDep && existingDep.status !== "failed") {
|
|
3765
|
+
console.log(source_default.green(`\u2713 Found linked server`));
|
|
3943
3766
|
console.log(source_default.gray(` Redeploying to maintain the same URL...`));
|
|
3944
|
-
console.log(
|
|
3945
|
-
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
...options.port !== void 0 ? { port: options.port } : {},
|
|
3952
|
-
env: Object.keys(envVars).length > 0 ? envVars : void 0,
|
|
3953
|
-
rootDir: options.rootDir || void 0
|
|
3954
|
-
};
|
|
3955
|
-
const deployment2 = await api.redeployDeployment(
|
|
3956
|
-
existingLink.deploymentId,
|
|
3957
|
-
redeploymentConfig
|
|
3958
|
-
);
|
|
3767
|
+
console.log(source_default.cyan(` URL: ${getMcpServerUrl(existingDep)}
|
|
3768
|
+
`));
|
|
3769
|
+
const newDep = await api.createDeployment({
|
|
3770
|
+
serverId,
|
|
3771
|
+
branch,
|
|
3772
|
+
trigger: "redeploy"
|
|
3773
|
+
});
|
|
3959
3774
|
await saveProjectLink(cwd, {
|
|
3960
3775
|
...existingLink,
|
|
3961
|
-
linkedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3962
|
-
|
|
3963
|
-
await displayDeploymentProgress(api, deployment2, {
|
|
3964
|
-
yes: options.yes
|
|
3776
|
+
linkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3777
|
+
deploymentId: newDep.id
|
|
3965
3778
|
});
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
}
|
|
3779
|
+
console.log(
|
|
3780
|
+
source_default.green("\u2713 Deployment created: ") + source_default.gray(newDep.id)
|
|
3781
|
+
);
|
|
3782
|
+
await displayDeploymentProgress(api, newDep.id, { yes: options.yes });
|
|
3971
3783
|
return;
|
|
3972
|
-
}
|
|
3784
|
+
}
|
|
3785
|
+
} catch (err) {
|
|
3786
|
+
const is404 = err?.status === 404 || (err?.message ?? "").includes("404");
|
|
3787
|
+
if (is404) {
|
|
3973
3788
|
console.log(
|
|
3974
|
-
source_default.yellow(
|
|
3975
|
-
`\u26A0\uFE0F Linked deployment not found or failed, creating new one...`
|
|
3976
|
-
)
|
|
3789
|
+
source_default.yellow("\u26A0\uFE0F Previously linked server no longer exists.\n")
|
|
3977
3790
|
);
|
|
3978
|
-
if (
|
|
3979
|
-
|
|
3980
|
-
source_default.
|
|
3791
|
+
if (!options.yes) {
|
|
3792
|
+
const shouldRecreate = await prompt(
|
|
3793
|
+
source_default.white("Create a new server and deploy? (Y/n): "),
|
|
3794
|
+
"y"
|
|
3981
3795
|
);
|
|
3796
|
+
if (!shouldRecreate) {
|
|
3797
|
+
console.log(source_default.gray("Deployment cancelled."));
|
|
3798
|
+
process.exit(0);
|
|
3799
|
+
}
|
|
3982
3800
|
}
|
|
3801
|
+
serverId = void 0;
|
|
3983
3802
|
}
|
|
3984
|
-
}
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3803
|
+
}
|
|
3804
|
+
}
|
|
3805
|
+
let deploymentId;
|
|
3806
|
+
if (serverId) {
|
|
3807
|
+
console.log(source_default.gray("Creating deployment..."));
|
|
3808
|
+
try {
|
|
3809
|
+
const result = await api.createDeployment({
|
|
3810
|
+
serverId,
|
|
3811
|
+
branch,
|
|
3812
|
+
trigger: "manual"
|
|
3813
|
+
});
|
|
3814
|
+
deploymentId = result.id;
|
|
3815
|
+
} catch (err) {
|
|
3816
|
+
const is404 = err?.status === 404 || (err?.message ?? "").includes("404");
|
|
3817
|
+
if (is404) {
|
|
3818
|
+
console.log(
|
|
3819
|
+
source_default.yellow(
|
|
3820
|
+
"\u26A0\uFE0F Linked server no longer exists. Creating a new one...\n"
|
|
3821
|
+
)
|
|
3822
|
+
);
|
|
3823
|
+
serverId = void 0;
|
|
3824
|
+
} else {
|
|
3825
|
+
throw err;
|
|
3990
3826
|
}
|
|
3991
3827
|
}
|
|
3992
3828
|
}
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3829
|
+
if (!serverId) {
|
|
3830
|
+
const orgId = await api.resolveOrganizationId();
|
|
3831
|
+
console.log(source_default.gray("Creating server and deployment..."));
|
|
3832
|
+
const serverResult = await api.createServer({
|
|
3996
3833
|
type: "github",
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
3834
|
+
organizationId: orgId,
|
|
3835
|
+
installationId: installationDbId,
|
|
3836
|
+
name: projectName,
|
|
3837
|
+
repoFullName,
|
|
3838
|
+
branch,
|
|
3839
|
+
rootDir: options.rootDir,
|
|
4001
3840
|
port,
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
console.log(
|
|
4015
|
-
source_default.gray("Organization: ") + source_default.cyan(config.profileName) + slug
|
|
4016
|
-
);
|
|
4017
|
-
}
|
|
4018
|
-
} catch {
|
|
3841
|
+
env: Object.keys(envVars).length > 0 ? envVars : void 0,
|
|
3842
|
+
region: options.region,
|
|
3843
|
+
buildCommand: options.buildCommand,
|
|
3844
|
+
startCommand: options.startCommand
|
|
3845
|
+
});
|
|
3846
|
+
deploymentId = serverResult.deploymentId ?? "";
|
|
3847
|
+
if (!deploymentId) {
|
|
3848
|
+
console.log(
|
|
3849
|
+
source_default.green("\u2713 Server created: ") + source_default.gray(serverResult.server.id)
|
|
3850
|
+
);
|
|
3851
|
+
console.log(source_default.yellow("\u26A0\uFE0F No deployment was triggered."));
|
|
3852
|
+
return;
|
|
4019
3853
|
}
|
|
3854
|
+
await saveProjectLink(cwd, {
|
|
3855
|
+
deploymentId,
|
|
3856
|
+
deploymentName: projectName,
|
|
3857
|
+
linkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3858
|
+
serverId: serverResult.server.id
|
|
3859
|
+
});
|
|
3860
|
+
console.log(
|
|
3861
|
+
source_default.gray(` Linked to this project (stored in .mcp-use/project.json)`)
|
|
3862
|
+
);
|
|
3863
|
+
console.log(source_default.gray(` Future deploys will reuse the same URL
|
|
3864
|
+
`));
|
|
3865
|
+
}
|
|
3866
|
+
if (!deploymentId) {
|
|
3867
|
+
console.log(source_default.red("\u2717 No deployment was created."));
|
|
3868
|
+
process.exit(1);
|
|
4020
3869
|
}
|
|
4021
|
-
console.log(source_default.gray("Creating deployment..."));
|
|
4022
|
-
const deployment = await api.createDeployment(deploymentRequest);
|
|
4023
|
-
console.log(
|
|
4024
|
-
source_default.green("\u2713 Deployment created: ") + source_default.gray(deployment.id)
|
|
4025
|
-
);
|
|
4026
|
-
await saveProjectLink(cwd, {
|
|
4027
|
-
deploymentId: deployment.id,
|
|
4028
|
-
deploymentName: projectName,
|
|
4029
|
-
deploymentUrl: deployment.domain,
|
|
4030
|
-
linkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4031
|
-
serverId: deployment.serverId
|
|
4032
|
-
});
|
|
4033
3870
|
console.log(
|
|
4034
|
-
source_default.
|
|
3871
|
+
source_default.green("\u2713 Deployment created: ") + source_default.gray(deploymentId)
|
|
4035
3872
|
);
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
3873
|
+
await displayDeploymentProgress(api, deploymentId, { yes: options.yes });
|
|
3874
|
+
if (options.open) {
|
|
3875
|
+
const dep = await api.getDeployment(deploymentId);
|
|
3876
|
+
const url = getMcpServerUrl(dep);
|
|
3877
|
+
if (url) {
|
|
3878
|
+
console.log(source_default.gray("\nOpening in browser..."));
|
|
3879
|
+
await open_default(url);
|
|
3880
|
+
}
|
|
4043
3881
|
}
|
|
4044
3882
|
} catch (error) {
|
|
4045
3883
|
console.error(
|
|
@@ -4115,19 +3953,19 @@ async function listDeploymentsCommand() {
|
|
|
4115
3953
|
);
|
|
4116
3954
|
console.log(
|
|
4117
3955
|
source_default.white.bold(
|
|
4118
|
-
`${"ID".padEnd(40)} ${"NAME".padEnd(25)} ${"STATUS".padEnd(12)} ${"
|
|
3956
|
+
`${"ID".padEnd(40)} ${"NAME".padEnd(25)} ${"STATUS".padEnd(12)} ${"MCP URL".padEnd(45)} ${"CREATED"}`
|
|
4119
3957
|
)
|
|
4120
3958
|
);
|
|
4121
|
-
console.log(source_default.gray("\u2500".repeat(
|
|
3959
|
+
console.log(source_default.gray("\u2500".repeat(140)));
|
|
4122
3960
|
for (const deployment of sortedDeployments) {
|
|
4123
3961
|
const id = formatId(deployment.id).padEnd(40);
|
|
4124
3962
|
const name = deployment.name.substring(0, 24).padEnd(25);
|
|
4125
3963
|
const statusColor = getStatusColor(deployment.status);
|
|
4126
3964
|
const status = statusColor(deployment.status.padEnd(12));
|
|
4127
|
-
const
|
|
3965
|
+
const mcpUrl = (deployment.mcpUrl || "-").substring(0, 44).padEnd(45);
|
|
4128
3966
|
const created = formatRelativeTime(deployment.createdAt);
|
|
4129
3967
|
console.log(
|
|
4130
|
-
`${source_default.gray(id)} ${name} ${status} ${source_default.cyan(
|
|
3968
|
+
`${source_default.gray(id)} ${name} ${status} ${source_default.cyan(mcpUrl)} ${source_default.gray(created)}`
|
|
4131
3969
|
);
|
|
4132
3970
|
}
|
|
4133
3971
|
console.log();
|
|
@@ -4159,31 +3997,28 @@ async function getDeploymentCommand(deploymentId) {
|
|
|
4159
3997
|
console.log(
|
|
4160
3998
|
source_default.white("Status: ") + statusColor(deployment.status)
|
|
4161
3999
|
);
|
|
4162
|
-
if (deployment.
|
|
4000
|
+
if (deployment.serverId) {
|
|
4163
4001
|
console.log(
|
|
4164
|
-
source_default.white("
|
|
4002
|
+
source_default.white("Server ID: ") + source_default.gray(deployment.serverId)
|
|
4165
4003
|
);
|
|
4166
4004
|
}
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
);
|
|
4005
|
+
const mcpUrl = getMcpServerUrl(deployment);
|
|
4006
|
+
if (mcpUrl) {
|
|
4007
|
+
console.log(source_default.white("MCP URL: ") + source_default.cyan(mcpUrl));
|
|
4171
4008
|
}
|
|
4172
|
-
|
|
4173
|
-
source_default.white("Source: ") + source_default.gray(deployment.source.type)
|
|
4174
|
-
);
|
|
4175
|
-
if (deployment.source.type === "github") {
|
|
4009
|
+
if (deployment.gitBranch) {
|
|
4176
4010
|
console.log(
|
|
4177
|
-
source_default.white("
|
|
4011
|
+
source_default.white("Branch: ") + source_default.gray(deployment.gitBranch)
|
|
4178
4012
|
);
|
|
4013
|
+
}
|
|
4014
|
+
if (deployment.gitCommitSha) {
|
|
4179
4015
|
console.log(
|
|
4180
|
-
source_default.white("
|
|
4016
|
+
source_default.white("Commit: ") + source_default.gray(deployment.gitCommitSha.substring(0, 7))
|
|
4181
4017
|
);
|
|
4182
4018
|
}
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
);
|
|
4019
|
+
if (deployment.port) {
|
|
4020
|
+
console.log(source_default.white("Port: ") + source_default.gray(deployment.port));
|
|
4021
|
+
}
|
|
4187
4022
|
if (deployment.provider) {
|
|
4188
4023
|
console.log(
|
|
4189
4024
|
source_default.white("Provider: ") + source_default.gray(deployment.provider)
|
|
@@ -4195,13 +4030,6 @@ async function getDeploymentCommand(deploymentId) {
|
|
|
4195
4030
|
console.log(
|
|
4196
4031
|
source_default.white("Updated: ") + source_default.gray(formatRelativeTime(deployment.updatedAt))
|
|
4197
4032
|
);
|
|
4198
|
-
if (deployment.source.env && Object.keys(deployment.source.env).length > 0) {
|
|
4199
|
-
console.log(source_default.white("\nEnvironment Variables:"));
|
|
4200
|
-
for (const [key, value] of Object.entries(deployment.source.env)) {
|
|
4201
|
-
const displayValue = key.toLowerCase().includes("key") || key.toLowerCase().includes("secret") || key.toLowerCase().includes("password") || key.toLowerCase().includes("token") ? "***" : value;
|
|
4202
|
-
console.log(source_default.gray(` ${key}=`) + source_default.white(displayValue));
|
|
4203
|
-
}
|
|
4204
|
-
}
|
|
4205
4033
|
if (deployment.status === "failed" && deployment.error) {
|
|
4206
4034
|
console.log(source_default.red("\nError:"));
|
|
4207
4035
|
console.log(source_default.red(` ${deployment.error}`));
|
|
@@ -4228,43 +4056,56 @@ async function restartDeploymentCommand(deploymentId, options) {
|
|
|
4228
4056
|
}
|
|
4229
4057
|
const api = await McpUseAPI.create();
|
|
4230
4058
|
const deployment = await api.getDeployment(deploymentId);
|
|
4059
|
+
if (!deployment.serverId) {
|
|
4060
|
+
console.log(
|
|
4061
|
+
source_default.red("\u2717 Cannot restart: deployment has no linked server.")
|
|
4062
|
+
);
|
|
4063
|
+
process.exit(1);
|
|
4064
|
+
}
|
|
4231
4065
|
console.log(
|
|
4232
4066
|
source_default.cyan.bold(`
|
|
4233
4067
|
\u{1F504} Restarting deployment: ${deployment.name}
|
|
4234
4068
|
`)
|
|
4235
4069
|
);
|
|
4236
|
-
const
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
);
|
|
4070
|
+
const newDep = await api.createDeployment({
|
|
4071
|
+
serverId: deployment.serverId,
|
|
4072
|
+
trigger: "redeploy"
|
|
4073
|
+
});
|
|
4074
|
+
console.log(source_default.green("\u2713 Restart initiated: ") + source_default.gray(newDep.id));
|
|
4240
4075
|
if (options.follow) {
|
|
4241
|
-
console.log(source_default.gray("\nFollowing
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
))
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4076
|
+
console.log(source_default.gray("\nFollowing build logs...\n"));
|
|
4077
|
+
let offset = 0;
|
|
4078
|
+
let terminal = false;
|
|
4079
|
+
while (!terminal) {
|
|
4080
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
4081
|
+
try {
|
|
4082
|
+
const resp = await api.getDeploymentBuildLogs(newDep.id, offset);
|
|
4083
|
+
if (resp.logs.length > 0) {
|
|
4084
|
+
const lines = resp.logs.split("\n").filter((l) => l.trim());
|
|
4085
|
+
for (const line of lines) {
|
|
4086
|
+
try {
|
|
4087
|
+
const logData = JSON.parse(line);
|
|
4088
|
+
if (logData.line) {
|
|
4089
|
+
const levelColor = logData.level === "error" ? source_default.red : logData.level === "warn" ? source_default.yellow : source_default.gray;
|
|
4090
|
+
const stepPrefix = logData.step ? source_default.cyan(`[${logData.step}]`) + " " : "";
|
|
4091
|
+
console.log(stepPrefix + levelColor(logData.line));
|
|
4092
|
+
}
|
|
4093
|
+
} catch {
|
|
4094
|
+
console.log(source_default.gray(line));
|
|
4095
|
+
}
|
|
4252
4096
|
}
|
|
4253
|
-
|
|
4254
|
-
|
|
4097
|
+
offset = resp.offset;
|
|
4098
|
+
}
|
|
4099
|
+
if (resp.status === "running" || resp.status === "failed" || resp.status === "stopped") {
|
|
4100
|
+
terminal = true;
|
|
4255
4101
|
}
|
|
4102
|
+
} catch {
|
|
4256
4103
|
}
|
|
4257
|
-
} catch (error) {
|
|
4258
|
-
console.log(
|
|
4259
|
-
source_default.gray(
|
|
4260
|
-
"\nLog stream ended. Use " + source_default.white(`mcp-use deployments get ${deploymentId}`) + " to check status."
|
|
4261
|
-
)
|
|
4262
|
-
);
|
|
4263
4104
|
}
|
|
4264
4105
|
} else {
|
|
4265
4106
|
console.log(
|
|
4266
4107
|
source_default.gray(
|
|
4267
|
-
"\nCheck status with: " + source_default.white(`mcp-use deployments get ${
|
|
4108
|
+
"\nCheck status with: " + source_default.white(`mcp-use deployments get ${newDep.id}`)
|
|
4268
4109
|
)
|
|
4269
4110
|
);
|
|
4270
4111
|
}
|
|
@@ -4298,8 +4139,10 @@ async function deleteDeploymentCommand(deploymentId, options) {
|
|
|
4298
4139
|
)
|
|
4299
4140
|
);
|
|
4300
4141
|
console.log(source_default.gray(` ID: ${deployment.id}`));
|
|
4301
|
-
|
|
4142
|
+
if (deployment.mcpUrl) {
|
|
4143
|
+
console.log(source_default.gray(` URL: ${deployment.mcpUrl}
|
|
4302
4144
|
`));
|
|
4145
|
+
}
|
|
4303
4146
|
const confirmed = await prompt2(
|
|
4304
4147
|
source_default.white("Are you sure you want to delete this deployment? (y/N): ")
|
|
4305
4148
|
);
|
|
@@ -4335,30 +4178,41 @@ async function logsCommand(deploymentId, options) {
|
|
|
4335
4178
|
}
|
|
4336
4179
|
const api = await McpUseAPI.create();
|
|
4337
4180
|
if (options.follow) {
|
|
4338
|
-
console.log(source_default.gray("
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4181
|
+
console.log(source_default.gray("Following build logs...\n"));
|
|
4182
|
+
let offset = 0;
|
|
4183
|
+
let terminal = false;
|
|
4184
|
+
while (!terminal) {
|
|
4185
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
4186
|
+
try {
|
|
4187
|
+
const resp = await api.getDeploymentBuildLogs(deploymentId, offset);
|
|
4188
|
+
if (resp.logs.length > 0) {
|
|
4189
|
+
const lines = resp.logs.split("\n").filter((l) => l.trim());
|
|
4190
|
+
for (const line of lines) {
|
|
4191
|
+
try {
|
|
4192
|
+
const logData = JSON.parse(line);
|
|
4193
|
+
if (logData.line) {
|
|
4194
|
+
const levelColor = logData.level === "error" ? source_default.red : logData.level === "warn" ? source_default.yellow : source_default.gray;
|
|
4195
|
+
const stepPrefix = logData.step ? source_default.cyan(`[${logData.step}]`) + " " : "";
|
|
4196
|
+
console.log(stepPrefix + levelColor(logData.line));
|
|
4197
|
+
}
|
|
4198
|
+
} catch {
|
|
4199
|
+
console.log(source_default.gray(line));
|
|
4200
|
+
}
|
|
4347
4201
|
}
|
|
4348
|
-
|
|
4349
|
-
|
|
4202
|
+
offset = resp.offset;
|
|
4203
|
+
}
|
|
4204
|
+
if (resp.status === "running" || resp.status === "failed" || resp.status === "stopped") {
|
|
4205
|
+
terminal = true;
|
|
4350
4206
|
}
|
|
4207
|
+
} catch {
|
|
4351
4208
|
}
|
|
4352
|
-
} catch (error) {
|
|
4353
|
-
console.log(source_default.gray("\nLog stream ended."));
|
|
4354
4209
|
}
|
|
4355
|
-
} else {
|
|
4356
|
-
const
|
|
4210
|
+
} else if (options.build) {
|
|
4211
|
+
const resp = await api.getDeploymentBuildLogs(deploymentId);
|
|
4212
|
+
const logs = resp.logs;
|
|
4357
4213
|
if (!logs || logs.trim() === "") {
|
|
4358
4214
|
console.log(
|
|
4359
|
-
source_default.yellow(
|
|
4360
|
-
`No ${options.build ? "build " : ""}logs available for this deployment.`
|
|
4361
|
-
)
|
|
4215
|
+
source_default.yellow("No build logs available for this deployment.")
|
|
4362
4216
|
);
|
|
4363
4217
|
return;
|
|
4364
4218
|
}
|
|
@@ -4375,6 +4229,25 @@ async function logsCommand(deploymentId, options) {
|
|
|
4375
4229
|
console.log(source_default.gray(line));
|
|
4376
4230
|
}
|
|
4377
4231
|
}
|
|
4232
|
+
} else {
|
|
4233
|
+
const logs = await api.getDeploymentLogs(deploymentId);
|
|
4234
|
+
if (!logs || logs.trim() === "") {
|
|
4235
|
+
console.log(source_default.yellow("No logs available for this deployment."));
|
|
4236
|
+
return;
|
|
4237
|
+
}
|
|
4238
|
+
const logLines = logs.split("\n").filter((l) => l.trim());
|
|
4239
|
+
for (const line of logLines) {
|
|
4240
|
+
try {
|
|
4241
|
+
const logData = JSON.parse(line);
|
|
4242
|
+
if (logData.line) {
|
|
4243
|
+
const levelColor = logData.level === "error" ? source_default.red : logData.level === "warn" ? source_default.yellow : source_default.gray;
|
|
4244
|
+
const stepPrefix = logData.step ? source_default.cyan(`[${logData.step}]`) + " " : "";
|
|
4245
|
+
console.log(stepPrefix + levelColor(logData.line));
|
|
4246
|
+
}
|
|
4247
|
+
} catch {
|
|
4248
|
+
console.log(source_default.gray(line));
|
|
4249
|
+
}
|
|
4250
|
+
}
|
|
4378
4251
|
}
|
|
4379
4252
|
console.log();
|
|
4380
4253
|
} catch (error) {
|
|
@@ -4385,7 +4258,7 @@ async function logsCommand(deploymentId, options) {
|
|
|
4385
4258
|
process.exit(1);
|
|
4386
4259
|
}
|
|
4387
4260
|
}
|
|
4388
|
-
async function
|
|
4261
|
+
async function stopDeploymentCommand(deploymentId) {
|
|
4389
4262
|
try {
|
|
4390
4263
|
if (!await isLoggedIn()) {
|
|
4391
4264
|
console.log(source_default.red("\u2717 You are not logged in."));
|
|
@@ -4397,33 +4270,19 @@ async function listEnvCommand(deploymentId) {
|
|
|
4397
4270
|
process.exit(1);
|
|
4398
4271
|
}
|
|
4399
4272
|
const api = await McpUseAPI.create();
|
|
4400
|
-
|
|
4401
|
-
console.log(
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
`)
|
|
4405
|
-
);
|
|
4406
|
-
if (!deployment.source.env || Object.keys(deployment.source.env).length === 0) {
|
|
4407
|
-
console.log(source_default.yellow("No environment variables set."));
|
|
4408
|
-
console.log();
|
|
4409
|
-
return;
|
|
4410
|
-
}
|
|
4411
|
-
for (const [key, value] of Object.entries(deployment.source.env)) {
|
|
4412
|
-
const displayValue = key.toLowerCase().includes("key") || key.toLowerCase().includes("secret") || key.toLowerCase().includes("password") || key.toLowerCase().includes("token") ? "***" : value;
|
|
4413
|
-
console.log(
|
|
4414
|
-
source_default.white(key) + source_default.gray("=") + source_default.cyan(displayValue)
|
|
4415
|
-
);
|
|
4416
|
-
}
|
|
4417
|
-
console.log();
|
|
4273
|
+
await api.stopDeployment(deploymentId);
|
|
4274
|
+
console.log(source_default.green.bold(`
|
|
4275
|
+
\u2713 Deployment stopped
|
|
4276
|
+
`));
|
|
4418
4277
|
} catch (error) {
|
|
4419
4278
|
console.error(
|
|
4420
|
-
source_default.red.bold("\n\u2717 Failed to
|
|
4279
|
+
source_default.red.bold("\n\u2717 Failed to stop deployment:"),
|
|
4421
4280
|
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
4422
4281
|
);
|
|
4423
4282
|
process.exit(1);
|
|
4424
4283
|
}
|
|
4425
4284
|
}
|
|
4426
|
-
async function
|
|
4285
|
+
async function startDeploymentCommand(deploymentId) {
|
|
4427
4286
|
try {
|
|
4428
4287
|
if (!await isLoggedIn()) {
|
|
4429
4288
|
console.log(source_default.red("\u2717 You are not logged in."));
|
|
@@ -4434,43 +4293,87 @@ async function setEnvCommand(deploymentId, envPairs) {
|
|
|
4434
4293
|
);
|
|
4435
4294
|
process.exit(1);
|
|
4436
4295
|
}
|
|
4437
|
-
const env2 = {};
|
|
4438
|
-
for (const pair of envPairs) {
|
|
4439
|
-
const [key, ...valueParts] = pair.split("=");
|
|
4440
|
-
if (!key || valueParts.length === 0) {
|
|
4441
|
-
console.log(source_default.red(`\u2717 Invalid format: ${pair}. Expected KEY=VALUE`));
|
|
4442
|
-
process.exit(1);
|
|
4443
|
-
}
|
|
4444
|
-
env2[key.trim()] = valueParts.join("=").trim();
|
|
4445
|
-
}
|
|
4446
|
-
const api = await McpUseAPI.create();
|
|
4447
|
-
const deployment = await api.getDeployment(deploymentId);
|
|
4448
|
-
const currentEnv = deployment.source.env || {};
|
|
4449
|
-
const mergedEnv = { ...currentEnv, ...env2 };
|
|
4450
|
-
const updated = await api.updateDeployment(deploymentId, {
|
|
4451
|
-
env: mergedEnv
|
|
4452
|
-
});
|
|
4453
4296
|
console.log(
|
|
4454
|
-
source_default.
|
|
4455
|
-
\
|
|
4456
|
-
|
|
4297
|
+
source_default.yellow(
|
|
4298
|
+
"\u26A0\uFE0F Start is not supported in this version. Use `mcp-use deployments restart` to redeploy."
|
|
4299
|
+
)
|
|
4457
4300
|
);
|
|
4458
|
-
for (const key of Object.keys(env2)) {
|
|
4459
|
-
const displayValue = key.toLowerCase().includes("key") || key.toLowerCase().includes("secret") || key.toLowerCase().includes("password") || key.toLowerCase().includes("token") ? "***" : env2[key];
|
|
4460
|
-
console.log(
|
|
4461
|
-
source_default.white(key) + source_default.gray("=") + source_default.cyan(displayValue)
|
|
4462
|
-
);
|
|
4463
|
-
}
|
|
4464
|
-
console.log();
|
|
4465
4301
|
} catch (error) {
|
|
4466
4302
|
console.error(
|
|
4467
|
-
source_default.red.bold("\n\u2717 Failed to
|
|
4303
|
+
source_default.red.bold("\n\u2717 Failed to start deployment:"),
|
|
4468
4304
|
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
4469
4305
|
);
|
|
4470
4306
|
process.exit(1);
|
|
4471
4307
|
}
|
|
4472
4308
|
}
|
|
4473
|
-
|
|
4309
|
+
function createDeploymentsCommand() {
|
|
4310
|
+
const deploymentsCommand = new import_commander2.Command("deployments").description(
|
|
4311
|
+
"Manage cloud deployments"
|
|
4312
|
+
);
|
|
4313
|
+
deploymentsCommand.command("list").alias("ls").description("List all deployments").action(listDeploymentsCommand);
|
|
4314
|
+
deploymentsCommand.command("get").argument("<deployment-id>", "Deployment ID").description("Get deployment details").action(getDeploymentCommand);
|
|
4315
|
+
deploymentsCommand.command("restart").argument("<deployment-id>", "Deployment ID").option("-f, --follow", "Follow build logs").description(
|
|
4316
|
+
"Restart a deployment (triggers a new deployment on the same server)"
|
|
4317
|
+
).action(restartDeploymentCommand);
|
|
4318
|
+
deploymentsCommand.command("delete").alias("rm").argument("<deployment-id>", "Deployment ID").option("-y, --yes", "Skip confirmation prompt").description("Delete a deployment").action(deleteDeploymentCommand);
|
|
4319
|
+
deploymentsCommand.command("logs").argument("<deployment-id>", "Deployment ID").option("-b, --build", "Show build logs instead of runtime logs").option("-f, --follow", "Follow build logs in real-time").description("View deployment logs").action(logsCommand);
|
|
4320
|
+
deploymentsCommand.command("stop").argument("<deployment-id>", "Deployment ID").description("Stop a deployment").action(stopDeploymentCommand);
|
|
4321
|
+
deploymentsCommand.command("start").argument("<deployment-id>", "Deployment ID").description("Start a stopped deployment").action(startDeploymentCommand);
|
|
4322
|
+
return deploymentsCommand;
|
|
4323
|
+
}
|
|
4324
|
+
|
|
4325
|
+
// src/commands/servers.ts
|
|
4326
|
+
var import_commander3 = require("commander");
|
|
4327
|
+
async function prompt3(question) {
|
|
4328
|
+
const readline = await import("readline");
|
|
4329
|
+
const rl = readline.createInterface({
|
|
4330
|
+
input: process.stdin,
|
|
4331
|
+
output: process.stdout
|
|
4332
|
+
});
|
|
4333
|
+
return new Promise((resolve2) => {
|
|
4334
|
+
rl.question(question, (answer) => {
|
|
4335
|
+
rl.close();
|
|
4336
|
+
const trimmedAnswer = answer.trim().toLowerCase();
|
|
4337
|
+
resolve2(trimmedAnswer === "y" || trimmedAnswer === "yes");
|
|
4338
|
+
});
|
|
4339
|
+
});
|
|
4340
|
+
}
|
|
4341
|
+
function isRecord(v) {
|
|
4342
|
+
return typeof v === "object" && v !== null;
|
|
4343
|
+
}
|
|
4344
|
+
function pickStr(obj, key) {
|
|
4345
|
+
if (!isRecord(obj)) return "-";
|
|
4346
|
+
const v = obj[key];
|
|
4347
|
+
if (typeof v === "string") return v;
|
|
4348
|
+
if (v != null && typeof v !== "object") return String(v);
|
|
4349
|
+
return "-";
|
|
4350
|
+
}
|
|
4351
|
+
async function applyOrgOption(api, org) {
|
|
4352
|
+
if (!org) return;
|
|
4353
|
+
const authInfo = await api.testAuth();
|
|
4354
|
+
const match = (authInfo.orgs ?? []).find(
|
|
4355
|
+
(o) => o.slug === org || o.id === org || o.name.toLowerCase() === org.toLowerCase()
|
|
4356
|
+
);
|
|
4357
|
+
if (!match) {
|
|
4358
|
+
console.error(
|
|
4359
|
+
source_default.red(
|
|
4360
|
+
`\u2717 Organization "${org}" not found. Run ${source_default.white("npx mcp-use org list")} to see available organizations.`
|
|
4361
|
+
)
|
|
4362
|
+
);
|
|
4363
|
+
process.exit(1);
|
|
4364
|
+
}
|
|
4365
|
+
api.setOrgId(match.id);
|
|
4366
|
+
const slug = match.slug ? source_default.gray(` (${match.slug})`) : "";
|
|
4367
|
+
console.log(source_default.gray("Organization: ") + source_default.cyan(match.name) + slug);
|
|
4368
|
+
}
|
|
4369
|
+
function getStatusColor2(status) {
|
|
4370
|
+
const s = status.toLowerCase();
|
|
4371
|
+
if (s.includes("run") || s === "active") return source_default.green;
|
|
4372
|
+
if (s.includes("fail") || s.includes("error")) return source_default.red;
|
|
4373
|
+
if (s.includes("build") || s.includes("pend")) return source_default.yellow;
|
|
4374
|
+
return source_default.gray;
|
|
4375
|
+
}
|
|
4376
|
+
async function listServersCommand(options) {
|
|
4474
4377
|
try {
|
|
4475
4378
|
if (!await isLoggedIn()) {
|
|
4476
4379
|
console.log(source_default.red("\u2717 You are not logged in."));
|
|
@@ -4482,32 +4385,62 @@ async function unsetEnvCommand(deploymentId, keys) {
|
|
|
4482
4385
|
process.exit(1);
|
|
4483
4386
|
}
|
|
4484
4387
|
const api = await McpUseAPI.create();
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4388
|
+
await applyOrgOption(api, options.org);
|
|
4389
|
+
if (options.org) console.log();
|
|
4390
|
+
const limit = options.limit ? parseInt(options.limit, 10) : void 0;
|
|
4391
|
+
const skip = options.skip ? parseInt(options.skip, 10) : void 0;
|
|
4392
|
+
if (limit !== void 0 && (Number.isNaN(limit) || limit < 1)) {
|
|
4393
|
+
console.log(source_default.red("\u2717 Invalid --limit"));
|
|
4394
|
+
process.exit(1);
|
|
4489
4395
|
}
|
|
4490
|
-
|
|
4491
|
-
|
|
4396
|
+
if (skip !== void 0 && (Number.isNaN(skip) || skip < 0)) {
|
|
4397
|
+
console.log(source_default.red("\u2717 Invalid --skip"));
|
|
4398
|
+
process.exit(1);
|
|
4399
|
+
}
|
|
4400
|
+
const servers = await api.listServers({
|
|
4401
|
+
limit,
|
|
4402
|
+
skip,
|
|
4403
|
+
sort: options.sort
|
|
4492
4404
|
});
|
|
4405
|
+
if (servers.length === 0) {
|
|
4406
|
+
console.log(source_default.yellow("No servers found."));
|
|
4407
|
+
console.log(
|
|
4408
|
+
source_default.gray(
|
|
4409
|
+
"\nCreate one by deploying with " + source_default.white("mcp-use deploy")
|
|
4410
|
+
)
|
|
4411
|
+
);
|
|
4412
|
+
return;
|
|
4413
|
+
}
|
|
4414
|
+
console.log(source_default.cyan.bold(`
|
|
4415
|
+
\u{1F5A5} Servers (${servers.length})
|
|
4416
|
+
`));
|
|
4493
4417
|
console.log(
|
|
4494
|
-
source_default.
|
|
4495
|
-
|
|
4496
|
-
|
|
4418
|
+
source_default.white.bold(
|
|
4419
|
+
`${"ID".padEnd(38)} ${"NAME".padEnd(22)} ${"STATUS".padEnd(14)} ${"REPO".padEnd(32)} ${"MCP URL".padEnd(52)}`
|
|
4420
|
+
)
|
|
4497
4421
|
);
|
|
4498
|
-
|
|
4499
|
-
|
|
4422
|
+
console.log(source_default.gray("\u2500".repeat(165)));
|
|
4423
|
+
for (const s of servers) {
|
|
4424
|
+
const id = s.id.substring(0, 37).padEnd(38);
|
|
4425
|
+
const name = (s.name || s.slug || "-").substring(0, 21).padEnd(22);
|
|
4426
|
+
const statusColor = getStatusColor2(s.status);
|
|
4427
|
+
const status = statusColor(s.status.substring(0, 13).padEnd(14));
|
|
4428
|
+
const repo = (s.connectedRepository?.repoFullName ?? "-").substring(0, 31).padEnd(32);
|
|
4429
|
+
const mcp = getMcpServerUrlForCloudServer(s).substring(0, 51).padEnd(52);
|
|
4430
|
+
console.log(
|
|
4431
|
+
`${source_default.gray(id)} ${name} ${status} ${source_default.gray(repo)} ${source_default.cyan(mcp)}`
|
|
4432
|
+
);
|
|
4500
4433
|
}
|
|
4501
4434
|
console.log();
|
|
4502
4435
|
} catch (error) {
|
|
4503
4436
|
console.error(
|
|
4504
|
-
source_default.red.bold("\n\u2717 Failed to
|
|
4437
|
+
source_default.red.bold("\n\u2717 Failed to list servers:"),
|
|
4505
4438
|
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
4506
4439
|
);
|
|
4507
4440
|
process.exit(1);
|
|
4508
4441
|
}
|
|
4509
4442
|
}
|
|
4510
|
-
async function
|
|
4443
|
+
async function getServerCommand(idOrSlug, options) {
|
|
4511
4444
|
try {
|
|
4512
4445
|
if (!await isLoggedIn()) {
|
|
4513
4446
|
console.log(source_default.red("\u2717 You are not logged in."));
|
|
@@ -4519,21 +4452,99 @@ async function stopDeploymentCommand(deploymentId) {
|
|
|
4519
4452
|
process.exit(1);
|
|
4520
4453
|
}
|
|
4521
4454
|
const api = await McpUseAPI.create();
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
console.log(source_default.
|
|
4526
|
-
|
|
4527
|
-
|
|
4455
|
+
await applyOrgOption(api, options.org);
|
|
4456
|
+
if (options.org) console.log();
|
|
4457
|
+
const server = await api.getServer(idOrSlug);
|
|
4458
|
+
console.log(source_default.cyan.bold("\n\u{1F5A5} Server Details\n"));
|
|
4459
|
+
console.log(source_default.white("ID: ") + source_default.gray(server.id));
|
|
4460
|
+
if (server.slug) {
|
|
4461
|
+
console.log(source_default.white("Slug: ") + source_default.cyan(server.slug));
|
|
4462
|
+
}
|
|
4463
|
+
console.log(
|
|
4464
|
+
source_default.white("Name: ") + source_default.cyan(server.name ?? "-")
|
|
4465
|
+
);
|
|
4466
|
+
const statusColor = getStatusColor2(server.status);
|
|
4467
|
+
console.log(source_default.white("Status: ") + statusColor(server.status));
|
|
4468
|
+
if (server.latestDeploymentStatus) {
|
|
4469
|
+
console.log(
|
|
4470
|
+
source_default.white("Last deploy: ") + source_default.gray(server.latestDeploymentStatus)
|
|
4471
|
+
);
|
|
4472
|
+
}
|
|
4473
|
+
console.log(source_default.white("Region: ") + source_default.gray(server.region));
|
|
4474
|
+
console.log(
|
|
4475
|
+
source_default.white("MCP URL: ") + source_default.cyan(getMcpServerUrlForCloudServer(server))
|
|
4476
|
+
);
|
|
4477
|
+
if (server.connectedRepository) {
|
|
4478
|
+
const cr = server.connectedRepository;
|
|
4479
|
+
console.log(source_default.white("\nRepository"));
|
|
4480
|
+
console.log(source_default.white(" Full name: ") + source_default.gray(cr.repoFullName));
|
|
4481
|
+
console.log(
|
|
4482
|
+
source_default.white(" Prod branch: ") + source_default.gray(cr.productionBranch)
|
|
4483
|
+
);
|
|
4484
|
+
}
|
|
4485
|
+
if (server.activeDeploymentId) {
|
|
4486
|
+
console.log(
|
|
4487
|
+
source_default.white("\nActive deployment: ") + source_default.cyan(server.activeDeploymentId)
|
|
4488
|
+
);
|
|
4489
|
+
}
|
|
4490
|
+
if (server.previousDeploymentId) {
|
|
4491
|
+
console.log(
|
|
4492
|
+
source_default.white("Previous deployment: ") + source_default.gray(server.previousDeploymentId)
|
|
4493
|
+
);
|
|
4494
|
+
}
|
|
4495
|
+
const depCount = server._count?.deployments;
|
|
4496
|
+
if (depCount != null) {
|
|
4497
|
+
console.log(
|
|
4498
|
+
source_default.white("Deployment count: ") + source_default.gray(String(depCount))
|
|
4499
|
+
);
|
|
4500
|
+
}
|
|
4501
|
+
console.log(
|
|
4502
|
+
source_default.white("Created: ") + source_default.gray(formatRelativeTime(server.createdAt))
|
|
4503
|
+
);
|
|
4504
|
+
console.log(
|
|
4505
|
+
source_default.white("Updated: ") + source_default.gray(formatRelativeTime(server.updatedAt))
|
|
4506
|
+
);
|
|
4507
|
+
const config = await readConfig();
|
|
4508
|
+
const base = (await getWebUrl()).replace(/\/$/, "");
|
|
4509
|
+
if (config.orgSlug) {
|
|
4510
|
+
console.log(
|
|
4511
|
+
source_default.white("\nDashboard: ") + source_default.cyan(`${base}/cloud/${config.orgSlug}/servers/${server.id}`)
|
|
4512
|
+
);
|
|
4513
|
+
} else {
|
|
4514
|
+
console.log(
|
|
4515
|
+
source_default.white("\nDashboard: ") + source_default.cyan(`${base}/cloud/servers/${server.id}`)
|
|
4516
|
+
);
|
|
4517
|
+
}
|
|
4518
|
+
if (Array.isArray(server.deployments) && server.deployments.length > 0) {
|
|
4519
|
+
console.log(source_default.cyan.bold("\nRecent deployments\n"));
|
|
4520
|
+
console.log(
|
|
4521
|
+
source_default.white.bold(
|
|
4522
|
+
`${"ID".padEnd(40)} ${"NAME".padEnd(24)} ${"STATUS".padEnd(12)} ${"UPDATED"}`
|
|
4523
|
+
)
|
|
4524
|
+
);
|
|
4525
|
+
console.log(source_default.gray("\u2500".repeat(100)));
|
|
4526
|
+
for (const d of server.deployments) {
|
|
4527
|
+
const did = pickStr(d, "id").padEnd(40);
|
|
4528
|
+
const dname = pickStr(d, "name").substring(0, 23).padEnd(24);
|
|
4529
|
+
const dst = pickStr(d, "status").padEnd(12);
|
|
4530
|
+
const du = pickStr(d, "updatedAt");
|
|
4531
|
+
const updated = du !== "-" ? formatRelativeTime(du) : source_default.gray("-");
|
|
4532
|
+
const sc = getStatusColor2(dst.trim());
|
|
4533
|
+
console.log(
|
|
4534
|
+
`${source_default.gray(did)} ${dname} ${sc(dst)} ${source_default.gray(updated)}`
|
|
4535
|
+
);
|
|
4536
|
+
}
|
|
4537
|
+
}
|
|
4538
|
+
console.log();
|
|
4528
4539
|
} catch (error) {
|
|
4529
4540
|
console.error(
|
|
4530
|
-
source_default.red.bold("\n\u2717 Failed to
|
|
4541
|
+
source_default.red.bold("\n\u2717 Failed to get server:"),
|
|
4531
4542
|
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
4532
4543
|
);
|
|
4533
4544
|
process.exit(1);
|
|
4534
4545
|
}
|
|
4535
4546
|
}
|
|
4536
|
-
async function
|
|
4547
|
+
async function deleteServerCommand(serverId, options) {
|
|
4537
4548
|
try {
|
|
4538
4549
|
if (!await isLoggedIn()) {
|
|
4539
4550
|
console.log(source_default.red("\u2717 You are not logged in."));
|
|
@@ -4545,36 +4556,59 @@ async function startDeploymentCommand(deploymentId) {
|
|
|
4545
4556
|
process.exit(1);
|
|
4546
4557
|
}
|
|
4547
4558
|
const api = await McpUseAPI.create();
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4559
|
+
await applyOrgOption(api, options.org);
|
|
4560
|
+
if (options.org) console.log();
|
|
4561
|
+
const server = await api.getServer(serverId);
|
|
4562
|
+
if (!options.yes) {
|
|
4563
|
+
console.log(
|
|
4564
|
+
source_default.yellow(
|
|
4565
|
+
`
|
|
4566
|
+
\u26A0\uFE0F You are about to delete server: ${source_default.white(server.name || server.slug || server.id)}`
|
|
4567
|
+
)
|
|
4568
|
+
);
|
|
4569
|
+
console.log(source_default.gray(` ID: ${server.id}`));
|
|
4570
|
+
if (server.connectedRepository?.repoFullName) {
|
|
4571
|
+
console.log(
|
|
4572
|
+
source_default.gray(` Repo: ${server.connectedRepository.repoFullName}
|
|
4573
|
+
`)
|
|
4574
|
+
);
|
|
4575
|
+
} else {
|
|
4576
|
+
console.log();
|
|
4577
|
+
}
|
|
4578
|
+
const confirmed = await prompt3(
|
|
4579
|
+
source_default.white(
|
|
4580
|
+
"This deletes the server and all its deployments. Continue? (y/N): "
|
|
4581
|
+
)
|
|
4582
|
+
);
|
|
4583
|
+
if (!confirmed) {
|
|
4584
|
+
console.log(source_default.gray("Deletion cancelled."));
|
|
4585
|
+
return;
|
|
4586
|
+
}
|
|
4587
|
+
}
|
|
4588
|
+
await api.deleteServer(server.id);
|
|
4589
|
+
console.log(
|
|
4590
|
+
source_default.green.bold(
|
|
4591
|
+
`
|
|
4592
|
+
\u2713 Server deleted: ${server.name || server.slug || server.id}
|
|
4593
|
+
`
|
|
4594
|
+
)
|
|
4595
|
+
);
|
|
4554
4596
|
} catch (error) {
|
|
4555
4597
|
console.error(
|
|
4556
|
-
source_default.red.bold("\n\u2717 Failed to
|
|
4598
|
+
source_default.red.bold("\n\u2717 Failed to delete server:"),
|
|
4557
4599
|
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
4558
4600
|
);
|
|
4559
4601
|
process.exit(1);
|
|
4560
4602
|
}
|
|
4561
4603
|
}
|
|
4562
|
-
function
|
|
4563
|
-
const
|
|
4564
|
-
"Manage cloud
|
|
4604
|
+
function createServersCommand() {
|
|
4605
|
+
const serversCommand = new import_commander3.Command("servers").description(
|
|
4606
|
+
"Manage cloud servers (Git-backed deploy targets)"
|
|
4565
4607
|
);
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
deploymentsCommand.command("logs").argument("<deployment-id>", "Deployment ID").option("-b, --build", "Show build logs instead of runtime logs").option("-f, --follow", "Stream logs in real-time").description("View deployment logs").action(logsCommand);
|
|
4571
|
-
const envCommand = deploymentsCommand.command("env").description("Manage environment variables");
|
|
4572
|
-
envCommand.command("list").argument("<deployment-id>", "Deployment ID").description("List environment variables").action(listEnvCommand);
|
|
4573
|
-
envCommand.command("set").argument("<deployment-id>", "Deployment ID").argument("<pairs...>", "Environment variables in KEY=VALUE format").description("Set environment variables").action(setEnvCommand);
|
|
4574
|
-
envCommand.command("unset").argument("<deployment-id>", "Deployment ID").argument("<keys...>", "Environment variable keys to remove").description("Unset environment variables").action(unsetEnvCommand);
|
|
4575
|
-
deploymentsCommand.command("stop").argument("<deployment-id>", "Deployment ID").description("Stop a deployment").action(stopDeploymentCommand);
|
|
4576
|
-
deploymentsCommand.command("start").argument("<deployment-id>", "Deployment ID").description("Start a stopped deployment").action(startDeploymentCommand);
|
|
4577
|
-
return deploymentsCommand;
|
|
4608
|
+
serversCommand.command("list").alias("ls").description("List servers for the current organization").option("--org <slug-or-id>", "Target organization (slug, id, or name)").option("--limit <n>", "Page size (1\u2013100, default 50)").option("--skip <n>", "Offset for pagination").option("--sort <field:asc|desc>", "Sort (e.g. updatedAt:desc)").action(listServersCommand);
|
|
4609
|
+
serversCommand.command("get").argument("<id-or-slug>", "Server UUID or slug").option("--org <slug-or-id>", "Resolve org context before fetch").description("Show server details and recent deployments").action(getServerCommand);
|
|
4610
|
+
serversCommand.command("delete").alias("rm").argument("<server-id>", "Server UUID (or slug if API accepts it)").option("-y, --yes", "Skip confirmation prompt").option("--org <slug-or-id>", "Target organization").description("Delete a server and all its deployments").action(deleteServerCommand);
|
|
4611
|
+
return serversCommand;
|
|
4578
4612
|
}
|
|
4579
4613
|
|
|
4580
4614
|
// src/commands/org.ts
|
|
@@ -4594,22 +4628,22 @@ async function orgListCommand() {
|
|
|
4594
4628
|
const api = await McpUseAPI.create();
|
|
4595
4629
|
const authInfo = await api.testAuth();
|
|
4596
4630
|
const config = await readConfig();
|
|
4597
|
-
const
|
|
4598
|
-
const activeId = config.
|
|
4599
|
-
if (
|
|
4631
|
+
const orgs = authInfo.orgs ?? [];
|
|
4632
|
+
const activeId = config.orgId || authInfo.default_org_id;
|
|
4633
|
+
if (orgs.length === 0) {
|
|
4600
4634
|
console.log(source_default.yellow("No organizations found."));
|
|
4601
4635
|
return;
|
|
4602
4636
|
}
|
|
4603
4637
|
console.log(source_default.cyan.bold("\u{1F3E2} Your organizations:\n"));
|
|
4604
|
-
for (const
|
|
4605
|
-
const isActive =
|
|
4638
|
+
for (const o of orgs) {
|
|
4639
|
+
const isActive = o.id === activeId;
|
|
4606
4640
|
const marker = isActive ? source_default.green(" \u2190 active") : "";
|
|
4607
|
-
const slug =
|
|
4608
|
-
const role = source_default.gray(` [${
|
|
4609
|
-
const name = isActive ? source_default.cyan.bold(
|
|
4641
|
+
const slug = o.slug ? source_default.gray(` (${o.slug})`) : "";
|
|
4642
|
+
const role = source_default.gray(` [${o.role}]`);
|
|
4643
|
+
const name = isActive ? source_default.cyan.bold(o.name) : source_default.white(o.name);
|
|
4610
4644
|
console.log(` ${name}${slug}${role}${marker}`);
|
|
4611
4645
|
}
|
|
4612
|
-
if (
|
|
4646
|
+
if (orgs.length > 1) {
|
|
4613
4647
|
console.log(
|
|
4614
4648
|
source_default.gray("\nSwitch with " + source_default.white("npx mcp-use org switch"))
|
|
4615
4649
|
);
|
|
@@ -4628,40 +4662,40 @@ async function orgSwitchCommand() {
|
|
|
4628
4662
|
const api = await McpUseAPI.create();
|
|
4629
4663
|
const authInfo = await api.testAuth();
|
|
4630
4664
|
const config = await readConfig();
|
|
4631
|
-
const
|
|
4632
|
-
if (
|
|
4665
|
+
const orgs = authInfo.orgs ?? [];
|
|
4666
|
+
if (orgs.length === 0) {
|
|
4633
4667
|
console.log(source_default.yellow("No organizations found."));
|
|
4634
4668
|
return;
|
|
4635
4669
|
}
|
|
4636
|
-
if (
|
|
4637
|
-
const
|
|
4638
|
-
const slug2 =
|
|
4670
|
+
if (orgs.length === 1) {
|
|
4671
|
+
const o = orgs[0];
|
|
4672
|
+
const slug2 = o.slug ? source_default.gray(` (${o.slug})`) : "";
|
|
4639
4673
|
console.log(
|
|
4640
4674
|
source_default.yellow(
|
|
4641
|
-
`You only have one organization: ${source_default.cyan(
|
|
4675
|
+
`You only have one organization: ${source_default.cyan(o.name)}${slug2}`
|
|
4642
4676
|
)
|
|
4643
4677
|
);
|
|
4644
4678
|
return;
|
|
4645
4679
|
}
|
|
4646
|
-
const activeId = config.
|
|
4647
|
-
const selected = await promptOrgSelection(
|
|
4680
|
+
const activeId = config.orgId || authInfo.default_org_id;
|
|
4681
|
+
const selected = await promptOrgSelection(orgs, activeId);
|
|
4648
4682
|
if (!selected) {
|
|
4649
4683
|
console.log(source_default.yellow("No organization selected."));
|
|
4650
4684
|
return;
|
|
4651
4685
|
}
|
|
4652
4686
|
await writeConfig({
|
|
4653
4687
|
...config,
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4688
|
+
orgId: selected.id,
|
|
4689
|
+
orgName: selected.name,
|
|
4690
|
+
orgSlug: selected.slug ?? void 0
|
|
4657
4691
|
});
|
|
4658
4692
|
try {
|
|
4659
|
-
await api.
|
|
4693
|
+
await api.setDefaultOrg(selected.id);
|
|
4660
4694
|
} catch {
|
|
4661
4695
|
}
|
|
4662
4696
|
const slug = selected.slug ? source_default.gray(` (${selected.slug})`) : "";
|
|
4663
4697
|
console.log(
|
|
4664
|
-
source_default.green.bold("\n\u2713 Switched to ") + source_default.cyan.bold(selected.
|
|
4698
|
+
source_default.green.bold("\n\u2713 Switched to ") + source_default.cyan.bold(selected.name) + slug
|
|
4665
4699
|
);
|
|
4666
4700
|
} catch (error) {
|
|
4667
4701
|
console.error(
|
|
@@ -4675,7 +4709,7 @@ async function orgCurrentCommand() {
|
|
|
4675
4709
|
try {
|
|
4676
4710
|
if (!await ensureLoggedIn()) return;
|
|
4677
4711
|
const config = await readConfig();
|
|
4678
|
-
if (!config.
|
|
4712
|
+
if (!config.orgId) {
|
|
4679
4713
|
console.log(
|
|
4680
4714
|
source_default.yellow(
|
|
4681
4715
|
"No organization selected. Run " + source_default.white("npx mcp-use org switch") + " to pick one."
|
|
@@ -4683,9 +4717,9 @@ async function orgCurrentCommand() {
|
|
|
4683
4717
|
);
|
|
4684
4718
|
return;
|
|
4685
4719
|
}
|
|
4686
|
-
const slug = config.
|
|
4720
|
+
const slug = config.orgSlug ? source_default.gray(` (${config.orgSlug})`) : "";
|
|
4687
4721
|
console.log(
|
|
4688
|
-
source_default.cyan.bold("\u{1F3E2} Active organization: ") + source_default.white(config.
|
|
4722
|
+
source_default.cyan.bold("\u{1F3E2} Active organization: ") + source_default.white(config.orgName || config.orgId) + slug
|
|
4689
4723
|
);
|
|
4690
4724
|
} catch (error) {
|
|
4691
4725
|
console.error(
|
|
@@ -4697,7 +4731,7 @@ async function orgCurrentCommand() {
|
|
|
4697
4731
|
}
|
|
4698
4732
|
|
|
4699
4733
|
// src/commands/skills.ts
|
|
4700
|
-
var
|
|
4734
|
+
var import_commander4 = require("commander");
|
|
4701
4735
|
var import_node_fs8 = require("fs");
|
|
4702
4736
|
var import_node_os5 = require("os");
|
|
4703
4737
|
var import_node_path6 = require("path");
|
|
@@ -4767,7 +4801,7 @@ async function addSkillsToProject(projectPath) {
|
|
|
4767
4801
|
}
|
|
4768
4802
|
}
|
|
4769
4803
|
function createSkillsCommand() {
|
|
4770
|
-
const skills = new
|
|
4804
|
+
const skills = new import_commander4.Command("skills").description(
|
|
4771
4805
|
"Manage mcp-use AI agent skills"
|
|
4772
4806
|
);
|
|
4773
4807
|
const installAction = async (options) => {
|
|
@@ -4943,7 +4977,7 @@ A new release of ${source_default.bold(PACKAGE_NAME)} is available: ${source_def
|
|
|
4943
4977
|
}
|
|
4944
4978
|
|
|
4945
4979
|
// src/index.ts
|
|
4946
|
-
var program = new
|
|
4980
|
+
var program = new import_commander5.Command();
|
|
4947
4981
|
var packageContent = (0, import_node_fs10.readFileSync)(
|
|
4948
4982
|
import_node_path8.default.join(__dirname, "../package.json"),
|
|
4949
4983
|
"utf-8"
|
|
@@ -6771,7 +6805,13 @@ program.command("deploy").description("Deploy MCP server from GitHub to Manufact
|
|
|
6771
6805
|
).option(
|
|
6772
6806
|
"--org <slug-or-id>",
|
|
6773
6807
|
"Deploy to a specific organization (by slug or ID)"
|
|
6774
|
-
).option("-y, --yes", "Skip confirmation prompts").
|
|
6808
|
+
).option("-y, --yes", "Skip confirmation prompts").option("--region <region>", "Deploy region: US, EU, or APAC (default: US)").option(
|
|
6809
|
+
"--build-command <cmd>",
|
|
6810
|
+
"Custom build command (overrides auto-detection)"
|
|
6811
|
+
).option(
|
|
6812
|
+
"--start-command <cmd>",
|
|
6813
|
+
"Custom start command (overrides auto-detection)"
|
|
6814
|
+
).action(async (options) => {
|
|
6775
6815
|
await deployCommand({
|
|
6776
6816
|
open: options.open,
|
|
6777
6817
|
name: options.name,
|
|
@@ -6782,11 +6822,15 @@ program.command("deploy").description("Deploy MCP server from GitHub to Manufact
|
|
|
6782
6822
|
envFile: options.envFile,
|
|
6783
6823
|
rootDir: options.rootDir,
|
|
6784
6824
|
org: options.org,
|
|
6785
|
-
yes: options.yes
|
|
6825
|
+
yes: options.yes,
|
|
6826
|
+
region: options.region,
|
|
6827
|
+
buildCommand: options.buildCommand,
|
|
6828
|
+
startCommand: options.startCommand
|
|
6786
6829
|
});
|
|
6787
6830
|
});
|
|
6788
6831
|
program.addCommand(createClientCommand());
|
|
6789
6832
|
program.addCommand(createDeploymentsCommand());
|
|
6833
|
+
program.addCommand(createServersCommand());
|
|
6790
6834
|
program.addCommand(createSkillsCommand());
|
|
6791
6835
|
program.command("generate-types").description(
|
|
6792
6836
|
"Generate TypeScript type definitions for tools (writes .mcp-use/tool-registry.d.ts)"
|