Skip to main content
Glama
ssh.mjs2.88 kB
// @ts-check import { config } from "@dotenvx/dotenvx"; import { NodeSSH } from "node-ssh"; import { parseArgsWithHelp } from "./utilities/parse_args_with_help.mjs"; import { printDuration } from "./utilities/performance_utils.mjs"; import { spawnPromise } from "./utilities/spawn_promise.mjs"; config({ override: true }); /** @description Opens a new intactive ssh session or execute a command remotely if arguments are specified. */ /** @example pnpm ssh ~ Initialize a new interactive ssh session based on the following environment variables: SSH_HOST, SSH_USERNAME, SSH_PASSWORD, SSH_PRIVATE_KEY, SSH_PRIVATE_KEY_PATH, SSH_PRIVATE_KEY_PASSWORD. */ /** @example pnpm ssh dokku ps:report syncado ~ Run a command remotely, in this case printing the status of the syncado dokku app. */ const { outputPrefix } = parseArgsWithHelp(import.meta.url); /** * * @param {string} cmd * @param {import('node-ssh').SSHExecCommandOptions & { outputPrefix: string; silent?: boolean; }} options */ async function sshCommand(cmd, options) { const startTime = performance.now(); await ssh.execCommand(cmd, { onStdout: (chunk) => !options?.silent && process.stdout.write(chunk.toString("utf8")), onStderr: (chunk) => process.stderr.write(chunk.toString("utf8")), ...options, }); console.log(`${outputPrefix}${cmd} (${printDuration(startTime)})`); } const ssh = new NodeSSH(); try { const command = process.argv.splice(2).join(" "); // If we have a command run it and then exit, otherwise spawn an interactive SSH session if (!command) { let preSsh = process.env.SSH_PASSWORD ? `sshpass -p ${process.env.SSH_PASSWORD} ` : ""; if (process.env.SSH_PRIVATE_KEY) { await spawnPromise( `echo ${process.env.SSH_PRIVATE_KEY} | ${preSsh}ssh -o IdentitiesOnly=yes -i /dev/stdin ${process.env.SSH_USERNAME}@${process.env.SSH_HOST}`, { forwardParams: false, outputPrefix, } ); } else if (process.env.SSH_PRIVATE_KEY_PATH) { await spawnPromise( `${preSsh}ssh -o IdentitiesOnly=yes -i ${process.env.SSH_PRIVATE_KEY_PATH} ${process.env.SSH_USERNAME}@${process.env.SSH_HOST}`, { forwardParams: false, outputPrefix, } ); } else { await spawnPromise( `${preSsh}ssh ${process.env.SSH_USERNAME}@${process.env.SSH_HOST}`, { forwardParams: false, outputPrefix, } ); } } else { await ssh.connect({ host: process.env.SSH_HOST, username: process.env.SSH_USERNAME, password: process.env.SSH_PASSWORD, privateKey: process.env.SSH_PRIVATE_KEY, privateKeyPath: process.env.SSH_PRIVATE_KEY_PATH, passphrase: process.env.SSH_PRIVATE_KEY_PASSWORD, }); await sshCommand(command, { outputPrefix, }); } } finally { ssh.dispose(); }

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/MCP-Manager/MCP-Checklists'

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