run_command
Execute Linux commands on a machine to run scripts, manage files, or process input through STDIN from a specified working directory.
Instructions
Run a command on this linux machine
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| command | Yes | Command with args | |
| workdir | No | Optional, current working directory | |
| stdin | No | Optional, text to pipe into the command's STDIN. For example, pass a python script to python3. Or, pass text for a new file to the cat command to create it! |
Implementation Reference
- src/run-command.ts:25-75 (handler)The core handler function `runCommand` that parses args, executes the shell command using `execute` (which uses child_process.exec or execFileWithInput), handles workdir and stdin, catches errors, and returns formatted CallToolResult.export type RunCommandArgs = Record<string, unknown> | undefined; export async function runCommand(args: RunCommandArgs): Promise<CallToolResult> { const command = args?.command as string; if (!command) { const message = "Command is required, current value: " + command; return { isError: true, content: [{ type: "text", text: message }], }; } const options: ObjectEncodingOptions & ExecOptions = { encoding: "utf8" }; if (args?.workdir) { options.cwd = String(args.workdir); } const stdin = args?.stdin as string; try { const result = await execute(command, stdin, options); return { content: messagesFor(result), }; } catch (error) { // PRN do I want to differentiate non-command related error (i.e. if messagesFor blows up // or presumably if smth else goes wrong with the node code in exec that isn't command related // if so, write a test first // console.log("ERROR_runCommand", error); // ExecException (error + stdout/stderr) merged // - IIUC this happens on uncaught failures // - but if you catch an exec() promise failure (or use exec's callback) => you get separated values: error, stdout, stderr // - which is why I mirror this response type in my reject(error) calls // // 'error' example: // code: 127, // killed: false, // signal: null, // cmd: 'nonexistentcommand', // stdout: '', // stderr: '/bin/sh: nonexistentcommand: command not found\n' const response = { isError: true, content: messagesFor(error as ExecResult), }; always_log("WARN: run_command failed", response); return response; } }
- src/tools.ts:17-44 (schema)The input schema definition for the run_command tool, including properties for command (required), workdir, and stdin.name: "run_command", description: "Run a command on this " + os.platform() + " machine", inputSchema: { type: "object", properties: { command: { type: "string", description: "Command with args", }, workdir: { // previous run_command calls can probe the filesystem and find paths to change to type: "string", description: "Optional, current working directory", }, stdin: { type: "string", description: "Optional, text to pipe into the command's STDIN. For example, pass a python script to python3. Or, pass text for a new file to the cat command to create it!", }, // args to consider: // - env - obscure cases where command takes a param only via an env var? // - timeout - lets just hard code this for now }, required: ["command"], }, },
- src/tools.ts:11-62 (registration)The `reisterTools` function that registers the run_command tool on the MCP server by handling ListToolsRequestSchema (listing the tool with schema) and CallToolRequestSchema (dispatching calls to runCommand based on name).export function reisterTools(server: Server) { server.setRequestHandler(ListToolsRequestSchema, async () => { verbose_log("INFO: ListTools"); return { tools: [ { name: "run_command", description: "Run a command on this " + os.platform() + " machine", inputSchema: { type: "object", properties: { command: { type: "string", description: "Command with args", }, workdir: { // previous run_command calls can probe the filesystem and find paths to change to type: "string", description: "Optional, current working directory", }, stdin: { type: "string", description: "Optional, text to pipe into the command's STDIN. For example, pass a python script to python3. Or, pass text for a new file to the cat command to create it!", }, // args to consider: // - env - obscure cases where command takes a param only via an env var? // - timeout - lets just hard code this for now }, required: ["command"], }, }, ], }; }); server.setRequestHandler( CallToolRequestSchema, async (request): Promise<CallToolResult> => { verbose_log("INFO: ToolRequest", request); switch (request.params.name) { case "run_command": { return await runCommand(request.params.arguments); } default: throw new Error("Unknown tool"); } } ); }