execute_command
Execute shell commands securely across Windows, macOS, and Linux platforms. Supports command arguments and includes whitelisting and approval mechanisms for enhanced security.
Instructions
Execute a shell command on the current platform
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Command arguments | |
| command | Yes | The command to execute |
Input Schema (JSON Schema)
{
"properties": {
"args": {
"description": "Command arguments",
"items": {
"type": "string"
},
"type": "array"
},
"command": {
"description": "The command to execute",
"type": "string"
}
},
"required": [
"command"
],
"type": "object"
}
Implementation Reference
- src/index.ts:335-417 (handler)The primary handler for the 'execute_command' MCP tool. Validates input with Zod, checks command whitelist security level, queues non-blocking for approval if required, or delegates execution to CommandService.executeCommand.private async handleExecuteCommand(args: any) { const schema = z.object({ command: z.string(), args: z.array(z.string()).optional(), }); // Log the start of command execution logger.debug(`handleExecuteCommand called with args: ${JSON.stringify(args)}`); const { command, args: commandArgs = [] } = schema.parse(args); // Extract the base command (without path) const baseCommand = path.basename(command); logger.debug(`[Executing Command] Command: ${command} ${commandArgs.join(' ')}`); logger.debug(`Base command: ${baseCommand}`); // Check if the command requires approval before attempting execution const whitelist = this.commandService.getWhitelist(); logger.debug(`Whitelist entries: ${whitelist.length}`); const whitelistEntry = whitelist.find(entry => entry.command === baseCommand); logger.debug(`Whitelist entry found: ${whitelistEntry ? 'yes' : 'no'}`); if (whitelistEntry) { logger.debug(`Security level: ${whitelistEntry.securityLevel}`); } if (whitelistEntry && whitelistEntry.securityLevel === CommandSecurityLevel.REQUIRES_APPROVAL) { logger.debug(`[Command Requires Approval] Command: ${command} ${commandArgs.join(' ')}`); // Use the non-blocking method to queue the command for approval const commandId = this.commandService.queueCommandForApprovalNonBlocking(command, commandArgs); logger.debug(`Command queued for approval with ID: ${commandId}`); // Return immediately with instructions for approval logger.debug(`Returning response to client`); return { content: [ { type: 'text', text: `This command requires approval. It has been queued with ID: ${commandId}\n\nPlease approve this command in the UI or use the 'approve_command' function with this command ID.`, }, ], isError: false, // Not an error, just needs approval }; } // For safe commands or forbidden commands, use the normal execution path try { // Use the CommandService's executeCommand method const result = await this.commandService.executeCommand(command, commandArgs); return { content: [ { type: 'text', text: result.stdout, }, { type: 'text', text: result.stderr ? `Error output: ${result.stderr}` : '', }, ], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; console.error(`[Command Execution Failed] Error: ${errorMessage}`); return { content: [ { type: 'text', text: `Command execution failed: ${errorMessage}`, }, ], isError: true, }; } }
- src/index.ts:152-168 (schema)Input schema definition for the 'execute_command' tool as registered in ListToolsRequestHandler.inputSchema: { type: 'object', properties: { command: { type: 'string', description: 'The command to execute', }, args: { type: 'array', items: { type: 'string', }, description: 'Command arguments', }, }, required: ['command'], },
- src/index.ts:149-169 (registration)Tool registration entry in the ListToolsRequestHandler response, defining name, description, and input schema.{ name: 'execute_command', description: 'Execute a shell command on the current platform', inputSchema: { type: 'object', properties: { command: { type: 'string', description: 'The command to execute', }, args: { type: 'array', items: { type: 'string', }, description: 'Command arguments', }, }, required: ['command'], }, },
- src/index.ts:285-286 (handler)Dispatch case in CallToolRequestHandler switch statement that routes to the execute_command handler.case 'execute_command': return await this.handleExecuteCommand(args);
- Core helper method executeCommand that performs whitelist validation, handles approval queuing or direct safe execution using child_process.execFile.public async executeCommand( command: string, args: string[] = [], options: { timeout?: number; requestedBy?: string; } = {} ): Promise<CommandResult> { const securityLevel = this.validateCommand(command, args); // If command is not whitelisted, reject if (securityLevel === null) { throw new Error(`Command not whitelisted: ${command}`); } // If command is forbidden, reject if (securityLevel === CommandSecurityLevel.FORBIDDEN) { throw new Error(`Command is forbidden: ${command}`); } // If command requires approval, add to pending queue if (securityLevel === CommandSecurityLevel.REQUIRES_APPROVAL) { return this.queueCommandForApproval(command, args, options.requestedBy); } // For safe commands, execute immediately try { const timeout = options.timeout || this.defaultTimeout; const { stdout, stderr } = await execFileAsync(command, args, { timeout, shell: this.useShell ? this.shell : false }); return { stdout, stderr }; } catch (error) { if (error instanceof Error) { throw new Error(`Command execution failed: ${error.message}`); } throw error; } }