@mcp-use/cli 3.2.0-canary.5 → 3.2.0-canary.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/client.d.ts +2 -0
- package/dist/commands/client.d.ts.map +1 -1
- package/dist/commands/screenshot.d.ts +65 -0
- package/dist/commands/screenshot.d.ts.map +1 -0
- package/dist/index.cjs +1044 -290
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +995 -241
- package/dist/index.js.map +1 -1
- package/dist/utils/cdp-screenshot.d.ts +33 -0
- package/dist/utils/cdp-screenshot.d.ts.map +1 -0
- package/dist/utils/chrome-path.d.ts +14 -0
- package/dist/utils/chrome-path.d.ts.map +1 -0
- package/dist/utils/session.d.ts +37 -0
- package/dist/utils/session.d.ts.map +1 -0
- package/package.json +5 -3
package/dist/index.cjs
CHANGED
|
@@ -30,10 +30,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
30
|
mod
|
|
31
31
|
));
|
|
32
32
|
|
|
33
|
-
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.
|
|
33
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.9_tsx@4.21.0_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js
|
|
34
34
|
var getImportMetaUrl, importMetaUrl;
|
|
35
35
|
var init_cjs_shims = __esm({
|
|
36
|
-
"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.
|
|
36
|
+
"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.9_tsx@4.21.0_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js"() {
|
|
37
37
|
"use strict";
|
|
38
38
|
getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
|
|
39
39
|
importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
@@ -253,15 +253,15 @@ var init_wsl_utils = __esm({
|
|
|
253
253
|
const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
|
|
254
254
|
return stdout.trim();
|
|
255
255
|
};
|
|
256
|
-
convertWslPathToWindows = async (
|
|
257
|
-
if (/^[a-z]+:\/\//i.test(
|
|
258
|
-
return
|
|
256
|
+
convertWslPathToWindows = async (path11) => {
|
|
257
|
+
if (/^[a-z]+:\/\//i.test(path11)) {
|
|
258
|
+
return path11;
|
|
259
259
|
}
|
|
260
260
|
try {
|
|
261
|
-
const { stdout } = await execFile2("wslpath", ["-aw",
|
|
261
|
+
const { stdout } = await execFile2("wslpath", ["-aw", path11], { encoding: "utf8" });
|
|
262
262
|
return stdout.trim();
|
|
263
263
|
} catch {
|
|
264
|
-
return
|
|
264
|
+
return path11;
|
|
265
265
|
}
|
|
266
266
|
};
|
|
267
267
|
}
|
|
@@ -1280,13 +1280,13 @@ var chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
|
|
|
1280
1280
|
var source_default = chalk;
|
|
1281
1281
|
|
|
1282
1282
|
// src/index.ts
|
|
1283
|
-
var
|
|
1283
|
+
var import_commander7 = require("commander");
|
|
1284
1284
|
var import_config8 = require("dotenv/config");
|
|
1285
|
-
var
|
|
1286
|
-
var
|
|
1287
|
-
var
|
|
1285
|
+
var import_node_child_process11 = require("child_process");
|
|
1286
|
+
var import_node_fs14 = require("fs");
|
|
1287
|
+
var import_promises8 = require("fs/promises");
|
|
1288
1288
|
var import_node_module2 = require("module");
|
|
1289
|
-
var
|
|
1289
|
+
var import_node_path12 = __toESM(require("path"), 1);
|
|
1290
1290
|
var import_node_url3 = require("url");
|
|
1291
1291
|
init_open();
|
|
1292
1292
|
var import_vite_plugin_singlefile = require("vite-plugin-singlefile");
|
|
@@ -1524,8 +1524,8 @@ var McpUseAPI = class _McpUseAPI {
|
|
|
1524
1524
|
return this.request(`/servers${q ? `?${q}` : ""}`);
|
|
1525
1525
|
}
|
|
1526
1526
|
async getServer(idOrSlug) {
|
|
1527
|
-
const
|
|
1528
|
-
return this.request(`/servers/${
|
|
1527
|
+
const path11 = encodeURIComponent(idOrSlug);
|
|
1528
|
+
return this.request(`/servers/${path11}`);
|
|
1529
1529
|
}
|
|
1530
1530
|
async deleteServer(id) {
|
|
1531
1531
|
await this.request(
|
|
@@ -2027,9 +2027,8 @@ async function whoamiCommand() {
|
|
|
2027
2027
|
|
|
2028
2028
|
// src/commands/client.ts
|
|
2029
2029
|
init_cjs_shims();
|
|
2030
|
-
var
|
|
2031
|
-
var
|
|
2032
|
-
var import_server = require("mcp-use/server");
|
|
2030
|
+
var import_commander2 = require("commander");
|
|
2031
|
+
var import_client3 = require("mcp-use/client");
|
|
2033
2032
|
var import_node_readline2 = require("readline");
|
|
2034
2033
|
|
|
2035
2034
|
// src/utils/format.ts
|
|
@@ -2623,6 +2622,121 @@ async function updateSessionInfo(name, serverInfo, capabilities) {
|
|
|
2623
2622
|
}
|
|
2624
2623
|
}
|
|
2625
2624
|
|
|
2625
|
+
// src/utils/session.ts
|
|
2626
|
+
init_cjs_shims();
|
|
2627
|
+
var import_client = require("mcp-use/client");
|
|
2628
|
+
var import_server = require("mcp-use/server");
|
|
2629
|
+
var activeSessions = /* @__PURE__ */ new Map();
|
|
2630
|
+
function getCliClientInfo() {
|
|
2631
|
+
return {
|
|
2632
|
+
name: "mcp-use CLI",
|
|
2633
|
+
title: "mcp-use CLI",
|
|
2634
|
+
version: (0, import_server.getPackageVersion)(),
|
|
2635
|
+
description: "mcp-use CLI - Command-line interface for MCP servers",
|
|
2636
|
+
icons: [
|
|
2637
|
+
{
|
|
2638
|
+
src: "https://manufact.com/logo.png"
|
|
2639
|
+
}
|
|
2640
|
+
],
|
|
2641
|
+
websiteUrl: "https://manufact.com"
|
|
2642
|
+
};
|
|
2643
|
+
}
|
|
2644
|
+
async function cleanupAndExit(code) {
|
|
2645
|
+
for (const [name, { client }] of activeSessions) {
|
|
2646
|
+
try {
|
|
2647
|
+
await client.closeAllSessions();
|
|
2648
|
+
} catch {
|
|
2649
|
+
}
|
|
2650
|
+
activeSessions.delete(name);
|
|
2651
|
+
}
|
|
2652
|
+
process.exit(code);
|
|
2653
|
+
}
|
|
2654
|
+
async function getOrRestoreSession(sessionName) {
|
|
2655
|
+
if (!sessionName) {
|
|
2656
|
+
const active = await getActiveSession();
|
|
2657
|
+
if (!active) {
|
|
2658
|
+
console.error(
|
|
2659
|
+
formatError("No active session. Connect to a server first.")
|
|
2660
|
+
);
|
|
2661
|
+
console.error(
|
|
2662
|
+
formatInfo("Use: npx mcp-use client connect <url> --name <name>")
|
|
2663
|
+
);
|
|
2664
|
+
return null;
|
|
2665
|
+
}
|
|
2666
|
+
sessionName = active.name;
|
|
2667
|
+
}
|
|
2668
|
+
if (activeSessions.has(sessionName)) {
|
|
2669
|
+
const { session } = activeSessions.get(sessionName);
|
|
2670
|
+
return { name: sessionName, session };
|
|
2671
|
+
}
|
|
2672
|
+
const config = await getSession(sessionName);
|
|
2673
|
+
if (!config) {
|
|
2674
|
+
console.error(formatError(`Session '${sessionName}' not found`));
|
|
2675
|
+
return null;
|
|
2676
|
+
}
|
|
2677
|
+
try {
|
|
2678
|
+
const client = new import_client.MCPClient();
|
|
2679
|
+
const cliClientInfo = getCliClientInfo();
|
|
2680
|
+
let authProvider;
|
|
2681
|
+
if (config.type === "http") {
|
|
2682
|
+
if (config.authMode === "oauth") {
|
|
2683
|
+
authProvider = await buildOAuthProvider(config.url);
|
|
2684
|
+
client.addServer(sessionName, {
|
|
2685
|
+
url: config.url,
|
|
2686
|
+
authProvider,
|
|
2687
|
+
clientInfo: cliClientInfo
|
|
2688
|
+
});
|
|
2689
|
+
} else {
|
|
2690
|
+
client.addServer(sessionName, {
|
|
2691
|
+
url: config.url,
|
|
2692
|
+
headers: config.authToken ? { Authorization: `Bearer ${config.authToken}` } : void 0,
|
|
2693
|
+
clientInfo: cliClientInfo
|
|
2694
|
+
});
|
|
2695
|
+
}
|
|
2696
|
+
} else if (config.type === "stdio") {
|
|
2697
|
+
client.addServer(sessionName, {
|
|
2698
|
+
command: config.command,
|
|
2699
|
+
args: config.args || [],
|
|
2700
|
+
env: config.env,
|
|
2701
|
+
clientInfo: cliClientInfo
|
|
2702
|
+
});
|
|
2703
|
+
} else {
|
|
2704
|
+
console.error(formatError(`Unknown session type: ${config.type}`));
|
|
2705
|
+
return null;
|
|
2706
|
+
}
|
|
2707
|
+
let session;
|
|
2708
|
+
try {
|
|
2709
|
+
session = await client.createSession(sessionName);
|
|
2710
|
+
} catch (err) {
|
|
2711
|
+
if (config.type === "http" && config.authMode === "oauth" && authProvider && isUnauthorized(err)) {
|
|
2712
|
+
const reAuth = await promptYesNo(
|
|
2713
|
+
`! Tokens for session '${sessionName}' expired and could not refresh. Re-authenticate now?`,
|
|
2714
|
+
true
|
|
2715
|
+
);
|
|
2716
|
+
if (!reAuth) {
|
|
2717
|
+
console.error(formatError(`Tokens expired and could not refresh.`));
|
|
2718
|
+
console.error(
|
|
2719
|
+
formatInfo(
|
|
2720
|
+
`Run: mcp-use client connect ${config.url} --name ${sessionName}`
|
|
2721
|
+
)
|
|
2722
|
+
);
|
|
2723
|
+
return null;
|
|
2724
|
+
}
|
|
2725
|
+
await runOAuthFlow(authProvider, config.url);
|
|
2726
|
+
session = await client.createSession(sessionName);
|
|
2727
|
+
} else {
|
|
2728
|
+
throw err;
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
activeSessions.set(sessionName, { client, session });
|
|
2732
|
+
console.error(formatInfo(`Reconnected to session '${sessionName}'`));
|
|
2733
|
+
return { name: sessionName, session };
|
|
2734
|
+
} catch (error) {
|
|
2735
|
+
console.error(formatError(`Failed to restore session: ${error.message}`));
|
|
2736
|
+
return null;
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
|
|
2626
2740
|
// src/commands/client-auth.ts
|
|
2627
2741
|
init_cjs_shims();
|
|
2628
2742
|
async function resolveSession(sessionArg) {
|
|
@@ -2738,121 +2852,711 @@ async function authLogoutCommand(sessionArg) {
|
|
|
2738
2852
|
);
|
|
2739
2853
|
}
|
|
2740
2854
|
|
|
2741
|
-
// src/commands/
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2855
|
+
// src/commands/screenshot.ts
|
|
2856
|
+
init_cjs_shims();
|
|
2857
|
+
var import_commander = require("commander");
|
|
2858
|
+
var import_client2 = require("mcp-use/client");
|
|
2859
|
+
var import_node_child_process9 = require("child_process");
|
|
2860
|
+
var import_node_fs8 = require("fs");
|
|
2861
|
+
var import_promises5 = require("fs/promises");
|
|
2862
|
+
var import_node_net = require("net");
|
|
2863
|
+
var import_node_path6 = __toESM(require("path"), 1);
|
|
2864
|
+
|
|
2865
|
+
// src/utils/cdp-screenshot.ts
|
|
2866
|
+
init_cjs_shims();
|
|
2867
|
+
var import_node_child_process8 = require("child_process");
|
|
2868
|
+
var import_node_fs6 = require("fs");
|
|
2869
|
+
var import_node_os5 = __toESM(require("os"), 1);
|
|
2870
|
+
var import_node_path4 = __toESM(require("path"), 1);
|
|
2871
|
+
var import_ws = __toESM(require("ws"), 1);
|
|
2872
|
+
var CdpClient = class {
|
|
2873
|
+
constructor(ws) {
|
|
2874
|
+
this.ws = ws;
|
|
2875
|
+
ws.on("message", (data) => {
|
|
2876
|
+
let msg;
|
|
2877
|
+
try {
|
|
2878
|
+
msg = JSON.parse(data.toString());
|
|
2879
|
+
} catch {
|
|
2880
|
+
return;
|
|
2881
|
+
}
|
|
2882
|
+
if (typeof msg.id !== "number") return;
|
|
2883
|
+
const cb = this.pending.get(msg.id);
|
|
2884
|
+
if (!cb) return;
|
|
2885
|
+
this.pending.delete(msg.id);
|
|
2886
|
+
if (msg.error) {
|
|
2887
|
+
cb.reject(new Error(msg.error.message ?? "CDP error"));
|
|
2888
|
+
} else {
|
|
2889
|
+
cb.resolve(msg.result ?? {});
|
|
2890
|
+
}
|
|
2891
|
+
});
|
|
2892
|
+
ws.on("close", () => {
|
|
2893
|
+
for (const cb of this.pending.values()) {
|
|
2894
|
+
cb.reject(new Error("CDP WebSocket closed"));
|
|
2895
|
+
}
|
|
2896
|
+
this.pending.clear();
|
|
2897
|
+
});
|
|
2898
|
+
ws.on("error", (err) => {
|
|
2899
|
+
for (const cb of this.pending.values()) {
|
|
2900
|
+
cb.reject(err);
|
|
2901
|
+
}
|
|
2902
|
+
this.pending.clear();
|
|
2903
|
+
});
|
|
2904
|
+
}
|
|
2905
|
+
nextId = 0;
|
|
2906
|
+
pending = /* @__PURE__ */ new Map();
|
|
2907
|
+
send(method, params = {}, sessionId) {
|
|
2908
|
+
const id = ++this.nextId;
|
|
2909
|
+
const payload = { id, method, params };
|
|
2910
|
+
if (sessionId) payload.sessionId = sessionId;
|
|
2911
|
+
return new Promise((resolve2, reject) => {
|
|
2912
|
+
this.pending.set(id, {
|
|
2913
|
+
resolve: (r) => resolve2(r),
|
|
2914
|
+
reject
|
|
2915
|
+
});
|
|
2916
|
+
this.ws.send(JSON.stringify(payload));
|
|
2917
|
+
});
|
|
2918
|
+
}
|
|
2919
|
+
close() {
|
|
2745
2920
|
try {
|
|
2746
|
-
|
|
2921
|
+
this.ws.close();
|
|
2747
2922
|
} catch {
|
|
2748
2923
|
}
|
|
2749
|
-
activeSessions.delete(name);
|
|
2750
2924
|
}
|
|
2751
|
-
|
|
2925
|
+
};
|
|
2926
|
+
function waitForDevToolsUrl(child, timeoutMs = 5e3) {
|
|
2927
|
+
return new Promise((resolve2, reject) => {
|
|
2928
|
+
let buf = "";
|
|
2929
|
+
const onData = (d) => {
|
|
2930
|
+
buf += d.toString();
|
|
2931
|
+
const m = buf.match(/DevTools listening on (ws:\/\/\S+)/);
|
|
2932
|
+
if (m) {
|
|
2933
|
+
cleanup();
|
|
2934
|
+
resolve2(m[1]);
|
|
2935
|
+
}
|
|
2936
|
+
};
|
|
2937
|
+
const onExit = (code) => {
|
|
2938
|
+
cleanup();
|
|
2939
|
+
reject(
|
|
2940
|
+
new Error(
|
|
2941
|
+
`Chrome exited (code ${code}) before exposing a DevTools port. Last stderr: ${buf.slice(-500)}`
|
|
2942
|
+
)
|
|
2943
|
+
);
|
|
2944
|
+
};
|
|
2945
|
+
const cleanup = () => {
|
|
2946
|
+
child.stderr?.off("data", onData);
|
|
2947
|
+
child.off("exit", onExit);
|
|
2948
|
+
clearTimeout(timer);
|
|
2949
|
+
};
|
|
2950
|
+
const timer = setTimeout(() => {
|
|
2951
|
+
cleanup();
|
|
2952
|
+
reject(
|
|
2953
|
+
new Error(`Chrome did not expose a DevTools port within ${timeoutMs}ms`)
|
|
2954
|
+
);
|
|
2955
|
+
}, timeoutMs);
|
|
2956
|
+
child.stderr?.on("data", onData);
|
|
2957
|
+
child.on("exit", onExit);
|
|
2958
|
+
});
|
|
2752
2959
|
}
|
|
2753
|
-
async function
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2960
|
+
async function captureScreenshot(opts) {
|
|
2961
|
+
const userDataDir = (0, import_node_fs6.mkdtempSync)(import_node_path4.default.join(import_node_os5.default.tmpdir(), "mcp-use-chrome-"));
|
|
2962
|
+
const chromeArgs = [
|
|
2963
|
+
"--headless=new",
|
|
2964
|
+
"--remote-debugging-port=0",
|
|
2965
|
+
`--user-data-dir=${userDataDir}`,
|
|
2966
|
+
"--no-first-run",
|
|
2967
|
+
"--no-default-browser-check",
|
|
2968
|
+
"--disable-extensions",
|
|
2969
|
+
"--disable-gpu",
|
|
2970
|
+
"--hide-scrollbars",
|
|
2971
|
+
"--mute-audio",
|
|
2972
|
+
`--window-size=${opts.width},${opts.height}`,
|
|
2973
|
+
"about:blank"
|
|
2974
|
+
];
|
|
2975
|
+
const child = (0, import_node_child_process8.spawn)(opts.chromePath, chromeArgs, {
|
|
2976
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
2977
|
+
});
|
|
2978
|
+
child.stdout?.resume();
|
|
2979
|
+
let cdp;
|
|
2980
|
+
let cleanedUp = false;
|
|
2981
|
+
const cleanup = () => {
|
|
2982
|
+
if (cleanedUp) return;
|
|
2983
|
+
cleanedUp = true;
|
|
2984
|
+
cdp?.close();
|
|
2985
|
+
if (!child.killed) {
|
|
2986
|
+
try {
|
|
2987
|
+
child.kill("SIGTERM");
|
|
2988
|
+
} catch {
|
|
2989
|
+
}
|
|
2990
|
+
const killTimer = setTimeout(() => {
|
|
2991
|
+
if (!child.killed) {
|
|
2992
|
+
try {
|
|
2993
|
+
child.kill("SIGKILL");
|
|
2994
|
+
} catch {
|
|
2995
|
+
}
|
|
2996
|
+
}
|
|
2997
|
+
}, 2e3);
|
|
2998
|
+
killTimer.unref();
|
|
2999
|
+
}
|
|
3000
|
+
try {
|
|
3001
|
+
(0, import_node_fs6.rmSync)(userDataDir, { recursive: true, force: true });
|
|
3002
|
+
} catch {
|
|
3003
|
+
}
|
|
3004
|
+
};
|
|
3005
|
+
try {
|
|
3006
|
+
const wsUrl = await waitForDevToolsUrl(child);
|
|
3007
|
+
const ws = new import_ws.default(wsUrl);
|
|
3008
|
+
await new Promise((resolve2, reject) => {
|
|
3009
|
+
const onOpen = () => {
|
|
3010
|
+
ws.off("error", onError);
|
|
3011
|
+
resolve2();
|
|
3012
|
+
};
|
|
3013
|
+
const onError = (err) => {
|
|
3014
|
+
ws.off("open", onOpen);
|
|
3015
|
+
reject(err);
|
|
3016
|
+
};
|
|
3017
|
+
ws.once("open", onOpen);
|
|
3018
|
+
ws.once("error", onError);
|
|
3019
|
+
});
|
|
3020
|
+
cdp = new CdpClient(ws);
|
|
3021
|
+
const { targetId } = await cdp.send(
|
|
3022
|
+
"Target.createTarget",
|
|
3023
|
+
{ url: "about:blank" }
|
|
3024
|
+
);
|
|
3025
|
+
const { sessionId } = await cdp.send(
|
|
3026
|
+
"Target.attachToTarget",
|
|
3027
|
+
{ targetId, flatten: true }
|
|
3028
|
+
);
|
|
3029
|
+
await cdp.send("Page.enable", {}, sessionId);
|
|
3030
|
+
await cdp.send(
|
|
3031
|
+
"Emulation.setDeviceMetricsOverride",
|
|
3032
|
+
{
|
|
3033
|
+
width: opts.width,
|
|
3034
|
+
height: opts.height,
|
|
3035
|
+
deviceScaleFactor: 1,
|
|
3036
|
+
mobile: false
|
|
3037
|
+
},
|
|
3038
|
+
sessionId
|
|
3039
|
+
);
|
|
3040
|
+
await cdp.send(
|
|
3041
|
+
"Emulation.setEmulatedMedia",
|
|
3042
|
+
{
|
|
3043
|
+
features: [
|
|
3044
|
+
{ name: "prefers-color-scheme", value: opts.theme },
|
|
3045
|
+
{ name: "prefers-reduced-motion", value: "reduce" }
|
|
3046
|
+
]
|
|
3047
|
+
},
|
|
3048
|
+
sessionId
|
|
3049
|
+
);
|
|
3050
|
+
if (opts.bundle !== void 0) {
|
|
3051
|
+
const payload = JSON.stringify(JSON.stringify(opts.bundle));
|
|
3052
|
+
await cdp.send(
|
|
3053
|
+
"Page.addScriptToEvaluateOnNewDocument",
|
|
3054
|
+
{
|
|
3055
|
+
source: `globalThis.__mcpUsePreviewBundle = JSON.parse(${payload});`,
|
|
3056
|
+
runImmediately: true
|
|
3057
|
+
},
|
|
3058
|
+
sessionId
|
|
2759
3059
|
);
|
|
2760
|
-
|
|
2761
|
-
|
|
3060
|
+
}
|
|
3061
|
+
await cdp.send("Page.navigate", { url: opts.url }, sessionId);
|
|
3062
|
+
const start = Date.now();
|
|
3063
|
+
const exprSelector = JSON.stringify(opts.waitForSelector);
|
|
3064
|
+
while (true) {
|
|
3065
|
+
const r = await cdp.send(
|
|
3066
|
+
"Runtime.evaluate",
|
|
3067
|
+
{
|
|
3068
|
+
expression: `!!document.querySelector(${exprSelector})`,
|
|
3069
|
+
returnByValue: true
|
|
3070
|
+
},
|
|
3071
|
+
sessionId
|
|
2762
3072
|
);
|
|
2763
|
-
|
|
3073
|
+
if (r.result?.value === true) break;
|
|
3074
|
+
if (Date.now() - start > opts.timeoutMs) {
|
|
3075
|
+
throw new Error(
|
|
3076
|
+
`Timed out after ${opts.timeoutMs}ms waiting for selector "${opts.waitForSelector}"`
|
|
3077
|
+
);
|
|
3078
|
+
}
|
|
3079
|
+
await new Promise((res) => setTimeout(res, 100));
|
|
2764
3080
|
}
|
|
2765
|
-
|
|
3081
|
+
if (opts.delayMs && opts.delayMs > 0) {
|
|
3082
|
+
await new Promise((res) => setTimeout(res, opts.delayMs));
|
|
3083
|
+
}
|
|
3084
|
+
const shot = await cdp.send(
|
|
3085
|
+
"Page.captureScreenshot",
|
|
3086
|
+
{
|
|
3087
|
+
format: "png",
|
|
3088
|
+
clip: {
|
|
3089
|
+
x: 0,
|
|
3090
|
+
y: 0,
|
|
3091
|
+
width: opts.width,
|
|
3092
|
+
height: opts.height,
|
|
3093
|
+
scale: 1
|
|
3094
|
+
}
|
|
3095
|
+
},
|
|
3096
|
+
sessionId
|
|
3097
|
+
);
|
|
3098
|
+
(0, import_node_fs6.writeFileSync)(opts.outputPath, Buffer.from(shot.data, "base64"));
|
|
3099
|
+
} finally {
|
|
3100
|
+
cleanup();
|
|
2766
3101
|
}
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
3102
|
+
}
|
|
3103
|
+
|
|
3104
|
+
// src/utils/chrome-path.ts
|
|
3105
|
+
init_cjs_shims();
|
|
3106
|
+
var import_node_fs7 = require("fs");
|
|
3107
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
3108
|
+
var ENV_VAR_NAMES = [
|
|
3109
|
+
"MCP_USE_CHROME_PATH",
|
|
3110
|
+
"PUPPETEER_EXECUTABLE_PATH",
|
|
3111
|
+
"CHROME_PATH"
|
|
3112
|
+
];
|
|
3113
|
+
var DARWIN_PATHS = [
|
|
3114
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
3115
|
+
"/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",
|
|
3116
|
+
"/Applications/Chromium.app/Contents/MacOS/Chromium",
|
|
3117
|
+
"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
|
|
3118
|
+
"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"
|
|
3119
|
+
];
|
|
3120
|
+
var LINUX_BINARIES = [
|
|
3121
|
+
"google-chrome-stable",
|
|
3122
|
+
"google-chrome",
|
|
3123
|
+
"chromium",
|
|
3124
|
+
"chromium-browser",
|
|
3125
|
+
"microsoft-edge",
|
|
3126
|
+
"microsoft-edge-stable",
|
|
3127
|
+
"brave-browser"
|
|
3128
|
+
];
|
|
3129
|
+
var WIN_SUBPATHS = [
|
|
3130
|
+
"Google\\Chrome\\Application\\chrome.exe",
|
|
3131
|
+
"Microsoft\\Edge\\Application\\msedge.exe",
|
|
3132
|
+
"BraveSoftware\\Brave-Browser\\Application\\brave.exe",
|
|
3133
|
+
"Chromium\\Application\\chrome.exe"
|
|
3134
|
+
];
|
|
3135
|
+
function isAccessible(p) {
|
|
3136
|
+
try {
|
|
3137
|
+
(0, import_node_fs7.accessSync)(p, import_node_fs7.constants.F_OK);
|
|
3138
|
+
return true;
|
|
3139
|
+
} catch {
|
|
3140
|
+
return false;
|
|
2770
3141
|
}
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
3142
|
+
}
|
|
3143
|
+
function findOnPath(binary) {
|
|
3144
|
+
const PATH = process.env.PATH ?? "";
|
|
3145
|
+
for (const dir of PATH.split(":")) {
|
|
3146
|
+
if (!dir) continue;
|
|
3147
|
+
const candidate = import_node_path5.default.posix.join(dir, binary);
|
|
3148
|
+
if (isAccessible(candidate)) return candidate;
|
|
3149
|
+
}
|
|
3150
|
+
return null;
|
|
3151
|
+
}
|
|
3152
|
+
function findChrome() {
|
|
3153
|
+
for (const name of ENV_VAR_NAMES) {
|
|
3154
|
+
const v = process.env[name];
|
|
3155
|
+
if (v && isAccessible(v)) return v;
|
|
3156
|
+
}
|
|
3157
|
+
if (process.platform === "darwin") {
|
|
3158
|
+
for (const p of DARWIN_PATHS) {
|
|
3159
|
+
if (isAccessible(p)) return p;
|
|
3160
|
+
}
|
|
3161
|
+
return null;
|
|
3162
|
+
}
|
|
3163
|
+
if (process.platform === "linux") {
|
|
3164
|
+
for (const bin of LINUX_BINARIES) {
|
|
3165
|
+
const p = findOnPath(bin);
|
|
3166
|
+
if (p) return p;
|
|
3167
|
+
}
|
|
2774
3168
|
return null;
|
|
2775
3169
|
}
|
|
3170
|
+
if (process.platform === "win32") {
|
|
3171
|
+
const dirs = [
|
|
3172
|
+
process.env["ProgramFiles"],
|
|
3173
|
+
process.env["ProgramFiles(x86)"],
|
|
3174
|
+
process.env["LocalAppData"]
|
|
3175
|
+
].filter((d) => Boolean(d));
|
|
3176
|
+
for (const dir of dirs) {
|
|
3177
|
+
for (const sub of WIN_SUBPATHS) {
|
|
3178
|
+
const candidate = import_node_path5.default.join(dir, sub);
|
|
3179
|
+
if (isAccessible(candidate)) return candidate;
|
|
3180
|
+
}
|
|
3181
|
+
}
|
|
3182
|
+
return null;
|
|
3183
|
+
}
|
|
3184
|
+
return null;
|
|
3185
|
+
}
|
|
3186
|
+
function resolveChromePath() {
|
|
3187
|
+
const found = findChrome();
|
|
3188
|
+
if (found) return found;
|
|
3189
|
+
throw new Error(
|
|
3190
|
+
"Could not find Chrome, Chromium, Edge, or Brave on this system. Install Chrome from https://google.com/chrome, or set MCP_USE_CHROME_PATH (or PUPPETEER_EXECUTABLE_PATH / CHROME_PATH) to a browser executable."
|
|
3191
|
+
);
|
|
3192
|
+
}
|
|
3193
|
+
|
|
3194
|
+
// src/commands/screenshot.ts
|
|
3195
|
+
function detectToolResourceUri(tool) {
|
|
3196
|
+
if (!tool) return null;
|
|
3197
|
+
const meta = tool._meta;
|
|
3198
|
+
if (!meta) return null;
|
|
3199
|
+
const uiMeta = meta.ui ?? void 0;
|
|
3200
|
+
return uiMeta?.resourceUri ?? meta["openai/outputTemplate"] ?? null;
|
|
3201
|
+
}
|
|
3202
|
+
async function captureToolScreenshot(inputs, options = {}) {
|
|
3203
|
+
const width = options.width ?? 800;
|
|
3204
|
+
const height = options.height ?? 600;
|
|
3205
|
+
const theme = options.theme ?? "light";
|
|
3206
|
+
const timeoutMs = options.timeoutMs ?? 3e4;
|
|
3207
|
+
const delayMs = options.delayMs ?? 0;
|
|
3208
|
+
const chromePath = resolveChromePath();
|
|
3209
|
+
const view = extractViewName(inputs.resourceUri);
|
|
3210
|
+
const devOptions = {
|
|
3211
|
+
width: String(width),
|
|
3212
|
+
height: String(height),
|
|
3213
|
+
theme,
|
|
3214
|
+
timeout: String(timeoutMs),
|
|
3215
|
+
inspector: options.inspector,
|
|
3216
|
+
quiet: options.quiet
|
|
3217
|
+
};
|
|
3218
|
+
let devHandle;
|
|
2776
3219
|
try {
|
|
2777
|
-
|
|
2778
|
-
const
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
3220
|
+
devHandle = await ensureDevServer(devOptions);
|
|
3221
|
+
const resourceContents = await inputs.session.readResource(
|
|
3222
|
+
inputs.resourceUri
|
|
3223
|
+
);
|
|
3224
|
+
const bundle = {
|
|
3225
|
+
resourceUri: inputs.resourceUri,
|
|
3226
|
+
resourceContents,
|
|
3227
|
+
toolInput: inputs.toolArgs,
|
|
3228
|
+
toolOutput: inputs.toolOutput
|
|
3229
|
+
};
|
|
3230
|
+
const previewUrl = new URL(`/inspector/preview/${view}`, devHandle.url);
|
|
3231
|
+
previewUrl.searchParams.set("theme", theme);
|
|
3232
|
+
const ts = timestampSuffix();
|
|
3233
|
+
const outputPath = import_node_path6.default.resolve(options.output ?? `./${view}-${ts}.png`);
|
|
3234
|
+
await (0, import_promises5.mkdir)(import_node_path6.default.dirname(outputPath), { recursive: true });
|
|
3235
|
+
await captureScreenshot({
|
|
3236
|
+
url: previewUrl.toString(),
|
|
3237
|
+
width,
|
|
3238
|
+
height,
|
|
3239
|
+
theme,
|
|
3240
|
+
waitForSelector: options.waitFor ?? 'body[data-view-ready="true"]',
|
|
3241
|
+
timeoutMs,
|
|
3242
|
+
outputPath,
|
|
3243
|
+
chromePath,
|
|
3244
|
+
delayMs: Number.isFinite(delayMs) && delayMs > 0 ? delayMs : 0,
|
|
3245
|
+
bundle
|
|
3246
|
+
});
|
|
3247
|
+
return { outputPath, width, height, view };
|
|
3248
|
+
} finally {
|
|
3249
|
+
killChild(devHandle?.child);
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
function getFreePort() {
|
|
3253
|
+
return new Promise((resolve2, reject) => {
|
|
3254
|
+
const srv = (0, import_node_net.createServer)();
|
|
3255
|
+
srv.unref();
|
|
3256
|
+
srv.on("error", reject);
|
|
3257
|
+
srv.listen(0, () => {
|
|
3258
|
+
const addr = srv.address();
|
|
3259
|
+
if (typeof addr === "object" && addr) {
|
|
3260
|
+
const port = addr.port;
|
|
3261
|
+
srv.close(() => resolve2(port));
|
|
2788
3262
|
} else {
|
|
2789
|
-
|
|
2790
|
-
url: config.url,
|
|
2791
|
-
headers: config.authToken ? { Authorization: `Bearer ${config.authToken}` } : void 0,
|
|
2792
|
-
clientInfo: cliClientInfo
|
|
2793
|
-
});
|
|
3263
|
+
srv.close(() => reject(new Error("Failed to allocate free port")));
|
|
2794
3264
|
}
|
|
2795
|
-
}
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
3265
|
+
});
|
|
3266
|
+
});
|
|
3267
|
+
}
|
|
3268
|
+
async function probeServer(url, timeoutMs = 1500) {
|
|
3269
|
+
const controller = new AbortController();
|
|
3270
|
+
const t = setTimeout(() => controller.abort(), timeoutMs);
|
|
3271
|
+
try {
|
|
3272
|
+
const u = new URL("/inspector/health", url);
|
|
3273
|
+
const res = await fetch(u, { signal: controller.signal });
|
|
3274
|
+
if (!res.ok) return false;
|
|
3275
|
+
const ct = res.headers.get("content-type") ?? "";
|
|
3276
|
+
if (!ct.includes("application/json")) return false;
|
|
3277
|
+
const body = await res.json();
|
|
3278
|
+
return body?.status === "ok";
|
|
3279
|
+
} catch {
|
|
3280
|
+
return false;
|
|
3281
|
+
} finally {
|
|
3282
|
+
clearTimeout(t);
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
async function waitForHealth(url, timeoutMs = 15e3) {
|
|
3286
|
+
const deadline = Date.now() + timeoutMs;
|
|
3287
|
+
while (Date.now() < deadline) {
|
|
3288
|
+
if (await probeServer(url)) return true;
|
|
3289
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
3290
|
+
}
|
|
3291
|
+
return false;
|
|
3292
|
+
}
|
|
3293
|
+
function resolveInspectorCli() {
|
|
3294
|
+
const candidateRoots = /* @__PURE__ */ new Set();
|
|
3295
|
+
const moduleDir = typeof __dirname !== "undefined" ? __dirname : import_node_path6.default.dirname(new URL(importMetaUrl).pathname);
|
|
3296
|
+
candidateRoots.add(moduleDir);
|
|
3297
|
+
candidateRoots.add(process.cwd());
|
|
3298
|
+
for (const start of candidateRoots) {
|
|
3299
|
+
let dir = start;
|
|
3300
|
+
while (true) {
|
|
3301
|
+
const candidate = import_node_path6.default.join(
|
|
3302
|
+
dir,
|
|
3303
|
+
"node_modules",
|
|
3304
|
+
"@mcp-use",
|
|
3305
|
+
"inspector",
|
|
3306
|
+
"dist",
|
|
3307
|
+
"cli.js"
|
|
3308
|
+
);
|
|
3309
|
+
if ((0, import_node_fs8.existsSync)(candidate)) return candidate;
|
|
3310
|
+
const parent = import_node_path6.default.dirname(dir);
|
|
3311
|
+
if (parent === dir) break;
|
|
3312
|
+
dir = parent;
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
throw new Error(
|
|
3316
|
+
"Could not locate `@mcp-use/inspector` in node_modules. Install the inspector package or pass --inspector <url> to use an existing instance."
|
|
3317
|
+
);
|
|
3318
|
+
}
|
|
3319
|
+
async function ensureDevServer(options) {
|
|
3320
|
+
if (options.inspector) {
|
|
3321
|
+
const ok = await probeServer(options.inspector);
|
|
3322
|
+
if (!ok) {
|
|
3323
|
+
throw new Error(
|
|
3324
|
+
`Inspector at ${options.inspector} did not respond on /inspector/health with status:"ok"`
|
|
3325
|
+
);
|
|
3326
|
+
}
|
|
3327
|
+
return { url: options.inspector };
|
|
3328
|
+
}
|
|
3329
|
+
const port = await getFreePort();
|
|
3330
|
+
const url = `http://localhost:${port}`;
|
|
3331
|
+
if (!options.quiet) {
|
|
3332
|
+
console.error(formatInfo(`Starting inspector on port ${port}\u2026`));
|
|
3333
|
+
}
|
|
3334
|
+
const inspectorCli = resolveInspectorCli();
|
|
3335
|
+
const child = (0, import_node_child_process9.spawn)(
|
|
3336
|
+
process.execPath,
|
|
3337
|
+
[inspectorCli, "--port", String(port), "--no-open"],
|
|
3338
|
+
{
|
|
3339
|
+
cwd: process.cwd(),
|
|
3340
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
3341
|
+
env: { ...process.env, MCP_INSPECTOR_MODE: "standalone" }
|
|
3342
|
+
}
|
|
3343
|
+
);
|
|
3344
|
+
const prefix = source_default.gray("[inspector]");
|
|
3345
|
+
if (!options.quiet) {
|
|
3346
|
+
child.stdout?.on("data", (d) => {
|
|
3347
|
+
process.stderr.write(`${prefix} ${d}`);
|
|
3348
|
+
});
|
|
3349
|
+
child.stderr?.on("data", (d) => {
|
|
3350
|
+
process.stderr.write(`${prefix} ${d}`);
|
|
3351
|
+
});
|
|
3352
|
+
} else {
|
|
3353
|
+
child.stdout?.resume();
|
|
3354
|
+
child.stderr?.resume();
|
|
3355
|
+
}
|
|
3356
|
+
const ready = await waitForHealth(url);
|
|
3357
|
+
if (!ready) {
|
|
3358
|
+
child.kill("SIGTERM");
|
|
3359
|
+
throw new Error(`Inspector failed to come up on ${url} within 15s.`);
|
|
3360
|
+
}
|
|
3361
|
+
return { url, child };
|
|
3362
|
+
}
|
|
3363
|
+
function killChild(child) {
|
|
3364
|
+
if (!child || child.killed) return;
|
|
3365
|
+
try {
|
|
3366
|
+
child.kill("SIGTERM");
|
|
3367
|
+
} catch {
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
function timestampSuffix(date = /* @__PURE__ */ new Date()) {
|
|
3371
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
3372
|
+
const datePart = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
3373
|
+
const timePart = `${pad(date.getHours())}-${pad(date.getMinutes())}-${pad(date.getSeconds())}`;
|
|
3374
|
+
return `${datePart}_${timePart}`;
|
|
3375
|
+
}
|
|
3376
|
+
function extractViewName(resourceUri) {
|
|
3377
|
+
const m = resourceUri.match(/^ui:\/\/widget\/(.+)$/);
|
|
3378
|
+
if (!m) return resourceUri;
|
|
3379
|
+
return m[1].replace(/\.html$/, "").replace(/\.[0-9a-f]+$/i, "");
|
|
3380
|
+
}
|
|
3381
|
+
function parseDimension(raw, name) {
|
|
3382
|
+
const n = parseInt(raw, 10);
|
|
3383
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
3384
|
+
throw new Error(`--${name} must be a positive integer (got "${raw}")`);
|
|
3385
|
+
}
|
|
3386
|
+
return n;
|
|
3387
|
+
}
|
|
3388
|
+
var AD_HOC_SESSION_NAME = "__screenshot_ad_hoc__";
|
|
3389
|
+
async function resolveSessionForScreenshot(options) {
|
|
3390
|
+
if (options.session) {
|
|
3391
|
+
const result2 = await getOrRestoreSession(options.session);
|
|
3392
|
+
return result2?.session ?? null;
|
|
3393
|
+
}
|
|
3394
|
+
if (options.mcp) {
|
|
3395
|
+
const client = new import_client2.MCPClient();
|
|
3396
|
+
client.addServer(AD_HOC_SESSION_NAME, {
|
|
3397
|
+
url: options.mcp,
|
|
3398
|
+
clientInfo: getCliClientInfo()
|
|
3399
|
+
});
|
|
3400
|
+
try {
|
|
3401
|
+
const session = await client.createSession(AD_HOC_SESSION_NAME);
|
|
3402
|
+
activeSessions.set(AD_HOC_SESSION_NAME, { client, session });
|
|
3403
|
+
return session;
|
|
3404
|
+
} catch (err) {
|
|
3405
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3406
|
+
console.error(formatError(`Failed to connect to ${options.mcp}: ${msg}`));
|
|
2804
3407
|
return null;
|
|
2805
3408
|
}
|
|
2806
|
-
|
|
3409
|
+
}
|
|
3410
|
+
const result = await getOrRestoreSession(null);
|
|
3411
|
+
return result?.session ?? null;
|
|
3412
|
+
}
|
|
3413
|
+
async function screenshotCommand(options, argsList) {
|
|
3414
|
+
let exitCode = 0;
|
|
3415
|
+
try {
|
|
3416
|
+
if (!options.tool) {
|
|
3417
|
+
console.error(
|
|
3418
|
+
formatError(
|
|
3419
|
+
"--tool <name> is required (optionally with key=value args)."
|
|
3420
|
+
)
|
|
3421
|
+
);
|
|
3422
|
+
exitCode = 1;
|
|
3423
|
+
return;
|
|
3424
|
+
}
|
|
2807
3425
|
try {
|
|
2808
|
-
|
|
3426
|
+
resolveChromePath();
|
|
2809
3427
|
} catch (err) {
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
3428
|
+
console.error(
|
|
3429
|
+
formatError(err instanceof Error ? err.message : String(err))
|
|
3430
|
+
);
|
|
3431
|
+
exitCode = 1;
|
|
3432
|
+
return;
|
|
3433
|
+
}
|
|
3434
|
+
const width = parseDimension(options.width, "width");
|
|
3435
|
+
const height = parseDimension(options.height, "height");
|
|
3436
|
+
const navTimeout = parseInt(options.timeout, 10) || 3e4;
|
|
3437
|
+
const delayMs = options.delay ? parseInt(options.delay, 10) : 0;
|
|
3438
|
+
const session = await resolveSessionForScreenshot(options);
|
|
3439
|
+
if (!session) {
|
|
3440
|
+
exitCode = 1;
|
|
3441
|
+
return;
|
|
3442
|
+
}
|
|
3443
|
+
const tool = session.tools.find((t) => t.name === options.tool);
|
|
3444
|
+
if (!tool) {
|
|
3445
|
+
throw new Error(
|
|
3446
|
+
`Tool "${options.tool}" not found. Available: ${session.tools.map((t) => t.name).join(", ")}`
|
|
3447
|
+
);
|
|
3448
|
+
}
|
|
3449
|
+
const resourceUri = detectToolResourceUri(tool);
|
|
3450
|
+
if (!resourceUri) {
|
|
3451
|
+
throw new Error(
|
|
3452
|
+
`Tool "${options.tool}" does not declare a UI resource (expected _meta.ui.resourceUri or openai/outputTemplate).`
|
|
3453
|
+
);
|
|
3454
|
+
}
|
|
3455
|
+
let toolArgs = {};
|
|
3456
|
+
if (argsList && argsList.length > 0) {
|
|
3457
|
+
try {
|
|
3458
|
+
toolArgs = parseToolArgs(
|
|
3459
|
+
argsList,
|
|
3460
|
+
tool.inputSchema
|
|
2814
3461
|
);
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
3462
|
+
} catch (err) {
|
|
3463
|
+
console.error(
|
|
3464
|
+
formatError(err instanceof Error ? err.message : String(err))
|
|
3465
|
+
);
|
|
3466
|
+
console.log("");
|
|
3467
|
+
console.log(formatInfo("Usage:"));
|
|
3468
|
+
console.log(
|
|
3469
|
+
` npx mcp-use screenshot --tool ${options.tool} key=value [key2=value2 ...]`
|
|
3470
|
+
);
|
|
3471
|
+
console.log(
|
|
3472
|
+
` npx mcp-use screenshot --tool ${options.tool} nested:='{"a":1}' # JSON value`
|
|
3473
|
+
);
|
|
3474
|
+
console.log(
|
|
3475
|
+
` npx mcp-use screenshot --tool ${options.tool} '{"key":"value"}' # full JSON object`
|
|
3476
|
+
);
|
|
3477
|
+
if (tool.inputSchema) {
|
|
3478
|
+
console.log("");
|
|
3479
|
+
console.log(formatInfo("Tool schema:"));
|
|
3480
|
+
console.log(formatSchema(tool.inputSchema));
|
|
2823
3481
|
}
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
} else {
|
|
2827
|
-
throw err;
|
|
3482
|
+
exitCode = 1;
|
|
3483
|
+
return;
|
|
2828
3484
|
}
|
|
2829
3485
|
}
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
return { name: sessionName, session };
|
|
2833
|
-
} catch (error) {
|
|
2834
|
-
console.error(formatError(`Failed to restore session: ${error.message}`));
|
|
2835
|
-
return null;
|
|
2836
|
-
}
|
|
2837
|
-
}
|
|
2838
|
-
function getCliClientInfo() {
|
|
2839
|
-
return {
|
|
2840
|
-
name: "mcp-use CLI",
|
|
2841
|
-
title: "mcp-use CLI",
|
|
2842
|
-
version: (0, import_server.getPackageVersion)(),
|
|
2843
|
-
description: "mcp-use CLI - Command-line interface for MCP servers",
|
|
2844
|
-
icons: [
|
|
3486
|
+
const toolOutput = await session.callTool(options.tool, toolArgs);
|
|
3487
|
+
const result = await captureToolScreenshot(
|
|
2845
3488
|
{
|
|
2846
|
-
|
|
3489
|
+
session,
|
|
3490
|
+
toolName: options.tool,
|
|
3491
|
+
toolArgs,
|
|
3492
|
+
toolOutput,
|
|
3493
|
+
resourceUri
|
|
3494
|
+
},
|
|
3495
|
+
{
|
|
3496
|
+
width,
|
|
3497
|
+
height,
|
|
3498
|
+
theme: options.theme,
|
|
3499
|
+
output: options.output,
|
|
3500
|
+
waitFor: options.waitFor,
|
|
3501
|
+
delayMs,
|
|
3502
|
+
timeoutMs: navTimeout,
|
|
3503
|
+
inspector: options.inspector,
|
|
3504
|
+
quiet: options.quiet
|
|
2847
3505
|
}
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
3506
|
+
);
|
|
3507
|
+
console.log(
|
|
3508
|
+
`Saved screenshot: ${result.outputPath} (${result.width}\xD7${result.height})`
|
|
3509
|
+
);
|
|
3510
|
+
} catch (err) {
|
|
3511
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3512
|
+
console.error(formatError(`Screenshot failed: ${msg}`));
|
|
3513
|
+
exitCode = 1;
|
|
3514
|
+
} finally {
|
|
3515
|
+
await cleanupAndExit(exitCode);
|
|
3516
|
+
}
|
|
2851
3517
|
}
|
|
3518
|
+
function createScreenshotCommand() {
|
|
3519
|
+
return new import_commander.Command("screenshot").description(
|
|
3520
|
+
"Render an MCP Apps view headlessly and save a PNG by calling a tool and rendering its UI resource with the result."
|
|
3521
|
+
).argument(
|
|
3522
|
+
"[args...]",
|
|
3523
|
+
"Tool args as key=value pairs (use key:=<json> for nested values, or pass a single JSON object)."
|
|
3524
|
+
).option(
|
|
3525
|
+
"--tool <name>",
|
|
3526
|
+
"Tool to call. Its UI resource is rendered with the result."
|
|
3527
|
+
).option("--width <px>", "Browser viewport width in pixels.", "800").option("--height <px>", "Browser viewport height in pixels.", "600").option(
|
|
3528
|
+
"--inspector <url>",
|
|
3529
|
+
"Inspector host that serves /inspector/preview/:view. When omitted, probes localhost:3000 then auto-spawns `mcp-use dev`."
|
|
3530
|
+
).option(
|
|
3531
|
+
"--session <name>",
|
|
3532
|
+
"Saved session name (from `mcp-use client connect`). Defaults to the active session."
|
|
3533
|
+
).option(
|
|
3534
|
+
"--mcp <url>",
|
|
3535
|
+
"Ad-hoc MCP server URL (escape hatch). Used only when no --session and no active saved session. No authentication."
|
|
3536
|
+
).option(
|
|
3537
|
+
"--theme <light|dark>",
|
|
3538
|
+
"Color scheme to render the view in.",
|
|
3539
|
+
"light"
|
|
3540
|
+
).option(
|
|
3541
|
+
"--output <path>",
|
|
3542
|
+
"Output PNG path. Defaults to ./<view>-<timestamp>.png in cwd."
|
|
3543
|
+
).option(
|
|
3544
|
+
"--wait-for <selector>",
|
|
3545
|
+
'Override readiness selector (default: body[data-view-ready="true"]).'
|
|
3546
|
+
).option(
|
|
3547
|
+
"--delay <ms>",
|
|
3548
|
+
"Extra wait after readiness, to let chart animations / async layouts settle.",
|
|
3549
|
+
"0"
|
|
3550
|
+
).option("--timeout <ms>", "Navigation + readiness timeout in ms.", "30000").option("--quiet", "Suppress dev-server output.").action(async (args, opts) => {
|
|
3551
|
+
await screenshotCommand(opts, args);
|
|
3552
|
+
});
|
|
3553
|
+
}
|
|
3554
|
+
|
|
3555
|
+
// src/commands/client.ts
|
|
2852
3556
|
async function connectCommand(urlOrCommand, options) {
|
|
2853
3557
|
try {
|
|
2854
3558
|
const sessionName = options.name || `session-${Date.now()}`;
|
|
2855
|
-
const client = new
|
|
3559
|
+
const client = new import_client3.MCPClient();
|
|
2856
3560
|
let session;
|
|
2857
3561
|
const cliClientInfo = getCliClientInfo();
|
|
2858
3562
|
if (options.stdio) {
|
|
@@ -3169,11 +3873,54 @@ async function callToolCommand(toolName, argsList, options) {
|
|
|
3169
3873
|
const callResult = await session.callTool(toolName, args, {
|
|
3170
3874
|
timeout: options?.timeout
|
|
3171
3875
|
});
|
|
3876
|
+
let screenshot = null;
|
|
3877
|
+
let screenshotError = null;
|
|
3878
|
+
if (options?.screenshot !== false) {
|
|
3879
|
+
const tool2 = session.tools.find((t) => t.name === toolName);
|
|
3880
|
+
const resourceUri = detectToolResourceUri(tool2);
|
|
3881
|
+
if (resourceUri) {
|
|
3882
|
+
console.error(
|
|
3883
|
+
formatInfo(`Capturing widget screenshot (${resourceUri})...`)
|
|
3884
|
+
);
|
|
3885
|
+
try {
|
|
3886
|
+
const shot = await captureToolScreenshot(
|
|
3887
|
+
{
|
|
3888
|
+
session,
|
|
3889
|
+
toolName,
|
|
3890
|
+
toolArgs: args,
|
|
3891
|
+
toolOutput: callResult,
|
|
3892
|
+
resourceUri
|
|
3893
|
+
},
|
|
3894
|
+
options?.screenshotOutput ? { output: options.screenshotOutput } : {}
|
|
3895
|
+
);
|
|
3896
|
+
screenshot = {
|
|
3897
|
+
path: shot.outputPath,
|
|
3898
|
+
width: shot.width,
|
|
3899
|
+
height: shot.height,
|
|
3900
|
+
view: shot.view
|
|
3901
|
+
};
|
|
3902
|
+
} catch (err) {
|
|
3903
|
+
screenshotError = err?.message ?? String(err);
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
}
|
|
3172
3907
|
if (options?.json) {
|
|
3173
3908
|
console.log(formatJson(callResult));
|
|
3174
3909
|
} else {
|
|
3175
3910
|
console.log(formatToolCall(callResult));
|
|
3176
3911
|
}
|
|
3912
|
+
if (screenshot) {
|
|
3913
|
+
console.error(
|
|
3914
|
+
formatSuccess(
|
|
3915
|
+
`Saved widget screenshot: ${screenshot.path} (${screenshot.width}\xD7${screenshot.height})`
|
|
3916
|
+
)
|
|
3917
|
+
);
|
|
3918
|
+
}
|
|
3919
|
+
if (screenshotError) {
|
|
3920
|
+
console.error(
|
|
3921
|
+
formatWarning(`Skipped widget screenshot: ${screenshotError}`)
|
|
3922
|
+
);
|
|
3923
|
+
}
|
|
3177
3924
|
if (callResult.isError) {
|
|
3178
3925
|
await cleanupAndExit(1);
|
|
3179
3926
|
}
|
|
@@ -3567,7 +4314,7 @@ async function interactiveCommand(options) {
|
|
|
3567
4314
|
}
|
|
3568
4315
|
}
|
|
3569
4316
|
function createClientCommand() {
|
|
3570
|
-
const clientCommand = new
|
|
4317
|
+
const clientCommand = new import_commander2.Command("client").description(
|
|
3571
4318
|
"Interactive MCP client for terminal usage"
|
|
3572
4319
|
);
|
|
3573
4320
|
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>", "Static Bearer token (skips OAuth)").option(
|
|
@@ -3578,22 +4325,28 @@ function createClientCommand() {
|
|
|
3578
4325
|
"OAuth loopback wait timeout in ms (default 300000)"
|
|
3579
4326
|
).action(connectCommand);
|
|
3580
4327
|
clientCommand.command("disconnect [session]").description("Disconnect from a session").option("--all", "Disconnect all sessions").action(disconnectCommand);
|
|
3581
|
-
const sessionsCommand = new
|
|
4328
|
+
const sessionsCommand = new import_commander2.Command("sessions").description(
|
|
3582
4329
|
"Manage CLI sessions"
|
|
3583
4330
|
);
|
|
3584
4331
|
sessionsCommand.command("list").description("List all saved sessions").action(listSessionsCommand);
|
|
3585
4332
|
sessionsCommand.command("switch <name>").description("Switch to a different session").action(switchSessionCommand);
|
|
3586
4333
|
clientCommand.addCommand(sessionsCommand);
|
|
3587
|
-
const toolsCommand = new
|
|
4334
|
+
const toolsCommand = new import_commander2.Command("tools").description(
|
|
3588
4335
|
"Interact with MCP tools"
|
|
3589
4336
|
);
|
|
3590
4337
|
toolsCommand.command("list").description("List available tools").option("--session <name>", "Use specific session").option("--json", "Output as JSON").action(listToolsCommand);
|
|
3591
4338
|
toolsCommand.command("call <name> [args...]").description(
|
|
3592
4339
|
"Call a tool. Args as key=value pairs (use key:=<json> for nested values, or pass a JSON object)"
|
|
3593
|
-
).option("--session <name>", "Use specific session").option("--timeout <ms>", "Request timeout in milliseconds", parseInt).option("--json", "Output as JSON").
|
|
4340
|
+
).option("--session <name>", "Use specific session").option("--timeout <ms>", "Request timeout in milliseconds", parseInt).option("--json", "Output as JSON").option(
|
|
4341
|
+
"--no-screenshot",
|
|
4342
|
+
"Skip the auto-screenshot for tools that render a widget"
|
|
4343
|
+
).option(
|
|
4344
|
+
"--screenshot-output <path>",
|
|
4345
|
+
"Output PNG path for the widget screenshot (defaults to ./<view>-<timestamp>.png)"
|
|
4346
|
+
).action((name, args, opts) => callToolCommand(name, args, opts));
|
|
3594
4347
|
toolsCommand.command("describe <name>").description("Show tool details and schema").option("--session <name>", "Use specific session").action(describeToolCommand);
|
|
3595
4348
|
clientCommand.addCommand(toolsCommand);
|
|
3596
|
-
const resourcesCommand = new
|
|
4349
|
+
const resourcesCommand = new import_commander2.Command("resources").description(
|
|
3597
4350
|
"Interact with MCP resources"
|
|
3598
4351
|
);
|
|
3599
4352
|
resourcesCommand.command("list").description("List available resources").option("--session <name>", "Use specific session").option("--json", "Output as JSON").action(listResourcesCommand);
|
|
@@ -3601,7 +4354,7 @@ function createClientCommand() {
|
|
|
3601
4354
|
resourcesCommand.command("subscribe <uri>").description("Subscribe to resource updates").option("--session <name>", "Use specific session").action(subscribeResourceCommand);
|
|
3602
4355
|
resourcesCommand.command("unsubscribe <uri>").description("Unsubscribe from resource updates").option("--session <name>", "Use specific session").action(unsubscribeResourceCommand);
|
|
3603
4356
|
clientCommand.addCommand(resourcesCommand);
|
|
3604
|
-
const promptsCommand = new
|
|
4357
|
+
const promptsCommand = new import_commander2.Command("prompts").description(
|
|
3605
4358
|
"Interact with MCP prompts"
|
|
3606
4359
|
);
|
|
3607
4360
|
promptsCommand.command("list").description("List available prompts").option("--session <name>", "Use specific session").option("--json", "Output as JSON").action(listPromptsCommand);
|
|
@@ -3610,7 +4363,7 @@ function createClientCommand() {
|
|
|
3610
4363
|
).option("--session <name>", "Use specific session").option("--json", "Output as JSON").action(getPromptCommand);
|
|
3611
4364
|
clientCommand.addCommand(promptsCommand);
|
|
3612
4365
|
clientCommand.command("interactive").description("Start interactive REPL mode").option("--session <name>", "Use specific session").action(interactiveCommand);
|
|
3613
|
-
const authCommand = new
|
|
4366
|
+
const authCommand = new import_commander2.Command("auth").description(
|
|
3614
4367
|
"Manage OAuth tokens for HTTP sessions"
|
|
3615
4368
|
);
|
|
3616
4369
|
authCommand.command("status [session]").description("Show OAuth token status for a session").action(authStatusCommand);
|
|
@@ -3622,15 +4375,15 @@ function createClientCommand() {
|
|
|
3622
4375
|
|
|
3623
4376
|
// src/commands/deploy.ts
|
|
3624
4377
|
init_cjs_shims();
|
|
3625
|
-
var
|
|
3626
|
-
var
|
|
4378
|
+
var import_node_fs10 = require("fs");
|
|
4379
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
3627
4380
|
init_open();
|
|
3628
4381
|
|
|
3629
4382
|
// src/utils/git.ts
|
|
3630
4383
|
init_cjs_shims();
|
|
3631
|
-
var
|
|
4384
|
+
var import_node_child_process10 = require("child_process");
|
|
3632
4385
|
var import_node_util7 = require("util");
|
|
3633
|
-
var execFileAsync5 = (0, import_node_util7.promisify)(
|
|
4386
|
+
var execFileAsync5 = (0, import_node_util7.promisify)(import_node_child_process10.execFile);
|
|
3634
4387
|
async function gitCommand(args, cwd = process.cwd()) {
|
|
3635
4388
|
try {
|
|
3636
4389
|
const { stdout } = await execFileAsync5("git", args, { cwd });
|
|
@@ -3781,17 +4534,17 @@ function getMcpServerUrlForCloudServer(server) {
|
|
|
3781
4534
|
|
|
3782
4535
|
// src/utils/project-link.ts
|
|
3783
4536
|
init_cjs_shims();
|
|
3784
|
-
var
|
|
3785
|
-
var
|
|
4537
|
+
var import_node_fs9 = require("fs");
|
|
4538
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
3786
4539
|
var MCP_USE_DIR = ".mcp-use";
|
|
3787
4540
|
var MCP_USE_DIR_PROJECT = "project.json";
|
|
3788
4541
|
function getMcpUseDirectory(cwd) {
|
|
3789
|
-
return
|
|
4542
|
+
return import_node_path7.default.join(cwd, MCP_USE_DIR);
|
|
3790
4543
|
}
|
|
3791
4544
|
async function getProjectLink(cwd) {
|
|
3792
4545
|
try {
|
|
3793
|
-
const linkPath =
|
|
3794
|
-
const content = await
|
|
4546
|
+
const linkPath = import_node_path7.default.join(getMcpUseDirectory(cwd), MCP_USE_DIR_PROJECT);
|
|
4547
|
+
const content = await import_node_fs9.promises.readFile(linkPath, "utf-8");
|
|
3795
4548
|
return JSON.parse(content);
|
|
3796
4549
|
} catch (err) {
|
|
3797
4550
|
if (err.code === "ENOENT") return null;
|
|
@@ -3800,17 +4553,17 @@ async function getProjectLink(cwd) {
|
|
|
3800
4553
|
}
|
|
3801
4554
|
async function saveProjectLink(cwd, link) {
|
|
3802
4555
|
const mcpUseDir = getMcpUseDirectory(cwd);
|
|
3803
|
-
await
|
|
3804
|
-
const linkPath =
|
|
3805
|
-
await
|
|
4556
|
+
await import_node_fs9.promises.mkdir(mcpUseDir, { recursive: true });
|
|
4557
|
+
const linkPath = import_node_path7.default.join(mcpUseDir, MCP_USE_DIR_PROJECT);
|
|
4558
|
+
await import_node_fs9.promises.writeFile(linkPath, JSON.stringify(link, null, 2), "utf-8");
|
|
3806
4559
|
await addToGitIgnore(cwd);
|
|
3807
4560
|
}
|
|
3808
4561
|
async function addToGitIgnore(cwd) {
|
|
3809
|
-
const gitignorePath =
|
|
4562
|
+
const gitignorePath = import_node_path7.default.join(cwd, ".gitignore");
|
|
3810
4563
|
try {
|
|
3811
4564
|
let content = "";
|
|
3812
4565
|
try {
|
|
3813
|
-
content = await
|
|
4566
|
+
content = await import_node_fs9.promises.readFile(gitignorePath, "utf-8");
|
|
3814
4567
|
} catch (err) {
|
|
3815
4568
|
if (err.code !== "ENOENT") throw err;
|
|
3816
4569
|
}
|
|
@@ -3819,7 +4572,7 @@ async function addToGitIgnore(cwd) {
|
|
|
3819
4572
|
# mcp-use deployment
|
|
3820
4573
|
${MCP_USE_DIR}
|
|
3821
4574
|
`;
|
|
3822
|
-
await
|
|
4575
|
+
await import_node_fs9.promises.writeFile(gitignorePath, newContent, "utf-8");
|
|
3823
4576
|
}
|
|
3824
4577
|
} catch (err) {
|
|
3825
4578
|
}
|
|
@@ -3828,7 +4581,7 @@ ${MCP_USE_DIR}
|
|
|
3828
4581
|
// src/commands/deploy.ts
|
|
3829
4582
|
async function parseEnvFile(filePath) {
|
|
3830
4583
|
try {
|
|
3831
|
-
const content = await
|
|
4584
|
+
const content = await import_node_fs10.promises.readFile(filePath, "utf-8");
|
|
3832
4585
|
const envVars = {};
|
|
3833
4586
|
const lines = content.split("\n");
|
|
3834
4587
|
let currentKey = null;
|
|
@@ -3947,7 +4700,7 @@ async function buildEnvVars(options) {
|
|
|
3947
4700
|
}
|
|
3948
4701
|
async function isMcpProject(cwd = process.cwd()) {
|
|
3949
4702
|
try {
|
|
3950
|
-
const content = await
|
|
4703
|
+
const content = await import_node_fs10.promises.readFile(import_node_path8.default.join(cwd, "package.json"), "utf-8");
|
|
3951
4704
|
const pkg = JSON.parse(content);
|
|
3952
4705
|
return !!(pkg.dependencies?.["mcp-use"] || pkg.dependencies?.["@modelcontextprotocol/sdk"] || pkg.devDependencies?.["mcp-use"] || pkg.devDependencies?.["@modelcontextprotocol/sdk"]);
|
|
3953
4706
|
} catch {
|
|
@@ -3956,16 +4709,16 @@ async function isMcpProject(cwd = process.cwd()) {
|
|
|
3956
4709
|
}
|
|
3957
4710
|
async function getProjectName(cwd = process.cwd()) {
|
|
3958
4711
|
try {
|
|
3959
|
-
const content = await
|
|
4712
|
+
const content = await import_node_fs10.promises.readFile(import_node_path8.default.join(cwd, "package.json"), "utf-8");
|
|
3960
4713
|
const pkg = JSON.parse(content);
|
|
3961
4714
|
if (pkg.name) return pkg.name;
|
|
3962
4715
|
} catch {
|
|
3963
4716
|
}
|
|
3964
|
-
return
|
|
4717
|
+
return import_node_path8.default.basename(cwd);
|
|
3965
4718
|
}
|
|
3966
4719
|
async function detectBuildCommand(cwd) {
|
|
3967
4720
|
try {
|
|
3968
|
-
const content = await
|
|
4721
|
+
const content = await import_node_fs10.promises.readFile(import_node_path8.default.join(cwd, "package.json"), "utf-8");
|
|
3969
4722
|
if (JSON.parse(content).scripts?.build) return "npm run build";
|
|
3970
4723
|
} catch {
|
|
3971
4724
|
}
|
|
@@ -3973,7 +4726,7 @@ async function detectBuildCommand(cwd) {
|
|
|
3973
4726
|
}
|
|
3974
4727
|
async function detectStartCommand(cwd) {
|
|
3975
4728
|
try {
|
|
3976
|
-
const content = await
|
|
4729
|
+
const content = await import_node_fs10.promises.readFile(import_node_path8.default.join(cwd, "package.json"), "utf-8");
|
|
3977
4730
|
const pkg = JSON.parse(content);
|
|
3978
4731
|
if (pkg.scripts?.start) return "npm start";
|
|
3979
4732
|
if (pkg.main) return `node ${pkg.main}`;
|
|
@@ -3984,7 +4737,7 @@ async function detectStartCommand(cwd) {
|
|
|
3984
4737
|
async function detectRuntime(cwd) {
|
|
3985
4738
|
for (const f of ["requirements.txt", "pyproject.toml", "setup.py"]) {
|
|
3986
4739
|
try {
|
|
3987
|
-
await
|
|
4740
|
+
await import_node_fs10.promises.access(import_node_path8.default.join(cwd, f));
|
|
3988
4741
|
return "python";
|
|
3989
4742
|
} catch {
|
|
3990
4743
|
continue;
|
|
@@ -4031,17 +4784,17 @@ var REQUIRED_IGNORES = [
|
|
|
4031
4784
|
".mcp-use"
|
|
4032
4785
|
];
|
|
4033
4786
|
async function ensureGitignore(cwd) {
|
|
4034
|
-
const gitignorePath =
|
|
4787
|
+
const gitignorePath = import_node_path8.default.join(cwd, ".gitignore");
|
|
4035
4788
|
let content = "";
|
|
4036
4789
|
try {
|
|
4037
|
-
content = await
|
|
4790
|
+
content = await import_node_fs10.promises.readFile(gitignorePath, "utf-8");
|
|
4038
4791
|
} catch {
|
|
4039
4792
|
}
|
|
4040
4793
|
const missing = REQUIRED_IGNORES.filter((entry) => !content.includes(entry));
|
|
4041
4794
|
if (missing.length > 0) {
|
|
4042
4795
|
const additions = missing.join("\n");
|
|
4043
4796
|
const newContent = content + (content.endsWith("\n") ? "" : "\n") + additions + "\n";
|
|
4044
|
-
await
|
|
4797
|
+
await import_node_fs10.promises.writeFile(gitignorePath, newContent, "utf-8");
|
|
4045
4798
|
}
|
|
4046
4799
|
}
|
|
4047
4800
|
async function displayDeploymentProgress(api, deploymentId, progressOptions) {
|
|
@@ -4491,10 +5244,10 @@ async function deployCommand(options) {
|
|
|
4491
5244
|
console.log(source_default.green("\u2713 GitHub connected\n"));
|
|
4492
5245
|
let installationDbId;
|
|
4493
5246
|
let githubInstallationId;
|
|
4494
|
-
const projectDir = options.rootDir ?
|
|
5247
|
+
const projectDir = options.rootDir ? import_node_path8.default.resolve(cwd, options.rootDir) : cwd;
|
|
4495
5248
|
if (options.rootDir) {
|
|
4496
5249
|
try {
|
|
4497
|
-
await
|
|
5250
|
+
await import_node_fs10.promises.access(projectDir);
|
|
4498
5251
|
} catch {
|
|
4499
5252
|
console.log(
|
|
4500
5253
|
source_default.red(`\u2717 Root directory not found: ${options.rootDir}`)
|
|
@@ -5004,7 +5757,7 @@ async function deployCommand(options) {
|
|
|
5004
5757
|
|
|
5005
5758
|
// src/commands/deployments.ts
|
|
5006
5759
|
init_cjs_shims();
|
|
5007
|
-
var
|
|
5760
|
+
var import_commander3 = require("commander");
|
|
5008
5761
|
async function prompt2(question) {
|
|
5009
5762
|
const readline = await import("readline");
|
|
5010
5763
|
const rl = readline.createInterface({
|
|
@@ -5416,7 +6169,7 @@ async function startDeploymentCommand(deploymentId) {
|
|
|
5416
6169
|
}
|
|
5417
6170
|
}
|
|
5418
6171
|
function createDeploymentsCommand() {
|
|
5419
|
-
const deploymentsCommand = new
|
|
6172
|
+
const deploymentsCommand = new import_commander3.Command("deployments").description(
|
|
5420
6173
|
"Manage cloud deployments"
|
|
5421
6174
|
);
|
|
5422
6175
|
deploymentsCommand.command("list").alias("ls").description("List all deployments").action(listDeploymentsCommand);
|
|
@@ -5433,11 +6186,11 @@ function createDeploymentsCommand() {
|
|
|
5433
6186
|
|
|
5434
6187
|
// src/commands/servers.ts
|
|
5435
6188
|
init_cjs_shims();
|
|
5436
|
-
var
|
|
6189
|
+
var import_commander5 = require("commander");
|
|
5437
6190
|
|
|
5438
6191
|
// src/commands/env.ts
|
|
5439
6192
|
init_cjs_shims();
|
|
5440
|
-
var
|
|
6193
|
+
var import_commander4 = require("commander");
|
|
5441
6194
|
var ALL_ENVS = ["production", "preview", "development"];
|
|
5442
6195
|
function parseEnvironments(raw) {
|
|
5443
6196
|
const parts = raw.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
@@ -5582,7 +6335,7 @@ async function removeEnvCommand(varId, options) {
|
|
|
5582
6335
|
}
|
|
5583
6336
|
}
|
|
5584
6337
|
function createEnvCommand() {
|
|
5585
|
-
const envCommand = new
|
|
6338
|
+
const envCommand = new import_commander4.Command("env").description(
|
|
5586
6339
|
"Manage environment variables for a server"
|
|
5587
6340
|
);
|
|
5588
6341
|
envCommand.command("list").alias("ls").description("List environment variables for a server").requiredOption("--server <id>", "Server UUID").option("--show-values", "Reveal non-sensitive values in output").action(listEnvCommand);
|
|
@@ -5866,7 +6619,7 @@ async function deleteServerCommand(serverId, options) {
|
|
|
5866
6619
|
}
|
|
5867
6620
|
}
|
|
5868
6621
|
function createServersCommand() {
|
|
5869
|
-
const serversCommand = new
|
|
6622
|
+
const serversCommand = new import_commander5.Command("servers").description(
|
|
5870
6623
|
"Manage cloud servers (Git-backed deploy targets)"
|
|
5871
6624
|
);
|
|
5872
6625
|
serversCommand.command("list").alias("ls").description("List servers for the current organization").option("--org <slug-or-id>", "Target organization (slug, id, or name)").option("--limit <n>", "Page size (1\u2013100, default 50)").option("--skip <n>", "Offset for pagination").option("--sort <field:asc|desc>", "Sort (e.g. updatedAt:desc)").action(listServersCommand);
|
|
@@ -5986,12 +6739,12 @@ async function orgCurrentCommand() {
|
|
|
5986
6739
|
|
|
5987
6740
|
// src/commands/skills.ts
|
|
5988
6741
|
init_cjs_shims();
|
|
5989
|
-
var
|
|
5990
|
-
var
|
|
5991
|
-
var
|
|
5992
|
-
var
|
|
6742
|
+
var import_commander6 = require("commander");
|
|
6743
|
+
var import_node_fs11 = require("fs");
|
|
6744
|
+
var import_node_os6 = require("os");
|
|
6745
|
+
var import_node_path9 = require("path");
|
|
5993
6746
|
var import_node_stream = require("stream");
|
|
5994
|
-
var
|
|
6747
|
+
var import_promises6 = require("stream/promises");
|
|
5995
6748
|
var import_tar = require("tar");
|
|
5996
6749
|
var REPO_OWNER = "mcp-use";
|
|
5997
6750
|
var REPO_NAME = "mcp-use";
|
|
@@ -6026,42 +6779,42 @@ function sendInstallTelemetryEvent(agents, skills) {
|
|
|
6026
6779
|
}
|
|
6027
6780
|
async function addSkillsToProject(projectPath) {
|
|
6028
6781
|
const tarballUrl = `https://codeload.github.com/${REPO_OWNER}/${REPO_NAME}/tar.gz/${REPO_BRANCH}`;
|
|
6029
|
-
const tempDir = (0,
|
|
6782
|
+
const tempDir = (0, import_node_fs11.mkdtempSync)((0, import_node_path9.join)((0, import_node_os6.tmpdir)(), "mcp-use-skills-"));
|
|
6030
6783
|
try {
|
|
6031
6784
|
const response = await fetch(tarballUrl);
|
|
6032
6785
|
if (!response.ok) {
|
|
6033
6786
|
throw new Error(`Failed to download tarball: ${response.statusText}`);
|
|
6034
6787
|
}
|
|
6035
|
-
await (0,
|
|
6788
|
+
await (0, import_promises6.pipeline)(
|
|
6036
6789
|
import_node_stream.Readable.fromWeb(response.body),
|
|
6037
6790
|
(0, import_tar.extract)({
|
|
6038
6791
|
cwd: tempDir,
|
|
6039
|
-
filter: (
|
|
6792
|
+
filter: (path11) => path11.includes("/skills/"),
|
|
6040
6793
|
strip: 1
|
|
6041
6794
|
})
|
|
6042
6795
|
);
|
|
6043
|
-
const skillsPath = (0,
|
|
6044
|
-
if (!(0,
|
|
6796
|
+
const skillsPath = (0, import_node_path9.join)(tempDir, "skills");
|
|
6797
|
+
if (!(0, import_node_fs11.existsSync)(skillsPath)) {
|
|
6045
6798
|
throw new Error("Skills folder not found in repository");
|
|
6046
6799
|
}
|
|
6047
6800
|
for (const preset of ALL_PRESETS) {
|
|
6048
6801
|
const folderName = AGENT_PRESET_FOLDERS[preset];
|
|
6049
|
-
const outputPath = (0,
|
|
6050
|
-
(0,
|
|
6802
|
+
const outputPath = (0, import_node_path9.join)(projectPath, folderName, "skills");
|
|
6803
|
+
(0, import_node_fs11.cpSync)(skillsPath, outputPath, { recursive: true });
|
|
6051
6804
|
}
|
|
6052
|
-
const skillNames = (0,
|
|
6805
|
+
const skillNames = (0, import_node_fs11.readdirSync)(skillsPath, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
6053
6806
|
sendInstallTelemetryEvent(ALL_PRESETS.join(","), skillNames.join(","));
|
|
6054
6807
|
} finally {
|
|
6055
|
-
(0,
|
|
6808
|
+
(0, import_node_fs11.rmSync)(tempDir, { recursive: true, force: true });
|
|
6056
6809
|
}
|
|
6057
6810
|
}
|
|
6058
6811
|
function createSkillsCommand() {
|
|
6059
|
-
const skills = new
|
|
6812
|
+
const skills = new import_commander6.Command("skills").description(
|
|
6060
6813
|
"Manage mcp-use AI agent skills"
|
|
6061
6814
|
);
|
|
6062
6815
|
const installAction = async (options) => {
|
|
6063
|
-
const projectPath = (0,
|
|
6064
|
-
if (!(0,
|
|
6816
|
+
const projectPath = (0, import_node_path9.resolve)(options.path);
|
|
6817
|
+
if (!(0, import_node_fs11.existsSync)(projectPath)) {
|
|
6065
6818
|
console.error(source_default.red(`Directory not found: ${projectPath}`));
|
|
6066
6819
|
process.exit(1);
|
|
6067
6820
|
}
|
|
@@ -6103,13 +6856,13 @@ function createSkillsCommand() {
|
|
|
6103
6856
|
|
|
6104
6857
|
// src/utils/next-shims.ts
|
|
6105
6858
|
init_cjs_shims();
|
|
6106
|
-
var
|
|
6107
|
-
var
|
|
6859
|
+
var import_node_fs12 = require("fs");
|
|
6860
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
6108
6861
|
var import_node_url2 = require("url");
|
|
6109
6862
|
async function detectNextJsProject(projectPath) {
|
|
6110
6863
|
try {
|
|
6111
|
-
const pkgPath =
|
|
6112
|
-
const content = await
|
|
6864
|
+
const pkgPath = import_node_path10.default.join(projectPath, "package.json");
|
|
6865
|
+
const content = await import_node_fs12.promises.readFile(pkgPath, "utf-8");
|
|
6113
6866
|
const pkg = JSON.parse(content);
|
|
6114
6867
|
const deps = pkg.dependencies ?? {};
|
|
6115
6868
|
const devDeps = pkg.devDependencies ?? {};
|
|
@@ -6127,9 +6880,9 @@ async function loadNextJsEnvFiles(projectPath) {
|
|
|
6127
6880
|
];
|
|
6128
6881
|
const dotenv = await import("dotenv");
|
|
6129
6882
|
for (const file of files) {
|
|
6130
|
-
const abs =
|
|
6883
|
+
const abs = import_node_path10.default.join(projectPath, file);
|
|
6131
6884
|
try {
|
|
6132
|
-
await
|
|
6885
|
+
await import_node_fs12.promises.access(abs);
|
|
6133
6886
|
} catch {
|
|
6134
6887
|
continue;
|
|
6135
6888
|
}
|
|
@@ -6139,20 +6892,20 @@ async function loadNextJsEnvFiles(projectPath) {
|
|
|
6139
6892
|
function getThisDir() {
|
|
6140
6893
|
if (typeof __dirname === "string") return __dirname;
|
|
6141
6894
|
const url = importMetaUrl;
|
|
6142
|
-
return
|
|
6895
|
+
return import_node_path10.default.dirname((0, import_node_url2.fileURLToPath)(url));
|
|
6143
6896
|
}
|
|
6144
6897
|
function resolveShimPath(filename) {
|
|
6145
6898
|
const thisDir = getThisDir();
|
|
6146
6899
|
const candidates = [
|
|
6147
6900
|
// Production: `dist/` next to this module
|
|
6148
|
-
|
|
6901
|
+
import_node_path10.default.join(thisDir, "shims", filename),
|
|
6149
6902
|
// Test / dev: one level up (e.g., from `dist/utils/` back to `src/shims/`)
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6903
|
+
import_node_path10.default.join(thisDir, "..", "shims", filename),
|
|
6904
|
+
import_node_path10.default.join(thisDir, "..", "..", "src", "shims", filename),
|
|
6905
|
+
import_node_path10.default.join(thisDir, "..", "src", "shims", filename)
|
|
6153
6906
|
];
|
|
6154
6907
|
for (const candidate of candidates) {
|
|
6155
|
-
if ((0,
|
|
6908
|
+
if ((0, import_node_fs12.existsSync)(candidate)) return candidate;
|
|
6156
6909
|
}
|
|
6157
6910
|
return void 0;
|
|
6158
6911
|
}
|
|
@@ -6170,7 +6923,7 @@ async function registerNextShimsInProcess() {
|
|
|
6170
6923
|
const cjsPath = getShimCjsPreloadPath();
|
|
6171
6924
|
if (cjsPath) {
|
|
6172
6925
|
const { createRequire: createRequire3 } = await import("module");
|
|
6173
|
-
const req = createRequire3((0, import_node_url2.pathToFileURL)(getThisDir() +
|
|
6926
|
+
const req = createRequire3((0, import_node_url2.pathToFileURL)(getThisDir() + import_node_path10.default.sep).href);
|
|
6174
6927
|
req(cjsPath);
|
|
6175
6928
|
anyRegistered = true;
|
|
6176
6929
|
}
|
|
@@ -6178,7 +6931,7 @@ async function registerNextShimsInProcess() {
|
|
|
6178
6931
|
if (loaderPath) {
|
|
6179
6932
|
const { register } = await import("module");
|
|
6180
6933
|
const loaderUrl = (0, import_node_url2.pathToFileURL)(loaderPath).href;
|
|
6181
|
-
register(loaderUrl, (0, import_node_url2.pathToFileURL)(getThisDir() +
|
|
6934
|
+
register(loaderUrl, (0, import_node_url2.pathToFileURL)(getThisDir() + import_node_path10.default.sep).href);
|
|
6182
6935
|
anyRegistered = true;
|
|
6183
6936
|
}
|
|
6184
6937
|
return anyRegistered;
|
|
@@ -6204,13 +6957,13 @@ function quoteNodeOption(value) {
|
|
|
6204
6957
|
|
|
6205
6958
|
// src/utils/update-check.ts
|
|
6206
6959
|
init_cjs_shims();
|
|
6207
|
-
var
|
|
6208
|
-
var
|
|
6960
|
+
var import_node_fs13 = require("fs");
|
|
6961
|
+
var import_promises7 = require("fs/promises");
|
|
6209
6962
|
var import_node_module = require("module");
|
|
6210
|
-
var
|
|
6211
|
-
var
|
|
6212
|
-
var CACHE_DIR =
|
|
6213
|
-
var CACHE_FILE =
|
|
6963
|
+
var import_node_os7 = __toESM(require("os"), 1);
|
|
6964
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
6965
|
+
var CACHE_DIR = import_node_path11.default.join(import_node_os7.default.homedir(), ".mcp-use");
|
|
6966
|
+
var CACHE_FILE = import_node_path11.default.join(CACHE_DIR, "update-check.json");
|
|
6214
6967
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
6215
6968
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
6216
6969
|
var PACKAGE_NAME = "mcp-use";
|
|
@@ -6235,7 +6988,7 @@ function isNewer(current, candidate) {
|
|
|
6235
6988
|
}
|
|
6236
6989
|
async function readCache() {
|
|
6237
6990
|
try {
|
|
6238
|
-
const content = await (0,
|
|
6991
|
+
const content = await (0, import_promises7.readFile)(CACHE_FILE, "utf-8");
|
|
6239
6992
|
return JSON.parse(content);
|
|
6240
6993
|
} catch {
|
|
6241
6994
|
return null;
|
|
@@ -6243,12 +6996,12 @@ async function readCache() {
|
|
|
6243
6996
|
}
|
|
6244
6997
|
async function writeCache(latestVersion) {
|
|
6245
6998
|
try {
|
|
6246
|
-
await (0,
|
|
6999
|
+
await (0, import_promises7.mkdir)(CACHE_DIR, { recursive: true });
|
|
6247
7000
|
const cache = {
|
|
6248
7001
|
lastChecked: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6249
7002
|
latestVersion
|
|
6250
7003
|
};
|
|
6251
|
-
await (0,
|
|
7004
|
+
await (0, import_promises7.writeFile)(CACHE_FILE, JSON.stringify(cache, null, 2), "utf-8");
|
|
6252
7005
|
} catch {
|
|
6253
7006
|
}
|
|
6254
7007
|
}
|
|
@@ -6293,16 +7046,16 @@ function resolveInstalledVersion(projectPath) {
|
|
|
6293
7046
|
if (projectPath) {
|
|
6294
7047
|
attempts.push(() => {
|
|
6295
7048
|
const projectRequire = (0, import_node_module.createRequire)(
|
|
6296
|
-
|
|
7049
|
+
import_node_path11.default.join(projectPath, "package.json")
|
|
6297
7050
|
);
|
|
6298
7051
|
return projectRequire.resolve(`${PACKAGE_NAME}/package.json`);
|
|
6299
7052
|
});
|
|
6300
7053
|
}
|
|
6301
|
-
attempts.push(() =>
|
|
7054
|
+
attempts.push(() => import_node_path11.default.join(__dirname, "../../mcp-use/package.json"));
|
|
6302
7055
|
for (const attempt of attempts) {
|
|
6303
7056
|
try {
|
|
6304
7057
|
const pkgPath = attempt();
|
|
6305
|
-
const json = JSON.parse((0,
|
|
7058
|
+
const json = JSON.parse((0, import_node_fs13.readFileSync)(pkgPath, "utf-8"));
|
|
6306
7059
|
if (typeof json.version === "string") return json.version;
|
|
6307
7060
|
} catch {
|
|
6308
7061
|
}
|
|
@@ -6334,9 +7087,9 @@ A new release of ${source_default.bold(PACKAGE_NAME)} is available: ${source_def
|
|
|
6334
7087
|
}
|
|
6335
7088
|
|
|
6336
7089
|
// src/index.ts
|
|
6337
|
-
var program = new
|
|
6338
|
-
var packageContent = (0,
|
|
6339
|
-
|
|
7090
|
+
var program = new import_commander7.Command();
|
|
7091
|
+
var packageContent = (0, import_node_fs14.readFileSync)(
|
|
7092
|
+
import_node_path12.default.join(__dirname, "../package.json"),
|
|
6340
7093
|
"utf-8"
|
|
6341
7094
|
);
|
|
6342
7095
|
var packageJson = JSON.parse(packageContent);
|
|
@@ -6367,16 +7120,16 @@ function displayPackageVersions(projectPath) {
|
|
|
6367
7120
|
if (projectPath) {
|
|
6368
7121
|
try {
|
|
6369
7122
|
const projectRequire = (0, import_node_module2.createRequire)(
|
|
6370
|
-
|
|
7123
|
+
import_node_path12.default.join(projectPath, "package.json")
|
|
6371
7124
|
);
|
|
6372
7125
|
pkgPath = projectRequire.resolve(`${pkg.name}/package.json`);
|
|
6373
7126
|
} catch (resolveError) {
|
|
6374
|
-
pkgPath =
|
|
7127
|
+
pkgPath = import_node_path12.default.join(__dirname, pkg.relativePath);
|
|
6375
7128
|
}
|
|
6376
7129
|
} else {
|
|
6377
|
-
pkgPath =
|
|
7130
|
+
pkgPath = import_node_path12.default.join(__dirname, pkg.relativePath);
|
|
6378
7131
|
}
|
|
6379
|
-
const pkgContent = (0,
|
|
7132
|
+
const pkgContent = (0, import_node_fs14.readFileSync)(pkgPath, "utf-8");
|
|
6380
7133
|
const pkgJson = JSON.parse(pkgContent);
|
|
6381
7134
|
const version = pkgJson.version || "unknown";
|
|
6382
7135
|
if (pkg.highlight) {
|
|
@@ -6431,7 +7184,7 @@ function normalizeBrowserHost(host) {
|
|
|
6431
7184
|
return host === "0.0.0.0" ? "localhost" : host;
|
|
6432
7185
|
}
|
|
6433
7186
|
function runCommand(command, args, cwd, env2, filterStderr = false) {
|
|
6434
|
-
const proc = (0,
|
|
7187
|
+
const proc = (0, import_node_child_process11.spawn)(command, args, {
|
|
6435
7188
|
cwd,
|
|
6436
7189
|
stdio: filterStderr ? ["inherit", "inherit", "pipe"] : "inherit",
|
|
6437
7190
|
shell: process.platform === "win32",
|
|
@@ -6464,7 +7217,7 @@ async function startTunnel(port, subdomain) {
|
|
|
6464
7217
|
if (subdomain) {
|
|
6465
7218
|
tunnelArgs.push("--subdomain", subdomain);
|
|
6466
7219
|
}
|
|
6467
|
-
const proc = (0,
|
|
7220
|
+
const proc = (0, import_node_child_process11.spawn)("npx", tunnelArgs, {
|
|
6468
7221
|
stdio: ["ignore", "pipe", "pipe"],
|
|
6469
7222
|
shell: process.platform === "win32"
|
|
6470
7223
|
});
|
|
@@ -6528,21 +7281,21 @@ async function startTunnel(port, subdomain) {
|
|
|
6528
7281
|
}
|
|
6529
7282
|
async function resolveEntryFile(projectPath, cliEntry, mcpDir) {
|
|
6530
7283
|
if (cliEntry) {
|
|
6531
|
-
await (0,
|
|
7284
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, cliEntry)).catch(() => {
|
|
6532
7285
|
throw new Error(`File not found: ${cliEntry}`);
|
|
6533
7286
|
});
|
|
6534
7287
|
return cliEntry;
|
|
6535
7288
|
}
|
|
6536
7289
|
if (mcpDir) {
|
|
6537
7290
|
const mcpCandidates = [
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
7291
|
+
import_node_path12.default.join(mcpDir, "index.ts"),
|
|
7292
|
+
import_node_path12.default.join(mcpDir, "index.tsx"),
|
|
7293
|
+
import_node_path12.default.join(mcpDir, "server.ts"),
|
|
7294
|
+
import_node_path12.default.join(mcpDir, "server.tsx")
|
|
6542
7295
|
];
|
|
6543
7296
|
for (const candidate of mcpCandidates) {
|
|
6544
7297
|
try {
|
|
6545
|
-
await (0,
|
|
7298
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, candidate));
|
|
6546
7299
|
return candidate;
|
|
6547
7300
|
} catch {
|
|
6548
7301
|
continue;
|
|
@@ -6551,17 +7304,17 @@ async function resolveEntryFile(projectPath, cliEntry, mcpDir) {
|
|
|
6551
7304
|
throw new Error(
|
|
6552
7305
|
`No entry file found inside ${mcpDir}.
|
|
6553
7306
|
|
|
6554
|
-
Expected one of: ${mcpCandidates.map((c) =>
|
|
7307
|
+
Expected one of: ${mcpCandidates.map((c) => import_node_path12.default.relative(projectPath, import_node_path12.default.join(projectPath, c))).join(", ")}
|
|
6555
7308
|
|
|
6556
7309
|
Fix this by either:
|
|
6557
|
-
1. Creating ${
|
|
7310
|
+
1. Creating ${import_node_path12.default.join(mcpDir, "index.ts")}, or
|
|
6558
7311
|
2. Passing --entry <file> on the command line`
|
|
6559
7312
|
);
|
|
6560
7313
|
}
|
|
6561
7314
|
const candidates = ["index.ts", "src/index.ts", "server.ts", "src/server.ts"];
|
|
6562
7315
|
for (const candidate of candidates) {
|
|
6563
7316
|
try {
|
|
6564
|
-
await (0,
|
|
7317
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, candidate));
|
|
6565
7318
|
return candidate;
|
|
6566
7319
|
} catch {
|
|
6567
7320
|
continue;
|
|
@@ -6579,7 +7332,7 @@ Fix this by either:
|
|
|
6579
7332
|
}
|
|
6580
7333
|
function resolveWidgetsDir(cliWidgetsDir, mcpDir) {
|
|
6581
7334
|
if (cliWidgetsDir) return cliWidgetsDir;
|
|
6582
|
-
if (mcpDir) return
|
|
7335
|
+
if (mcpDir) return import_node_path12.default.join(mcpDir, "resources");
|
|
6583
7336
|
return "resources";
|
|
6584
7337
|
}
|
|
6585
7338
|
function makeWidgetServerOnlyGuard(widgetName) {
|
|
@@ -6614,8 +7367,8 @@ function isBunRuntime() {
|
|
|
6614
7367
|
return typeof globalThis.Bun !== "undefined" || typeof process.versions.bun === "string";
|
|
6615
7368
|
}
|
|
6616
7369
|
async function generateToolRegistryTypesForServer(projectPath, serverFileRelative) {
|
|
6617
|
-
const serverFile =
|
|
6618
|
-
const serverFileExists = await (0,
|
|
7370
|
+
const serverFile = import_node_path12.default.join(projectPath, serverFileRelative);
|
|
7371
|
+
const serverFileExists = await (0, import_promises8.access)(serverFile).then(() => true).catch(() => false);
|
|
6619
7372
|
if (!serverFileExists) {
|
|
6620
7373
|
throw new Error(`Server file not found: ${serverFile}`);
|
|
6621
7374
|
}
|
|
@@ -6640,8 +7393,8 @@ async function generateToolRegistryTypesForServer(projectPath, serverFileRelativ
|
|
|
6640
7393
|
await loadNextJsEnvFiles(projectPath);
|
|
6641
7394
|
await registerNextShimsInProcess();
|
|
6642
7395
|
}
|
|
6643
|
-
const projectTsconfigPath =
|
|
6644
|
-
const hasTsconfig = await (0,
|
|
7396
|
+
const projectTsconfigPath = import_node_path12.default.join(projectPath, "tsconfig.json");
|
|
7397
|
+
const hasTsconfig = await (0, import_promises8.access)(projectTsconfigPath).then(() => true).catch(() => false);
|
|
6645
7398
|
if (hasTsconfig) {
|
|
6646
7399
|
process.env.TSX_TSCONFIG_PATH = projectTsconfigPath;
|
|
6647
7400
|
}
|
|
@@ -6649,7 +7402,7 @@ async function generateToolRegistryTypesForServer(projectPath, serverFileRelativ
|
|
|
6649
7402
|
if (previousCwd !== projectPath) process.chdir(projectPath);
|
|
6650
7403
|
try {
|
|
6651
7404
|
const projectRequire = (0, import_node_module2.createRequire)(
|
|
6652
|
-
|
|
7405
|
+
import_node_path12.default.join(projectPath, "package.json")
|
|
6653
7406
|
);
|
|
6654
7407
|
const tsxEsmApiPath = projectRequire.resolve("tsx/esm/api");
|
|
6655
7408
|
const tsxEsmApi = await import((0, import_node_url3.pathToFileURL)(tsxEsmApiPath).href);
|
|
@@ -6676,8 +7429,8 @@ async function generateToolRegistryTypesForServer(projectPath, serverFileRelativ
|
|
|
6676
7429
|
"No MCPServer instance found. Make sure your server file creates an MCPServer instance."
|
|
6677
7430
|
);
|
|
6678
7431
|
}
|
|
6679
|
-
const mcpUsePath =
|
|
6680
|
-
const { generateToolRegistryTypes } = await import((0, import_node_url3.pathToFileURL)(
|
|
7432
|
+
const mcpUsePath = import_node_path12.default.join(projectPath, "node_modules", "mcp-use");
|
|
7433
|
+
const { generateToolRegistryTypes } = await import((0, import_node_url3.pathToFileURL)(import_node_path12.default.join(mcpUsePath, "dist", "src", "server", "index.js")).href).then((mod) => mod);
|
|
6681
7434
|
if (!generateToolRegistryTypes) {
|
|
6682
7435
|
throw new Error("generateToolRegistryTypes not found in mcp-use package");
|
|
6683
7436
|
}
|
|
@@ -6695,10 +7448,10 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
6695
7448
|
const { promises: fs11 } = await import("fs");
|
|
6696
7449
|
const { build } = await import("vite");
|
|
6697
7450
|
const widgetsDirRelative = options.widgetsDir ?? "resources";
|
|
6698
|
-
const resourcesDir =
|
|
7451
|
+
const resourcesDir = import_node_path12.default.resolve(projectPath, widgetsDirRelative);
|
|
6699
7452
|
const mcpUrl = process.env.MCP_URL;
|
|
6700
7453
|
try {
|
|
6701
|
-
await (0,
|
|
7454
|
+
await (0, import_promises8.access)(resourcesDir);
|
|
6702
7455
|
} catch {
|
|
6703
7456
|
console.log(
|
|
6704
7457
|
source_default.gray(
|
|
@@ -6717,10 +7470,10 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
6717
7470
|
if (dirent.isFile() && (dirent.name.endsWith(".tsx") || dirent.name.endsWith(".ts"))) {
|
|
6718
7471
|
entries.push({
|
|
6719
7472
|
name: dirent.name.replace(/\.tsx?$/, ""),
|
|
6720
|
-
path:
|
|
7473
|
+
path: import_node_path12.default.join(resourcesDir, dirent.name)
|
|
6721
7474
|
});
|
|
6722
7475
|
} else if (dirent.isDirectory()) {
|
|
6723
|
-
const widgetPath =
|
|
7476
|
+
const widgetPath = import_node_path12.default.join(resourcesDir, dirent.name, "widget.tsx");
|
|
6724
7477
|
try {
|
|
6725
7478
|
await fs11.access(widgetPath);
|
|
6726
7479
|
entries.push({
|
|
@@ -6750,14 +7503,14 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
6750
7503
|
);
|
|
6751
7504
|
const react = (await import("@vitejs/plugin-react")).default;
|
|
6752
7505
|
const tailwindcss = (await import("@tailwindcss/vite")).default;
|
|
6753
|
-
const projectTsconfigPath =
|
|
7506
|
+
const projectTsconfigPath = import_node_path12.default.join(projectPath, "tsconfig.json");
|
|
6754
7507
|
let hasProjectTsconfig = false;
|
|
6755
7508
|
try {
|
|
6756
|
-
await (0,
|
|
7509
|
+
await (0, import_promises8.access)(projectTsconfigPath);
|
|
6757
7510
|
hasProjectTsconfig = true;
|
|
6758
7511
|
} catch {
|
|
6759
7512
|
}
|
|
6760
|
-
const packageJsonPath =
|
|
7513
|
+
const packageJsonPath = import_node_path12.default.join(projectPath, "package.json");
|
|
6761
7514
|
let favicon = "";
|
|
6762
7515
|
try {
|
|
6763
7516
|
const pkgContent = await fs11.readFile(packageJsonPath, "utf-8");
|
|
@@ -6769,16 +7522,16 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
6769
7522
|
const widgetName = entry.name;
|
|
6770
7523
|
const entryPath = entry.path.replace(/\\/g, "/");
|
|
6771
7524
|
console.log(source_default.gray(` - Building ${widgetName}...`));
|
|
6772
|
-
const tempDir =
|
|
7525
|
+
const tempDir = import_node_path12.default.join(projectPath, ".mcp-use", widgetName);
|
|
6773
7526
|
await fs11.mkdir(tempDir, { recursive: true });
|
|
6774
|
-
const relativeResourcesPath =
|
|
6775
|
-
const mcpUsePath =
|
|
6776
|
-
const relativeMcpUsePath =
|
|
6777
|
-
const projectSrcDir =
|
|
7527
|
+
const relativeResourcesPath = import_node_path12.default.relative(tempDir, resourcesDir).replace(/\\/g, "/");
|
|
7528
|
+
const mcpUsePath = import_node_path12.default.join(projectPath, "node_modules", "mcp-use");
|
|
7529
|
+
const relativeMcpUsePath = import_node_path12.default.relative(tempDir, mcpUsePath).replace(/\\/g, "/");
|
|
7530
|
+
const projectSrcDir = import_node_path12.default.join(projectPath, "src");
|
|
6778
7531
|
let projectSrcSourceLine = "";
|
|
6779
7532
|
try {
|
|
6780
|
-
await (0,
|
|
6781
|
-
const relativeProjectSrcPath =
|
|
7533
|
+
await (0, import_promises8.access)(projectSrcDir);
|
|
7534
|
+
const relativeProjectSrcPath = import_node_path12.default.relative(tempDir, projectSrcDir).replace(/\\/g, "/");
|
|
6782
7535
|
projectSrcSourceLine = `@source "${relativeProjectSrcPath}";
|
|
6783
7536
|
`;
|
|
6784
7537
|
} catch {
|
|
@@ -6789,7 +7542,7 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
6789
7542
|
@source "${relativeResourcesPath}";
|
|
6790
7543
|
@source "${relativeMcpUsePath}/**/*.{ts,tsx,js,jsx}";
|
|
6791
7544
|
${projectSrcSourceLine}`;
|
|
6792
|
-
await fs11.writeFile(
|
|
7545
|
+
await fs11.writeFile(import_node_path12.default.join(tempDir, "styles.css"), cssContent, "utf8");
|
|
6793
7546
|
const entryContent = `import React from 'react'
|
|
6794
7547
|
import { createRoot } from 'react-dom/client'
|
|
6795
7548
|
import './styles.css'
|
|
@@ -6814,9 +7567,9 @@ if (container && Component) {
|
|
|
6814
7567
|
<script type="module" src="/entry.tsx"></script>
|
|
6815
7568
|
</body>
|
|
6816
7569
|
</html>`;
|
|
6817
|
-
await fs11.writeFile(
|
|
6818
|
-
await fs11.writeFile(
|
|
6819
|
-
const outDir =
|
|
7570
|
+
await fs11.writeFile(import_node_path12.default.join(tempDir, "entry.tsx"), entryContent, "utf8");
|
|
7571
|
+
await fs11.writeFile(import_node_path12.default.join(tempDir, "index.html"), htmlContent, "utf8");
|
|
7572
|
+
const outDir = import_node_path12.default.join(
|
|
6820
7573
|
projectPath,
|
|
6821
7574
|
"dist",
|
|
6822
7575
|
"resources",
|
|
@@ -6826,13 +7579,13 @@ if (container && Component) {
|
|
|
6826
7579
|
const baseUrl = mcpUrl ? `${mcpUrl}/${widgetName}/` : `/mcp-use/widgets/${widgetName}/`;
|
|
6827
7580
|
let widgetMetadata = {};
|
|
6828
7581
|
try {
|
|
6829
|
-
const metadataTempDir =
|
|
7582
|
+
const metadataTempDir = import_node_path12.default.join(
|
|
6830
7583
|
projectPath,
|
|
6831
7584
|
".mcp-use",
|
|
6832
7585
|
`${widgetName}-metadata`
|
|
6833
7586
|
);
|
|
6834
7587
|
await fs11.mkdir(metadataTempDir, { recursive: true });
|
|
6835
|
-
const { createServer } = await import("vite");
|
|
7588
|
+
const { createServer: createServer2 } = await import("vite");
|
|
6836
7589
|
const nodeStubsPlugin = {
|
|
6837
7590
|
name: "node-stubs",
|
|
6838
7591
|
enforce: "pre",
|
|
@@ -6860,9 +7613,9 @@ export default PostHog;
|
|
|
6860
7613
|
}
|
|
6861
7614
|
};
|
|
6862
7615
|
const serverOnlyGuard = makeWidgetServerOnlyGuard(widgetName);
|
|
6863
|
-
const metadataServer = await
|
|
7616
|
+
const metadataServer = await createServer2({
|
|
6864
7617
|
root: metadataTempDir,
|
|
6865
|
-
cacheDir:
|
|
7618
|
+
cacheDir: import_node_path12.default.join(metadataTempDir, ".vite-cache"),
|
|
6866
7619
|
plugins: [serverOnlyGuard, nodeStubsPlugin, tailwindcss(), react()],
|
|
6867
7620
|
// When the project has a tsconfig, enable Vite's native tsconfig-paths
|
|
6868
7621
|
// resolver so `@/*` (or any custom alias) resolves through the
|
|
@@ -7093,7 +7846,7 @@ export default {
|
|
|
7093
7846
|
// Inline all assets under 100MB (effectively all)
|
|
7094
7847
|
} : {},
|
|
7095
7848
|
rolldownOptions: {
|
|
7096
|
-
input:
|
|
7849
|
+
input: import_node_path12.default.join(tempDir, "index.html"),
|
|
7097
7850
|
external: (id) => {
|
|
7098
7851
|
return false;
|
|
7099
7852
|
}
|
|
@@ -7101,11 +7854,11 @@ export default {
|
|
|
7101
7854
|
}
|
|
7102
7855
|
});
|
|
7103
7856
|
try {
|
|
7104
|
-
const assetsDir =
|
|
7857
|
+
const assetsDir = import_node_path12.default.join(outDir, "assets");
|
|
7105
7858
|
const assetFiles = await fs11.readdir(assetsDir);
|
|
7106
7859
|
const jsFiles = assetFiles.filter((f) => f.endsWith(".js"));
|
|
7107
7860
|
for (const jsFile of jsFiles) {
|
|
7108
|
-
const jsPath =
|
|
7861
|
+
const jsPath = import_node_path12.default.join(assetsDir, jsFile);
|
|
7109
7862
|
let content = await fs11.readFile(jsPath, "utf8");
|
|
7110
7863
|
const zodConfigPatterns = [
|
|
7111
7864
|
// Non-minified: export const globalConfig = {}
|
|
@@ -7137,7 +7890,7 @@ export default {
|
|
|
7137
7890
|
const mcpServerUrl = process.env.MCP_SERVER_URL;
|
|
7138
7891
|
if (mcpServerUrl) {
|
|
7139
7892
|
try {
|
|
7140
|
-
const htmlPath =
|
|
7893
|
+
const htmlPath = import_node_path12.default.join(outDir, "index.html");
|
|
7141
7894
|
let html = await fs11.readFile(htmlPath, "utf8");
|
|
7142
7895
|
const injectionScript = `<script>window.__getFile = (filename) => { return "${mcpUrl}/${widgetName}/"+filename }; window.__mcpPublicUrl = "${mcpServerUrl}/mcp-use/public"; window.__mcpPublicAssetsUrl = "${mcpUrl}/public";</script>`;
|
|
7143
7896
|
if (!html.includes("window.__mcpPublicUrl")) {
|
|
@@ -7213,7 +7966,7 @@ async function collectTsFiles(projectPath, includePatterns, excludePatterns) {
|
|
|
7213
7966
|
for (const file of literalFiles) {
|
|
7214
7967
|
if (/\.tsx?$/.test(file) && !file.endsWith(".d.ts")) {
|
|
7215
7968
|
try {
|
|
7216
|
-
await (0,
|
|
7969
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, file));
|
|
7217
7970
|
files.push(file);
|
|
7218
7971
|
} catch {
|
|
7219
7972
|
}
|
|
@@ -7221,13 +7974,13 @@ async function collectTsFiles(projectPath, includePatterns, excludePatterns) {
|
|
|
7221
7974
|
}
|
|
7222
7975
|
const excludeSet = new Set(excludePatterns.map((e) => e.replace(/\*+/g, "")));
|
|
7223
7976
|
for (const prefix of dirPrefixes) {
|
|
7224
|
-
const dirPath =
|
|
7977
|
+
const dirPath = import_node_path12.default.join(projectPath, prefix);
|
|
7225
7978
|
try {
|
|
7226
7979
|
const entries = await fs11.readdir(dirPath, { recursive: true });
|
|
7227
7980
|
for (const entry of entries) {
|
|
7228
7981
|
const entryStr = String(entry);
|
|
7229
|
-
const rel =
|
|
7230
|
-
if (/\.tsx?$/.test(entryStr) && !entryStr.endsWith(".d.ts") && !excludeSet.has(rel.split(
|
|
7982
|
+
const rel = import_node_path12.default.join(prefix, entryStr);
|
|
7983
|
+
if (/\.tsx?$/.test(entryStr) && !entryStr.endsWith(".d.ts") && !excludeSet.has(rel.split(import_node_path12.default.sep)[0])) {
|
|
7231
7984
|
files.push(rel);
|
|
7232
7985
|
}
|
|
7233
7986
|
}
|
|
@@ -7239,7 +7992,7 @@ async function collectTsFiles(projectPath, includePatterns, excludePatterns) {
|
|
|
7239
7992
|
async function transpileWithEsbuild(projectPath) {
|
|
7240
7993
|
const esbuild = await import("esbuild");
|
|
7241
7994
|
const { promises: fs11 } = await import("fs");
|
|
7242
|
-
const tsconfigPath =
|
|
7995
|
+
const tsconfigPath = import_node_path12.default.join(projectPath, "tsconfig.json");
|
|
7243
7996
|
let tsconfig = {};
|
|
7244
7997
|
try {
|
|
7245
7998
|
const raw = await fs11.readFile(tsconfigPath, "utf-8");
|
|
@@ -7269,10 +8022,10 @@ async function transpileWithEsbuild(projectPath) {
|
|
|
7269
8022
|
const target = (compilerOptions.target || "ES2022").toLowerCase();
|
|
7270
8023
|
const moduleStr = (compilerOptions.module || "ESNext").toLowerCase();
|
|
7271
8024
|
const format = moduleStr.includes("commonjs") ? "cjs" : "esm";
|
|
7272
|
-
const outbase = compilerOptions.rootDir ?
|
|
8025
|
+
const outbase = compilerOptions.rootDir ? import_node_path12.default.resolve(projectPath, compilerOptions.rootDir) : projectPath;
|
|
7273
8026
|
await esbuild.build({
|
|
7274
|
-
entryPoints: files.map((f) =>
|
|
7275
|
-
outdir:
|
|
8027
|
+
entryPoints: files.map((f) => import_node_path12.default.join(projectPath, f)),
|
|
8028
|
+
outdir: import_node_path12.default.join(projectPath, outDir),
|
|
7276
8029
|
outbase,
|
|
7277
8030
|
bundle: true,
|
|
7278
8031
|
packages: "external",
|
|
@@ -7299,7 +8052,7 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
7299
8052
|
"Inline all JS/CSS into HTML (required for VS Code MCP Apps)"
|
|
7300
8053
|
).option("--no-inline", "Keep JS/CSS as separate files (default)").option("--no-typecheck", "Skip TypeScript type checking (faster builds)").action(async (options) => {
|
|
7301
8054
|
try {
|
|
7302
|
-
const projectPath =
|
|
8055
|
+
const projectPath = import_node_path12.default.resolve(options.path);
|
|
7303
8056
|
const { promises: fs11 } = await import("fs");
|
|
7304
8057
|
displayPackageVersions(projectPath);
|
|
7305
8058
|
const mcpDir = options.mcpDir;
|
|
@@ -7359,7 +8112,7 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
7359
8112
|
}
|
|
7360
8113
|
if (options.typecheck !== false && !mcpDir) {
|
|
7361
8114
|
console.log(source_default.gray("Type checking..."));
|
|
7362
|
-
const tscBin =
|
|
8115
|
+
const tscBin = import_node_path12.default.join(
|
|
7363
8116
|
projectPath,
|
|
7364
8117
|
"node_modules",
|
|
7365
8118
|
"typescript",
|
|
@@ -7382,7 +8135,7 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
7382
8135
|
if (mcpDir) {
|
|
7383
8136
|
entryPoint = sourceServerFile;
|
|
7384
8137
|
} else {
|
|
7385
|
-
const baseName =
|
|
8138
|
+
const baseName = import_node_path12.default.basename(sourceServerFile, ".ts") + ".js";
|
|
7386
8139
|
const possibleOutputs = [
|
|
7387
8140
|
`dist/${baseName}`,
|
|
7388
8141
|
// rootDir set to project root or src
|
|
@@ -7393,7 +8146,7 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
7393
8146
|
];
|
|
7394
8147
|
for (const candidate of possibleOutputs) {
|
|
7395
8148
|
try {
|
|
7396
|
-
await (0,
|
|
8149
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, candidate));
|
|
7397
8150
|
entryPoint = candidate;
|
|
7398
8151
|
break;
|
|
7399
8152
|
} catch {
|
|
@@ -7402,17 +8155,17 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
7402
8155
|
}
|
|
7403
8156
|
}
|
|
7404
8157
|
}
|
|
7405
|
-
const publicDir =
|
|
8158
|
+
const publicDir = import_node_path12.default.join(projectPath, "public");
|
|
7406
8159
|
try {
|
|
7407
8160
|
await fs11.access(publicDir);
|
|
7408
8161
|
console.log(source_default.gray("Copying public assets..."));
|
|
7409
|
-
await fs11.cp(publicDir,
|
|
8162
|
+
await fs11.cp(publicDir, import_node_path12.default.join(projectPath, "dist", "public"), {
|
|
7410
8163
|
recursive: true
|
|
7411
8164
|
});
|
|
7412
8165
|
console.log(source_default.green("\u2713 Public assets copied"));
|
|
7413
8166
|
} catch {
|
|
7414
8167
|
}
|
|
7415
|
-
const manifestPath =
|
|
8168
|
+
const manifestPath = import_node_path12.default.join(projectPath, "dist", "mcp-use.json");
|
|
7416
8169
|
let existingManifest = {};
|
|
7417
8170
|
try {
|
|
7418
8171
|
const existingContent = await fs11.readFile(manifestPath, "utf-8");
|
|
@@ -7437,7 +8190,7 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
7437
8190
|
// Server entry point for `mcp-use start`
|
|
7438
8191
|
widgets: widgetsData
|
|
7439
8192
|
};
|
|
7440
|
-
await fs11.mkdir(
|
|
8193
|
+
await fs11.mkdir(import_node_path12.default.dirname(manifestPath), { recursive: true });
|
|
7441
8194
|
await fs11.writeFile(
|
|
7442
8195
|
manifestPath,
|
|
7443
8196
|
JSON.stringify(manifest, null, 2),
|
|
@@ -7474,7 +8227,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7474
8227
|
).option("--no-open", "Do not auto-open inspector").option("--no-hmr", "Disable hot module reloading (use tsx watch instead)").option("--tunnel", "Expose server through a tunnel").action(async (options) => {
|
|
7475
8228
|
try {
|
|
7476
8229
|
process.env.MCP_USE_CLI_DEV = "1";
|
|
7477
|
-
const projectPath =
|
|
8230
|
+
const projectPath = import_node_path12.default.resolve(options.path);
|
|
7478
8231
|
let port = parseInt(options.port, 10);
|
|
7479
8232
|
const host = options.host;
|
|
7480
8233
|
const useHmr = options.hmr !== false;
|
|
@@ -7502,10 +8255,10 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7502
8255
|
let tunnelUrl = void 0;
|
|
7503
8256
|
if (options.tunnel) {
|
|
7504
8257
|
try {
|
|
7505
|
-
const manifestPath =
|
|
8258
|
+
const manifestPath = import_node_path12.default.join(projectPath, "dist", "mcp-use.json");
|
|
7506
8259
|
let existingSubdomain;
|
|
7507
8260
|
try {
|
|
7508
|
-
const manifestContent = await (0,
|
|
8261
|
+
const manifestContent = await (0, import_promises8.readFile)(manifestPath, "utf-8");
|
|
7509
8262
|
const manifest = JSON.parse(manifestContent);
|
|
7510
8263
|
existingSubdomain = manifest.tunnel?.subdomain;
|
|
7511
8264
|
if (existingSubdomain) {
|
|
@@ -7543,7 +8296,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7543
8296
|
try {
|
|
7544
8297
|
let manifest = {};
|
|
7545
8298
|
try {
|
|
7546
|
-
const manifestContent = await (0,
|
|
8299
|
+
const manifestContent = await (0, import_promises8.readFile)(manifestPath, "utf-8");
|
|
7547
8300
|
manifest = JSON.parse(manifestContent);
|
|
7548
8301
|
} catch {
|
|
7549
8302
|
}
|
|
@@ -7551,8 +8304,8 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7551
8304
|
manifest.tunnel = {};
|
|
7552
8305
|
}
|
|
7553
8306
|
manifest.tunnel.subdomain = tunnelSubdomain;
|
|
7554
|
-
await (0,
|
|
7555
|
-
await (0,
|
|
8307
|
+
await (0, import_promises8.mkdir)(import_node_path12.default.dirname(manifestPath), { recursive: true });
|
|
8308
|
+
await (0, import_promises8.writeFile)(
|
|
7556
8309
|
manifestPath,
|
|
7557
8310
|
JSON.stringify(manifest, null, 2),
|
|
7558
8311
|
"utf-8"
|
|
@@ -7606,10 +8359,10 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7606
8359
|
let args;
|
|
7607
8360
|
try {
|
|
7608
8361
|
const projectRequire = createRequire4(
|
|
7609
|
-
|
|
8362
|
+
import_node_path12.default.join(projectPath, "package.json")
|
|
7610
8363
|
);
|
|
7611
8364
|
const tsxPkgPath = projectRequire.resolve("tsx/package.json");
|
|
7612
|
-
const tsxPkg = JSON.parse(await (0,
|
|
8365
|
+
const tsxPkg = JSON.parse(await (0, import_promises8.readFile)(tsxPkgPath, "utf-8"));
|
|
7613
8366
|
let binPath;
|
|
7614
8367
|
if (typeof tsxPkg.bin === "string") {
|
|
7615
8368
|
binPath = tsxPkg.bin;
|
|
@@ -7618,7 +8371,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7618
8371
|
} else {
|
|
7619
8372
|
throw new Error("No bin field found in tsx package.json");
|
|
7620
8373
|
}
|
|
7621
|
-
const tsxBin =
|
|
8374
|
+
const tsxBin = import_node_path12.default.resolve(import_node_path12.default.dirname(tsxPkgPath), binPath);
|
|
7622
8375
|
cmd = "node";
|
|
7623
8376
|
args = [tsxBin, "watch", serverFile];
|
|
7624
8377
|
} catch (error) {
|
|
@@ -7707,10 +8460,10 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7707
8460
|
const chokidar = chokidarModule.default || chokidarModule;
|
|
7708
8461
|
const { fileURLToPath: fileURLToPath3 } = await import("url");
|
|
7709
8462
|
const { createRequire: createRequire3 } = await import("module");
|
|
7710
|
-
const projectTsconfigPath =
|
|
8463
|
+
const projectTsconfigPath = import_node_path12.default.join(projectPath, "tsconfig.json");
|
|
7711
8464
|
let tsconfigAvailable = false;
|
|
7712
8465
|
try {
|
|
7713
|
-
await (0,
|
|
8466
|
+
await (0, import_promises8.access)(projectTsconfigPath);
|
|
7714
8467
|
tsconfigAvailable = true;
|
|
7715
8468
|
process.env.TSX_TSCONFIG_PATH = projectTsconfigPath;
|
|
7716
8469
|
if (process.cwd() !== projectPath) process.chdir(projectPath);
|
|
@@ -7719,7 +8472,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7719
8472
|
let tsxLoaderActive = false;
|
|
7720
8473
|
try {
|
|
7721
8474
|
const projectRequire = createRequire3(
|
|
7722
|
-
|
|
8475
|
+
import_node_path12.default.join(projectPath, "package.json")
|
|
7723
8476
|
);
|
|
7724
8477
|
const tsxEsmApiPath = projectRequire.resolve("tsx/esm/api");
|
|
7725
8478
|
const tsxEsmApi = await import((0, import_node_url3.pathToFileURL)(tsxEsmApiPath).href);
|
|
@@ -7750,7 +8503,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7750
8503
|
)
|
|
7751
8504
|
);
|
|
7752
8505
|
}
|
|
7753
|
-
const serverFilePath =
|
|
8506
|
+
const serverFilePath = import_node_path12.default.join(projectPath, serverFile);
|
|
7754
8507
|
const serverFileUrl = (0, import_node_url3.pathToFileURL)(serverFilePath).href;
|
|
7755
8508
|
globalThis.__mcpUseHmrMode = true;
|
|
7756
8509
|
const importServerModule = async () => {
|
|
@@ -7847,8 +8600,8 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7847
8600
|
}
|
|
7848
8601
|
let watcher = chokidar.watch(".", {
|
|
7849
8602
|
cwd: projectPath,
|
|
7850
|
-
ignored: (
|
|
7851
|
-
const normalizedPath =
|
|
8603
|
+
ignored: (path11, stats) => {
|
|
8604
|
+
const normalizedPath = path11.replace(/\\/g, "/");
|
|
7852
8605
|
if (/(^|\/)\.[^/]/.test(normalizedPath)) {
|
|
7853
8606
|
return true;
|
|
7854
8607
|
}
|
|
@@ -8022,10 +8775,10 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
8022
8775
|
}
|
|
8023
8776
|
tunnelUrl = void 0;
|
|
8024
8777
|
if (withTunnel) {
|
|
8025
|
-
const manifestPath =
|
|
8778
|
+
const manifestPath = import_node_path12.default.join(projectPath, "dist", "mcp-use.json");
|
|
8026
8779
|
let existingSubdomain;
|
|
8027
8780
|
try {
|
|
8028
|
-
const manifestContent = await (0,
|
|
8781
|
+
const manifestContent = await (0, import_promises8.readFile)(manifestPath, "utf-8");
|
|
8029
8782
|
const manifest = JSON.parse(manifestContent);
|
|
8030
8783
|
existingSubdomain = manifest.tunnel?.subdomain;
|
|
8031
8784
|
if (existingSubdomain) {
|
|
@@ -8059,16 +8812,16 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
8059
8812
|
tunnelSubdomain = tunnelInfo.subdomain;
|
|
8060
8813
|
process.env.MCP_URL = tunnelUrl;
|
|
8061
8814
|
try {
|
|
8062
|
-
const mPath =
|
|
8815
|
+
const mPath = import_node_path12.default.join(projectPath, "dist", "mcp-use.json");
|
|
8063
8816
|
let manifest = {};
|
|
8064
8817
|
try {
|
|
8065
|
-
manifest = JSON.parse(await (0,
|
|
8818
|
+
manifest = JSON.parse(await (0, import_promises8.readFile)(mPath, "utf-8"));
|
|
8066
8819
|
} catch {
|
|
8067
8820
|
}
|
|
8068
8821
|
if (!manifest.tunnel) manifest.tunnel = {};
|
|
8069
8822
|
manifest.tunnel.subdomain = tunnelSubdomain;
|
|
8070
|
-
await (0,
|
|
8071
|
-
await (0,
|
|
8823
|
+
await (0, import_promises8.mkdir)(import_node_path12.default.dirname(mPath), { recursive: true });
|
|
8824
|
+
await (0, import_promises8.writeFile)(mPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
8072
8825
|
} catch {
|
|
8073
8826
|
}
|
|
8074
8827
|
} else {
|
|
@@ -8171,7 +8924,7 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
8171
8924
|
"Folder holding the MCP entry + resources (e.g. 'src/mcp' for Next.js apps)"
|
|
8172
8925
|
).option("--port <port>", "Server port", "3000").option("--tunnel", "Expose server through a tunnel").action(async (options) => {
|
|
8173
8926
|
try {
|
|
8174
|
-
const projectPath =
|
|
8927
|
+
const projectPath = import_node_path12.default.resolve(options.path);
|
|
8175
8928
|
const portFlagProvided = process.argv.includes("--port") || process.argv.includes("-p") || process.argv.some((arg) => arg.startsWith("--port=")) || process.argv.some((arg) => arg.startsWith("-p="));
|
|
8176
8929
|
let port = portFlagProvided ? parseInt(options.port, 10) : parseInt(process.env.PORT || options.port || "3000", 10);
|
|
8177
8930
|
if (!await isPortAvailable(port)) {
|
|
@@ -8189,10 +8942,10 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
8189
8942
|
let tunnelSubdomain = void 0;
|
|
8190
8943
|
if (options.tunnel) {
|
|
8191
8944
|
try {
|
|
8192
|
-
const manifestPath2 =
|
|
8945
|
+
const manifestPath2 = import_node_path12.default.join(projectPath, "dist", "mcp-use.json");
|
|
8193
8946
|
let existingSubdomain;
|
|
8194
8947
|
try {
|
|
8195
|
-
const manifestContent = await (0,
|
|
8948
|
+
const manifestContent = await (0, import_promises8.readFile)(manifestPath2, "utf-8");
|
|
8196
8949
|
const manifest = JSON.parse(manifestContent);
|
|
8197
8950
|
existingSubdomain = manifest.tunnel?.subdomain;
|
|
8198
8951
|
if (existingSubdomain) {
|
|
@@ -8236,7 +8989,7 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
8236
8989
|
try {
|
|
8237
8990
|
let manifest = {};
|
|
8238
8991
|
try {
|
|
8239
|
-
const manifestContent = await (0,
|
|
8992
|
+
const manifestContent = await (0, import_promises8.readFile)(manifestPath2, "utf-8");
|
|
8240
8993
|
manifest = JSON.parse(manifestContent);
|
|
8241
8994
|
} catch {
|
|
8242
8995
|
}
|
|
@@ -8244,8 +8997,8 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
8244
8997
|
manifest.tunnel = {};
|
|
8245
8998
|
}
|
|
8246
8999
|
manifest.tunnel.subdomain = subdomain;
|
|
8247
|
-
await (0,
|
|
8248
|
-
await (0,
|
|
9000
|
+
await (0, import_promises8.mkdir)(import_node_path12.default.dirname(manifestPath2), { recursive: true });
|
|
9001
|
+
await (0, import_promises8.writeFile)(
|
|
8249
9002
|
manifestPath2,
|
|
8250
9003
|
JSON.stringify(manifest, null, 2),
|
|
8251
9004
|
"utf-8"
|
|
@@ -8263,12 +9016,12 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
8263
9016
|
}
|
|
8264
9017
|
}
|
|
8265
9018
|
let serverFile;
|
|
8266
|
-
const manifestPath =
|
|
9019
|
+
const manifestPath = import_node_path12.default.join(projectPath, "dist", "mcp-use.json");
|
|
8267
9020
|
try {
|
|
8268
|
-
const manifestContent = await (0,
|
|
9021
|
+
const manifestContent = await (0, import_promises8.readFile)(manifestPath, "utf-8");
|
|
8269
9022
|
const manifest = JSON.parse(manifestContent);
|
|
8270
9023
|
if (manifest.entryPoint) {
|
|
8271
|
-
await (0,
|
|
9024
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, manifest.entryPoint));
|
|
8272
9025
|
serverFile = manifest.entryPoint;
|
|
8273
9026
|
}
|
|
8274
9027
|
} catch {
|
|
@@ -8289,7 +9042,7 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
8289
9042
|
];
|
|
8290
9043
|
for (const candidate of serverCandidates) {
|
|
8291
9044
|
try {
|
|
8292
|
-
await (0,
|
|
9045
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, candidate));
|
|
8293
9046
|
serverFile = candidate;
|
|
8294
9047
|
break;
|
|
8295
9048
|
} catch {
|
|
@@ -8340,13 +9093,13 @@ Looked for:
|
|
|
8340
9093
|
if (isTsEntry) {
|
|
8341
9094
|
try {
|
|
8342
9095
|
const projectRequire = (0, import_node_module2.createRequire)(
|
|
8343
|
-
|
|
9096
|
+
import_node_path12.default.join(projectPath, "package.json")
|
|
8344
9097
|
);
|
|
8345
9098
|
const tsxPkgPath = projectRequire.resolve("tsx/package.json");
|
|
8346
|
-
const tsxPkg = JSON.parse(await (0,
|
|
9099
|
+
const tsxPkg = JSON.parse(await (0, import_promises8.readFile)(tsxPkgPath, "utf-8"));
|
|
8347
9100
|
const binField = typeof tsxPkg.bin === "string" ? tsxPkg.bin : tsxPkg.bin?.tsx ?? Object.values(tsxPkg.bin ?? {})[0];
|
|
8348
9101
|
if (!binField) throw new Error("tsx bin entry not found");
|
|
8349
|
-
const tsxBin =
|
|
9102
|
+
const tsxBin = import_node_path12.default.resolve(import_node_path12.default.dirname(tsxPkgPath), binField);
|
|
8350
9103
|
spawnCmd = "node";
|
|
8351
9104
|
spawnArgs = [tsxBin, serverFile];
|
|
8352
9105
|
} catch (error) {
|
|
@@ -8359,7 +9112,7 @@ Looked for:
|
|
|
8359
9112
|
spawnArgs = ["tsx", serverFile];
|
|
8360
9113
|
}
|
|
8361
9114
|
}
|
|
8362
|
-
const serverProc = (0,
|
|
9115
|
+
const serverProc = (0, import_node_child_process11.spawn)(spawnCmd, spawnArgs, {
|
|
8363
9116
|
cwd: projectPath,
|
|
8364
9117
|
stdio: "inherit",
|
|
8365
9118
|
env: env2
|
|
@@ -8492,10 +9245,11 @@ program.addCommand(createClientCommand());
|
|
|
8492
9245
|
program.addCommand(createDeploymentsCommand());
|
|
8493
9246
|
program.addCommand(createServersCommand());
|
|
8494
9247
|
program.addCommand(createSkillsCommand());
|
|
9248
|
+
program.addCommand(createScreenshotCommand());
|
|
8495
9249
|
program.command("generate-types").description(
|
|
8496
9250
|
"Generate TypeScript type definitions for tools (writes .mcp-use/tool-registry.d.ts)"
|
|
8497
9251
|
).option("-p, --path <path>", "Path to project directory", process.cwd()).option("--server <file>", "Server entry file", "index.ts").action(async (options) => {
|
|
8498
|
-
const projectPath =
|
|
9252
|
+
const projectPath = import_node_path12.default.resolve(options.path);
|
|
8499
9253
|
try {
|
|
8500
9254
|
console.log(source_default.blue("Generating tool registry types..."));
|
|
8501
9255
|
const result = await generateToolRegistryTypesForServer(
|