ubuntu_update_packages
Update Ubuntu system packages via SSH connection, with options for security-only updates, package upgrades, and cleanup of unused dependencies.
Instructions
Update system packages on Ubuntu
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| connectionId | Yes | ID of an active SSH connection | |
| securityOnly | No | Whether to update only security packages (default: false) | |
| upgrade | No | Whether to upgrade packages after update (default: true) | |
| autoremove | No | Whether to remove unused packages after update (default: false) | |
| sudo | No | Whether to run the command with sudo (default: true) |
Implementation Reference
- src/ubuntu-website-tools.ts:132-182 (handler)The main execution handler for the 'ubuntu_update_packages' tool. It connects to the SSH server, builds and executes apt update/upgrade commands based on parameters like securityOnly, upgrade, autoremove, and sudo.async ubuntu_update_packages(params) { const { connectionId, securityOnly = false, upgrade = true, autoremove = false, sudo = true } = params; try { const conn = getConnection(connectionMap, connectionId); const sudoPrefix = sudo ? 'sudo ' : ''; // Build the update command let commands = []; // Always update package lists first if (securityOnly) { commands.push(`${sudoPrefix}apt-get update -o Dir::Etc::SourceList=/etc/apt/security.sources.list`); } else { commands.push(`${sudoPrefix}apt-get update`); } // Upgrade if requested if (upgrade) { if (securityOnly) { commands.push(`${sudoPrefix}apt-get upgrade -s | grep "^Inst" | grep -i security | awk '{print $2}' | xargs ${sudoPrefix}apt-get install -y`); } else { commands.push(`${sudoPrefix}apt-get upgrade -y`); } } // Auto-remove if requested if (autoremove) { commands.push(`${sudoPrefix}apt-get autoremove -y`); } // Execute all commands in sequence and collect results let output = ''; for (const cmd of commands) { const result = await executeSSHCommand(conn, cmd, 300000); // 5-minute timeout for upgrades output += `Command: ${cmd}\nExit code: ${result.code}\nOutput:\n${result.stdout || result.stderr}\n\n`; } return { content: [{ type: 'text', text: `Package update completed.\n\n${output}` }] }; } catch (error: any) { return { content: [{ type: 'text', text: `Package update error: ${error.message}` }], isError: true }; } },
- src/ubuntu-website-tools.ts:538-566 (schema)The input schema and description for the 'ubuntu_update_packages' tool, defining parameters and validation.ubuntu_update_packages: { description: 'Update system packages on Ubuntu', inputSchema: { type: 'object', properties: { connectionId: { type: 'string', description: 'ID of an active SSH connection' }, securityOnly: { type: 'boolean', description: 'Whether to update only security packages (default: false)' }, upgrade: { type: 'boolean', description: 'Whether to upgrade packages after update (default: true)' }, autoremove: { type: 'boolean', description: 'Whether to remove unused packages after update (default: false)' }, sudo: { type: 'boolean', description: 'Whether to run the command with sudo (default: true)' } }, required: ['connectionId'] } },
- src/index.ts:293-296 (registration)Registration/dispatch logic in the main CallToolRequestSchema handler that routes 'ubuntu_update_packages' calls to the specific ubuntuToolHandlers function.// Handle Ubuntu tools directly if (toolName.startsWith('ubuntu_') && ubuntuToolHandlers[toolName]) { return ubuntuToolHandlers[toolName](request.params.arguments); }
- src/index.ts:179-179 (registration)Call to addUbuntuTools which initializes Ubuntu tools including overriding ListTools to expose 'ubuntu_update_packages' schema.addUbuntuTools(this.server, this.connections);
- src/ubuntu-website-tools.ts:18-58 (helper)Shared utility function executeSSHCommand used by the ubuntu_update_packages handler to run APT commands over SSH.async function executeSSHCommand(conn: Client, command: string, timeout = 60000): Promise<{ code: number; signal: string; stdout: string; stderr: string; }> { return new Promise((resolve, reject) => { // Set up timeout const timeoutId = setTimeout(() => { reject(new Error(`Command execution timed out after ${timeout}ms`)); }, timeout); conn.exec(command, {}, (err: Error | undefined, stream: any) => { if (err) { clearTimeout(timeoutId); return reject(new Error(`Failed to execute command: ${err.message}`)); } let stdout = ''; let stderr = ''; stream.on('close', (code: number, signal: string) => { clearTimeout(timeoutId); resolve({ code, signal, stdout: stdout.trim(), stderr: stderr.trim() }); }); stream.on('data', (data: Buffer) => { stdout += data.toString(); }); stream.stderr.on('data', (data: Buffer) => { stderr += data.toString(); }); }); }); }