Skip to main content
Glama

IT Tools MCP Server

index.ts•3.16 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { z } from "zod"; import { Client as SSHClient } from "ssh2"; import fs from "fs"; import path from "path"; import os from "os"; function resolvePrivateKey(privateKeyArg?: string): string | undefined { // If not provided, try default keys if (!privateKeyArg) { const home = os.homedir(); const defaultKeys = [ path.join(home, '.ssh', 'id_rsa'), path.join(home, '.ssh', 'id_ed25519'), ]; for (const keyPath of defaultKeys) { if (fs.existsSync(keyPath)) { return fs.readFileSync(keyPath, 'utf8'); } } return undefined; } // If it looks like a path, try to read it if ( privateKeyArg.startsWith('/') || privateKeyArg.startsWith('~') || privateKeyArg.endsWith('.pem') || privateKeyArg.endsWith('.key') ) { let keyPath = privateKeyArg; if (keyPath.startsWith('~')) { keyPath = path.join(os.homedir(), keyPath.slice(1)); } if (fs.existsSync(keyPath)) { return fs.readFileSync(keyPath, 'utf8'); } else { throw new Error('Private key file not found: ' + keyPath); } } // Otherwise, assume it's the key content return privateKeyArg; } export function registerSsh(server: McpServer) { server.registerTool("ssh", { description: "Connect to a target via SSH", inputSchema: { target: z.string().describe("Target host"), user: z.string().describe("Username"), command: z.string().describe("Command to run on remote host"), privateKey: z.string().optional().describe("Private key for authentication (PEM format, optional, or path to key file)") }, // VS Code compliance annotations annotations: { title: "Ssh", description: "Connect to a target via SSH", readOnlyHint: false } }, async ({ target, user, command, privateKey }) => { return new Promise((resolve) => { let resolvedKey: string | undefined; try { resolvedKey = resolvePrivateKey(privateKey); } catch (err: any) { resolve({ content: [{ type: "text", text: `SSH key error: ${err.message}` }] }); return; } const conn = new SSHClient(); let output = ""; conn.on("ready", () => { conn.exec(command, (err, stream) => { if (err) { resolve({ content: [{ type: "text", text: `SSH error: ${err.message}` }] }); conn.end(); return; } stream.on("close", () => { conn.end(); resolve({ content: [{ type: "text", text: output }] }); }).on("data", (data: Buffer) => { output += data.toString(); }).stderr.on("data", (data: Buffer) => { output += data.toString(); }); }); }).on("error", (err) => { resolve({ content: [{ type: "text", text: `SSH connection error: ${err.message}` }] }); }).connect({ host: target, username: user, ...(resolvedKey ? { privateKey: resolvedKey } : {}) }); }); } ); }

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/wrenchpilot/it-tools-mcp'

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