使用说明
SSH MCP Server
English | 简体中文
A stdio MCP server for AI clients that need SSH command execution, file transfer, interactive terminals, and serial consoles. Connection profiles and execution history are shared by MCP instances on the same machine. After a profile is registered, models operate through a stable connection ID instead of receiving saved targets, usernames, or authentication details again.
Highlights
- SSH command execution, SFTP transfer, and directory management.
- SSH shell/TUI and serial terminals with controlled read/write turns, stream offsets, and explicit completion states.
- SQLite-backed connection profiles and execution history that survive restarts and are shared across local MCP instances.
- A fixed, model-oriented surface of eleven everyday tools.
- Strict stdio boundaries: MCP data uses stdout only; logs use stderr only.
Install
Recommended: use a prebuilt archive from GitHub Releases. Download the archive for your platform, extract it, and place sshmcp (sshmcp.exe on Windows) in a stable directory. Every archive contains the example configuration, both READMEs, and the license.
Building from source requires Go 1.24.4 or newer:
git clone https://github.com/Cigarliu/ssh-mcp-server.git
cd ssh-mcp-server
go build -o sshmcp ./cmd/server
On first start, the server writes a default configuration when none exists:
- Windows:
%USERPROFILE%\.sshmcp\config.yaml - macOS/Linux:
~/.sshmcp/config.yaml
Pass -config <path> to use a different file.
MCP Client Configuration
Register the binary as a stdio MCP server. For example, on Windows:
{
"mcpServers": {
"ssh-mcp": {
"command": "C:\\Tools\\sshmcp\\sshmcp.exe",
"args": ["-config", "C:\\Users\\you\\.sshmcp\\config.yaml"]
}
}
}
On macOS or Linux, use the corresponding absolute paths. Do not make a stdio MCP server request a sudo password at startup: it consumes stdin and breaks the MCP handshake.
Connections and History
For a first direct SSH connection, the model should create a short, stable, readable connection_id and a user-facing description:
{
"transport": "ssh",
"connection_id": "prod-web-hk",
"description": "Hong Kong production web server for deployments and log triage",
"host": "203.0.113.10",
"username": "deploy",
"private_key": "~/.ssh/id_ed25519"
}
After a successful connection, later conversations and MCP instances need only:
{ "transport": "ssh", "connection_id": "prod-web-hk" }
connection_list returns only IDs, descriptions, active state, and locally visible serial ports. It never returns saved addresses, usernames, passwords, or private-key paths. connection_history reads durable ssh_exec and terminal_interact records.
For ordinary commands:
connection_open -> ssh_exec -> connection_close
For interactive shells, REPLs, and TUIs:
connection_open -> terminal_open -> terminal_interact -> terminal_close -> connection_close
terminal_interact defaults to wait: "quiet". Use wait: "until" only for a known complete prompt or delimiter; until is a literal, not a regular expression. When the result is limit_reached, continue with next_offset.
Tool Surface
The server always exposes the same eleven model-facing tools: connection open, close, list, and history; one-shot SSH execution; task-oriented SFTP transfer and management; and terminal open, interact, view, and close. There is no tool profile switch and no public session_id, alias, or legacy host-management API.
Configuration and Security
Minimal configuration:
logging:
level: info
format: console
output: stderr
The default state database is ~/.sshmcp/state.db. Override it when needed:
state:
database_path: "/absolute/path/to/sshmcp-state.db"
SQLite uses WAL and a write wait so several MCP instances on the same machine can share state. The database contains connection parameters and execution history. Keep it in a protected local directory; never place it in OneDrive, Dropbox, a network share, or source control. hosts is only a one-time compatibility import source; SQLite owns subsequent state.
See config.example.yaml for all fields. See SECURITY.md for security reporting and credential handling.
Serial
Use connection_list to find locally visible serial ports, then open one with connection_open:
{
"transport": "serial",
"device": "/dev/ttyUSB0",
"baud_rate": 115200,
"data_bits": 8,
"parity": "none",
"stop_bits": "1"
}
On Linux, the account running the server needs device access, commonly by joining the dialout group and signing in again.
Development and Maintenance
go test ./...
go vet ./...
go test -race ./...
Local SSH and serial integration tests are explicitly opt-in. Default tests do not connect to devices or read real credentials.
When a maintainer pushes a version tag, GitHub Actions builds Linux (amd64, arm64), macOS (amd64, arm64), and Windows (amd64) archives and creates the matching GitHub Release:
git tag -a vX.Y.Z -m "Release vX.Y.Z"
git push origin vX.Y.Z
Release builds inject the tag into the MCP server version. The GitHub Release page is the download and release-notes entry point for each version.
License
See LICENSE.
