Skip to main content
Glama

ssh_tool

Execute commands on SSH servers by specifying server names and commands to run remotely.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
serverNameYesSSH server name
commandYesCommand to execute

Implementation Reference

  • The default exported async function that serves as the main handler for the ssh_tool. It processes the request, validates parameters, establishes SSH connection, executes the command, and returns the result or error in the expected format.
    export default async (request: any) => { try { // 解析请求参数 const { serverName, command } = request.params.arguments; // 验证参数 if (!serverName || !command) { throw new Error("Missing required parameters: serverName, command"); } // 获取SSH连接 const conn = await getSSHConnection(serverName); // 执行命令 const result = await executeCommand(conn, command); // 返回成功结果 return { content: [ { type: "text", text: JSON.stringify({ server: serverName, command: command, ...result }, null, 2) } ] }; } catch (error) { // 返回错误结果 return { content: [ { type: "text", text: JSON.stringify({ error: error instanceof Error ? error.message : String(error) }, null, 2) } ], isError: true }; } };
  • The input schema definition for the ssh_tool, specifying parameters serverName and command as required.
    export const schema = { name: "ssh_tool", description: "Connect to SSH server and execute commands", type: "object", properties: { serverName: { type: "string", description: "SSH server name", }, command: { type: "string", description: "Command to execute", }, }, required: ["serverName", "command"] };
  • Dynamic registration of tools (including ssh_tool) in the loadTools function by scanning src/tools directory, importing modules, extracting schema, handler (default export), and destroy function, then storing in global tools and handlers maps.
    // 获取所有工具文件 const toolFiles = fs.readdirSync(toolsDir).filter(file => file.endsWith('.js') || file.endsWith('.ts')); // 加载每个工具 for (const file of toolFiles) { const toolPath = path.join(toolsDir, file); try { // 如果是重新加载,清除模块缓存 if (reload) clearModuleCache(toolPath); // 导入模块,重新加载时添加时间戳防止缓存 const importPath = 'file://' + toolPath + (reload ? `?update=${Date.now()}` : ''); const { default: tool, schema, destroy } = await import(importPath); const toolName = path.parse(toolPath).name; // 注册工具 tools.push({ name: toolName, description: tool.description, inputSchema: schema, destroy: destroy }); // 注册处理函数 handlers[toolName] = async (request: ToolRequest) => { return await tool(request); }; } catch (error) { console.error(`Failed to ${reload ? 'reload' : 'load'} tool ${file}:`, error); } } isLoaded = true; if (reload) console.log(`Successfully reloaded ${tools.length} tools`); return handlers; }
  • Helper function to retrieve or establish a new SSH connection using environment variables like SSH_{serverName}_URI.
    async function getSSHConnection(serverName: string): Promise<Client> { // 如果已有连接,直接返回 if (sshConnections[serverName]) { return sshConnections[serverName]; } // 从环境变量获取连接信息 const sshUri = process.env[`SSH_${serverName}_URI`]; if (!sshUri) { throw new Error(`SSH_${serverName}_URI environment variable must be set.`); } // 解析连接信息 const [usernameAndpassword, HostAndport] = sshUri.split('@'); const [username, password] = usernameAndpassword.split(':'); const [host, port] = HostAndport.split(':'); // 创建新连接 return new Promise((resolve, reject) => { const conn = new Client(); conn.on('ready', () => { sshConnections[serverName] = conn; resolve(conn); }); conn.on('error', (err) => { delete sshConnections[serverName]; reject(new Error(`SSH connection error: ${err.message}`)); }); conn.on('end', () => { delete sshConnections[serverName]; }); conn.connect({ host: host, port: parseInt(port), username: username, password: password }); }); }
  • Helper function to execute a command over an established SSH connection and capture stdout, stderr, exit code, and signal.
    /** * 在SSH服务器上执行命令 * @param conn SSH连接 * @param command 要执行的命令 * @returns 命令执行结果 */ async function executeCommand(conn: Client, command: string): Promise<{ stdout: string, stderr: string, code: number | null, signal: any }> { return new Promise((resolve, reject) => { conn.exec(command, (err, stream) => { if (err) { reject(new Error(`Command execution failed: ${err.message}`)); return; } let stdout = ''; let stderr = ''; stream.on('close', (code, signal) => { resolve({ stdout, stderr, code, signal }); }); stream.on('data', (data) => { stdout += data.toString(); }); stream.stderr.on('data', (data) => { stderr += data.toString(); }); stream.on('error', (err) => { reject(new Error(`Stream error: ${err.message}`)); }); }); }); }

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/xiaoguomeiyitian/ToolBox'

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