Skip to main content
Glama

SSH MCP Server

index.js4.13 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js"; import { Client } from "ssh2"; const server = new Server( { name: "mcp-ssh-server", version: "1.0.0" }, { capabilities: { tools: {}, notifications: {} } } ); let sshClient = null; let sshConfig = null; server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: "ssh_connect", description: "Connect to SSH server", inputSchema: { type: "object", properties: { host: { type: "string", description: "SSH server address" }, port: { type: "number", description: "SSH port (default: 22)", default: 22 }, username: { type: "string", description: "Username" }, password: { type: "string", description: "Password" } }, required: ["host", "username", "password"] } }, { name: "ssh_exec", description: "Execute command over SSH", inputSchema: { type: "object", properties: { command: { type: "string", description: "Command to execute" } }, required: ["command"] } }, { name: "ssh_disconnect", description: "Close SSH connection", inputSchema: { type: "object", properties: {} } } ] })); server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; if (name === "ssh_connect") { return new Promise((resolve) => { sshClient = new Client(); sshConfig = { host: args.host, port: args.port || 22, username: args.username, password: args.password }; sshClient.on("ready", () => { resolve({ content: [{ type: "text", text: `Connection successful: ${args.username}@${args.host}` }] }); }).on("error", (err) => { resolve({ content: [{ type: "text", text: `Connection error: ${err.message}` }], isError: true }); }).connect(sshConfig); }); } if (name === "ssh_exec") { if (!sshClient) { return { content: [{ type: "text", text: "Please connect first using ssh_connect" }], isError: true }; } return new Promise((resolve) => { sshClient.exec(args.command, (err, stream) => { if (err) { return resolve({ content: [{ type: "text", text: `Command error: ${err.message}` }], isError: true }); } let output = ""; let buffer = ""; const sendProgress = (chunk) => { buffer += chunk; if (buffer.includes("\n") || buffer.length > 100) { server.notification({ method: "notifications/progress", params: { progressToken: request.params._meta?.progressToken, progress: buffer } }); buffer = ""; } }; stream.on("data", (data) => { const chunk = data.toString(); output += chunk; sendProgress(chunk); }); stream.stderr.on("data", (data) => { const chunk = data.toString(); output += chunk; sendProgress(chunk); }); stream.on("close", () => { if (buffer) sendProgress(buffer); resolve({ content: [{ type: "text", text: output || "Command completed" }] }); }); }); }); } if (name === "ssh_disconnect") { if (sshClient) { sshClient.end(); sshClient = null; } return { content: [{ type: "text", text: "Connection closed" }] }; } return { content: [{ type: "text", text: "Unknown tool" }], isError: true }; }); async function main() { const transport = new StdioServerTransport(); await server.connect(transport); } main();

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

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