ssh_exec
Execute commands on remote SSH servers using natural language, with options for connection selection, working directory, and timeout.
Instructions
Execute a command on an SSH server
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| command | Yes | Command to execute | |
| connectionId | No | Connection ID (optional, uses most recent if not provided) | |
| timeout | No | Command timeout in milliseconds (optional) | |
| cwd | No | Working directory (optional) |
Implementation Reference
- src/index.ts:80-105 (registration)Tool registration for ssh_exec in ListToolsRequestSchema handler. Defines name, description, and inputSchema with parameters: command (required), connectionId, timeout, cwd (all optional).
{ name: 'ssh_exec', description: 'Execute a command on an SSH server', inputSchema: { type: 'object', properties: { command: { type: 'string', description: 'Command to execute', }, connectionId: { type: 'string', description: 'Connection ID (optional, uses most recent if not provided)', }, timeout: { type: 'number', description: 'Command timeout in milliseconds (optional)', }, cwd: { type: 'string', description: 'Working directory (optional)', }, }, required: ['command'], }, }, - src/index.ts:349-375 (handler)Main handler for ssh_exec tool call in CallToolRequestSchema switch statement. Extracts command, connectionId, timeout, cwd from args and delegates to sshManager.exec().
case 'ssh_exec': { const command = args.command as string; const connectionId = args.connectionId as string | undefined; const timeout = args.timeout as number | undefined; const cwd = args.cwd as string | undefined; try { const result = await sshManager.exec(command, connectionId, { timeout, cwd }); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } catch (err: unknown) { return { content: [ { type: 'text', text: JSON.stringify({ error: err instanceof Error ? err.message : String(err) }, null, 2), }, ], isError: true, }; } } - src/ssh-manager.ts:151-225 (handler)Core exec method in SSHManager class. Finds the connection (by ID or most recent), checks if busy, optionally changes directory via shell-escaped cd, executes command via ssh2 Client.exec(), collects stdout/stderr/exitCode/duration, and handles timeouts.
async exec( command: string, connectionId?: string, options?: { timeout?: number; cwd?: string } ): Promise<ExecResult> { const conn = this.getConnection(connectionId); if (!conn) { throw new Error('No connection available'); } if (conn.isBusy) { throw new Error('Connection is busy'); } conn.isBusy = true; conn.lastActivity = new Date(); const startTime = Date.now(); // Log command execution if enabled if (this.logCommands) { console.error(`[SSH] Executing: ${command}${options?.cwd ? ` (cwd: ${options.cwd})` : ''}`); } try { // Use shell escape to prevent command injection const fullCommand = options?.cwd ? `cd ${shellEscape(options.cwd)} && ${command}` : command; return await new Promise((resolve, reject) => { const timeoutMs = options?.timeout || this.commandTimeout; const timeout = setTimeout(() => { reject(new Error('Command timeout')); }, timeoutMs); conn.client.exec(fullCommand, (err, stream) => { if (err) { clearTimeout(timeout); reject(err); return; } let stdout = ''; let stderr = ''; let exitCode = 0; stream.on('data', (data: Buffer) => { stdout += data.toString(); }); stream.stderr.on('data', (data: Buffer) => { stderr += data.toString(); }); stream.on('close', (code: number | null) => { clearTimeout(timeout); exitCode = code ?? 0; resolve({ stdout, stderr, exitCode, duration: Date.now() - startTime, }); }); }); }); } finally { conn.isBusy = false; conn.lastActivity = new Date(); // Log completion if enabled if (this.logCommands) { console.error(`[SSH] Command completed in ${Date.now() - startTime}ms`); } } } - src/ssh-manager.ts:20-23 (helper)shellEscape helper function used in exec to prevent command injection by wrapping values in single quotes and escaping embedded single quotes.
function shellEscape(value: string): string { // Use single quotes and escape any single quotes inside return "'" + value.replace(/'/g, "'\\''") + "'"; } - src/types.ts:42-47 (schema)ExecResult type definition for the return value of ssh_manager.exec(): stdout, stderr, exitCode, and duration.
export interface ExecResult { stdout: string; stderr: string; exitCode: number; duration: number; }