@mcp-use/cli 3.0.0-canary.4 → 3.0.0-canary.6
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/deploy.d.ts +3 -3
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deployments.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 +941 -600
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +940 -599
- package/dist/index.js.map +1 -1
- package/dist/utils/api.d.ts +71 -1
- 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/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");
|
|
@@ -1334,6 +1334,35 @@ var McpUseAPI = class _McpUseAPI {
|
|
|
1334
1334
|
body: JSON.stringify(body)
|
|
1335
1335
|
});
|
|
1336
1336
|
}
|
|
1337
|
+
async listServers(params) {
|
|
1338
|
+
const search = new URLSearchParams();
|
|
1339
|
+
if (params?.organizationId) {
|
|
1340
|
+
search.set("organizationId", params.organizationId);
|
|
1341
|
+
}
|
|
1342
|
+
if (params?.limit != null) {
|
|
1343
|
+
search.set("limit", String(params.limit));
|
|
1344
|
+
}
|
|
1345
|
+
if (params?.skip != null) {
|
|
1346
|
+
search.set("skip", String(params.skip));
|
|
1347
|
+
}
|
|
1348
|
+
if (params?.sort) {
|
|
1349
|
+
search.set("sort", params.sort);
|
|
1350
|
+
}
|
|
1351
|
+
const q = search.toString();
|
|
1352
|
+
return this.request(`/servers${q ? `?${q}` : ""}`);
|
|
1353
|
+
}
|
|
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"
|
|
1363
|
+
}
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1337
1366
|
// ── Deployments ─────────────────────────────────────────────────
|
|
1338
1367
|
async createDeployment(input) {
|
|
1339
1368
|
return this.request("/deployments", {
|
|
@@ -1378,7 +1407,9 @@ var McpUseAPI = class _McpUseAPI {
|
|
|
1378
1407
|
is_connected: resp.installations.length > 0,
|
|
1379
1408
|
installations: resp.installations.map((i) => ({
|
|
1380
1409
|
id: i.id,
|
|
1381
|
-
installation_id: i.installationId
|
|
1410
|
+
installation_id: i.installationId,
|
|
1411
|
+
account_login: i.account?.login ?? "",
|
|
1412
|
+
account_type: i.account?.type ?? "User"
|
|
1382
1413
|
}))
|
|
1383
1414
|
};
|
|
1384
1415
|
}
|
|
@@ -1407,7 +1438,27 @@ var McpUseAPI = class _McpUseAPI {
|
|
|
1407
1438
|
}
|
|
1408
1439
|
async getGitHubAppName() {
|
|
1409
1440
|
if (process.env.MCP_GITHUB_APP_NAME) return process.env.MCP_GITHUB_APP_NAME;
|
|
1410
|
-
|
|
1441
|
+
if (this.baseUrl.includes("localhost")) return "mcp-use-local";
|
|
1442
|
+
if (this.baseUrl.includes(".dev.")) return "mcp-use-dev";
|
|
1443
|
+
return "mcp-use";
|
|
1444
|
+
}
|
|
1445
|
+
/**
|
|
1446
|
+
* Returns the GitHub numeric installation ID (not the DB UUID) for the org.
|
|
1447
|
+
* Used for building direct installation settings URLs.
|
|
1448
|
+
*/
|
|
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
|
+
});
|
|
1411
1462
|
}
|
|
1412
1463
|
};
|
|
1413
1464
|
|
|
@@ -2462,9 +2513,9 @@ async function listPromptsCommand(options) {
|
|
|
2462
2513
|
}
|
|
2463
2514
|
console.log(formatHeader(`Available Prompts (${prompts.length}):`));
|
|
2464
2515
|
console.log("");
|
|
2465
|
-
const tableData = prompts.map((
|
|
2466
|
-
name: source_default.bold(
|
|
2467
|
-
description:
|
|
2516
|
+
const tableData = prompts.map((prompt4) => ({
|
|
2517
|
+
name: source_default.bold(prompt4.name),
|
|
2518
|
+
description: prompt4.description || source_default.gray("No description")
|
|
2468
2519
|
}));
|
|
2469
2520
|
console.log(
|
|
2470
2521
|
formatTable(tableData, [
|
|
@@ -2492,20 +2543,20 @@ async function getPromptCommand(promptName, argsJson, options) {
|
|
|
2492
2543
|
}
|
|
2493
2544
|
}
|
|
2494
2545
|
console.error(formatInfo(`Getting prompt '${promptName}'...`));
|
|
2495
|
-
const
|
|
2546
|
+
const prompt4 = await session.getPrompt(promptName, args);
|
|
2496
2547
|
if (options?.json) {
|
|
2497
|
-
console.log(formatJson(
|
|
2548
|
+
console.log(formatJson(prompt4));
|
|
2498
2549
|
} else {
|
|
2499
2550
|
console.log(formatHeader(`Prompt: ${promptName}`));
|
|
2500
2551
|
console.log("");
|
|
2501
|
-
if (
|
|
2502
|
-
console.log(
|
|
2552
|
+
if (prompt4.description) {
|
|
2553
|
+
console.log(prompt4.description);
|
|
2503
2554
|
console.log("");
|
|
2504
2555
|
}
|
|
2505
|
-
if (
|
|
2556
|
+
if (prompt4.messages) {
|
|
2506
2557
|
console.log(formatHeader("Messages:"));
|
|
2507
2558
|
console.log("");
|
|
2508
|
-
console.log(formatPromptMessages(
|
|
2559
|
+
console.log(formatPromptMessages(prompt4.messages));
|
|
2509
2560
|
}
|
|
2510
2561
|
}
|
|
2511
2562
|
} catch (error) {
|
|
@@ -2645,8 +2696,8 @@ async function interactiveCommand(options) {
|
|
|
2645
2696
|
async (argsInput) => {
|
|
2646
2697
|
try {
|
|
2647
2698
|
const args = argsInput.trim() ? JSON.parse(argsInput) : {};
|
|
2648
|
-
const
|
|
2649
|
-
console.log(formatPromptMessages(
|
|
2699
|
+
const prompt4 = await session.getPrompt(arg, args);
|
|
2700
|
+
console.log(formatPromptMessages(prompt4.messages));
|
|
2650
2701
|
} catch (error) {
|
|
2651
2702
|
console.error(formatError(error.message));
|
|
2652
2703
|
}
|
|
@@ -2812,6 +2863,20 @@ async function getGitInfo(cwd = process.cwd()) {
|
|
|
2812
2863
|
hasUncommittedChanges: uncommittedChanges
|
|
2813
2864
|
};
|
|
2814
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
|
+
}
|
|
2815
2880
|
function isGitHubUrl(url) {
|
|
2816
2881
|
try {
|
|
2817
2882
|
const parsedUrl = new URL(url);
|
|
@@ -2826,6 +2891,22 @@ function isGitHubUrl(url) {
|
|
|
2826
2891
|
return false;
|
|
2827
2892
|
}
|
|
2828
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
|
+
|
|
2829
2910
|
// src/utils/project-link.ts
|
|
2830
2911
|
var import_node_fs6 = require("fs");
|
|
2831
2912
|
var import_node_path4 = __toESM(require("path"), 1);
|
|
@@ -2872,10 +2953,6 @@ ${MCP_USE_DIR}
|
|
|
2872
2953
|
}
|
|
2873
2954
|
|
|
2874
2955
|
// src/commands/deploy.ts
|
|
2875
|
-
var GATEWAY_DOMAIN = "run.mcp-use.com";
|
|
2876
|
-
function buildGatewayUrl(slugOrId) {
|
|
2877
|
-
return `https://${slugOrId}.${GATEWAY_DOMAIN}/mcp`;
|
|
2878
|
-
}
|
|
2879
2956
|
async function parseEnvFile(filePath) {
|
|
2880
2957
|
try {
|
|
2881
2958
|
const content = await import_node_fs7.promises.readFile(filePath, "utf-8");
|
|
@@ -2885,9 +2962,7 @@ async function parseEnvFile(filePath) {
|
|
|
2885
2962
|
let currentValue = "";
|
|
2886
2963
|
for (let line of lines) {
|
|
2887
2964
|
line = line.trim();
|
|
2888
|
-
if (!line || line.startsWith("#"))
|
|
2889
|
-
continue;
|
|
2890
|
-
}
|
|
2965
|
+
if (!line || line.startsWith("#")) continue;
|
|
2891
2966
|
if (currentKey && !line.includes("=")) {
|
|
2892
2967
|
currentValue += "\n" + line;
|
|
2893
2968
|
continue;
|
|
@@ -2898,20 +2973,15 @@ async function parseEnvFile(filePath) {
|
|
|
2898
2973
|
currentValue = "";
|
|
2899
2974
|
}
|
|
2900
2975
|
const equalIndex = line.indexOf("=");
|
|
2901
|
-
if (equalIndex === -1)
|
|
2902
|
-
continue;
|
|
2903
|
-
}
|
|
2976
|
+
if (equalIndex === -1) continue;
|
|
2904
2977
|
const key = line.substring(0, equalIndex).trim();
|
|
2905
|
-
|
|
2978
|
+
const value = line.substring(equalIndex + 1).trim();
|
|
2906
2979
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
2907
|
-
console.log(
|
|
2908
|
-
source_default.yellow(`\u26A0\uFE0F Skipping invalid environment variable key: ${key}`)
|
|
2909
|
-
);
|
|
2980
|
+
console.log(source_default.yellow(`\u26A0\uFE0F Skipping invalid env key: ${key}`));
|
|
2910
2981
|
continue;
|
|
2911
2982
|
}
|
|
2912
2983
|
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
2913
|
-
|
|
2914
|
-
envVars[key] = value;
|
|
2984
|
+
envVars[key] = value.slice(1, -1);
|
|
2915
2985
|
} else if (value.startsWith('"') || value.startsWith("'")) {
|
|
2916
2986
|
currentKey = key;
|
|
2917
2987
|
currentValue = value.slice(1);
|
|
@@ -2935,16 +3005,12 @@ async function parseEnvFile(filePath) {
|
|
|
2935
3005
|
function parseEnvVar(envStr) {
|
|
2936
3006
|
const equalIndex = envStr.indexOf("=");
|
|
2937
3007
|
if (equalIndex === -1) {
|
|
2938
|
-
throw new Error(
|
|
2939
|
-
`Invalid environment variable format: "${envStr}". Expected KEY=VALUE`
|
|
2940
|
-
);
|
|
3008
|
+
throw new Error(`Invalid env format: "${envStr}". Expected KEY=VALUE`);
|
|
2941
3009
|
}
|
|
2942
3010
|
const key = envStr.substring(0, equalIndex).trim();
|
|
2943
3011
|
const value = envStr.substring(equalIndex + 1);
|
|
2944
3012
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
|
|
2945
|
-
throw new Error(
|
|
2946
|
-
`Invalid environment variable key: "${key}". Keys must start with a letter or underscore and contain only letters, numbers, and underscores.`
|
|
2947
|
-
);
|
|
3013
|
+
throw new Error(`Invalid env key: "${key}".`);
|
|
2948
3014
|
}
|
|
2949
3015
|
return { key, value };
|
|
2950
3016
|
}
|
|
@@ -2987,72 +3053,48 @@ async function buildEnvVars(options) {
|
|
|
2987
3053
|
}
|
|
2988
3054
|
async function isMcpProject(cwd = process.cwd()) {
|
|
2989
3055
|
try {
|
|
2990
|
-
const
|
|
2991
|
-
const
|
|
2992
|
-
|
|
2993
|
-
const hasMcpDeps = packageJson2.dependencies?.["mcp-use"] || packageJson2.dependencies?.["@modelcontextprotocol/sdk"] || packageJson2.devDependencies?.["mcp-use"] || packageJson2.devDependencies?.["@modelcontextprotocol/sdk"];
|
|
2994
|
-
const hasMcpScripts = packageJson2.scripts?.mcp || packageJson2.scripts?.["mcp:dev"];
|
|
2995
|
-
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"]);
|
|
2996
3059
|
} catch {
|
|
2997
3060
|
return false;
|
|
2998
3061
|
}
|
|
2999
3062
|
}
|
|
3000
3063
|
async function getProjectName(cwd = process.cwd()) {
|
|
3001
3064
|
try {
|
|
3002
|
-
const
|
|
3003
|
-
const
|
|
3004
|
-
|
|
3005
|
-
if (packageJson2.name) {
|
|
3006
|
-
return packageJson2.name;
|
|
3007
|
-
}
|
|
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;
|
|
3008
3068
|
} catch {
|
|
3009
3069
|
}
|
|
3010
3070
|
return import_node_path5.default.basename(cwd);
|
|
3011
3071
|
}
|
|
3012
|
-
async function detectBuildCommand(cwd
|
|
3072
|
+
async function detectBuildCommand(cwd) {
|
|
3013
3073
|
try {
|
|
3014
|
-
const
|
|
3015
|
-
|
|
3016
|
-
const packageJson2 = JSON.parse(content);
|
|
3017
|
-
if (packageJson2.scripts?.build) {
|
|
3018
|
-
return "npm run build";
|
|
3019
|
-
}
|
|
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";
|
|
3020
3076
|
} catch {
|
|
3021
3077
|
}
|
|
3022
3078
|
return void 0;
|
|
3023
3079
|
}
|
|
3024
|
-
async function detectStartCommand(cwd
|
|
3080
|
+
async function detectStartCommand(cwd) {
|
|
3025
3081
|
try {
|
|
3026
|
-
const
|
|
3027
|
-
const
|
|
3028
|
-
|
|
3029
|
-
if (
|
|
3030
|
-
return "npm start";
|
|
3031
|
-
}
|
|
3032
|
-
if (packageJson2.main) {
|
|
3033
|
-
return `node ${packageJson2.main}`;
|
|
3034
|
-
}
|
|
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}`;
|
|
3035
3086
|
} catch {
|
|
3036
3087
|
}
|
|
3037
3088
|
return void 0;
|
|
3038
3089
|
}
|
|
3039
|
-
async function detectRuntime(cwd
|
|
3040
|
-
|
|
3041
|
-
const pythonFiles = ["requirements.txt", "pyproject.toml", "setup.py"];
|
|
3042
|
-
for (const file of pythonFiles) {
|
|
3043
|
-
try {
|
|
3044
|
-
await import_node_fs7.promises.access(import_node_path5.default.join(cwd, file));
|
|
3045
|
-
return "python";
|
|
3046
|
-
} catch {
|
|
3047
|
-
continue;
|
|
3048
|
-
}
|
|
3049
|
-
}
|
|
3090
|
+
async function detectRuntime(cwd) {
|
|
3091
|
+
for (const f of ["requirements.txt", "pyproject.toml", "setup.py"]) {
|
|
3050
3092
|
try {
|
|
3051
|
-
await import_node_fs7.promises.access(import_node_path5.default.join(cwd,
|
|
3052
|
-
return "
|
|
3093
|
+
await import_node_fs7.promises.access(import_node_path5.default.join(cwd, f));
|
|
3094
|
+
return "python";
|
|
3053
3095
|
} catch {
|
|
3096
|
+
continue;
|
|
3054
3097
|
}
|
|
3055
|
-
} catch {
|
|
3056
3098
|
}
|
|
3057
3099
|
return "node";
|
|
3058
3100
|
}
|
|
@@ -3062,31 +3104,51 @@ async function prompt(question, defaultValue = "n") {
|
|
|
3062
3104
|
input: process.stdin,
|
|
3063
3105
|
output: process.stdout
|
|
3064
3106
|
});
|
|
3065
|
-
const
|
|
3066
|
-
const
|
|
3067
|
-
/(\(y\/n\):)/,
|
|
3068
|
-
`(${defaultIndicator}):`
|
|
3069
|
-
);
|
|
3107
|
+
const indicator = defaultValue === "y" ? "Y/n" : "y/N";
|
|
3108
|
+
const q = question.replace(/(\(y\/n\):)/, `(${indicator}):`);
|
|
3070
3109
|
return new Promise((resolve2) => {
|
|
3071
|
-
rl.question(
|
|
3110
|
+
rl.question(q, (answer) => {
|
|
3072
3111
|
rl.close();
|
|
3073
|
-
const
|
|
3074
|
-
if (
|
|
3075
|
-
|
|
3076
|
-
} else {
|
|
3077
|
-
resolve2(trimmedAnswer === "y" || trimmedAnswer === "yes");
|
|
3078
|
-
}
|
|
3112
|
+
const a = answer.trim().toLowerCase();
|
|
3113
|
+
if (a === "") resolve2(defaultValue === "y");
|
|
3114
|
+
else resolve2(a === "y" || a === "yes");
|
|
3079
3115
|
});
|
|
3080
3116
|
});
|
|
3081
3117
|
}
|
|
3082
|
-
function
|
|
3083
|
-
|
|
3084
|
-
|
|
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 {
|
|
3085
3145
|
}
|
|
3086
|
-
|
|
3087
|
-
|
|
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");
|
|
3088
3151
|
}
|
|
3089
|
-
return "";
|
|
3090
3152
|
}
|
|
3091
3153
|
async function displayDeploymentProgress(api, deploymentId, progressOptions) {
|
|
3092
3154
|
const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
@@ -3096,11 +3158,10 @@ async function displayDeploymentProgress(api, deploymentId, progressOptions) {
|
|
|
3096
3158
|
if (spinnerInterval) clearInterval(spinnerInterval);
|
|
3097
3159
|
process.stdout.write("\r\x1B[K");
|
|
3098
3160
|
spinnerInterval = setInterval(() => {
|
|
3099
|
-
const frame = frames[frameIndex];
|
|
3100
|
-
frameIndex = (frameIndex + 1) % frames.length;
|
|
3101
3161
|
process.stdout.write(
|
|
3102
|
-
"\r" + source_default.cyan(
|
|
3162
|
+
"\r" + source_default.cyan(frames[frameIndex]) + " " + source_default.gray(message)
|
|
3103
3163
|
);
|
|
3164
|
+
frameIndex = (frameIndex + 1) % frames.length;
|
|
3104
3165
|
}, 80);
|
|
3105
3166
|
};
|
|
3106
3167
|
const stopSpinner = () => {
|
|
@@ -3117,57 +3178,49 @@ async function displayDeploymentProgress(api, deploymentId, progressOptions) {
|
|
|
3117
3178
|
let delay = 2e3;
|
|
3118
3179
|
const maxDelay = 1e4;
|
|
3119
3180
|
let buildLogOffset = 0;
|
|
3120
|
-
const sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
3121
3181
|
while (checkCount < maxChecks) {
|
|
3122
|
-
|
|
3182
|
+
const waitMs = delay;
|
|
3183
|
+
await new Promise((r) => setTimeout(r, waitMs));
|
|
3123
3184
|
checkCount++;
|
|
3124
3185
|
try {
|
|
3125
|
-
const
|
|
3186
|
+
const resp = await api.getDeploymentBuildLogs(
|
|
3126
3187
|
deploymentId,
|
|
3127
3188
|
buildLogOffset
|
|
3128
3189
|
);
|
|
3129
|
-
if (
|
|
3130
|
-
const
|
|
3131
|
-
for (const line of logLines) {
|
|
3190
|
+
if (resp.logs.length > 0) {
|
|
3191
|
+
for (const line of resp.logs.split("\n").filter((l) => l.trim())) {
|
|
3132
3192
|
try {
|
|
3133
|
-
const
|
|
3134
|
-
if (
|
|
3193
|
+
const d = JSON.parse(line);
|
|
3194
|
+
if (d.line) {
|
|
3135
3195
|
stopSpinner();
|
|
3136
|
-
const
|
|
3137
|
-
const
|
|
3138
|
-
console.log(
|
|
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));
|
|
3139
3199
|
}
|
|
3140
3200
|
} catch {
|
|
3141
3201
|
stopSpinner();
|
|
3142
3202
|
console.log(source_default.gray(line));
|
|
3143
3203
|
}
|
|
3144
3204
|
}
|
|
3145
|
-
buildLogOffset =
|
|
3205
|
+
buildLogOffset = resp.offset;
|
|
3146
3206
|
}
|
|
3147
3207
|
} catch {
|
|
3148
3208
|
}
|
|
3149
|
-
const
|
|
3150
|
-
if (
|
|
3209
|
+
const dep = await api.getDeployment(deploymentId);
|
|
3210
|
+
if (dep.status === "running") {
|
|
3151
3211
|
stopSpinner();
|
|
3152
|
-
const
|
|
3153
|
-
let dashboardUrl = null;
|
|
3212
|
+
const mcpUrl = getMcpServerUrl(dep);
|
|
3154
3213
|
const webUrl = (await getWebUrl()).replace(/\/$/, "");
|
|
3155
3214
|
const config = await readConfig();
|
|
3156
|
-
|
|
3157
|
-
if (
|
|
3158
|
-
|
|
3159
|
-
dashboardUrl = `${webUrl}/cloud/${orgSlug}/servers/${deployment.serverId}`;
|
|
3160
|
-
} else {
|
|
3161
|
-
dashboardUrl = `${webUrl}/cloud/servers/${deployment.serverId}`;
|
|
3162
|
-
}
|
|
3215
|
+
let dashboardUrl = null;
|
|
3216
|
+
if (dep.serverId) {
|
|
3217
|
+
dashboardUrl = config.orgSlug ? `${webUrl}/cloud/${config.orgSlug}/servers/${dep.serverId}` : `${webUrl}/cloud/servers/${dep.serverId}`;
|
|
3163
3218
|
}
|
|
3164
|
-
const inspectorUrl = `https://inspector.manufact.com/inspector?autoConnect=${encodeURIComponent(
|
|
3165
|
-
mcpServerUrl
|
|
3166
|
-
)}`;
|
|
3219
|
+
const inspectorUrl = `https://inspector.manufact.com/inspector?autoConnect=${encodeURIComponent(mcpUrl)}`;
|
|
3167
3220
|
console.log(source_default.green.bold("\u2713 Deployment successful!\n"));
|
|
3168
|
-
if (
|
|
3221
|
+
if (mcpUrl) {
|
|
3169
3222
|
console.log(source_default.white("\u{1F310} MCP Server URL:"));
|
|
3170
|
-
console.log(source_default.cyan.bold(` ${
|
|
3223
|
+
console.log(source_default.cyan.bold(` ${mcpUrl}
|
|
3171
3224
|
`));
|
|
3172
3225
|
}
|
|
3173
3226
|
if (dashboardUrl) {
|
|
@@ -3178,39 +3231,42 @@ async function displayDeploymentProgress(api, deploymentId, progressOptions) {
|
|
|
3178
3231
|
console.log(source_default.white("\u{1F50D} Inspector URL:"));
|
|
3179
3232
|
console.log(source_default.cyan.bold(` ${inspectorUrl}
|
|
3180
3233
|
`));
|
|
3181
|
-
console.log(source_default.gray("Deployment ID: ") + source_default.white(
|
|
3234
|
+
console.log(source_default.gray("Deployment ID: ") + source_default.white(dep.id));
|
|
3182
3235
|
return;
|
|
3183
|
-
} else if (
|
|
3236
|
+
} else if (dep.status === "failed") {
|
|
3184
3237
|
stopSpinner();
|
|
3185
3238
|
console.log(source_default.red.bold("\u2717 Deployment failed\n"));
|
|
3186
|
-
if (
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
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."
|
|
3195
3257
|
);
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
serverId: deployment.serverId,
|
|
3200
|
-
trigger: "redeploy"
|
|
3201
|
-
});
|
|
3202
|
-
await displayDeploymentProgress(api, newDep.id, progressOptions);
|
|
3203
|
-
return;
|
|
3204
|
-
}
|
|
3258
|
+
console.log(source_default.gray(" Details: " + dep.error));
|
|
3259
|
+
} else {
|
|
3260
|
+
console.log(source_default.red("Error: ") + dep.error);
|
|
3205
3261
|
}
|
|
3206
3262
|
}
|
|
3207
3263
|
process.exit(1);
|
|
3208
|
-
} else if (
|
|
3264
|
+
} else if (dep.status === "building" || dep.status === "pending") {
|
|
3209
3265
|
startSpinner("Building and deploying...");
|
|
3210
3266
|
delay = Math.min(delay * 1.2, maxDelay);
|
|
3211
3267
|
} else {
|
|
3212
3268
|
stopSpinner();
|
|
3213
|
-
console.log(source_default.yellow("\u26A0\uFE0F Deployment status: ") +
|
|
3269
|
+
console.log(source_default.yellow("\u26A0\uFE0F Deployment status: ") + dep.status);
|
|
3214
3270
|
return;
|
|
3215
3271
|
}
|
|
3216
3272
|
}
|
|
@@ -3222,58 +3278,12 @@ async function displayDeploymentProgress(api, deploymentId, progressOptions) {
|
|
|
3222
3278
|
}
|
|
3223
3279
|
async function checkRepoAccess(api, owner, repo) {
|
|
3224
3280
|
try {
|
|
3225
|
-
const
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
} catch (error) {
|
|
3229
|
-
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 {
|
|
3230
3284
|
return false;
|
|
3231
3285
|
}
|
|
3232
3286
|
}
|
|
3233
|
-
var GITHUB_SETUP_POLL_INTERVAL_MS = 2e3;
|
|
3234
|
-
var GITHUB_SETUP_POLL_MAX_MS = 12e4;
|
|
3235
|
-
async function waitForGitHubSetupAfterBrowser(api, repoName, yes) {
|
|
3236
|
-
if (!yes) {
|
|
3237
|
-
console.log(source_default.gray("Waiting for GitHub configuration..."));
|
|
3238
|
-
await prompt(
|
|
3239
|
-
source_default.white("Press Enter when you've completed the GitHub setup..."),
|
|
3240
|
-
"y"
|
|
3241
|
-
);
|
|
3242
|
-
return;
|
|
3243
|
-
}
|
|
3244
|
-
console.log(
|
|
3245
|
-
source_default.gray(
|
|
3246
|
-
"Waiting for GitHub configuration (polling every 2s, up to 2 min)..."
|
|
3247
|
-
)
|
|
3248
|
-
);
|
|
3249
|
-
const deadline = Date.now() + GITHUB_SETUP_POLL_MAX_MS;
|
|
3250
|
-
while (Date.now() < deadline) {
|
|
3251
|
-
try {
|
|
3252
|
-
const status = await api.getGitHubConnectionStatus();
|
|
3253
|
-
if (!status.is_connected) {
|
|
3254
|
-
await new Promise((r) => setTimeout(r, GITHUB_SETUP_POLL_INTERVAL_MS));
|
|
3255
|
-
continue;
|
|
3256
|
-
}
|
|
3257
|
-
if (repoName) {
|
|
3258
|
-
const parts = repoName.split("/");
|
|
3259
|
-
const owner = parts[0];
|
|
3260
|
-
const repo = parts[1];
|
|
3261
|
-
if (owner && repo && await checkRepoAccess(api, owner, repo)) {
|
|
3262
|
-
return;
|
|
3263
|
-
}
|
|
3264
|
-
} else {
|
|
3265
|
-
return;
|
|
3266
|
-
}
|
|
3267
|
-
} catch {
|
|
3268
|
-
}
|
|
3269
|
-
await new Promise((r) => setTimeout(r, GITHUB_SETUP_POLL_INTERVAL_MS));
|
|
3270
|
-
}
|
|
3271
|
-
console.log(
|
|
3272
|
-
source_default.yellow(
|
|
3273
|
-
"\u26A0\uFE0F Timed out waiting for GitHub setup. Continuing with verification..."
|
|
3274
|
-
)
|
|
3275
|
-
);
|
|
3276
|
-
}
|
|
3277
3287
|
async function promptGitHubInstallation(api, reason, repoName, opts) {
|
|
3278
3288
|
const yes = !!opts?.yes;
|
|
3279
3289
|
console.log();
|
|
@@ -3299,96 +3309,48 @@ async function promptGitHubInstallation(api, reason, repoName, opts) {
|
|
|
3299
3309
|
),
|
|
3300
3310
|
"y"
|
|
3301
3311
|
);
|
|
3302
|
-
if (!shouldInstall)
|
|
3303
|
-
return false;
|
|
3304
|
-
}
|
|
3312
|
+
if (!shouldInstall) return false;
|
|
3305
3313
|
try {
|
|
3306
3314
|
const appName = await api.getGitHubAppName();
|
|
3307
|
-
const installUrl =
|
|
3308
|
-
console.log(
|
|
3309
|
-
|
|
3310
|
-
`
|
|
3311
|
-
Opening browser to ${reason === "not_connected" ? "install" : "configure"} GitHub App...`
|
|
3312
|
-
)
|
|
3313
|
-
);
|
|
3315
|
+
const installUrl = `https://github.com/apps/${appName}/installations/new`;
|
|
3316
|
+
console.log(source_default.cyan(`
|
|
3317
|
+
Opening browser...`));
|
|
3314
3318
|
console.log(source_default.gray(`URL: ${installUrl}
|
|
3315
3319
|
`));
|
|
3316
3320
|
if (reason === "no_access") {
|
|
3317
|
-
console.log(source_default.white("Please:"));
|
|
3318
3321
|
console.log(
|
|
3319
|
-
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")
|
|
3320
3323
|
);
|
|
3321
|
-
|
|
3324
|
+
} else {
|
|
3322
3325
|
console.log(
|
|
3323
|
-
source_default.
|
|
3324
|
-
` 3. Grant access to ${source_default.bold(repoName || "your repository")}`
|
|
3325
|
-
)
|
|
3326
|
+
source_default.white("Complete the GitHub App installation, then return here.\n")
|
|
3326
3327
|
);
|
|
3327
|
-
console.log(source_default.cyan(" 4. Save your changes"));
|
|
3328
|
-
console.log(source_default.cyan(" 5. Return here when done\n"));
|
|
3329
|
-
} else {
|
|
3330
|
-
console.log(source_default.white("Please:"));
|
|
3331
|
-
console.log(source_default.cyan(" 1. Select the repositories to grant access"));
|
|
3332
|
-
if (repoName) {
|
|
3333
|
-
console.log(
|
|
3334
|
-
source_default.cyan(` 2. Make sure to include ${source_default.bold(repoName)}`)
|
|
3335
|
-
);
|
|
3336
|
-
console.log(source_default.cyan(" 3. Complete the installation"));
|
|
3337
|
-
} else {
|
|
3338
|
-
console.log(source_default.cyan(" 2. Complete the installation"));
|
|
3339
|
-
}
|
|
3340
|
-
console.log();
|
|
3341
3328
|
}
|
|
3342
3329
|
await open_default(installUrl);
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
const
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
)
|
|
3359
|
-
);
|
|
3360
|
-
} else {
|
|
3361
|
-
console.log(source_default.green(`\u2713 Repository ${repoName} is accessible!
|
|
3362
|
-
`));
|
|
3363
|
-
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 {
|
|
3364
3345
|
}
|
|
3365
|
-
} else {
|
|
3366
|
-
console.log(source_default.green("\u2713 GitHub connected successfully!\n"));
|
|
3367
|
-
verified = true;
|
|
3368
3346
|
}
|
|
3369
|
-
} catch (error) {
|
|
3370
|
-
console.log(
|
|
3371
|
-
source_default.yellow("\u26A0\uFE0F Could not verify GitHub connection (API issue)")
|
|
3372
|
-
);
|
|
3373
|
-
}
|
|
3374
|
-
if (!verified) {
|
|
3375
|
-
console.log(
|
|
3376
|
-
source_default.gray(
|
|
3377
|
-
"\nNote: If you completed the GitHub setup, the deployment may work now.\n"
|
|
3378
|
-
)
|
|
3379
|
-
);
|
|
3380
3347
|
}
|
|
3381
3348
|
return true;
|
|
3382
|
-
} catch
|
|
3383
|
-
console.log(
|
|
3384
|
-
source_default.yellow("\n\u26A0\uFE0F Unable to open GitHub installation automatically")
|
|
3385
|
-
);
|
|
3349
|
+
} catch {
|
|
3350
|
+
console.log(source_default.yellow("\n\u26A0\uFE0F Unable to open browser automatically"));
|
|
3386
3351
|
console.log(
|
|
3387
3352
|
source_default.white("Please visit: ") + source_default.cyan("https://manufact.com/cloud/settings")
|
|
3388
3353
|
);
|
|
3389
|
-
console.log(
|
|
3390
|
-
source_default.gray("Then connect your GitHub account and try again.\n")
|
|
3391
|
-
);
|
|
3392
3354
|
return false;
|
|
3393
3355
|
}
|
|
3394
3356
|
}
|
|
@@ -3396,47 +3358,139 @@ async function deployCommand(options) {
|
|
|
3396
3358
|
try {
|
|
3397
3359
|
const cwd = process.cwd();
|
|
3398
3360
|
if (!await isLoggedIn()) {
|
|
3399
|
-
console.log(source_default.
|
|
3361
|
+
console.log(source_default.cyan.bold("Welcome to Manufact Cloud!\n"));
|
|
3400
3362
|
if (options.yes) {
|
|
3401
3363
|
console.log(
|
|
3402
|
-
source_default.
|
|
3403
|
-
"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."
|
|
3404
3366
|
)
|
|
3405
3367
|
);
|
|
3406
3368
|
process.exit(1);
|
|
3407
3369
|
}
|
|
3408
3370
|
const shouldLogin = await prompt(
|
|
3409
|
-
source_default.white("
|
|
3371
|
+
source_default.white("You need to log in to deploy. Log in now? (Y/n): "),
|
|
3410
3372
|
"y"
|
|
3411
3373
|
);
|
|
3412
|
-
if (shouldLogin) {
|
|
3413
|
-
try {
|
|
3414
|
-
await loginCommand({ silent: false });
|
|
3415
|
-
if (!await isLoggedIn()) {
|
|
3416
|
-
console.log(
|
|
3417
|
-
source_default.red("\u2717 Login verification failed. Please try again.")
|
|
3418
|
-
);
|
|
3419
|
-
process.exit(1);
|
|
3420
|
-
}
|
|
3421
|
-
console.log(source_default.gray("\nContinuing with deployment...\n"));
|
|
3422
|
-
} catch (error) {
|
|
3423
|
-
console.error(
|
|
3424
|
-
source_default.red.bold("\u2717 Login failed:"),
|
|
3425
|
-
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
3426
|
-
);
|
|
3427
|
-
process.exit(1);
|
|
3428
|
-
}
|
|
3429
|
-
} else {
|
|
3374
|
+
if (!shouldLogin) {
|
|
3430
3375
|
console.log(
|
|
3431
3376
|
source_default.gray(
|
|
3432
3377
|
"Run " + source_default.white("npx mcp-use login") + " to get started."
|
|
3433
3378
|
)
|
|
3434
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) {
|
|
3435
3471
|
console.log(source_default.gray("Deployment cancelled."));
|
|
3436
3472
|
process.exit(0);
|
|
3437
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);
|
|
3438
3489
|
}
|
|
3439
|
-
|
|
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"));
|
|
3440
3494
|
const projectDir = options.rootDir ? import_node_path5.default.resolve(cwd, options.rootDir) : cwd;
|
|
3441
3495
|
if (options.rootDir) {
|
|
3442
3496
|
try {
|
|
@@ -3447,292 +3501,274 @@ async function deployCommand(options) {
|
|
|
3447
3501
|
);
|
|
3448
3502
|
process.exit(1);
|
|
3449
3503
|
}
|
|
3450
|
-
console.log(source_default.gray(` Root dir: `) + source_default.cyan(options.rootDir));
|
|
3451
3504
|
}
|
|
3452
3505
|
const isMcp = await isMcpProject(projectDir);
|
|
3453
|
-
if (!isMcp) {
|
|
3506
|
+
if (!isMcp && !options.yes) {
|
|
3454
3507
|
console.log(
|
|
3455
|
-
source_default.yellow(
|
|
3456
|
-
"\u26A0\uFE0F This doesn't appear to be an MCP server project (no mcp-use or @modelcontextprotocol/sdk dependency found)."
|
|
3457
|
-
)
|
|
3508
|
+
source_default.yellow("\u26A0\uFE0F This doesn't look like an MCP server project.")
|
|
3458
3509
|
);
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
console.log(source_default.gray("Deployment cancelled."));
|
|
3465
|
-
process.exit(0);
|
|
3466
|
-
}
|
|
3510
|
+
const shouldContinue = await prompt(
|
|
3511
|
+
source_default.white("Continue anyway? (y/n): ")
|
|
3512
|
+
);
|
|
3513
|
+
if (!shouldContinue) {
|
|
3514
|
+
process.exit(0);
|
|
3467
3515
|
}
|
|
3468
3516
|
console.log();
|
|
3469
3517
|
}
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
console.log(source_default.
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
console.log(source_default.cyan(" git push -u origin main\n"));
|
|
3483
|
-
process.exit(1);
|
|
3484
|
-
}
|
|
3485
|
-
if (!gitInfo.remoteUrl) {
|
|
3486
|
-
console.log(source_default.red("\u2717 No git remote configured\n"));
|
|
3487
|
-
console.log(source_default.white("Add a GitHub remote:"));
|
|
3488
|
-
console.log(source_default.cyan(" git remote add origin <your-github-url>\n"));
|
|
3489
|
-
process.exit(1);
|
|
3490
|
-
}
|
|
3491
|
-
if (!isGitHubUrl(gitInfo.remoteUrl)) {
|
|
3492
|
-
console.log(source_default.red("\u2717 Remote is not a GitHub repository"));
|
|
3493
|
-
console.log(source_default.yellow(` Current remote: ${gitInfo.remoteUrl}
|
|
3494
|
-
`));
|
|
3495
|
-
console.log(source_default.white("Please add a GitHub remote to deploy."));
|
|
3496
|
-
process.exit(1);
|
|
3497
|
-
}
|
|
3498
|
-
if (!gitInfo.owner || !gitInfo.repo) {
|
|
3499
|
-
console.log(source_default.red("\u2717 Could not parse GitHub repository information"));
|
|
3500
|
-
process.exit(1);
|
|
3501
|
-
}
|
|
3502
|
-
if (gitInfo.hasUncommittedChanges) {
|
|
3503
|
-
console.log(source_default.yellow("\u26A0\uFE0F You have uncommitted changes\n"));
|
|
3504
|
-
console.log(source_default.white("Deployments use the code pushed to GitHub."));
|
|
3505
|
-
console.log(
|
|
3506
|
-
source_default.white(
|
|
3507
|
-
"Local changes will not be included until you commit and push.\n"
|
|
3508
|
-
)
|
|
3509
|
-
);
|
|
3510
|
-
if (!options.yes) {
|
|
3511
|
-
const shouldContinue = await prompt(
|
|
3512
|
-
source_default.white("Continue with deployment from GitHub? (y/n): ")
|
|
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"
|
|
3513
3530
|
);
|
|
3514
|
-
if (!
|
|
3515
|
-
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
|
+
);
|
|
3516
3537
|
process.exit(0);
|
|
3517
3538
|
}
|
|
3518
3539
|
}
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
console.log(source_default.white("GitHub repository detected:"));
|
|
3522
|
-
console.log(
|
|
3523
|
-
source_default.gray(` Repository: `) + source_default.cyan(`${gitInfo.owner}/${gitInfo.repo}`)
|
|
3524
|
-
);
|
|
3525
|
-
console.log(
|
|
3526
|
-
source_default.gray(` Branch: `) + source_default.cyan(gitInfo.branch || "main")
|
|
3527
|
-
);
|
|
3528
|
-
if (gitInfo.commitSha) {
|
|
3529
|
-
console.log(
|
|
3530
|
-
source_default.gray(` Commit: `) + source_default.gray(gitInfo.commitSha.substring(0, 7))
|
|
3531
|
-
);
|
|
3532
|
-
}
|
|
3533
|
-
if (gitInfo.commitMessage) {
|
|
3534
|
-
console.log(
|
|
3535
|
-
source_default.gray(` Message: `) + source_default.gray(gitInfo.commitMessage.split("\n")[0])
|
|
3540
|
+
const defaultIdx = installations.findIndex(
|
|
3541
|
+
(i) => i.account_type === "Organization"
|
|
3536
3542
|
);
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
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
|
+
);
|
|
3548
3612
|
process.exit(0);
|
|
3549
3613
|
}
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
const runtime = options.runtime || await detectRuntime(projectDir);
|
|
3553
|
-
const port = options.port || 3e3;
|
|
3554
|
-
const buildCommand = await detectBuildCommand(projectDir);
|
|
3555
|
-
const startCommand = await detectStartCommand(projectDir);
|
|
3556
|
-
const envVars = await buildEnvVars(options);
|
|
3557
|
-
console.log();
|
|
3558
|
-
console.log(source_default.white("Deployment configuration:"));
|
|
3559
|
-
console.log(source_default.gray(` Name: `) + source_default.cyan(projectName));
|
|
3560
|
-
console.log(source_default.gray(` Runtime: `) + source_default.cyan(runtime));
|
|
3561
|
-
console.log(source_default.gray(` Port: `) + source_default.cyan(port));
|
|
3562
|
-
if (options.rootDir) {
|
|
3614
|
+
const repoName = options.yes ? projectName2 : await promptText(source_default.gray("Repository name:"), projectName2);
|
|
3615
|
+
await ensureGitignore(cwd);
|
|
3563
3616
|
console.log(
|
|
3564
|
-
source_default.gray(
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
if (buildCommand) {
|
|
3568
|
-
console.log(source_default.gray(` Build command: `) + source_default.cyan(buildCommand));
|
|
3569
|
-
}
|
|
3570
|
-
if (startCommand) {
|
|
3571
|
-
console.log(source_default.gray(` Start command: `) + source_default.cyan(startCommand));
|
|
3572
|
-
}
|
|
3573
|
-
if (envVars && Object.keys(envVars).length > 0) {
|
|
3574
|
-
console.log(
|
|
3575
|
-
source_default.gray(` Environment: `) + source_default.cyan(`${Object.keys(envVars).length} variable(s)`)
|
|
3576
|
-
);
|
|
3577
|
-
console.log(
|
|
3578
|
-
source_default.gray(` `) + source_default.gray(Object.keys(envVars).join(", "))
|
|
3617
|
+
source_default.gray(
|
|
3618
|
+
`Creating repository on ${repoInstallation.account_login}...`
|
|
3619
|
+
)
|
|
3579
3620
|
);
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
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"
|
|
3588
3639
|
);
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
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)) {
|
|
3646
|
+
console.log(source_default.red("\u2717 Remote is not a GitHub repository"));
|
|
3647
|
+
console.log(source_default.yellow(` Current remote: ${gitInfo.remoteUrl}
|
|
3648
|
+
`));
|
|
3649
|
+
process.exit(1);
|
|
3650
|
+
} else if (!gitInfo.owner || !gitInfo.repo) {
|
|
3651
|
+
console.log(source_default.red("\u2717 Could not parse GitHub repository information"));
|
|
3652
|
+
process.exit(1);
|
|
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"
|
|
3600
3662
|
);
|
|
3601
|
-
|
|
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
|
+
}
|
|
3602
3672
|
}
|
|
3603
|
-
} catch (error) {
|
|
3604
|
-
console.error(
|
|
3605
|
-
source_default.red("\u2717 Failed to resolve organization:"),
|
|
3606
|
-
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
3607
|
-
);
|
|
3608
|
-
process.exit(1);
|
|
3609
3673
|
}
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
if (!
|
|
3617
|
-
|
|
3618
|
-
|
|
3674
|
+
console.log(source_default.gray("Checking repository access..."));
|
|
3675
|
+
const hasAccess = await checkRepoAccess(
|
|
3676
|
+
api,
|
|
3677
|
+
gitInfo.owner,
|
|
3678
|
+
gitInfo.repo
|
|
3679
|
+
);
|
|
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(
|
|
3619
3687
|
api,
|
|
3620
|
-
"
|
|
3688
|
+
"no_access",
|
|
3621
3689
|
repoFullName,
|
|
3622
|
-
{ yes: options.yes }
|
|
3690
|
+
{ yes: options.yes, installationId: githubInstallationId }
|
|
3623
3691
|
);
|
|
3624
|
-
if (!
|
|
3625
|
-
console.log(source_default.gray("Deployment cancelled."));
|
|
3692
|
+
if (!configured) {
|
|
3626
3693
|
process.exit(0);
|
|
3627
3694
|
}
|
|
3628
|
-
const
|
|
3629
|
-
if (!
|
|
3630
|
-
|
|
3631
|
-
source_default.red("\n\u2717 GitHub connection could not be verified.")
|
|
3632
|
-
);
|
|
3695
|
+
const retry = await checkRepoAccess(api, gitInfo.owner, gitInfo.repo);
|
|
3696
|
+
if (!retry) {
|
|
3697
|
+
const appName = await api.getGitHubAppName();
|
|
3633
3698
|
console.log(
|
|
3634
|
-
source_default.
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
process.exit(1);
|
|
3638
|
-
}
|
|
3639
|
-
installationDbId = retryStatus.installations?.[0]?.id;
|
|
3640
|
-
githubVerified = true;
|
|
3641
|
-
} else if (gitInfo.owner && gitInfo.repo) {
|
|
3642
|
-
installationDbId = connectionStatus.installations?.[0]?.id;
|
|
3643
|
-
console.log(source_default.gray("Checking repository access..."));
|
|
3644
|
-
const hasAccess = await checkRepoAccess(
|
|
3645
|
-
api,
|
|
3646
|
-
gitInfo.owner,
|
|
3647
|
-
gitInfo.repo
|
|
3648
|
-
);
|
|
3649
|
-
if (!hasAccess) {
|
|
3650
|
-
const repoFullName = `${gitInfo.owner}/${gitInfo.repo}`;
|
|
3651
|
-
console.log(
|
|
3652
|
-
source_default.yellow(
|
|
3653
|
-
`\u26A0\uFE0F GitHub App doesn't have access to ${source_default.cyan(repoFullName)}`
|
|
3699
|
+
source_default.red(
|
|
3700
|
+
`
|
|
3701
|
+
\u2717 Repository ${source_default.cyan(repoFullName)} is still not accessible.`
|
|
3654
3702
|
)
|
|
3655
3703
|
);
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
);
|
|
3662
|
-
|
|
3663
|
-
console.log(source_default.gray("Deployment cancelled."));
|
|
3664
|
-
process.exit(0);
|
|
3665
|
-
}
|
|
3666
|
-
const hasAccessRetry = await checkRepoAccess(
|
|
3667
|
-
api,
|
|
3668
|
-
gitInfo.owner,
|
|
3669
|
-
gitInfo.repo
|
|
3670
|
-
);
|
|
3671
|
-
if (!hasAccessRetry) {
|
|
3672
|
-
console.log(
|
|
3673
|
-
source_default.red(
|
|
3674
|
-
`
|
|
3675
|
-
\u2717 Repository ${source_default.cyan(repoFullName)} is still not accessible.`
|
|
3676
|
-
)
|
|
3677
|
-
);
|
|
3678
|
-
console.log(
|
|
3679
|
-
source_default.gray(
|
|
3680
|
-
"Please make sure the GitHub App has access to this repository."
|
|
3681
|
-
)
|
|
3682
|
-
);
|
|
3683
|
-
console.log(
|
|
3684
|
-
source_default.cyan(" https://github.com/settings/installations\n")
|
|
3685
|
-
);
|
|
3686
|
-
process.exit(1);
|
|
3687
|
-
}
|
|
3688
|
-
githubVerified = true;
|
|
3689
|
-
} else {
|
|
3690
|
-
console.log(source_default.green("\u2713 Repository access confirmed"));
|
|
3691
|
-
githubVerified = true;
|
|
3704
|
+
console.log(
|
|
3705
|
+
source_default.cyan(
|
|
3706
|
+
` https://github.com/apps/${appName}/installations/new
|
|
3707
|
+
`
|
|
3708
|
+
)
|
|
3709
|
+
);
|
|
3710
|
+
process.exit(1);
|
|
3692
3711
|
}
|
|
3693
3712
|
}
|
|
3694
|
-
|
|
3695
|
-
|
|
3713
|
+
console.log(source_default.green("\u2713 Repository access confirmed"));
|
|
3714
|
+
}
|
|
3715
|
+
const projectName = options.name || await getProjectName(projectDir);
|
|
3716
|
+
const port = options.port || 3e3;
|
|
3717
|
+
const buildCommand = await detectBuildCommand(projectDir);
|
|
3718
|
+
const startCommand = await detectStartCommand(projectDir);
|
|
3719
|
+
const runtime = options.runtime || await detectRuntime(projectDir);
|
|
3720
|
+
const envVars = await buildEnvVars(options);
|
|
3721
|
+
console.log();
|
|
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));
|
|
3725
|
+
console.log(source_default.gray(` Name: `) + source_default.cyan(projectName));
|
|
3726
|
+
console.log(source_default.gray(` Runtime: `) + source_default.cyan(runtime));
|
|
3727
|
+
console.log(source_default.gray(` Port: `) + source_default.cyan(port));
|
|
3728
|
+
if (options.region)
|
|
3729
|
+
console.log(source_default.gray(` Region: `) + source_default.cyan(options.region));
|
|
3730
|
+
if (options.buildCommand)
|
|
3696
3731
|
console.log(
|
|
3697
|
-
source_default.gray(
|
|
3698
|
-
"Error: " + (error instanceof Error ? error.message : "Unknown error")
|
|
3699
|
-
)
|
|
3732
|
+
source_default.gray(` Build command: `) + source_default.cyan(options.buildCommand)
|
|
3700
3733
|
);
|
|
3701
|
-
|
|
3734
|
+
else if (buildCommand)
|
|
3702
3735
|
console.log(
|
|
3703
|
-
source_default.
|
|
3704
|
-
" 1. You have connected GitHub at https://manufact.com/cloud/settings"
|
|
3705
|
-
)
|
|
3736
|
+
source_default.gray(` Build command: `) + source_default.gray(buildCommand + " (auto-detected)")
|
|
3706
3737
|
);
|
|
3738
|
+
if (options.startCommand)
|
|
3707
3739
|
console.log(
|
|
3708
|
-
source_default.
|
|
3740
|
+
source_default.gray(` Start command: `) + source_default.cyan(options.startCommand)
|
|
3709
3741
|
);
|
|
3710
|
-
|
|
3711
|
-
process.exit(1);
|
|
3712
|
-
}
|
|
3713
|
-
if (!githubVerified) {
|
|
3742
|
+
else if (startCommand)
|
|
3714
3743
|
console.log(
|
|
3715
|
-
source_default.
|
|
3744
|
+
source_default.gray(` Start command: `) + source_default.gray(startCommand + " (auto-detected)")
|
|
3716
3745
|
);
|
|
3717
|
-
|
|
3746
|
+
if (Object.keys(envVars).length > 0) {
|
|
3747
|
+
console.log(
|
|
3748
|
+
source_default.gray(` Environment: `) + source_default.cyan(`${Object.keys(envVars).length} variable(s)`)
|
|
3749
|
+
);
|
|
3750
|
+
}
|
|
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
|
+
}
|
|
3718
3758
|
}
|
|
3719
3759
|
const existingLink = !options.new ? await getProjectLink(cwd) : null;
|
|
3720
|
-
|
|
3760
|
+
let serverId = existingLink?.serverId;
|
|
3721
3761
|
if (existingLink && serverId) {
|
|
3722
3762
|
try {
|
|
3723
|
-
const
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
if (existingDeployment && existingDeployment.status !== "failed") {
|
|
3727
|
-
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`));
|
|
3728
3766
|
console.log(source_default.gray(` Redeploying to maintain the same URL...`));
|
|
3729
|
-
console.log(
|
|
3730
|
-
|
|
3731
|
-
`)
|
|
3732
|
-
);
|
|
3767
|
+
console.log(source_default.cyan(` URL: ${getMcpServerUrl(existingDep)}
|
|
3768
|
+
`));
|
|
3733
3769
|
const newDep = await api.createDeployment({
|
|
3734
3770
|
serverId,
|
|
3735
|
-
branch
|
|
3771
|
+
branch,
|
|
3736
3772
|
trigger: "redeploy"
|
|
3737
3773
|
});
|
|
3738
3774
|
await saveProjectLink(cwd, {
|
|
@@ -3740,89 +3776,79 @@ async function deployCommand(options) {
|
|
|
3740
3776
|
linkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3741
3777
|
deploymentId: newDep.id
|
|
3742
3778
|
});
|
|
3743
|
-
await displayDeploymentProgress(api, newDep.id, {
|
|
3744
|
-
yes: options.yes
|
|
3745
|
-
});
|
|
3746
|
-
return;
|
|
3747
|
-
} else {
|
|
3748
3779
|
console.log(
|
|
3749
|
-
source_default.
|
|
3750
|
-
`\u26A0\uFE0F Linked deployment not found or failed, creating new one...`
|
|
3751
|
-
)
|
|
3780
|
+
source_default.green("\u2713 Deployment created: ") + source_default.gray(newDep.id)
|
|
3752
3781
|
);
|
|
3753
|
-
|
|
3782
|
+
await displayDeploymentProgress(api, newDep.id, { yes: options.yes });
|
|
3783
|
+
return;
|
|
3754
3784
|
}
|
|
3755
|
-
} catch (
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
);
|
|
3759
|
-
console.log(source_default.gray(` Will reuse existing server: ${serverId}`));
|
|
3760
|
-
}
|
|
3761
|
-
}
|
|
3762
|
-
if (!options.org) {
|
|
3763
|
-
try {
|
|
3764
|
-
const config = await readConfig();
|
|
3765
|
-
if (config.orgName) {
|
|
3766
|
-
const slug = config.orgSlug ? source_default.gray(` (${config.orgSlug})`) : "";
|
|
3785
|
+
} catch (err) {
|
|
3786
|
+
const is404 = err?.status === 404 || (err?.message ?? "").includes("404");
|
|
3787
|
+
if (is404) {
|
|
3767
3788
|
console.log(
|
|
3768
|
-
source_default.
|
|
3789
|
+
source_default.yellow("\u26A0\uFE0F Previously linked server no longer exists.\n")
|
|
3769
3790
|
);
|
|
3791
|
+
if (!options.yes) {
|
|
3792
|
+
const shouldRecreate = await prompt(
|
|
3793
|
+
source_default.white("Create a new server and deploy? (Y/n): "),
|
|
3794
|
+
"y"
|
|
3795
|
+
);
|
|
3796
|
+
if (!shouldRecreate) {
|
|
3797
|
+
console.log(source_default.gray("Deployment cancelled."));
|
|
3798
|
+
process.exit(0);
|
|
3799
|
+
}
|
|
3800
|
+
}
|
|
3801
|
+
serverId = void 0;
|
|
3770
3802
|
}
|
|
3771
|
-
} catch {
|
|
3772
3803
|
}
|
|
3773
3804
|
}
|
|
3774
3805
|
let deploymentId;
|
|
3775
3806
|
if (serverId) {
|
|
3776
3807
|
console.log(source_default.gray("Creating deployment..."));
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
if (!orgId) {
|
|
3797
|
-
console.log(
|
|
3798
|
-
source_default.red("\u2717 No organization set. Run `mcp-use org switch` first.")
|
|
3799
|
-
);
|
|
3800
|
-
process.exit(1);
|
|
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;
|
|
3826
|
+
}
|
|
3801
3827
|
}
|
|
3828
|
+
}
|
|
3829
|
+
if (!serverId) {
|
|
3830
|
+
const orgId = await api.resolveOrganizationId();
|
|
3802
3831
|
console.log(source_default.gray("Creating server and deployment..."));
|
|
3803
3832
|
const serverResult = await api.createServer({
|
|
3804
3833
|
type: "github",
|
|
3805
3834
|
organizationId: orgId,
|
|
3806
3835
|
installationId: installationDbId,
|
|
3807
3836
|
name: projectName,
|
|
3808
|
-
repoFullName
|
|
3809
|
-
branch
|
|
3837
|
+
repoFullName,
|
|
3838
|
+
branch,
|
|
3810
3839
|
rootDir: options.rootDir,
|
|
3811
3840
|
port,
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3841
|
+
env: Object.keys(envVars).length > 0 ? envVars : void 0,
|
|
3842
|
+
region: options.region,
|
|
3843
|
+
buildCommand: options.buildCommand,
|
|
3844
|
+
startCommand: options.startCommand
|
|
3815
3845
|
});
|
|
3816
3846
|
deploymentId = serverResult.deploymentId ?? "";
|
|
3817
3847
|
if (!deploymentId) {
|
|
3818
3848
|
console.log(
|
|
3819
3849
|
source_default.green("\u2713 Server created: ") + source_default.gray(serverResult.server.id)
|
|
3820
3850
|
);
|
|
3821
|
-
console.log(
|
|
3822
|
-
source_default.yellow(
|
|
3823
|
-
"\u26A0\uFE0F No deployment was triggered. You may need to trigger one manually."
|
|
3824
|
-
)
|
|
3825
|
-
);
|
|
3851
|
+
console.log(source_default.yellow("\u26A0\uFE0F No deployment was triggered."));
|
|
3826
3852
|
return;
|
|
3827
3853
|
}
|
|
3828
3854
|
await saveProjectLink(cwd, {
|
|
@@ -3837,10 +3863,22 @@ async function deployCommand(options) {
|
|
|
3837
3863
|
console.log(source_default.gray(` Future deploys will reuse the same URL
|
|
3838
3864
|
`));
|
|
3839
3865
|
}
|
|
3866
|
+
if (!deploymentId) {
|
|
3867
|
+
console.log(source_default.red("\u2717 No deployment was created."));
|
|
3868
|
+
process.exit(1);
|
|
3869
|
+
}
|
|
3840
3870
|
console.log(
|
|
3841
3871
|
source_default.green("\u2713 Deployment created: ") + source_default.gray(deploymentId)
|
|
3842
3872
|
);
|
|
3843
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
|
+
}
|
|
3881
|
+
}
|
|
3844
3882
|
} catch (error) {
|
|
3845
3883
|
console.error(
|
|
3846
3884
|
source_default.red.bold("\n\u2717 Deployment failed:"),
|
|
@@ -3959,11 +3997,15 @@ async function getDeploymentCommand(deploymentId) {
|
|
|
3959
3997
|
console.log(
|
|
3960
3998
|
source_default.white("Status: ") + statusColor(deployment.status)
|
|
3961
3999
|
);
|
|
3962
|
-
if (deployment.
|
|
4000
|
+
if (deployment.serverId) {
|
|
3963
4001
|
console.log(
|
|
3964
|
-
source_default.white("
|
|
4002
|
+
source_default.white("Server ID: ") + source_default.gray(deployment.serverId)
|
|
3965
4003
|
);
|
|
3966
4004
|
}
|
|
4005
|
+
const mcpUrl = getMcpServerUrl(deployment);
|
|
4006
|
+
if (mcpUrl) {
|
|
4007
|
+
console.log(source_default.white("MCP URL: ") + source_default.cyan(mcpUrl));
|
|
4008
|
+
}
|
|
3967
4009
|
if (deployment.gitBranch) {
|
|
3968
4010
|
console.log(
|
|
3969
4011
|
source_default.white("Branch: ") + source_default.gray(deployment.gitBranch)
|
|
@@ -4280,6 +4322,295 @@ function createDeploymentsCommand() {
|
|
|
4280
4322
|
return deploymentsCommand;
|
|
4281
4323
|
}
|
|
4282
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) {
|
|
4377
|
+
try {
|
|
4378
|
+
if (!await isLoggedIn()) {
|
|
4379
|
+
console.log(source_default.red("\u2717 You are not logged in."));
|
|
4380
|
+
console.log(
|
|
4381
|
+
source_default.gray(
|
|
4382
|
+
"Run " + source_default.white("npx mcp-use login") + " to get started."
|
|
4383
|
+
)
|
|
4384
|
+
);
|
|
4385
|
+
process.exit(1);
|
|
4386
|
+
}
|
|
4387
|
+
const api = await McpUseAPI.create();
|
|
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);
|
|
4395
|
+
}
|
|
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
|
|
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
|
+
`));
|
|
4417
|
+
console.log(
|
|
4418
|
+
source_default.white.bold(
|
|
4419
|
+
`${"ID".padEnd(38)} ${"NAME".padEnd(22)} ${"STATUS".padEnd(14)} ${"REPO".padEnd(32)} ${"MCP URL".padEnd(52)}`
|
|
4420
|
+
)
|
|
4421
|
+
);
|
|
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
|
+
);
|
|
4433
|
+
}
|
|
4434
|
+
console.log();
|
|
4435
|
+
} catch (error) {
|
|
4436
|
+
console.error(
|
|
4437
|
+
source_default.red.bold("\n\u2717 Failed to list servers:"),
|
|
4438
|
+
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
4439
|
+
);
|
|
4440
|
+
process.exit(1);
|
|
4441
|
+
}
|
|
4442
|
+
}
|
|
4443
|
+
async function getServerCommand(idOrSlug, options) {
|
|
4444
|
+
try {
|
|
4445
|
+
if (!await isLoggedIn()) {
|
|
4446
|
+
console.log(source_default.red("\u2717 You are not logged in."));
|
|
4447
|
+
console.log(
|
|
4448
|
+
source_default.gray(
|
|
4449
|
+
"Run " + source_default.white("npx mcp-use login") + " to get started."
|
|
4450
|
+
)
|
|
4451
|
+
);
|
|
4452
|
+
process.exit(1);
|
|
4453
|
+
}
|
|
4454
|
+
const api = await McpUseAPI.create();
|
|
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();
|
|
4539
|
+
} catch (error) {
|
|
4540
|
+
console.error(
|
|
4541
|
+
source_default.red.bold("\n\u2717 Failed to get server:"),
|
|
4542
|
+
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
4543
|
+
);
|
|
4544
|
+
process.exit(1);
|
|
4545
|
+
}
|
|
4546
|
+
}
|
|
4547
|
+
async function deleteServerCommand(serverId, options) {
|
|
4548
|
+
try {
|
|
4549
|
+
if (!await isLoggedIn()) {
|
|
4550
|
+
console.log(source_default.red("\u2717 You are not logged in."));
|
|
4551
|
+
console.log(
|
|
4552
|
+
source_default.gray(
|
|
4553
|
+
"Run " + source_default.white("npx mcp-use login") + " to get started."
|
|
4554
|
+
)
|
|
4555
|
+
);
|
|
4556
|
+
process.exit(1);
|
|
4557
|
+
}
|
|
4558
|
+
const api = await McpUseAPI.create();
|
|
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
|
+
);
|
|
4596
|
+
} catch (error) {
|
|
4597
|
+
console.error(
|
|
4598
|
+
source_default.red.bold("\n\u2717 Failed to delete server:"),
|
|
4599
|
+
source_default.red(error instanceof Error ? error.message : "Unknown error")
|
|
4600
|
+
);
|
|
4601
|
+
process.exit(1);
|
|
4602
|
+
}
|
|
4603
|
+
}
|
|
4604
|
+
function createServersCommand() {
|
|
4605
|
+
const serversCommand = new import_commander3.Command("servers").description(
|
|
4606
|
+
"Manage cloud servers (Git-backed deploy targets)"
|
|
4607
|
+
);
|
|
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;
|
|
4612
|
+
}
|
|
4613
|
+
|
|
4283
4614
|
// src/commands/org.ts
|
|
4284
4615
|
async function ensureLoggedIn() {
|
|
4285
4616
|
if (!await isLoggedIn()) {
|
|
@@ -4400,7 +4731,7 @@ async function orgCurrentCommand() {
|
|
|
4400
4731
|
}
|
|
4401
4732
|
|
|
4402
4733
|
// src/commands/skills.ts
|
|
4403
|
-
var
|
|
4734
|
+
var import_commander4 = require("commander");
|
|
4404
4735
|
var import_node_fs8 = require("fs");
|
|
4405
4736
|
var import_node_os5 = require("os");
|
|
4406
4737
|
var import_node_path6 = require("path");
|
|
@@ -4470,7 +4801,7 @@ async function addSkillsToProject(projectPath) {
|
|
|
4470
4801
|
}
|
|
4471
4802
|
}
|
|
4472
4803
|
function createSkillsCommand() {
|
|
4473
|
-
const skills = new
|
|
4804
|
+
const skills = new import_commander4.Command("skills").description(
|
|
4474
4805
|
"Manage mcp-use AI agent skills"
|
|
4475
4806
|
);
|
|
4476
4807
|
const installAction = async (options) => {
|
|
@@ -4646,7 +4977,7 @@ A new release of ${source_default.bold(PACKAGE_NAME)} is available: ${source_def
|
|
|
4646
4977
|
}
|
|
4647
4978
|
|
|
4648
4979
|
// src/index.ts
|
|
4649
|
-
var program = new
|
|
4980
|
+
var program = new import_commander5.Command();
|
|
4650
4981
|
var packageContent = (0, import_node_fs10.readFileSync)(
|
|
4651
4982
|
import_node_path8.default.join(__dirname, "../package.json"),
|
|
4652
4983
|
"utf-8"
|
|
@@ -6474,7 +6805,13 @@ program.command("deploy").description("Deploy MCP server from GitHub to Manufact
|
|
|
6474
6805
|
).option(
|
|
6475
6806
|
"--org <slug-or-id>",
|
|
6476
6807
|
"Deploy to a specific organization (by slug or ID)"
|
|
6477
|
-
).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) => {
|
|
6478
6815
|
await deployCommand({
|
|
6479
6816
|
open: options.open,
|
|
6480
6817
|
name: options.name,
|
|
@@ -6485,11 +6822,15 @@ program.command("deploy").description("Deploy MCP server from GitHub to Manufact
|
|
|
6485
6822
|
envFile: options.envFile,
|
|
6486
6823
|
rootDir: options.rootDir,
|
|
6487
6824
|
org: options.org,
|
|
6488
|
-
yes: options.yes
|
|
6825
|
+
yes: options.yes,
|
|
6826
|
+
region: options.region,
|
|
6827
|
+
buildCommand: options.buildCommand,
|
|
6828
|
+
startCommand: options.startCommand
|
|
6489
6829
|
});
|
|
6490
6830
|
});
|
|
6491
6831
|
program.addCommand(createClientCommand());
|
|
6492
6832
|
program.addCommand(createDeploymentsCommand());
|
|
6833
|
+
program.addCommand(createServersCommand());
|
|
6493
6834
|
program.addCommand(createSkillsCommand());
|
|
6494
6835
|
program.command("generate-types").description(
|
|
6495
6836
|
"Generate TypeScript type definitions for tools (writes .mcp-use/tool-registry.d.ts)"
|