execute_command
Run shell commands in Windows using PowerShell, CMD, or Git Bash. Specify the shell, command, and working directory for precise system control and automation.
Instructions
Execute a command in the specified shell (powershell, cmd, or gitbash)
Example usage (PowerShell):
{
"shell": "powershell",
"command": "Get-Process | Select-Object -First 5",
"workingDir": "C:\Users\username"
}
Example usage (CMD):
{
"shell": "cmd",
"command": "dir /b",
"workingDir": "C:\Projects"
}
Example usage (Git Bash):
{
"shell": "gitbash",
"command": "ls -la",
"workingDir": "/c/Users/username"
}
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| command | Yes | Command to execute | |
| shell | Yes | Shell to use for command execution | |
| workingDir | No | Working directory for command execution (optional) |
Implementation Reference
- src/index.ts:283-436 (handler)Core handler logic for the 'execute_command' tool. Validates and parses input using Zod, checks security constraints, spawns the shell process using child_process.spawn, captures stdout/stderr, handles process events, timeouts, errors, logs to command history, and returns structured response with output, isError flag, and metadata.case "execute_command": { const args = z.object({ shell: z.enum(Object.keys(this.config.shells).filter(shell => this.config.shells[shell as keyof typeof this.config.shells].enabled ) as [string, ...string[]]), command: z.string(), workingDir: z.string().optional() }).parse(request.params.arguments); // Validate command this.validateCommand(args.shell as keyof ServerConfig['shells'], args.command); // Validate working directory if provided let workingDir = args.workingDir ? path.resolve(args.workingDir) : process.cwd(); const shellKey = args.shell as keyof typeof this.config.shells; const shellConfig = this.config.shells[shellKey]; if (this.config.security.restrictWorkingDirectory) { const isAllowedPath = Array.from(this.allowedPaths).some( allowedPath => workingDir.startsWith(allowedPath) ); if (!isAllowedPath) { throw new McpError( ErrorCode.InvalidRequest, `Working directory (${workingDir}) outside allowed paths. Consult the server admin for configuration changes (config.json - restrictWorkingDirectory, allowedPaths).` ); } } // Execute command return new Promise((resolve, reject) => { let shellProcess: ReturnType<typeof spawn>; try { shellProcess = spawn( shellConfig.command, [...shellConfig.args, args.command], { cwd: workingDir, stdio: ['pipe', 'pipe', 'pipe'] } ); } catch (err) { throw new McpError( ErrorCode.InternalError, `Failed to start shell process: ${err instanceof Error ? err.message : String(err)}. Consult the server admin for configuration changes (config.json - shells).` ); } if (!shellProcess.stdout || !shellProcess.stderr) { throw new McpError( ErrorCode.InternalError, 'Failed to initialize shell process streams' ); } let output = ''; let error = ''; shellProcess.stdout.on('data', (data) => { output += data.toString(); }); shellProcess.stderr.on('data', (data) => { error += data.toString(); }); shellProcess.on('close', (code) => { // Prepare detailed result message let resultMessage = ''; if (code === 0) { resultMessage = output || 'Command completed successfully (no output)'; } else { resultMessage = `Command failed with exit code ${code}\n`; if (error) { resultMessage += `Error output:\n${error}\n`; } if (output) { resultMessage += `Standard output:\n${output}`; } if (!error && !output) { resultMessage += 'No error message or output was provided'; } } // Store in history if enabled if (this.config.security.logCommands) { this.commandHistory.push({ command: args.command, output: resultMessage, timestamp: new Date().toISOString(), exitCode: code ?? -1 }); // Trim history if needed if (this.commandHistory.length > this.config.security.maxHistorySize) { this.commandHistory = this.commandHistory.slice(-this.config.security.maxHistorySize); } } resolve({ content: [{ type: "text", text: resultMessage }], isError: code !== 0, metadata: { exitCode: code ?? -1, shell: args.shell, workingDirectory: workingDir } }); }); // Handle process errors (e.g., shell crashes) shellProcess.on('error', (err) => { const errorMessage = `Shell process error: ${err.message}`; if (this.config.security.logCommands) { this.commandHistory.push({ command: args.command, output: errorMessage, timestamp: new Date().toISOString(), exitCode: -1 }); } reject(new McpError( ErrorCode.InternalError, errorMessage )); }); // Set configurable timeout to prevent hanging const timeout = setTimeout(() => { shellProcess.kill(); const timeoutMessage = `Command execution timed out after ${this.config.security.commandTimeout} seconds. Consult the server admin for configuration changes (config.json - commandTimeout).`; if (this.config.security.logCommands) { this.commandHistory.push({ command: args.command, output: timeoutMessage, timestamp: new Date().toISOString(), exitCode: -1 }); } reject(new McpError( ErrorCode.InternalError, timeoutMessage )); }, this.config.security.commandTimeout * 1000); shellProcess.on('close', () => clearTimeout(timeout)); }); }
- src/index.ts:124-175 (registration)Tool registration in the ListTools response, defining name, detailed usage description with shell examples, and inputSchema JSON Schema for validation (shell enum from enabled config shells, required command, optional workingDir).{ name: "execute_command", description: `Execute a command in the specified shell (powershell, cmd, or gitbash) Example usage (PowerShell): \`\`\`json { "shell": "powershell", "command": "Get-Process | Select-Object -First 5", "workingDir": "C:\\Users\\username" } \`\`\` Example usage (CMD): \`\`\`json { "shell": "cmd", "command": "dir /b", "workingDir": "C:\\Projects" } \`\`\` Example usage (Git Bash): \`\`\`json { "shell": "gitbash", "command": "ls -la", "workingDir": "/c/Users/username" } \`\`\``, inputSchema: { type: "object", properties: { shell: { type: "string", enum: Object.keys(this.config.shells).filter(shell => this.config.shells[shell as keyof typeof this.config.shells].enabled ), description: "Shell to use for command execution" }, command: { type: "string", description: "Command to execute" }, workingDir: { type: "string", description: "Working directory for command execution (optional)" } }, required: ["shell", "command"] } },
- src/index.ts:284-290 (schema)Runtime input validation schema using Zod, mirroring the inputSchema from registration, parsing arguments from CallToolRequest.const args = z.object({ shell: z.enum(Object.keys(this.config.shells).filter(shell => this.config.shells[shell as keyof typeof this.config.shells].enabled ) as [string, ...string[]]), command: z.string(), workingDir: z.string().optional() }).parse(request.params.arguments);