Skip to main content
Glama
lgariv
by lgariv

ssh_run

Execute remote commands on servers via SSH to run non-interactive tasks and retrieve execution results including output, errors, and status codes.

Instructions

Runs a non-interactive command remotely over SSH and returns stdout, stderr, and exit code

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
commandYesCommand to run remotely

Implementation Reference

  • The main handler function for the 'ssh_run' tool. It establishes an SSH connection, executes the provided command using runRemoteCommand, formats the output as JSON, and handles errors.
    async ({ command }) => {
      try {
        const ssh = await createSshConnection();
        try {
          const result = await runRemoteCommand(ssh, command);
          ssh.end();
          const text = JSON.stringify(
            { command, ...result, stdout: result.stdout.trim(), stderr: result.stderr.trim() },
            null,
            2
          );
          return { content: [{ type: "text", text }] };
        } finally {
          ssh.end();
        }
      } catch (error) {
        const message = error instanceof Error ? error.message : String(error);
        return { content: [{ type: "text", text: `SSH command failed: ${message}` }], isError: true };
      }
    }
  • Input schema for the 'ssh_run' tool defining the 'command' parameter using Zod.
    inputSchema: { command: z.string().min(1).describe("Command to run remotely") },
  • src/index.ts:111-138 (registration)
    Registration of the 'ssh_run' tool on the McpServer instance, including schema and handler.
    server.registerTool(
      "ssh_run",
      {
        title: "Run Remote Command",
        description: "Runs a non-interactive command remotely over SSH and returns stdout, stderr, and exit code",
        inputSchema: { command: z.string().min(1).describe("Command to run remotely") },
      },
      async ({ command }) => {
        try {
          const ssh = await createSshConnection();
          try {
            const result = await runRemoteCommand(ssh, command);
            ssh.end();
            const text = JSON.stringify(
              { command, ...result, stdout: result.stdout.trim(), stderr: result.stderr.trim() },
              null,
              2
            );
            return { content: [{ type: "text", text }] };
          } finally {
            ssh.end();
          }
        } catch (error) {
          const message = error instanceof Error ? error.message : String(error);
          return { content: [{ type: "text", text: `SSH command failed: ${message}` }], isError: true };
        }
      }
    );
  • Helper function to execute a command over an established SSH connection and capture stdout, stderr, and exit code.
    async function runRemoteCommand(ssh: SSHClient, command: string): Promise<{ exitCode: number; stdout: string; stderr: string }>{
      return await new Promise((resolve, reject) => {
        ssh.exec(command, (err: Error | undefined, stream: ClientChannel) => {
          if (err) return reject(err);
          let stdout = "";
          let stderr = "";
          stream
            .on("close", (code: number) => {
              resolve({ exitCode: code ?? 0, stdout, stderr });
            })
            .on("data", (data: Buffer) => {
              stdout += data.toString();
            })
            .stderr.on("data", (data: Buffer) => {
              stderr += data.toString();
            });
        });
      });
    }
  • Helper function to create and connect an SSH client using environment variables.
    async function createSshConnection(): Promise<SSHClient> {
      const env = getEnv();
      const ssh = new SSHClient();
      const config: ConnectConfig = {
        host: env.SSH_HOST,
        port: Number(env.SSH_PORT),
        username: env.SSH_USERNAME,
        password: env.SSH_PASSWORD,
        readyTimeout: 15000,
        tryKeyboard: false,
        algorithms: {
          // Keep defaults; allow host key algo negotiation modern-first
        },
      };
      await new Promise<void>((resolve, reject) => {
        ssh
          .on("ready", () => resolve())
          .on("error", (err: Error) => reject(err))
          .connect(config);
      });
      return ssh;
    }
Install Server

Other 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/lgariv/ssh-mcp'

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