SSH MCP Server is a lightweight Model Context Protocol (MCP) server that exposes SSH command execution for Linux and Windows targets. It lets MCP‑compatible clients (Claude Desktop, Cursor, MCP Inspector, etc.) run shell commands over SSH in a controlled, timeout‑aware way.
Licensed under the MIT License. See LICENSE.
- Quick Start
- Features
- Installation
- Usage
- Client Setup
- Testing
- Security Notes
- Disclaimer
- Support
- Forking
- Install (or clone & build) this package
- Run the server (pick a transport:
streamorsse) - Point your MCP client at it
- Use the
exectool to run commands on the target host
- MCP-compliant server exposing SSH command execution
- Linux + Windows remote hosts supported (shell semantics may differ)
- Password or private key authentication
- TypeScript, minimal deps, official MCP SDK
- SSE (legacy) and HTTP Stream (modern, default) transports
- Execution timeout with best‑effort termination of the remote process
- Optional local fallback exec (set
MCP_LOCAL_EXEC=1) for debugging
exec: Execute a shell command on the remote server- Parameters:
command(required): Shell command to execute on the remote SSH server
- Timeout Configuration:
- Timeout is configured via command line argument
--timeout(in milliseconds) - Default timeout: 60000ms (1 minute)
- When a command times out, the server automatically attempts to abort the running process before closing the connection
- Timeout is configured via command line argument
- Parameters:
npm install -g ssh-mcpThen run with:
ssh-mcp --host=1.2.3.4 --user=myuser --password=secret --transport=streamgit clone https://github.com/tufantunc/ssh-mcp.git
cd ssh-mcp
npm install
npm run build
node build/index.js --host=1.2.3.4 --user=myuser --transport=streamMinimal example (HTTP Stream transport):
ssh-mcp --host=1.2.3.4 --user=myuser --password=secret --transport=stream --timeout=30000SSE (legacy) transport:
ssh-mcp --host=1.2.3.4 --user=myuser --password=secret --transport=sseUsing an SSH key:
ssh-mcp --host=host.example --user=deploy --key=C:\\keys\\id_ed25519Environment (optional):
set LOG_LEVEL=debug # increase logging
set MCP_LOCAL_EXEC=1 # run commands locally (no SSH) for quick test
set MCP_AUTH_TOKEN=token123 # require Bearer token on requestsBatch launchers (Windows) included:
StartHTTPMCP.bat– HTTP Stream (default)StartSSEMCP.bat– SSEStartDocker-SSH.bat– Sample .bat that spins up a local Ubuntu SSH test container on port 2222 using Docker (Used the Docker image from the Claude samples).
Run with verbose to enable extra logging, e.g.:
StartHTTPMCP.bat verboseYou can configure Claude Desktop to use this MCP Server.
| Transport | Flag | Endpoint(s) | Notes |
|---|---|---|---|
| HTTP Stream (default) | --transport=stream |
/mcp |
Single endpoint; SSE replacement |
| SSE (legacy) | --transport=sse |
/sse + /messages |
Retained for broad client compatibility |
Required:
--hosttarget host/IP--userSSH username
Common optional:
--sshPort=<n>(default 22)--listenPort=<n>(HTTP listen port, default 3001)--listenHost=<host>bind address (default 127.0.0.1)--password=<pwd>password auth--key=<path>private key (overrides password if both given)--timeout=<ms>command timeout (default 60000)--transport=stream|sse
Claude Desktop now supports Custom Connectors for HTTP-based MCP servers. See the Custom Connectors guide for setup instructions.
-
Start your SSH MCP server locally:
ssh-mcp --host=your-server.com --user=myuser --password=secret --transport=sse
-
In Claude Desktop, add a Custom Connector:
- Name: SSH MCP Server
- URL:
http://localhost:3001/sse(SSE transport) - Type: Server-Sent Events
Or for HTTP Stream transport:
- URL:
http://localhost:3001/mcp - Type: HTTP Stream
GitHub Copilot supports MCP through the mcp.json configuration file. Create or edit your mcp.json file:
Location: %APPDATA%\Code\User\mcp.json (Windows) or ~/.config/Code/User/mcp.json (Linux/Mac)
Start your server and GitHub Copilot will automatically connect:
ssh-mcp --host=your-server.com --user=myuser --password=secret --transport=sseNote: Use SSE transport (/sse endpoint) for maximum compatibility with both Claude and GitHub Copilot.
node build/index.js --transport=stream --listenPort=3001 --host=1.2.3.4 --sshPort=22 --user=root --password=pass --timeout=30000Inspector:
npm run build
npx @modelcontextprotocol/inspector http://127.0.0.1:3001/mcpLocal SSH test container (Windows, Docker required):
StartDocker-SSH.bat
StartHTTPMCP.bat -- then connect with --host=127.0.0.1 --sshPort=2222 --user=computeruse --password=computeruseDocker Setup: This project has been tested with the Ubuntu Docker image from Anthropic's computer-use-demo reference implementation, which provides a fully configured environment Ubuntu Linux environment. You can achieve same functionality with Computer Use, but it very slow and costly.
Switch to SSE for clients that require it:
ssh-mcp --transport=sse --host=127.0.0.1 --user=me --password=secretLocal command mode (no SSH network hop):
set MCP_LOCAL_EXEC=1
ssh-mcp --host=localhost --user=ignored --transport=streamProduction considerations:
- Prefer key auth over passwords
- Run behind a firewall / localhost + SSH tunnel
- Set
MCP_AUTH_TOKENto require a bearer token - Restrict origins with
ALLOWED_ORIGINSenv - Use network segmentation for sensitive hosts
- Review (and possibly wrap) the
exectool if you need command allow‑listing
SSH MCP Server is provided under the MIT License. Use at your own risk. This project is not affiliated with or endorsed by any SSH or MCP provider.
We welcome contributions! Please see our Contributing Guidelines for more information.
This project follows a Code of Conduct to ensure a welcoming environment for everyone.
If this project helps you, a star ⭐ or feedback issue is appreciated. Pull requests welcome.
See also:
If you maintain a fork, please:
- Add lineage details in
CHANGELOG.mdunder[Unreleased] > Fork Lineage. - Keep
FORKING.mdupdated with your policies. - Use distinct version tags (e.g.
v1.1.0-fork.1). - Change the npm package name if you republish.
See FORKING.md for full instructions.
\n+### Releases & Publishing
\n+Automated npm publishing is configured via .github/workflows/release.yml and triggers on tags named v* (e.g. v1.1.1).\n+\n+Workflow summary:\n+1. Update CHANGELOG.md under [Unreleased] and move entries to a new version heading.\n+2. Commit changes.\n+3. Bump version & create tag (pick one):\n+ bash\n+ npm run release:patch # or release:minor / release:major\n+ \n+ These scripts: update version, commit, tag.\n+4. Push commits & tags:\n+ bash\n+ git push && git push --tags\n+ \n+5. GitHub Action builds and publishes (requires NPM_TOKEN secret).\n+\n+Manual alternative:\n+bash\n+npm version patch -m "chore: release %s"\n+git push && git push --tags\n+\n+\n+Repository secret required:\n+* NPM_TOKEN – npm auth token with publish rights. Add via GitHub Settings → Secrets → Actions.\n+\n+If forking & publishing under a different name, change the name field in package.json before the first publish.\n*** End Patch
{ "servers": { "ssh-mcp": { "url": "http://localhost:3001/sse", "type": "http" } }, "inputs": [] }