@mcp-use/cli 2.5.6 → 2.6.0-canary.10

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/index.js CHANGED
@@ -1,371 +1,1444 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") {
11
- for (let key of __getOwnPropNames(from))
12
- if (!__hasOwnProp.call(to, key) && key !== except)
13
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
- }
15
- return to;
16
- };
17
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
- // If the importer is in node compatibility mode or this is not an ESM
19
- // file that has been converted to a CommonJS file using a Babel-
20
- // compatible transform (i.e. "__esModule" has not been set), then set
21
- // "default" to the CommonJS "module.exports" for node compatibility.
22
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
- mod
24
- ));
25
-
26
- // src/index.ts
27
- var import_chalk3 = __toESM(require("chalk"));
28
- var import_commander = require("commander");
29
- var import_config4 = require("dotenv/config");
30
- var import_node_child_process3 = require("child_process");
31
- var import_node_fs3 = require("fs");
32
- var import_promises = require("fs/promises");
33
- var import_node_path3 = __toESM(require("path"));
34
- var import_open3 = __toESM(require("open"));
35
2
 
36
- // src/commands/auth.ts
37
- var import_chalk = __toESM(require("chalk"));
38
- var import_node_http = require("http");
39
- var import_open = __toESM(require("open"));
3
+ // ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3_yaml@2.8.1/node_modules/tsup/assets/esm_shims.js
4
+ import path from "path";
5
+ import { fileURLToPath } from "url";
6
+ var getFilename = () => fileURLToPath(import.meta.url);
7
+ var getDirname = () => path.dirname(getFilename());
8
+ var __dirname = /* @__PURE__ */ getDirname();
40
9
 
41
- // src/utils/config.ts
42
- var import_node_fs = require("fs");
43
- var import_node_path = __toESM(require("path"));
44
- var import_node_os = __toESM(require("os"));
45
- var CONFIG_DIR = import_node_path.default.join(import_node_os.default.homedir(), ".mcp-use");
46
- var CONFIG_FILE = import_node_path.default.join(CONFIG_DIR, "config.json");
47
- var DEFAULT_API_URL = process.env.MCP_API_URL ? process.env.MCP_API_URL.replace(/\/api\/v1$/, "") + "/api/v1" : "https://cloud.mcp-use.com/api/v1";
48
- var DEFAULT_WEB_URL = process.env.MCP_WEB_URL ? process.env.MCP_WEB_URL : "https://mcp-use.com";
49
- async function ensureConfigDir() {
50
- try {
51
- await import_node_fs.promises.mkdir(CONFIG_DIR, { recursive: true });
52
- } catch (error) {
53
- }
54
- }
55
- async function readConfig() {
56
- try {
57
- const content = await import_node_fs.promises.readFile(CONFIG_FILE, "utf-8");
58
- return JSON.parse(content);
59
- } catch (error) {
60
- return {};
10
+ // ../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
11
+ var ANSI_BACKGROUND_OFFSET = 10;
12
+ var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
13
+ var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
14
+ var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
15
+ var styles = {
16
+ modifier: {
17
+ reset: [0, 0],
18
+ // 21 isn't widely supported and 22 does the same thing
19
+ bold: [1, 22],
20
+ dim: [2, 22],
21
+ italic: [3, 23],
22
+ underline: [4, 24],
23
+ overline: [53, 55],
24
+ inverse: [7, 27],
25
+ hidden: [8, 28],
26
+ strikethrough: [9, 29]
27
+ },
28
+ color: {
29
+ black: [30, 39],
30
+ red: [31, 39],
31
+ green: [32, 39],
32
+ yellow: [33, 39],
33
+ blue: [34, 39],
34
+ magenta: [35, 39],
35
+ cyan: [36, 39],
36
+ white: [37, 39],
37
+ // Bright color
38
+ blackBright: [90, 39],
39
+ gray: [90, 39],
40
+ // Alias of `blackBright`
41
+ grey: [90, 39],
42
+ // Alias of `blackBright`
43
+ redBright: [91, 39],
44
+ greenBright: [92, 39],
45
+ yellowBright: [93, 39],
46
+ blueBright: [94, 39],
47
+ magentaBright: [95, 39],
48
+ cyanBright: [96, 39],
49
+ whiteBright: [97, 39]
50
+ },
51
+ bgColor: {
52
+ bgBlack: [40, 49],
53
+ bgRed: [41, 49],
54
+ bgGreen: [42, 49],
55
+ bgYellow: [43, 49],
56
+ bgBlue: [44, 49],
57
+ bgMagenta: [45, 49],
58
+ bgCyan: [46, 49],
59
+ bgWhite: [47, 49],
60
+ // Bright color
61
+ bgBlackBright: [100, 49],
62
+ bgGray: [100, 49],
63
+ // Alias of `bgBlackBright`
64
+ bgGrey: [100, 49],
65
+ // Alias of `bgBlackBright`
66
+ bgRedBright: [101, 49],
67
+ bgGreenBright: [102, 49],
68
+ bgYellowBright: [103, 49],
69
+ bgBlueBright: [104, 49],
70
+ bgMagentaBright: [105, 49],
71
+ bgCyanBright: [106, 49],
72
+ bgWhiteBright: [107, 49]
61
73
  }
62
- }
63
- async function writeConfig(config) {
64
- await ensureConfigDir();
65
- await import_node_fs.promises.writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
66
- }
67
- async function deleteConfig() {
68
- try {
69
- await import_node_fs.promises.unlink(CONFIG_FILE);
70
- } catch (error) {
74
+ };
75
+ var modifierNames = Object.keys(styles.modifier);
76
+ var foregroundColorNames = Object.keys(styles.color);
77
+ var backgroundColorNames = Object.keys(styles.bgColor);
78
+ var colorNames = [...foregroundColorNames, ...backgroundColorNames];
79
+ function assembleStyles() {
80
+ const codes = /* @__PURE__ */ new Map();
81
+ for (const [groupName, group] of Object.entries(styles)) {
82
+ for (const [styleName, style] of Object.entries(group)) {
83
+ styles[styleName] = {
84
+ open: `\x1B[${style[0]}m`,
85
+ close: `\x1B[${style[1]}m`
86
+ };
87
+ group[styleName] = styles[styleName];
88
+ codes.set(style[0], style[1]);
89
+ }
90
+ Object.defineProperty(styles, groupName, {
91
+ value: group,
92
+ enumerable: false
93
+ });
71
94
  }
95
+ Object.defineProperty(styles, "codes", {
96
+ value: codes,
97
+ enumerable: false
98
+ });
99
+ styles.color.close = "\x1B[39m";
100
+ styles.bgColor.close = "\x1B[49m";
101
+ styles.color.ansi = wrapAnsi16();
102
+ styles.color.ansi256 = wrapAnsi256();
103
+ styles.color.ansi16m = wrapAnsi16m();
104
+ styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
105
+ styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
106
+ styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
107
+ Object.defineProperties(styles, {
108
+ rgbToAnsi256: {
109
+ value(red, green, blue) {
110
+ if (red === green && green === blue) {
111
+ if (red < 8) {
112
+ return 16;
113
+ }
114
+ if (red > 248) {
115
+ return 231;
116
+ }
117
+ return Math.round((red - 8) / 247 * 24) + 232;
118
+ }
119
+ return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
120
+ },
121
+ enumerable: false
122
+ },
123
+ hexToRgb: {
124
+ value(hex) {
125
+ const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
126
+ if (!matches) {
127
+ return [0, 0, 0];
128
+ }
129
+ let [colorString] = matches;
130
+ if (colorString.length === 3) {
131
+ colorString = [...colorString].map((character) => character + character).join("");
132
+ }
133
+ const integer = Number.parseInt(colorString, 16);
134
+ return [
135
+ /* eslint-disable no-bitwise */
136
+ integer >> 16 & 255,
137
+ integer >> 8 & 255,
138
+ integer & 255
139
+ /* eslint-enable no-bitwise */
140
+ ];
141
+ },
142
+ enumerable: false
143
+ },
144
+ hexToAnsi256: {
145
+ value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
146
+ enumerable: false
147
+ },
148
+ ansi256ToAnsi: {
149
+ value(code) {
150
+ if (code < 8) {
151
+ return 30 + code;
152
+ }
153
+ if (code < 16) {
154
+ return 90 + (code - 8);
155
+ }
156
+ let red;
157
+ let green;
158
+ let blue;
159
+ if (code >= 232) {
160
+ red = ((code - 232) * 10 + 8) / 255;
161
+ green = red;
162
+ blue = red;
163
+ } else {
164
+ code -= 16;
165
+ const remainder = code % 36;
166
+ red = Math.floor(code / 36) / 5;
167
+ green = Math.floor(remainder / 6) / 5;
168
+ blue = remainder % 6 / 5;
169
+ }
170
+ const value = Math.max(red, green, blue) * 2;
171
+ if (value === 0) {
172
+ return 30;
173
+ }
174
+ let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
175
+ if (value === 2) {
176
+ result += 60;
177
+ }
178
+ return result;
179
+ },
180
+ enumerable: false
181
+ },
182
+ rgbToAnsi: {
183
+ value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
184
+ enumerable: false
185
+ },
186
+ hexToAnsi: {
187
+ value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
188
+ enumerable: false
189
+ }
190
+ });
191
+ return styles;
72
192
  }
73
- async function getApiUrl() {
74
- const config = await readConfig();
75
- return config.apiUrl || DEFAULT_API_URL;
193
+ var ansiStyles = assembleStyles();
194
+ var ansi_styles_default = ansiStyles;
195
+
196
+ // ../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/vendor/supports-color/index.js
197
+ import process2 from "process";
198
+ import os from "os";
199
+ import tty from "tty";
200
+ function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process2.argv) {
201
+ const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
202
+ const position = argv.indexOf(prefix + flag);
203
+ const terminatorPosition = argv.indexOf("--");
204
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
76
205
  }
77
- async function getApiKey() {
78
- const config = await readConfig();
79
- return config.apiKey || null;
206
+ var { env } = process2;
207
+ var flagForceColor;
208
+ if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
209
+ flagForceColor = 0;
210
+ } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
211
+ flagForceColor = 1;
80
212
  }
81
- async function isLoggedIn() {
82
- const apiKey = await getApiKey();
83
- return !!apiKey;
213
+ function envForceColor() {
214
+ if ("FORCE_COLOR" in env) {
215
+ if (env.FORCE_COLOR === "true") {
216
+ return 1;
217
+ }
218
+ if (env.FORCE_COLOR === "false") {
219
+ return 0;
220
+ }
221
+ return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
222
+ }
84
223
  }
85
- async function getWebUrl() {
86
- return DEFAULT_WEB_URL;
224
+ function translateLevel(level) {
225
+ if (level === 0) {
226
+ return false;
227
+ }
228
+ return {
229
+ level,
230
+ hasBasic: true,
231
+ has256: level >= 2,
232
+ has16m: level >= 3
233
+ };
87
234
  }
88
-
89
- // src/utils/api.ts
90
- var McpUseAPI = class _McpUseAPI {
91
- baseUrl;
92
- apiKey;
93
- constructor(baseUrl, apiKey) {
94
- this.baseUrl = baseUrl || "";
95
- this.apiKey = apiKey;
235
+ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
236
+ const noFlagForceColor = envForceColor();
237
+ if (noFlagForceColor !== void 0) {
238
+ flagForceColor = noFlagForceColor;
96
239
  }
97
- /**
98
- * Initialize API client with config
99
- */
100
- static async create() {
101
- const baseUrl = await getApiUrl();
102
- const apiKey = await getApiKey();
103
- return new _McpUseAPI(baseUrl, apiKey ?? void 0);
240
+ const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
241
+ if (forceColor === 0) {
242
+ return 0;
104
243
  }
105
- /**
106
- * Make authenticated request
107
- */
108
- async request(endpoint, options = {}) {
109
- const url = `${this.baseUrl}${endpoint}`;
110
- const headers = {
111
- "Content-Type": "application/json",
112
- ...options.headers || {}
113
- };
114
- if (this.apiKey) {
115
- headers["x-api-key"] = this.apiKey;
116
- }
117
- const response = await fetch(url, {
118
- ...options,
119
- headers
120
- });
121
- if (!response.ok) {
122
- const error = await response.text();
123
- throw new Error(`API request failed: ${response.status} ${error}`);
244
+ if (sniffFlags) {
245
+ if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
246
+ return 3;
124
247
  }
125
- return response.json();
126
- }
127
- /**
128
- * Create API key using JWT token
129
- */
130
- async createApiKey(jwtToken, name = "CLI") {
131
- const url = `${this.baseUrl}/api-key`;
132
- const response = await fetch(url, {
133
- method: "POST",
134
- headers: {
135
- "Content-Type": "application/json",
136
- Authorization: `Bearer ${jwtToken}`
137
- },
138
- body: JSON.stringify({ name })
139
- });
140
- if (!response.ok) {
141
- const error = await response.text();
142
- throw new Error(`Failed to create API key: ${response.status} ${error}`);
248
+ if (hasFlag("color=256")) {
249
+ return 2;
143
250
  }
144
- return response.json();
145
251
  }
146
- /**
147
- * Test authentication
148
- */
149
- async testAuth() {
150
- return this.request("/test-auth");
252
+ if ("TF_BUILD" in env && "AGENT_NAME" in env) {
253
+ return 1;
151
254
  }
152
- /**
153
- * Create deployment
154
- */
155
- async createDeployment(request) {
156
- return this.request("/deployments", {
157
- method: "POST",
158
- body: JSON.stringify(request)
159
- });
255
+ if (haveStream && !streamIsTTY && forceColor === void 0) {
256
+ return 0;
160
257
  }
161
- /**
162
- * Get deployment by ID
163
- */
164
- async getDeployment(deploymentId) {
165
- return this.request(`/deployments/${deploymentId}`);
258
+ const min = forceColor || 0;
259
+ if (env.TERM === "dumb") {
260
+ return min;
166
261
  }
167
- /**
168
- * Stream deployment logs
169
- */
170
- async *streamDeploymentLogs(deploymentId) {
171
- const url = `${this.baseUrl}/deployments/${deploymentId}/logs/stream`;
172
- const headers = {};
173
- if (this.apiKey) {
174
- headers["x-api-key"] = this.apiKey;
175
- }
176
- const response = await fetch(url, { headers });
177
- if (!response.ok) {
178
- throw new Error(`Failed to stream logs: ${response.status}`);
262
+ if (process2.platform === "win32") {
263
+ const osRelease = os.release().split(".");
264
+ if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
265
+ return Number(osRelease[2]) >= 14931 ? 3 : 2;
179
266
  }
180
- if (!response.body) {
181
- throw new Error("Response body is null");
267
+ return 1;
268
+ }
269
+ if ("CI" in env) {
270
+ if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => key in env)) {
271
+ return 3;
182
272
  }
183
- const reader = response.body.getReader();
184
- const decoder = new TextDecoder();
185
- let buffer = "";
186
- try {
187
- while (true) {
188
- const { done, value } = await reader.read();
189
- if (done) break;
190
- buffer += decoder.decode(value, { stream: true });
191
- const lines = buffer.split("\n");
192
- buffer = lines.pop() || "";
193
- for (const line of lines) {
194
- if (line.startsWith("data: ")) {
195
- const data = line.slice(6);
196
- try {
197
- const parsed = JSON.parse(data);
198
- if (parsed.log) {
199
- yield parsed.log;
200
- } else if (parsed.error) {
201
- throw new Error(parsed.error);
202
- }
203
- } catch (e) {
204
- }
205
- }
206
- }
207
- }
208
- } finally {
209
- reader.releaseLock();
273
+ if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
274
+ return 1;
210
275
  }
276
+ return min;
211
277
  }
212
- /**
213
- * Create deployment with source code upload
214
- */
215
- async createDeploymentWithUpload(request, filePath) {
216
- const { readFile: readFile2 } = await import("fs/promises");
217
- const { basename } = await import("path");
218
- const { stat } = await import("fs/promises");
219
- const stats = await stat(filePath);
220
- const maxSize = 2 * 1024 * 1024;
221
- if (stats.size > maxSize) {
222
- throw new Error(
223
- `File size (${(stats.size / 1024 / 1024).toFixed(2)}MB) exceeds maximum of 2MB`
224
- );
225
- }
226
- const fileBuffer = await readFile2(filePath);
227
- const filename = basename(filePath);
228
- const formData = new FormData();
229
- const blob = new Blob([fileBuffer], { type: "application/gzip" });
230
- formData.append("source_file", blob, filename);
231
- formData.append("name", request.name);
232
- formData.append("source_type", "upload");
233
- if (request.source.type === "upload") {
234
- formData.append("runtime", request.source.runtime || "node");
235
- formData.append("port", String(request.source.port || 3e3));
236
- if (request.source.startCommand) {
237
- formData.append("startCommand", request.source.startCommand);
238
- }
239
- if (request.source.buildCommand) {
240
- formData.append("buildCommand", request.source.buildCommand);
278
+ if ("TEAMCITY_VERSION" in env) {
279
+ return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
280
+ }
281
+ if (env.COLORTERM === "truecolor") {
282
+ return 3;
283
+ }
284
+ if (env.TERM === "xterm-kitty") {
285
+ return 3;
286
+ }
287
+ if (env.TERM === "xterm-ghostty") {
288
+ return 3;
289
+ }
290
+ if (env.TERM === "wezterm") {
291
+ return 3;
292
+ }
293
+ if ("TERM_PROGRAM" in env) {
294
+ const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
295
+ switch (env.TERM_PROGRAM) {
296
+ case "iTerm.app": {
297
+ return version >= 3 ? 3 : 2;
241
298
  }
242
- if (request.source.env && Object.keys(request.source.env).length > 0) {
243
- formData.append("env", JSON.stringify(request.source.env));
299
+ case "Apple_Terminal": {
300
+ return 2;
244
301
  }
245
302
  }
246
- if (request.customDomain) {
247
- formData.append("customDomain", request.customDomain);
248
- }
249
- if (request.healthCheckPath) {
250
- formData.append("healthCheckPath", request.healthCheckPath);
251
- }
252
- const url = `${this.baseUrl}/deployments`;
253
- const headers = {};
254
- if (this.apiKey) {
255
- headers["x-api-key"] = this.apiKey;
256
- }
257
- const response = await fetch(url, {
258
- method: "POST",
259
- headers,
260
- body: formData
261
- });
262
- if (!response.ok) {
263
- const error = await response.text();
264
- throw new Error(`Deployment failed: ${error}`);
265
- }
266
- return response.json();
267
303
  }
304
+ if (/-256(color)?$/i.test(env.TERM)) {
305
+ return 2;
306
+ }
307
+ if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
308
+ return 1;
309
+ }
310
+ if ("COLORTERM" in env) {
311
+ return 1;
312
+ }
313
+ return min;
314
+ }
315
+ function createSupportsColor(stream, options = {}) {
316
+ const level = _supportsColor(stream, {
317
+ streamIsTTY: stream && stream.isTTY,
318
+ ...options
319
+ });
320
+ return translateLevel(level);
321
+ }
322
+ var supportsColor = {
323
+ stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
324
+ stderr: createSupportsColor({ isTTY: tty.isatty(2) })
268
325
  };
326
+ var supports_color_default = supportsColor;
269
327
 
270
- // src/commands/auth.ts
271
- var LOGIN_TIMEOUT = 3e5;
272
- async function findAvailablePort(startPort = 8765) {
273
- for (let port = startPort; port < startPort + 100; port++) {
274
- try {
275
- await new Promise((resolve, reject) => {
276
- const server = (0, import_node_http.createServer)();
277
- server.once("error", reject);
278
- server.once("listening", () => {
279
- server.close();
280
- resolve();
281
- });
282
- server.listen(port);
283
- });
284
- return port;
285
- } catch {
286
- continue;
287
- }
328
+ // ../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/utilities.js
329
+ function stringReplaceAll(string, substring, replacer) {
330
+ let index = string.indexOf(substring);
331
+ if (index === -1) {
332
+ return string;
288
333
  }
289
- throw new Error("No available ports found");
334
+ const substringLength = substring.length;
335
+ let endIndex = 0;
336
+ let returnValue = "";
337
+ do {
338
+ returnValue += string.slice(endIndex, index) + substring + replacer;
339
+ endIndex = index + substringLength;
340
+ index = string.indexOf(substring, endIndex);
341
+ } while (index !== -1);
342
+ returnValue += string.slice(endIndex);
343
+ return returnValue;
290
344
  }
291
- async function startCallbackServer(port) {
345
+ function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
346
+ let endIndex = 0;
347
+ let returnValue = "";
348
+ do {
349
+ const gotCR = string[index - 1] === "\r";
350
+ returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
351
+ endIndex = index + 1;
352
+ index = string.indexOf("\n", endIndex);
353
+ } while (index !== -1);
354
+ returnValue += string.slice(endIndex);
355
+ return returnValue;
356
+ }
357
+
358
+ // ../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/index.js
359
+ var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
360
+ var GENERATOR = Symbol("GENERATOR");
361
+ var STYLER = Symbol("STYLER");
362
+ var IS_EMPTY = Symbol("IS_EMPTY");
363
+ var levelMapping = [
364
+ "ansi",
365
+ "ansi",
366
+ "ansi256",
367
+ "ansi16m"
368
+ ];
369
+ var styles2 = /* @__PURE__ */ Object.create(null);
370
+ var applyOptions = (object, options = {}) => {
371
+ if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
372
+ throw new Error("The `level` option should be an integer from 0 to 3");
373
+ }
374
+ const colorLevel = stdoutColor ? stdoutColor.level : 0;
375
+ object.level = options.level === void 0 ? colorLevel : options.level;
376
+ };
377
+ var chalkFactory = (options) => {
378
+ const chalk2 = (...strings) => strings.join(" ");
379
+ applyOptions(chalk2, options);
380
+ Object.setPrototypeOf(chalk2, createChalk.prototype);
381
+ return chalk2;
382
+ };
383
+ function createChalk(options) {
384
+ return chalkFactory(options);
385
+ }
386
+ Object.setPrototypeOf(createChalk.prototype, Function.prototype);
387
+ for (const [styleName, style] of Object.entries(ansi_styles_default)) {
388
+ styles2[styleName] = {
389
+ get() {
390
+ const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
391
+ Object.defineProperty(this, styleName, { value: builder });
392
+ return builder;
393
+ }
394
+ };
395
+ }
396
+ styles2.visible = {
397
+ get() {
398
+ const builder = createBuilder(this, this[STYLER], true);
399
+ Object.defineProperty(this, "visible", { value: builder });
400
+ return builder;
401
+ }
402
+ };
403
+ var getModelAnsi = (model, level, type, ...arguments_) => {
404
+ if (model === "rgb") {
405
+ if (level === "ansi16m") {
406
+ return ansi_styles_default[type].ansi16m(...arguments_);
407
+ }
408
+ if (level === "ansi256") {
409
+ return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
410
+ }
411
+ return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
412
+ }
413
+ if (model === "hex") {
414
+ return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
415
+ }
416
+ return ansi_styles_default[type][model](...arguments_);
417
+ };
418
+ var usedModels = ["rgb", "hex", "ansi256"];
419
+ for (const model of usedModels) {
420
+ styles2[model] = {
421
+ get() {
422
+ const { level } = this;
423
+ return function(...arguments_) {
424
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
425
+ return createBuilder(this, styler, this[IS_EMPTY]);
426
+ };
427
+ }
428
+ };
429
+ const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
430
+ styles2[bgModel] = {
431
+ get() {
432
+ const { level } = this;
433
+ return function(...arguments_) {
434
+ const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
435
+ return createBuilder(this, styler, this[IS_EMPTY]);
436
+ };
437
+ }
438
+ };
439
+ }
440
+ var proto = Object.defineProperties(() => {
441
+ }, {
442
+ ...styles2,
443
+ level: {
444
+ enumerable: true,
445
+ get() {
446
+ return this[GENERATOR].level;
447
+ },
448
+ set(level) {
449
+ this[GENERATOR].level = level;
450
+ }
451
+ }
452
+ });
453
+ var createStyler = (open2, close, parent) => {
454
+ let openAll;
455
+ let closeAll;
456
+ if (parent === void 0) {
457
+ openAll = open2;
458
+ closeAll = close;
459
+ } else {
460
+ openAll = parent.openAll + open2;
461
+ closeAll = close + parent.closeAll;
462
+ }
463
+ return {
464
+ open: open2,
465
+ close,
466
+ openAll,
467
+ closeAll,
468
+ parent
469
+ };
470
+ };
471
+ var createBuilder = (self, _styler, _isEmpty) => {
472
+ const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
473
+ Object.setPrototypeOf(builder, proto);
474
+ builder[GENERATOR] = self;
475
+ builder[STYLER] = _styler;
476
+ builder[IS_EMPTY] = _isEmpty;
477
+ return builder;
478
+ };
479
+ var applyStyle = (self, string) => {
480
+ if (self.level <= 0 || !string) {
481
+ return self[IS_EMPTY] ? "" : string;
482
+ }
483
+ let styler = self[STYLER];
484
+ if (styler === void 0) {
485
+ return string;
486
+ }
487
+ const { openAll, closeAll } = styler;
488
+ if (string.includes("\x1B")) {
489
+ while (styler !== void 0) {
490
+ string = stringReplaceAll(string, styler.close, styler.open);
491
+ styler = styler.parent;
492
+ }
493
+ }
494
+ const lfIndex = string.indexOf("\n");
495
+ if (lfIndex !== -1) {
496
+ string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
497
+ }
498
+ return openAll + string + closeAll;
499
+ };
500
+ Object.defineProperties(createChalk.prototype, styles2);
501
+ var chalk = createChalk();
502
+ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
503
+ var source_default = chalk;
504
+
505
+ // src/index.ts
506
+ import { Command as Command2 } from "commander";
507
+ import "dotenv/config";
508
+ import { spawn } from "child_process";
509
+ import { readFileSync } from "fs";
510
+ import { access, mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
511
+ import path5 from "path";
512
+
513
+ // ../../node_modules/.pnpm/open@11.0.0/node_modules/open/index.js
514
+ import process9 from "process";
515
+ import path2 from "path";
516
+ import { fileURLToPath as fileURLToPath2 } from "url";
517
+ import childProcess3 from "child_process";
518
+ import fs6, { constants as fsConstants3 } from "fs/promises";
519
+
520
+ // ../../node_modules/.pnpm/wsl-utils@0.3.0/node_modules/wsl-utils/index.js
521
+ import { promisify as promisify2 } from "util";
522
+ import childProcess2 from "child_process";
523
+ import fs5, { constants as fsConstants2 } from "fs/promises";
524
+
525
+ // ../../node_modules/.pnpm/is-wsl@3.1.0/node_modules/is-wsl/index.js
526
+ import process3 from "process";
527
+ import os2 from "os";
528
+ import fs3 from "fs";
529
+
530
+ // ../../node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
531
+ import fs2 from "fs";
532
+
533
+ // ../../node_modules/.pnpm/is-docker@3.0.0/node_modules/is-docker/index.js
534
+ import fs from "fs";
535
+ var isDockerCached;
536
+ function hasDockerEnv() {
537
+ try {
538
+ fs.statSync("/.dockerenv");
539
+ return true;
540
+ } catch {
541
+ return false;
542
+ }
543
+ }
544
+ function hasDockerCGroup() {
545
+ try {
546
+ return fs.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
547
+ } catch {
548
+ return false;
549
+ }
550
+ }
551
+ function isDocker() {
552
+ if (isDockerCached === void 0) {
553
+ isDockerCached = hasDockerEnv() || hasDockerCGroup();
554
+ }
555
+ return isDockerCached;
556
+ }
557
+
558
+ // ../../node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
559
+ var cachedResult;
560
+ var hasContainerEnv = () => {
561
+ try {
562
+ fs2.statSync("/run/.containerenv");
563
+ return true;
564
+ } catch {
565
+ return false;
566
+ }
567
+ };
568
+ function isInsideContainer() {
569
+ if (cachedResult === void 0) {
570
+ cachedResult = hasContainerEnv() || isDocker();
571
+ }
572
+ return cachedResult;
573
+ }
574
+
575
+ // ../../node_modules/.pnpm/is-wsl@3.1.0/node_modules/is-wsl/index.js
576
+ var isWsl = () => {
577
+ if (process3.platform !== "linux") {
578
+ return false;
579
+ }
580
+ if (os2.release().toLowerCase().includes("microsoft")) {
581
+ if (isInsideContainer()) {
582
+ return false;
583
+ }
584
+ return true;
585
+ }
586
+ try {
587
+ return fs3.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
588
+ } catch {
589
+ return false;
590
+ }
591
+ };
592
+ var is_wsl_default = process3.env.__IS_WSL_TEST__ ? isWsl : isWsl();
593
+
594
+ // ../../node_modules/.pnpm/powershell-utils@0.1.0/node_modules/powershell-utils/index.js
595
+ import process4 from "process";
596
+ import { Buffer } from "buffer";
597
+ import { promisify } from "util";
598
+ import childProcess from "child_process";
599
+ import fs4, { constants as fsConstants } from "fs/promises";
600
+ var execFile = promisify(childProcess.execFile);
601
+ var powerShellPath = () => `${process4.env.SYSTEMROOT || process4.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
602
+ var executePowerShell = async (command, options = {}) => {
603
+ const {
604
+ powerShellPath: psPath,
605
+ ...execFileOptions
606
+ } = options;
607
+ const encodedCommand = executePowerShell.encodeCommand(command);
608
+ return execFile(
609
+ psPath ?? powerShellPath(),
610
+ [
611
+ ...executePowerShell.argumentsPrefix,
612
+ encodedCommand
613
+ ],
614
+ {
615
+ encoding: "utf8",
616
+ ...execFileOptions
617
+ }
618
+ );
619
+ };
620
+ executePowerShell.argumentsPrefix = [
621
+ "-NoProfile",
622
+ "-NonInteractive",
623
+ "-ExecutionPolicy",
624
+ "Bypass",
625
+ "-EncodedCommand"
626
+ ];
627
+ executePowerShell.encodeCommand = (command) => Buffer.from(command, "utf16le").toString("base64");
628
+ executePowerShell.escapeArgument = (value) => `'${String(value).replaceAll("'", "''")}'`;
629
+
630
+ // ../../node_modules/.pnpm/wsl-utils@0.3.0/node_modules/wsl-utils/index.js
631
+ var execFile2 = promisify2(childProcess2.execFile);
632
+ var wslDrivesMountPoint = /* @__PURE__ */ (() => {
633
+ const defaultMountPoint = "/mnt/";
634
+ let mountPoint;
635
+ return async function() {
636
+ if (mountPoint) {
637
+ return mountPoint;
638
+ }
639
+ const configFilePath = "/etc/wsl.conf";
640
+ let isConfigFileExists = false;
641
+ try {
642
+ await fs5.access(configFilePath, fsConstants2.F_OK);
643
+ isConfigFileExists = true;
644
+ } catch {
645
+ }
646
+ if (!isConfigFileExists) {
647
+ return defaultMountPoint;
648
+ }
649
+ const configContent = await fs5.readFile(configFilePath, { encoding: "utf8" });
650
+ const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
651
+ if (!configMountPoint) {
652
+ return defaultMountPoint;
653
+ }
654
+ mountPoint = configMountPoint.groups.mountPoint.trim();
655
+ mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
656
+ return mountPoint;
657
+ };
658
+ })();
659
+ var powerShellPathFromWsl = async () => {
660
+ const mountPoint = await wslDrivesMountPoint();
661
+ return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
662
+ };
663
+ var powerShellPath2 = is_wsl_default ? powerShellPathFromWsl : powerShellPath;
664
+ var canAccessPowerShellPromise;
665
+ var canAccessPowerShell = async () => {
666
+ canAccessPowerShellPromise ??= (async () => {
667
+ try {
668
+ const psPath = await powerShellPath2();
669
+ await fs5.access(psPath, fsConstants2.X_OK);
670
+ return true;
671
+ } catch {
672
+ return false;
673
+ }
674
+ })();
675
+ return canAccessPowerShellPromise;
676
+ };
677
+ var wslDefaultBrowser = async () => {
678
+ const psPath = await powerShellPath2();
679
+ const command = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
680
+ const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
681
+ return stdout.trim();
682
+ };
683
+ var convertWslPathToWindows = async (path6) => {
684
+ if (/^[a-z]+:\/\//i.test(path6)) {
685
+ return path6;
686
+ }
687
+ try {
688
+ const { stdout } = await execFile2("wslpath", ["-aw", path6], { encoding: "utf8" });
689
+ return stdout.trim();
690
+ } catch {
691
+ return path6;
692
+ }
693
+ };
694
+
695
+ // ../../node_modules/.pnpm/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js
696
+ function defineLazyProperty(object, propertyName, valueGetter) {
697
+ const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
698
+ Object.defineProperty(object, propertyName, {
699
+ configurable: true,
700
+ enumerable: true,
701
+ get() {
702
+ const result = valueGetter();
703
+ define(result);
704
+ return result;
705
+ },
706
+ set(value) {
707
+ define(value);
708
+ }
709
+ });
710
+ return object;
711
+ }
712
+
713
+ // ../../node_modules/.pnpm/default-browser@5.4.0/node_modules/default-browser/index.js
714
+ import { promisify as promisify6 } from "util";
715
+ import process7 from "process";
716
+ import { execFile as execFile6 } from "child_process";
717
+
718
+ // ../../node_modules/.pnpm/default-browser-id@5.0.0/node_modules/default-browser-id/index.js
719
+ import { promisify as promisify3 } from "util";
720
+ import process5 from "process";
721
+ import { execFile as execFile3 } from "child_process";
722
+ var execFileAsync = promisify3(execFile3);
723
+ async function defaultBrowserId() {
724
+ if (process5.platform !== "darwin") {
725
+ throw new Error("macOS only");
726
+ }
727
+ const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
728
+ const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
729
+ return match?.groups.id ?? "com.apple.Safari";
730
+ }
731
+
732
+ // ../../node_modules/.pnpm/run-applescript@7.1.0/node_modules/run-applescript/index.js
733
+ import process6 from "process";
734
+ import { promisify as promisify4 } from "util";
735
+ import { execFile as execFile4, execFileSync } from "child_process";
736
+ var execFileAsync2 = promisify4(execFile4);
737
+ async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
738
+ if (process6.platform !== "darwin") {
739
+ throw new Error("macOS only");
740
+ }
741
+ const outputArguments = humanReadableOutput ? [] : ["-ss"];
742
+ const execOptions = {};
743
+ if (signal) {
744
+ execOptions.signal = signal;
745
+ }
746
+ const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
747
+ return stdout.trim();
748
+ }
749
+
750
+ // ../../node_modules/.pnpm/bundle-name@4.1.0/node_modules/bundle-name/index.js
751
+ async function bundleName(bundleId) {
752
+ return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
753
+ tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
754
+ }
755
+
756
+ // ../../node_modules/.pnpm/default-browser@5.4.0/node_modules/default-browser/windows.js
757
+ import { promisify as promisify5 } from "util";
758
+ import { execFile as execFile5 } from "child_process";
759
+ var execFileAsync3 = promisify5(execFile5);
760
+ var windowsBrowserProgIds = {
761
+ MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
762
+ // The missing `L` is correct.
763
+ MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
764
+ MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
765
+ AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
766
+ ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
767
+ ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
768
+ ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
769
+ ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
770
+ BraveHTML: { name: "Brave", id: "com.brave.Browser" },
771
+ BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
772
+ BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
773
+ BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
774
+ FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
775
+ OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
776
+ VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
777
+ "IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
778
+ };
779
+ var _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
780
+ var UnknownBrowserError = class extends Error {
781
+ };
782
+ async function defaultBrowser(_execFileAsync = execFileAsync3) {
783
+ const { stdout } = await _execFileAsync("reg", [
784
+ "QUERY",
785
+ " HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
786
+ "/v",
787
+ "ProgId"
788
+ ]);
789
+ const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
790
+ if (!match) {
791
+ throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
792
+ }
793
+ const { id } = match.groups;
794
+ const browser = windowsBrowserProgIds[id];
795
+ if (!browser) {
796
+ throw new UnknownBrowserError(`Unknown browser ID: ${id}`);
797
+ }
798
+ return browser;
799
+ }
800
+
801
+ // ../../node_modules/.pnpm/default-browser@5.4.0/node_modules/default-browser/index.js
802
+ var execFileAsync4 = promisify6(execFile6);
803
+ var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
804
+ async function defaultBrowser2() {
805
+ if (process7.platform === "darwin") {
806
+ const id = await defaultBrowserId();
807
+ const name = await bundleName(id);
808
+ return { name, id };
809
+ }
810
+ if (process7.platform === "linux") {
811
+ const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
812
+ const id = stdout.trim();
813
+ const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
814
+ return { name, id };
815
+ }
816
+ if (process7.platform === "win32") {
817
+ return defaultBrowser();
818
+ }
819
+ throw new Error("Only macOS, Linux, and Windows are supported");
820
+ }
821
+
822
+ // ../../node_modules/.pnpm/is-in-ssh@1.0.0/node_modules/is-in-ssh/index.js
823
+ import process8 from "process";
824
+ var isInSsh = Boolean(process8.env.SSH_CONNECTION || process8.env.SSH_CLIENT || process8.env.SSH_TTY);
825
+ var is_in_ssh_default = isInSsh;
826
+
827
+ // ../../node_modules/.pnpm/open@11.0.0/node_modules/open/index.js
828
+ var fallbackAttemptSymbol = Symbol("fallbackAttempt");
829
+ var __dirname2 = import.meta.url ? path2.dirname(fileURLToPath2(import.meta.url)) : "";
830
+ var localXdgOpenPath = path2.join(__dirname2, "xdg-open");
831
+ var { platform, arch } = process9;
832
+ var tryEachApp = async (apps2, opener) => {
833
+ if (apps2.length === 0) {
834
+ return;
835
+ }
836
+ const errors = [];
837
+ for (const app of apps2) {
838
+ try {
839
+ return await opener(app);
840
+ } catch (error) {
841
+ errors.push(error);
842
+ }
843
+ }
844
+ throw new AggregateError(errors, "Failed to open in all supported apps");
845
+ };
846
+ var baseOpen = async (options) => {
847
+ options = {
848
+ wait: false,
849
+ background: false,
850
+ newInstance: false,
851
+ allowNonzeroExitCode: false,
852
+ ...options
853
+ };
854
+ const isFallbackAttempt = options[fallbackAttemptSymbol] === true;
855
+ delete options[fallbackAttemptSymbol];
856
+ if (Array.isArray(options.app)) {
857
+ return tryEachApp(options.app, (singleApp) => baseOpen({
858
+ ...options,
859
+ app: singleApp,
860
+ [fallbackAttemptSymbol]: true
861
+ }));
862
+ }
863
+ let { name: app, arguments: appArguments = [] } = options.app ?? {};
864
+ appArguments = [...appArguments];
865
+ if (Array.isArray(app)) {
866
+ return tryEachApp(app, (appName) => baseOpen({
867
+ ...options,
868
+ app: {
869
+ name: appName,
870
+ arguments: appArguments
871
+ },
872
+ [fallbackAttemptSymbol]: true
873
+ }));
874
+ }
875
+ if (app === "browser" || app === "browserPrivate") {
876
+ const ids = {
877
+ "com.google.chrome": "chrome",
878
+ "google-chrome.desktop": "chrome",
879
+ "com.brave.browser": "brave",
880
+ "org.mozilla.firefox": "firefox",
881
+ "firefox.desktop": "firefox",
882
+ "com.microsoft.msedge": "edge",
883
+ "com.microsoft.edge": "edge",
884
+ "com.microsoft.edgemac": "edge",
885
+ "microsoft-edge.desktop": "edge",
886
+ "com.apple.safari": "safari"
887
+ };
888
+ const flags = {
889
+ chrome: "--incognito",
890
+ brave: "--incognito",
891
+ firefox: "--private-window",
892
+ edge: "--inPrivate"
893
+ // Safari doesn't support private mode via command line
894
+ };
895
+ let browser;
896
+ if (is_wsl_default) {
897
+ const progId = await wslDefaultBrowser();
898
+ const browserInfo = _windowsBrowserProgIdMap.get(progId);
899
+ browser = browserInfo ?? {};
900
+ } else {
901
+ browser = await defaultBrowser2();
902
+ }
903
+ if (browser.id in ids) {
904
+ const browserName = ids[browser.id.toLowerCase()];
905
+ if (app === "browserPrivate") {
906
+ if (browserName === "safari") {
907
+ throw new Error("Safari doesn't support opening in private mode via command line");
908
+ }
909
+ appArguments.push(flags[browserName]);
910
+ }
911
+ return baseOpen({
912
+ ...options,
913
+ app: {
914
+ name: apps[browserName],
915
+ arguments: appArguments
916
+ }
917
+ });
918
+ }
919
+ throw new Error(`${browser.name} is not supported as a default browser`);
920
+ }
921
+ let command;
922
+ const cliArguments = [];
923
+ const childProcessOptions = {};
924
+ let shouldUseWindowsInWsl = false;
925
+ if (is_wsl_default && !isInsideContainer() && !is_in_ssh_default && !app) {
926
+ shouldUseWindowsInWsl = await canAccessPowerShell();
927
+ }
928
+ if (platform === "darwin") {
929
+ command = "open";
930
+ if (options.wait) {
931
+ cliArguments.push("--wait-apps");
932
+ }
933
+ if (options.background) {
934
+ cliArguments.push("--background");
935
+ }
936
+ if (options.newInstance) {
937
+ cliArguments.push("--new");
938
+ }
939
+ if (app) {
940
+ cliArguments.push("-a", app);
941
+ }
942
+ } else if (platform === "win32" || shouldUseWindowsInWsl) {
943
+ command = await powerShellPath2();
944
+ cliArguments.push(...executePowerShell.argumentsPrefix);
945
+ if (!is_wsl_default) {
946
+ childProcessOptions.windowsVerbatimArguments = true;
947
+ }
948
+ if (is_wsl_default && options.target) {
949
+ options.target = await convertWslPathToWindows(options.target);
950
+ }
951
+ const encodedArguments = ["$ProgressPreference = 'SilentlyContinue';", "Start"];
952
+ if (options.wait) {
953
+ encodedArguments.push("-Wait");
954
+ }
955
+ if (app) {
956
+ encodedArguments.push(executePowerShell.escapeArgument(app));
957
+ if (options.target) {
958
+ appArguments.push(options.target);
959
+ }
960
+ } else if (options.target) {
961
+ encodedArguments.push(executePowerShell.escapeArgument(options.target));
962
+ }
963
+ if (appArguments.length > 0) {
964
+ appArguments = appArguments.map((argument) => executePowerShell.escapeArgument(argument));
965
+ encodedArguments.push("-ArgumentList", appArguments.join(","));
966
+ }
967
+ options.target = executePowerShell.encodeCommand(encodedArguments.join(" "));
968
+ if (!options.wait) {
969
+ childProcessOptions.stdio = "ignore";
970
+ }
971
+ } else {
972
+ if (app) {
973
+ command = app;
974
+ } else {
975
+ const isBundled = !__dirname2 || __dirname2 === "/";
976
+ let exeLocalXdgOpen = false;
977
+ try {
978
+ await fs6.access(localXdgOpenPath, fsConstants3.X_OK);
979
+ exeLocalXdgOpen = true;
980
+ } catch {
981
+ }
982
+ const useSystemXdgOpen = process9.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
983
+ command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
984
+ }
985
+ if (appArguments.length > 0) {
986
+ cliArguments.push(...appArguments);
987
+ }
988
+ if (!options.wait) {
989
+ childProcessOptions.stdio = "ignore";
990
+ childProcessOptions.detached = true;
991
+ }
992
+ }
993
+ if (platform === "darwin" && appArguments.length > 0) {
994
+ cliArguments.push("--args", ...appArguments);
995
+ }
996
+ if (options.target) {
997
+ cliArguments.push(options.target);
998
+ }
999
+ const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
1000
+ if (options.wait) {
1001
+ return new Promise((resolve, reject) => {
1002
+ subprocess.once("error", reject);
1003
+ subprocess.once("close", (exitCode) => {
1004
+ if (!options.allowNonzeroExitCode && exitCode !== 0) {
1005
+ reject(new Error(`Exited with code ${exitCode}`));
1006
+ return;
1007
+ }
1008
+ resolve(subprocess);
1009
+ });
1010
+ });
1011
+ }
1012
+ if (isFallbackAttempt) {
1013
+ return new Promise((resolve, reject) => {
1014
+ subprocess.once("error", reject);
1015
+ subprocess.once("spawn", () => {
1016
+ subprocess.once("close", (exitCode) => {
1017
+ subprocess.off("error", reject);
1018
+ if (exitCode !== 0) {
1019
+ reject(new Error(`Exited with code ${exitCode}`));
1020
+ return;
1021
+ }
1022
+ subprocess.unref();
1023
+ resolve(subprocess);
1024
+ });
1025
+ });
1026
+ });
1027
+ }
1028
+ subprocess.unref();
292
1029
  return new Promise((resolve, reject) => {
293
- let tokenResolver = null;
294
- const tokenPromise = new Promise((res) => {
295
- tokenResolver = res;
1030
+ subprocess.once("error", reject);
1031
+ subprocess.once("spawn", () => {
1032
+ subprocess.off("error", reject);
1033
+ resolve(subprocess);
296
1034
  });
297
- const server = (0, import_node_http.createServer)((req, res) => {
298
- if (req.url?.startsWith("/callback")) {
299
- const url = new URL(req.url, `http://localhost:${port}`);
300
- const token = url.searchParams.get("token");
301
- if (token && tokenResolver) {
302
- res.writeHead(200, { "Content-Type": "text/html" });
303
- res.end(`
304
- <!DOCTYPE html>
305
- <html>
306
- <head>
307
- <title>Login Successful</title>
308
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
309
- <style>
310
- * {
311
- margin: 0;
312
- padding: 0;
313
- box-sizing: border-box;
314
- }
315
- body {
316
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
317
- display: flex;
318
- justify-content: center;
319
- align-items: center;
320
- min-height: 100vh;
321
- background: #000;
322
- padding: 1rem;
323
- }
324
- .container {
325
- width: 100%;
326
- max-width: 28rem;
327
- padding: 3rem;
328
- text-align: center;
329
- -webkit-backdrop-filter: blur(40px);
330
- border: 1px solid rgba(255, 255, 255, 0.2);
331
- border-radius: 1.5rem;
332
- box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
333
- }
334
- .icon-container {
335
- display: inline-flex;
336
- align-items: center;
337
- justify-content: center;
338
- width: 6rem;
339
- height: 6rem;
340
- margin-bottom: 2rem;
341
- background: rgba(255, 255, 255, 0.1);
342
- backdrop-filter: blur(10px);
343
- -webkit-backdrop-filter: blur(10px);
344
- border-radius: 50%;
345
- }
346
- .checkmark {
347
- font-size: 4rem;
348
- color: #fff;
349
- line-height: 1;
350
- animation: scaleIn 0.5s ease-out;
351
- }
352
- @keyframes scaleIn {
353
- from {
354
- transform: scale(0);
355
- opacity: 0;
356
- }
357
- to {
358
- transform: scale(1);
359
- opacity: 1;
360
- }
361
- }
362
- h1 {
363
- color: #fff;
364
- margin: 0 0 1rem 0;
365
- font-size: 2.5rem;
366
- font-weight: 700;
367
- letter-spacing: -0.025em;
368
- }
1035
+ });
1036
+ };
1037
+ var open = (target, options) => {
1038
+ if (typeof target !== "string") {
1039
+ throw new TypeError("Expected a `target`");
1040
+ }
1041
+ return baseOpen({
1042
+ ...options,
1043
+ target
1044
+ });
1045
+ };
1046
+ function detectArchBinary(binary) {
1047
+ if (typeof binary === "string" || Array.isArray(binary)) {
1048
+ return binary;
1049
+ }
1050
+ const { [arch]: archBinary } = binary;
1051
+ if (!archBinary) {
1052
+ throw new Error(`${arch} is not supported`);
1053
+ }
1054
+ return archBinary;
1055
+ }
1056
+ function detectPlatformBinary({ [platform]: platformBinary }, { wsl } = {}) {
1057
+ if (wsl && is_wsl_default) {
1058
+ return detectArchBinary(wsl);
1059
+ }
1060
+ if (!platformBinary) {
1061
+ throw new Error(`${platform} is not supported`);
1062
+ }
1063
+ return detectArchBinary(platformBinary);
1064
+ }
1065
+ var apps = {
1066
+ browser: "browser",
1067
+ browserPrivate: "browserPrivate"
1068
+ };
1069
+ defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
1070
+ darwin: "google chrome",
1071
+ win32: "chrome",
1072
+ // `chromium-browser` is the older deb package name used by Ubuntu/Debian before snap.
1073
+ linux: ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"]
1074
+ }, {
1075
+ wsl: {
1076
+ ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
1077
+ x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
1078
+ }
1079
+ }));
1080
+ defineLazyProperty(apps, "brave", () => detectPlatformBinary({
1081
+ darwin: "brave browser",
1082
+ win32: "brave",
1083
+ linux: ["brave-browser", "brave"]
1084
+ }, {
1085
+ wsl: {
1086
+ ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
1087
+ x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
1088
+ }
1089
+ }));
1090
+ defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
1091
+ darwin: "firefox",
1092
+ win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
1093
+ linux: "firefox"
1094
+ }, {
1095
+ wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
1096
+ }));
1097
+ defineLazyProperty(apps, "edge", () => detectPlatformBinary({
1098
+ darwin: "microsoft edge",
1099
+ win32: "msedge",
1100
+ linux: ["microsoft-edge", "microsoft-edge-dev"]
1101
+ }, {
1102
+ wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
1103
+ }));
1104
+ defineLazyProperty(apps, "safari", () => detectPlatformBinary({
1105
+ darwin: "Safari"
1106
+ }));
1107
+ var open_default = open;
1108
+
1109
+ // src/commands/auth.ts
1110
+ import {
1111
+ createServer
1112
+ } from "http";
1113
+
1114
+ // src/utils/config.ts
1115
+ import { promises as fs7 } from "fs";
1116
+ import path3 from "path";
1117
+ import os3 from "os";
1118
+ var CONFIG_DIR = path3.join(os3.homedir(), ".mcp-use");
1119
+ var CONFIG_FILE = path3.join(CONFIG_DIR, "config.json");
1120
+ var DEFAULT_API_URL = process.env.MCP_API_URL ? process.env.MCP_API_URL.replace(/\/api\/v1$/, "") + "/api/v1" : "https://cloud.mcp-use.com/api/v1";
1121
+ var DEFAULT_WEB_URL = process.env.MCP_WEB_URL ? process.env.MCP_WEB_URL : "https://mcp-use.com";
1122
+ async function ensureConfigDir() {
1123
+ try {
1124
+ await fs7.mkdir(CONFIG_DIR, { recursive: true });
1125
+ } catch (error) {
1126
+ }
1127
+ }
1128
+ async function readConfig() {
1129
+ try {
1130
+ const content = await fs7.readFile(CONFIG_FILE, "utf-8");
1131
+ return JSON.parse(content);
1132
+ } catch (error) {
1133
+ return {};
1134
+ }
1135
+ }
1136
+ async function writeConfig(config) {
1137
+ await ensureConfigDir();
1138
+ await fs7.writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
1139
+ }
1140
+ async function deleteConfig() {
1141
+ try {
1142
+ await fs7.unlink(CONFIG_FILE);
1143
+ } catch (error) {
1144
+ }
1145
+ }
1146
+ async function getApiUrl() {
1147
+ const config = await readConfig();
1148
+ return config.apiUrl || DEFAULT_API_URL;
1149
+ }
1150
+ async function getApiKey() {
1151
+ const config = await readConfig();
1152
+ return config.apiKey || null;
1153
+ }
1154
+ async function isLoggedIn() {
1155
+ const apiKey = await getApiKey();
1156
+ return !!apiKey;
1157
+ }
1158
+ async function getWebUrl() {
1159
+ return DEFAULT_WEB_URL;
1160
+ }
1161
+
1162
+ // src/utils/api.ts
1163
+ var McpUseAPI = class _McpUseAPI {
1164
+ baseUrl;
1165
+ apiKey;
1166
+ constructor(baseUrl, apiKey) {
1167
+ this.baseUrl = baseUrl || "";
1168
+ this.apiKey = apiKey;
1169
+ }
1170
+ /**
1171
+ * Initialize API client with config
1172
+ */
1173
+ static async create() {
1174
+ const baseUrl = await getApiUrl();
1175
+ const apiKey = await getApiKey();
1176
+ return new _McpUseAPI(baseUrl, apiKey ?? void 0);
1177
+ }
1178
+ /**
1179
+ * Make authenticated request
1180
+ */
1181
+ async request(endpoint, options = {}) {
1182
+ const url = `${this.baseUrl}${endpoint}`;
1183
+ const headers = {
1184
+ "Content-Type": "application/json",
1185
+ ...options.headers || {}
1186
+ };
1187
+ if (this.apiKey) {
1188
+ headers["x-api-key"] = this.apiKey;
1189
+ }
1190
+ const response = await fetch(url, {
1191
+ ...options,
1192
+ headers
1193
+ });
1194
+ if (!response.ok) {
1195
+ const error = await response.text();
1196
+ throw new Error(`API request failed: ${response.status} ${error}`);
1197
+ }
1198
+ return response.json();
1199
+ }
1200
+ /**
1201
+ * Create API key using JWT token
1202
+ */
1203
+ async createApiKey(jwtToken, name = "CLI") {
1204
+ const url = `${this.baseUrl}/api-key`;
1205
+ const response = await fetch(url, {
1206
+ method: "POST",
1207
+ headers: {
1208
+ "Content-Type": "application/json",
1209
+ Authorization: `Bearer ${jwtToken}`
1210
+ },
1211
+ body: JSON.stringify({ name })
1212
+ });
1213
+ if (!response.ok) {
1214
+ const error = await response.text();
1215
+ throw new Error(`Failed to create API key: ${response.status} ${error}`);
1216
+ }
1217
+ return response.json();
1218
+ }
1219
+ /**
1220
+ * Test authentication
1221
+ */
1222
+ async testAuth() {
1223
+ return this.request("/test-auth");
1224
+ }
1225
+ /**
1226
+ * Create deployment
1227
+ */
1228
+ async createDeployment(request) {
1229
+ return this.request("/deployments", {
1230
+ method: "POST",
1231
+ body: JSON.stringify(request)
1232
+ });
1233
+ }
1234
+ /**
1235
+ * Get deployment by ID
1236
+ */
1237
+ async getDeployment(deploymentId) {
1238
+ return this.request(`/deployments/${deploymentId}`);
1239
+ }
1240
+ /**
1241
+ * Stream deployment logs
1242
+ */
1243
+ async *streamDeploymentLogs(deploymentId) {
1244
+ const url = `${this.baseUrl}/deployments/${deploymentId}/logs/stream`;
1245
+ const headers = {};
1246
+ if (this.apiKey) {
1247
+ headers["x-api-key"] = this.apiKey;
1248
+ }
1249
+ const response = await fetch(url, { headers });
1250
+ if (!response.ok) {
1251
+ throw new Error(`Failed to stream logs: ${response.status}`);
1252
+ }
1253
+ if (!response.body) {
1254
+ throw new Error("Response body is null");
1255
+ }
1256
+ const reader = response.body.getReader();
1257
+ const decoder = new TextDecoder();
1258
+ let buffer = "";
1259
+ try {
1260
+ while (true) {
1261
+ const { done, value } = await reader.read();
1262
+ if (done) break;
1263
+ buffer += decoder.decode(value, { stream: true });
1264
+ const lines = buffer.split("\n");
1265
+ buffer = lines.pop() || "";
1266
+ for (const line of lines) {
1267
+ if (line.startsWith("data: ")) {
1268
+ const data = line.slice(6);
1269
+ try {
1270
+ const parsed = JSON.parse(data);
1271
+ if (parsed.log) {
1272
+ yield parsed.log;
1273
+ } else if (parsed.error) {
1274
+ throw new Error(parsed.error);
1275
+ }
1276
+ } catch (e) {
1277
+ }
1278
+ }
1279
+ }
1280
+ }
1281
+ } finally {
1282
+ reader.releaseLock();
1283
+ }
1284
+ }
1285
+ /**
1286
+ * Create deployment with source code upload
1287
+ */
1288
+ async createDeploymentWithUpload(request, filePath) {
1289
+ const { readFile: readFile3 } = await import("fs/promises");
1290
+ const { basename } = await import("path");
1291
+ const { stat } = await import("fs/promises");
1292
+ const stats = await stat(filePath);
1293
+ const maxSize = 2 * 1024 * 1024;
1294
+ if (stats.size > maxSize) {
1295
+ throw new Error(
1296
+ `File size (${(stats.size / 1024 / 1024).toFixed(2)}MB) exceeds maximum of 2MB`
1297
+ );
1298
+ }
1299
+ const fileBuffer = await readFile3(filePath);
1300
+ const filename = basename(filePath);
1301
+ const formData = new FormData();
1302
+ const blob = new Blob([fileBuffer], { type: "application/gzip" });
1303
+ formData.append("source_file", blob, filename);
1304
+ formData.append("name", request.name);
1305
+ formData.append("source_type", "upload");
1306
+ if (request.source.type === "upload") {
1307
+ formData.append("runtime", request.source.runtime || "node");
1308
+ formData.append("port", String(request.source.port || 3e3));
1309
+ if (request.source.startCommand) {
1310
+ formData.append("startCommand", request.source.startCommand);
1311
+ }
1312
+ if (request.source.buildCommand) {
1313
+ formData.append("buildCommand", request.source.buildCommand);
1314
+ }
1315
+ if (request.source.env && Object.keys(request.source.env).length > 0) {
1316
+ formData.append("env", JSON.stringify(request.source.env));
1317
+ }
1318
+ }
1319
+ if (request.customDomain) {
1320
+ formData.append("customDomain", request.customDomain);
1321
+ }
1322
+ if (request.healthCheckPath) {
1323
+ formData.append("healthCheckPath", request.healthCheckPath);
1324
+ }
1325
+ const url = `${this.baseUrl}/deployments`;
1326
+ const headers = {};
1327
+ if (this.apiKey) {
1328
+ headers["x-api-key"] = this.apiKey;
1329
+ }
1330
+ const response = await fetch(url, {
1331
+ method: "POST",
1332
+ headers,
1333
+ body: formData
1334
+ });
1335
+ if (!response.ok) {
1336
+ const error = await response.text();
1337
+ throw new Error(`Deployment failed: ${error}`);
1338
+ }
1339
+ return response.json();
1340
+ }
1341
+ };
1342
+
1343
+ // src/commands/auth.ts
1344
+ var LOGIN_TIMEOUT = 3e5;
1345
+ async function findAvailablePort(startPort = 8765) {
1346
+ for (let port = startPort; port < startPort + 100; port++) {
1347
+ try {
1348
+ await new Promise((resolve, reject) => {
1349
+ const server = createServer();
1350
+ server.once("error", reject);
1351
+ server.once("listening", () => {
1352
+ server.close();
1353
+ resolve();
1354
+ });
1355
+ server.listen(port);
1356
+ });
1357
+ return port;
1358
+ } catch {
1359
+ continue;
1360
+ }
1361
+ }
1362
+ throw new Error("No available ports found");
1363
+ }
1364
+ async function startCallbackServer(port) {
1365
+ return new Promise((resolve, reject) => {
1366
+ let tokenResolver = null;
1367
+ const tokenPromise = new Promise((res) => {
1368
+ tokenResolver = res;
1369
+ });
1370
+ const server = createServer((req, res) => {
1371
+ if (req.url?.startsWith("/callback")) {
1372
+ const url = new URL(req.url, `http://localhost:${port}`);
1373
+ const token = url.searchParams.get("token");
1374
+ if (token && tokenResolver) {
1375
+ res.writeHead(200, { "Content-Type": "text/html" });
1376
+ res.end(`
1377
+ <!DOCTYPE html>
1378
+ <html>
1379
+ <head>
1380
+ <title>Login Successful</title>
1381
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
1382
+ <style>
1383
+ * {
1384
+ margin: 0;
1385
+ padding: 0;
1386
+ box-sizing: border-box;
1387
+ }
1388
+ body {
1389
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
1390
+ display: flex;
1391
+ justify-content: center;
1392
+ align-items: center;
1393
+ min-height: 100vh;
1394
+ background: #000;
1395
+ padding: 1rem;
1396
+ }
1397
+ .container {
1398
+ width: 100%;
1399
+ max-width: 28rem;
1400
+ padding: 3rem;
1401
+ text-align: center;
1402
+ -webkit-backdrop-filter: blur(40px);
1403
+ border: 1px solid rgba(255, 255, 255, 0.2);
1404
+ border-radius: 1.5rem;
1405
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
1406
+ }
1407
+ .icon-container {
1408
+ display: inline-flex;
1409
+ align-items: center;
1410
+ justify-content: center;
1411
+ width: 6rem;
1412
+ height: 6rem;
1413
+ margin-bottom: 2rem;
1414
+ background: rgba(255, 255, 255, 0.1);
1415
+ backdrop-filter: blur(10px);
1416
+ -webkit-backdrop-filter: blur(10px);
1417
+ border-radius: 50%;
1418
+ }
1419
+ .checkmark {
1420
+ font-size: 4rem;
1421
+ color: #fff;
1422
+ line-height: 1;
1423
+ animation: scaleIn 0.5s ease-out;
1424
+ }
1425
+ @keyframes scaleIn {
1426
+ from {
1427
+ transform: scale(0);
1428
+ opacity: 0;
1429
+ }
1430
+ to {
1431
+ transform: scale(1);
1432
+ opacity: 1;
1433
+ }
1434
+ }
1435
+ h1 {
1436
+ color: #fff;
1437
+ margin: 0 0 1rem 0;
1438
+ font-size: 2.5rem;
1439
+ font-weight: 700;
1440
+ letter-spacing: -0.025em;
1441
+ }
369
1442
  p {
370
1443
  color: rgba(255, 255, 255, 0.8);
371
1444
  margin: 0 0 2rem 0;
@@ -480,695 +1553,1680 @@ async function startCallbackServer(port) {
480
1553
  `);
481
1554
  }
482
1555
  }
483
- });
484
- server.listen(port, () => {
485
- resolve({ server, token: tokenPromise });
486
- });
487
- server.on("error", reject);
488
- });
489
- }
490
- async function loginCommand() {
491
- try {
492
- if (await isLoggedIn()) {
1556
+ });
1557
+ server.listen(port, () => {
1558
+ resolve({ server, token: tokenPromise });
1559
+ });
1560
+ server.on("error", reject);
1561
+ });
1562
+ }
1563
+ async function loginCommand() {
1564
+ try {
1565
+ if (await isLoggedIn()) {
1566
+ console.log(
1567
+ source_default.yellow(
1568
+ "\u26A0\uFE0F You are already logged in. Run 'mcp-use logout' first if you want to login with a different account."
1569
+ )
1570
+ );
1571
+ return;
1572
+ }
1573
+ console.log(source_default.cyan.bold("\u{1F510} Logging in to mcp-use cloud...\n"));
1574
+ const port = await findAvailablePort();
1575
+ const redirectUri = `http://localhost:${port}/callback`;
1576
+ console.log(source_default.gray(`Starting local server on port ${port}...`));
1577
+ const { server, token } = await startCallbackServer(port);
1578
+ const webUrl = await getWebUrl();
1579
+ const loginUrl = `${webUrl}/auth/cli?redirect_uri=${encodeURIComponent(redirectUri)}`;
1580
+ console.log(source_default.gray(`Opening browser to ${webUrl}/auth/cli...
1581
+ `));
1582
+ console.log(
1583
+ source_default.white(
1584
+ "If the browser doesn't open automatically, please visit:\n" + source_default.cyan(loginUrl)
1585
+ )
1586
+ );
1587
+ await open_default(loginUrl);
1588
+ console.log(
1589
+ source_default.gray("\nWaiting for authentication... (this may take a moment)")
1590
+ );
1591
+ const jwtToken = await Promise.race([
1592
+ token,
1593
+ new Promise(
1594
+ (_, reject) => setTimeout(
1595
+ () => reject(new Error("Login timeout - please try again")),
1596
+ LOGIN_TIMEOUT
1597
+ )
1598
+ )
1599
+ ]);
1600
+ server.close();
1601
+ console.log(
1602
+ source_default.gray("Received authentication token, creating API key...")
1603
+ );
1604
+ const api = await McpUseAPI.create();
1605
+ const apiKeyResponse = await api.createApiKey(jwtToken, "CLI");
1606
+ await writeConfig({
1607
+ apiKey: apiKeyResponse.api_key
1608
+ });
1609
+ console.log(source_default.green.bold("\n\u2713 Successfully logged in!"));
1610
+ console.log(
1611
+ source_default.gray(
1612
+ `
1613
+ Your API key has been saved to ${source_default.white("~/.mcp-use/config.json")}`
1614
+ )
1615
+ );
1616
+ console.log(
1617
+ source_default.gray(
1618
+ "You can now deploy your MCP servers with " + source_default.white("mcp-use deploy")
1619
+ )
1620
+ );
1621
+ process.exit(0);
1622
+ } catch (error) {
1623
+ console.error(
1624
+ source_default.red.bold("\n\u2717 Login failed:"),
1625
+ source_default.red(error instanceof Error ? error.message : "Unknown error")
1626
+ );
1627
+ process.exit(1);
1628
+ }
1629
+ }
1630
+ async function logoutCommand() {
1631
+ try {
1632
+ if (!await isLoggedIn()) {
1633
+ console.log(source_default.yellow("\u26A0\uFE0F You are not logged in."));
1634
+ return;
1635
+ }
1636
+ console.log(source_default.cyan.bold("\u{1F513} Logging out...\n"));
1637
+ await deleteConfig();
1638
+ console.log(source_default.green.bold("\u2713 Successfully logged out!"));
1639
+ console.log(
1640
+ source_default.gray(
1641
+ "\nYour local config has been deleted. The API key will remain active until revoked from the web interface."
1642
+ )
1643
+ );
1644
+ } catch (error) {
1645
+ console.error(
1646
+ source_default.red.bold("\n\u2717 Logout failed:"),
1647
+ source_default.red(error instanceof Error ? error.message : "Unknown error")
1648
+ );
1649
+ process.exit(1);
1650
+ }
1651
+ }
1652
+ async function whoamiCommand() {
1653
+ try {
1654
+ if (!await isLoggedIn()) {
1655
+ console.log(source_default.yellow("\u26A0\uFE0F You are not logged in."));
1656
+ console.log(
1657
+ source_default.gray("Run " + source_default.white("mcp-use login") + " to get started.")
1658
+ );
1659
+ return;
1660
+ }
1661
+ console.log(source_default.cyan.bold("\u{1F464} Current user:\n"));
1662
+ const api = await McpUseAPI.create();
1663
+ const authInfo = await api.testAuth();
1664
+ console.log(source_default.white("Email: ") + source_default.cyan(authInfo.email));
1665
+ console.log(source_default.white("User ID: ") + source_default.gray(authInfo.user_id));
1666
+ const apiKey = await getApiKey();
1667
+ if (apiKey) {
1668
+ const masked = apiKey.substring(0, 6) + "...";
1669
+ console.log(source_default.white("API Key: ") + source_default.gray(masked));
1670
+ }
1671
+ } catch (error) {
1672
+ console.error(
1673
+ source_default.red.bold("\n\u2717 Failed to get user info:"),
1674
+ source_default.red(error instanceof Error ? error.message : "Unknown error")
1675
+ );
1676
+ process.exit(1);
1677
+ }
1678
+ }
1679
+
1680
+ // src/commands/deploy.ts
1681
+ import { promises as fs8 } from "fs";
1682
+ import path4 from "path";
1683
+ import os4 from "os";
1684
+ import { exec as exec2 } from "child_process";
1685
+ import { promisify as promisify8 } from "util";
1686
+
1687
+ // src/utils/git.ts
1688
+ import { exec } from "child_process";
1689
+ import { promisify as promisify7 } from "util";
1690
+ var execAsync = promisify7(exec);
1691
+ async function gitCommand(command, cwd = process.cwd()) {
1692
+ try {
1693
+ const { stdout } = await execAsync(command, { cwd });
1694
+ return stdout.trim();
1695
+ } catch (error) {
1696
+ return null;
1697
+ }
1698
+ }
1699
+ async function isGitRepo(cwd = process.cwd()) {
1700
+ const result = await gitCommand("git rev-parse --is-inside-work-tree", cwd);
1701
+ return result === "true";
1702
+ }
1703
+ async function getRemoteUrl(cwd = process.cwd()) {
1704
+ return gitCommand("git config --get remote.origin.url", cwd);
1705
+ }
1706
+ function parseGitHubUrl(url) {
1707
+ const sshMatch = url.match(/git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/);
1708
+ const httpsMatch = url.match(
1709
+ /https:\/\/github\.com\/([^/]+)\/(.+?)(?:\.git)?$/
1710
+ );
1711
+ const match = sshMatch || httpsMatch;
1712
+ if (!match) return null;
1713
+ return {
1714
+ owner: match[1],
1715
+ repo: match[2]
1716
+ };
1717
+ }
1718
+ async function getCurrentBranch(cwd = process.cwd()) {
1719
+ return gitCommand("git rev-parse --abbrev-ref HEAD", cwd);
1720
+ }
1721
+ async function getCommitSha(cwd = process.cwd()) {
1722
+ return gitCommand("git rev-parse HEAD", cwd);
1723
+ }
1724
+ async function getCommitMessage(cwd = process.cwd()) {
1725
+ return gitCommand("git log -1 --pretty=%B", cwd);
1726
+ }
1727
+ async function getGitInfo(cwd = process.cwd()) {
1728
+ const isRepo = await isGitRepo(cwd);
1729
+ if (!isRepo) {
1730
+ return { isGitRepo: false };
1731
+ }
1732
+ const remoteUrl = await getRemoteUrl(cwd);
1733
+ const branch = await getCurrentBranch(cwd);
1734
+ const commitSha = await getCommitSha(cwd);
1735
+ const commitMessage = await getCommitMessage(cwd);
1736
+ let owner;
1737
+ let repo;
1738
+ if (remoteUrl) {
1739
+ const parsed = parseGitHubUrl(remoteUrl);
1740
+ if (parsed) {
1741
+ owner = parsed.owner;
1742
+ repo = parsed.repo;
1743
+ }
1744
+ }
1745
+ return {
1746
+ isGitRepo: true,
1747
+ remoteUrl: remoteUrl || void 0,
1748
+ owner,
1749
+ repo,
1750
+ branch: branch || void 0,
1751
+ commitSha: commitSha || void 0,
1752
+ commitMessage: commitMessage || void 0
1753
+ };
1754
+ }
1755
+ function isGitHubUrl(url) {
1756
+ try {
1757
+ const parsedUrl = new URL(url);
1758
+ return parsedUrl.hostname === "github.com" || parsedUrl.hostname === "www.github.com";
1759
+ } catch {
1760
+ const sshMatch = url.match(/^git@([^:/]+)[:/]/);
1761
+ if (sshMatch) {
1762
+ const host = sshMatch[1];
1763
+ return host === "github.com" || host === "www.github.com";
1764
+ }
1765
+ }
1766
+ return false;
1767
+ }
1768
+
1769
+ // src/commands/deploy.ts
1770
+ var execAsync2 = promisify8(exec2);
1771
+ async function isMcpProject(cwd = process.cwd()) {
1772
+ try {
1773
+ const packageJsonPath = path4.join(cwd, "package.json");
1774
+ const content = await fs8.readFile(packageJsonPath, "utf-8");
1775
+ const packageJson2 = JSON.parse(content);
1776
+ const hasMcpDeps = packageJson2.dependencies?.["mcp-use"] || packageJson2.dependencies?.["@modelcontextprotocol/sdk"] || packageJson2.devDependencies?.["mcp-use"] || packageJson2.devDependencies?.["@modelcontextprotocol/sdk"];
1777
+ const hasMcpScripts = packageJson2.scripts?.mcp || packageJson2.scripts?.["mcp:dev"];
1778
+ return !!(hasMcpDeps || hasMcpScripts);
1779
+ } catch {
1780
+ return false;
1781
+ }
1782
+ }
1783
+ async function getProjectName(cwd = process.cwd()) {
1784
+ try {
1785
+ const packageJsonPath = path4.join(cwd, "package.json");
1786
+ const content = await fs8.readFile(packageJsonPath, "utf-8");
1787
+ const packageJson2 = JSON.parse(content);
1788
+ if (packageJson2.name) {
1789
+ return packageJson2.name;
1790
+ }
1791
+ } catch {
1792
+ }
1793
+ return path4.basename(cwd);
1794
+ }
1795
+ async function detectBuildCommand(cwd = process.cwd()) {
1796
+ try {
1797
+ const packageJsonPath = path4.join(cwd, "package.json");
1798
+ const content = await fs8.readFile(packageJsonPath, "utf-8");
1799
+ const packageJson2 = JSON.parse(content);
1800
+ if (packageJson2.scripts?.build) {
1801
+ return "npm run build";
1802
+ }
1803
+ } catch {
1804
+ }
1805
+ return void 0;
1806
+ }
1807
+ async function detectStartCommand(cwd = process.cwd()) {
1808
+ try {
1809
+ const packageJsonPath = path4.join(cwd, "package.json");
1810
+ const content = await fs8.readFile(packageJsonPath, "utf-8");
1811
+ const packageJson2 = JSON.parse(content);
1812
+ if (packageJson2.scripts?.start) {
1813
+ return "npm start";
1814
+ }
1815
+ if (packageJson2.main) {
1816
+ return `node ${packageJson2.main}`;
1817
+ }
1818
+ } catch {
1819
+ }
1820
+ return void 0;
1821
+ }
1822
+ async function detectRuntime(cwd = process.cwd()) {
1823
+ try {
1824
+ const pythonFiles = ["requirements.txt", "pyproject.toml", "setup.py"];
1825
+ for (const file of pythonFiles) {
1826
+ try {
1827
+ await fs8.access(path4.join(cwd, file));
1828
+ return "python";
1829
+ } catch {
1830
+ continue;
1831
+ }
1832
+ }
1833
+ try {
1834
+ await fs8.access(path4.join(cwd, "package.json"));
1835
+ return "node";
1836
+ } catch {
1837
+ }
1838
+ } catch {
1839
+ }
1840
+ return "node";
1841
+ }
1842
+ async function prompt(question, defaultValue = "n") {
1843
+ const readline = await import("readline");
1844
+ const rl = readline.createInterface({
1845
+ input: process.stdin,
1846
+ output: process.stdout
1847
+ });
1848
+ const defaultIndicator = defaultValue === "y" ? "Y/n" : "y/N";
1849
+ const questionWithDefault = question.replace(
1850
+ /(\(y\/n\):)/,
1851
+ `(${defaultIndicator}):`
1852
+ );
1853
+ return new Promise((resolve) => {
1854
+ rl.question(questionWithDefault, (answer) => {
1855
+ rl.close();
1856
+ const trimmedAnswer = answer.trim().toLowerCase();
1857
+ if (trimmedAnswer === "") {
1858
+ resolve(defaultValue === "y");
1859
+ } else {
1860
+ resolve(trimmedAnswer === "y" || trimmedAnswer === "yes");
1861
+ }
1862
+ });
1863
+ });
1864
+ }
1865
+ async function createTarball(cwd) {
1866
+ const tmpDir = os4.tmpdir();
1867
+ const tarballPath = path4.join(tmpDir, `mcp-deploy-${Date.now()}.tar.gz`);
1868
+ const excludePatterns = [
1869
+ "node_modules",
1870
+ ".git",
1871
+ "dist",
1872
+ "build",
1873
+ ".next",
1874
+ ".venv",
1875
+ "__pycache__",
1876
+ "*.pyc",
1877
+ ".DS_Store",
1878
+ "._*",
1879
+ // macOS resource fork files
1880
+ ".mcp-use",
1881
+ // Build artifacts directory
1882
+ ".env",
1883
+ ".env.local",
1884
+ "*.log"
1885
+ ];
1886
+ const excludeFlags = excludePatterns.map((pattern) => `--exclude=${pattern}`).join(" ");
1887
+ const command = `tar ${excludeFlags} -czf "${tarballPath}" -C "${cwd}" . 2>&1 || true`;
1888
+ try {
1889
+ await execAsync2(command);
1890
+ return tarballPath;
1891
+ } catch (error) {
1892
+ throw new Error(
1893
+ `Failed to create tarball: ${error instanceof Error ? error.message : "Unknown error"}`
1894
+ );
1895
+ }
1896
+ }
1897
+ function formatFileSize(bytes) {
1898
+ if (bytes === 0) return "0 B";
1899
+ const k = 1024;
1900
+ const sizes = ["B", "KB", "MB", "GB"];
1901
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
1902
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
1903
+ }
1904
+ async function displayDeploymentProgress(api, deployment) {
1905
+ const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
1906
+ let frameIndex = 0;
1907
+ let spinnerInterval = null;
1908
+ let lastStep = "";
1909
+ const startSpinner = (message) => {
1910
+ if (spinnerInterval) {
1911
+ clearInterval(spinnerInterval);
1912
+ }
1913
+ process.stdout.write("\r\x1B[K");
1914
+ spinnerInterval = setInterval(() => {
1915
+ const frame = frames[frameIndex];
1916
+ frameIndex = (frameIndex + 1) % frames.length;
1917
+ process.stdout.write(
1918
+ "\r" + source_default.cyan(frame) + " " + source_default.gray(message)
1919
+ );
1920
+ }, 80);
1921
+ };
1922
+ const stopSpinner = () => {
1923
+ if (spinnerInterval) {
1924
+ clearInterval(spinnerInterval);
1925
+ spinnerInterval = null;
1926
+ process.stdout.write("\r\x1B[K");
1927
+ }
1928
+ };
1929
+ console.log();
1930
+ startSpinner("Deploying...");
1931
+ try {
1932
+ for await (const log of api.streamDeploymentLogs(deployment.id)) {
1933
+ try {
1934
+ const logData = JSON.parse(log);
1935
+ if (logData.step && logData.step !== lastStep) {
1936
+ lastStep = logData.step;
1937
+ const stepMessages = {
1938
+ clone: "Preparing source code...",
1939
+ analyze: "Analyzing project...",
1940
+ build: "Building container image...",
1941
+ deploy: "Deploying to cloud..."
1942
+ };
1943
+ const message = stepMessages[logData.step] || "Deploying...";
1944
+ startSpinner(message);
1945
+ }
1946
+ if (logData.line) {
1947
+ stopSpinner();
1948
+ const levelColor = logData.level === "error" ? source_default.red : logData.level === "warn" ? source_default.yellow : source_default.gray;
1949
+ const stepPrefix = logData.step ? source_default.cyan(`[${logData.step}]`) + " " : "";
1950
+ console.log(stepPrefix + levelColor(logData.line));
1951
+ }
1952
+ } catch {
1953
+ }
1954
+ }
1955
+ } catch (error) {
1956
+ stopSpinner();
1957
+ }
1958
+ let checkCount = 0;
1959
+ const maxChecks = 60;
1960
+ let delay = 3e3;
1961
+ const maxDelay = 1e4;
1962
+ let lastDisplayedLogLength = 0;
1963
+ while (checkCount < maxChecks) {
1964
+ const currentDelay = delay;
1965
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
1966
+ const finalDeployment = await api.getDeployment(deployment.id);
1967
+ if (finalDeployment.buildLogs && finalDeployment.buildLogs.length > lastDisplayedLogLength) {
1968
+ const newLogs = finalDeployment.buildLogs.substring(
1969
+ lastDisplayedLogLength
1970
+ );
1971
+ const logLines = newLogs.split("\n").filter((l) => l.trim());
1972
+ for (const line of logLines) {
1973
+ try {
1974
+ const logData = JSON.parse(line);
1975
+ if (logData.line) {
1976
+ stopSpinner();
1977
+ const levelColor = logData.level === "error" ? source_default.red : logData.level === "warn" ? source_default.yellow : source_default.gray;
1978
+ const stepPrefix = logData.step ? source_default.cyan(`[${logData.step}]`) + " " : "";
1979
+ console.log(stepPrefix + levelColor(logData.line));
1980
+ }
1981
+ } catch {
1982
+ }
1983
+ }
1984
+ lastDisplayedLogLength = finalDeployment.buildLogs.length;
1985
+ }
1986
+ if (finalDeployment.status === "running") {
1987
+ const mcpUrl = `https://${finalDeployment.domain}/mcp`;
1988
+ const inspectorUrl = `https://inspector.mcp-use.com/inspector?autoConnect=${encodeURIComponent(mcpUrl)}`;
1989
+ console.log(source_default.green.bold("\u2713 Deployment successful!\n"));
1990
+ console.log(source_default.white("\u{1F310} MCP Server URL:"));
1991
+ console.log(source_default.cyan.bold(` ${mcpUrl}
1992
+ `));
1993
+ console.log(source_default.white("\u{1F50D} Inspector URL:"));
1994
+ console.log(source_default.cyan.bold(` ${inspectorUrl}
1995
+ `));
1996
+ if (finalDeployment.customDomain) {
1997
+ const customMcpUrl = `https://${finalDeployment.customDomain}/mcp`;
1998
+ const customInspectorUrl = `https://inspector.mcp-use.com/inspect?autoConnect=${encodeURIComponent(customMcpUrl)}`;
1999
+ console.log(source_default.white("\u{1F517} Custom Domain:"));
2000
+ console.log(source_default.cyan.bold(` ${customMcpUrl}
2001
+ `));
2002
+ console.log(source_default.white("\u{1F50D} Custom Inspector:"));
2003
+ console.log(source_default.cyan.bold(` ${customInspectorUrl}
2004
+ `));
2005
+ }
2006
+ console.log(
2007
+ source_default.gray("Deployment ID: ") + source_default.white(finalDeployment.id)
2008
+ );
2009
+ return;
2010
+ } else if (finalDeployment.status === "failed") {
2011
+ console.log(source_default.red.bold("\u2717 Deployment failed\n"));
2012
+ if (finalDeployment.error) {
2013
+ console.log(source_default.red("Error: ") + finalDeployment.error);
2014
+ }
2015
+ if (finalDeployment.buildLogs) {
2016
+ console.log(source_default.gray("\nBuild logs:"));
2017
+ try {
2018
+ const logs = finalDeployment.buildLogs.split("\n").filter((l) => l.trim());
2019
+ for (const log of logs) {
2020
+ try {
2021
+ const logData = JSON.parse(log);
2022
+ if (logData.line) {
2023
+ console.log(source_default.gray(` ${logData.line}`));
2024
+ }
2025
+ } catch {
2026
+ console.log(source_default.gray(` ${log}`));
2027
+ }
2028
+ }
2029
+ } catch {
2030
+ console.log(source_default.gray(finalDeployment.buildLogs));
2031
+ }
2032
+ }
2033
+ process.exit(1);
2034
+ } else if (finalDeployment.status === "building") {
2035
+ startSpinner("Building and deploying...");
2036
+ checkCount++;
2037
+ delay = Math.min(delay * 1.2, maxDelay);
2038
+ } else {
2039
+ console.log(
2040
+ source_default.yellow("\u26A0\uFE0F Deployment status: ") + finalDeployment.status
2041
+ );
2042
+ return;
2043
+ }
2044
+ }
2045
+ stopSpinner();
2046
+ console.log(source_default.yellow("\u26A0\uFE0F Deployment is taking longer than expected."));
2047
+ console.log(
2048
+ source_default.gray("Check status with: ") + source_default.white(`mcp-use status ${deployment.id}`)
2049
+ );
2050
+ }
2051
+ async function deployCommand(options) {
2052
+ try {
2053
+ const cwd = process.cwd();
2054
+ if (!await isLoggedIn()) {
2055
+ console.log(source_default.red("\u2717 You are not logged in."));
2056
+ console.log(
2057
+ source_default.gray("Run " + source_default.white("mcp-use login") + " to get started.")
2058
+ );
2059
+ process.exit(1);
2060
+ }
2061
+ console.log(source_default.cyan.bold("\u{1F680} Deploying to mcp-use cloud...\n"));
2062
+ const isMcp = await isMcpProject(cwd);
2063
+ if (!isMcp) {
2064
+ console.log(
2065
+ source_default.yellow(
2066
+ "\u26A0\uFE0F This doesn't appear to be an MCP server project (no mcp-use or @modelcontextprotocol/sdk dependency found)."
2067
+ )
2068
+ );
2069
+ const shouldContinue = await prompt(
2070
+ source_default.white("Continue anyway? (y/n): ")
2071
+ );
2072
+ if (!shouldContinue) {
2073
+ console.log(source_default.gray("Deployment cancelled."));
2074
+ process.exit(0);
2075
+ }
2076
+ console.log();
2077
+ }
2078
+ const gitInfo = await getGitInfo(cwd);
2079
+ if (!options.fromSource && gitInfo.isGitRepo && gitInfo.remoteUrl && isGitHubUrl(gitInfo.remoteUrl)) {
2080
+ if (!gitInfo.owner || !gitInfo.repo) {
2081
+ console.log(
2082
+ source_default.red(
2083
+ "\u2717 Could not parse GitHub repository information from remote URL."
2084
+ )
2085
+ );
2086
+ process.exit(1);
2087
+ }
2088
+ console.log(source_default.white("GitHub repository detected:"));
2089
+ console.log(
2090
+ source_default.gray(` Repository: `) + source_default.cyan(`${gitInfo.owner}/${gitInfo.repo}`)
2091
+ );
2092
+ console.log(
2093
+ source_default.gray(` Branch: `) + source_default.cyan(gitInfo.branch || "main")
2094
+ );
2095
+ if (gitInfo.commitSha) {
2096
+ console.log(
2097
+ source_default.gray(` Commit: `) + source_default.gray(gitInfo.commitSha.substring(0, 7))
2098
+ );
2099
+ }
2100
+ if (gitInfo.commitMessage) {
2101
+ console.log(
2102
+ source_default.gray(` Message: `) + source_default.gray(gitInfo.commitMessage.split("\n")[0])
2103
+ );
2104
+ }
2105
+ console.log();
2106
+ const shouldDeploy = await prompt(
2107
+ source_default.white(
2108
+ `Deploy from GitHub repository ${gitInfo.owner}/${gitInfo.repo}? (y/n): `
2109
+ )
2110
+ );
2111
+ if (!shouldDeploy) {
2112
+ console.log(source_default.gray("Deployment cancelled."));
2113
+ process.exit(0);
2114
+ }
2115
+ const projectName = options.name || await getProjectName(cwd);
2116
+ const runtime = options.runtime || await detectRuntime(cwd);
2117
+ const port = options.port || 3e3;
2118
+ const buildCommand = await detectBuildCommand(cwd);
2119
+ const startCommand = await detectStartCommand(cwd);
2120
+ console.log();
2121
+ console.log(source_default.white("Deployment configuration:"));
2122
+ console.log(source_default.gray(` Name: `) + source_default.cyan(projectName));
2123
+ console.log(source_default.gray(` Runtime: `) + source_default.cyan(runtime));
2124
+ console.log(source_default.gray(` Port: `) + source_default.cyan(port));
2125
+ if (buildCommand) {
2126
+ console.log(source_default.gray(` Build command: `) + source_default.cyan(buildCommand));
2127
+ }
2128
+ if (startCommand) {
2129
+ console.log(source_default.gray(` Start command: `) + source_default.cyan(startCommand));
2130
+ }
2131
+ console.log();
2132
+ const deploymentRequest = {
2133
+ name: projectName,
2134
+ source: {
2135
+ type: "github",
2136
+ repo: `${gitInfo.owner}/${gitInfo.repo}`,
2137
+ branch: gitInfo.branch || "main",
2138
+ runtime,
2139
+ port,
2140
+ buildCommand,
2141
+ startCommand
2142
+ },
2143
+ healthCheckPath: "/healthz"
2144
+ };
2145
+ console.log(source_default.gray("Creating deployment..."));
2146
+ const api = await McpUseAPI.create();
2147
+ const deployment = await api.createDeployment(deploymentRequest);
2148
+ console.log(
2149
+ source_default.green("\u2713 Deployment created: ") + source_default.gray(deployment.id)
2150
+ );
2151
+ await displayDeploymentProgress(api, deployment);
2152
+ if (options.open && deployment.domain) {
2153
+ console.log();
2154
+ console.log(source_default.gray("Opening deployment in browser..."));
2155
+ await open_default(`https://${deployment.domain}`);
2156
+ }
2157
+ } else {
2158
+ if (options.fromSource) {
2159
+ console.log(
2160
+ source_default.white("\u{1F4E6} Deploying from local source code (--from-source)...")
2161
+ );
2162
+ } else {
2163
+ console.log(
2164
+ source_default.yellow(
2165
+ "\u26A0\uFE0F This is not a GitHub repository or no remote is configured."
2166
+ )
2167
+ );
2168
+ console.log(source_default.white("Deploying from local source code instead..."));
2169
+ }
2170
+ console.log();
2171
+ const projectName = options.name || await getProjectName(cwd);
2172
+ const runtime = options.runtime || await detectRuntime(cwd);
2173
+ const port = options.port || 3e3;
2174
+ const buildCommand = await detectBuildCommand(cwd);
2175
+ const startCommand = await detectStartCommand(cwd);
2176
+ console.log(source_default.white("Deployment configuration:"));
2177
+ console.log(source_default.gray(` Name: `) + source_default.cyan(projectName));
2178
+ console.log(source_default.gray(` Runtime: `) + source_default.cyan(runtime));
2179
+ console.log(source_default.gray(` Port: `) + source_default.cyan(port));
2180
+ if (buildCommand) {
2181
+ console.log(source_default.gray(` Build command: `) + source_default.cyan(buildCommand));
2182
+ }
2183
+ if (startCommand) {
2184
+ console.log(source_default.gray(` Start command: `) + source_default.cyan(startCommand));
2185
+ }
2186
+ console.log();
2187
+ const shouldDeploy = await prompt(
2188
+ source_default.white("Deploy from local source? (y/n): "),
2189
+ "y"
2190
+ );
2191
+ if (!shouldDeploy) {
2192
+ console.log(source_default.gray("Deployment cancelled."));
2193
+ process.exit(0);
2194
+ }
2195
+ console.log();
2196
+ console.log(source_default.gray("Packaging source code..."));
2197
+ const tarballPath = await createTarball(cwd);
2198
+ const stats = await fs8.stat(tarballPath);
493
2199
  console.log(
494
- import_chalk.default.yellow(
495
- "\u26A0\uFE0F You are already logged in. Run 'mcp-use logout' first if you want to login with a different account."
496
- )
2200
+ source_default.green("\u2713 Packaged: ") + source_default.gray(formatFileSize(stats.size))
497
2201
  );
498
- return;
2202
+ const maxSize = 2 * 1024 * 1024;
2203
+ if (stats.size > maxSize) {
2204
+ console.log(
2205
+ source_default.red(
2206
+ `\u2717 File size (${formatFileSize(stats.size)}) exceeds maximum of 2MB`
2207
+ )
2208
+ );
2209
+ await fs8.unlink(tarballPath);
2210
+ process.exit(1);
2211
+ }
2212
+ const deploymentRequest = {
2213
+ name: projectName,
2214
+ source: {
2215
+ type: "upload",
2216
+ runtime,
2217
+ port,
2218
+ buildCommand,
2219
+ startCommand
2220
+ },
2221
+ healthCheckPath: "/healthz"
2222
+ };
2223
+ console.log(source_default.gray("Creating deployment..."));
2224
+ const api = await McpUseAPI.create();
2225
+ const deployment = await api.createDeploymentWithUpload(
2226
+ deploymentRequest,
2227
+ tarballPath
2228
+ );
2229
+ await fs8.unlink(tarballPath);
2230
+ console.log(
2231
+ source_default.green("\u2713 Deployment created: ") + source_default.gray(deployment.id)
2232
+ );
2233
+ await displayDeploymentProgress(api, deployment);
2234
+ if (options.open && deployment.domain) {
2235
+ console.log();
2236
+ console.log(source_default.gray("Opening deployment in browser..."));
2237
+ await open_default(`https://${deployment.domain}`);
2238
+ }
499
2239
  }
500
- console.log(import_chalk.default.cyan.bold("\u{1F510} Logging in to mcp-use cloud...\n"));
501
- const port = await findAvailablePort();
502
- const redirectUri = `http://localhost:${port}/callback`;
503
- console.log(import_chalk.default.gray(`Starting local server on port ${port}...`));
504
- const { server, token } = await startCallbackServer(port);
505
- const webUrl = await getWebUrl();
506
- const loginUrl = `${webUrl}/auth/cli?redirect_uri=${encodeURIComponent(redirectUri)}`;
507
- console.log(import_chalk.default.gray(`Opening browser to ${webUrl}/auth/cli...
508
- `));
509
- console.log(
510
- import_chalk.default.white(
511
- "If the browser doesn't open automatically, please visit:\n" + import_chalk.default.cyan(loginUrl)
512
- )
513
- );
514
- await (0, import_open.default)(loginUrl);
515
- console.log(
516
- import_chalk.default.gray("\nWaiting for authentication... (this may take a moment)")
517
- );
518
- const jwtToken = await Promise.race([
519
- token,
520
- new Promise(
521
- (_, reject) => setTimeout(
522
- () => reject(new Error("Login timeout - please try again")),
523
- LOGIN_TIMEOUT
524
- )
525
- )
526
- ]);
527
- server.close();
528
- console.log(
529
- import_chalk.default.gray("Received authentication token, creating API key...")
530
- );
531
- const api = await McpUseAPI.create();
532
- const apiKeyResponse = await api.createApiKey(jwtToken, "CLI");
533
- await writeConfig({
534
- apiKey: apiKeyResponse.api_key
535
- });
536
- console.log(import_chalk.default.green.bold("\n\u2713 Successfully logged in!"));
537
- console.log(
538
- import_chalk.default.gray(
539
- `
540
- Your API key has been saved to ${import_chalk.default.white("~/.mcp-use/config.json")}`
541
- )
542
- );
543
- console.log(
544
- import_chalk.default.gray(
545
- "You can now deploy your MCP servers with " + import_chalk.default.white("mcp-use deploy")
546
- )
547
- );
548
- process.exit(0);
549
2240
  } catch (error) {
550
2241
  console.error(
551
- import_chalk.default.red.bold("\n\u2717 Login failed:"),
552
- import_chalk.default.red(error instanceof Error ? error.message : "Unknown error")
2242
+ source_default.red.bold("\n\u2717 Deployment failed:"),
2243
+ source_default.red(error instanceof Error ? error.message : "Unknown error")
553
2244
  );
554
2245
  process.exit(1);
555
2246
  }
556
2247
  }
557
- async function logoutCommand() {
558
- try {
559
- if (!await isLoggedIn()) {
560
- console.log(import_chalk.default.yellow("\u26A0\uFE0F You are not logged in."));
561
- return;
562
- }
563
- console.log(import_chalk.default.cyan.bold("\u{1F513} Logging out...\n"));
564
- await deleteConfig();
565
- console.log(import_chalk.default.green.bold("\u2713 Successfully logged out!"));
566
- console.log(
567
- import_chalk.default.gray(
568
- "\nYour local config has been deleted. The API key will remain active until revoked from the web interface."
569
- )
570
- );
571
- } catch (error) {
572
- console.error(
573
- import_chalk.default.red.bold("\n\u2717 Logout failed:"),
574
- import_chalk.default.red(error instanceof Error ? error.message : "Unknown error")
575
- );
576
- process.exit(1);
2248
+
2249
+ // src/commands/client.ts
2250
+ import { Command } from "commander";
2251
+ import { createInterface } from "readline";
2252
+ import { MCPClient } from "mcp-use";
2253
+
2254
+ // src/utils/session-storage.ts
2255
+ import { homedir } from "os";
2256
+ import { join } from "path";
2257
+ import { readFile, writeFile, mkdir } from "fs/promises";
2258
+ import { existsSync } from "fs";
2259
+ var SESSION_FILE_PATH = join(homedir(), ".mcp-use", "cli-sessions.json");
2260
+ async function ensureSessionDir() {
2261
+ const dir = join(homedir(), ".mcp-use");
2262
+ if (!existsSync(dir)) {
2263
+ await mkdir(dir, { recursive: true });
577
2264
  }
578
2265
  }
579
- async function whoamiCommand() {
2266
+ async function loadSessions() {
580
2267
  try {
581
- if (!await isLoggedIn()) {
582
- console.log(import_chalk.default.yellow("\u26A0\uFE0F You are not logged in."));
583
- console.log(
584
- import_chalk.default.gray("Run " + import_chalk.default.white("mcp-use login") + " to get started.")
585
- );
586
- return;
587
- }
588
- console.log(import_chalk.default.cyan.bold("\u{1F464} Current user:\n"));
589
- const api = await McpUseAPI.create();
590
- const authInfo = await api.testAuth();
591
- console.log(import_chalk.default.white("Email: ") + import_chalk.default.cyan(authInfo.email));
592
- console.log(import_chalk.default.white("User ID: ") + import_chalk.default.gray(authInfo.user_id));
593
- const apiKey = await getApiKey();
594
- if (apiKey) {
595
- const masked = apiKey.substring(0, 8) + "..." + apiKey.substring(apiKey.length - 4);
596
- console.log(import_chalk.default.white("API Key: ") + import_chalk.default.gray(masked));
2268
+ await ensureSessionDir();
2269
+ if (!existsSync(SESSION_FILE_PATH)) {
2270
+ return { activeSession: null, sessions: {} };
597
2271
  }
2272
+ const content = await readFile(SESSION_FILE_PATH, "utf-8");
2273
+ return JSON.parse(content);
598
2274
  } catch (error) {
599
- console.error(
600
- import_chalk.default.red.bold("\n\u2717 Failed to get user info:"),
601
- import_chalk.default.red(error instanceof Error ? error.message : "Unknown error")
602
- );
603
- process.exit(1);
2275
+ return { activeSession: null, sessions: {} };
604
2276
  }
605
2277
  }
606
-
607
- // src/commands/deploy.ts
608
- var import_chalk2 = __toESM(require("chalk"));
609
- var import_node_fs2 = require("fs");
610
- var import_node_path2 = __toESM(require("path"));
611
- var import_node_os2 = __toESM(require("os"));
612
- var import_node_child_process2 = require("child_process");
613
- var import_node_util2 = require("util");
614
-
615
- // src/utils/git.ts
616
- var import_node_child_process = require("child_process");
617
- var import_node_util = require("util");
618
- var execAsync = (0, import_node_util.promisify)(import_node_child_process.exec);
619
- async function gitCommand(command, cwd = process.cwd()) {
620
- try {
621
- const { stdout } = await execAsync(command, { cwd });
622
- return stdout.trim();
623
- } catch (error) {
2278
+ async function saveSessions(storage) {
2279
+ await ensureSessionDir();
2280
+ await writeFile(SESSION_FILE_PATH, JSON.stringify(storage, null, 2), "utf-8");
2281
+ }
2282
+ async function saveSession(name, config) {
2283
+ const storage = await loadSessions();
2284
+ storage.sessions[name] = {
2285
+ ...config,
2286
+ lastUsed: (/* @__PURE__ */ new Date()).toISOString()
2287
+ };
2288
+ if (!storage.activeSession) {
2289
+ storage.activeSession = name;
2290
+ }
2291
+ await saveSessions(storage);
2292
+ }
2293
+ async function getActiveSession() {
2294
+ const storage = await loadSessions();
2295
+ if (!storage.activeSession || !storage.sessions[storage.activeSession]) {
624
2296
  return null;
625
2297
  }
2298
+ return {
2299
+ name: storage.activeSession,
2300
+ config: storage.sessions[storage.activeSession]
2301
+ };
626
2302
  }
627
- async function isGitRepo(cwd = process.cwd()) {
628
- const result = await gitCommand("git rev-parse --is-inside-work-tree", cwd);
629
- return result === "true";
2303
+ async function getSession(name) {
2304
+ const storage = await loadSessions();
2305
+ return storage.sessions[name] || null;
630
2306
  }
631
- async function getRemoteUrl(cwd = process.cwd()) {
632
- return gitCommand("git config --get remote.origin.url", cwd);
2307
+ async function setActiveSession(name) {
2308
+ const storage = await loadSessions();
2309
+ if (!storage.sessions[name]) {
2310
+ throw new Error(`Session '${name}' not found`);
2311
+ }
2312
+ storage.activeSession = name;
2313
+ storage.sessions[name].lastUsed = (/* @__PURE__ */ new Date()).toISOString();
2314
+ await saveSessions(storage);
633
2315
  }
634
- function parseGitHubUrl(url) {
635
- const sshMatch = url.match(/git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/);
636
- const httpsMatch = url.match(
637
- /https:\/\/github\.com\/([^/]+)\/(.+?)(?:\.git)?$/
638
- );
639
- const match = sshMatch || httpsMatch;
640
- if (!match) return null;
641
- return {
642
- owner: match[1],
643
- repo: match[2]
2316
+ async function listAllSessions() {
2317
+ const storage = await loadSessions();
2318
+ return Object.entries(storage.sessions).map(([name, config]) => ({
2319
+ name,
2320
+ config,
2321
+ isActive: name === storage.activeSession
2322
+ }));
2323
+ }
2324
+ async function updateSessionInfo(name, serverInfo, capabilities) {
2325
+ const storage = await loadSessions();
2326
+ if (storage.sessions[name]) {
2327
+ storage.sessions[name].serverInfo = serverInfo;
2328
+ storage.sessions[name].capabilities = capabilities;
2329
+ storage.sessions[name].lastUsed = (/* @__PURE__ */ new Date()).toISOString();
2330
+ await saveSessions(storage);
2331
+ }
2332
+ }
2333
+
2334
+ // src/utils/format.ts
2335
+ function formatTable(data, columns) {
2336
+ if (data.length === 0) {
2337
+ return source_default.gray("No items found");
2338
+ }
2339
+ const widths = columns.map((col) => {
2340
+ const maxDataWidth = Math.max(
2341
+ ...data.map((row) => String(row[col.key] || "").length)
2342
+ );
2343
+ const headerWidth = col.header.length;
2344
+ return col.width || Math.max(maxDataWidth, headerWidth, 10);
2345
+ });
2346
+ const createRow = (values, bold = false) => {
2347
+ const cells = values.map((val, i) => {
2348
+ const padded = val.padEnd(widths[i]);
2349
+ return bold ? source_default.bold(padded) : padded;
2350
+ });
2351
+ return `\u2502 ${cells.join(" \u2502 ")} \u2502`;
644
2352
  };
2353
+ const separator = (char) => {
2354
+ const parts = widths.map((w) => char.repeat(w + 2));
2355
+ if (char === "\u2500") {
2356
+ return `\u251C${parts.join("\u253C")}\u2524`;
2357
+ }
2358
+ return `\u2514${parts.join("\u2534")}\u2518`;
2359
+ };
2360
+ const lines = [];
2361
+ lines.push(`\u250C${widths.map((w) => "\u2500".repeat(w + 2)).join("\u252C")}\u2510`);
2362
+ lines.push(
2363
+ createRow(
2364
+ columns.map((c) => c.header),
2365
+ true
2366
+ )
2367
+ );
2368
+ lines.push(separator("\u2500"));
2369
+ data.forEach((row) => {
2370
+ lines.push(createRow(columns.map((c) => String(row[c.key] || ""))));
2371
+ });
2372
+ lines.push(separator("\u2500"));
2373
+ return lines.join("\n");
645
2374
  }
646
- async function getCurrentBranch(cwd = process.cwd()) {
647
- return gitCommand("git rev-parse --abbrev-ref HEAD", cwd);
2375
+ function formatJson(data, pretty = true) {
2376
+ if (pretty) {
2377
+ return JSON.stringify(data, null, 2);
2378
+ }
2379
+ return JSON.stringify(data);
648
2380
  }
649
- async function getCommitSha(cwd = process.cwd()) {
650
- return gitCommand("git rev-parse HEAD", cwd);
2381
+ function formatToolCall(result) {
2382
+ const lines = [];
2383
+ if (result.isError) {
2384
+ lines.push(source_default.red("\u2717 Tool execution failed"));
2385
+ lines.push("");
2386
+ } else {
2387
+ lines.push(source_default.green("\u2713 Tool executed successfully"));
2388
+ lines.push("");
2389
+ }
2390
+ if (result.content && result.content.length > 0) {
2391
+ result.content.forEach((item, index) => {
2392
+ if (result.content.length > 1) {
2393
+ lines.push(source_default.bold(`Content ${index + 1}:`));
2394
+ }
2395
+ if (item.type === "text") {
2396
+ lines.push(item.text);
2397
+ } else if (item.type === "image") {
2398
+ lines.push(source_default.cyan(`[Image: ${item.mimeType || "unknown type"}]`));
2399
+ if (item.data) {
2400
+ lines.push(source_default.gray(`Data: ${item.data.substring(0, 50)}...`));
2401
+ }
2402
+ } else if (item.type === "resource") {
2403
+ lines.push(source_default.cyan(`[Resource]`));
2404
+ if (item.resource?.uri) {
2405
+ lines.push(source_default.gray(`URI: ${item.resource.uri}`));
2406
+ }
2407
+ if (item.resource && "text" in item.resource && item.resource.text) {
2408
+ lines.push(item.resource.text);
2409
+ }
2410
+ } else {
2411
+ lines.push(source_default.gray(`[Unknown content type: ${item.type}]`));
2412
+ }
2413
+ if (index < result.content.length - 1) {
2414
+ lines.push("");
2415
+ }
2416
+ });
2417
+ }
2418
+ return lines.join("\n");
651
2419
  }
652
- async function getCommitMessage(cwd = process.cwd()) {
653
- return gitCommand("git log -1 --pretty=%B", cwd);
2420
+ function formatResourceContent(content) {
2421
+ if (!content || !content.contents) {
2422
+ return source_default.gray("No content");
2423
+ }
2424
+ const lines = [];
2425
+ content.contents.forEach((item, index) => {
2426
+ if (content.contents.length > 1) {
2427
+ lines.push(source_default.bold(`Content ${index + 1}:`));
2428
+ }
2429
+ if (item.uri) {
2430
+ lines.push(source_default.gray(`URI: ${item.uri}`));
2431
+ }
2432
+ if (item.mimeType) {
2433
+ lines.push(source_default.gray(`Type: ${item.mimeType}`));
2434
+ }
2435
+ if ("text" in item && item.text) {
2436
+ lines.push("");
2437
+ lines.push(item.text);
2438
+ } else if ("blob" in item && item.blob) {
2439
+ lines.push("");
2440
+ lines.push(source_default.cyan(`[Binary data: ${item.blob.length} bytes]`));
2441
+ }
2442
+ if (index < content.contents.length - 1) {
2443
+ lines.push("");
2444
+ lines.push(source_default.gray("\u2500".repeat(50)));
2445
+ lines.push("");
2446
+ }
2447
+ });
2448
+ return lines.join("\n");
654
2449
  }
655
- async function getGitInfo(cwd = process.cwd()) {
656
- const isRepo = await isGitRepo(cwd);
657
- if (!isRepo) {
658
- return { isGitRepo: false };
2450
+ function formatSchema(schema, indent = 0) {
2451
+ if (!schema) {
2452
+ return source_default.gray("No schema");
659
2453
  }
660
- const remoteUrl = await getRemoteUrl(cwd);
661
- const branch = await getCurrentBranch(cwd);
662
- const commitSha = await getCommitSha(cwd);
663
- const commitMessage = await getCommitMessage(cwd);
664
- let owner;
665
- let repo;
666
- if (remoteUrl) {
667
- const parsed = parseGitHubUrl(remoteUrl);
668
- if (parsed) {
669
- owner = parsed.owner;
670
- repo = parsed.repo;
2454
+ const lines = [];
2455
+ const pad = " ".repeat(indent);
2456
+ if (schema.type === "object" && schema.properties) {
2457
+ Object.entries(schema.properties).forEach(([key, value]) => {
2458
+ const required = schema.required?.includes(key);
2459
+ const type = value.type || "any";
2460
+ const desc = value.description || "";
2461
+ const keyStr = required ? source_default.bold(key) : key;
2462
+ const typeStr = source_default.cyan(`(${type})`);
2463
+ const requiredStr = required ? source_default.red(" *required") : "";
2464
+ lines.push(`${pad}${keyStr} ${typeStr}${requiredStr}`);
2465
+ if (desc) {
2466
+ lines.push(`${pad} ${source_default.gray(desc)}`);
2467
+ }
2468
+ if (value.type === "object" && value.properties) {
2469
+ lines.push(formatSchema(value, indent + 1));
2470
+ }
2471
+ if (value.type === "array" && value.items) {
2472
+ lines.push(`${pad} ${source_default.gray("Items:")}`);
2473
+ if (value.items.type === "object") {
2474
+ lines.push(formatSchema(value.items, indent + 2));
2475
+ } else {
2476
+ lines.push(
2477
+ `${pad} ${source_default.cyan(`(${value.items.type || "any"})`)}`
2478
+ );
2479
+ }
2480
+ }
2481
+ });
2482
+ } else {
2483
+ lines.push(`${pad}${source_default.cyan(`Type: ${schema.type || "any"}`)}`);
2484
+ if (schema.description) {
2485
+ lines.push(`${pad}${source_default.gray(schema.description)}`);
671
2486
  }
672
2487
  }
673
- return {
674
- isGitRepo: true,
675
- remoteUrl: remoteUrl || void 0,
676
- owner,
677
- repo,
678
- branch: branch || void 0,
679
- commitSha: commitSha || void 0,
680
- commitMessage: commitMessage || void 0
681
- };
2488
+ return lines.join("\n");
682
2489
  }
683
- function isGitHubUrl(url) {
684
- return url.includes("github.com");
2490
+ function formatError(error) {
2491
+ const message = typeof error === "string" ? error : error.message;
2492
+ return source_default.red(`\u2717 Error: ${message}`);
685
2493
  }
686
-
687
- // src/commands/deploy.ts
688
- var import_open2 = __toESM(require("open"));
689
- var execAsync2 = (0, import_node_util2.promisify)(import_node_child_process2.exec);
690
- async function isMcpProject(cwd = process.cwd()) {
691
- try {
692
- const packageJsonPath = import_node_path2.default.join(cwd, "package.json");
693
- const content = await import_node_fs2.promises.readFile(packageJsonPath, "utf-8");
694
- const packageJson2 = JSON.parse(content);
695
- const hasMcpDeps = packageJson2.dependencies?.["mcp-use"] || packageJson2.dependencies?.["@modelcontextprotocol/sdk"] || packageJson2.devDependencies?.["mcp-use"] || packageJson2.devDependencies?.["@modelcontextprotocol/sdk"];
696
- const hasMcpScripts = packageJson2.scripts?.mcp || packageJson2.scripts?.["mcp:dev"];
697
- return !!(hasMcpDeps || hasMcpScripts);
698
- } catch {
699
- return false;
2494
+ function formatSuccess(message) {
2495
+ return source_default.green(`\u2713 ${message}`);
2496
+ }
2497
+ function formatInfo(message) {
2498
+ return source_default.cyan(message);
2499
+ }
2500
+ function formatWarning(message) {
2501
+ return source_default.yellow(`\u26A0 ${message}`);
2502
+ }
2503
+ function formatHeader(text) {
2504
+ return source_default.bold.white(text);
2505
+ }
2506
+ function formatKeyValue(pairs) {
2507
+ const maxKeyLength = Math.max(...Object.keys(pairs).map((k) => k.length), 0);
2508
+ return Object.entries(pairs).map(([key, value]) => {
2509
+ const paddedKey = key.padEnd(maxKeyLength);
2510
+ return ` ${source_default.gray(paddedKey)}: ${value}`;
2511
+ }).join("\n");
2512
+ }
2513
+ function formatPromptMessages(messages) {
2514
+ if (!messages || messages.length === 0) {
2515
+ return source_default.gray("No messages");
700
2516
  }
2517
+ const lines = [];
2518
+ messages.forEach((msg, index) => {
2519
+ const role = msg.role || "unknown";
2520
+ const roleStr = role === "user" ? source_default.blue("[User]") : role === "assistant" ? source_default.green("[Assistant]") : source_default.gray(`[${role}]`);
2521
+ lines.push(`${roleStr}`);
2522
+ if (msg.content) {
2523
+ if (typeof msg.content === "string") {
2524
+ lines.push(msg.content);
2525
+ } else if (msg.content.type === "text") {
2526
+ lines.push(msg.content.text);
2527
+ } else if (msg.content.type === "image") {
2528
+ lines.push(source_default.cyan(`[Image: ${msg.content.mimeType}]`));
2529
+ } else if (msg.content.type === "resource") {
2530
+ lines.push(source_default.cyan(`[Resource: ${msg.content.resource?.uri}]`));
2531
+ if (msg.content.resource?.text) {
2532
+ lines.push(msg.content.resource.text);
2533
+ }
2534
+ }
2535
+ }
2536
+ if (index < messages.length - 1) {
2537
+ lines.push("");
2538
+ }
2539
+ });
2540
+ return lines.join("\n");
701
2541
  }
702
- async function getProjectName(cwd = process.cwd()) {
703
- try {
704
- const packageJsonPath = import_node_path2.default.join(cwd, "package.json");
705
- const content = await import_node_fs2.promises.readFile(packageJsonPath, "utf-8");
706
- const packageJson2 = JSON.parse(content);
707
- if (packageJson2.name) {
708
- return packageJson2.name;
2542
+
2543
+ // src/commands/client.ts
2544
+ var activeSessions = /* @__PURE__ */ new Map();
2545
+ async function getOrRestoreSession(sessionName) {
2546
+ if (!sessionName) {
2547
+ const active = await getActiveSession();
2548
+ if (!active) {
2549
+ console.error(
2550
+ formatError("No active session. Connect to a server first.")
2551
+ );
2552
+ console.error(
2553
+ formatInfo("Use: npx mcp-use client connect <url> --name <name>")
2554
+ );
2555
+ return null;
709
2556
  }
710
- } catch {
2557
+ sessionName = active.name;
2558
+ }
2559
+ if (activeSessions.has(sessionName)) {
2560
+ const { session } = activeSessions.get(sessionName);
2561
+ return { name: sessionName, session };
2562
+ }
2563
+ const config = await getSession(sessionName);
2564
+ if (!config) {
2565
+ console.error(formatError(`Session '${sessionName}' not found`));
2566
+ return null;
711
2567
  }
712
- return import_node_path2.default.basename(cwd);
713
- }
714
- async function detectBuildCommand(cwd = process.cwd()) {
715
2568
  try {
716
- const packageJsonPath = import_node_path2.default.join(cwd, "package.json");
717
- const content = await import_node_fs2.promises.readFile(packageJsonPath, "utf-8");
718
- const packageJson2 = JSON.parse(content);
719
- if (packageJson2.scripts?.build) {
720
- return "npm run build";
2569
+ const client = new MCPClient();
2570
+ if (config.type === "http") {
2571
+ client.addServer(sessionName, {
2572
+ url: config.url,
2573
+ headers: config.authToken ? { Authorization: `Bearer ${config.authToken}` } : void 0
2574
+ });
2575
+ } else if (config.type === "stdio") {
2576
+ client.addServer(sessionName, {
2577
+ command: config.command,
2578
+ args: config.args || [],
2579
+ env: config.env
2580
+ });
2581
+ } else {
2582
+ console.error(formatError(`Unknown session type: ${config.type}`));
2583
+ return null;
721
2584
  }
722
- } catch {
2585
+ const session = await client.createSession(sessionName);
2586
+ activeSessions.set(sessionName, { client, session });
2587
+ console.error(formatInfo(`Reconnected to session '${sessionName}'`));
2588
+ return { name: sessionName, session };
2589
+ } catch (error) {
2590
+ console.error(formatError(`Failed to restore session: ${error.message}`));
2591
+ return null;
723
2592
  }
724
- return void 0;
725
2593
  }
726
- async function detectStartCommand(cwd = process.cwd()) {
2594
+ async function connectCommand(urlOrCommand, options) {
727
2595
  try {
728
- const packageJsonPath = import_node_path2.default.join(cwd, "package.json");
729
- const content = await import_node_fs2.promises.readFile(packageJsonPath, "utf-8");
730
- const packageJson2 = JSON.parse(content);
731
- if (packageJson2.scripts?.start) {
732
- return "npm start";
2596
+ const sessionName = options.name || `session-${Date.now()}`;
2597
+ const client = new MCPClient();
2598
+ let session;
2599
+ if (options.stdio) {
2600
+ const parts = urlOrCommand.split(" ");
2601
+ const command = parts[0];
2602
+ const args = parts.slice(1);
2603
+ console.error(
2604
+ formatInfo(`Connecting to stdio server: ${command} ${args.join(" ")}`)
2605
+ );
2606
+ client.addServer(sessionName, {
2607
+ command,
2608
+ args
2609
+ });
2610
+ session = await client.createSession(sessionName);
2611
+ await saveSession(sessionName, {
2612
+ type: "stdio",
2613
+ command,
2614
+ args,
2615
+ lastUsed: (/* @__PURE__ */ new Date()).toISOString()
2616
+ });
2617
+ } else {
2618
+ console.error(formatInfo(`Connecting to ${urlOrCommand}...`));
2619
+ client.addServer(sessionName, {
2620
+ url: urlOrCommand,
2621
+ headers: options.auth ? { Authorization: `Bearer ${options.auth}` } : void 0
2622
+ });
2623
+ session = await client.createSession(sessionName);
2624
+ await saveSession(sessionName, {
2625
+ type: "http",
2626
+ url: urlOrCommand,
2627
+ authToken: options.auth,
2628
+ lastUsed: (/* @__PURE__ */ new Date()).toISOString()
2629
+ });
733
2630
  }
734
- if (packageJson2.main) {
735
- return `node ${packageJson2.main}`;
2631
+ activeSessions.set(sessionName, { client, session });
2632
+ const serverInfo = session.serverInfo;
2633
+ const capabilities = session.serverCapabilities;
2634
+ if (serverInfo) {
2635
+ await updateSessionInfo(sessionName, serverInfo, capabilities);
736
2636
  }
737
- } catch {
2637
+ console.log(formatSuccess(`Connected to ${sessionName}`));
2638
+ if (serverInfo) {
2639
+ console.log("");
2640
+ console.log(formatHeader("Server Information:"));
2641
+ console.log(
2642
+ formatKeyValue({
2643
+ Name: serverInfo.name,
2644
+ Version: serverInfo.version || "unknown"
2645
+ })
2646
+ );
2647
+ }
2648
+ if (capabilities) {
2649
+ console.log("");
2650
+ console.log(formatHeader("Capabilities:"));
2651
+ const caps = Object.keys(capabilities).join(", ");
2652
+ console.log(` ${caps || "none"}`);
2653
+ }
2654
+ const tools = session.tools;
2655
+ console.log("");
2656
+ console.log(
2657
+ formatInfo(
2658
+ `Available: ${tools.length} tool${tools.length !== 1 ? "s" : ""}`
2659
+ )
2660
+ );
2661
+ } catch (error) {
2662
+ console.error(formatError(`Connection failed: ${error.message}`));
2663
+ process.exit(1);
738
2664
  }
739
- return void 0;
740
2665
  }
741
- async function detectRuntime(cwd = process.cwd()) {
2666
+ async function disconnectCommand(sessionName, options) {
742
2667
  try {
743
- const pythonFiles = ["requirements.txt", "pyproject.toml", "setup.py"];
744
- for (const file of pythonFiles) {
745
- try {
746
- await import_node_fs2.promises.access(import_node_path2.default.join(cwd, file));
747
- return "python";
748
- } catch {
749
- continue;
2668
+ if (options?.all) {
2669
+ for (const [name, { client }] of activeSessions.entries()) {
2670
+ await client.closeAllSessions();
2671
+ activeSessions.delete(name);
2672
+ console.log(formatSuccess(`Disconnected from ${name}`));
2673
+ }
2674
+ return;
2675
+ }
2676
+ if (!sessionName) {
2677
+ const active = await getActiveSession();
2678
+ if (!active) {
2679
+ console.error(formatError("No active session to disconnect"));
2680
+ return;
750
2681
  }
2682
+ sessionName = active.name;
751
2683
  }
752
- try {
753
- await import_node_fs2.promises.access(import_node_path2.default.join(cwd, "package.json"));
754
- return "node";
755
- } catch {
2684
+ const sessionData = activeSessions.get(sessionName);
2685
+ if (sessionData) {
2686
+ await sessionData.client.closeAllSessions();
2687
+ activeSessions.delete(sessionName);
2688
+ console.log(formatSuccess(`Disconnected from ${sessionName}`));
2689
+ } else {
2690
+ console.log(formatInfo(`Session '${sessionName}' is not connected`));
756
2691
  }
757
- } catch {
2692
+ } catch (error) {
2693
+ console.error(formatError(`Failed to disconnect: ${error.message}`));
2694
+ process.exit(1);
758
2695
  }
759
- return "node";
760
- }
761
- async function prompt(question, defaultValue = "n") {
762
- const readline = await import("readline");
763
- const rl = readline.createInterface({
764
- input: process.stdin,
765
- output: process.stdout
766
- });
767
- const defaultIndicator = defaultValue === "y" ? "Y/n" : "y/N";
768
- const questionWithDefault = question.replace(
769
- /(\(y\/n\):)/,
770
- `(${defaultIndicator}):`
771
- );
772
- return new Promise((resolve) => {
773
- rl.question(questionWithDefault, (answer) => {
774
- rl.close();
775
- const trimmedAnswer = answer.trim().toLowerCase();
776
- if (trimmedAnswer === "") {
777
- resolve(defaultValue === "y");
778
- } else {
779
- resolve(trimmedAnswer === "y" || trimmedAnswer === "yes");
780
- }
781
- });
782
- });
783
2696
  }
784
- async function createTarball(cwd) {
785
- const tmpDir = import_node_os2.default.tmpdir();
786
- const tarballPath = import_node_path2.default.join(tmpDir, `mcp-deploy-${Date.now()}.tar.gz`);
787
- const excludePatterns = [
788
- "node_modules",
789
- ".git",
790
- "dist",
791
- "build",
792
- ".next",
793
- ".venv",
794
- "__pycache__",
795
- "*.pyc",
796
- ".DS_Store",
797
- "._*",
798
- // macOS resource fork files
799
- ".mcp-use",
800
- // Build artifacts directory
801
- ".env",
802
- ".env.local",
803
- "*.log"
804
- ];
805
- const excludeFlags = excludePatterns.map((pattern) => `--exclude=${pattern}`).join(" ");
806
- const command = `tar ${excludeFlags} -czf "${tarballPath}" -C "${cwd}" . 2>&1 || true`;
2697
+ async function listSessionsCommand() {
807
2698
  try {
808
- await execAsync2(command);
809
- return tarballPath;
810
- } catch (error) {
811
- throw new Error(
812
- `Failed to create tarball: ${error instanceof Error ? error.message : "Unknown error"}`
2699
+ const sessions = await listAllSessions();
2700
+ if (sessions.length === 0) {
2701
+ console.log(formatInfo("No saved sessions"));
2702
+ console.log(
2703
+ formatInfo("Connect to a server with: npx mcp-use client connect <url>")
2704
+ );
2705
+ return;
2706
+ }
2707
+ console.log(formatHeader("Saved Sessions:"));
2708
+ console.log("");
2709
+ const tableData = sessions.map((s) => ({
2710
+ name: s.isActive ? source_default.green.bold(`${s.name} *`) : s.name,
2711
+ type: s.config.type,
2712
+ target: s.config.type === "http" ? s.config.url || "" : `${s.config.command} ${(s.config.args || []).join(" ")}`,
2713
+ server: s.config.serverInfo?.name || "unknown",
2714
+ status: activeSessions.has(s.name) ? source_default.green("connected") : source_default.gray("disconnected")
2715
+ }));
2716
+ console.log(
2717
+ formatTable(tableData, [
2718
+ { key: "name", header: "Name" },
2719
+ { key: "type", header: "Type" },
2720
+ { key: "target", header: "Target", width: 40 },
2721
+ { key: "server", header: "Server" },
2722
+ { key: "status", header: "Status" }
2723
+ ])
813
2724
  );
2725
+ console.log("");
2726
+ console.log(source_default.gray("* = active session"));
2727
+ } catch (error) {
2728
+ console.error(formatError(`Failed to list sessions: ${error.message}`));
2729
+ process.exit(1);
814
2730
  }
815
2731
  }
816
- function formatFileSize(bytes) {
817
- if (bytes === 0) return "0 B";
818
- const k = 1024;
819
- const sizes = ["B", "KB", "MB", "GB"];
820
- const i = Math.floor(Math.log(bytes) / Math.log(k));
821
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
2732
+ async function switchSessionCommand(name) {
2733
+ try {
2734
+ await setActiveSession(name);
2735
+ console.log(formatSuccess(`Switched to session '${name}'`));
2736
+ } catch (error) {
2737
+ console.error(formatError(`Failed to switch session: ${error.message}`));
2738
+ process.exit(1);
2739
+ }
822
2740
  }
823
- async function displayDeploymentProgress(api, deployment) {
824
- const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
825
- let frameIndex = 0;
826
- let spinnerInterval = null;
827
- let lastStep = "";
828
- const startSpinner = (message) => {
829
- if (spinnerInterval) {
830
- clearInterval(spinnerInterval);
2741
+ async function listToolsCommand(options) {
2742
+ try {
2743
+ const result = await getOrRestoreSession(options.session || null);
2744
+ if (!result) return;
2745
+ const { session } = result;
2746
+ const tools = await session.listTools();
2747
+ if (options.json) {
2748
+ console.log(formatJson(tools));
2749
+ return;
831
2750
  }
832
- process.stdout.write("\r\x1B[K");
833
- spinnerInterval = setInterval(() => {
834
- const frame = frames[frameIndex];
835
- frameIndex = (frameIndex + 1) % frames.length;
836
- process.stdout.write(
837
- "\r" + import_chalk2.default.cyan(frame) + " " + import_chalk2.default.gray(message)
838
- );
839
- }, 80);
840
- };
841
- const stopSpinner = () => {
842
- if (spinnerInterval) {
843
- clearInterval(spinnerInterval);
844
- spinnerInterval = null;
845
- process.stdout.write("\r\x1B[K");
2751
+ if (tools.length === 0) {
2752
+ console.log(formatInfo("No tools available"));
2753
+ return;
846
2754
  }
847
- };
848
- console.log();
849
- startSpinner("Deploying...");
2755
+ console.log(formatHeader(`Available Tools (${tools.length}):`));
2756
+ console.log("");
2757
+ const tableData = tools.map((tool) => ({
2758
+ name: source_default.bold(tool.name),
2759
+ description: tool.description || source_default.gray("No description")
2760
+ }));
2761
+ console.log(
2762
+ formatTable(tableData, [
2763
+ { key: "name", header: "Tool", width: 25 },
2764
+ { key: "description", header: "Description", width: 50 }
2765
+ ])
2766
+ );
2767
+ } catch (error) {
2768
+ console.error(formatError(`Failed to list tools: ${error.message}`));
2769
+ process.exit(1);
2770
+ }
2771
+ }
2772
+ async function describeToolCommand(toolName, options) {
850
2773
  try {
851
- for await (const log of api.streamDeploymentLogs(deployment.id)) {
852
- try {
853
- const logData = JSON.parse(log);
854
- if (logData.step && logData.step !== lastStep) {
855
- lastStep = logData.step;
856
- const stepMessages = {
857
- clone: "Preparing source code...",
858
- analyze: "Analyzing project...",
859
- build: "Building container image...",
860
- deploy: "Deploying to cloud..."
861
- };
862
- const message = stepMessages[logData.step] || "Deploying...";
863
- startSpinner(message);
864
- }
865
- if (logData.line) {
866
- stopSpinner();
867
- const levelColor = logData.level === "error" ? import_chalk2.default.red : logData.level === "warn" ? import_chalk2.default.yellow : import_chalk2.default.gray;
868
- const stepPrefix = logData.step ? import_chalk2.default.cyan(`[${logData.step}]`) + " " : "";
869
- console.log(stepPrefix + levelColor(logData.line));
870
- }
871
- } catch {
872
- }
2774
+ const result = await getOrRestoreSession(options.session || null);
2775
+ if (!result) return;
2776
+ const { session } = result;
2777
+ const tools = session.tools;
2778
+ const tool = tools.find((t) => t.name === toolName);
2779
+ if (!tool) {
2780
+ console.error(formatError(`Tool '${toolName}' not found`));
2781
+ console.log("");
2782
+ console.log(formatInfo("Available tools:"));
2783
+ tools.forEach((t) => console.log(` \u2022 ${t.name}`));
2784
+ return;
2785
+ }
2786
+ console.log(formatHeader(`Tool: ${tool.name}`));
2787
+ console.log("");
2788
+ if (tool.description) {
2789
+ console.log(tool.description);
2790
+ console.log("");
2791
+ }
2792
+ if (tool.inputSchema) {
2793
+ console.log(formatHeader("Input Schema:"));
2794
+ console.log(formatSchema(tool.inputSchema));
873
2795
  }
874
2796
  } catch (error) {
875
- stopSpinner();
2797
+ console.error(formatError(`Failed to describe tool: ${error.message}`));
2798
+ process.exit(1);
876
2799
  }
877
- let checkCount = 0;
878
- const maxChecks = 60;
879
- let delay = 3e3;
880
- const maxDelay = 1e4;
881
- let lastDisplayedLogLength = 0;
882
- while (checkCount < maxChecks) {
883
- const currentDelay = delay;
884
- await new Promise((resolve) => setTimeout(resolve, currentDelay));
885
- const finalDeployment = await api.getDeployment(deployment.id);
886
- if (finalDeployment.buildLogs && finalDeployment.buildLogs.length > lastDisplayedLogLength) {
887
- const newLogs = finalDeployment.buildLogs.substring(
888
- lastDisplayedLogLength
889
- );
890
- const logLines = newLogs.split("\n").filter((l) => l.trim());
891
- for (const line of logLines) {
892
- try {
893
- const logData = JSON.parse(line);
894
- if (logData.line) {
895
- stopSpinner();
896
- const levelColor = logData.level === "error" ? import_chalk2.default.red : logData.level === "warn" ? import_chalk2.default.yellow : import_chalk2.default.gray;
897
- const stepPrefix = logData.step ? import_chalk2.default.cyan(`[${logData.step}]`) + " " : "";
898
- console.log(stepPrefix + levelColor(logData.line));
899
- }
900
- } catch {
901
- }
902
- }
903
- lastDisplayedLogLength = finalDeployment.buildLogs.length;
904
- }
905
- if (finalDeployment.status === "running") {
906
- const mcpUrl = `https://${finalDeployment.domain}/mcp`;
907
- const inspectorUrl = `https://inspector.mcp-use.com/inspector?autoConnect=${encodeURIComponent(mcpUrl)}`;
908
- console.log(import_chalk2.default.green.bold("\u2713 Deployment successful!\n"));
909
- console.log(import_chalk2.default.white("\u{1F310} MCP Server URL:"));
910
- console.log(import_chalk2.default.cyan.bold(` ${mcpUrl}
911
- `));
912
- console.log(import_chalk2.default.white("\u{1F50D} Inspector URL:"));
913
- console.log(import_chalk2.default.cyan.bold(` ${inspectorUrl}
914
- `));
915
- if (finalDeployment.customDomain) {
916
- const customMcpUrl = `https://${finalDeployment.customDomain}/mcp`;
917
- const customInspectorUrl = `https://inspector.mcp-use.com/inspect?autoConnect=${encodeURIComponent(customMcpUrl)}`;
918
- console.log(import_chalk2.default.white("\u{1F517} Custom Domain:"));
919
- console.log(import_chalk2.default.cyan.bold(` ${customMcpUrl}
920
- `));
921
- console.log(import_chalk2.default.white("\u{1F50D} Custom Inspector:"));
922
- console.log(import_chalk2.default.cyan.bold(` ${customInspectorUrl}
923
- `));
924
- }
925
- console.log(
926
- import_chalk2.default.gray("Deployment ID: ") + import_chalk2.default.white(finalDeployment.id)
927
- );
928
- return;
929
- } else if (finalDeployment.status === "failed") {
930
- console.log(import_chalk2.default.red.bold("\u2717 Deployment failed\n"));
931
- if (finalDeployment.error) {
932
- console.log(import_chalk2.default.red("Error: ") + finalDeployment.error);
2800
+ }
2801
+ async function callToolCommand(toolName, argsJson, options) {
2802
+ try {
2803
+ const result = await getOrRestoreSession(options?.session || null);
2804
+ if (!result) return;
2805
+ const { session } = result;
2806
+ let args = {};
2807
+ if (argsJson) {
2808
+ try {
2809
+ args = JSON.parse(argsJson);
2810
+ } catch (error) {
2811
+ console.error(formatError("Invalid JSON arguments"));
2812
+ return;
933
2813
  }
934
- if (finalDeployment.buildLogs) {
935
- console.log(import_chalk2.default.gray("\nBuild logs:"));
936
- try {
937
- const logs = finalDeployment.buildLogs.split("\n").filter((l) => l.trim());
938
- for (const log of logs) {
939
- try {
940
- const logData = JSON.parse(log);
941
- if (logData.line) {
942
- console.log(import_chalk2.default.gray(` ${logData.line}`));
943
- }
944
- } catch {
945
- console.log(import_chalk2.default.gray(` ${log}`));
946
- }
947
- }
948
- } catch {
949
- console.log(import_chalk2.default.gray(finalDeployment.buildLogs));
950
- }
2814
+ } else {
2815
+ const tools = session.tools;
2816
+ const tool = tools.find((t) => t.name === toolName);
2817
+ if (tool?.inputSchema?.required && tool.inputSchema.required.length > 0) {
2818
+ console.error(
2819
+ formatError(
2820
+ "This tool requires arguments. Provide them as a JSON string."
2821
+ )
2822
+ );
2823
+ console.log("");
2824
+ console.log(formatInfo("Example:"));
2825
+ console.log(
2826
+ ` npx mcp-use client tools call ${toolName} '{"param": "value"}'`
2827
+ );
2828
+ console.log("");
2829
+ console.log(formatInfo("Tool schema:"));
2830
+ console.log(formatSchema(tool.inputSchema));
2831
+ return;
951
2832
  }
952
- process.exit(1);
953
- } else if (finalDeployment.status === "building") {
954
- startSpinner("Building and deploying...");
955
- checkCount++;
956
- delay = Math.min(delay * 1.2, maxDelay);
2833
+ }
2834
+ console.error(formatInfo(`Calling tool '${toolName}'...`));
2835
+ const callResult = await session.callTool(toolName, args, {
2836
+ timeout: options?.timeout
2837
+ });
2838
+ if (options?.json) {
2839
+ console.log(formatJson(callResult));
957
2840
  } else {
958
- console.log(
959
- import_chalk2.default.yellow("\u26A0\uFE0F Deployment status: ") + finalDeployment.status
960
- );
2841
+ console.log(formatToolCall(callResult));
2842
+ }
2843
+ } catch (error) {
2844
+ console.error(formatError(`Failed to call tool: ${error.message}`));
2845
+ process.exit(1);
2846
+ }
2847
+ }
2848
+ async function listResourcesCommand(options) {
2849
+ try {
2850
+ const result = await getOrRestoreSession(options.session || null);
2851
+ if (!result) return;
2852
+ const { session } = result;
2853
+ const resourcesResult = await session.listAllResources();
2854
+ const resources = resourcesResult.resources;
2855
+ if (options.json) {
2856
+ console.log(formatJson(resources));
961
2857
  return;
962
2858
  }
2859
+ if (resources.length === 0) {
2860
+ console.log(formatInfo("No resources available"));
2861
+ return;
2862
+ }
2863
+ console.log(formatHeader(`Available Resources (${resources.length}):`));
2864
+ console.log("");
2865
+ const tableData = resources.map((resource) => ({
2866
+ uri: resource.uri,
2867
+ name: resource.name || source_default.gray("(no name)"),
2868
+ type: resource.mimeType || source_default.gray("unknown")
2869
+ }));
2870
+ console.log(
2871
+ formatTable(tableData, [
2872
+ { key: "uri", header: "URI", width: 40 },
2873
+ { key: "name", header: "Name", width: 20 },
2874
+ { key: "type", header: "Type", width: 15 }
2875
+ ])
2876
+ );
2877
+ } catch (error) {
2878
+ console.error(formatError(`Failed to list resources: ${error.message}`));
2879
+ process.exit(1);
963
2880
  }
964
- stopSpinner();
965
- console.log(import_chalk2.default.yellow("\u26A0\uFE0F Deployment is taking longer than expected."));
966
- console.log(
967
- import_chalk2.default.gray("Check status with: ") + import_chalk2.default.white(`mcp-use status ${deployment.id}`)
968
- );
969
2881
  }
970
- async function deployCommand(options) {
2882
+ async function readResourceCommand(uri, options) {
971
2883
  try {
972
- const cwd = process.cwd();
973
- if (!await isLoggedIn()) {
974
- console.log(import_chalk2.default.red("\u2717 You are not logged in."));
975
- console.log(
976
- import_chalk2.default.gray("Run " + import_chalk2.default.white("mcp-use login") + " to get started.")
977
- );
978
- process.exit(1);
2884
+ const result = await getOrRestoreSession(options.session || null);
2885
+ if (!result) return;
2886
+ const { session } = result;
2887
+ console.error(formatInfo(`Reading resource: ${uri}`));
2888
+ const resource = await session.readResource(uri);
2889
+ if (options.json) {
2890
+ console.log(formatJson(resource));
2891
+ } else {
2892
+ console.log(formatResourceContent(resource));
979
2893
  }
980
- console.log(import_chalk2.default.cyan.bold("\u{1F680} Deploying to mcp-use cloud...\n"));
981
- const isMcp = await isMcpProject(cwd);
982
- if (!isMcp) {
983
- console.log(
984
- import_chalk2.default.yellow(
985
- "\u26A0\uFE0F This doesn't appear to be an MCP server project (no mcp-use or @modelcontextprotocol/sdk dependency found)."
986
- )
987
- );
988
- const shouldContinue = await prompt(
989
- import_chalk2.default.white("Continue anyway? (y/n): ")
990
- );
991
- if (!shouldContinue) {
992
- console.log(import_chalk2.default.gray("Deployment cancelled."));
993
- process.exit(0);
2894
+ } catch (error) {
2895
+ console.error(formatError(`Failed to read resource: ${error.message}`));
2896
+ process.exit(1);
2897
+ }
2898
+ }
2899
+ async function subscribeResourceCommand(uri, options) {
2900
+ try {
2901
+ const result = await getOrRestoreSession(options.session || null);
2902
+ if (!result) return;
2903
+ const { session } = result;
2904
+ await session.subscribeToResource(uri);
2905
+ console.log(formatSuccess(`Subscribed to resource: ${uri}`));
2906
+ session.on("notification", async (notification) => {
2907
+ if (notification.method === "notifications/resources/updated") {
2908
+ console.log("");
2909
+ console.log(formatInfo("Resource updated:"));
2910
+ console.log(formatJson(notification.params));
994
2911
  }
995
- console.log();
2912
+ });
2913
+ console.log(formatInfo("Listening for updates... (Press Ctrl+C to stop)"));
2914
+ await new Promise(() => {
2915
+ });
2916
+ } catch (error) {
2917
+ console.error(
2918
+ formatError(`Failed to subscribe to resource: ${error.message}`)
2919
+ );
2920
+ process.exit(1);
2921
+ }
2922
+ }
2923
+ async function unsubscribeResourceCommand(uri, options) {
2924
+ try {
2925
+ const result = await getOrRestoreSession(options.session || null);
2926
+ if (!result) return;
2927
+ const { session } = result;
2928
+ await session.unsubscribeFromResource(uri);
2929
+ console.log(formatSuccess(`Unsubscribed from resource: ${uri}`));
2930
+ } catch (error) {
2931
+ console.error(
2932
+ formatError(`Failed to unsubscribe from resource: ${error.message}`)
2933
+ );
2934
+ process.exit(1);
2935
+ }
2936
+ }
2937
+ async function listPromptsCommand(options) {
2938
+ try {
2939
+ const result = await getOrRestoreSession(options.session || null);
2940
+ if (!result) return;
2941
+ const { session } = result;
2942
+ const promptsResult = await session.listPrompts();
2943
+ const prompts = promptsResult.prompts;
2944
+ if (options.json) {
2945
+ console.log(formatJson(prompts));
2946
+ return;
996
2947
  }
997
- const gitInfo = await getGitInfo(cwd);
998
- if (!options.fromSource && gitInfo.isGitRepo && gitInfo.remoteUrl && isGitHubUrl(gitInfo.remoteUrl)) {
999
- if (!gitInfo.owner || !gitInfo.repo) {
1000
- console.log(
1001
- import_chalk2.default.red(
1002
- "\u2717 Could not parse GitHub repository information from remote URL."
1003
- )
1004
- );
1005
- process.exit(1);
1006
- }
1007
- console.log(import_chalk2.default.white("GitHub repository detected:"));
1008
- console.log(
1009
- import_chalk2.default.gray(` Repository: `) + import_chalk2.default.cyan(`${gitInfo.owner}/${gitInfo.repo}`)
1010
- );
1011
- console.log(
1012
- import_chalk2.default.gray(` Branch: `) + import_chalk2.default.cyan(gitInfo.branch || "main")
1013
- );
1014
- if (gitInfo.commitSha) {
1015
- console.log(
1016
- import_chalk2.default.gray(` Commit: `) + import_chalk2.default.gray(gitInfo.commitSha.substring(0, 7))
1017
- );
1018
- }
1019
- if (gitInfo.commitMessage) {
1020
- console.log(
1021
- import_chalk2.default.gray(` Message: `) + import_chalk2.default.gray(gitInfo.commitMessage.split("\n")[0])
1022
- );
1023
- }
1024
- console.log();
1025
- const shouldDeploy = await prompt(
1026
- import_chalk2.default.white(
1027
- `Deploy from GitHub repository ${gitInfo.owner}/${gitInfo.repo}? (y/n): `
1028
- )
1029
- );
1030
- if (!shouldDeploy) {
1031
- console.log(import_chalk2.default.gray("Deployment cancelled."));
1032
- process.exit(0);
1033
- }
1034
- const projectName = options.name || await getProjectName(cwd);
1035
- const runtime = options.runtime || await detectRuntime(cwd);
1036
- const port = options.port || 3e3;
1037
- const buildCommand = await detectBuildCommand(cwd);
1038
- const startCommand = await detectStartCommand(cwd);
1039
- console.log();
1040
- console.log(import_chalk2.default.white("Deployment configuration:"));
1041
- console.log(import_chalk2.default.gray(` Name: `) + import_chalk2.default.cyan(projectName));
1042
- console.log(import_chalk2.default.gray(` Runtime: `) + import_chalk2.default.cyan(runtime));
1043
- console.log(import_chalk2.default.gray(` Port: `) + import_chalk2.default.cyan(port));
1044
- if (buildCommand) {
1045
- console.log(import_chalk2.default.gray(` Build command: `) + import_chalk2.default.cyan(buildCommand));
1046
- }
1047
- if (startCommand) {
1048
- console.log(import_chalk2.default.gray(` Start command: `) + import_chalk2.default.cyan(startCommand));
1049
- }
1050
- console.log();
1051
- const deploymentRequest = {
1052
- name: projectName,
1053
- source: {
1054
- type: "github",
1055
- repo: `${gitInfo.owner}/${gitInfo.repo}`,
1056
- branch: gitInfo.branch || "main",
1057
- runtime,
1058
- port,
1059
- buildCommand,
1060
- startCommand
1061
- },
1062
- healthCheckPath: "/healthz"
1063
- };
1064
- console.log(import_chalk2.default.gray("Creating deployment..."));
1065
- const api = await McpUseAPI.create();
1066
- const deployment = await api.createDeployment(deploymentRequest);
1067
- console.log(
1068
- import_chalk2.default.green("\u2713 Deployment created: ") + import_chalk2.default.gray(deployment.id)
1069
- );
1070
- await displayDeploymentProgress(api, deployment);
1071
- if (options.open && deployment.domain) {
1072
- console.log();
1073
- console.log(import_chalk2.default.gray("Opening deployment in browser..."));
1074
- await (0, import_open2.default)(`https://${deployment.domain}`);
2948
+ if (prompts.length === 0) {
2949
+ console.log(formatInfo("No prompts available"));
2950
+ return;
2951
+ }
2952
+ console.log(formatHeader(`Available Prompts (${prompts.length}):`));
2953
+ console.log("");
2954
+ const tableData = prompts.map((prompt2) => ({
2955
+ name: source_default.bold(prompt2.name),
2956
+ description: prompt2.description || source_default.gray("No description")
2957
+ }));
2958
+ console.log(
2959
+ formatTable(tableData, [
2960
+ { key: "name", header: "Prompt", width: 25 },
2961
+ { key: "description", header: "Description", width: 50 }
2962
+ ])
2963
+ );
2964
+ } catch (error) {
2965
+ console.error(formatError(`Failed to list prompts: ${error.message}`));
2966
+ process.exit(1);
2967
+ }
2968
+ }
2969
+ async function getPromptCommand(promptName, argsJson, options) {
2970
+ try {
2971
+ const result = await getOrRestoreSession(options?.session || null);
2972
+ if (!result) return;
2973
+ const { session } = result;
2974
+ let args = {};
2975
+ if (argsJson) {
2976
+ try {
2977
+ args = JSON.parse(argsJson);
2978
+ } catch (error) {
2979
+ console.error(formatError("Invalid JSON arguments"));
2980
+ return;
1075
2981
  }
2982
+ }
2983
+ console.error(formatInfo(`Getting prompt '${promptName}'...`));
2984
+ const prompt2 = await session.getPrompt(promptName, args);
2985
+ if (options?.json) {
2986
+ console.log(formatJson(prompt2));
1076
2987
  } else {
1077
- if (options.fromSource) {
1078
- console.log(
1079
- import_chalk2.default.white("\u{1F4E6} Deploying from local source code (--from-source)...")
1080
- );
1081
- } else {
1082
- console.log(
1083
- import_chalk2.default.yellow(
1084
- "\u26A0\uFE0F This is not a GitHub repository or no remote is configured."
1085
- )
1086
- );
1087
- console.log(import_chalk2.default.white("Deploying from local source code instead..."));
2988
+ console.log(formatHeader(`Prompt: ${promptName}`));
2989
+ console.log("");
2990
+ if (prompt2.description) {
2991
+ console.log(prompt2.description);
2992
+ console.log("");
1088
2993
  }
1089
- console.log();
1090
- const projectName = options.name || await getProjectName(cwd);
1091
- const runtime = options.runtime || await detectRuntime(cwd);
1092
- const port = options.port || 3e3;
1093
- const buildCommand = await detectBuildCommand(cwd);
1094
- const startCommand = await detectStartCommand(cwd);
1095
- console.log(import_chalk2.default.white("Deployment configuration:"));
1096
- console.log(import_chalk2.default.gray(` Name: `) + import_chalk2.default.cyan(projectName));
1097
- console.log(import_chalk2.default.gray(` Runtime: `) + import_chalk2.default.cyan(runtime));
1098
- console.log(import_chalk2.default.gray(` Port: `) + import_chalk2.default.cyan(port));
1099
- if (buildCommand) {
1100
- console.log(import_chalk2.default.gray(` Build command: `) + import_chalk2.default.cyan(buildCommand));
2994
+ if (prompt2.messages) {
2995
+ console.log(formatHeader("Messages:"));
2996
+ console.log("");
2997
+ console.log(formatPromptMessages(prompt2.messages));
1101
2998
  }
1102
- if (startCommand) {
1103
- console.log(import_chalk2.default.gray(` Start command: `) + import_chalk2.default.cyan(startCommand));
2999
+ }
3000
+ } catch (error) {
3001
+ console.error(formatError(`Failed to get prompt: ${error.message}`));
3002
+ process.exit(1);
3003
+ }
3004
+ }
3005
+ async function interactiveCommand(options) {
3006
+ try {
3007
+ const result = await getOrRestoreSession(options.session || null);
3008
+ if (!result) return;
3009
+ const { name: sessionName, session } = result;
3010
+ console.log(formatHeader("MCP Interactive Mode"));
3011
+ console.log("");
3012
+ console.log(formatInfo(`Connected to: ${sessionName}`));
3013
+ console.log("");
3014
+ console.log(source_default.gray("Commands:"));
3015
+ console.log(source_default.gray(" tools list - List available tools"));
3016
+ console.log(
3017
+ source_default.gray(
3018
+ " tools call <name> - Call a tool (will prompt for args)"
3019
+ )
3020
+ );
3021
+ console.log(source_default.gray(" tools describe <name> - Show tool details"));
3022
+ console.log(
3023
+ source_default.gray(" resources list - List available resources")
3024
+ );
3025
+ console.log(source_default.gray(" resources read <uri> - Read a resource"));
3026
+ console.log(
3027
+ source_default.gray(" prompts list - List available prompts")
3028
+ );
3029
+ console.log(source_default.gray(" prompts get <name> - Get a prompt"));
3030
+ console.log(source_default.gray(" sessions list - List all sessions"));
3031
+ console.log(
3032
+ source_default.gray(" sessions switch <name> - Switch to another session")
3033
+ );
3034
+ console.log(
3035
+ source_default.gray(" exit, quit - Exit interactive mode")
3036
+ );
3037
+ console.log("");
3038
+ const rl = createInterface({
3039
+ input: process.stdin,
3040
+ output: process.stdout,
3041
+ prompt: source_default.cyan("mcp> ")
3042
+ });
3043
+ rl.prompt();
3044
+ rl.on("line", async (line) => {
3045
+ const trimmed = line.trim();
3046
+ if (!trimmed) {
3047
+ rl.prompt();
3048
+ return;
1104
3049
  }
1105
- console.log();
1106
- const shouldDeploy = await prompt(
1107
- import_chalk2.default.white("Deploy from local source? (y/n): "),
1108
- "y"
1109
- );
1110
- if (!shouldDeploy) {
1111
- console.log(import_chalk2.default.gray("Deployment cancelled."));
3050
+ if (trimmed === "exit" || trimmed === "quit") {
3051
+ console.log(formatInfo("Goodbye!"));
3052
+ rl.close();
1112
3053
  process.exit(0);
1113
3054
  }
1114
- console.log();
1115
- console.log(import_chalk2.default.gray("Packaging source code..."));
1116
- const tarballPath = await createTarball(cwd);
1117
- const stats = await import_node_fs2.promises.stat(tarballPath);
1118
- console.log(
1119
- import_chalk2.default.green("\u2713 Packaged: ") + import_chalk2.default.gray(formatFileSize(stats.size))
1120
- );
1121
- const maxSize = 2 * 1024 * 1024;
1122
- if (stats.size > maxSize) {
1123
- console.log(
1124
- import_chalk2.default.red(
1125
- `\u2717 File size (${formatFileSize(stats.size)}) exceeds maximum of 2MB`
1126
- )
1127
- );
1128
- await import_node_fs2.promises.unlink(tarballPath);
1129
- process.exit(1);
1130
- }
1131
- const deploymentRequest = {
1132
- name: projectName,
1133
- source: {
1134
- type: "upload",
1135
- runtime,
1136
- port,
1137
- buildCommand,
1138
- startCommand
1139
- },
1140
- healthCheckPath: "/healthz"
1141
- };
1142
- console.log(import_chalk2.default.gray("Creating deployment..."));
1143
- const api = await McpUseAPI.create();
1144
- const deployment = await api.createDeploymentWithUpload(
1145
- deploymentRequest,
1146
- tarballPath
1147
- );
1148
- await import_node_fs2.promises.unlink(tarballPath);
1149
- console.log(
1150
- import_chalk2.default.green("\u2713 Deployment created: ") + import_chalk2.default.gray(deployment.id)
1151
- );
1152
- await displayDeploymentProgress(api, deployment);
1153
- if (options.open && deployment.domain) {
1154
- console.log();
1155
- console.log(import_chalk2.default.gray("Opening deployment in browser..."));
1156
- await (0, import_open2.default)(`https://${deployment.domain}`);
3055
+ const parts = trimmed.split(" ");
3056
+ const scope = parts[0];
3057
+ const command = parts[1];
3058
+ const arg = parts[2];
3059
+ try {
3060
+ if (scope === "tools") {
3061
+ if (command === "list") {
3062
+ const tools = await session.listTools();
3063
+ console.log(
3064
+ formatInfo(
3065
+ `Available tools: ${tools.map((t) => t.name).join(", ")}`
3066
+ )
3067
+ );
3068
+ } else if (command === "call" && arg) {
3069
+ rl.question(
3070
+ "Arguments (JSON, or press Enter for none): ",
3071
+ async (argsInput) => {
3072
+ try {
3073
+ const args = argsInput.trim() ? JSON.parse(argsInput) : {};
3074
+ const result2 = await session.callTool(arg, args);
3075
+ console.log(formatToolCall(result2));
3076
+ } catch (error) {
3077
+ console.error(formatError(error.message));
3078
+ }
3079
+ rl.prompt();
3080
+ }
3081
+ );
3082
+ return;
3083
+ } else if (command === "describe" && arg) {
3084
+ const tools = session.tools;
3085
+ const tool = tools.find((t) => t.name === arg);
3086
+ if (tool) {
3087
+ console.log(formatHeader(`Tool: ${tool.name}`));
3088
+ if (tool.description) console.log(tool.description);
3089
+ if (tool.inputSchema) {
3090
+ console.log("");
3091
+ console.log(formatSchema(tool.inputSchema));
3092
+ }
3093
+ } else {
3094
+ console.error(formatError(`Tool '${arg}' not found`));
3095
+ }
3096
+ } else {
3097
+ console.error(
3098
+ formatError(
3099
+ "Invalid command. Try: tools list, tools call <name>, tools describe <name>"
3100
+ )
3101
+ );
3102
+ }
3103
+ } else if (scope === "resources") {
3104
+ if (command === "list") {
3105
+ const result2 = await session.listAllResources();
3106
+ const resources = result2.resources;
3107
+ console.log(
3108
+ formatInfo(
3109
+ `Available resources: ${resources.map((r) => r.uri).join(", ")}`
3110
+ )
3111
+ );
3112
+ } else if (command === "read" && arg) {
3113
+ const resource = await session.readResource(arg);
3114
+ console.log(formatResourceContent(resource));
3115
+ } else {
3116
+ console.error(
3117
+ formatError(
3118
+ "Invalid command. Try: resources list, resources read <uri>"
3119
+ )
3120
+ );
3121
+ }
3122
+ } else if (scope === "prompts") {
3123
+ if (command === "list") {
3124
+ const result2 = await session.listPrompts();
3125
+ const prompts = result2.prompts;
3126
+ console.log(
3127
+ formatInfo(
3128
+ `Available prompts: ${prompts.map((p) => p.name).join(", ")}`
3129
+ )
3130
+ );
3131
+ } else if (command === "get" && arg) {
3132
+ rl.question(
3133
+ "Arguments (JSON, or press Enter for none): ",
3134
+ async (argsInput) => {
3135
+ try {
3136
+ const args = argsInput.trim() ? JSON.parse(argsInput) : {};
3137
+ const prompt2 = await session.getPrompt(arg, args);
3138
+ console.log(formatPromptMessages(prompt2.messages));
3139
+ } catch (error) {
3140
+ console.error(formatError(error.message));
3141
+ }
3142
+ rl.prompt();
3143
+ }
3144
+ );
3145
+ return;
3146
+ } else {
3147
+ console.error(
3148
+ formatError(
3149
+ "Invalid command. Try: prompts list, prompts get <name>"
3150
+ )
3151
+ );
3152
+ }
3153
+ } else if (scope === "sessions") {
3154
+ if (command === "list") {
3155
+ await listSessionsCommand();
3156
+ } else if (command === "switch" && arg) {
3157
+ console.log(
3158
+ formatWarning(
3159
+ "Session switching in interactive mode will be available in a future version"
3160
+ )
3161
+ );
3162
+ } else {
3163
+ console.error(formatError("Invalid command. Try: sessions list"));
3164
+ }
3165
+ } else {
3166
+ console.error(
3167
+ formatError(
3168
+ "Unknown command. Type a valid scope: tools, resources, prompts, sessions"
3169
+ )
3170
+ );
3171
+ }
3172
+ } catch (error) {
3173
+ console.error(formatError(error.message));
1157
3174
  }
1158
- }
3175
+ rl.prompt();
3176
+ });
3177
+ rl.on("close", () => {
3178
+ console.log("");
3179
+ console.log(formatInfo("Goodbye!"));
3180
+ process.exit(0);
3181
+ });
1159
3182
  } catch (error) {
1160
3183
  console.error(
1161
- import_chalk2.default.red.bold("\n\u2717 Deployment failed:"),
1162
- import_chalk2.default.red(error instanceof Error ? error.message : "Unknown error")
3184
+ formatError(`Failed to start interactive mode: ${error.message}`)
1163
3185
  );
1164
3186
  process.exit(1);
1165
3187
  }
1166
3188
  }
3189
+ function createClientCommand() {
3190
+ const clientCommand = new Command("client").description(
3191
+ "Interactive MCP client for terminal usage"
3192
+ );
3193
+ clientCommand.command("connect <url>").description("Connect to an MCP server").option("--name <name>", "Session name").option("--stdio", "Use stdio connector instead of HTTP").option("--auth <token>", "Authentication token").action(connectCommand);
3194
+ clientCommand.command("disconnect [session]").description("Disconnect from a session").option("--all", "Disconnect all sessions").action(disconnectCommand);
3195
+ const sessionsCommand = new Command("sessions").description(
3196
+ "Manage CLI sessions"
3197
+ );
3198
+ sessionsCommand.command("list").description("List all saved sessions").action(listSessionsCommand);
3199
+ sessionsCommand.command("switch <name>").description("Switch to a different session").action(switchSessionCommand);
3200
+ clientCommand.addCommand(sessionsCommand);
3201
+ const toolsCommand = new Command("tools").description(
3202
+ "Interact with MCP tools"
3203
+ );
3204
+ toolsCommand.command("list").description("List available tools").option("--session <name>", "Use specific session").option("--json", "Output as JSON").action(listToolsCommand);
3205
+ toolsCommand.command("call <name> [args]").description("Call a tool with arguments (JSON string)").option("--session <name>", "Use specific session").option("--timeout <ms>", "Request timeout in milliseconds", parseInt).option("--json", "Output as JSON").action(callToolCommand);
3206
+ toolsCommand.command("describe <name>").description("Show tool details and schema").option("--session <name>", "Use specific session").action(describeToolCommand);
3207
+ clientCommand.addCommand(toolsCommand);
3208
+ const resourcesCommand = new Command("resources").description(
3209
+ "Interact with MCP resources"
3210
+ );
3211
+ resourcesCommand.command("list").description("List available resources").option("--session <name>", "Use specific session").option("--json", "Output as JSON").action(listResourcesCommand);
3212
+ resourcesCommand.command("read <uri>").description("Read a resource by URI").option("--session <name>", "Use specific session").option("--json", "Output as JSON").action(readResourceCommand);
3213
+ resourcesCommand.command("subscribe <uri>").description("Subscribe to resource updates").option("--session <name>", "Use specific session").action(subscribeResourceCommand);
3214
+ resourcesCommand.command("unsubscribe <uri>").description("Unsubscribe from resource updates").option("--session <name>", "Use specific session").action(unsubscribeResourceCommand);
3215
+ clientCommand.addCommand(resourcesCommand);
3216
+ const promptsCommand = new Command("prompts").description(
3217
+ "Interact with MCP prompts"
3218
+ );
3219
+ promptsCommand.command("list").description("List available prompts").option("--session <name>", "Use specific session").option("--json", "Output as JSON").action(listPromptsCommand);
3220
+ promptsCommand.command("get <name> [args]").description("Get a prompt with arguments (JSON string)").option("--session <name>", "Use specific session").option("--json", "Output as JSON").action(getPromptCommand);
3221
+ clientCommand.addCommand(promptsCommand);
3222
+ clientCommand.command("interactive").description("Start interactive REPL mode").option("--session <name>", "Use specific session").action(interactiveCommand);
3223
+ return clientCommand;
3224
+ }
1167
3225
 
1168
3226
  // src/index.ts
1169
- var program = new import_commander.Command();
1170
- var packageContent = (0, import_node_fs3.readFileSync)(
1171
- import_node_path3.default.join(__dirname, "../package.json"),
3227
+ var program = new Command2();
3228
+ var packageContent = readFileSync(
3229
+ path5.join(__dirname, "../package.json"),
1172
3230
  "utf-8"
1173
3231
  );
1174
3232
  var packageJson = JSON.parse(packageContent);
@@ -1208,12 +3266,12 @@ async function waitForServer(port, host = "localhost", maxAttempts = 30) {
1208
3266
  }
1209
3267
  return false;
1210
3268
  }
1211
- function runCommand(command, args, cwd, env, filterStderr = false) {
1212
- const proc = (0, import_node_child_process3.spawn)(command, args, {
3269
+ function runCommand(command, args, cwd, env2, filterStderr = false) {
3270
+ const proc = spawn(command, args, {
1213
3271
  cwd,
1214
3272
  stdio: filterStderr ? ["inherit", "inherit", "pipe"] : "inherit",
1215
3273
  shell: false,
1216
- env: env ? { ...process.env, ...env } : process.env
3274
+ env: env2 ? { ...process.env, ...env2 } : process.env
1217
3275
  });
1218
3276
  if (filterStderr && proc.stderr) {
1219
3277
  proc.stderr.on("data", (data) => {
@@ -1237,12 +3295,12 @@ function runCommand(command, args, cwd, env, filterStderr = false) {
1237
3295
  }
1238
3296
  async function startTunnel(port, subdomain) {
1239
3297
  return new Promise((resolve, reject) => {
1240
- console.log(import_chalk3.default.gray(`Starting tunnel for port ${port}...`));
3298
+ console.log(source_default.gray(`Starting tunnel for port ${port}...`));
1241
3299
  const tunnelArgs = ["--yes", "@mcp-use/tunnel", String(port)];
1242
3300
  if (subdomain) {
1243
3301
  tunnelArgs.push("--subdomain", subdomain);
1244
3302
  }
1245
- const proc = (0, import_node_child_process3.spawn)("npx", tunnelArgs, {
3303
+ const proc = spawn("npx", tunnelArgs, {
1246
3304
  stdio: ["ignore", "pipe", "pipe"],
1247
3305
  shell: false
1248
3306
  });
@@ -1262,7 +3320,7 @@ async function startTunnel(port, subdomain) {
1262
3320
  let extractedSubdomain = subdomainMatch ? subdomainMatch[1] : fullDomain.split(".")[0];
1263
3321
  if (!/^[a-z0-9-]+$/i.test(extractedSubdomain)) {
1264
3322
  console.warn(
1265
- import_chalk3.default.yellow(
3323
+ source_default.yellow(
1266
3324
  `Warning: Extracted subdomain "${extractedSubdomain}" does not match expected format.`
1267
3325
  )
1268
3326
  );
@@ -1270,7 +3328,7 @@ async function startTunnel(port, subdomain) {
1270
3328
  }
1271
3329
  resolved = true;
1272
3330
  clearTimeout(setupTimeout);
1273
- console.log(import_chalk3.default.green.bold(`\u2713 Tunnel established: ${url}/mcp`));
3331
+ console.log(source_default.green.bold(`\u2713 Tunnel established: ${url}/mcp`));
1274
3332
  resolve({ url, subdomain: extractedSubdomain, process: proc });
1275
3333
  }
1276
3334
  });
@@ -1307,7 +3365,7 @@ async function findServerFile(projectPath) {
1307
3365
  const candidates = ["index.ts", "src/index.ts", "server.ts", "src/server.ts"];
1308
3366
  for (const candidate of candidates) {
1309
3367
  try {
1310
- await (0, import_promises.access)(import_node_path3.default.join(projectPath, candidate));
3368
+ await access(path5.join(projectPath, candidate));
1311
3369
  return candidate;
1312
3370
  } catch {
1313
3371
  continue;
@@ -1316,21 +3374,21 @@ async function findServerFile(projectPath) {
1316
3374
  throw new Error("No server file found");
1317
3375
  }
1318
3376
  async function buildWidgets(projectPath) {
1319
- const { promises: fs3 } = await import("fs");
3377
+ const { promises: fs9 } = await import("fs");
1320
3378
  const { build } = await import("vite");
1321
- const resourcesDir = import_node_path3.default.join(projectPath, "resources");
3379
+ const resourcesDir = path5.join(projectPath, "resources");
1322
3380
  const mcpUrl = process.env.MCP_URL;
1323
3381
  try {
1324
- await (0, import_promises.access)(resourcesDir);
3382
+ await access(resourcesDir);
1325
3383
  } catch {
1326
3384
  console.log(
1327
- import_chalk3.default.gray("No resources/ directory found - skipping widget build")
3385
+ source_default.gray("No resources/ directory found - skipping widget build")
1328
3386
  );
1329
3387
  return [];
1330
3388
  }
1331
3389
  const entries = [];
1332
3390
  try {
1333
- const files = await fs3.readdir(resourcesDir, { withFileTypes: true });
3391
+ const files = await fs9.readdir(resourcesDir, { withFileTypes: true });
1334
3392
  for (const dirent of files) {
1335
3393
  if (dirent.name.startsWith("._") || dirent.name.startsWith(".DS_Store")) {
1336
3394
  continue;
@@ -1338,12 +3396,12 @@ async function buildWidgets(projectPath) {
1338
3396
  if (dirent.isFile() && (dirent.name.endsWith(".tsx") || dirent.name.endsWith(".ts"))) {
1339
3397
  entries.push({
1340
3398
  name: dirent.name.replace(/\.tsx?$/, ""),
1341
- path: import_node_path3.default.join(resourcesDir, dirent.name)
3399
+ path: path5.join(resourcesDir, dirent.name)
1342
3400
  });
1343
3401
  } else if (dirent.isDirectory()) {
1344
- const widgetPath = import_node_path3.default.join(resourcesDir, dirent.name, "widget.tsx");
3402
+ const widgetPath = path5.join(resourcesDir, dirent.name, "widget.tsx");
1345
3403
  try {
1346
- await fs3.access(widgetPath);
3404
+ await fs9.access(widgetPath);
1347
3405
  entries.push({
1348
3406
  name: dirent.name,
1349
3407
  path: widgetPath
@@ -1353,30 +3411,41 @@ async function buildWidgets(projectPath) {
1353
3411
  }
1354
3412
  }
1355
3413
  } catch (error) {
1356
- console.log(import_chalk3.default.gray("No widgets found in resources/ directory"));
3414
+ console.log(source_default.gray("No widgets found in resources/ directory"));
1357
3415
  return [];
1358
3416
  }
1359
3417
  if (entries.length === 0) {
1360
- console.log(import_chalk3.default.gray("No widgets found in resources/ directory"));
3418
+ console.log(source_default.gray("No widgets found in resources/ directory"));
1361
3419
  return [];
1362
3420
  }
1363
- console.log(import_chalk3.default.gray(`Building ${entries.length} widget(s)...`));
3421
+ console.log(source_default.gray(`Building ${entries.length} widget(s)...`));
1364
3422
  const react = (await import("@vitejs/plugin-react")).default;
1365
3423
  const tailwindcss = (await import("@tailwindcss/vite")).default;
3424
+ const packageJsonPath = path5.join(projectPath, "package.json");
3425
+ let favicon = "";
3426
+ try {
3427
+ const pkgContent = await fs9.readFile(packageJsonPath, "utf-8");
3428
+ const pkg = JSON.parse(pkgContent);
3429
+ favicon = pkg.mcpUse?.favicon || "";
3430
+ } catch {
3431
+ }
1366
3432
  const builtWidgets = [];
1367
3433
  for (const entry of entries) {
1368
3434
  const widgetName = entry.name;
1369
3435
  const entryPath = entry.path;
1370
- console.log(import_chalk3.default.gray(` - Building ${widgetName}...`));
1371
- const tempDir = import_node_path3.default.join(projectPath, ".mcp-use", widgetName);
1372
- await fs3.mkdir(tempDir, { recursive: true });
1373
- const relativeResourcesPath = import_node_path3.default.relative(tempDir, resourcesDir).replace(/\\/g, "/");
3436
+ console.log(source_default.gray(` - Building ${widgetName}...`));
3437
+ const tempDir = path5.join(projectPath, ".mcp-use", widgetName);
3438
+ await fs9.mkdir(tempDir, { recursive: true });
3439
+ const relativeResourcesPath = path5.relative(tempDir, resourcesDir).replace(/\\/g, "/");
3440
+ const mcpUsePath = path5.join(projectPath, "node_modules", "mcp-use");
3441
+ const relativeMcpUsePath = path5.relative(tempDir, mcpUsePath).replace(/\\/g, "/");
1374
3442
  const cssContent = `@import "tailwindcss";
1375
3443
 
1376
- /* Configure Tailwind to scan the resources directory */
3444
+ /* Configure Tailwind to scan the resources directory and mcp-use package */
1377
3445
  @source "${relativeResourcesPath}";
3446
+ @source "${relativeMcpUsePath}/**/*.{ts,tsx,js,jsx}";
1378
3447
  `;
1379
- await fs3.writeFile(import_node_path3.default.join(tempDir, "styles.css"), cssContent, "utf8");
3448
+ await fs9.writeFile(path5.join(tempDir, "styles.css"), cssContent, "utf8");
1380
3449
  const entryContent = `import React from 'react'
1381
3450
  import { createRoot } from 'react-dom/client'
1382
3451
  import './styles.css'
@@ -1393,16 +3462,17 @@ if (container && Component) {
1393
3462
  <head>
1394
3463
  <meta charset="UTF-8" />
1395
3464
  <meta name="viewport" content="width=device-width,initial-scale=1" />
1396
- <title>${widgetName} Widget</title>
3465
+ <title>${widgetName} Widget</title>${favicon ? `
3466
+ <link rel="icon" href="/mcp-use/public/${favicon}" />` : ""}
1397
3467
  </head>
1398
3468
  <body>
1399
3469
  <div id="widget-root"></div>
1400
3470
  <script type="module" src="/entry.tsx"></script>
1401
3471
  </body>
1402
3472
  </html>`;
1403
- await fs3.writeFile(import_node_path3.default.join(tempDir, "entry.tsx"), entryContent, "utf8");
1404
- await fs3.writeFile(import_node_path3.default.join(tempDir, "index.html"), htmlContent, "utf8");
1405
- const outDir = import_node_path3.default.join(
3473
+ await fs9.writeFile(path5.join(tempDir, "entry.tsx"), entryContent, "utf8");
3474
+ await fs9.writeFile(path5.join(tempDir, "index.html"), htmlContent, "utf8");
3475
+ const outDir = path5.join(
1406
3476
  projectPath,
1407
3477
  "dist",
1408
3478
  "resources",
@@ -1412,12 +3482,12 @@ if (container && Component) {
1412
3482
  const baseUrl = mcpUrl ? `${mcpUrl}/${widgetName}/` : `/mcp-use/widgets/${widgetName}/`;
1413
3483
  let widgetMetadata = {};
1414
3484
  try {
1415
- const metadataTempDir = import_node_path3.default.join(
3485
+ const metadataTempDir = path5.join(
1416
3486
  projectPath,
1417
3487
  ".mcp-use",
1418
3488
  `${widgetName}-metadata`
1419
3489
  );
1420
- await fs3.mkdir(metadataTempDir, { recursive: true });
3490
+ await fs9.mkdir(metadataTempDir, { recursive: true });
1421
3491
  const { createServer: createServer2 } = await import("vite");
1422
3492
  const nodeStubsPlugin = {
1423
3493
  name: "node-stubs",
@@ -1447,7 +3517,7 @@ export default PostHog;
1447
3517
  };
1448
3518
  const metadataServer = await createServer2({
1449
3519
  root: metadataTempDir,
1450
- cacheDir: import_node_path3.default.join(metadataTempDir, ".vite-cache"),
3520
+ cacheDir: path5.join(metadataTempDir, ".vite-cache"),
1451
3521
  plugins: [nodeStubsPlugin, tailwindcss(), react()],
1452
3522
  resolve: {
1453
3523
  alias: {
@@ -1507,12 +3577,12 @@ export default PostHog;
1507
3577
  await new Promise((resolve) => setTimeout(resolve, 50));
1508
3578
  } catch (error) {
1509
3579
  console.warn(
1510
- import_chalk3.default.yellow(` \u26A0 Could not extract metadata for ${widgetName}`)
3580
+ source_default.yellow(` \u26A0 Could not extract metadata for ${widgetName}`)
1511
3581
  );
1512
3582
  } finally {
1513
3583
  await metadataServer.close();
1514
3584
  try {
1515
- await fs3.rm(metadataTempDir, { recursive: true, force: true });
3585
+ await fs9.rm(metadataTempDir, { recursive: true, force: true });
1516
3586
  } catch {
1517
3587
  }
1518
3588
  }
@@ -1635,7 +3705,7 @@ export default {
1635
3705
  outDir,
1636
3706
  emptyOutDir: true,
1637
3707
  rollupOptions: {
1638
- input: import_node_path3.default.join(tempDir, "index.html"),
3708
+ input: path5.join(tempDir, "index.html"),
1639
3709
  external: (id) => {
1640
3710
  return false;
1641
3711
  }
@@ -1645,8 +3715,8 @@ export default {
1645
3715
  const mcpServerUrl = process.env.MCP_SERVER_URL;
1646
3716
  if (mcpServerUrl) {
1647
3717
  try {
1648
- const htmlPath = import_node_path3.default.join(outDir, "index.html");
1649
- let html = await fs3.readFile(htmlPath, "utf8");
3718
+ const htmlPath = path5.join(outDir, "index.html");
3719
+ let html = await fs9.readFile(htmlPath, "utf8");
1650
3720
  const injectionScript = `<script>window.__getFile = (filename) => { return "${mcpUrl}/${widgetName}/"+filename }; window.__mcpPublicUrl = "${mcpServerUrl}/mcp-use/public"; window.__mcpPublicAssetsUrl = "${mcpUrl}/public";</script>`;
1651
3721
  if (!html.includes("window.__mcpPublicUrl")) {
1652
3722
  html = html.replace(
@@ -1667,13 +3737,13 @@ export default {
1667
3737
  <base href="${mcpServerUrl}">`
1668
3738
  );
1669
3739
  }
1670
- await fs3.writeFile(htmlPath, html, "utf8");
3740
+ await fs9.writeFile(htmlPath, html, "utf8");
1671
3741
  console.log(
1672
- import_chalk3.default.gray(` \u2192 Injected MCP_SERVER_URL into ${widgetName}`)
3742
+ source_default.gray(` \u2192 Injected MCP_SERVER_URL into ${widgetName}`)
1673
3743
  );
1674
3744
  } catch (error) {
1675
3745
  console.warn(
1676
- import_chalk3.default.yellow(
3746
+ source_default.yellow(
1677
3747
  ` \u26A0 Failed to post-process HTML for ${widgetName}:`,
1678
3748
  error
1679
3749
  )
@@ -1684,36 +3754,36 @@ export default {
1684
3754
  name: widgetName,
1685
3755
  metadata: widgetMetadata
1686
3756
  });
1687
- console.log(import_chalk3.default.green(` \u2713 Built ${widgetName}`));
3757
+ console.log(source_default.green(` \u2713 Built ${widgetName}`));
1688
3758
  } catch (error) {
1689
- console.error(import_chalk3.default.red(` \u2717 Failed to build ${widgetName}:`), error);
3759
+ console.error(source_default.red(` \u2717 Failed to build ${widgetName}:`), error);
1690
3760
  }
1691
3761
  }
1692
3762
  return builtWidgets;
1693
3763
  }
1694
3764
  program.command("build").description("Build TypeScript and MCP UI widgets").option("-p, --path <path>", "Path to project directory", process.cwd()).option("--with-inspector", "Include inspector in production build").action(async (options) => {
1695
3765
  try {
1696
- const projectPath = import_node_path3.default.resolve(options.path);
1697
- const { promises: fs3 } = await import("fs");
1698
- console.log(import_chalk3.default.cyan.bold(`mcp-use v${packageJson.version}`));
3766
+ const projectPath = path5.resolve(options.path);
3767
+ const { promises: fs9 } = await import("fs");
3768
+ console.log(source_default.cyan.bold(`mcp-use v${packageJson.version}`));
1699
3769
  const builtWidgets = await buildWidgets(projectPath);
1700
- console.log(import_chalk3.default.gray("Building TypeScript..."));
3770
+ console.log(source_default.gray("Building TypeScript..."));
1701
3771
  await runCommand("npx", ["tsc"], projectPath);
1702
- console.log(import_chalk3.default.green("\u2713 TypeScript build complete!"));
1703
- const publicDir = import_node_path3.default.join(projectPath, "public");
3772
+ console.log(source_default.green("\u2713 TypeScript build complete!"));
3773
+ const publicDir = path5.join(projectPath, "public");
1704
3774
  try {
1705
- await fs3.access(publicDir);
1706
- console.log(import_chalk3.default.gray("Copying public assets..."));
1707
- await fs3.cp(publicDir, import_node_path3.default.join(projectPath, "dist", "public"), {
3775
+ await fs9.access(publicDir);
3776
+ console.log(source_default.gray("Copying public assets..."));
3777
+ await fs9.cp(publicDir, path5.join(projectPath, "dist", "public"), {
1708
3778
  recursive: true
1709
3779
  });
1710
- console.log(import_chalk3.default.green("\u2713 Public assets copied"));
3780
+ console.log(source_default.green("\u2713 Public assets copied"));
1711
3781
  } catch {
1712
3782
  }
1713
- const manifestPath = import_node_path3.default.join(projectPath, "dist", "mcp-use.json");
3783
+ const manifestPath = path5.join(projectPath, "dist", "mcp-use.json");
1714
3784
  let existingManifest = {};
1715
3785
  try {
1716
- const existingContent = await fs3.readFile(manifestPath, "utf-8");
3786
+ const existingContent = await fs9.readFile(manifestPath, "utf-8");
1717
3787
  existingManifest = JSON.parse(existingContent);
1718
3788
  } catch {
1719
3789
  }
@@ -1733,41 +3803,41 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
1733
3803
  buildId,
1734
3804
  widgets: widgetsData
1735
3805
  };
1736
- await fs3.mkdir(import_node_path3.default.dirname(manifestPath), { recursive: true });
1737
- await fs3.writeFile(
3806
+ await fs9.mkdir(path5.dirname(manifestPath), { recursive: true });
3807
+ await fs9.writeFile(
1738
3808
  manifestPath,
1739
3809
  JSON.stringify(manifest, null, 2),
1740
3810
  "utf8"
1741
3811
  );
1742
- console.log(import_chalk3.default.green("\u2713 Build manifest created"));
1743
- console.log(import_chalk3.default.green.bold(`
3812
+ console.log(source_default.green("\u2713 Build manifest created"));
3813
+ console.log(source_default.green.bold(`
1744
3814
  \u2713 Build complete!`));
1745
3815
  if (builtWidgets.length > 0) {
1746
- console.log(import_chalk3.default.gray(` ${builtWidgets.length} widget(s) built`));
3816
+ console.log(source_default.gray(` ${builtWidgets.length} widget(s) built`));
1747
3817
  }
1748
3818
  if (options.withInspector) {
1749
- console.log(import_chalk3.default.gray(" Inspector included"));
3819
+ console.log(source_default.gray(" Inspector included"));
1750
3820
  }
1751
3821
  } catch (error) {
1752
- console.error(import_chalk3.default.red("Build failed:"), error);
3822
+ console.error(source_default.red("Build failed:"), error);
1753
3823
  process.exit(1);
1754
3824
  }
1755
3825
  });
1756
3826
  program.command("dev").description("Run development server with auto-reload and inspector").option("-p, --path <path>", "Path to project directory", process.cwd()).option("--port <port>", "Server port", "3000").option("--host <host>", "Server host", "localhost").option("--no-open", "Do not auto-open inspector").action(async (options) => {
1757
3827
  try {
1758
- const projectPath = import_node_path3.default.resolve(options.path);
3828
+ const projectPath = path5.resolve(options.path);
1759
3829
  let port = parseInt(options.port, 10);
1760
3830
  const host = options.host;
1761
- console.log(import_chalk3.default.cyan.bold(`mcp-use v${packageJson.version}`));
3831
+ console.log(source_default.cyan.bold(`mcp-use v${packageJson.version}`));
1762
3832
  if (!await isPortAvailable(port, host)) {
1763
- console.log(import_chalk3.default.yellow.bold(`\u26A0\uFE0F Port ${port} is already in use`));
3833
+ console.log(source_default.yellow.bold(`\u26A0\uFE0F Port ${port} is already in use`));
1764
3834
  const availablePort = await findAvailablePort2(port, host);
1765
- console.log(import_chalk3.default.green.bold(`\u2713 Using port ${availablePort} instead`));
3835
+ console.log(source_default.green.bold(`\u2713 Using port ${availablePort} instead`));
1766
3836
  port = availablePort;
1767
3837
  }
1768
3838
  const serverFile = await findServerFile(projectPath);
1769
3839
  const processes = [];
1770
- const env = {
3840
+ const env2 = {
1771
3841
  PORT: String(port),
1772
3842
  HOST: host,
1773
3843
  NODE_ENV: "development"
@@ -1776,7 +3846,7 @@ program.command("dev").description("Run development server with auto-reload and
1776
3846
  "npx",
1777
3847
  ["tsx", "watch", serverFile],
1778
3848
  projectPath,
1779
- env,
3849
+ env2,
1780
3850
  true
1781
3851
  );
1782
3852
  processes.push(serverCommand.process);
@@ -1787,17 +3857,17 @@ program.command("dev").description("Run development server with auto-reload and
1787
3857
  const mcpEndpoint = `http://${host}:${port}/mcp`;
1788
3858
  const inspectorUrl = `http://${host}:${port}/inspector?autoConnect=${encodeURIComponent(mcpEndpoint)}`;
1789
3859
  const readyTime = Date.now() - startTime;
1790
- console.log(import_chalk3.default.green.bold(`\u2713 Ready in ${readyTime}ms`));
1791
- console.log(import_chalk3.default.whiteBright(`Local: http://${host}:${port}`));
1792
- console.log(import_chalk3.default.whiteBright(`Network: http://${host}:${port}`));
1793
- console.log(import_chalk3.default.whiteBright(`MCP: ${mcpEndpoint}`));
1794
- console.log(import_chalk3.default.whiteBright(`Inspector: ${inspectorUrl}
3860
+ console.log(source_default.green.bold(`\u2713 Ready in ${readyTime}ms`));
3861
+ console.log(source_default.whiteBright(`Local: http://${host}:${port}`));
3862
+ console.log(source_default.whiteBright(`Network: http://${host}:${port}`));
3863
+ console.log(source_default.whiteBright(`MCP: ${mcpEndpoint}`));
3864
+ console.log(source_default.whiteBright(`Inspector: ${inspectorUrl}
1795
3865
  `));
1796
- await (0, import_open3.default)(inspectorUrl);
3866
+ await open_default(inspectorUrl);
1797
3867
  }
1798
3868
  }
1799
3869
  const cleanup = () => {
1800
- console.log(import_chalk3.default.gray("\n\nShutting down..."));
3870
+ console.log(source_default.gray("\n\nShutting down..."));
1801
3871
  const processesToKill = processes.length;
1802
3872
  let killedCount = 0;
1803
3873
  const checkAndExit = () => {
@@ -1828,13 +3898,13 @@ program.command("dev").description("Run development server with auto-reload and
1828
3898
  await new Promise(() => {
1829
3899
  });
1830
3900
  } catch (error) {
1831
- console.error(import_chalk3.default.red("Dev mode failed:"), error);
3901
+ console.error(source_default.red("Dev mode failed:"), error);
1832
3902
  process.exit(1);
1833
3903
  }
1834
3904
  });
1835
3905
  program.command("start").description("Start production server").option("-p, --path <path>", "Path to project directory", process.cwd()).option("--port <port>", "Server port", "3000").option("--tunnel", "Expose server through a tunnel").action(async (options) => {
1836
3906
  try {
1837
- const projectPath = import_node_path3.default.resolve(options.path);
3907
+ const projectPath = path5.resolve(options.path);
1838
3908
  const port = parseInt(options.port, 10);
1839
3909
  console.log(
1840
3910
  `\x1B[36m\x1B[1mmcp-use\x1B[0m \x1B[90mVersion: ${packageJson.version}\x1B[0m
@@ -1845,20 +3915,20 @@ program.command("start").description("Start production server").option("-p, --pa
1845
3915
  let tunnelSubdomain = void 0;
1846
3916
  if (options.tunnel) {
1847
3917
  try {
1848
- const manifestPath = import_node_path3.default.join(projectPath, "dist", "mcp-use.json");
3918
+ const manifestPath = path5.join(projectPath, "dist", "mcp-use.json");
1849
3919
  let existingSubdomain;
1850
3920
  try {
1851
- const manifestContent = await (0, import_promises.readFile)(manifestPath, "utf-8");
3921
+ const manifestContent = await readFile2(manifestPath, "utf-8");
1852
3922
  const manifest = JSON.parse(manifestContent);
1853
3923
  existingSubdomain = manifest.tunnel?.subdomain;
1854
3924
  if (existingSubdomain) {
1855
3925
  console.log(
1856
- import_chalk3.default.gray(`Found existing subdomain: ${existingSubdomain}`)
3926
+ source_default.gray(`Found existing subdomain: ${existingSubdomain}`)
1857
3927
  );
1858
3928
  }
1859
3929
  } catch (error) {
1860
3930
  console.debug(
1861
- import_chalk3.default.gray(
3931
+ source_default.gray(
1862
3932
  `Debug: Failed to read or parse mcp-use.json: ${error instanceof Error ? error.message : String(error)}`
1863
3933
  )
1864
3934
  );
@@ -1871,7 +3941,7 @@ program.command("start").description("Start production server").option("-p, --pa
1871
3941
  try {
1872
3942
  let manifest = {};
1873
3943
  try {
1874
- const manifestContent = await (0, import_promises.readFile)(manifestPath, "utf-8");
3944
+ const manifestContent = await readFile2(manifestPath, "utf-8");
1875
3945
  manifest = JSON.parse(manifestContent);
1876
3946
  } catch {
1877
3947
  }
@@ -1879,44 +3949,44 @@ program.command("start").description("Start production server").option("-p, --pa
1879
3949
  manifest.tunnel = {};
1880
3950
  }
1881
3951
  manifest.tunnel.subdomain = subdomain;
1882
- await (0, import_promises.mkdir)(import_node_path3.default.dirname(manifestPath), { recursive: true });
1883
- await (0, import_promises.writeFile)(
3952
+ await mkdir2(path5.dirname(manifestPath), { recursive: true });
3953
+ await writeFile2(
1884
3954
  manifestPath,
1885
3955
  JSON.stringify(manifest, null, 2),
1886
3956
  "utf-8"
1887
3957
  );
1888
3958
  } catch (error) {
1889
3959
  console.warn(
1890
- import_chalk3.default.yellow(
3960
+ source_default.yellow(
1891
3961
  `\u26A0\uFE0F Failed to save subdomain to mcp-use.json: ${error instanceof Error ? error.message : "Unknown error"}`
1892
3962
  )
1893
3963
  );
1894
3964
  }
1895
3965
  } catch (error) {
1896
- console.error(import_chalk3.default.red("Failed to start tunnel:"), error);
3966
+ console.error(source_default.red("Failed to start tunnel:"), error);
1897
3967
  process.exit(1);
1898
3968
  }
1899
3969
  }
1900
3970
  let serverFile = "dist/index.js";
1901
3971
  try {
1902
- await (0, import_promises.access)(import_node_path3.default.join(projectPath, serverFile));
3972
+ await access(path5.join(projectPath, serverFile));
1903
3973
  } catch {
1904
3974
  serverFile = "dist/server.js";
1905
3975
  }
1906
3976
  console.log("Starting production server...");
1907
- const env = {
3977
+ const env2 = {
1908
3978
  ...process.env,
1909
3979
  PORT: String(port),
1910
3980
  NODE_ENV: "production"
1911
3981
  };
1912
3982
  if (mcpUrl) {
1913
- env.MCP_URL = mcpUrl;
1914
- console.log(import_chalk3.default.whiteBright(`Tunnel: ${mcpUrl}/mcp`));
3983
+ env2.MCP_URL = mcpUrl;
3984
+ console.log(source_default.whiteBright(`Tunnel: ${mcpUrl}/mcp`));
1915
3985
  }
1916
- const serverProc = (0, import_node_child_process3.spawn)("node", [serverFile], {
3986
+ const serverProc = spawn("node", [serverFile], {
1917
3987
  cwd: projectPath,
1918
3988
  stdio: "inherit",
1919
- env
3989
+ env: env2
1920
3990
  });
1921
3991
  let cleanupInProgress = false;
1922
3992
  const cleanup = async () => {
@@ -1924,7 +3994,7 @@ program.command("start").description("Start production server").option("-p, --pa
1924
3994
  return;
1925
3995
  }
1926
3996
  cleanupInProgress = true;
1927
- console.log(import_chalk3.default.gray("\n\nShutting down..."));
3997
+ console.log(source_default.gray("\n\nShutting down..."));
1928
3998
  if (tunnelProcess && typeof tunnelProcess.markShutdown === "function") {
1929
3999
  tunnelProcess.markShutdown();
1930
4000
  }
@@ -1994,4 +4064,6 @@ program.command("deploy").description("Deploy MCP server to mcp-use cloud").opti
1994
4064
  fromSource: options.fromSource
1995
4065
  });
1996
4066
  });
4067
+ program.addCommand(createClientCommand());
1997
4068
  program.parse();
4069
+ //# sourceMappingURL=index.js.map