@mcp-use/cli 2.2.1 → 2.2.2-canary.0

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
@@ -24,17 +24,1100 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/index.ts
27
- var import_config = require("dotenv/config");
27
+ var import_config4 = require("dotenv/config");
28
28
  var import_commander = require("commander");
29
- var import_node_child_process = require("child_process");
30
- var import_node_fs = require("fs");
29
+ var import_node_child_process3 = require("child_process");
30
+ var import_node_fs3 = require("fs");
31
31
  var import_promises = require("fs/promises");
32
- var import_node_path = __toESM(require("path"));
33
- var import_open = __toESM(require("open"));
32
+ var import_node_path3 = __toESM(require("path"));
33
+ var import_open3 = __toESM(require("open"));
34
+ var import_chalk3 = __toESM(require("chalk"));
35
+
36
+ // src/commands/auth.ts
34
37
  var import_chalk = __toESM(require("chalk"));
38
+ var import_node_http = require("http");
39
+ var import_open = __toESM(require("open"));
40
+
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 {};
61
+ }
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) {
71
+ }
72
+ }
73
+ async function getApiUrl() {
74
+ const config = await readConfig();
75
+ return config.apiUrl || DEFAULT_API_URL;
76
+ }
77
+ async function getApiKey() {
78
+ const config = await readConfig();
79
+ return config.apiKey || null;
80
+ }
81
+ async function isLoggedIn() {
82
+ const apiKey = await getApiKey();
83
+ return !!apiKey;
84
+ }
85
+ async function getWebUrl() {
86
+ return DEFAULT_WEB_URL;
87
+ }
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;
96
+ }
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);
104
+ }
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}`);
124
+ }
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}`);
143
+ }
144
+ return response.json();
145
+ }
146
+ /**
147
+ * Test authentication
148
+ */
149
+ async testAuth() {
150
+ return this.request("/test-auth");
151
+ }
152
+ /**
153
+ * Create deployment
154
+ */
155
+ async createDeployment(request) {
156
+ return this.request("/deployments", {
157
+ method: "POST",
158
+ body: JSON.stringify(request)
159
+ });
160
+ }
161
+ /**
162
+ * Get deployment by ID
163
+ */
164
+ async getDeployment(deploymentId) {
165
+ return this.request(`/deployments/${deploymentId}`);
166
+ }
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}`);
179
+ }
180
+ if (!response.body) {
181
+ throw new Error("Response body is null");
182
+ }
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();
210
+ }
211
+ }
212
+ /**
213
+ * Upload source code tarball
214
+ */
215
+ async uploadSource(filePath) {
216
+ const { readFile } = await import("fs/promises");
217
+ const { basename } = await import("path");
218
+ const fileBuffer = await readFile(filePath);
219
+ const filename = basename(filePath);
220
+ const formData = new FormData();
221
+ const blob = new Blob([fileBuffer], { type: "application/gzip" });
222
+ formData.append("file", blob, filename);
223
+ const url = `${this.baseUrl}/uploads`;
224
+ const headers = {};
225
+ if (this.apiKey) {
226
+ headers["x-api-key"] = this.apiKey;
227
+ }
228
+ const response = await fetch(url, {
229
+ method: "POST",
230
+ headers,
231
+ body: formData
232
+ });
233
+ if (!response.ok) {
234
+ const error = await response.text();
235
+ throw new Error(`Upload failed: ${error}`);
236
+ }
237
+ return response.json();
238
+ }
239
+ };
240
+
241
+ // src/commands/auth.ts
242
+ var LOGIN_TIMEOUT = 3e5;
243
+ async function findAvailablePort(startPort = 8765) {
244
+ for (let port = startPort; port < startPort + 100; port++) {
245
+ try {
246
+ await new Promise((resolve, reject) => {
247
+ const server = (0, import_node_http.createServer)();
248
+ server.once("error", reject);
249
+ server.once("listening", () => {
250
+ server.close();
251
+ resolve();
252
+ });
253
+ server.listen(port);
254
+ });
255
+ return port;
256
+ } catch {
257
+ continue;
258
+ }
259
+ }
260
+ throw new Error("No available ports found");
261
+ }
262
+ async function startCallbackServer(port) {
263
+ return new Promise((resolve, reject) => {
264
+ let tokenResolver = null;
265
+ const tokenPromise = new Promise((res) => {
266
+ tokenResolver = res;
267
+ });
268
+ const server = (0, import_node_http.createServer)((req, res) => {
269
+ if (req.url?.startsWith("/callback")) {
270
+ const url = new URL(req.url, `http://localhost:${port}`);
271
+ const token = url.searchParams.get("token");
272
+ if (token && tokenResolver) {
273
+ res.writeHead(200, { "Content-Type": "text/html" });
274
+ res.end(`
275
+ <!DOCTYPE html>
276
+ <html>
277
+ <head>
278
+ <title>Login Successful</title>
279
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
280
+ <style>
281
+ * {
282
+ margin: 0;
283
+ padding: 0;
284
+ box-sizing: border-box;
285
+ }
286
+ body {
287
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
288
+ display: flex;
289
+ justify-content: center;
290
+ align-items: center;
291
+ min-height: 100vh;
292
+ background: #000;
293
+ padding: 1rem;
294
+ }
295
+ .container {
296
+ width: 100%;
297
+ max-width: 28rem;
298
+ padding: 3rem;
299
+ text-align: center;
300
+ -webkit-backdrop-filter: blur(40px);
301
+ border: 1px solid rgba(255, 255, 255, 0.2);
302
+ border-radius: 1.5rem;
303
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
304
+ }
305
+ .icon-container {
306
+ display: inline-flex;
307
+ align-items: center;
308
+ justify-content: center;
309
+ width: 6rem;
310
+ height: 6rem;
311
+ margin-bottom: 2rem;
312
+ background: rgba(255, 255, 255, 0.1);
313
+ backdrop-filter: blur(10px);
314
+ -webkit-backdrop-filter: blur(10px);
315
+ border-radius: 50%;
316
+ }
317
+ .checkmark {
318
+ font-size: 4rem;
319
+ color: #fff;
320
+ line-height: 1;
321
+ animation: scaleIn 0.5s ease-out;
322
+ }
323
+ @keyframes scaleIn {
324
+ from {
325
+ transform: scale(0);
326
+ opacity: 0;
327
+ }
328
+ to {
329
+ transform: scale(1);
330
+ opacity: 1;
331
+ }
332
+ }
333
+ h1 {
334
+ color: #fff;
335
+ margin: 0 0 1rem 0;
336
+ font-size: 2.5rem;
337
+ font-weight: 700;
338
+ letter-spacing: -0.025em;
339
+ }
340
+ p {
341
+ color: rgba(255, 255, 255, 0.8);
342
+ margin: 0 0 2rem 0;
343
+ font-size: 1.125rem;
344
+ line-height: 1.5;
345
+ }
346
+ .spinner {
347
+ display: inline-block;
348
+ width: 2rem;
349
+ height: 2rem;
350
+ border: 3px solid rgba(255, 255, 255, 0.3);
351
+ border-top-color: #fff;
352
+ border-radius: 50%;
353
+ animation: spin 0.8s linear infinite;
354
+ }
355
+ @keyframes spin {
356
+ to { transform: rotate(360deg); }
357
+ }
358
+ .footer {
359
+ margin-top: 2rem;
360
+ color: rgba(255, 255, 255, 0.6);
361
+ font-size: 0.875rem;
362
+ }
363
+ </style>
364
+ </head>
365
+ <body>
366
+ <div class="container">
367
+ <h1>Authentication Successful!</h1>
368
+ <p>You can now close this window and return to the CLI.</p>
369
+ </div>
370
+ </body>
371
+ </html>
372
+ `);
373
+ tokenResolver(token);
374
+ } else {
375
+ res.writeHead(400, { "Content-Type": "text/html" });
376
+ res.end(`
377
+ <!DOCTYPE html>
378
+ <html>
379
+ <head>
380
+ <title>Login Failed</title>
381
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
382
+ <style>
383
+ * {
384
+ margin: 0;
385
+ padding: 0;
386
+ box-sizing: border-box;
387
+ }
388
+ body {
389
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
390
+ display: flex;
391
+ justify-content: center;
392
+ align-items: center;
393
+ min-height: 100vh;
394
+ background: #000;
395
+ padding: 1rem;
396
+ }
397
+ .container {
398
+ width: 100%;
399
+ max-width: 28rem;
400
+ padding: 3rem;
401
+ text-align: center;
402
+ background: rgba(255, 255, 255, 0.1);
403
+ backdrop-filter: blur(40px);
404
+ -webkit-backdrop-filter: blur(40px);
405
+ border: 1px solid rgba(255, 255, 255, 0.2);
406
+ border-radius: 1.5rem;
407
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
408
+ }
409
+ .icon-container {
410
+ display: inline-flex;
411
+ align-items: center;
412
+ justify-content: center;
413
+ width: 6rem;
414
+ height: 6rem;
415
+ margin-bottom: 2rem;
416
+ background: rgba(255, 255, 255, 0.1);
417
+ backdrop-filter: blur(10px);
418
+ -webkit-backdrop-filter: blur(10px);
419
+ border-radius: 50%;
420
+ }
421
+ .cross {
422
+ font-size: 4rem;
423
+ color: #fff;
424
+ line-height: 1;
425
+ }
426
+ h1 {
427
+ color: #fff;
428
+ margin: 0 0 1rem 0;
429
+ font-size: 2.5rem;
430
+ font-weight: 700;
431
+ letter-spacing: -0.025em;
432
+ }
433
+ p {
434
+ color: rgba(255, 255, 255, 0.8);
435
+ margin: 0;
436
+ font-size: 1.125rem;
437
+ line-height: 1.5;
438
+ }
439
+ </style>
440
+ </head>
441
+ <body>
442
+ <div class="container">
443
+ <div class="icon-container">
444
+ <div class="cross">\u2717</div>
445
+ </div>
446
+ <h1>Login Failed</h1>
447
+ <p>No token received. Please try again.</p>
448
+ </div>
449
+ </body>
450
+ </html>
451
+ `);
452
+ }
453
+ }
454
+ });
455
+ server.listen(port, () => {
456
+ resolve({ server, token: tokenPromise });
457
+ });
458
+ server.on("error", reject);
459
+ });
460
+ }
461
+ async function loginCommand() {
462
+ try {
463
+ if (await isLoggedIn()) {
464
+ console.log(
465
+ import_chalk.default.yellow(
466
+ "\u26A0\uFE0F You are already logged in. Run 'mcp-use logout' first if you want to login with a different account."
467
+ )
468
+ );
469
+ return;
470
+ }
471
+ console.log(import_chalk.default.cyan.bold("\u{1F510} Logging in to mcp-use cloud...\n"));
472
+ const port = await findAvailablePort();
473
+ const redirectUri = `http://localhost:${port}/callback`;
474
+ console.log(import_chalk.default.gray(`Starting local server on port ${port}...`));
475
+ const { server, token } = await startCallbackServer(port);
476
+ const webUrl = await getWebUrl();
477
+ const loginUrl = `${webUrl}/auth/cli?redirect_uri=${encodeURIComponent(redirectUri)}`;
478
+ console.log(import_chalk.default.gray(`Opening browser to ${webUrl}/auth/cli...
479
+ `));
480
+ console.log(
481
+ import_chalk.default.white(
482
+ "If the browser doesn't open automatically, please visit:\n" + import_chalk.default.cyan(loginUrl)
483
+ )
484
+ );
485
+ await (0, import_open.default)(loginUrl);
486
+ console.log(
487
+ import_chalk.default.gray("\nWaiting for authentication... (this may take a moment)")
488
+ );
489
+ const jwtToken = await Promise.race([
490
+ token,
491
+ new Promise(
492
+ (_, reject) => setTimeout(
493
+ () => reject(new Error("Login timeout - please try again")),
494
+ LOGIN_TIMEOUT
495
+ )
496
+ )
497
+ ]);
498
+ server.close();
499
+ console.log(
500
+ import_chalk.default.gray("Received authentication token, creating API key...")
501
+ );
502
+ const api = await McpUseAPI.create();
503
+ const apiKeyResponse = await api.createApiKey(jwtToken, "CLI");
504
+ await writeConfig({
505
+ apiKey: apiKeyResponse.api_key
506
+ });
507
+ console.log(import_chalk.default.green.bold("\n\u2713 Successfully logged in!"));
508
+ console.log(
509
+ import_chalk.default.gray(
510
+ `
511
+ Your API key has been saved to ${import_chalk.default.white("~/.mcp-use/config.json")}`
512
+ )
513
+ );
514
+ console.log(
515
+ import_chalk.default.gray(
516
+ "You can now deploy your MCP servers with " + import_chalk.default.white("mcp-use deploy")
517
+ )
518
+ );
519
+ process.exit(0);
520
+ } catch (error) {
521
+ console.error(
522
+ import_chalk.default.red.bold("\n\u2717 Login failed:"),
523
+ import_chalk.default.red(error instanceof Error ? error.message : "Unknown error")
524
+ );
525
+ process.exit(1);
526
+ }
527
+ }
528
+ async function logoutCommand() {
529
+ try {
530
+ if (!await isLoggedIn()) {
531
+ console.log(import_chalk.default.yellow("\u26A0\uFE0F You are not logged in."));
532
+ return;
533
+ }
534
+ console.log(import_chalk.default.cyan.bold("\u{1F513} Logging out...\n"));
535
+ await deleteConfig();
536
+ console.log(import_chalk.default.green.bold("\u2713 Successfully logged out!"));
537
+ console.log(
538
+ import_chalk.default.gray(
539
+ "\nYour local config has been deleted. The API key will remain active until revoked from the web interface."
540
+ )
541
+ );
542
+ } catch (error) {
543
+ console.error(
544
+ import_chalk.default.red.bold("\n\u2717 Logout failed:"),
545
+ import_chalk.default.red(error instanceof Error ? error.message : "Unknown error")
546
+ );
547
+ process.exit(1);
548
+ }
549
+ }
550
+ async function whoamiCommand() {
551
+ try {
552
+ if (!await isLoggedIn()) {
553
+ console.log(import_chalk.default.yellow("\u26A0\uFE0F You are not logged in."));
554
+ console.log(
555
+ import_chalk.default.gray("Run " + import_chalk.default.white("mcp-use login") + " to get started.")
556
+ );
557
+ return;
558
+ }
559
+ console.log(import_chalk.default.cyan.bold("\u{1F464} Current user:\n"));
560
+ const api = await McpUseAPI.create();
561
+ const authInfo = await api.testAuth();
562
+ console.log(import_chalk.default.white("Email: ") + import_chalk.default.cyan(authInfo.email));
563
+ console.log(import_chalk.default.white("User ID: ") + import_chalk.default.gray(authInfo.user_id));
564
+ const apiKey = await getApiKey();
565
+ if (apiKey) {
566
+ const masked = apiKey.substring(0, 8) + "..." + apiKey.substring(apiKey.length - 4);
567
+ console.log(import_chalk.default.white("API Key: ") + import_chalk.default.gray(masked));
568
+ }
569
+ } catch (error) {
570
+ console.error(
571
+ import_chalk.default.red.bold("\n\u2717 Failed to get user info:"),
572
+ import_chalk.default.red(error instanceof Error ? error.message : "Unknown error")
573
+ );
574
+ process.exit(1);
575
+ }
576
+ }
577
+
578
+ // src/commands/deploy.ts
579
+ var import_chalk2 = __toESM(require("chalk"));
580
+ var import_node_fs2 = require("fs");
581
+ var import_node_path2 = __toESM(require("path"));
582
+ var import_node_os2 = __toESM(require("os"));
583
+ var import_node_child_process2 = require("child_process");
584
+ var import_node_util2 = require("util");
585
+
586
+ // src/utils/git.ts
587
+ var import_node_child_process = require("child_process");
588
+ var import_node_util = require("util");
589
+ var execAsync = (0, import_node_util.promisify)(import_node_child_process.exec);
590
+ async function gitCommand(command, cwd = process.cwd()) {
591
+ try {
592
+ const { stdout } = await execAsync(command, { cwd });
593
+ return stdout.trim();
594
+ } catch (error) {
595
+ return null;
596
+ }
597
+ }
598
+ async function isGitRepo(cwd = process.cwd()) {
599
+ const result = await gitCommand("git rev-parse --is-inside-work-tree", cwd);
600
+ return result === "true";
601
+ }
602
+ async function getRemoteUrl(cwd = process.cwd()) {
603
+ return gitCommand("git config --get remote.origin.url", cwd);
604
+ }
605
+ function parseGitHubUrl(url) {
606
+ const sshMatch = url.match(/git@github\.com:([^/]+)\/(.+?)(?:\.git)?$/);
607
+ const httpsMatch = url.match(
608
+ /https:\/\/github\.com\/([^/]+)\/(.+?)(?:\.git)?$/
609
+ );
610
+ const match = sshMatch || httpsMatch;
611
+ if (!match) return null;
612
+ return {
613
+ owner: match[1],
614
+ repo: match[2]
615
+ };
616
+ }
617
+ async function getCurrentBranch(cwd = process.cwd()) {
618
+ return gitCommand("git rev-parse --abbrev-ref HEAD", cwd);
619
+ }
620
+ async function getCommitSha(cwd = process.cwd()) {
621
+ return gitCommand("git rev-parse HEAD", cwd);
622
+ }
623
+ async function getCommitMessage(cwd = process.cwd()) {
624
+ return gitCommand("git log -1 --pretty=%B", cwd);
625
+ }
626
+ async function getGitInfo(cwd = process.cwd()) {
627
+ const isRepo = await isGitRepo(cwd);
628
+ if (!isRepo) {
629
+ return { isGitRepo: false };
630
+ }
631
+ const remoteUrl = await getRemoteUrl(cwd);
632
+ const branch = await getCurrentBranch(cwd);
633
+ const commitSha = await getCommitSha(cwd);
634
+ const commitMessage = await getCommitMessage(cwd);
635
+ let owner;
636
+ let repo;
637
+ if (remoteUrl) {
638
+ const parsed = parseGitHubUrl(remoteUrl);
639
+ if (parsed) {
640
+ owner = parsed.owner;
641
+ repo = parsed.repo;
642
+ }
643
+ }
644
+ return {
645
+ isGitRepo: true,
646
+ remoteUrl: remoteUrl || void 0,
647
+ owner,
648
+ repo,
649
+ branch: branch || void 0,
650
+ commitSha: commitSha || void 0,
651
+ commitMessage: commitMessage || void 0
652
+ };
653
+ }
654
+ function isGitHubUrl(url) {
655
+ return url.includes("github.com");
656
+ }
657
+
658
+ // src/commands/deploy.ts
659
+ var import_open2 = __toESM(require("open"));
660
+ var execAsync2 = (0, import_node_util2.promisify)(import_node_child_process2.exec);
661
+ async function isMcpProject(cwd = process.cwd()) {
662
+ try {
663
+ const packageJsonPath = import_node_path2.default.join(cwd, "package.json");
664
+ const content = await import_node_fs2.promises.readFile(packageJsonPath, "utf-8");
665
+ const packageJson2 = JSON.parse(content);
666
+ const hasMcpDeps = packageJson2.dependencies?.["mcp-use"] || packageJson2.dependencies?.["@modelcontextprotocol/sdk"] || packageJson2.devDependencies?.["mcp-use"] || packageJson2.devDependencies?.["@modelcontextprotocol/sdk"];
667
+ const hasMcpScripts = packageJson2.scripts?.mcp || packageJson2.scripts?.["mcp:dev"];
668
+ return !!(hasMcpDeps || hasMcpScripts);
669
+ } catch {
670
+ return false;
671
+ }
672
+ }
673
+ async function getProjectName(cwd = process.cwd()) {
674
+ try {
675
+ const packageJsonPath = import_node_path2.default.join(cwd, "package.json");
676
+ const content = await import_node_fs2.promises.readFile(packageJsonPath, "utf-8");
677
+ const packageJson2 = JSON.parse(content);
678
+ if (packageJson2.name) {
679
+ return packageJson2.name;
680
+ }
681
+ } catch {
682
+ }
683
+ return import_node_path2.default.basename(cwd);
684
+ }
685
+ async function detectBuildCommand(cwd = process.cwd()) {
686
+ try {
687
+ const packageJsonPath = import_node_path2.default.join(cwd, "package.json");
688
+ const content = await import_node_fs2.promises.readFile(packageJsonPath, "utf-8");
689
+ const packageJson2 = JSON.parse(content);
690
+ if (packageJson2.scripts?.build) {
691
+ return "npm run build";
692
+ }
693
+ } catch {
694
+ }
695
+ return void 0;
696
+ }
697
+ async function detectStartCommand(cwd = process.cwd()) {
698
+ try {
699
+ const packageJsonPath = import_node_path2.default.join(cwd, "package.json");
700
+ const content = await import_node_fs2.promises.readFile(packageJsonPath, "utf-8");
701
+ const packageJson2 = JSON.parse(content);
702
+ if (packageJson2.scripts?.start) {
703
+ return "npm start";
704
+ }
705
+ if (packageJson2.main) {
706
+ return `node ${packageJson2.main}`;
707
+ }
708
+ } catch {
709
+ }
710
+ return void 0;
711
+ }
712
+ async function detectRuntime(cwd = process.cwd()) {
713
+ try {
714
+ const pythonFiles = ["requirements.txt", "pyproject.toml", "setup.py"];
715
+ for (const file of pythonFiles) {
716
+ try {
717
+ await import_node_fs2.promises.access(import_node_path2.default.join(cwd, file));
718
+ return "python";
719
+ } catch {
720
+ continue;
721
+ }
722
+ }
723
+ try {
724
+ await import_node_fs2.promises.access(import_node_path2.default.join(cwd, "package.json"));
725
+ return "node";
726
+ } catch {
727
+ }
728
+ } catch {
729
+ }
730
+ return "node";
731
+ }
732
+ async function prompt(question) {
733
+ const readline = await import("readline");
734
+ const rl = readline.createInterface({
735
+ input: process.stdin,
736
+ output: process.stdout
737
+ });
738
+ return new Promise((resolve) => {
739
+ rl.question(question, (answer) => {
740
+ rl.close();
741
+ resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
742
+ });
743
+ });
744
+ }
745
+ async function createTarball(cwd) {
746
+ const tmpDir = import_node_os2.default.tmpdir();
747
+ const tarballPath = import_node_path2.default.join(tmpDir, `mcp-deploy-${Date.now()}.tar.gz`);
748
+ const excludePatterns = [
749
+ "node_modules",
750
+ ".git",
751
+ "dist",
752
+ "build",
753
+ ".next",
754
+ ".venv",
755
+ "__pycache__",
756
+ "*.pyc",
757
+ ".DS_Store",
758
+ ".env",
759
+ ".env.local",
760
+ "*.log"
761
+ ];
762
+ const excludeFlags = excludePatterns.map((pattern) => `--exclude='${pattern}'`).join(" ");
763
+ const command = `tar ${excludeFlags} -czf "${tarballPath}" -C "${cwd}" .`;
764
+ try {
765
+ await execAsync2(command);
766
+ return tarballPath;
767
+ } catch (error) {
768
+ throw new Error(
769
+ `Failed to create tarball: ${error instanceof Error ? error.message : "Unknown error"}`
770
+ );
771
+ }
772
+ }
773
+ function formatFileSize(bytes) {
774
+ if (bytes === 0) return "0 B";
775
+ const k = 1024;
776
+ const sizes = ["B", "KB", "MB", "GB"];
777
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
778
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
779
+ }
780
+ async function displayDeploymentProgress(api, deployment) {
781
+ const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
782
+ let frameIndex = 0;
783
+ let spinnerInterval = null;
784
+ let lastStep = "";
785
+ const startSpinner = (message) => {
786
+ if (spinnerInterval) {
787
+ clearInterval(spinnerInterval);
788
+ }
789
+ process.stdout.write("\r\x1B[K");
790
+ spinnerInterval = setInterval(() => {
791
+ const frame = frames[frameIndex];
792
+ frameIndex = (frameIndex + 1) % frames.length;
793
+ process.stdout.write(
794
+ "\r" + import_chalk2.default.cyan(frame) + " " + import_chalk2.default.gray(message)
795
+ );
796
+ }, 80);
797
+ };
798
+ const stopSpinner = () => {
799
+ if (spinnerInterval) {
800
+ clearInterval(spinnerInterval);
801
+ spinnerInterval = null;
802
+ process.stdout.write("\r\x1B[K");
803
+ }
804
+ };
805
+ console.log();
806
+ startSpinner("Deploying...");
807
+ try {
808
+ for await (const log of api.streamDeploymentLogs(deployment.id)) {
809
+ try {
810
+ const logData = JSON.parse(log);
811
+ if (logData.step && logData.step !== lastStep) {
812
+ lastStep = logData.step;
813
+ const stepMessages = {
814
+ clone: "Preparing source code...",
815
+ analyze: "Analyzing project...",
816
+ build: "Building container image...",
817
+ deploy: "Deploying to cloud..."
818
+ };
819
+ const message = stepMessages[logData.step] || "Deploying...";
820
+ startSpinner(message);
821
+ }
822
+ if (logData.line) {
823
+ stopSpinner();
824
+ const levelColor = logData.level === "error" ? import_chalk2.default.red : logData.level === "warn" ? import_chalk2.default.yellow : import_chalk2.default.gray;
825
+ const stepPrefix = logData.step ? import_chalk2.default.cyan(`[${logData.step}]`) + " " : "";
826
+ console.log(stepPrefix + levelColor(logData.line));
827
+ }
828
+ } catch {
829
+ }
830
+ }
831
+ } catch (error) {
832
+ stopSpinner();
833
+ }
834
+ let checkCount = 0;
835
+ const maxChecks = 60;
836
+ let delay = 3e3;
837
+ const maxDelay = 1e4;
838
+ let lastDisplayedLogLength = 0;
839
+ while (checkCount < maxChecks) {
840
+ const currentDelay = delay;
841
+ await new Promise((resolve) => setTimeout(resolve, currentDelay));
842
+ const finalDeployment = await api.getDeployment(deployment.id);
843
+ if (finalDeployment.buildLogs && finalDeployment.buildLogs.length > lastDisplayedLogLength) {
844
+ const newLogs = finalDeployment.buildLogs.substring(
845
+ lastDisplayedLogLength
846
+ );
847
+ const logLines = newLogs.split("\n").filter((l) => l.trim());
848
+ for (const line of logLines) {
849
+ try {
850
+ const logData = JSON.parse(line);
851
+ if (logData.line) {
852
+ stopSpinner();
853
+ const levelColor = logData.level === "error" ? import_chalk2.default.red : logData.level === "warn" ? import_chalk2.default.yellow : import_chalk2.default.gray;
854
+ const stepPrefix = logData.step ? import_chalk2.default.cyan(`[${logData.step}]`) + " " : "";
855
+ console.log(stepPrefix + levelColor(logData.line));
856
+ }
857
+ } catch {
858
+ }
859
+ }
860
+ lastDisplayedLogLength = finalDeployment.buildLogs.length;
861
+ }
862
+ if (finalDeployment.status === "running") {
863
+ const mcpUrl = `https://${finalDeployment.domain}/mcp`;
864
+ const inspectorUrl = `https://inspector.mcp-use.com/inspect?autoConnect=${encodeURIComponent(mcpUrl)}`;
865
+ console.log(import_chalk2.default.green.bold("\u2713 Deployment successful!\n"));
866
+ console.log(import_chalk2.default.white("\u{1F310} MCP Server URL:"));
867
+ console.log(import_chalk2.default.cyan.bold(` ${mcpUrl}
868
+ `));
869
+ console.log(import_chalk2.default.white("\u{1F50D} Inspector URL:"));
870
+ console.log(import_chalk2.default.cyan.bold(` ${inspectorUrl}
871
+ `));
872
+ if (finalDeployment.customDomain) {
873
+ const customMcpUrl = `https://${finalDeployment.customDomain}/mcp`;
874
+ const customInspectorUrl = `https://inspector.mcp-use.com/inspect?autoConnect=${encodeURIComponent(customMcpUrl)}`;
875
+ console.log(import_chalk2.default.white("\u{1F517} Custom Domain:"));
876
+ console.log(import_chalk2.default.cyan.bold(` ${customMcpUrl}
877
+ `));
878
+ console.log(import_chalk2.default.white("\u{1F50D} Custom Inspector:"));
879
+ console.log(import_chalk2.default.cyan.bold(` ${customInspectorUrl}
880
+ `));
881
+ }
882
+ console.log(
883
+ import_chalk2.default.gray("Deployment ID: ") + import_chalk2.default.white(finalDeployment.id)
884
+ );
885
+ return;
886
+ } else if (finalDeployment.status === "failed") {
887
+ console.log(import_chalk2.default.red.bold("\u2717 Deployment failed\n"));
888
+ if (finalDeployment.error) {
889
+ console.log(import_chalk2.default.red("Error: ") + finalDeployment.error);
890
+ }
891
+ if (finalDeployment.buildLogs) {
892
+ console.log(import_chalk2.default.gray("\nBuild logs:"));
893
+ try {
894
+ const logs = finalDeployment.buildLogs.split("\n").filter((l) => l.trim());
895
+ for (const log of logs) {
896
+ try {
897
+ const logData = JSON.parse(log);
898
+ if (logData.line) {
899
+ console.log(import_chalk2.default.gray(` ${logData.line}`));
900
+ }
901
+ } catch {
902
+ console.log(import_chalk2.default.gray(` ${log}`));
903
+ }
904
+ }
905
+ } catch {
906
+ console.log(import_chalk2.default.gray(finalDeployment.buildLogs));
907
+ }
908
+ }
909
+ process.exit(1);
910
+ } else if (finalDeployment.status === "building") {
911
+ startSpinner("Building and deploying...");
912
+ checkCount++;
913
+ delay = Math.min(delay * 1.2, maxDelay);
914
+ } else {
915
+ console.log(
916
+ import_chalk2.default.yellow("\u26A0\uFE0F Deployment status: ") + finalDeployment.status
917
+ );
918
+ return;
919
+ }
920
+ }
921
+ stopSpinner();
922
+ console.log(import_chalk2.default.yellow("\u26A0\uFE0F Deployment is taking longer than expected."));
923
+ console.log(
924
+ import_chalk2.default.gray("Check status with: ") + import_chalk2.default.white(`mcp-use status ${deployment.id}`)
925
+ );
926
+ }
927
+ async function deployCommand(options) {
928
+ try {
929
+ const cwd = process.cwd();
930
+ if (!await isLoggedIn()) {
931
+ console.log(import_chalk2.default.red("\u2717 You are not logged in."));
932
+ console.log(
933
+ import_chalk2.default.gray("Run " + import_chalk2.default.white("mcp-use login") + " to get started.")
934
+ );
935
+ process.exit(1);
936
+ }
937
+ console.log(import_chalk2.default.cyan.bold("\u{1F680} Deploying to mcp-use cloud...\n"));
938
+ const isMcp = await isMcpProject(cwd);
939
+ if (!isMcp) {
940
+ console.log(
941
+ import_chalk2.default.yellow(
942
+ "\u26A0\uFE0F This doesn't appear to be an MCP server project (no mcp-use or @modelcontextprotocol/sdk dependency found)."
943
+ )
944
+ );
945
+ const shouldContinue = await prompt(
946
+ import_chalk2.default.white("Continue anyway? (y/n): ")
947
+ );
948
+ if (!shouldContinue) {
949
+ console.log(import_chalk2.default.gray("Deployment cancelled."));
950
+ process.exit(0);
951
+ }
952
+ console.log();
953
+ }
954
+ const gitInfo = await getGitInfo(cwd);
955
+ if (!options.fromSource && gitInfo.isGitRepo && gitInfo.remoteUrl && isGitHubUrl(gitInfo.remoteUrl)) {
956
+ if (!gitInfo.owner || !gitInfo.repo) {
957
+ console.log(
958
+ import_chalk2.default.red(
959
+ "\u2717 Could not parse GitHub repository information from remote URL."
960
+ )
961
+ );
962
+ process.exit(1);
963
+ }
964
+ console.log(import_chalk2.default.white("GitHub repository detected:"));
965
+ console.log(
966
+ import_chalk2.default.gray(` Repository: `) + import_chalk2.default.cyan(`${gitInfo.owner}/${gitInfo.repo}`)
967
+ );
968
+ console.log(
969
+ import_chalk2.default.gray(` Branch: `) + import_chalk2.default.cyan(gitInfo.branch || "main")
970
+ );
971
+ if (gitInfo.commitSha) {
972
+ console.log(
973
+ import_chalk2.default.gray(` Commit: `) + import_chalk2.default.gray(gitInfo.commitSha.substring(0, 7))
974
+ );
975
+ }
976
+ if (gitInfo.commitMessage) {
977
+ console.log(
978
+ import_chalk2.default.gray(` Message: `) + import_chalk2.default.gray(gitInfo.commitMessage.split("\n")[0])
979
+ );
980
+ }
981
+ console.log();
982
+ const shouldDeploy = await prompt(
983
+ import_chalk2.default.white(
984
+ `Deploy from GitHub repository ${gitInfo.owner}/${gitInfo.repo}? (y/n): `
985
+ )
986
+ );
987
+ if (!shouldDeploy) {
988
+ console.log(import_chalk2.default.gray("Deployment cancelled."));
989
+ process.exit(0);
990
+ }
991
+ const projectName = options.name || await getProjectName(cwd);
992
+ const runtime = options.runtime || await detectRuntime(cwd);
993
+ const port = options.port || 3e3;
994
+ const buildCommand = await detectBuildCommand(cwd);
995
+ const startCommand = await detectStartCommand(cwd);
996
+ console.log();
997
+ console.log(import_chalk2.default.white("Deployment configuration:"));
998
+ console.log(import_chalk2.default.gray(` Name: `) + import_chalk2.default.cyan(projectName));
999
+ console.log(import_chalk2.default.gray(` Runtime: `) + import_chalk2.default.cyan(runtime));
1000
+ console.log(import_chalk2.default.gray(` Port: `) + import_chalk2.default.cyan(port));
1001
+ if (buildCommand) {
1002
+ console.log(import_chalk2.default.gray(` Build command: `) + import_chalk2.default.cyan(buildCommand));
1003
+ }
1004
+ if (startCommand) {
1005
+ console.log(import_chalk2.default.gray(` Start command: `) + import_chalk2.default.cyan(startCommand));
1006
+ }
1007
+ console.log();
1008
+ const deploymentRequest = {
1009
+ name: projectName,
1010
+ source: {
1011
+ type: "github",
1012
+ repo: `${gitInfo.owner}/${gitInfo.repo}`,
1013
+ branch: gitInfo.branch || "main",
1014
+ runtime,
1015
+ port,
1016
+ buildCommand,
1017
+ startCommand
1018
+ },
1019
+ healthCheckPath: "/healthz"
1020
+ };
1021
+ console.log(import_chalk2.default.gray("Creating deployment..."));
1022
+ const api = await McpUseAPI.create();
1023
+ const deployment = await api.createDeployment(deploymentRequest);
1024
+ console.log(
1025
+ import_chalk2.default.green("\u2713 Deployment created: ") + import_chalk2.default.gray(deployment.id)
1026
+ );
1027
+ await displayDeploymentProgress(api, deployment);
1028
+ if (options.open && deployment.domain) {
1029
+ console.log();
1030
+ console.log(import_chalk2.default.gray("Opening deployment in browser..."));
1031
+ await (0, import_open2.default)(`https://${deployment.domain}`);
1032
+ }
1033
+ } else {
1034
+ if (options.fromSource) {
1035
+ console.log(
1036
+ import_chalk2.default.white("\u{1F4E6} Deploying from local source code (--from-source)...")
1037
+ );
1038
+ } else {
1039
+ console.log(
1040
+ import_chalk2.default.yellow(
1041
+ "\u26A0\uFE0F This is not a GitHub repository or no remote is configured."
1042
+ )
1043
+ );
1044
+ console.log(import_chalk2.default.white("Deploying from local source code instead..."));
1045
+ }
1046
+ console.log();
1047
+ const projectName = options.name || await getProjectName(cwd);
1048
+ const runtime = options.runtime || await detectRuntime(cwd);
1049
+ const port = options.port || 3e3;
1050
+ const buildCommand = await detectBuildCommand(cwd);
1051
+ const startCommand = await detectStartCommand(cwd);
1052
+ console.log(import_chalk2.default.white("Deployment configuration:"));
1053
+ console.log(import_chalk2.default.gray(` Name: `) + import_chalk2.default.cyan(projectName));
1054
+ console.log(import_chalk2.default.gray(` Runtime: `) + import_chalk2.default.cyan(runtime));
1055
+ console.log(import_chalk2.default.gray(` Port: `) + import_chalk2.default.cyan(port));
1056
+ if (buildCommand) {
1057
+ console.log(import_chalk2.default.gray(` Build command: `) + import_chalk2.default.cyan(buildCommand));
1058
+ }
1059
+ if (startCommand) {
1060
+ console.log(import_chalk2.default.gray(` Start command: `) + import_chalk2.default.cyan(startCommand));
1061
+ }
1062
+ console.log();
1063
+ const shouldDeploy = await prompt(
1064
+ import_chalk2.default.white("Deploy from local source? (y/n): ")
1065
+ );
1066
+ if (!shouldDeploy) {
1067
+ console.log(import_chalk2.default.gray("Deployment cancelled."));
1068
+ process.exit(0);
1069
+ }
1070
+ console.log();
1071
+ console.log(import_chalk2.default.gray("Packaging source code..."));
1072
+ const tarballPath = await createTarball(cwd);
1073
+ const stats = await import_node_fs2.promises.stat(tarballPath);
1074
+ console.log(
1075
+ import_chalk2.default.green("\u2713 Packaged: ") + import_chalk2.default.gray(formatFileSize(stats.size))
1076
+ );
1077
+ console.log(import_chalk2.default.gray("Uploading source code..."));
1078
+ const api = await McpUseAPI.create();
1079
+ const uploadResponse = await api.uploadSource(tarballPath);
1080
+ console.log(
1081
+ import_chalk2.default.green("\u2713 Uploaded: ") + import_chalk2.default.gray(uploadResponse.uploadId)
1082
+ );
1083
+ await import_node_fs2.promises.unlink(tarballPath);
1084
+ const deploymentRequest = {
1085
+ name: projectName,
1086
+ source: {
1087
+ type: "upload",
1088
+ uploadId: uploadResponse.uploadId,
1089
+ runtime,
1090
+ port,
1091
+ buildCommand,
1092
+ startCommand
1093
+ },
1094
+ healthCheckPath: "/healthz"
1095
+ };
1096
+ console.log(import_chalk2.default.gray("Creating deployment..."));
1097
+ const deployment = await api.createDeployment(deploymentRequest);
1098
+ console.log(
1099
+ import_chalk2.default.green("\u2713 Deployment created: ") + import_chalk2.default.gray(deployment.id)
1100
+ );
1101
+ await displayDeploymentProgress(api, deployment);
1102
+ if (options.open && deployment.domain) {
1103
+ console.log();
1104
+ console.log(import_chalk2.default.gray("Opening deployment in browser..."));
1105
+ await (0, import_open2.default)(`https://${deployment.domain}`);
1106
+ }
1107
+ }
1108
+ } catch (error) {
1109
+ console.error(
1110
+ import_chalk2.default.red.bold("\n\u2717 Deployment failed:"),
1111
+ import_chalk2.default.red(error instanceof Error ? error.message : "Unknown error")
1112
+ );
1113
+ process.exit(1);
1114
+ }
1115
+ }
1116
+
1117
+ // src/index.ts
35
1118
  var program = new import_commander.Command();
36
- var packageContent = (0, import_node_fs.readFileSync)(
37
- import_node_path.default.join(__dirname, "../package.json"),
1119
+ var packageContent = (0, import_node_fs3.readFileSync)(
1120
+ import_node_path3.default.join(__dirname, "../package.json"),
38
1121
  "utf-8"
39
1122
  );
40
1123
  var packageJson = JSON.parse(packageContent);
@@ -48,7 +1131,7 @@ async function isPortAvailable(port, host = "localhost") {
48
1131
  return true;
49
1132
  }
50
1133
  }
51
- async function findAvailablePort(startPort, host = "localhost") {
1134
+ async function findAvailablePort2(startPort, host = "localhost") {
52
1135
  for (let port = startPort; port < startPort + 100; port++) {
53
1136
  if (await isPortAvailable(port, host)) {
54
1137
  return port;
@@ -70,7 +1153,7 @@ async function waitForServer(port, host = "localhost", maxAttempts = 30) {
70
1153
  return false;
71
1154
  }
72
1155
  function runCommand(command, args, cwd, env, filterStderr = false) {
73
- const proc = (0, import_node_child_process.spawn)(command, args, {
1156
+ const proc = (0, import_node_child_process3.spawn)(command, args, {
74
1157
  cwd,
75
1158
  stdio: filterStderr ? ["inherit", "inherit", "pipe"] : "inherit",
76
1159
  shell: false,
@@ -98,8 +1181,8 @@ function runCommand(command, args, cwd, env, filterStderr = false) {
98
1181
  }
99
1182
  async function startTunnel(port) {
100
1183
  return new Promise((resolve, reject) => {
101
- console.log(import_chalk.default.gray(`Starting tunnel for port ${port}...`));
102
- const proc = (0, import_node_child_process.spawn)("npx", ["--yes", "@mcp-use/tunnel", String(port)], {
1184
+ console.log(import_chalk3.default.gray(`Starting tunnel for port ${port}...`));
1185
+ const proc = (0, import_node_child_process3.spawn)("npx", ["--yes", "@mcp-use/tunnel", String(port)], {
103
1186
  stdio: ["ignore", "pipe", "pipe"],
104
1187
  shell: false
105
1188
  });
@@ -113,7 +1196,7 @@ async function startTunnel(port) {
113
1196
  const subdomain = url;
114
1197
  resolved = true;
115
1198
  clearTimeout(setupTimeout);
116
- console.log(import_chalk.default.green.bold(`\u2713 Tunnel established: ${url}/mcp`));
1199
+ console.log(import_chalk3.default.green.bold(`\u2713 Tunnel established: ${url}/mcp`));
117
1200
  resolve({ url, subdomain, process: proc });
118
1201
  }
119
1202
  });
@@ -144,7 +1227,7 @@ async function findServerFile(projectPath) {
144
1227
  const candidates = ["index.ts", "src/index.ts", "server.ts", "src/server.ts"];
145
1228
  for (const candidate of candidates) {
146
1229
  try {
147
- await (0, import_promises.access)(import_node_path.default.join(projectPath, candidate));
1230
+ await (0, import_promises.access)(import_node_path3.default.join(projectPath, candidate));
148
1231
  return candidate;
149
1232
  } catch {
150
1233
  continue;
@@ -153,18 +1236,18 @@ async function findServerFile(projectPath) {
153
1236
  throw new Error("No server file found");
154
1237
  }
155
1238
  async function buildWidgets(projectPath) {
156
- const { promises: fs } = await import("fs");
1239
+ const { promises: fs3 } = await import("fs");
157
1240
  const { build } = await import("vite");
158
- const resourcesDir = import_node_path.default.join(projectPath, "resources");
1241
+ const resourcesDir = import_node_path3.default.join(projectPath, "resources");
159
1242
  const mcpUrl = process.env.MCP_URL;
160
1243
  if (!mcpUrl) {
161
1244
  console.log(
162
- import_chalk.default.yellow(
1245
+ import_chalk3.default.yellow(
163
1246
  "\u26A0\uFE0F MCP_URL not set - using relative paths (widgets may not work correctly)"
164
1247
  )
165
1248
  );
166
1249
  console.log(
167
- import_chalk.default.gray(
1250
+ import_chalk3.default.gray(
168
1251
  " Set MCP_URL environment variable for production builds (e.g., https://myserver.com)"
169
1252
  )
170
1253
  );
@@ -173,39 +1256,39 @@ async function buildWidgets(projectPath) {
173
1256
  await (0, import_promises.access)(resourcesDir);
174
1257
  } catch {
175
1258
  console.log(
176
- import_chalk.default.gray("No resources/ directory found - skipping widget build")
1259
+ import_chalk3.default.gray("No resources/ directory found - skipping widget build")
177
1260
  );
178
1261
  return [];
179
1262
  }
180
1263
  let entries = [];
181
1264
  try {
182
- const files = await fs.readdir(resourcesDir);
183
- entries = files.filter((f) => f.endsWith(".tsx") || f.endsWith(".ts")).map((f) => import_node_path.default.join(resourcesDir, f));
1265
+ const files = await fs3.readdir(resourcesDir);
1266
+ entries = files.filter((f) => f.endsWith(".tsx") || f.endsWith(".ts")).map((f) => import_node_path3.default.join(resourcesDir, f));
184
1267
  } catch (error) {
185
- console.log(import_chalk.default.gray("No widgets found in resources/ directory"));
1268
+ console.log(import_chalk3.default.gray("No widgets found in resources/ directory"));
186
1269
  return [];
187
1270
  }
188
1271
  if (entries.length === 0) {
189
- console.log(import_chalk.default.gray("No widgets found in resources/ directory"));
1272
+ console.log(import_chalk3.default.gray("No widgets found in resources/ directory"));
190
1273
  return [];
191
1274
  }
192
- console.log(import_chalk.default.gray(`Building ${entries.length} widget(s)...`));
1275
+ console.log(import_chalk3.default.gray(`Building ${entries.length} widget(s)...`));
193
1276
  const react = (await import("@vitejs/plugin-react")).default;
194
1277
  const tailwindcss = (await import("@tailwindcss/vite")).default;
195
1278
  const builtWidgets = [];
196
1279
  for (const entry of entries) {
197
- const baseName = import_node_path.default.basename(entry).replace(/\.tsx?$/, "");
1280
+ const baseName = import_node_path3.default.basename(entry).replace(/\.tsx?$/, "");
198
1281
  const widgetName = baseName;
199
- console.log(import_chalk.default.gray(` - Building ${widgetName}...`));
200
- const tempDir = import_node_path.default.join(projectPath, ".mcp-use", widgetName);
201
- await fs.mkdir(tempDir, { recursive: true });
202
- const relativeResourcesPath = import_node_path.default.relative(tempDir, resourcesDir).replace(/\\/g, "/");
1282
+ console.log(import_chalk3.default.gray(` - Building ${widgetName}...`));
1283
+ const tempDir = import_node_path3.default.join(projectPath, ".mcp-use", widgetName);
1284
+ await fs3.mkdir(tempDir, { recursive: true });
1285
+ const relativeResourcesPath = import_node_path3.default.relative(tempDir, resourcesDir).replace(/\\/g, "/");
203
1286
  const cssContent = `@import "tailwindcss";
204
1287
 
205
1288
  /* Configure Tailwind to scan the resources directory */
206
1289
  @source "${relativeResourcesPath}";
207
1290
  `;
208
- await fs.writeFile(import_node_path.default.join(tempDir, "styles.css"), cssContent, "utf8");
1291
+ await fs3.writeFile(import_node_path3.default.join(tempDir, "styles.css"), cssContent, "utf8");
209
1292
  const entryContent = `import React from 'react'
210
1293
  import { createRoot } from 'react-dom/client'
211
1294
  import './styles.css'
@@ -229,9 +1312,9 @@ if (container && Component) {
229
1312
  <script type="module" src="/entry.tsx"></script>
230
1313
  </body>
231
1314
  </html>`;
232
- await fs.writeFile(import_node_path.default.join(tempDir, "entry.tsx"), entryContent, "utf8");
233
- await fs.writeFile(import_node_path.default.join(tempDir, "index.html"), htmlContent, "utf8");
234
- const outDir = import_node_path.default.join(
1315
+ await fs3.writeFile(import_node_path3.default.join(tempDir, "entry.tsx"), entryContent, "utf8");
1316
+ await fs3.writeFile(import_node_path3.default.join(tempDir, "index.html"), htmlContent, "utf8");
1317
+ const outDir = import_node_path3.default.join(
235
1318
  projectPath,
236
1319
  "dist",
237
1320
  "resources",
@@ -241,16 +1324,16 @@ if (container && Component) {
241
1324
  const baseUrl = mcpUrl ? `${mcpUrl}/${widgetName}/` : `/mcp-use/widgets/${widgetName}/`;
242
1325
  let widgetMetadata = {};
243
1326
  try {
244
- const metadataTempDir = import_node_path.default.join(
1327
+ const metadataTempDir = import_node_path3.default.join(
245
1328
  projectPath,
246
1329
  ".mcp-use",
247
1330
  `${widgetName}-metadata`
248
1331
  );
249
- await fs.mkdir(metadataTempDir, { recursive: true });
250
- const { createServer } = await import("vite");
251
- const metadataServer = await createServer({
1332
+ await fs3.mkdir(metadataTempDir, { recursive: true });
1333
+ const { createServer: createServer2 } = await import("vite");
1334
+ const metadataServer = await createServer2({
252
1335
  root: metadataTempDir,
253
- cacheDir: import_node_path.default.join(metadataTempDir, ".vite-cache"),
1336
+ cacheDir: import_node_path3.default.join(metadataTempDir, ".vite-cache"),
254
1337
  plugins: [tailwindcss(), react()],
255
1338
  resolve: {
256
1339
  alias: {
@@ -290,12 +1373,12 @@ if (container && Component) {
290
1373
  await new Promise((resolve) => setTimeout(resolve, 50));
291
1374
  } catch (error) {
292
1375
  console.warn(
293
- import_chalk.default.yellow(` \u26A0 Could not extract metadata for ${widgetName}`)
1376
+ import_chalk3.default.yellow(` \u26A0 Could not extract metadata for ${widgetName}`)
294
1377
  );
295
1378
  } finally {
296
1379
  await metadataServer.close();
297
1380
  try {
298
- await fs.rm(metadataTempDir, { recursive: true, force: true });
1381
+ await fs3.rm(metadataTempDir, { recursive: true, force: true });
299
1382
  } catch {
300
1383
  }
301
1384
  }
@@ -326,7 +1409,7 @@ if (container && Component) {
326
1409
  outDir,
327
1410
  emptyOutDir: true,
328
1411
  rollupOptions: {
329
- input: import_node_path.default.join(tempDir, "index.html")
1412
+ input: import_node_path3.default.join(tempDir, "index.html")
330
1413
  }
331
1414
  }
332
1415
  });
@@ -334,23 +1417,23 @@ if (container && Component) {
334
1417
  name: widgetName,
335
1418
  metadata: widgetMetadata
336
1419
  });
337
- console.log(import_chalk.default.green(` \u2713 Built ${widgetName}`));
1420
+ console.log(import_chalk3.default.green(` \u2713 Built ${widgetName}`));
338
1421
  } catch (error) {
339
- console.error(import_chalk.default.red(` \u2717 Failed to build ${widgetName}:`), error);
1422
+ console.error(import_chalk3.default.red(` \u2717 Failed to build ${widgetName}:`), error);
340
1423
  }
341
1424
  }
342
1425
  return builtWidgets;
343
1426
  }
344
1427
  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) => {
345
1428
  try {
346
- const projectPath = import_node_path.default.resolve(options.path);
347
- const { promises: fs } = await import("fs");
348
- console.log(import_chalk.default.cyan.bold(`mcp-use v${packageJson.version}`));
1429
+ const projectPath = import_node_path3.default.resolve(options.path);
1430
+ const { promises: fs3 } = await import("fs");
1431
+ console.log(import_chalk3.default.cyan.bold(`mcp-use v${packageJson.version}`));
349
1432
  const builtWidgets = await buildWidgets(projectPath);
350
- console.log(import_chalk.default.gray("Building TypeScript..."));
1433
+ console.log(import_chalk3.default.gray("Building TypeScript..."));
351
1434
  await runCommand("npx", ["tsc"], projectPath);
352
- console.log(import_chalk.default.green("\u2713 TypeScript build complete!"));
353
- const manifestPath = import_node_path.default.join(projectPath, "dist", "mcp-use.json");
1435
+ console.log(import_chalk3.default.green("\u2713 TypeScript build complete!"));
1436
+ const manifestPath = import_node_path3.default.join(projectPath, "dist", "mcp-use.json");
354
1437
  const widgetsData = {};
355
1438
  for (const widget of builtWidgets) {
356
1439
  widgetsData[widget.name] = widget.metadata;
@@ -361,36 +1444,36 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
361
1444
  buildTime: (/* @__PURE__ */ new Date()).toISOString(),
362
1445
  widgets: widgetsData
363
1446
  };
364
- await fs.mkdir(import_node_path.default.dirname(manifestPath), { recursive: true });
365
- await fs.writeFile(
1447
+ await fs3.mkdir(import_node_path3.default.dirname(manifestPath), { recursive: true });
1448
+ await fs3.writeFile(
366
1449
  manifestPath,
367
1450
  JSON.stringify(manifest, null, 2),
368
1451
  "utf8"
369
1452
  );
370
- console.log(import_chalk.default.green("\u2713 Build manifest created"));
371
- console.log(import_chalk.default.green.bold(`
1453
+ console.log(import_chalk3.default.green("\u2713 Build manifest created"));
1454
+ console.log(import_chalk3.default.green.bold(`
372
1455
  \u2713 Build complete!`));
373
1456
  if (builtWidgets.length > 0) {
374
- console.log(import_chalk.default.gray(` ${builtWidgets.length} widget(s) built`));
1457
+ console.log(import_chalk3.default.gray(` ${builtWidgets.length} widget(s) built`));
375
1458
  }
376
1459
  if (options.withInspector) {
377
- console.log(import_chalk.default.gray(" Inspector included"));
1460
+ console.log(import_chalk3.default.gray(" Inspector included"));
378
1461
  }
379
1462
  } catch (error) {
380
- console.error(import_chalk.default.red("Build failed:"), error);
1463
+ console.error(import_chalk3.default.red("Build failed:"), error);
381
1464
  process.exit(1);
382
1465
  }
383
1466
  });
384
1467
  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) => {
385
1468
  try {
386
- const projectPath = import_node_path.default.resolve(options.path);
1469
+ const projectPath = import_node_path3.default.resolve(options.path);
387
1470
  let port = parseInt(options.port, 10);
388
1471
  const host = options.host;
389
- console.log(import_chalk.default.cyan.bold(`mcp-use v${packageJson.version}`));
1472
+ console.log(import_chalk3.default.cyan.bold(`mcp-use v${packageJson.version}`));
390
1473
  if (!await isPortAvailable(port, host)) {
391
- console.log(import_chalk.default.yellow.bold(`\u26A0\uFE0F Port ${port} is already in use`));
392
- const availablePort = await findAvailablePort(port, host);
393
- console.log(import_chalk.default.green.bold(`\u2713 Using port ${availablePort} instead`));
1474
+ console.log(import_chalk3.default.yellow.bold(`\u26A0\uFE0F Port ${port} is already in use`));
1475
+ const availablePort = await findAvailablePort2(port, host);
1476
+ console.log(import_chalk3.default.green.bold(`\u2713 Using port ${availablePort} instead`));
394
1477
  port = availablePort;
395
1478
  }
396
1479
  let mcpUrl;
@@ -422,20 +1505,20 @@ program.command("dev").description("Run development server with auto-reload and
422
1505
  inspectorUrl += `&tunnelUrl=${encodeURIComponent(mcpUrl)}`;
423
1506
  }
424
1507
  const readyTime = Date.now() - startTime;
425
- console.log(import_chalk.default.green.bold(`\u2713 Ready in ${readyTime}ms`));
426
- console.log(import_chalk.default.whiteBright(`Local: http://${host}:${port}`));
427
- console.log(import_chalk.default.whiteBright(`Network: http://${host}:${port}`));
1508
+ console.log(import_chalk3.default.green.bold(`\u2713 Ready in ${readyTime}ms`));
1509
+ console.log(import_chalk3.default.whiteBright(`Local: http://${host}:${port}`));
1510
+ console.log(import_chalk3.default.whiteBright(`Network: http://${host}:${port}`));
428
1511
  if (mcpUrl) {
429
- console.log(import_chalk.default.whiteBright(`Tunnel: ${mcpUrl}`));
1512
+ console.log(import_chalk3.default.whiteBright(`Tunnel: ${mcpUrl}`));
430
1513
  }
431
- console.log(import_chalk.default.whiteBright(`MCP: ${mcpEndpoint}`));
432
- console.log(import_chalk.default.whiteBright(`Inspector: ${inspectorUrl}
1514
+ console.log(import_chalk3.default.whiteBright(`MCP: ${mcpEndpoint}`));
1515
+ console.log(import_chalk3.default.whiteBright(`Inspector: ${inspectorUrl}
433
1516
  `));
434
- await (0, import_open.default)(inspectorUrl);
1517
+ await (0, import_open3.default)(inspectorUrl);
435
1518
  }
436
1519
  }
437
1520
  const cleanup = () => {
438
- console.log(import_chalk.default.gray("\n\nShutting down..."));
1521
+ console.log(import_chalk3.default.gray("\n\nShutting down..."));
439
1522
  const processesToKill = processes.length;
440
1523
  let killedCount = 0;
441
1524
  const checkAndExit = () => {
@@ -466,13 +1549,13 @@ program.command("dev").description("Run development server with auto-reload and
466
1549
  await new Promise(() => {
467
1550
  });
468
1551
  } catch (error) {
469
- console.error(import_chalk.default.red("Dev mode failed:"), error);
1552
+ console.error(import_chalk3.default.red("Dev mode failed:"), error);
470
1553
  process.exit(1);
471
1554
  }
472
1555
  });
473
1556
  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) => {
474
1557
  try {
475
- const projectPath = import_node_path.default.resolve(options.path);
1558
+ const projectPath = import_node_path3.default.resolve(options.path);
476
1559
  const port = parseInt(options.port, 10);
477
1560
  console.log(
478
1561
  `\x1B[36m\x1B[1mmcp-use\x1B[0m \x1B[90mVersion: ${packageJson.version}\x1B[0m
@@ -486,13 +1569,13 @@ program.command("start").description("Start production server").option("-p, --pa
486
1569
  mcpUrl = tunnelInfo.subdomain;
487
1570
  tunnelProcess = tunnelInfo.process;
488
1571
  } catch (error) {
489
- console.error(import_chalk.default.red("Failed to start tunnel:"), error);
1572
+ console.error(import_chalk3.default.red("Failed to start tunnel:"), error);
490
1573
  process.exit(1);
491
1574
  }
492
1575
  }
493
1576
  let serverFile = "dist/index.js";
494
1577
  try {
495
- await (0, import_promises.access)(import_node_path.default.join(projectPath, serverFile));
1578
+ await (0, import_promises.access)(import_node_path3.default.join(projectPath, serverFile));
496
1579
  } catch {
497
1580
  serverFile = "dist/server.js";
498
1581
  }
@@ -504,9 +1587,9 @@ program.command("start").description("Start production server").option("-p, --pa
504
1587
  };
505
1588
  if (mcpUrl) {
506
1589
  env.MCP_URL = mcpUrl;
507
- console.log(import_chalk.default.whiteBright(`Tunnel: ${mcpUrl}`));
1590
+ console.log(import_chalk3.default.whiteBright(`Tunnel: ${mcpUrl}`));
508
1591
  }
509
- const serverProc = (0, import_node_child_process.spawn)("node", [serverFile], {
1592
+ const serverProc = (0, import_node_child_process3.spawn)("node", [serverFile], {
510
1593
  cwd: projectPath,
511
1594
  stdio: "inherit",
512
1595
  env
@@ -549,4 +1632,25 @@ program.command("start").description("Start production server").option("-p, --pa
549
1632
  process.exit(1);
550
1633
  }
551
1634
  });
1635
+ program.command("login").description("Login to mcp-use cloud").action(async () => {
1636
+ await loginCommand();
1637
+ });
1638
+ program.command("logout").description("Logout from mcp-use cloud").action(async () => {
1639
+ await logoutCommand();
1640
+ });
1641
+ program.command("whoami").description("Show current user information").action(async () => {
1642
+ await whoamiCommand();
1643
+ });
1644
+ program.command("deploy").description("Deploy MCP server to mcp-use cloud").option("--open", "Open deployment in browser after successful deploy").option("--name <name>", "Custom deployment name").option("--port <port>", "Server port", "3000").option("--runtime <runtime>", "Runtime (node or python)").option(
1645
+ "--from-source",
1646
+ "Deploy from local source code (even for GitHub repos)"
1647
+ ).action(async (options) => {
1648
+ await deployCommand({
1649
+ open: options.open,
1650
+ name: options.name,
1651
+ port: options.port ? parseInt(options.port, 10) : void 0,
1652
+ runtime: options.runtime,
1653
+ fromSource: options.fromSource
1654
+ });
1655
+ });
552
1656
  program.parse();