PlugWiki
SSH — policy-gated remote access logo

SSH MCP Server (tufantunc): Setup for Claude, Cursor and Other Apps

CommunityLocal
Getnpmssh-mcptufantunc/ssh-mcp

Lets your AI assistant run commands and move files on your Linux or Windows servers over SSH, under role and approval rules you set.

It runs on your computer and reaches your servers over SSH using your own keys or SSH agent. Nothing works until you write a config file that lists your hosts, roles and approval rules. Commands are classified and logged, but ordinary changes are not blocked by default, so treat it as real shell access.

Good for

  • Developers and admins who want Claude or Cursor to check logs and servers
  • Teams that need an audit log and approval step for every AI command
  • People who manage several hosts through a bastion

Works in

12 should work

Tap an app to see how to set it up and any known problems.

Install SSH — policy-gated remote access MCP

Claude Code

  1. 1

    Copy this prompt.

    Add the SSH — policy-gated remote access MCP server to Claude Code. Run this command:
    
    claude mcp add ssh-policy-gated-access -- npx -y ssh-mcp
    
    Then check that it loaded and tell me if I need to sign in or restart.
  2. 2

    Paste it into Claude Code. It shows the change and asks before running it.

Requires Node.js.

Read-only mode: Set `readOnly = true` on the profile in config.toml, or give it the viewer role.

Create the config file first, or every tool call is refused. On Linux it is ~/.config/ssh-mcp/config.toml, on macOS ~/Library/Application Support/ssh-mcp/config.toml, and on Windows %APPDATA%\ssh-mcp\config.toml; list each host as a [[profiles]] entry and run chmod 700 on the folder and chmod 600 on the file. For a quick test without a file you can pass --host, --user and --group=dev to the command. Set a password with SSH_MCP_PASSWORD, or use an SSH agent or key file instead.

Built from the package data we hold. Not yet tested by us.

Tools

  • Shows the servers you set up and which are connected

    Lists the SSH profiles from your config file and whether each one is connected. The assistant uses it to learn which hosts it may use.

    Try: “Which servers can you reach?”

    Read · list-connections

  • Runs a safe, read-only command on a server

    Runs one command from a fixed allowlist, such as ls, cat, grep, find or df. It cannot change the server, and it refuses commands with line breaks.

    Try: “Show the last 50 lines of /var/log/nginx/error.log on web-1.”

    Network · read-command

  • Runs any shell command on a server

    Runs one command on the remote host. Risky commands go through the approval step you set for that profile, but ordinary changes such as editing files or restarting services do not.

    Try: “Restart the app service on staging and tell me if it comes back up.”

    Delete · run-command

  • Runs a command with sudo

    Runs a command with sudo. It always goes through the approval step for the profile, and the sudo password is passed over stdin and not on the command line.

    Try: “Use sudo to install the security updates on build-box.”

    Delete · privileged-command

  • Lists files in a remote folder

    Lists a folder over SFTP. The number of entries and the size of the answer are capped.

    Try: “List the files in /var/www/releases on web-1.”

    Network · sftp-list

  • Reads a remote file into the chat

    Downloads one file over SFTP and hands its contents to the assistant.

    Try: “Fetch /etc/nginx/nginx.conf and explain the proxy rules.”

    Network · sftp-download

  • Writes text to a file on a server

    Uploads content to a path over SFTP. It overwrites an existing file with no warning and has no option to refuse that.

    Try: “Upload this config to /etc/myapp/config.yml on staging.”

    Write · sftp-upload

  • Sends a local file to a server

    Streams a file from your computer to the server without passing it through the model. It only works inside the transfer folder you set in config, and refuses if none is set.

    Try: “Upload build.tar.gz from my transfer folder to /opt/releases on web-1.”

    Write · sftp-upload-file

  • Saves a remote file to your computer

    Streams a file from the server to your disk without passing it through the model. It only writes inside the transfer folder you set in config, and refuses if none is set.

    Try: “Download the 2 GB database dump from backup-1 to my transfer folder.”

    Write · sftp-download-file

  • Starts a named shell or background job

    Opens a named session on a host. An interactive one keeps its folder and variables between commands, and a background one runs a long job such as a log tail.

    Try: “Open a background session that follows /var/log/syslog on web-1.”

    Runs code · open-session

  • Lists open sessions on a server

    Shows the sessions that are currently open for one host.

    Try: “What sessions are open on web-1?”

    Read · list-sessions

  • Reads output from a background job

    Returns the most recent lines from a background session, for example a log you are following.

    Try: “Show the latest 20 lines from the logs session.”

    Read · read-session-output

Read from the source code

Permissions

high risk · 5 things to watch · 14 advisories

High risk

The assistant can run arbitrary commands, including sudo, and upload or delete files on any host in your config. Use a low-privilege account, set readOnly = true on profiles you only monitor, and use ask-all approval on production.

What it can do

Watch out for

  • It runs arbitrary commands on your servers

    run-command and privileged-command can change or delete anything the SSH user can. Use a dedicated low-privilege account and a restrictive role. github.com

  • The default approval step is narrow

    The default ask-destructive mode prompts only for patterns such as rm -rf, interpreter one-liners, uploads and sudo. Ordinary writes, service control and signals run without a prompt, so use ask-all on production. github.com

  • sftp-upload overwrites files without warning

    It replaces an existing file at the path and has no overwrite flag. Use profiles without write roles on hosts where that matters. github.com

  • It tells your hosts an AI agent connected

    Each command sends AI_AGENT=ssh-mcp to the host by default. Clear announceAgent on a profile for a host you do not control. github.com

  • The HTTP mode needs a bearer token

    If you start it with --transport=http it requires --bearerToken and listens on 127.0.0.1 by default. Put TLS in front of it before exposing it. github.com

Security advisories

14 known advisories, all fixed in a newer version.

Show all 14
Technical details
Turning on read-onlySet readOnly = true on a profile in config.toml, or give the profile the viewer role.
Talks toThe SSH hosts in your config. Optional HTTP listener, 127.0.0.1:3000 by default
Sign-in and keysPasswords come from SSH_MCP_PASSWORD (or a per-profile SSH_MCP_<PROFILE>_PASSWORD) and key paths from SSH_MCP_KEY. It also supports an SSH agent and the OS keychain. Passwords are never taken as command-line arguments.
Scopes
  • Whatever the SSH user on each host can do, limited by the profile role (viewer, operator or admin)

Questions

Is the ssh-mcp server by tufantunc official?

No. It is a community project by tufantunc. It is not made by OpenSSH or any SSH vendor.

Why does every tool say it is refused after I install it?

You have not made the config file yet. Without it the server starts but refuses every tool call until config.toml exists in the path for your system. The README gives the path for Linux, macOS and Windows.

Do I need an API key?

No. It logs into your servers with your SSH key, an SSH agent, the OS keychain or a password. Set SSH_MCP_PASSWORD for password logins or SSH_MCP_KEY for a key file path, and SSH_MCP_PASSPHRASE for an encrypted key.

Can it run read-only?

Yes. Set readOnly = true on a profile or give it the viewer role. Then the assistant can only use read-only commands and listings on that host.

Can it use sudo?

Yes, through the privileged-command tool, if the role and policy allow it. It needs SSH_MCP_SUDO_PASSWORD unless sudo needs no password. By default the admin role is refused sudo on hosts treated as production.

Does it run locally or send data to a third party?

It runs on your computer and connects straight to your hosts. It has an optional HTTP mode if you start it with --transport=http, which needs a bearer token.

Which apps does it work with?

Claude Code, Claude Desktop, Cursor and Windsurf are named in the README. Use the install box for the exact steps, and create the config file first.

Information

updated Nov 2, 2026

Publisher
Community
Package
ssh-mcp
Registry
npm
Transport
stdio, Streamable HTTP
Auth
token in env
Version
2.22.0
License
MIT
Last commit
Oct 26, 2026
Open issues
1
Listed in
Official MCP registry

GitHubnpmOfficial MCP RegistryChangelogIssues

Sources

Docs, issue trackers and discussions this page is built from. Issues, quotes and findings above link to their own source.

Show all 2
  1. ssh-mcp README (v2.22.1) · github.com
  2. ssh-mcp tool descriptions (v2.22.1) · github.com

Facts from the official MCP registry, GitHub, npm, PyPI and the Docker catalog. Updated Nov 2, 2026.