Skip to main content
Glama

execute_command

Run shell commands securely within Windows Subsystem for Linux (WSL) by specifying the command, working directory, and timeout, with built-in validation and protection against vulnerabilities like shell injection.

Instructions

Execute a command in WSL

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
commandYesCommand to execute
timeoutNoTimeout in milliseconds
working_dirNoWorking directory for command execution

Implementation Reference

  • Low-level handler that sanitizes input, spawns WSL process via child_process.spawn, captures stdout/stderr/exit code, and handles timeout.
    public async execute_command( command: string, working_dir?: string, timeout?: number, ): Promise<CommandResponse> { return new Promise((resolve, reject) => { const sanitized_command = this.sanitize_command(command); const validated_dir = this.validate_working_dir(working_dir); const validated_timeout = this.validate_timeout(timeout); const cd_command = validated_dir ? `cd "${validated_dir}" && ` : ''; const full_command = `${cd_command}${sanitized_command}`; const wsl_process = spawn(wsl_config.executable, [ '--exec', wsl_config.shell, '-c', full_command, ]); let stdout = ''; let stderr = ''; wsl_process.stdout.on('data', (data) => { stdout += data.toString(); }); wsl_process.stderr.on('data', (data) => { stderr += data.toString(); }); let timeout_id: NodeJS.Timeout | undefined; if (validated_timeout) { timeout_id = setTimeout(() => { wsl_process.kill(); reject(new CommandTimeoutError(validated_timeout)); }, validated_timeout); } wsl_process.on('close', (code) => { if (timeout_id) { clearTimeout(timeout_id); } resolve({ stdout, stderr, exit_code: code, command: sanitized_command, working_dir: validated_dir, }); }); wsl_process.on('error', (error) => { if (timeout_id) { clearTimeout(timeout_id); } reject(error); }); }); }
  • src/index.ts:325-395 (registration)
    MCP server tool registration for 'execute_command', including schema, annotations, and the handler function.
    this.server.tool( { name: 'execute_command', description: 'Execute a command in WSL (use read-only tools when possible)', schema: v.object({ command: v.pipe( v.string(), v.description('Command to execute'), ), working_dir: v.optional( v.pipe( v.string(), v.description('Working directory'), ), ), timeout: v.optional( v.pipe( v.number(), v.description('Timeout (ms)'), ), ), }), annotations: { readOnlyHint: false, destructiveHint: true, }, }, async ({ command, working_dir, timeout }) => { try { const result = await this.execute_wsl_command( command, working_dir, timeout, ); if (result.requires_confirmation) { return { content: [ { type: 'text' as const, text: result.stderr, }, ], }; } return { content: [ { type: 'text' as const, text: this.format_output(result), }, ], }; } catch (error) { return { content: [ { type: 'text' as const, text: `Error executing command: ${ error instanceof Error ? error.message : String(error) }`, }, ], isError: true, }; } }, );
  • Helper method in WslServer that implements safety checks for dangerous commands, requiring confirmation via separate tool if needed, before delegating to CommandExecutor.
    private async execute_wsl_command( command: string, working_dir?: string, timeout?: number, ): Promise<CommandResponse> { return new Promise((resolve, reject) => { const requires_confirmation = this.command_executor.is_dangerous_command(command); if (requires_confirmation) { // Generate a unique confirmation ID const confirmation_id = Math.random() .toString(36) .substring(7); this.pending_confirmations.set(confirmation_id, { command, working_dir, timeout, resolve, reject, }); // Return early with confirmation request resolve({ stdout: '', stderr: `Command "${command}" requires confirmation. Use confirm_command with ID: ${confirmation_id}`, exit_code: null, command, requires_confirmation: true, }); return; } this.command_executor .execute_command(command, working_dir, timeout) .then(resolve) .catch(reject); }); }
  • Helper method to detect potentially dangerous commands based on predefined list.
    public is_dangerous_command(command: string): boolean { return dangerous_commands.some( (dangerous) => command.toLowerCase().includes(dangerous.toLowerCase()) || command.match(new RegExp(`\\b${dangerous}\\b`, 'i')), ); }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/spences10/mcp-wsl-exec'

If you have feedback or need assistance with the MCP directory API, please join our Discord server