SSH — Claude Code MCP server: policy-gated remote access
Hands your agent SSH on remote hosts, with every call classified, checked against a role and written to an audit log.
claude mcp add --env SSH_MCP_PASSWORD=<SSH_MCP_PASSWORD> --env SSH_MCP_KEY=<SSH_MCP_KEY> --env SSH_MCP_PASSPHRASE=<SSH_MCP_PASSPHRASE> --env SSH_MCP_SUDO_PASSWORD=<SSH_MCP_SUDO_PASSWORD> --transport stdio ssh-policy-gated-remote-access -- npx -y ssh-mcpWhat SSH — policy-gated remote access does
The server sits between the agent and the remote machine. A command is classified first, then matched against a role × host-group matrix, and anything destructive waits for a human to approve it. Either decision lands in the log.
Start it without a config and it still comes up, but every tool call is refused. The config lives at ~/.config/ssh-mcp/config.toml on Linux, ~/Library/Application Support/ssh-mcp/config.toml on macOS, %APPDATA%\ssh-mcp\config.toml on Windows. Profiles inside it carry the host, port, user, auth method, role and approval policy.
On Linux and macOS the server inspects permissions on the file and its directory, and won't start if anyone besides the owner can reach them — hence chmod 700 on the directory and chmod 600 on the file. Windows has no mode bits, so the ACL is checked instead: an account that can rewrite the config is an authorization bypass, and the server refuses. Read-only exposure gets reported rather than blocked. Two flags shift that line, --strictConfigAcl and --allowUncheckedConfigAcl. Keep passwords out of command-line arguments, where ps aux exposes them, and use environment variables or an SSH agent.
What it helps with
- run a command on a remote host without handing the agent a full shell
- hold destructive operations until a person approves them
- separate permissions by role and host group
- keep a record of what the agent tried to do on a server
- connect over a key or through an SSH agent
Example prompts for the agent
- Open a session on the host in the
devprofile and list the files under/var/log. - Run
systemctl status nginxon the production host, and ask me first if it counts as destructive. - Close every active session and show me what went into the audit log in the last hour.
How to install SSH — policy-gated remote access
Platform CLI
claude mcp add --env SSH_MCP_PASSWORD=<SSH_MCP_PASSWORD> --env SSH_MCP_KEY=<SSH_MCP_KEY> --env SSH_MCP_PASSPHRASE=<SSH_MCP_PASSPHRASE> --env SSH_MCP_SUDO_PASSWORD=<SSH_MCP_SUDO_PASSWORD> --transport stdio ssh-policy-gated-remote-access -- npx -y ssh-mcpReplace <…> with your own values
Platform CLI
codex mcp add ssh-policy-gated-remote-access --env SSH_MCP_PASSWORD=<SSH_MCP_PASSWORD> --env SSH_MCP_KEY=<SSH_MCP_KEY> --env SSH_MCP_PASSPHRASE=<SSH_MCP_PASSPHRASE> --env SSH_MCP_SUDO_PASSWORD=<SSH_MCP_SUDO_PASSWORD> -- npx -y ssh-mcpReplace <…> with your own values
Config file
{
"mcpServers": {
"ssh-policy-gated-remote-access": {
"command": "npx",
"args": [
"-y",
"ssh-mcp"
],
"env": {
"SSH_MCP_PASSWORD": "<SSH_MCP_PASSWORD>",
"SSH_MCP_KEY": "<SSH_MCP_KEY>",
"SSH_MCP_PASSPHRASE": "<SSH_MCP_PASSPHRASE>",
"SSH_MCP_SUDO_PASSWORD": "<SSH_MCP_SUDO_PASSWORD>"
}
}
}
}Replace <…> with your own values
Config file
{
"servers": {
"ssh-policy-gated-remote-access": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"ssh-mcp"
],
"env": {
"SSH_MCP_PASSWORD": "<SSH_MCP_PASSWORD>",
"SSH_MCP_KEY": "<SSH_MCP_KEY>",
"SSH_MCP_PASSPHRASE": "<SSH_MCP_PASSPHRASE>",
"SSH_MCP_SUDO_PASSWORD": "<SSH_MCP_SUDO_PASSWORD>"
}
}
}
}Replace <…> with your own values
Platform CLI
gemini mcp add -e SSH_MCP_PASSWORD=<SSH_MCP_PASSWORD> -e SSH_MCP_KEY=<SSH_MCP_KEY> -e SSH_MCP_PASSPHRASE=<SSH_MCP_PASSPHRASE> -e SSH_MCP_SUDO_PASSWORD=<SSH_MCP_SUDO_PASSWORD> ssh-policy-gated-remote-access npx -y ssh-mcpReplace <…> with your own values
Step by step, with commands for each platform: How to add an MCP server to Claude Code, Codex, Cursor, VS Code, Gemini CLI and more
Questions about SSH — policy-gated remote access
How do I install SSH — policy-gated remote access in Claude Code?
Run npm install -g ssh-mcp, then register the server: `claude mcp add ssh-mcp -e SSH_MCP_PASSWORD=<SSH_MCP_PASSWORD> -e SSH_MCP_PASSPHRASE=<SSH_MCP_PASSPHRASE> -e SSH_MCP_SUDO_PASSWORD=<SSH_MCP_SUDO_PASSWORD> -- npx -y ssh-mcp`. Create the config file afterwards and fix its permissions.
What does this MCP server do?
It gives an agent SSH access to remote hosts while checking commands against policy. Destructive work needs approval, and each decision is logged.
What has to be set up before the first run?
A config.toml with host profiles, roles and an approval mode. Without it the server starts but refuses every tool call.