@mcp-use/cli 3.2.0-canary.5 → 3.2.0-canary.7
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 +72 -0
- package/dist/commands/screenshot.d.ts.map +1 -0
- package/dist/index.cjs +1097 -290
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1048 -241
- package/dist/index.js.map +1 -1
- package/dist/utils/cdp-screenshot.d.ts +44 -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,764 @@ 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
|
+
let userDataDir;
|
|
2962
|
+
let child;
|
|
2963
|
+
let cdp;
|
|
2964
|
+
let cleanedUp = false;
|
|
2965
|
+
const cleanup = () => {
|
|
2966
|
+
if (cleanedUp) return;
|
|
2967
|
+
cleanedUp = true;
|
|
2968
|
+
cdp?.close();
|
|
2969
|
+
if (child && !child.killed) {
|
|
2970
|
+
try {
|
|
2971
|
+
child.kill("SIGTERM");
|
|
2972
|
+
} catch {
|
|
2973
|
+
}
|
|
2974
|
+
const localChild = child;
|
|
2975
|
+
const killTimer = setTimeout(() => {
|
|
2976
|
+
if (!localChild.killed) {
|
|
2977
|
+
try {
|
|
2978
|
+
localChild.kill("SIGKILL");
|
|
2979
|
+
} catch {
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
}, 2e3);
|
|
2983
|
+
killTimer.unref();
|
|
2984
|
+
}
|
|
2985
|
+
if (userDataDir) {
|
|
2986
|
+
try {
|
|
2987
|
+
(0, import_node_fs6.rmSync)(userDataDir, { recursive: true, force: true });
|
|
2988
|
+
} catch {
|
|
2989
|
+
}
|
|
2990
|
+
}
|
|
2991
|
+
};
|
|
2992
|
+
try {
|
|
2993
|
+
let wsUrl;
|
|
2994
|
+
if (opts.cdpUrl) {
|
|
2995
|
+
wsUrl = opts.cdpUrl;
|
|
2996
|
+
} else {
|
|
2997
|
+
if (!opts.chromePath) {
|
|
2998
|
+
throw new Error(
|
|
2999
|
+
"captureScreenshot requires either `cdpUrl` or `chromePath`"
|
|
3000
|
+
);
|
|
3001
|
+
}
|
|
3002
|
+
userDataDir = (0, import_node_fs6.mkdtempSync)(import_node_path4.default.join(import_node_os5.default.tmpdir(), "mcp-use-chrome-"));
|
|
3003
|
+
const chromeArgs = [
|
|
3004
|
+
"--headless=new",
|
|
3005
|
+
"--remote-debugging-port=0",
|
|
3006
|
+
`--user-data-dir=${userDataDir}`,
|
|
3007
|
+
"--no-first-run",
|
|
3008
|
+
"--no-default-browser-check",
|
|
3009
|
+
"--disable-extensions",
|
|
3010
|
+
"--disable-gpu",
|
|
3011
|
+
"--hide-scrollbars",
|
|
3012
|
+
"--mute-audio",
|
|
3013
|
+
`--window-size=${opts.width},${opts.height}`,
|
|
3014
|
+
"about:blank"
|
|
3015
|
+
];
|
|
3016
|
+
child = (0, import_node_child_process8.spawn)(opts.chromePath, chromeArgs, {
|
|
3017
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
3018
|
+
});
|
|
3019
|
+
child.stdout?.resume();
|
|
3020
|
+
wsUrl = await waitForDevToolsUrl(child);
|
|
3021
|
+
}
|
|
3022
|
+
const ws = new import_ws.default(wsUrl);
|
|
3023
|
+
await new Promise((resolve2, reject) => {
|
|
3024
|
+
const onOpen = () => {
|
|
3025
|
+
ws.off("error", onError);
|
|
3026
|
+
resolve2();
|
|
3027
|
+
};
|
|
3028
|
+
const onError = (err) => {
|
|
3029
|
+
ws.off("open", onOpen);
|
|
3030
|
+
reject(err);
|
|
3031
|
+
};
|
|
3032
|
+
ws.once("open", onOpen);
|
|
3033
|
+
ws.once("error", onError);
|
|
3034
|
+
});
|
|
3035
|
+
cdp = new CdpClient(ws);
|
|
3036
|
+
let sessionId;
|
|
3037
|
+
if (opts.cdpUrl) {
|
|
3038
|
+
const attachPromise = new Promise((resolve2, reject) => {
|
|
3039
|
+
const timer = setTimeout(
|
|
3040
|
+
() => reject(
|
|
3041
|
+
new Error(
|
|
3042
|
+
"Timed out waiting for Target.attachedToTarget event from remote CDP"
|
|
3043
|
+
)
|
|
3044
|
+
),
|
|
3045
|
+
1e4
|
|
3046
|
+
);
|
|
3047
|
+
const onMessage = (data) => {
|
|
3048
|
+
try {
|
|
3049
|
+
const msg = JSON.parse(data.toString());
|
|
3050
|
+
if (msg.method === "Target.attachedToTarget" && msg.params?.targetInfo?.type === "page" && typeof msg.params.sessionId === "string") {
|
|
3051
|
+
clearTimeout(timer);
|
|
3052
|
+
ws.off("message", onMessage);
|
|
3053
|
+
resolve2(msg.params.sessionId);
|
|
3054
|
+
}
|
|
3055
|
+
} catch {
|
|
3056
|
+
}
|
|
3057
|
+
};
|
|
3058
|
+
ws.on("message", onMessage);
|
|
3059
|
+
});
|
|
3060
|
+
await cdp.send("Target.setAutoAttach", {
|
|
3061
|
+
autoAttach: true,
|
|
3062
|
+
waitForDebuggerOnStart: false,
|
|
3063
|
+
flatten: true
|
|
3064
|
+
});
|
|
3065
|
+
sessionId = await attachPromise;
|
|
3066
|
+
} else {
|
|
3067
|
+
const { targetId } = await cdp.send(
|
|
3068
|
+
"Target.createTarget",
|
|
3069
|
+
{ url: "about:blank" }
|
|
2759
3070
|
);
|
|
2760
|
-
|
|
2761
|
-
|
|
3071
|
+
const attach = await cdp.send(
|
|
3072
|
+
"Target.attachToTarget",
|
|
3073
|
+
{ targetId, flatten: true }
|
|
2762
3074
|
);
|
|
2763
|
-
|
|
3075
|
+
sessionId = attach.sessionId;
|
|
2764
3076
|
}
|
|
2765
|
-
|
|
3077
|
+
await cdp.send("Page.enable", {}, sessionId);
|
|
3078
|
+
await cdp.send(
|
|
3079
|
+
"Emulation.setDeviceMetricsOverride",
|
|
3080
|
+
{
|
|
3081
|
+
width: opts.width,
|
|
3082
|
+
height: opts.height,
|
|
3083
|
+
deviceScaleFactor: 1,
|
|
3084
|
+
mobile: false
|
|
3085
|
+
},
|
|
3086
|
+
sessionId
|
|
3087
|
+
);
|
|
3088
|
+
await cdp.send(
|
|
3089
|
+
"Emulation.setEmulatedMedia",
|
|
3090
|
+
{
|
|
3091
|
+
features: [
|
|
3092
|
+
{ name: "prefers-color-scheme", value: opts.theme },
|
|
3093
|
+
{ name: "prefers-reduced-motion", value: "reduce" }
|
|
3094
|
+
]
|
|
3095
|
+
},
|
|
3096
|
+
sessionId
|
|
3097
|
+
);
|
|
3098
|
+
if (opts.bundle !== void 0) {
|
|
3099
|
+
const payload = JSON.stringify(JSON.stringify(opts.bundle));
|
|
3100
|
+
await cdp.send(
|
|
3101
|
+
"Page.addScriptToEvaluateOnNewDocument",
|
|
3102
|
+
{
|
|
3103
|
+
source: `globalThis.__mcpUsePreviewBundle = JSON.parse(${payload});`,
|
|
3104
|
+
runImmediately: true
|
|
3105
|
+
},
|
|
3106
|
+
sessionId
|
|
3107
|
+
);
|
|
3108
|
+
}
|
|
3109
|
+
await cdp.send("Page.navigate", { url: opts.url }, sessionId);
|
|
3110
|
+
const start = Date.now();
|
|
3111
|
+
const exprSelector = JSON.stringify(opts.waitForSelector);
|
|
3112
|
+
while (true) {
|
|
3113
|
+
const r = await cdp.send(
|
|
3114
|
+
"Runtime.evaluate",
|
|
3115
|
+
{
|
|
3116
|
+
expression: `!!document.querySelector(${exprSelector})`,
|
|
3117
|
+
returnByValue: true
|
|
3118
|
+
},
|
|
3119
|
+
sessionId
|
|
3120
|
+
);
|
|
3121
|
+
if (r.result?.value === true) break;
|
|
3122
|
+
if (Date.now() - start > opts.timeoutMs) {
|
|
3123
|
+
throw new Error(
|
|
3124
|
+
`Timed out after ${opts.timeoutMs}ms waiting for selector "${opts.waitForSelector}"`
|
|
3125
|
+
);
|
|
3126
|
+
}
|
|
3127
|
+
await new Promise((res) => setTimeout(res, 100));
|
|
3128
|
+
}
|
|
3129
|
+
if (opts.delayMs && opts.delayMs > 0) {
|
|
3130
|
+
await new Promise((res) => setTimeout(res, opts.delayMs));
|
|
3131
|
+
}
|
|
3132
|
+
const shot = await cdp.send(
|
|
3133
|
+
"Page.captureScreenshot",
|
|
3134
|
+
{
|
|
3135
|
+
format: "png",
|
|
3136
|
+
clip: {
|
|
3137
|
+
x: 0,
|
|
3138
|
+
y: 0,
|
|
3139
|
+
width: opts.width,
|
|
3140
|
+
height: opts.height,
|
|
3141
|
+
scale: 1
|
|
3142
|
+
}
|
|
3143
|
+
},
|
|
3144
|
+
sessionId
|
|
3145
|
+
);
|
|
3146
|
+
(0, import_node_fs6.writeFileSync)(opts.outputPath, Buffer.from(shot.data, "base64"));
|
|
3147
|
+
} finally {
|
|
3148
|
+
cleanup();
|
|
2766
3149
|
}
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3152
|
+
// src/utils/chrome-path.ts
|
|
3153
|
+
init_cjs_shims();
|
|
3154
|
+
var import_node_fs7 = require("fs");
|
|
3155
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
3156
|
+
var ENV_VAR_NAMES = [
|
|
3157
|
+
"MCP_USE_CHROME_PATH",
|
|
3158
|
+
"PUPPETEER_EXECUTABLE_PATH",
|
|
3159
|
+
"CHROME_PATH"
|
|
3160
|
+
];
|
|
3161
|
+
var DARWIN_PATHS = [
|
|
3162
|
+
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
|
|
3163
|
+
"/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",
|
|
3164
|
+
"/Applications/Chromium.app/Contents/MacOS/Chromium",
|
|
3165
|
+
"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
|
|
3166
|
+
"/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"
|
|
3167
|
+
];
|
|
3168
|
+
var LINUX_BINARIES = [
|
|
3169
|
+
"google-chrome-stable",
|
|
3170
|
+
"google-chrome",
|
|
3171
|
+
"chromium",
|
|
3172
|
+
"chromium-browser",
|
|
3173
|
+
"microsoft-edge",
|
|
3174
|
+
"microsoft-edge-stable",
|
|
3175
|
+
"brave-browser"
|
|
3176
|
+
];
|
|
3177
|
+
var WIN_SUBPATHS = [
|
|
3178
|
+
"Google\\Chrome\\Application\\chrome.exe",
|
|
3179
|
+
"Microsoft\\Edge\\Application\\msedge.exe",
|
|
3180
|
+
"BraveSoftware\\Brave-Browser\\Application\\brave.exe",
|
|
3181
|
+
"Chromium\\Application\\chrome.exe"
|
|
3182
|
+
];
|
|
3183
|
+
function isAccessible(p) {
|
|
3184
|
+
try {
|
|
3185
|
+
(0, import_node_fs7.accessSync)(p, import_node_fs7.constants.F_OK);
|
|
3186
|
+
return true;
|
|
3187
|
+
} catch {
|
|
3188
|
+
return false;
|
|
2770
3189
|
}
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
3190
|
+
}
|
|
3191
|
+
function findOnPath(binary) {
|
|
3192
|
+
const PATH = process.env.PATH ?? "";
|
|
3193
|
+
for (const dir of PATH.split(":")) {
|
|
3194
|
+
if (!dir) continue;
|
|
3195
|
+
const candidate = import_node_path5.default.posix.join(dir, binary);
|
|
3196
|
+
if (isAccessible(candidate)) return candidate;
|
|
3197
|
+
}
|
|
3198
|
+
return null;
|
|
3199
|
+
}
|
|
3200
|
+
function findChrome() {
|
|
3201
|
+
for (const name of ENV_VAR_NAMES) {
|
|
3202
|
+
const v = process.env[name];
|
|
3203
|
+
if (v && isAccessible(v)) return v;
|
|
3204
|
+
}
|
|
3205
|
+
if (process.platform === "darwin") {
|
|
3206
|
+
for (const p of DARWIN_PATHS) {
|
|
3207
|
+
if (isAccessible(p)) return p;
|
|
3208
|
+
}
|
|
2774
3209
|
return null;
|
|
2775
3210
|
}
|
|
3211
|
+
if (process.platform === "linux") {
|
|
3212
|
+
for (const bin of LINUX_BINARIES) {
|
|
3213
|
+
const p = findOnPath(bin);
|
|
3214
|
+
if (p) return p;
|
|
3215
|
+
}
|
|
3216
|
+
return null;
|
|
3217
|
+
}
|
|
3218
|
+
if (process.platform === "win32") {
|
|
3219
|
+
const dirs = [
|
|
3220
|
+
process.env["ProgramFiles"],
|
|
3221
|
+
process.env["ProgramFiles(x86)"],
|
|
3222
|
+
process.env["LocalAppData"]
|
|
3223
|
+
].filter((d) => Boolean(d));
|
|
3224
|
+
for (const dir of dirs) {
|
|
3225
|
+
for (const sub of WIN_SUBPATHS) {
|
|
3226
|
+
const candidate = import_node_path5.default.join(dir, sub);
|
|
3227
|
+
if (isAccessible(candidate)) return candidate;
|
|
3228
|
+
}
|
|
3229
|
+
}
|
|
3230
|
+
return null;
|
|
3231
|
+
}
|
|
3232
|
+
return null;
|
|
3233
|
+
}
|
|
3234
|
+
function resolveChromePath() {
|
|
3235
|
+
const found = findChrome();
|
|
3236
|
+
if (found) return found;
|
|
3237
|
+
throw new Error(
|
|
3238
|
+
"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."
|
|
3239
|
+
);
|
|
3240
|
+
}
|
|
3241
|
+
|
|
3242
|
+
// src/commands/screenshot.ts
|
|
3243
|
+
function detectToolResourceUri(tool) {
|
|
3244
|
+
if (!tool) return null;
|
|
3245
|
+
const meta = tool._meta;
|
|
3246
|
+
if (!meta) return null;
|
|
3247
|
+
const uiMeta = meta.ui ?? void 0;
|
|
3248
|
+
return uiMeta?.resourceUri ?? meta["openai/outputTemplate"] ?? null;
|
|
3249
|
+
}
|
|
3250
|
+
async function captureToolScreenshot(inputs, options = {}) {
|
|
3251
|
+
const width = options.width ?? 800;
|
|
3252
|
+
const height = options.height ?? 600;
|
|
3253
|
+
const theme = options.theme ?? "light";
|
|
3254
|
+
const timeoutMs = options.timeoutMs ?? 3e4;
|
|
3255
|
+
const delayMs = options.delayMs ?? 0;
|
|
3256
|
+
const chromePath = options.cdpUrl ? void 0 : resolveChromePath();
|
|
3257
|
+
const view = extractViewName(inputs.resourceUri);
|
|
3258
|
+
const devOptions = {
|
|
3259
|
+
width: String(width),
|
|
3260
|
+
height: String(height),
|
|
3261
|
+
theme,
|
|
3262
|
+
timeout: String(timeoutMs),
|
|
3263
|
+
inspector: options.inspector,
|
|
3264
|
+
quiet: options.quiet
|
|
3265
|
+
};
|
|
3266
|
+
let devHandle;
|
|
2776
3267
|
try {
|
|
2777
|
-
|
|
2778
|
-
const
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
3268
|
+
devHandle = await ensureDevServer(devOptions);
|
|
3269
|
+
const resourceContents = await inputs.session.readResource(
|
|
3270
|
+
inputs.resourceUri
|
|
3271
|
+
);
|
|
3272
|
+
const bundle = {
|
|
3273
|
+
resourceUri: inputs.resourceUri,
|
|
3274
|
+
resourceContents,
|
|
3275
|
+
toolInput: inputs.toolArgs,
|
|
3276
|
+
toolOutput: inputs.toolOutput
|
|
3277
|
+
};
|
|
3278
|
+
const previewUrl = new URL(`/inspector/preview/${view}`, devHandle.url);
|
|
3279
|
+
previewUrl.searchParams.set("theme", theme);
|
|
3280
|
+
const ts = timestampSuffix();
|
|
3281
|
+
const outputPath = import_node_path6.default.resolve(options.output ?? `./${view}-${ts}.png`);
|
|
3282
|
+
await (0, import_promises5.mkdir)(import_node_path6.default.dirname(outputPath), { recursive: true });
|
|
3283
|
+
await captureScreenshot({
|
|
3284
|
+
url: previewUrl.toString(),
|
|
3285
|
+
width,
|
|
3286
|
+
height,
|
|
3287
|
+
theme,
|
|
3288
|
+
waitForSelector: options.waitFor ?? 'body[data-view-ready="true"]',
|
|
3289
|
+
timeoutMs,
|
|
3290
|
+
outputPath,
|
|
3291
|
+
chromePath,
|
|
3292
|
+
cdpUrl: options.cdpUrl,
|
|
3293
|
+
delayMs: Number.isFinite(delayMs) && delayMs > 0 ? delayMs : 0,
|
|
3294
|
+
bundle
|
|
3295
|
+
});
|
|
3296
|
+
return { outputPath, width, height, view };
|
|
3297
|
+
} finally {
|
|
3298
|
+
killChild(devHandle?.child);
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
function getFreePort() {
|
|
3302
|
+
return new Promise((resolve2, reject) => {
|
|
3303
|
+
const srv = (0, import_node_net.createServer)();
|
|
3304
|
+
srv.unref();
|
|
3305
|
+
srv.on("error", reject);
|
|
3306
|
+
srv.listen(0, () => {
|
|
3307
|
+
const addr = srv.address();
|
|
3308
|
+
if (typeof addr === "object" && addr) {
|
|
3309
|
+
const port = addr.port;
|
|
3310
|
+
srv.close(() => resolve2(port));
|
|
2788
3311
|
} else {
|
|
2789
|
-
|
|
2790
|
-
url: config.url,
|
|
2791
|
-
headers: config.authToken ? { Authorization: `Bearer ${config.authToken}` } : void 0,
|
|
2792
|
-
clientInfo: cliClientInfo
|
|
2793
|
-
});
|
|
3312
|
+
srv.close(() => reject(new Error("Failed to allocate free port")));
|
|
2794
3313
|
}
|
|
2795
|
-
}
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
3314
|
+
});
|
|
3315
|
+
});
|
|
3316
|
+
}
|
|
3317
|
+
async function probeServer(url, timeoutMs = 1500) {
|
|
3318
|
+
const controller = new AbortController();
|
|
3319
|
+
const t = setTimeout(() => controller.abort(), timeoutMs);
|
|
3320
|
+
try {
|
|
3321
|
+
const u = new URL("/inspector/health", url);
|
|
3322
|
+
const res = await fetch(u, { signal: controller.signal });
|
|
3323
|
+
if (!res.ok) return false;
|
|
3324
|
+
const ct = res.headers.get("content-type") ?? "";
|
|
3325
|
+
if (!ct.includes("application/json")) return false;
|
|
3326
|
+
const body = await res.json();
|
|
3327
|
+
return body?.status === "ok";
|
|
3328
|
+
} catch {
|
|
3329
|
+
return false;
|
|
3330
|
+
} finally {
|
|
3331
|
+
clearTimeout(t);
|
|
3332
|
+
}
|
|
3333
|
+
}
|
|
3334
|
+
async function waitForHealth(url, timeoutMs = 15e3) {
|
|
3335
|
+
const deadline = Date.now() + timeoutMs;
|
|
3336
|
+
while (Date.now() < deadline) {
|
|
3337
|
+
if (await probeServer(url)) return true;
|
|
3338
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
3339
|
+
}
|
|
3340
|
+
return false;
|
|
3341
|
+
}
|
|
3342
|
+
function resolveInspectorCli() {
|
|
3343
|
+
const candidateRoots = /* @__PURE__ */ new Set();
|
|
3344
|
+
const moduleDir = typeof __dirname !== "undefined" ? __dirname : import_node_path6.default.dirname(new URL(importMetaUrl).pathname);
|
|
3345
|
+
candidateRoots.add(moduleDir);
|
|
3346
|
+
candidateRoots.add(process.cwd());
|
|
3347
|
+
for (const start of candidateRoots) {
|
|
3348
|
+
let dir = start;
|
|
3349
|
+
while (true) {
|
|
3350
|
+
const candidate = import_node_path6.default.join(
|
|
3351
|
+
dir,
|
|
3352
|
+
"node_modules",
|
|
3353
|
+
"@mcp-use",
|
|
3354
|
+
"inspector",
|
|
3355
|
+
"dist",
|
|
3356
|
+
"cli.js"
|
|
3357
|
+
);
|
|
3358
|
+
if ((0, import_node_fs8.existsSync)(candidate)) return candidate;
|
|
3359
|
+
const parent = import_node_path6.default.dirname(dir);
|
|
3360
|
+
if (parent === dir) break;
|
|
3361
|
+
dir = parent;
|
|
3362
|
+
}
|
|
3363
|
+
}
|
|
3364
|
+
throw new Error(
|
|
3365
|
+
"Could not locate `@mcp-use/inspector` in node_modules. Install the inspector package or pass --inspector <url> to use an existing instance."
|
|
3366
|
+
);
|
|
3367
|
+
}
|
|
3368
|
+
async function ensureDevServer(options) {
|
|
3369
|
+
if (options.inspector) {
|
|
3370
|
+
const ok = await probeServer(options.inspector);
|
|
3371
|
+
if (!ok) {
|
|
3372
|
+
throw new Error(
|
|
3373
|
+
`Inspector at ${options.inspector} did not respond on /inspector/health with status:"ok"`
|
|
3374
|
+
);
|
|
3375
|
+
}
|
|
3376
|
+
return { url: options.inspector };
|
|
3377
|
+
}
|
|
3378
|
+
const port = await getFreePort();
|
|
3379
|
+
const url = `http://localhost:${port}`;
|
|
3380
|
+
if (!options.quiet) {
|
|
3381
|
+
console.error(formatInfo(`Starting inspector on port ${port}\u2026`));
|
|
3382
|
+
}
|
|
3383
|
+
const inspectorCli = resolveInspectorCli();
|
|
3384
|
+
const child = (0, import_node_child_process9.spawn)(
|
|
3385
|
+
process.execPath,
|
|
3386
|
+
[inspectorCli, "--port", String(port), "--no-open"],
|
|
3387
|
+
{
|
|
3388
|
+
cwd: process.cwd(),
|
|
3389
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
3390
|
+
env: { ...process.env, MCP_INSPECTOR_MODE: "standalone" }
|
|
3391
|
+
}
|
|
3392
|
+
);
|
|
3393
|
+
const prefix = source_default.gray("[inspector]");
|
|
3394
|
+
if (!options.quiet) {
|
|
3395
|
+
child.stdout?.on("data", (d) => {
|
|
3396
|
+
process.stderr.write(`${prefix} ${d}`);
|
|
3397
|
+
});
|
|
3398
|
+
child.stderr?.on("data", (d) => {
|
|
3399
|
+
process.stderr.write(`${prefix} ${d}`);
|
|
3400
|
+
});
|
|
3401
|
+
} else {
|
|
3402
|
+
child.stdout?.resume();
|
|
3403
|
+
child.stderr?.resume();
|
|
3404
|
+
}
|
|
3405
|
+
const ready = await waitForHealth(url);
|
|
3406
|
+
if (!ready) {
|
|
3407
|
+
child.kill("SIGTERM");
|
|
3408
|
+
throw new Error(`Inspector failed to come up on ${url} within 15s.`);
|
|
3409
|
+
}
|
|
3410
|
+
return { url, child };
|
|
3411
|
+
}
|
|
3412
|
+
function killChild(child) {
|
|
3413
|
+
if (!child || child.killed) return;
|
|
3414
|
+
try {
|
|
3415
|
+
child.kill("SIGTERM");
|
|
3416
|
+
} catch {
|
|
3417
|
+
}
|
|
3418
|
+
}
|
|
3419
|
+
function timestampSuffix(date = /* @__PURE__ */ new Date()) {
|
|
3420
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
3421
|
+
const datePart = `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
3422
|
+
const timePart = `${pad(date.getHours())}-${pad(date.getMinutes())}-${pad(date.getSeconds())}`;
|
|
3423
|
+
return `${datePart}_${timePart}`;
|
|
3424
|
+
}
|
|
3425
|
+
function extractViewName(resourceUri) {
|
|
3426
|
+
const m = resourceUri.match(/^ui:\/\/widget\/(.+)$/);
|
|
3427
|
+
if (!m) return resourceUri;
|
|
3428
|
+
return m[1].replace(/\.html$/, "").replace(/\.[0-9a-f]+$/i, "");
|
|
3429
|
+
}
|
|
3430
|
+
function parseDimension(raw, name) {
|
|
3431
|
+
const n = parseInt(raw, 10);
|
|
3432
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
3433
|
+
throw new Error(`--${name} must be a positive integer (got "${raw}")`);
|
|
3434
|
+
}
|
|
3435
|
+
return n;
|
|
3436
|
+
}
|
|
3437
|
+
var AD_HOC_SESSION_NAME = "__screenshot_ad_hoc__";
|
|
3438
|
+
async function resolveSessionForScreenshot(options) {
|
|
3439
|
+
if (options.session) {
|
|
3440
|
+
const result2 = await getOrRestoreSession(options.session);
|
|
3441
|
+
return result2?.session ?? null;
|
|
3442
|
+
}
|
|
3443
|
+
if (options.mcp) {
|
|
3444
|
+
const client = new import_client2.MCPClient();
|
|
3445
|
+
client.addServer(AD_HOC_SESSION_NAME, {
|
|
3446
|
+
url: options.mcp,
|
|
3447
|
+
clientInfo: getCliClientInfo()
|
|
3448
|
+
});
|
|
3449
|
+
try {
|
|
3450
|
+
const session = await client.createSession(AD_HOC_SESSION_NAME);
|
|
3451
|
+
activeSessions.set(AD_HOC_SESSION_NAME, { client, session });
|
|
3452
|
+
return session;
|
|
3453
|
+
} catch (err) {
|
|
3454
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3455
|
+
console.error(formatError(`Failed to connect to ${options.mcp}: ${msg}`));
|
|
2804
3456
|
return null;
|
|
2805
3457
|
}
|
|
2806
|
-
|
|
3458
|
+
}
|
|
3459
|
+
const result = await getOrRestoreSession(null);
|
|
3460
|
+
return result?.session ?? null;
|
|
3461
|
+
}
|
|
3462
|
+
async function screenshotCommand(options, argsList) {
|
|
3463
|
+
let exitCode = 0;
|
|
3464
|
+
try {
|
|
3465
|
+
if (!options.tool) {
|
|
3466
|
+
console.error(
|
|
3467
|
+
formatError(
|
|
3468
|
+
"--tool <name> is required (optionally with key=value args)."
|
|
3469
|
+
)
|
|
3470
|
+
);
|
|
3471
|
+
exitCode = 1;
|
|
3472
|
+
return;
|
|
3473
|
+
}
|
|
2807
3474
|
try {
|
|
2808
|
-
|
|
3475
|
+
resolveChromePath();
|
|
2809
3476
|
} catch (err) {
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
3477
|
+
console.error(
|
|
3478
|
+
formatError(err instanceof Error ? err.message : String(err))
|
|
3479
|
+
);
|
|
3480
|
+
exitCode = 1;
|
|
3481
|
+
return;
|
|
3482
|
+
}
|
|
3483
|
+
const width = parseDimension(options.width, "width");
|
|
3484
|
+
const height = parseDimension(options.height, "height");
|
|
3485
|
+
const navTimeout = parseInt(options.timeout, 10) || 3e4;
|
|
3486
|
+
const delayMs = options.delay ? parseInt(options.delay, 10) : 0;
|
|
3487
|
+
const session = await resolveSessionForScreenshot(options);
|
|
3488
|
+
if (!session) {
|
|
3489
|
+
exitCode = 1;
|
|
3490
|
+
return;
|
|
3491
|
+
}
|
|
3492
|
+
const tool = session.tools.find((t) => t.name === options.tool);
|
|
3493
|
+
if (!tool) {
|
|
3494
|
+
throw new Error(
|
|
3495
|
+
`Tool "${options.tool}" not found. Available: ${session.tools.map((t) => t.name).join(", ")}`
|
|
3496
|
+
);
|
|
3497
|
+
}
|
|
3498
|
+
const resourceUri = detectToolResourceUri(tool);
|
|
3499
|
+
if (!resourceUri) {
|
|
3500
|
+
throw new Error(
|
|
3501
|
+
`Tool "${options.tool}" does not declare a UI resource (expected _meta.ui.resourceUri or openai/outputTemplate).`
|
|
3502
|
+
);
|
|
3503
|
+
}
|
|
3504
|
+
let toolArgs = {};
|
|
3505
|
+
if (argsList && argsList.length > 0) {
|
|
3506
|
+
try {
|
|
3507
|
+
toolArgs = parseToolArgs(
|
|
3508
|
+
argsList,
|
|
3509
|
+
tool.inputSchema
|
|
2814
3510
|
);
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
3511
|
+
} catch (err) {
|
|
3512
|
+
console.error(
|
|
3513
|
+
formatError(err instanceof Error ? err.message : String(err))
|
|
3514
|
+
);
|
|
3515
|
+
console.log("");
|
|
3516
|
+
console.log(formatInfo("Usage:"));
|
|
3517
|
+
console.log(
|
|
3518
|
+
` npx mcp-use screenshot --tool ${options.tool} key=value [key2=value2 ...]`
|
|
3519
|
+
);
|
|
3520
|
+
console.log(
|
|
3521
|
+
` npx mcp-use screenshot --tool ${options.tool} nested:='{"a":1}' # JSON value`
|
|
3522
|
+
);
|
|
3523
|
+
console.log(
|
|
3524
|
+
` npx mcp-use screenshot --tool ${options.tool} '{"key":"value"}' # full JSON object`
|
|
3525
|
+
);
|
|
3526
|
+
if (tool.inputSchema) {
|
|
3527
|
+
console.log("");
|
|
3528
|
+
console.log(formatInfo("Tool schema:"));
|
|
3529
|
+
console.log(formatSchema(tool.inputSchema));
|
|
2823
3530
|
}
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
} else {
|
|
2827
|
-
throw err;
|
|
3531
|
+
exitCode = 1;
|
|
3532
|
+
return;
|
|
2828
3533
|
}
|
|
2829
3534
|
}
|
|
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: [
|
|
3535
|
+
const toolOutput = await session.callTool(options.tool, toolArgs);
|
|
3536
|
+
const result = await captureToolScreenshot(
|
|
2845
3537
|
{
|
|
2846
|
-
|
|
3538
|
+
session,
|
|
3539
|
+
toolName: options.tool,
|
|
3540
|
+
toolArgs,
|
|
3541
|
+
toolOutput,
|
|
3542
|
+
resourceUri
|
|
3543
|
+
},
|
|
3544
|
+
{
|
|
3545
|
+
width,
|
|
3546
|
+
height,
|
|
3547
|
+
theme: options.theme,
|
|
3548
|
+
output: options.output,
|
|
3549
|
+
waitFor: options.waitFor,
|
|
3550
|
+
delayMs,
|
|
3551
|
+
timeoutMs: navTimeout,
|
|
3552
|
+
inspector: options.inspector,
|
|
3553
|
+
quiet: options.quiet,
|
|
3554
|
+
cdpUrl: options.cdpUrl
|
|
2847
3555
|
}
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
3556
|
+
);
|
|
3557
|
+
console.log(
|
|
3558
|
+
`Saved screenshot: ${result.outputPath} (${result.width}\xD7${result.height})`
|
|
3559
|
+
);
|
|
3560
|
+
} catch (err) {
|
|
3561
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
3562
|
+
console.error(formatError(`Screenshot failed: ${msg}`));
|
|
3563
|
+
exitCode = 1;
|
|
3564
|
+
} finally {
|
|
3565
|
+
await cleanupAndExit(exitCode);
|
|
3566
|
+
}
|
|
3567
|
+
}
|
|
3568
|
+
function createScreenshotCommand() {
|
|
3569
|
+
return new import_commander.Command("screenshot").description(
|
|
3570
|
+
"Render an MCP Apps view headlessly and save a PNG by calling a tool and rendering its UI resource with the result."
|
|
3571
|
+
).argument(
|
|
3572
|
+
"[args...]",
|
|
3573
|
+
"Tool args as key=value pairs (use key:=<json> for nested values, or pass a single JSON object)."
|
|
3574
|
+
).option(
|
|
3575
|
+
"--tool <name>",
|
|
3576
|
+
"Tool to call. Its UI resource is rendered with the result."
|
|
3577
|
+
).option("--width <px>", "Browser viewport width in pixels.", "800").option("--height <px>", "Browser viewport height in pixels.", "600").option(
|
|
3578
|
+
"--inspector <url>",
|
|
3579
|
+
"Inspector host that serves /inspector/preview/:view. When omitted, probes localhost:3000 then auto-spawns `mcp-use dev`."
|
|
3580
|
+
).option(
|
|
3581
|
+
"--session <name>",
|
|
3582
|
+
"Saved session name (from `mcp-use client connect`). Defaults to the active session."
|
|
3583
|
+
).option(
|
|
3584
|
+
"--mcp <url>",
|
|
3585
|
+
"Ad-hoc MCP server URL (escape hatch). Used only when no --session and no active saved session. No authentication."
|
|
3586
|
+
).option(
|
|
3587
|
+
"--theme <light|dark>",
|
|
3588
|
+
"Color scheme to render the view in.",
|
|
3589
|
+
"light"
|
|
3590
|
+
).option(
|
|
3591
|
+
"--output <path>",
|
|
3592
|
+
"Output PNG path. Defaults to ./<view>-<timestamp>.png in cwd."
|
|
3593
|
+
).option(
|
|
3594
|
+
"--wait-for <selector>",
|
|
3595
|
+
'Override readiness selector (default: body[data-view-ready="true"]).'
|
|
3596
|
+
).option(
|
|
3597
|
+
"--delay <ms>",
|
|
3598
|
+
"Extra wait after readiness, to let chart animations / async layouts settle.",
|
|
3599
|
+
"0"
|
|
3600
|
+
).option("--timeout <ms>", "Navigation + readiness timeout in ms.", "30000").option(
|
|
3601
|
+
"--cdp-url <url>",
|
|
3602
|
+
"Connect to an existing CDP WebSocket (ws:// or wss://) instead of spawning local Chrome. Useful for hosted browsers like Notte."
|
|
3603
|
+
).option("--quiet", "Suppress dev-server output.").action(async (args, opts) => {
|
|
3604
|
+
await screenshotCommand(opts, args);
|
|
3605
|
+
});
|
|
2851
3606
|
}
|
|
3607
|
+
|
|
3608
|
+
// src/commands/client.ts
|
|
2852
3609
|
async function connectCommand(urlOrCommand, options) {
|
|
2853
3610
|
try {
|
|
2854
3611
|
const sessionName = options.name || `session-${Date.now()}`;
|
|
2855
|
-
const client = new
|
|
3612
|
+
const client = new import_client3.MCPClient();
|
|
2856
3613
|
let session;
|
|
2857
3614
|
const cliClientInfo = getCliClientInfo();
|
|
2858
3615
|
if (options.stdio) {
|
|
@@ -3169,11 +3926,54 @@ async function callToolCommand(toolName, argsList, options) {
|
|
|
3169
3926
|
const callResult = await session.callTool(toolName, args, {
|
|
3170
3927
|
timeout: options?.timeout
|
|
3171
3928
|
});
|
|
3929
|
+
let screenshot = null;
|
|
3930
|
+
let screenshotError = null;
|
|
3931
|
+
if (options?.screenshot !== false) {
|
|
3932
|
+
const tool2 = session.tools.find((t) => t.name === toolName);
|
|
3933
|
+
const resourceUri = detectToolResourceUri(tool2);
|
|
3934
|
+
if (resourceUri) {
|
|
3935
|
+
console.error(
|
|
3936
|
+
formatInfo(`Capturing widget screenshot (${resourceUri})...`)
|
|
3937
|
+
);
|
|
3938
|
+
try {
|
|
3939
|
+
const shot = await captureToolScreenshot(
|
|
3940
|
+
{
|
|
3941
|
+
session,
|
|
3942
|
+
toolName,
|
|
3943
|
+
toolArgs: args,
|
|
3944
|
+
toolOutput: callResult,
|
|
3945
|
+
resourceUri
|
|
3946
|
+
},
|
|
3947
|
+
options?.screenshotOutput ? { output: options.screenshotOutput } : {}
|
|
3948
|
+
);
|
|
3949
|
+
screenshot = {
|
|
3950
|
+
path: shot.outputPath,
|
|
3951
|
+
width: shot.width,
|
|
3952
|
+
height: shot.height,
|
|
3953
|
+
view: shot.view
|
|
3954
|
+
};
|
|
3955
|
+
} catch (err) {
|
|
3956
|
+
screenshotError = err?.message ?? String(err);
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
}
|
|
3172
3960
|
if (options?.json) {
|
|
3173
3961
|
console.log(formatJson(callResult));
|
|
3174
3962
|
} else {
|
|
3175
3963
|
console.log(formatToolCall(callResult));
|
|
3176
3964
|
}
|
|
3965
|
+
if (screenshot) {
|
|
3966
|
+
console.error(
|
|
3967
|
+
formatSuccess(
|
|
3968
|
+
`Saved widget screenshot: ${screenshot.path} (${screenshot.width}\xD7${screenshot.height})`
|
|
3969
|
+
)
|
|
3970
|
+
);
|
|
3971
|
+
}
|
|
3972
|
+
if (screenshotError) {
|
|
3973
|
+
console.error(
|
|
3974
|
+
formatWarning(`Skipped widget screenshot: ${screenshotError}`)
|
|
3975
|
+
);
|
|
3976
|
+
}
|
|
3177
3977
|
if (callResult.isError) {
|
|
3178
3978
|
await cleanupAndExit(1);
|
|
3179
3979
|
}
|
|
@@ -3567,7 +4367,7 @@ async function interactiveCommand(options) {
|
|
|
3567
4367
|
}
|
|
3568
4368
|
}
|
|
3569
4369
|
function createClientCommand() {
|
|
3570
|
-
const clientCommand = new
|
|
4370
|
+
const clientCommand = new import_commander2.Command("client").description(
|
|
3571
4371
|
"Interactive MCP client for terminal usage"
|
|
3572
4372
|
);
|
|
3573
4373
|
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 +4378,28 @@ function createClientCommand() {
|
|
|
3578
4378
|
"OAuth loopback wait timeout in ms (default 300000)"
|
|
3579
4379
|
).action(connectCommand);
|
|
3580
4380
|
clientCommand.command("disconnect [session]").description("Disconnect from a session").option("--all", "Disconnect all sessions").action(disconnectCommand);
|
|
3581
|
-
const sessionsCommand = new
|
|
4381
|
+
const sessionsCommand = new import_commander2.Command("sessions").description(
|
|
3582
4382
|
"Manage CLI sessions"
|
|
3583
4383
|
);
|
|
3584
4384
|
sessionsCommand.command("list").description("List all saved sessions").action(listSessionsCommand);
|
|
3585
4385
|
sessionsCommand.command("switch <name>").description("Switch to a different session").action(switchSessionCommand);
|
|
3586
4386
|
clientCommand.addCommand(sessionsCommand);
|
|
3587
|
-
const toolsCommand = new
|
|
4387
|
+
const toolsCommand = new import_commander2.Command("tools").description(
|
|
3588
4388
|
"Interact with MCP tools"
|
|
3589
4389
|
);
|
|
3590
4390
|
toolsCommand.command("list").description("List available tools").option("--session <name>", "Use specific session").option("--json", "Output as JSON").action(listToolsCommand);
|
|
3591
4391
|
toolsCommand.command("call <name> [args...]").description(
|
|
3592
4392
|
"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").
|
|
4393
|
+
).option("--session <name>", "Use specific session").option("--timeout <ms>", "Request timeout in milliseconds", parseInt).option("--json", "Output as JSON").option(
|
|
4394
|
+
"--no-screenshot",
|
|
4395
|
+
"Skip the auto-screenshot for tools that render a widget"
|
|
4396
|
+
).option(
|
|
4397
|
+
"--screenshot-output <path>",
|
|
4398
|
+
"Output PNG path for the widget screenshot (defaults to ./<view>-<timestamp>.png)"
|
|
4399
|
+
).action((name, args, opts) => callToolCommand(name, args, opts));
|
|
3594
4400
|
toolsCommand.command("describe <name>").description("Show tool details and schema").option("--session <name>", "Use specific session").action(describeToolCommand);
|
|
3595
4401
|
clientCommand.addCommand(toolsCommand);
|
|
3596
|
-
const resourcesCommand = new
|
|
4402
|
+
const resourcesCommand = new import_commander2.Command("resources").description(
|
|
3597
4403
|
"Interact with MCP resources"
|
|
3598
4404
|
);
|
|
3599
4405
|
resourcesCommand.command("list").description("List available resources").option("--session <name>", "Use specific session").option("--json", "Output as JSON").action(listResourcesCommand);
|
|
@@ -3601,7 +4407,7 @@ function createClientCommand() {
|
|
|
3601
4407
|
resourcesCommand.command("subscribe <uri>").description("Subscribe to resource updates").option("--session <name>", "Use specific session").action(subscribeResourceCommand);
|
|
3602
4408
|
resourcesCommand.command("unsubscribe <uri>").description("Unsubscribe from resource updates").option("--session <name>", "Use specific session").action(unsubscribeResourceCommand);
|
|
3603
4409
|
clientCommand.addCommand(resourcesCommand);
|
|
3604
|
-
const promptsCommand = new
|
|
4410
|
+
const promptsCommand = new import_commander2.Command("prompts").description(
|
|
3605
4411
|
"Interact with MCP prompts"
|
|
3606
4412
|
);
|
|
3607
4413
|
promptsCommand.command("list").description("List available prompts").option("--session <name>", "Use specific session").option("--json", "Output as JSON").action(listPromptsCommand);
|
|
@@ -3610,7 +4416,7 @@ function createClientCommand() {
|
|
|
3610
4416
|
).option("--session <name>", "Use specific session").option("--json", "Output as JSON").action(getPromptCommand);
|
|
3611
4417
|
clientCommand.addCommand(promptsCommand);
|
|
3612
4418
|
clientCommand.command("interactive").description("Start interactive REPL mode").option("--session <name>", "Use specific session").action(interactiveCommand);
|
|
3613
|
-
const authCommand = new
|
|
4419
|
+
const authCommand = new import_commander2.Command("auth").description(
|
|
3614
4420
|
"Manage OAuth tokens for HTTP sessions"
|
|
3615
4421
|
);
|
|
3616
4422
|
authCommand.command("status [session]").description("Show OAuth token status for a session").action(authStatusCommand);
|
|
@@ -3622,15 +4428,15 @@ function createClientCommand() {
|
|
|
3622
4428
|
|
|
3623
4429
|
// src/commands/deploy.ts
|
|
3624
4430
|
init_cjs_shims();
|
|
3625
|
-
var
|
|
3626
|
-
var
|
|
4431
|
+
var import_node_fs10 = require("fs");
|
|
4432
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
3627
4433
|
init_open();
|
|
3628
4434
|
|
|
3629
4435
|
// src/utils/git.ts
|
|
3630
4436
|
init_cjs_shims();
|
|
3631
|
-
var
|
|
4437
|
+
var import_node_child_process10 = require("child_process");
|
|
3632
4438
|
var import_node_util7 = require("util");
|
|
3633
|
-
var execFileAsync5 = (0, import_node_util7.promisify)(
|
|
4439
|
+
var execFileAsync5 = (0, import_node_util7.promisify)(import_node_child_process10.execFile);
|
|
3634
4440
|
async function gitCommand(args, cwd = process.cwd()) {
|
|
3635
4441
|
try {
|
|
3636
4442
|
const { stdout } = await execFileAsync5("git", args, { cwd });
|
|
@@ -3781,17 +4587,17 @@ function getMcpServerUrlForCloudServer(server) {
|
|
|
3781
4587
|
|
|
3782
4588
|
// src/utils/project-link.ts
|
|
3783
4589
|
init_cjs_shims();
|
|
3784
|
-
var
|
|
3785
|
-
var
|
|
4590
|
+
var import_node_fs9 = require("fs");
|
|
4591
|
+
var import_node_path7 = __toESM(require("path"), 1);
|
|
3786
4592
|
var MCP_USE_DIR = ".mcp-use";
|
|
3787
4593
|
var MCP_USE_DIR_PROJECT = "project.json";
|
|
3788
4594
|
function getMcpUseDirectory(cwd) {
|
|
3789
|
-
return
|
|
4595
|
+
return import_node_path7.default.join(cwd, MCP_USE_DIR);
|
|
3790
4596
|
}
|
|
3791
4597
|
async function getProjectLink(cwd) {
|
|
3792
4598
|
try {
|
|
3793
|
-
const linkPath =
|
|
3794
|
-
const content = await
|
|
4599
|
+
const linkPath = import_node_path7.default.join(getMcpUseDirectory(cwd), MCP_USE_DIR_PROJECT);
|
|
4600
|
+
const content = await import_node_fs9.promises.readFile(linkPath, "utf-8");
|
|
3795
4601
|
return JSON.parse(content);
|
|
3796
4602
|
} catch (err) {
|
|
3797
4603
|
if (err.code === "ENOENT") return null;
|
|
@@ -3800,17 +4606,17 @@ async function getProjectLink(cwd) {
|
|
|
3800
4606
|
}
|
|
3801
4607
|
async function saveProjectLink(cwd, link) {
|
|
3802
4608
|
const mcpUseDir = getMcpUseDirectory(cwd);
|
|
3803
|
-
await
|
|
3804
|
-
const linkPath =
|
|
3805
|
-
await
|
|
4609
|
+
await import_node_fs9.promises.mkdir(mcpUseDir, { recursive: true });
|
|
4610
|
+
const linkPath = import_node_path7.default.join(mcpUseDir, MCP_USE_DIR_PROJECT);
|
|
4611
|
+
await import_node_fs9.promises.writeFile(linkPath, JSON.stringify(link, null, 2), "utf-8");
|
|
3806
4612
|
await addToGitIgnore(cwd);
|
|
3807
4613
|
}
|
|
3808
4614
|
async function addToGitIgnore(cwd) {
|
|
3809
|
-
const gitignorePath =
|
|
4615
|
+
const gitignorePath = import_node_path7.default.join(cwd, ".gitignore");
|
|
3810
4616
|
try {
|
|
3811
4617
|
let content = "";
|
|
3812
4618
|
try {
|
|
3813
|
-
content = await
|
|
4619
|
+
content = await import_node_fs9.promises.readFile(gitignorePath, "utf-8");
|
|
3814
4620
|
} catch (err) {
|
|
3815
4621
|
if (err.code !== "ENOENT") throw err;
|
|
3816
4622
|
}
|
|
@@ -3819,7 +4625,7 @@ async function addToGitIgnore(cwd) {
|
|
|
3819
4625
|
# mcp-use deployment
|
|
3820
4626
|
${MCP_USE_DIR}
|
|
3821
4627
|
`;
|
|
3822
|
-
await
|
|
4628
|
+
await import_node_fs9.promises.writeFile(gitignorePath, newContent, "utf-8");
|
|
3823
4629
|
}
|
|
3824
4630
|
} catch (err) {
|
|
3825
4631
|
}
|
|
@@ -3828,7 +4634,7 @@ ${MCP_USE_DIR}
|
|
|
3828
4634
|
// src/commands/deploy.ts
|
|
3829
4635
|
async function parseEnvFile(filePath) {
|
|
3830
4636
|
try {
|
|
3831
|
-
const content = await
|
|
4637
|
+
const content = await import_node_fs10.promises.readFile(filePath, "utf-8");
|
|
3832
4638
|
const envVars = {};
|
|
3833
4639
|
const lines = content.split("\n");
|
|
3834
4640
|
let currentKey = null;
|
|
@@ -3947,7 +4753,7 @@ async function buildEnvVars(options) {
|
|
|
3947
4753
|
}
|
|
3948
4754
|
async function isMcpProject(cwd = process.cwd()) {
|
|
3949
4755
|
try {
|
|
3950
|
-
const content = await
|
|
4756
|
+
const content = await import_node_fs10.promises.readFile(import_node_path8.default.join(cwd, "package.json"), "utf-8");
|
|
3951
4757
|
const pkg = JSON.parse(content);
|
|
3952
4758
|
return !!(pkg.dependencies?.["mcp-use"] || pkg.dependencies?.["@modelcontextprotocol/sdk"] || pkg.devDependencies?.["mcp-use"] || pkg.devDependencies?.["@modelcontextprotocol/sdk"]);
|
|
3953
4759
|
} catch {
|
|
@@ -3956,16 +4762,16 @@ async function isMcpProject(cwd = process.cwd()) {
|
|
|
3956
4762
|
}
|
|
3957
4763
|
async function getProjectName(cwd = process.cwd()) {
|
|
3958
4764
|
try {
|
|
3959
|
-
const content = await
|
|
4765
|
+
const content = await import_node_fs10.promises.readFile(import_node_path8.default.join(cwd, "package.json"), "utf-8");
|
|
3960
4766
|
const pkg = JSON.parse(content);
|
|
3961
4767
|
if (pkg.name) return pkg.name;
|
|
3962
4768
|
} catch {
|
|
3963
4769
|
}
|
|
3964
|
-
return
|
|
4770
|
+
return import_node_path8.default.basename(cwd);
|
|
3965
4771
|
}
|
|
3966
4772
|
async function detectBuildCommand(cwd) {
|
|
3967
4773
|
try {
|
|
3968
|
-
const content = await
|
|
4774
|
+
const content = await import_node_fs10.promises.readFile(import_node_path8.default.join(cwd, "package.json"), "utf-8");
|
|
3969
4775
|
if (JSON.parse(content).scripts?.build) return "npm run build";
|
|
3970
4776
|
} catch {
|
|
3971
4777
|
}
|
|
@@ -3973,7 +4779,7 @@ async function detectBuildCommand(cwd) {
|
|
|
3973
4779
|
}
|
|
3974
4780
|
async function detectStartCommand(cwd) {
|
|
3975
4781
|
try {
|
|
3976
|
-
const content = await
|
|
4782
|
+
const content = await import_node_fs10.promises.readFile(import_node_path8.default.join(cwd, "package.json"), "utf-8");
|
|
3977
4783
|
const pkg = JSON.parse(content);
|
|
3978
4784
|
if (pkg.scripts?.start) return "npm start";
|
|
3979
4785
|
if (pkg.main) return `node ${pkg.main}`;
|
|
@@ -3984,7 +4790,7 @@ async function detectStartCommand(cwd) {
|
|
|
3984
4790
|
async function detectRuntime(cwd) {
|
|
3985
4791
|
for (const f of ["requirements.txt", "pyproject.toml", "setup.py"]) {
|
|
3986
4792
|
try {
|
|
3987
|
-
await
|
|
4793
|
+
await import_node_fs10.promises.access(import_node_path8.default.join(cwd, f));
|
|
3988
4794
|
return "python";
|
|
3989
4795
|
} catch {
|
|
3990
4796
|
continue;
|
|
@@ -4031,17 +4837,17 @@ var REQUIRED_IGNORES = [
|
|
|
4031
4837
|
".mcp-use"
|
|
4032
4838
|
];
|
|
4033
4839
|
async function ensureGitignore(cwd) {
|
|
4034
|
-
const gitignorePath =
|
|
4840
|
+
const gitignorePath = import_node_path8.default.join(cwd, ".gitignore");
|
|
4035
4841
|
let content = "";
|
|
4036
4842
|
try {
|
|
4037
|
-
content = await
|
|
4843
|
+
content = await import_node_fs10.promises.readFile(gitignorePath, "utf-8");
|
|
4038
4844
|
} catch {
|
|
4039
4845
|
}
|
|
4040
4846
|
const missing = REQUIRED_IGNORES.filter((entry) => !content.includes(entry));
|
|
4041
4847
|
if (missing.length > 0) {
|
|
4042
4848
|
const additions = missing.join("\n");
|
|
4043
4849
|
const newContent = content + (content.endsWith("\n") ? "" : "\n") + additions + "\n";
|
|
4044
|
-
await
|
|
4850
|
+
await import_node_fs10.promises.writeFile(gitignorePath, newContent, "utf-8");
|
|
4045
4851
|
}
|
|
4046
4852
|
}
|
|
4047
4853
|
async function displayDeploymentProgress(api, deploymentId, progressOptions) {
|
|
@@ -4491,10 +5297,10 @@ async function deployCommand(options) {
|
|
|
4491
5297
|
console.log(source_default.green("\u2713 GitHub connected\n"));
|
|
4492
5298
|
let installationDbId;
|
|
4493
5299
|
let githubInstallationId;
|
|
4494
|
-
const projectDir = options.rootDir ?
|
|
5300
|
+
const projectDir = options.rootDir ? import_node_path8.default.resolve(cwd, options.rootDir) : cwd;
|
|
4495
5301
|
if (options.rootDir) {
|
|
4496
5302
|
try {
|
|
4497
|
-
await
|
|
5303
|
+
await import_node_fs10.promises.access(projectDir);
|
|
4498
5304
|
} catch {
|
|
4499
5305
|
console.log(
|
|
4500
5306
|
source_default.red(`\u2717 Root directory not found: ${options.rootDir}`)
|
|
@@ -5004,7 +5810,7 @@ async function deployCommand(options) {
|
|
|
5004
5810
|
|
|
5005
5811
|
// src/commands/deployments.ts
|
|
5006
5812
|
init_cjs_shims();
|
|
5007
|
-
var
|
|
5813
|
+
var import_commander3 = require("commander");
|
|
5008
5814
|
async function prompt2(question) {
|
|
5009
5815
|
const readline = await import("readline");
|
|
5010
5816
|
const rl = readline.createInterface({
|
|
@@ -5416,7 +6222,7 @@ async function startDeploymentCommand(deploymentId) {
|
|
|
5416
6222
|
}
|
|
5417
6223
|
}
|
|
5418
6224
|
function createDeploymentsCommand() {
|
|
5419
|
-
const deploymentsCommand = new
|
|
6225
|
+
const deploymentsCommand = new import_commander3.Command("deployments").description(
|
|
5420
6226
|
"Manage cloud deployments"
|
|
5421
6227
|
);
|
|
5422
6228
|
deploymentsCommand.command("list").alias("ls").description("List all deployments").action(listDeploymentsCommand);
|
|
@@ -5433,11 +6239,11 @@ function createDeploymentsCommand() {
|
|
|
5433
6239
|
|
|
5434
6240
|
// src/commands/servers.ts
|
|
5435
6241
|
init_cjs_shims();
|
|
5436
|
-
var
|
|
6242
|
+
var import_commander5 = require("commander");
|
|
5437
6243
|
|
|
5438
6244
|
// src/commands/env.ts
|
|
5439
6245
|
init_cjs_shims();
|
|
5440
|
-
var
|
|
6246
|
+
var import_commander4 = require("commander");
|
|
5441
6247
|
var ALL_ENVS = ["production", "preview", "development"];
|
|
5442
6248
|
function parseEnvironments(raw) {
|
|
5443
6249
|
const parts = raw.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
@@ -5582,7 +6388,7 @@ async function removeEnvCommand(varId, options) {
|
|
|
5582
6388
|
}
|
|
5583
6389
|
}
|
|
5584
6390
|
function createEnvCommand() {
|
|
5585
|
-
const envCommand = new
|
|
6391
|
+
const envCommand = new import_commander4.Command("env").description(
|
|
5586
6392
|
"Manage environment variables for a server"
|
|
5587
6393
|
);
|
|
5588
6394
|
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 +6672,7 @@ async function deleteServerCommand(serverId, options) {
|
|
|
5866
6672
|
}
|
|
5867
6673
|
}
|
|
5868
6674
|
function createServersCommand() {
|
|
5869
|
-
const serversCommand = new
|
|
6675
|
+
const serversCommand = new import_commander5.Command("servers").description(
|
|
5870
6676
|
"Manage cloud servers (Git-backed deploy targets)"
|
|
5871
6677
|
);
|
|
5872
6678
|
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 +6792,12 @@ async function orgCurrentCommand() {
|
|
|
5986
6792
|
|
|
5987
6793
|
// src/commands/skills.ts
|
|
5988
6794
|
init_cjs_shims();
|
|
5989
|
-
var
|
|
5990
|
-
var
|
|
5991
|
-
var
|
|
5992
|
-
var
|
|
6795
|
+
var import_commander6 = require("commander");
|
|
6796
|
+
var import_node_fs11 = require("fs");
|
|
6797
|
+
var import_node_os6 = require("os");
|
|
6798
|
+
var import_node_path9 = require("path");
|
|
5993
6799
|
var import_node_stream = require("stream");
|
|
5994
|
-
var
|
|
6800
|
+
var import_promises6 = require("stream/promises");
|
|
5995
6801
|
var import_tar = require("tar");
|
|
5996
6802
|
var REPO_OWNER = "mcp-use";
|
|
5997
6803
|
var REPO_NAME = "mcp-use";
|
|
@@ -6026,42 +6832,42 @@ function sendInstallTelemetryEvent(agents, skills) {
|
|
|
6026
6832
|
}
|
|
6027
6833
|
async function addSkillsToProject(projectPath) {
|
|
6028
6834
|
const tarballUrl = `https://codeload.github.com/${REPO_OWNER}/${REPO_NAME}/tar.gz/${REPO_BRANCH}`;
|
|
6029
|
-
const tempDir = (0,
|
|
6835
|
+
const tempDir = (0, import_node_fs11.mkdtempSync)((0, import_node_path9.join)((0, import_node_os6.tmpdir)(), "mcp-use-skills-"));
|
|
6030
6836
|
try {
|
|
6031
6837
|
const response = await fetch(tarballUrl);
|
|
6032
6838
|
if (!response.ok) {
|
|
6033
6839
|
throw new Error(`Failed to download tarball: ${response.statusText}`);
|
|
6034
6840
|
}
|
|
6035
|
-
await (0,
|
|
6841
|
+
await (0, import_promises6.pipeline)(
|
|
6036
6842
|
import_node_stream.Readable.fromWeb(response.body),
|
|
6037
6843
|
(0, import_tar.extract)({
|
|
6038
6844
|
cwd: tempDir,
|
|
6039
|
-
filter: (
|
|
6845
|
+
filter: (path11) => path11.includes("/skills/"),
|
|
6040
6846
|
strip: 1
|
|
6041
6847
|
})
|
|
6042
6848
|
);
|
|
6043
|
-
const skillsPath = (0,
|
|
6044
|
-
if (!(0,
|
|
6849
|
+
const skillsPath = (0, import_node_path9.join)(tempDir, "skills");
|
|
6850
|
+
if (!(0, import_node_fs11.existsSync)(skillsPath)) {
|
|
6045
6851
|
throw new Error("Skills folder not found in repository");
|
|
6046
6852
|
}
|
|
6047
6853
|
for (const preset of ALL_PRESETS) {
|
|
6048
6854
|
const folderName = AGENT_PRESET_FOLDERS[preset];
|
|
6049
|
-
const outputPath = (0,
|
|
6050
|
-
(0,
|
|
6855
|
+
const outputPath = (0, import_node_path9.join)(projectPath, folderName, "skills");
|
|
6856
|
+
(0, import_node_fs11.cpSync)(skillsPath, outputPath, { recursive: true });
|
|
6051
6857
|
}
|
|
6052
|
-
const skillNames = (0,
|
|
6858
|
+
const skillNames = (0, import_node_fs11.readdirSync)(skillsPath, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
|
|
6053
6859
|
sendInstallTelemetryEvent(ALL_PRESETS.join(","), skillNames.join(","));
|
|
6054
6860
|
} finally {
|
|
6055
|
-
(0,
|
|
6861
|
+
(0, import_node_fs11.rmSync)(tempDir, { recursive: true, force: true });
|
|
6056
6862
|
}
|
|
6057
6863
|
}
|
|
6058
6864
|
function createSkillsCommand() {
|
|
6059
|
-
const skills = new
|
|
6865
|
+
const skills = new import_commander6.Command("skills").description(
|
|
6060
6866
|
"Manage mcp-use AI agent skills"
|
|
6061
6867
|
);
|
|
6062
6868
|
const installAction = async (options) => {
|
|
6063
|
-
const projectPath = (0,
|
|
6064
|
-
if (!(0,
|
|
6869
|
+
const projectPath = (0, import_node_path9.resolve)(options.path);
|
|
6870
|
+
if (!(0, import_node_fs11.existsSync)(projectPath)) {
|
|
6065
6871
|
console.error(source_default.red(`Directory not found: ${projectPath}`));
|
|
6066
6872
|
process.exit(1);
|
|
6067
6873
|
}
|
|
@@ -6103,13 +6909,13 @@ function createSkillsCommand() {
|
|
|
6103
6909
|
|
|
6104
6910
|
// src/utils/next-shims.ts
|
|
6105
6911
|
init_cjs_shims();
|
|
6106
|
-
var
|
|
6107
|
-
var
|
|
6912
|
+
var import_node_fs12 = require("fs");
|
|
6913
|
+
var import_node_path10 = __toESM(require("path"), 1);
|
|
6108
6914
|
var import_node_url2 = require("url");
|
|
6109
6915
|
async function detectNextJsProject(projectPath) {
|
|
6110
6916
|
try {
|
|
6111
|
-
const pkgPath =
|
|
6112
|
-
const content = await
|
|
6917
|
+
const pkgPath = import_node_path10.default.join(projectPath, "package.json");
|
|
6918
|
+
const content = await import_node_fs12.promises.readFile(pkgPath, "utf-8");
|
|
6113
6919
|
const pkg = JSON.parse(content);
|
|
6114
6920
|
const deps = pkg.dependencies ?? {};
|
|
6115
6921
|
const devDeps = pkg.devDependencies ?? {};
|
|
@@ -6127,9 +6933,9 @@ async function loadNextJsEnvFiles(projectPath) {
|
|
|
6127
6933
|
];
|
|
6128
6934
|
const dotenv = await import("dotenv");
|
|
6129
6935
|
for (const file of files) {
|
|
6130
|
-
const abs =
|
|
6936
|
+
const abs = import_node_path10.default.join(projectPath, file);
|
|
6131
6937
|
try {
|
|
6132
|
-
await
|
|
6938
|
+
await import_node_fs12.promises.access(abs);
|
|
6133
6939
|
} catch {
|
|
6134
6940
|
continue;
|
|
6135
6941
|
}
|
|
@@ -6139,20 +6945,20 @@ async function loadNextJsEnvFiles(projectPath) {
|
|
|
6139
6945
|
function getThisDir() {
|
|
6140
6946
|
if (typeof __dirname === "string") return __dirname;
|
|
6141
6947
|
const url = importMetaUrl;
|
|
6142
|
-
return
|
|
6948
|
+
return import_node_path10.default.dirname((0, import_node_url2.fileURLToPath)(url));
|
|
6143
6949
|
}
|
|
6144
6950
|
function resolveShimPath(filename) {
|
|
6145
6951
|
const thisDir = getThisDir();
|
|
6146
6952
|
const candidates = [
|
|
6147
6953
|
// Production: `dist/` next to this module
|
|
6148
|
-
|
|
6954
|
+
import_node_path10.default.join(thisDir, "shims", filename),
|
|
6149
6955
|
// Test / dev: one level up (e.g., from `dist/utils/` back to `src/shims/`)
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6956
|
+
import_node_path10.default.join(thisDir, "..", "shims", filename),
|
|
6957
|
+
import_node_path10.default.join(thisDir, "..", "..", "src", "shims", filename),
|
|
6958
|
+
import_node_path10.default.join(thisDir, "..", "src", "shims", filename)
|
|
6153
6959
|
];
|
|
6154
6960
|
for (const candidate of candidates) {
|
|
6155
|
-
if ((0,
|
|
6961
|
+
if ((0, import_node_fs12.existsSync)(candidate)) return candidate;
|
|
6156
6962
|
}
|
|
6157
6963
|
return void 0;
|
|
6158
6964
|
}
|
|
@@ -6170,7 +6976,7 @@ async function registerNextShimsInProcess() {
|
|
|
6170
6976
|
const cjsPath = getShimCjsPreloadPath();
|
|
6171
6977
|
if (cjsPath) {
|
|
6172
6978
|
const { createRequire: createRequire3 } = await import("module");
|
|
6173
|
-
const req = createRequire3((0, import_node_url2.pathToFileURL)(getThisDir() +
|
|
6979
|
+
const req = createRequire3((0, import_node_url2.pathToFileURL)(getThisDir() + import_node_path10.default.sep).href);
|
|
6174
6980
|
req(cjsPath);
|
|
6175
6981
|
anyRegistered = true;
|
|
6176
6982
|
}
|
|
@@ -6178,7 +6984,7 @@ async function registerNextShimsInProcess() {
|
|
|
6178
6984
|
if (loaderPath) {
|
|
6179
6985
|
const { register } = await import("module");
|
|
6180
6986
|
const loaderUrl = (0, import_node_url2.pathToFileURL)(loaderPath).href;
|
|
6181
|
-
register(loaderUrl, (0, import_node_url2.pathToFileURL)(getThisDir() +
|
|
6987
|
+
register(loaderUrl, (0, import_node_url2.pathToFileURL)(getThisDir() + import_node_path10.default.sep).href);
|
|
6182
6988
|
anyRegistered = true;
|
|
6183
6989
|
}
|
|
6184
6990
|
return anyRegistered;
|
|
@@ -6204,13 +7010,13 @@ function quoteNodeOption(value) {
|
|
|
6204
7010
|
|
|
6205
7011
|
// src/utils/update-check.ts
|
|
6206
7012
|
init_cjs_shims();
|
|
6207
|
-
var
|
|
6208
|
-
var
|
|
7013
|
+
var import_node_fs13 = require("fs");
|
|
7014
|
+
var import_promises7 = require("fs/promises");
|
|
6209
7015
|
var import_node_module = require("module");
|
|
6210
|
-
var
|
|
6211
|
-
var
|
|
6212
|
-
var CACHE_DIR =
|
|
6213
|
-
var CACHE_FILE =
|
|
7016
|
+
var import_node_os7 = __toESM(require("os"), 1);
|
|
7017
|
+
var import_node_path11 = __toESM(require("path"), 1);
|
|
7018
|
+
var CACHE_DIR = import_node_path11.default.join(import_node_os7.default.homedir(), ".mcp-use");
|
|
7019
|
+
var CACHE_FILE = import_node_path11.default.join(CACHE_DIR, "update-check.json");
|
|
6214
7020
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
6215
7021
|
var FETCH_TIMEOUT_MS = 3e3;
|
|
6216
7022
|
var PACKAGE_NAME = "mcp-use";
|
|
@@ -6235,7 +7041,7 @@ function isNewer(current, candidate) {
|
|
|
6235
7041
|
}
|
|
6236
7042
|
async function readCache() {
|
|
6237
7043
|
try {
|
|
6238
|
-
const content = await (0,
|
|
7044
|
+
const content = await (0, import_promises7.readFile)(CACHE_FILE, "utf-8");
|
|
6239
7045
|
return JSON.parse(content);
|
|
6240
7046
|
} catch {
|
|
6241
7047
|
return null;
|
|
@@ -6243,12 +7049,12 @@ async function readCache() {
|
|
|
6243
7049
|
}
|
|
6244
7050
|
async function writeCache(latestVersion) {
|
|
6245
7051
|
try {
|
|
6246
|
-
await (0,
|
|
7052
|
+
await (0, import_promises7.mkdir)(CACHE_DIR, { recursive: true });
|
|
6247
7053
|
const cache = {
|
|
6248
7054
|
lastChecked: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6249
7055
|
latestVersion
|
|
6250
7056
|
};
|
|
6251
|
-
await (0,
|
|
7057
|
+
await (0, import_promises7.writeFile)(CACHE_FILE, JSON.stringify(cache, null, 2), "utf-8");
|
|
6252
7058
|
} catch {
|
|
6253
7059
|
}
|
|
6254
7060
|
}
|
|
@@ -6293,16 +7099,16 @@ function resolveInstalledVersion(projectPath) {
|
|
|
6293
7099
|
if (projectPath) {
|
|
6294
7100
|
attempts.push(() => {
|
|
6295
7101
|
const projectRequire = (0, import_node_module.createRequire)(
|
|
6296
|
-
|
|
7102
|
+
import_node_path11.default.join(projectPath, "package.json")
|
|
6297
7103
|
);
|
|
6298
7104
|
return projectRequire.resolve(`${PACKAGE_NAME}/package.json`);
|
|
6299
7105
|
});
|
|
6300
7106
|
}
|
|
6301
|
-
attempts.push(() =>
|
|
7107
|
+
attempts.push(() => import_node_path11.default.join(__dirname, "../../mcp-use/package.json"));
|
|
6302
7108
|
for (const attempt of attempts) {
|
|
6303
7109
|
try {
|
|
6304
7110
|
const pkgPath = attempt();
|
|
6305
|
-
const json = JSON.parse((0,
|
|
7111
|
+
const json = JSON.parse((0, import_node_fs13.readFileSync)(pkgPath, "utf-8"));
|
|
6306
7112
|
if (typeof json.version === "string") return json.version;
|
|
6307
7113
|
} catch {
|
|
6308
7114
|
}
|
|
@@ -6334,9 +7140,9 @@ A new release of ${source_default.bold(PACKAGE_NAME)} is available: ${source_def
|
|
|
6334
7140
|
}
|
|
6335
7141
|
|
|
6336
7142
|
// src/index.ts
|
|
6337
|
-
var program = new
|
|
6338
|
-
var packageContent = (0,
|
|
6339
|
-
|
|
7143
|
+
var program = new import_commander7.Command();
|
|
7144
|
+
var packageContent = (0, import_node_fs14.readFileSync)(
|
|
7145
|
+
import_node_path12.default.join(__dirname, "../package.json"),
|
|
6340
7146
|
"utf-8"
|
|
6341
7147
|
);
|
|
6342
7148
|
var packageJson = JSON.parse(packageContent);
|
|
@@ -6367,16 +7173,16 @@ function displayPackageVersions(projectPath) {
|
|
|
6367
7173
|
if (projectPath) {
|
|
6368
7174
|
try {
|
|
6369
7175
|
const projectRequire = (0, import_node_module2.createRequire)(
|
|
6370
|
-
|
|
7176
|
+
import_node_path12.default.join(projectPath, "package.json")
|
|
6371
7177
|
);
|
|
6372
7178
|
pkgPath = projectRequire.resolve(`${pkg.name}/package.json`);
|
|
6373
7179
|
} catch (resolveError) {
|
|
6374
|
-
pkgPath =
|
|
7180
|
+
pkgPath = import_node_path12.default.join(__dirname, pkg.relativePath);
|
|
6375
7181
|
}
|
|
6376
7182
|
} else {
|
|
6377
|
-
pkgPath =
|
|
7183
|
+
pkgPath = import_node_path12.default.join(__dirname, pkg.relativePath);
|
|
6378
7184
|
}
|
|
6379
|
-
const pkgContent = (0,
|
|
7185
|
+
const pkgContent = (0, import_node_fs14.readFileSync)(pkgPath, "utf-8");
|
|
6380
7186
|
const pkgJson = JSON.parse(pkgContent);
|
|
6381
7187
|
const version = pkgJson.version || "unknown";
|
|
6382
7188
|
if (pkg.highlight) {
|
|
@@ -6431,7 +7237,7 @@ function normalizeBrowserHost(host) {
|
|
|
6431
7237
|
return host === "0.0.0.0" ? "localhost" : host;
|
|
6432
7238
|
}
|
|
6433
7239
|
function runCommand(command, args, cwd, env2, filterStderr = false) {
|
|
6434
|
-
const proc = (0,
|
|
7240
|
+
const proc = (0, import_node_child_process11.spawn)(command, args, {
|
|
6435
7241
|
cwd,
|
|
6436
7242
|
stdio: filterStderr ? ["inherit", "inherit", "pipe"] : "inherit",
|
|
6437
7243
|
shell: process.platform === "win32",
|
|
@@ -6464,7 +7270,7 @@ async function startTunnel(port, subdomain) {
|
|
|
6464
7270
|
if (subdomain) {
|
|
6465
7271
|
tunnelArgs.push("--subdomain", subdomain);
|
|
6466
7272
|
}
|
|
6467
|
-
const proc = (0,
|
|
7273
|
+
const proc = (0, import_node_child_process11.spawn)("npx", tunnelArgs, {
|
|
6468
7274
|
stdio: ["ignore", "pipe", "pipe"],
|
|
6469
7275
|
shell: process.platform === "win32"
|
|
6470
7276
|
});
|
|
@@ -6528,21 +7334,21 @@ async function startTunnel(port, subdomain) {
|
|
|
6528
7334
|
}
|
|
6529
7335
|
async function resolveEntryFile(projectPath, cliEntry, mcpDir) {
|
|
6530
7336
|
if (cliEntry) {
|
|
6531
|
-
await (0,
|
|
7337
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, cliEntry)).catch(() => {
|
|
6532
7338
|
throw new Error(`File not found: ${cliEntry}`);
|
|
6533
7339
|
});
|
|
6534
7340
|
return cliEntry;
|
|
6535
7341
|
}
|
|
6536
7342
|
if (mcpDir) {
|
|
6537
7343
|
const mcpCandidates = [
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
7344
|
+
import_node_path12.default.join(mcpDir, "index.ts"),
|
|
7345
|
+
import_node_path12.default.join(mcpDir, "index.tsx"),
|
|
7346
|
+
import_node_path12.default.join(mcpDir, "server.ts"),
|
|
7347
|
+
import_node_path12.default.join(mcpDir, "server.tsx")
|
|
6542
7348
|
];
|
|
6543
7349
|
for (const candidate of mcpCandidates) {
|
|
6544
7350
|
try {
|
|
6545
|
-
await (0,
|
|
7351
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, candidate));
|
|
6546
7352
|
return candidate;
|
|
6547
7353
|
} catch {
|
|
6548
7354
|
continue;
|
|
@@ -6551,17 +7357,17 @@ async function resolveEntryFile(projectPath, cliEntry, mcpDir) {
|
|
|
6551
7357
|
throw new Error(
|
|
6552
7358
|
`No entry file found inside ${mcpDir}.
|
|
6553
7359
|
|
|
6554
|
-
Expected one of: ${mcpCandidates.map((c) =>
|
|
7360
|
+
Expected one of: ${mcpCandidates.map((c) => import_node_path12.default.relative(projectPath, import_node_path12.default.join(projectPath, c))).join(", ")}
|
|
6555
7361
|
|
|
6556
7362
|
Fix this by either:
|
|
6557
|
-
1. Creating ${
|
|
7363
|
+
1. Creating ${import_node_path12.default.join(mcpDir, "index.ts")}, or
|
|
6558
7364
|
2. Passing --entry <file> on the command line`
|
|
6559
7365
|
);
|
|
6560
7366
|
}
|
|
6561
7367
|
const candidates = ["index.ts", "src/index.ts", "server.ts", "src/server.ts"];
|
|
6562
7368
|
for (const candidate of candidates) {
|
|
6563
7369
|
try {
|
|
6564
|
-
await (0,
|
|
7370
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, candidate));
|
|
6565
7371
|
return candidate;
|
|
6566
7372
|
} catch {
|
|
6567
7373
|
continue;
|
|
@@ -6579,7 +7385,7 @@ Fix this by either:
|
|
|
6579
7385
|
}
|
|
6580
7386
|
function resolveWidgetsDir(cliWidgetsDir, mcpDir) {
|
|
6581
7387
|
if (cliWidgetsDir) return cliWidgetsDir;
|
|
6582
|
-
if (mcpDir) return
|
|
7388
|
+
if (mcpDir) return import_node_path12.default.join(mcpDir, "resources");
|
|
6583
7389
|
return "resources";
|
|
6584
7390
|
}
|
|
6585
7391
|
function makeWidgetServerOnlyGuard(widgetName) {
|
|
@@ -6614,8 +7420,8 @@ function isBunRuntime() {
|
|
|
6614
7420
|
return typeof globalThis.Bun !== "undefined" || typeof process.versions.bun === "string";
|
|
6615
7421
|
}
|
|
6616
7422
|
async function generateToolRegistryTypesForServer(projectPath, serverFileRelative) {
|
|
6617
|
-
const serverFile =
|
|
6618
|
-
const serverFileExists = await (0,
|
|
7423
|
+
const serverFile = import_node_path12.default.join(projectPath, serverFileRelative);
|
|
7424
|
+
const serverFileExists = await (0, import_promises8.access)(serverFile).then(() => true).catch(() => false);
|
|
6619
7425
|
if (!serverFileExists) {
|
|
6620
7426
|
throw new Error(`Server file not found: ${serverFile}`);
|
|
6621
7427
|
}
|
|
@@ -6640,8 +7446,8 @@ async function generateToolRegistryTypesForServer(projectPath, serverFileRelativ
|
|
|
6640
7446
|
await loadNextJsEnvFiles(projectPath);
|
|
6641
7447
|
await registerNextShimsInProcess();
|
|
6642
7448
|
}
|
|
6643
|
-
const projectTsconfigPath =
|
|
6644
|
-
const hasTsconfig = await (0,
|
|
7449
|
+
const projectTsconfigPath = import_node_path12.default.join(projectPath, "tsconfig.json");
|
|
7450
|
+
const hasTsconfig = await (0, import_promises8.access)(projectTsconfigPath).then(() => true).catch(() => false);
|
|
6645
7451
|
if (hasTsconfig) {
|
|
6646
7452
|
process.env.TSX_TSCONFIG_PATH = projectTsconfigPath;
|
|
6647
7453
|
}
|
|
@@ -6649,7 +7455,7 @@ async function generateToolRegistryTypesForServer(projectPath, serverFileRelativ
|
|
|
6649
7455
|
if (previousCwd !== projectPath) process.chdir(projectPath);
|
|
6650
7456
|
try {
|
|
6651
7457
|
const projectRequire = (0, import_node_module2.createRequire)(
|
|
6652
|
-
|
|
7458
|
+
import_node_path12.default.join(projectPath, "package.json")
|
|
6653
7459
|
);
|
|
6654
7460
|
const tsxEsmApiPath = projectRequire.resolve("tsx/esm/api");
|
|
6655
7461
|
const tsxEsmApi = await import((0, import_node_url3.pathToFileURL)(tsxEsmApiPath).href);
|
|
@@ -6676,8 +7482,8 @@ async function generateToolRegistryTypesForServer(projectPath, serverFileRelativ
|
|
|
6676
7482
|
"No MCPServer instance found. Make sure your server file creates an MCPServer instance."
|
|
6677
7483
|
);
|
|
6678
7484
|
}
|
|
6679
|
-
const mcpUsePath =
|
|
6680
|
-
const { generateToolRegistryTypes } = await import((0, import_node_url3.pathToFileURL)(
|
|
7485
|
+
const mcpUsePath = import_node_path12.default.join(projectPath, "node_modules", "mcp-use");
|
|
7486
|
+
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
7487
|
if (!generateToolRegistryTypes) {
|
|
6682
7488
|
throw new Error("generateToolRegistryTypes not found in mcp-use package");
|
|
6683
7489
|
}
|
|
@@ -6695,10 +7501,10 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
6695
7501
|
const { promises: fs11 } = await import("fs");
|
|
6696
7502
|
const { build } = await import("vite");
|
|
6697
7503
|
const widgetsDirRelative = options.widgetsDir ?? "resources";
|
|
6698
|
-
const resourcesDir =
|
|
7504
|
+
const resourcesDir = import_node_path12.default.resolve(projectPath, widgetsDirRelative);
|
|
6699
7505
|
const mcpUrl = process.env.MCP_URL;
|
|
6700
7506
|
try {
|
|
6701
|
-
await (0,
|
|
7507
|
+
await (0, import_promises8.access)(resourcesDir);
|
|
6702
7508
|
} catch {
|
|
6703
7509
|
console.log(
|
|
6704
7510
|
source_default.gray(
|
|
@@ -6717,10 +7523,10 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
6717
7523
|
if (dirent.isFile() && (dirent.name.endsWith(".tsx") || dirent.name.endsWith(".ts"))) {
|
|
6718
7524
|
entries.push({
|
|
6719
7525
|
name: dirent.name.replace(/\.tsx?$/, ""),
|
|
6720
|
-
path:
|
|
7526
|
+
path: import_node_path12.default.join(resourcesDir, dirent.name)
|
|
6721
7527
|
});
|
|
6722
7528
|
} else if (dirent.isDirectory()) {
|
|
6723
|
-
const widgetPath =
|
|
7529
|
+
const widgetPath = import_node_path12.default.join(resourcesDir, dirent.name, "widget.tsx");
|
|
6724
7530
|
try {
|
|
6725
7531
|
await fs11.access(widgetPath);
|
|
6726
7532
|
entries.push({
|
|
@@ -6750,14 +7556,14 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
6750
7556
|
);
|
|
6751
7557
|
const react = (await import("@vitejs/plugin-react")).default;
|
|
6752
7558
|
const tailwindcss = (await import("@tailwindcss/vite")).default;
|
|
6753
|
-
const projectTsconfigPath =
|
|
7559
|
+
const projectTsconfigPath = import_node_path12.default.join(projectPath, "tsconfig.json");
|
|
6754
7560
|
let hasProjectTsconfig = false;
|
|
6755
7561
|
try {
|
|
6756
|
-
await (0,
|
|
7562
|
+
await (0, import_promises8.access)(projectTsconfigPath);
|
|
6757
7563
|
hasProjectTsconfig = true;
|
|
6758
7564
|
} catch {
|
|
6759
7565
|
}
|
|
6760
|
-
const packageJsonPath =
|
|
7566
|
+
const packageJsonPath = import_node_path12.default.join(projectPath, "package.json");
|
|
6761
7567
|
let favicon = "";
|
|
6762
7568
|
try {
|
|
6763
7569
|
const pkgContent = await fs11.readFile(packageJsonPath, "utf-8");
|
|
@@ -6769,16 +7575,16 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
6769
7575
|
const widgetName = entry.name;
|
|
6770
7576
|
const entryPath = entry.path.replace(/\\/g, "/");
|
|
6771
7577
|
console.log(source_default.gray(` - Building ${widgetName}...`));
|
|
6772
|
-
const tempDir =
|
|
7578
|
+
const tempDir = import_node_path12.default.join(projectPath, ".mcp-use", widgetName);
|
|
6773
7579
|
await fs11.mkdir(tempDir, { recursive: true });
|
|
6774
|
-
const relativeResourcesPath =
|
|
6775
|
-
const mcpUsePath =
|
|
6776
|
-
const relativeMcpUsePath =
|
|
6777
|
-
const projectSrcDir =
|
|
7580
|
+
const relativeResourcesPath = import_node_path12.default.relative(tempDir, resourcesDir).replace(/\\/g, "/");
|
|
7581
|
+
const mcpUsePath = import_node_path12.default.join(projectPath, "node_modules", "mcp-use");
|
|
7582
|
+
const relativeMcpUsePath = import_node_path12.default.relative(tempDir, mcpUsePath).replace(/\\/g, "/");
|
|
7583
|
+
const projectSrcDir = import_node_path12.default.join(projectPath, "src");
|
|
6778
7584
|
let projectSrcSourceLine = "";
|
|
6779
7585
|
try {
|
|
6780
|
-
await (0,
|
|
6781
|
-
const relativeProjectSrcPath =
|
|
7586
|
+
await (0, import_promises8.access)(projectSrcDir);
|
|
7587
|
+
const relativeProjectSrcPath = import_node_path12.default.relative(tempDir, projectSrcDir).replace(/\\/g, "/");
|
|
6782
7588
|
projectSrcSourceLine = `@source "${relativeProjectSrcPath}";
|
|
6783
7589
|
`;
|
|
6784
7590
|
} catch {
|
|
@@ -6789,7 +7595,7 @@ async function buildWidgets(projectPath, options = {}) {
|
|
|
6789
7595
|
@source "${relativeResourcesPath}";
|
|
6790
7596
|
@source "${relativeMcpUsePath}/**/*.{ts,tsx,js,jsx}";
|
|
6791
7597
|
${projectSrcSourceLine}`;
|
|
6792
|
-
await fs11.writeFile(
|
|
7598
|
+
await fs11.writeFile(import_node_path12.default.join(tempDir, "styles.css"), cssContent, "utf8");
|
|
6793
7599
|
const entryContent = `import React from 'react'
|
|
6794
7600
|
import { createRoot } from 'react-dom/client'
|
|
6795
7601
|
import './styles.css'
|
|
@@ -6814,9 +7620,9 @@ if (container && Component) {
|
|
|
6814
7620
|
<script type="module" src="/entry.tsx"></script>
|
|
6815
7621
|
</body>
|
|
6816
7622
|
</html>`;
|
|
6817
|
-
await fs11.writeFile(
|
|
6818
|
-
await fs11.writeFile(
|
|
6819
|
-
const outDir =
|
|
7623
|
+
await fs11.writeFile(import_node_path12.default.join(tempDir, "entry.tsx"), entryContent, "utf8");
|
|
7624
|
+
await fs11.writeFile(import_node_path12.default.join(tempDir, "index.html"), htmlContent, "utf8");
|
|
7625
|
+
const outDir = import_node_path12.default.join(
|
|
6820
7626
|
projectPath,
|
|
6821
7627
|
"dist",
|
|
6822
7628
|
"resources",
|
|
@@ -6826,13 +7632,13 @@ if (container && Component) {
|
|
|
6826
7632
|
const baseUrl = mcpUrl ? `${mcpUrl}/${widgetName}/` : `/mcp-use/widgets/${widgetName}/`;
|
|
6827
7633
|
let widgetMetadata = {};
|
|
6828
7634
|
try {
|
|
6829
|
-
const metadataTempDir =
|
|
7635
|
+
const metadataTempDir = import_node_path12.default.join(
|
|
6830
7636
|
projectPath,
|
|
6831
7637
|
".mcp-use",
|
|
6832
7638
|
`${widgetName}-metadata`
|
|
6833
7639
|
);
|
|
6834
7640
|
await fs11.mkdir(metadataTempDir, { recursive: true });
|
|
6835
|
-
const { createServer } = await import("vite");
|
|
7641
|
+
const { createServer: createServer2 } = await import("vite");
|
|
6836
7642
|
const nodeStubsPlugin = {
|
|
6837
7643
|
name: "node-stubs",
|
|
6838
7644
|
enforce: "pre",
|
|
@@ -6860,9 +7666,9 @@ export default PostHog;
|
|
|
6860
7666
|
}
|
|
6861
7667
|
};
|
|
6862
7668
|
const serverOnlyGuard = makeWidgetServerOnlyGuard(widgetName);
|
|
6863
|
-
const metadataServer = await
|
|
7669
|
+
const metadataServer = await createServer2({
|
|
6864
7670
|
root: metadataTempDir,
|
|
6865
|
-
cacheDir:
|
|
7671
|
+
cacheDir: import_node_path12.default.join(metadataTempDir, ".vite-cache"),
|
|
6866
7672
|
plugins: [serverOnlyGuard, nodeStubsPlugin, tailwindcss(), react()],
|
|
6867
7673
|
// When the project has a tsconfig, enable Vite's native tsconfig-paths
|
|
6868
7674
|
// resolver so `@/*` (or any custom alias) resolves through the
|
|
@@ -7093,7 +7899,7 @@ export default {
|
|
|
7093
7899
|
// Inline all assets under 100MB (effectively all)
|
|
7094
7900
|
} : {},
|
|
7095
7901
|
rolldownOptions: {
|
|
7096
|
-
input:
|
|
7902
|
+
input: import_node_path12.default.join(tempDir, "index.html"),
|
|
7097
7903
|
external: (id) => {
|
|
7098
7904
|
return false;
|
|
7099
7905
|
}
|
|
@@ -7101,11 +7907,11 @@ export default {
|
|
|
7101
7907
|
}
|
|
7102
7908
|
});
|
|
7103
7909
|
try {
|
|
7104
|
-
const assetsDir =
|
|
7910
|
+
const assetsDir = import_node_path12.default.join(outDir, "assets");
|
|
7105
7911
|
const assetFiles = await fs11.readdir(assetsDir);
|
|
7106
7912
|
const jsFiles = assetFiles.filter((f) => f.endsWith(".js"));
|
|
7107
7913
|
for (const jsFile of jsFiles) {
|
|
7108
|
-
const jsPath =
|
|
7914
|
+
const jsPath = import_node_path12.default.join(assetsDir, jsFile);
|
|
7109
7915
|
let content = await fs11.readFile(jsPath, "utf8");
|
|
7110
7916
|
const zodConfigPatterns = [
|
|
7111
7917
|
// Non-minified: export const globalConfig = {}
|
|
@@ -7137,7 +7943,7 @@ export default {
|
|
|
7137
7943
|
const mcpServerUrl = process.env.MCP_SERVER_URL;
|
|
7138
7944
|
if (mcpServerUrl) {
|
|
7139
7945
|
try {
|
|
7140
|
-
const htmlPath =
|
|
7946
|
+
const htmlPath = import_node_path12.default.join(outDir, "index.html");
|
|
7141
7947
|
let html = await fs11.readFile(htmlPath, "utf8");
|
|
7142
7948
|
const injectionScript = `<script>window.__getFile = (filename) => { return "${mcpUrl}/${widgetName}/"+filename }; window.__mcpPublicUrl = "${mcpServerUrl}/mcp-use/public"; window.__mcpPublicAssetsUrl = "${mcpUrl}/public";</script>`;
|
|
7143
7949
|
if (!html.includes("window.__mcpPublicUrl")) {
|
|
@@ -7213,7 +8019,7 @@ async function collectTsFiles(projectPath, includePatterns, excludePatterns) {
|
|
|
7213
8019
|
for (const file of literalFiles) {
|
|
7214
8020
|
if (/\.tsx?$/.test(file) && !file.endsWith(".d.ts")) {
|
|
7215
8021
|
try {
|
|
7216
|
-
await (0,
|
|
8022
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, file));
|
|
7217
8023
|
files.push(file);
|
|
7218
8024
|
} catch {
|
|
7219
8025
|
}
|
|
@@ -7221,13 +8027,13 @@ async function collectTsFiles(projectPath, includePatterns, excludePatterns) {
|
|
|
7221
8027
|
}
|
|
7222
8028
|
const excludeSet = new Set(excludePatterns.map((e) => e.replace(/\*+/g, "")));
|
|
7223
8029
|
for (const prefix of dirPrefixes) {
|
|
7224
|
-
const dirPath =
|
|
8030
|
+
const dirPath = import_node_path12.default.join(projectPath, prefix);
|
|
7225
8031
|
try {
|
|
7226
8032
|
const entries = await fs11.readdir(dirPath, { recursive: true });
|
|
7227
8033
|
for (const entry of entries) {
|
|
7228
8034
|
const entryStr = String(entry);
|
|
7229
|
-
const rel =
|
|
7230
|
-
if (/\.tsx?$/.test(entryStr) && !entryStr.endsWith(".d.ts") && !excludeSet.has(rel.split(
|
|
8035
|
+
const rel = import_node_path12.default.join(prefix, entryStr);
|
|
8036
|
+
if (/\.tsx?$/.test(entryStr) && !entryStr.endsWith(".d.ts") && !excludeSet.has(rel.split(import_node_path12.default.sep)[0])) {
|
|
7231
8037
|
files.push(rel);
|
|
7232
8038
|
}
|
|
7233
8039
|
}
|
|
@@ -7239,7 +8045,7 @@ async function collectTsFiles(projectPath, includePatterns, excludePatterns) {
|
|
|
7239
8045
|
async function transpileWithEsbuild(projectPath) {
|
|
7240
8046
|
const esbuild = await import("esbuild");
|
|
7241
8047
|
const { promises: fs11 } = await import("fs");
|
|
7242
|
-
const tsconfigPath =
|
|
8048
|
+
const tsconfigPath = import_node_path12.default.join(projectPath, "tsconfig.json");
|
|
7243
8049
|
let tsconfig = {};
|
|
7244
8050
|
try {
|
|
7245
8051
|
const raw = await fs11.readFile(tsconfigPath, "utf-8");
|
|
@@ -7269,10 +8075,10 @@ async function transpileWithEsbuild(projectPath) {
|
|
|
7269
8075
|
const target = (compilerOptions.target || "ES2022").toLowerCase();
|
|
7270
8076
|
const moduleStr = (compilerOptions.module || "ESNext").toLowerCase();
|
|
7271
8077
|
const format = moduleStr.includes("commonjs") ? "cjs" : "esm";
|
|
7272
|
-
const outbase = compilerOptions.rootDir ?
|
|
8078
|
+
const outbase = compilerOptions.rootDir ? import_node_path12.default.resolve(projectPath, compilerOptions.rootDir) : projectPath;
|
|
7273
8079
|
await esbuild.build({
|
|
7274
|
-
entryPoints: files.map((f) =>
|
|
7275
|
-
outdir:
|
|
8080
|
+
entryPoints: files.map((f) => import_node_path12.default.join(projectPath, f)),
|
|
8081
|
+
outdir: import_node_path12.default.join(projectPath, outDir),
|
|
7276
8082
|
outbase,
|
|
7277
8083
|
bundle: true,
|
|
7278
8084
|
packages: "external",
|
|
@@ -7299,7 +8105,7 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
7299
8105
|
"Inline all JS/CSS into HTML (required for VS Code MCP Apps)"
|
|
7300
8106
|
).option("--no-inline", "Keep JS/CSS as separate files (default)").option("--no-typecheck", "Skip TypeScript type checking (faster builds)").action(async (options) => {
|
|
7301
8107
|
try {
|
|
7302
|
-
const projectPath =
|
|
8108
|
+
const projectPath = import_node_path12.default.resolve(options.path);
|
|
7303
8109
|
const { promises: fs11 } = await import("fs");
|
|
7304
8110
|
displayPackageVersions(projectPath);
|
|
7305
8111
|
const mcpDir = options.mcpDir;
|
|
@@ -7359,7 +8165,7 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
7359
8165
|
}
|
|
7360
8166
|
if (options.typecheck !== false && !mcpDir) {
|
|
7361
8167
|
console.log(source_default.gray("Type checking..."));
|
|
7362
|
-
const tscBin =
|
|
8168
|
+
const tscBin = import_node_path12.default.join(
|
|
7363
8169
|
projectPath,
|
|
7364
8170
|
"node_modules",
|
|
7365
8171
|
"typescript",
|
|
@@ -7382,7 +8188,7 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
7382
8188
|
if (mcpDir) {
|
|
7383
8189
|
entryPoint = sourceServerFile;
|
|
7384
8190
|
} else {
|
|
7385
|
-
const baseName =
|
|
8191
|
+
const baseName = import_node_path12.default.basename(sourceServerFile, ".ts") + ".js";
|
|
7386
8192
|
const possibleOutputs = [
|
|
7387
8193
|
`dist/${baseName}`,
|
|
7388
8194
|
// rootDir set to project root or src
|
|
@@ -7393,7 +8199,7 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
7393
8199
|
];
|
|
7394
8200
|
for (const candidate of possibleOutputs) {
|
|
7395
8201
|
try {
|
|
7396
|
-
await (0,
|
|
8202
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, candidate));
|
|
7397
8203
|
entryPoint = candidate;
|
|
7398
8204
|
break;
|
|
7399
8205
|
} catch {
|
|
@@ -7402,17 +8208,17 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
7402
8208
|
}
|
|
7403
8209
|
}
|
|
7404
8210
|
}
|
|
7405
|
-
const publicDir =
|
|
8211
|
+
const publicDir = import_node_path12.default.join(projectPath, "public");
|
|
7406
8212
|
try {
|
|
7407
8213
|
await fs11.access(publicDir);
|
|
7408
8214
|
console.log(source_default.gray("Copying public assets..."));
|
|
7409
|
-
await fs11.cp(publicDir,
|
|
8215
|
+
await fs11.cp(publicDir, import_node_path12.default.join(projectPath, "dist", "public"), {
|
|
7410
8216
|
recursive: true
|
|
7411
8217
|
});
|
|
7412
8218
|
console.log(source_default.green("\u2713 Public assets copied"));
|
|
7413
8219
|
} catch {
|
|
7414
8220
|
}
|
|
7415
|
-
const manifestPath =
|
|
8221
|
+
const manifestPath = import_node_path12.default.join(projectPath, "dist", "mcp-use.json");
|
|
7416
8222
|
let existingManifest = {};
|
|
7417
8223
|
try {
|
|
7418
8224
|
const existingContent = await fs11.readFile(manifestPath, "utf-8");
|
|
@@ -7437,7 +8243,7 @@ program.command("build").description("Build TypeScript and MCP UI widgets").opti
|
|
|
7437
8243
|
// Server entry point for `mcp-use start`
|
|
7438
8244
|
widgets: widgetsData
|
|
7439
8245
|
};
|
|
7440
|
-
await fs11.mkdir(
|
|
8246
|
+
await fs11.mkdir(import_node_path12.default.dirname(manifestPath), { recursive: true });
|
|
7441
8247
|
await fs11.writeFile(
|
|
7442
8248
|
manifestPath,
|
|
7443
8249
|
JSON.stringify(manifest, null, 2),
|
|
@@ -7474,7 +8280,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7474
8280
|
).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
8281
|
try {
|
|
7476
8282
|
process.env.MCP_USE_CLI_DEV = "1";
|
|
7477
|
-
const projectPath =
|
|
8283
|
+
const projectPath = import_node_path12.default.resolve(options.path);
|
|
7478
8284
|
let port = parseInt(options.port, 10);
|
|
7479
8285
|
const host = options.host;
|
|
7480
8286
|
const useHmr = options.hmr !== false;
|
|
@@ -7502,10 +8308,10 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7502
8308
|
let tunnelUrl = void 0;
|
|
7503
8309
|
if (options.tunnel) {
|
|
7504
8310
|
try {
|
|
7505
|
-
const manifestPath =
|
|
8311
|
+
const manifestPath = import_node_path12.default.join(projectPath, "dist", "mcp-use.json");
|
|
7506
8312
|
let existingSubdomain;
|
|
7507
8313
|
try {
|
|
7508
|
-
const manifestContent = await (0,
|
|
8314
|
+
const manifestContent = await (0, import_promises8.readFile)(manifestPath, "utf-8");
|
|
7509
8315
|
const manifest = JSON.parse(manifestContent);
|
|
7510
8316
|
existingSubdomain = manifest.tunnel?.subdomain;
|
|
7511
8317
|
if (existingSubdomain) {
|
|
@@ -7543,7 +8349,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7543
8349
|
try {
|
|
7544
8350
|
let manifest = {};
|
|
7545
8351
|
try {
|
|
7546
|
-
const manifestContent = await (0,
|
|
8352
|
+
const manifestContent = await (0, import_promises8.readFile)(manifestPath, "utf-8");
|
|
7547
8353
|
manifest = JSON.parse(manifestContent);
|
|
7548
8354
|
} catch {
|
|
7549
8355
|
}
|
|
@@ -7551,8 +8357,8 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7551
8357
|
manifest.tunnel = {};
|
|
7552
8358
|
}
|
|
7553
8359
|
manifest.tunnel.subdomain = tunnelSubdomain;
|
|
7554
|
-
await (0,
|
|
7555
|
-
await (0,
|
|
8360
|
+
await (0, import_promises8.mkdir)(import_node_path12.default.dirname(manifestPath), { recursive: true });
|
|
8361
|
+
await (0, import_promises8.writeFile)(
|
|
7556
8362
|
manifestPath,
|
|
7557
8363
|
JSON.stringify(manifest, null, 2),
|
|
7558
8364
|
"utf-8"
|
|
@@ -7606,10 +8412,10 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7606
8412
|
let args;
|
|
7607
8413
|
try {
|
|
7608
8414
|
const projectRequire = createRequire4(
|
|
7609
|
-
|
|
8415
|
+
import_node_path12.default.join(projectPath, "package.json")
|
|
7610
8416
|
);
|
|
7611
8417
|
const tsxPkgPath = projectRequire.resolve("tsx/package.json");
|
|
7612
|
-
const tsxPkg = JSON.parse(await (0,
|
|
8418
|
+
const tsxPkg = JSON.parse(await (0, import_promises8.readFile)(tsxPkgPath, "utf-8"));
|
|
7613
8419
|
let binPath;
|
|
7614
8420
|
if (typeof tsxPkg.bin === "string") {
|
|
7615
8421
|
binPath = tsxPkg.bin;
|
|
@@ -7618,7 +8424,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7618
8424
|
} else {
|
|
7619
8425
|
throw new Error("No bin field found in tsx package.json");
|
|
7620
8426
|
}
|
|
7621
|
-
const tsxBin =
|
|
8427
|
+
const tsxBin = import_node_path12.default.resolve(import_node_path12.default.dirname(tsxPkgPath), binPath);
|
|
7622
8428
|
cmd = "node";
|
|
7623
8429
|
args = [tsxBin, "watch", serverFile];
|
|
7624
8430
|
} catch (error) {
|
|
@@ -7707,10 +8513,10 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7707
8513
|
const chokidar = chokidarModule.default || chokidarModule;
|
|
7708
8514
|
const { fileURLToPath: fileURLToPath3 } = await import("url");
|
|
7709
8515
|
const { createRequire: createRequire3 } = await import("module");
|
|
7710
|
-
const projectTsconfigPath =
|
|
8516
|
+
const projectTsconfigPath = import_node_path12.default.join(projectPath, "tsconfig.json");
|
|
7711
8517
|
let tsconfigAvailable = false;
|
|
7712
8518
|
try {
|
|
7713
|
-
await (0,
|
|
8519
|
+
await (0, import_promises8.access)(projectTsconfigPath);
|
|
7714
8520
|
tsconfigAvailable = true;
|
|
7715
8521
|
process.env.TSX_TSCONFIG_PATH = projectTsconfigPath;
|
|
7716
8522
|
if (process.cwd() !== projectPath) process.chdir(projectPath);
|
|
@@ -7719,7 +8525,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7719
8525
|
let tsxLoaderActive = false;
|
|
7720
8526
|
try {
|
|
7721
8527
|
const projectRequire = createRequire3(
|
|
7722
|
-
|
|
8528
|
+
import_node_path12.default.join(projectPath, "package.json")
|
|
7723
8529
|
);
|
|
7724
8530
|
const tsxEsmApiPath = projectRequire.resolve("tsx/esm/api");
|
|
7725
8531
|
const tsxEsmApi = await import((0, import_node_url3.pathToFileURL)(tsxEsmApiPath).href);
|
|
@@ -7750,7 +8556,7 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7750
8556
|
)
|
|
7751
8557
|
);
|
|
7752
8558
|
}
|
|
7753
|
-
const serverFilePath =
|
|
8559
|
+
const serverFilePath = import_node_path12.default.join(projectPath, serverFile);
|
|
7754
8560
|
const serverFileUrl = (0, import_node_url3.pathToFileURL)(serverFilePath).href;
|
|
7755
8561
|
globalThis.__mcpUseHmrMode = true;
|
|
7756
8562
|
const importServerModule = async () => {
|
|
@@ -7847,8 +8653,8 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
7847
8653
|
}
|
|
7848
8654
|
let watcher = chokidar.watch(".", {
|
|
7849
8655
|
cwd: projectPath,
|
|
7850
|
-
ignored: (
|
|
7851
|
-
const normalizedPath =
|
|
8656
|
+
ignored: (path11, stats) => {
|
|
8657
|
+
const normalizedPath = path11.replace(/\\/g, "/");
|
|
7852
8658
|
if (/(^|\/)\.[^/]/.test(normalizedPath)) {
|
|
7853
8659
|
return true;
|
|
7854
8660
|
}
|
|
@@ -8022,10 +8828,10 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
8022
8828
|
}
|
|
8023
8829
|
tunnelUrl = void 0;
|
|
8024
8830
|
if (withTunnel) {
|
|
8025
|
-
const manifestPath =
|
|
8831
|
+
const manifestPath = import_node_path12.default.join(projectPath, "dist", "mcp-use.json");
|
|
8026
8832
|
let existingSubdomain;
|
|
8027
8833
|
try {
|
|
8028
|
-
const manifestContent = await (0,
|
|
8834
|
+
const manifestContent = await (0, import_promises8.readFile)(manifestPath, "utf-8");
|
|
8029
8835
|
const manifest = JSON.parse(manifestContent);
|
|
8030
8836
|
existingSubdomain = manifest.tunnel?.subdomain;
|
|
8031
8837
|
if (existingSubdomain) {
|
|
@@ -8059,16 +8865,16 @@ program.command("dev").description("Run development server with auto-reload and
|
|
|
8059
8865
|
tunnelSubdomain = tunnelInfo.subdomain;
|
|
8060
8866
|
process.env.MCP_URL = tunnelUrl;
|
|
8061
8867
|
try {
|
|
8062
|
-
const mPath =
|
|
8868
|
+
const mPath = import_node_path12.default.join(projectPath, "dist", "mcp-use.json");
|
|
8063
8869
|
let manifest = {};
|
|
8064
8870
|
try {
|
|
8065
|
-
manifest = JSON.parse(await (0,
|
|
8871
|
+
manifest = JSON.parse(await (0, import_promises8.readFile)(mPath, "utf-8"));
|
|
8066
8872
|
} catch {
|
|
8067
8873
|
}
|
|
8068
8874
|
if (!manifest.tunnel) manifest.tunnel = {};
|
|
8069
8875
|
manifest.tunnel.subdomain = tunnelSubdomain;
|
|
8070
|
-
await (0,
|
|
8071
|
-
await (0,
|
|
8876
|
+
await (0, import_promises8.mkdir)(import_node_path12.default.dirname(mPath), { recursive: true });
|
|
8877
|
+
await (0, import_promises8.writeFile)(mPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
8072
8878
|
} catch {
|
|
8073
8879
|
}
|
|
8074
8880
|
} else {
|
|
@@ -8171,7 +8977,7 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
8171
8977
|
"Folder holding the MCP entry + resources (e.g. 'src/mcp' for Next.js apps)"
|
|
8172
8978
|
).option("--port <port>", "Server port", "3000").option("--tunnel", "Expose server through a tunnel").action(async (options) => {
|
|
8173
8979
|
try {
|
|
8174
|
-
const projectPath =
|
|
8980
|
+
const projectPath = import_node_path12.default.resolve(options.path);
|
|
8175
8981
|
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
8982
|
let port = portFlagProvided ? parseInt(options.port, 10) : parseInt(process.env.PORT || options.port || "3000", 10);
|
|
8177
8983
|
if (!await isPortAvailable(port)) {
|
|
@@ -8189,10 +8995,10 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
8189
8995
|
let tunnelSubdomain = void 0;
|
|
8190
8996
|
if (options.tunnel) {
|
|
8191
8997
|
try {
|
|
8192
|
-
const manifestPath2 =
|
|
8998
|
+
const manifestPath2 = import_node_path12.default.join(projectPath, "dist", "mcp-use.json");
|
|
8193
8999
|
let existingSubdomain;
|
|
8194
9000
|
try {
|
|
8195
|
-
const manifestContent = await (0,
|
|
9001
|
+
const manifestContent = await (0, import_promises8.readFile)(manifestPath2, "utf-8");
|
|
8196
9002
|
const manifest = JSON.parse(manifestContent);
|
|
8197
9003
|
existingSubdomain = manifest.tunnel?.subdomain;
|
|
8198
9004
|
if (existingSubdomain) {
|
|
@@ -8236,7 +9042,7 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
8236
9042
|
try {
|
|
8237
9043
|
let manifest = {};
|
|
8238
9044
|
try {
|
|
8239
|
-
const manifestContent = await (0,
|
|
9045
|
+
const manifestContent = await (0, import_promises8.readFile)(manifestPath2, "utf-8");
|
|
8240
9046
|
manifest = JSON.parse(manifestContent);
|
|
8241
9047
|
} catch {
|
|
8242
9048
|
}
|
|
@@ -8244,8 +9050,8 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
8244
9050
|
manifest.tunnel = {};
|
|
8245
9051
|
}
|
|
8246
9052
|
manifest.tunnel.subdomain = subdomain;
|
|
8247
|
-
await (0,
|
|
8248
|
-
await (0,
|
|
9053
|
+
await (0, import_promises8.mkdir)(import_node_path12.default.dirname(manifestPath2), { recursive: true });
|
|
9054
|
+
await (0, import_promises8.writeFile)(
|
|
8249
9055
|
manifestPath2,
|
|
8250
9056
|
JSON.stringify(manifest, null, 2),
|
|
8251
9057
|
"utf-8"
|
|
@@ -8263,12 +9069,12 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
8263
9069
|
}
|
|
8264
9070
|
}
|
|
8265
9071
|
let serverFile;
|
|
8266
|
-
const manifestPath =
|
|
9072
|
+
const manifestPath = import_node_path12.default.join(projectPath, "dist", "mcp-use.json");
|
|
8267
9073
|
try {
|
|
8268
|
-
const manifestContent = await (0,
|
|
9074
|
+
const manifestContent = await (0, import_promises8.readFile)(manifestPath, "utf-8");
|
|
8269
9075
|
const manifest = JSON.parse(manifestContent);
|
|
8270
9076
|
if (manifest.entryPoint) {
|
|
8271
|
-
await (0,
|
|
9077
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, manifest.entryPoint));
|
|
8272
9078
|
serverFile = manifest.entryPoint;
|
|
8273
9079
|
}
|
|
8274
9080
|
} catch {
|
|
@@ -8289,7 +9095,7 @@ program.command("start").description("Start production server").option("-p, --pa
|
|
|
8289
9095
|
];
|
|
8290
9096
|
for (const candidate of serverCandidates) {
|
|
8291
9097
|
try {
|
|
8292
|
-
await (0,
|
|
9098
|
+
await (0, import_promises8.access)(import_node_path12.default.join(projectPath, candidate));
|
|
8293
9099
|
serverFile = candidate;
|
|
8294
9100
|
break;
|
|
8295
9101
|
} catch {
|
|
@@ -8340,13 +9146,13 @@ Looked for:
|
|
|
8340
9146
|
if (isTsEntry) {
|
|
8341
9147
|
try {
|
|
8342
9148
|
const projectRequire = (0, import_node_module2.createRequire)(
|
|
8343
|
-
|
|
9149
|
+
import_node_path12.default.join(projectPath, "package.json")
|
|
8344
9150
|
);
|
|
8345
9151
|
const tsxPkgPath = projectRequire.resolve("tsx/package.json");
|
|
8346
|
-
const tsxPkg = JSON.parse(await (0,
|
|
9152
|
+
const tsxPkg = JSON.parse(await (0, import_promises8.readFile)(tsxPkgPath, "utf-8"));
|
|
8347
9153
|
const binField = typeof tsxPkg.bin === "string" ? tsxPkg.bin : tsxPkg.bin?.tsx ?? Object.values(tsxPkg.bin ?? {})[0];
|
|
8348
9154
|
if (!binField) throw new Error("tsx bin entry not found");
|
|
8349
|
-
const tsxBin =
|
|
9155
|
+
const tsxBin = import_node_path12.default.resolve(import_node_path12.default.dirname(tsxPkgPath), binField);
|
|
8350
9156
|
spawnCmd = "node";
|
|
8351
9157
|
spawnArgs = [tsxBin, serverFile];
|
|
8352
9158
|
} catch (error) {
|
|
@@ -8359,7 +9165,7 @@ Looked for:
|
|
|
8359
9165
|
spawnArgs = ["tsx", serverFile];
|
|
8360
9166
|
}
|
|
8361
9167
|
}
|
|
8362
|
-
const serverProc = (0,
|
|
9168
|
+
const serverProc = (0, import_node_child_process11.spawn)(spawnCmd, spawnArgs, {
|
|
8363
9169
|
cwd: projectPath,
|
|
8364
9170
|
stdio: "inherit",
|
|
8365
9171
|
env: env2
|
|
@@ -8492,10 +9298,11 @@ program.addCommand(createClientCommand());
|
|
|
8492
9298
|
program.addCommand(createDeploymentsCommand());
|
|
8493
9299
|
program.addCommand(createServersCommand());
|
|
8494
9300
|
program.addCommand(createSkillsCommand());
|
|
9301
|
+
program.addCommand(createScreenshotCommand());
|
|
8495
9302
|
program.command("generate-types").description(
|
|
8496
9303
|
"Generate TypeScript type definitions for tools (writes .mcp-use/tool-registry.d.ts)"
|
|
8497
9304
|
).option("-p, --path <path>", "Path to project directory", process.cwd()).option("--server <file>", "Server entry file", "index.ts").action(async (options) => {
|
|
8498
|
-
const projectPath =
|
|
9305
|
+
const projectPath = import_node_path12.default.resolve(options.path);
|
|
8499
9306
|
try {
|
|
8500
9307
|
console.log(source_default.blue("Generating tool registry types..."));
|
|
8501
9308
|
const result = await generateToolRegistryTypesForServer(
|