From 9f42629b348b873b05fd1a7143f9be784aac300a Mon Sep 17 00:00:00 2001 From: Nicolas Barraud Date: Mon, 10 Mar 2025 20:34:07 -0400 Subject: [PATCH] Forgot package files --- bin/cli.js | 345 +++++++++++++++++++++------------------------- package-lock.json | 68 +++++++-- package.json | 29 ++-- 3 files changed, 238 insertions(+), 204 deletions(-) diff --git a/bin/cli.js b/bin/cli.js index 4efce01..2c4f535 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -7,213 +7,186 @@ import { spawnPromise } from "spawn-rx"; import { fileURLToPath } from "url"; const __dirname = dirname(fileURLToPath(import.meta.url)); function handleError(error) { - let message; - if (error instanceof Error) { - message = error.message; - } else if (typeof error === "string") { - message = error; - } else { - message = "Unknown error"; - } - console.error(message); - process.exit(1); + let message; + if (error instanceof Error) { + message = error.message; + } + else if (typeof error === "string") { + message = error; + } + else { + message = "Unknown error"; + } + console.error(message); + process.exit(1); } function delay(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); + return new Promise((resolve) => setTimeout(resolve, ms)); } async function runWebClient(args) { - const inspectorServerPath = resolve( - __dirname, - "..", - "server", - "build", - "index.js", - ); - // Path to the client entry point - const inspectorClientPath = resolve( - __dirname, - "..", - "client", - "bin", - "cli.js", - ); - const CLIENT_PORT = process.env.CLIENT_PORT ?? "5173"; - const SERVER_PORT = process.env.SERVER_PORT ?? "3000"; - console.log("Starting MCP inspector..."); - const abort = new AbortController(); - let cancelled = false; - process.on("SIGINT", () => { - cancelled = true; - abort.abort(); - }); - const server = spawnPromise( - "node", - [ - inspectorServerPath, - ...(args.command ? [`--env`, args.command] : []), - ...(args.args ? [`--args=${args.args.join(" ")}`] : []), - ], - { - env: { - ...process.env, - PORT: SERVER_PORT, - MCP_ENV_VARS: JSON.stringify(args.envArgs), - }, - signal: abort.signal, - echoOutput: true, - }, - ); - const client = spawnPromise("node", [inspectorClientPath], { - env: { ...process.env, PORT: CLIENT_PORT }, - signal: abort.signal, - echoOutput: true, - }); - // Make sure our server/client didn't immediately fail - await Promise.any([server, client, delay(2 * 1000)]); - const portParam = SERVER_PORT === "3000" ? "" : `?proxyPort=${SERVER_PORT}`; - console.log( - `\nšŸ” MCP Inspector is up and running at http://localhost:${CLIENT_PORT}${portParam} šŸš€`, - ); - try { - await Promise.any([server, client]); - } catch (e) { - if (!cancelled || process.env.DEBUG) { - throw e; + const inspectorServerPath = resolve(__dirname, "..", "server", "build", "index.js"); + // Path to the client entry point + const inspectorClientPath = resolve(__dirname, "..", "client", "bin", "cli.js"); + const CLIENT_PORT = process.env.CLIENT_PORT ?? "5173"; + const SERVER_PORT = process.env.SERVER_PORT ?? "3000"; + console.log("Starting MCP inspector..."); + const abort = new AbortController(); + let cancelled = false; + process.on("SIGINT", () => { + cancelled = true; + abort.abort(); + }); + const server = spawnPromise("node", [ + inspectorServerPath, + ...(args.command ? [`--env`, args.command] : []), + ...(args.args ? [`--args=${args.args.join(" ")}`] : []), + ], { + env: { + ...process.env, + PORT: SERVER_PORT, + MCP_ENV_VARS: JSON.stringify(args.envArgs), + }, + signal: abort.signal, + echoOutput: true, + }); + const client = spawnPromise("node", [inspectorClientPath], { + env: { ...process.env, PORT: CLIENT_PORT }, + signal: abort.signal, + echoOutput: true, + }); + // Make sure our server/client didn't immediately fail + await Promise.any([server, client, delay(2 * 1000)]); + const portParam = SERVER_PORT === "3000" ? "" : `?proxyPort=${SERVER_PORT}`; + console.log(`\nšŸ” MCP Inspector is up and running at http://localhost:${CLIENT_PORT}${portParam} šŸš€`); + try { + await Promise.any([server, client]); + } + catch (e) { + if (!cancelled || process.env.DEBUG) { + throw e; + } } - } } async function runCli(args) { - const projectRoot = resolve(__dirname, ".."); - const cliPath = resolve(projectRoot, "cli", "build", "index.js"); - const abort = new AbortController(); - let cancelled = false; - process.on("SIGINT", () => { - cancelled = true; - abort.abort(); - }); - try { - await spawnPromise("node", [cliPath, args.command, ...args.args], { - env: { ...process.env, ...args.envArgs }, - signal: abort.signal, - echoOutput: true, + const projectRoot = resolve(__dirname, ".."); + const cliPath = resolve(projectRoot, "cli", "build", "index.js"); + const abort = new AbortController(); + let cancelled = false; + process.on("SIGINT", () => { + cancelled = true; + abort.abort(); }); - } catch (e) { - if (!cancelled || process.env.DEBUG) { - throw e; + try { + await spawnPromise("node", [cliPath, args.command, ...args.args], { + env: { ...process.env, ...args.envArgs }, + signal: abort.signal, + echoOutput: true, + }); + } + catch (e) { + if (!cancelled || process.env.DEBUG) { + throw e; + } } - } } function loadConfigFile(configPath, serverName) { - try { - const resolvedConfigPath = path.isAbsolute(configPath) - ? configPath - : path.resolve(process.cwd(), configPath); - if (!fs.existsSync(resolvedConfigPath)) { - throw new Error(`Config file not found: ${resolvedConfigPath}`); + try { + const resolvedConfigPath = path.isAbsolute(configPath) + ? configPath + : path.resolve(process.cwd(), configPath); + if (!fs.existsSync(resolvedConfigPath)) { + throw new Error(`Config file not found: ${resolvedConfigPath}`); + } + const configContent = fs.readFileSync(resolvedConfigPath, "utf8"); + const parsedConfig = JSON.parse(configContent); + if (!parsedConfig.mcpServers || !parsedConfig.mcpServers[serverName]) { + const availableServers = Object.keys(parsedConfig.mcpServers || {}).join(", "); + throw new Error(`Server '${serverName}' not found in config file. Available servers: ${availableServers}`); + } + const serverConfig = parsedConfig.mcpServers[serverName]; + return serverConfig; } - const configContent = fs.readFileSync(resolvedConfigPath, "utf8"); - const parsedConfig = JSON.parse(configContent); - if (!parsedConfig.mcpServers || !parsedConfig.mcpServers[serverName]) { - const availableServers = Object.keys(parsedConfig.mcpServers || {}).join( - ", ", - ); - throw new Error( - `Server '${serverName}' not found in config file. Available servers: ${availableServers}`, - ); + catch (err) { + if (err instanceof SyntaxError) { + throw new Error(`Invalid JSON in config file: ${err.message}`); + } + throw err; } - const serverConfig = parsedConfig.mcpServers[serverName]; - return serverConfig; - } catch (err) { - if (err instanceof SyntaxError) { - throw new Error(`Invalid JSON in config file: ${err.message}`); - } - throw err; - } } function parseKeyValuePair(value, previous = {}) { - const parts = value.split("="); - const key = parts[0]; - const val = parts.slice(1).join("="); - if (val === undefined || val === "") { - throw new Error( - `Invalid parameter format: ${value}. Use key=value format.`, - ); - } - return { ...previous, [key]: val }; + const parts = value.split("="); + const key = parts[0]; + const val = parts.slice(1).join("="); + if (val === undefined || val === "") { + throw new Error(`Invalid parameter format: ${value}. Use key=value format.`); + } + return { ...previous, [key]: val }; } function parseArgs() { - const program = new Command(); - const argSeparatorIndex = process.argv.indexOf("--"); - let preArgs = process.argv; - let postArgs = []; - if (argSeparatorIndex !== -1) { - preArgs = process.argv.slice(0, argSeparatorIndex); - postArgs = process.argv.slice(argSeparatorIndex + 1); - } - program - .name("inspector-bin") - .allowExcessArguments() - .allowUnknownOption() - .option( - "-e ", - "environment variables in KEY=VALUE format", - parseKeyValuePair, - {}, - ) - .option("--config ", "config file path") - .option("--server ", "server name from config file") - .option("--cli", "enable CLI mode"); - // Parse only the arguments before -- - program.parse(preArgs); - const options = program.opts(); - const remainingArgs = program.args; - // Add back any arguments that came after -- - const finalArgs = [...remainingArgs, ...postArgs]; - // Validate that config and server are provided together - if ( - (options.config && !options.server) || - (!options.config && options.server) - ) { - throw new Error( - "Both --config and --server must be provided together. If you specify one, you must specify the other.", - ); - } - // If config file is specified, load and use the options from the file. We must merge the args - // from the command line and the file together, or we will miss the method options (--method, - // etc.) - if (options.config && options.server) { - const config = loadConfigFile(options.config, options.server); + const program = new Command(); + const argSeparatorIndex = process.argv.indexOf("--"); + let preArgs = process.argv; + let postArgs = []; + if (argSeparatorIndex !== -1) { + preArgs = process.argv.slice(0, argSeparatorIndex); + postArgs = process.argv.slice(argSeparatorIndex + 1); + } + program + .name("inspector-bin") + .allowExcessArguments() + .allowUnknownOption() + .option("-e ", "environment variables in KEY=VALUE format", parseKeyValuePair, {}) + .option("--config ", "config file path") + .option("--server ", "server name from config file") + .option("--cli", "enable CLI mode"); + // Parse only the arguments before -- + program.parse(preArgs); + const options = program.opts(); + const remainingArgs = program.args; + // Add back any arguments that came after -- + const finalArgs = [...remainingArgs, ...postArgs]; + // Validate that config and server are provided together + if ((options.config && !options.server) || + (!options.config && options.server)) { + throw new Error("Both --config and --server must be provided together. If you specify one, you must specify the other."); + } + // If config file is specified, load and use the options from the file. We must merge the args + // from the command line and the file together, or we will miss the method options (--method, + // etc.) + if (options.config && options.server) { + const config = loadConfigFile(options.config, options.server); + return { + command: config.command, + args: [...(config.args || []), ...finalArgs], + envArgs: { ...(config.env || {}), ...(options.e || {}) }, + cli: options.cli || false, + }; + } + // Otherwise use command line arguments + const command = finalArgs[0] || ""; + const args = finalArgs.slice(1); return { - command: config.command, - args: [...(config.args || []), ...finalArgs], - envArgs: { ...(config.env || {}), ...(options.e || {}) }, - cli: options.cli || false, + command, + args, + envArgs: options.e || {}, + cli: options.cli || false, }; - } - // Otherwise use command line arguments - const command = finalArgs[0] || ""; - const args = finalArgs.slice(1); - return { - command, - args, - envArgs: options.e || {}, - cli: options.cli || false, - }; } async function main() { - process.on("uncaughtException", (error) => { - handleError(error); - }); - try { - const args = parseArgs(); - console.log(args); - if (args.cli) { - runCli(args); - } else { - await runWebClient(args); + process.on("uncaughtException", (error) => { + handleError(error); + }); + try { + const args = parseArgs(); + if (args.cli) { + runCli(args); + } + else { + await runWebClient(args); + } + } + catch (error) { + handleError(error); } - } catch (error) { - handleError(error); - } } main(); diff --git a/package-lock.json b/package-lock.json index 550bb75..13ac966 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,25 +10,56 @@ "license": "MIT", "workspaces": [ "client", - "server" + "server", + "cli", + "bin" ], "dependencies": { - "@modelcontextprotocol/inspector-client": "0.4.1", - "@modelcontextprotocol/inspector-server": "0.4.1", + "@modelcontextprotocol/inspector-bin": "0.5.1", + "@modelcontextprotocol/inspector-cli": "0.5.1", + "@modelcontextprotocol/inspector-client": "0.5.1", + "@modelcontextprotocol/inspector-server": "0.5.1", + "@modelcontextprotocol/sdk": "^1.6.1", + "commander": "^13.1.0", "concurrently": "^9.0.1", "shell-quote": "^1.8.2", "spawn-rx": "^5.1.2", - "ts-node": "^10.9.2" + "ts-node": "^10.9.2", + "zod": "^3.23.8" }, "bin": { - "mcp-inspector": "bin/cli.js" + "mcp-inspector": "bin/cli.js", + "mcp-inspector-cli": "cli/bin/cli.js" }, "devDependencies": { "@types/node": "^22.7.5", "@types/shell-quote": "^1.7.5", - "prettier": "3.3.3" + "prettier": "3.3.3", + "typescript": "^5.4.2" } }, + "bin": { + "name": "@modelcontextprotocol/inspector-bin", + "version": "0.5.1", + "license": "MIT", + "bin": { + "mcp-inspector": "cli.js" + }, + "devDependencies": {} + }, + "cli": { + "name": "@modelcontextprotocol/inspector-cli", + "version": "0.5.1", + "license": "MIT", + "dependencies": { + "commander": "^13.1.0", + "spawn-rx": "^5.1.2" + }, + "bin": { + "mcp-inspector-cli": "build/index.js" + }, + "devDependencies": {} + }, "client": { "name": "@modelcontextprotocol/inspector-client", "version": "0.5.1", @@ -1204,6 +1235,14 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@modelcontextprotocol/inspector-bin": { + "resolved": "bin", + "link": true + }, + "node_modules/@modelcontextprotocol/inspector-cli": { + "resolved": "cli", + "link": true + }, "node_modules/@modelcontextprotocol/inspector-client": { "resolved": "client", "link": true @@ -4108,12 +4147,12 @@ "license": "MIT" }, "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", "license": "MIT", "engines": { - "node": ">= 6" + "node": ">=18" } }, "node_modules/concat-map": { @@ -6936,6 +6975,15 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", diff --git a/package.json b/package.json index 3de7ce4..a0c1129 100644 --- a/package.json +++ b/package.json @@ -8,24 +8,31 @@ "bugs": "https://github.com/modelcontextprotocol/inspector/issues", "type": "module", "bin": { - "mcp-inspector": "./bin/cli.js" + "mcp-inspector": "./bin/cli.js", + "mcp-inspector-cli": "./cli/bin/cli.js" }, "files": [ "bin", "client/bin", "client/dist", - "server/build" + "server/build", + "cli/bin", + "cli/build" ], "workspaces": [ "client", - "server" + "server", + "cli", + "bin" ], "scripts": { "dev": "concurrently \"cd client && npm run dev\" \"cd server && npm run dev\"", "dev:windows": "concurrently \"cd client && npm run dev\" \"cd server && npm run dev:windows", + "build-bin": "cd bin && npm run build", "build-server": "cd server && npm run build", "build-client": "cd client && npm run build", - "build": "npm run build-server && npm run build-client", + "build-cli": "cd cli && npm run build", + "build": "npm run build-bin && npm run build-server && npm run build-client && npm run build-cli", "start-server": "cd server && npm run start", "start-client": "cd client && npm run preview", "start": "node ./bin/cli.js", @@ -34,16 +41,22 @@ "publish-all": "npm publish --workspaces --access public && npm publish --access public" }, "dependencies": { - "@modelcontextprotocol/inspector-client": "0.4.1", - "@modelcontextprotocol/inspector-server": "0.4.1", + "@modelcontextprotocol/inspector-bin": "0.5.1", + "@modelcontextprotocol/inspector-cli": "0.5.1", + "@modelcontextprotocol/inspector-client": "0.5.1", + "@modelcontextprotocol/inspector-server": "0.5.1", + "@modelcontextprotocol/sdk": "^1.6.1", + "commander": "^13.1.0", "concurrently": "^9.0.1", "shell-quote": "^1.8.2", "spawn-rx": "^5.1.2", - "ts-node": "^10.9.2" + "ts-node": "^10.9.2", + "zod": "^3.23.8" }, "devDependencies": { "@types/node": "^22.7.5", "@types/shell-quote": "^1.7.5", - "prettier": "3.3.3" + "prettier": "3.3.3", + "typescript": "^5.4.2" } }