ssh MCP server
2026년 11월 9일 커밋Model Context Protocol을 통해 AI agent에게 지속적인 SSH 세션, 가상 터미널 에뮬레이션, SFTP 파일 전송 기능을 제공합니다.
다른 이름 taigrr/ssh-mcp
- 스타
- 13
- Tools
- 15
- 다운로드, 30일
- —
- 최신 버전
- —
- 마지막 커밋
- 2026년 11월 9일
- 라이선스
- 0BSD
ssh MCP란?
ssh은(는) MCP server입니다. Model Context Protocol을 통해 AI agent에게 지속적인 SSH 세션, 가상 터미널 에뮬레이션, SFTP 파일 전송 기능을 제공합니다. 15개 도구를 제공합니다. 예: ssh_connect, ssh_exec, ssh_send_command.
프로젝트 README에서 생성된 요약
ssh MCP server 정보
ssh-mcp를 사용하면 AI 코딩 agent 내부에서 원격 서버를 관리하고 인프라를 디버깅할 수 있습니다. 이 MCP server는 AI agent가 특정 원격 호스트 세트에 직접 접근하여 명령을 실행하고, 파일을 관리하며, 터미널 사용자 인터페이스와 상호작용할 수 있도록 지원합니다. 기존의 ~/.ssh/config에서 연결 세부 정보를 가져오고 ssh-agent 또는 gpg-agent를 통해 인증하므로, 사용자의 기존 보안 워크플로우를 그대로 유지합니다.
개발자는 이 도구를 사용하여 로컬 코딩과 원격 실행 사이의 간극을 메울 수 있습니다. ANSI 렌더링을 처리하기 위해 PTY 에뮬레이션이 포함된 가상 터미널을 제공하므로, agent가 터미널에서 사람이 보는 것과 동일한 화면을 볼 수 있습니다. 또한 SFTP를 통해 디렉토리 재귀적 업로드 및 다운로드를 포함한 양방향 파일 전송을 지원합니다. 보안 유지를 위해 이 서버는 허용 목록(allowlist) 방식으로 작동하며, --allowed-hosts 플래그나 config.json 파일을 통해 허용할 호스트를 명시적으로 정의해야 합니다.
활용 사례
- 1원격 서버 디버깅AI agent가 지속적인 셸을 사용하여 스테이징 서버에 접속하고 로그나 시스템 상태를 조사할 수 있습니다.
- 2자동 파일 관리SFTP를 사용하여 agent에게 설정 파일을 이동하거나 원격 머신에 코드를 배포하도록 지시할 수 있습니다.
프로젝트의 README를 바탕으로 작성되었습니다. 모든 활용 사례는 해당 내용의 인용문과 대조하여 확인합니다.
ssh MCP 도구 15
README에서 감지됨ssh_connectssh_execssh_send_commandssh_send_keysssh_get_screenssh_clear_screenssh_resizessh_read_filessh_write_filessh_edit_filessh_uploadssh_download
| ssh_connect | — | |
| ssh_exec | — | |
| ssh_send_command | — | |
| ssh_send_keys | — | |
| ssh_get_screen | — | |
| ssh_clear_screen | — | |
| ssh_resize | — | |
| ssh_read_file | — | |
| ssh_write_file | — | |
| ssh_edit_file | — | |
| ssh_upload | — | |
| ssh_download | — |
도구 15개 모두 보기도구 수 줄이기
ssh_list_sessionsssh_list_hostsssh_close_session
| ssh_list_sessions | — | |
| ssh_list_hosts | — | |
| ssh_close_session | — |
구성
SSH_AUTH_SOCK
| 이름 | 설명 | 유형 |
|---|---|---|
| SSH_AUTH_SOCK | — |
자동 검사
2026년 11월 13일에 실행됨전체 보고서 →아직 인증되지 않았습니다. 서버는 80점 이상의 점수, 심각한 결함 없음, 그리고 검사에 충분한 데이터를 갖추어야 합니다. 검사 방식 · 점수를 높이기 위해 수정할 항목
- 소스 저장소 연결 및 접근 가능taigrr/ssh-mcp is public and reachablegithub.com/taigrr/ssh-mcp ↗통과
- 패키지가 이 저장소를 소스로 명시검사되지 않음
- 빌드 출처(Sigstore 증명)검사되지 않음
- 오픈 소스 라이선스 (OSI)0BSDspdx.org/licenses/0BSD.html ↗통과
- 최근 1년 내 커밋 또는 릴리스Last commit or release 2026-11-09github.com/taigrr/ssh-mcp ↗통과
- OpenSSF Scorecard검사되지 않음
- 패키지 이름이 인기 패키지와 유사하지 않음검사되지 않음
- 패키지 및 해당 종속성에 중요한 보안 권고 없음검사되지 않음
- 모델에 대한 숨겨진 지침 없음15 tool descriptions and the README read; no override phrases, credential paths or hidden characters통과
- 파괴적인 도구에 라벨 표시됨No tool named like delete, drop or exec통과
- 원격 엔드포인트가 MCP 핸드셰이크에 응답검사되지 않음
README
GitHub에서 보기ssh-mcp
MCP server providing persistent SSH sessions for AI coding agents via the Model Context Protocol.
The Problem
AI coding agents can't interact with remote machines. You need to manually SSH in, run commands, and paste output back. For fleet management, server debugging, or remote development, this kills the feedback loop.
The Solution
ssh-mcp gives your AI agent direct SSH access to an allowed set of hosts. It resolves connections from ~/.ssh/config, authenticates via ssh-agent/gpg-agent, and exposes a virtual terminal so the agent sees exactly what you'd see.
# Start with allowed hosts
ssh-mcp --allowed-hosts="web1,db1,staging"
Features
- SSH config integration — Resolves hosts from
~/.ssh/config(HostName, Port, User, IdentityFile) - Agent forwarding — Authenticates via
ssh-agentorgpg-agent(SSH_AUTH_SOCK) - Virtual terminal — Full PTY emulation with ANSI rendering via charmbracelet/x/vt
- File transfer — Bidirectional file and directory transfers via SFTP (recursive)
- Allowlist-only access — Only explicitly permitted hosts can be connected to
- Session management — Multiple concurrent sessions with independent state
- Zero config — Works out of the box if your
~/.ssh/configis set up
Installation
go install github.com/taigrr/ssh-mcp@latest
Requirements
- Go >= 1.26.5 (for installation)
~/.ssh/configentries for your hosts- One of:
ssh-agentorgpg-agentrunning (recommended)- SSH private key at
~/.ssh/id_ed25519or~/.ssh/id_rsa
Quick Start
- Ensure your hosts are in
~/.ssh/config:
Host my-desktop
HostName 10.0.1.50
User tai
- Run with allowed hosts:
ssh-mcp --allowed-hosts="my-desktop"
- Or use a config file (
config.jsonin working directory):
{
"hosts": ["my-desktop", "web1", "db1"]
}
🔌 MCP Tools
| Tool | Description |
|---|---|
ssh_connect |
Connect to an allowed host by alias (optional width, height) |
ssh_exec |
Run a command and block until it finishes or times out |
ssh_send_command |
Send a command (non-blocking); for TUIs / fire-and-forget |
ssh_send_keys |
Send raw bytes with no newline (Ctrl-C, Esc, arrows, TUI keys) |
ssh_get_screen |
Get the current terminal screen content |
ssh_clear_screen |
Reset the local emulator screen + scrollback |
ssh_resize |
Resize a session's terminal (sends SIGWINCH to the remote shell) |
ssh_read_file |
Read a remote file over SFTP (clean bytes, no shell) |
ssh_write_file |
Write a remote file over SFTP (no quoting pitfalls) |
ssh_edit_file |
Exact find-and-replace edit of a remote file (read it first) |
ssh_upload |
Upload a local file or directory via SFTP |
ssh_download |
Download a remote file or directory via SFTP |
ssh_list_sessions |
List all sessions with active state and size |
ssh_list_hosts |
List allowed hosts with resolved connection details |
ssh_close_session |
Close a session |
Choosing between ssh_exec and ssh_send_command
Both run in the same persistent shell (cwd and environment carry over), but they have opposite blocking semantics:
ssh_execis what you want for almost everything that should finish: builds,git, installs, queries, scripts. It wraps the command with internal sentinels, blocks until it completes ortimeout_mselapses, and returns clean output (ANSI/prompt stripped) plus the exit code. On timeout the command is not killed — it keeps running, and you get a screen snapshot so you can see what it is stuck on, then poll (ssh_get_screen), interrupt (ssh_send_keysCtrl-C), or wait longer.ssh_send_commandis non-blocking and exists for interactive TUIs (vim, less, htop, tmux, REPLs) and fire-and-forget launches. It returns the screen after a short settle delay regardless of completion.
The emulator backing every session is a real virtual terminal, so even when an
ssh_exec command times out or a TUI is open, the session stays responsive and
its state is always inspectable via ssh_get_screen — nothing can hang the
server.
ssh_exec's timeout_ms defaults to 60s (matching Crush's bash tool, which
auto-backgrounds a synchronous command after 60s) and is capped at 10m. A
timeout is not an error: the tool returns a normal result noting the command
is still running, plus the current screen, so the model just keeps going with
ssh_get_screen / ssh_send_keys.
One shell per session: concurrency
Each session is a single interactive shell with one stdin and one stdout. The server keeps that consistent under concurrent tool calls:
- Byte level — all writes to the shell go through one serialized path, so bytes from different calls never interleave mid-sequence. Output is captured by a concurrency-safe terminal emulator.
- Two
ssh_execat once (same session) — rejected. Only onessh_execmay be waiting in a session's shell at a time; the loser gets an "already executing" error. This prevents two wrapped commands from racing into the same shell and scrambling each other's captured output. ssh_send_commandduring anssh_exec— rejected for the same reason (it would inject a second command line mid-exec).ssh_send_keysduring anssh_exec— allowed on purpose. This is how you send Ctrl-C to interrupt a command that timed out and is still running.- Different sessions — fully independent; run them in parallel freely.
If you fire several commands at the same session simultaneously, expect all but one to come back with an "already executing" error rather than corrupting the shell. Sequence them, or use separate sessions.
Terminal size
Sessions default to a 200x50 virtual terminal, large enough for typical
ls, tail, ps, log, and progress-bar output without triggering line wraps
that pollute scrollback. Clients can override the initial size via width /
height on ssh_connect, or resize a live session with ssh_resize. Values
are clamped to [20, 500] columns x [5, 200] rows.
Session lifecycle
ssh_list_sessions returns every session the server knows about along with
its current state ([active] or [inactive]) and current terminal size.
Background goroutines watch each session's stdout and keepalive channel; when
they detect that the remote end has gone away (EOF, keepalive timeout) the
session is automatically marked inactive and removed from the manager, so
a follow-up ssh_list_sessions won't keep advertising a dead entry. Only
sessions reported as [active] accept ssh_send_command / ssh_get_screen
/ ssh_resize; attempts on inactive entries return ErrSessionInactive.
ssh_send_command is non-blocking
ssh_send_command writes the command + newline to the remote shell's stdin,
waits a short settle delay (~3.5s) for the terminal to redraw, then returns
the screen as-is. It does not wait for the command to finish. This is
intentional: it keeps TUIs (vim, htop, tmux, less) interactive across calls.
Practical consequences for clients (especially LLM agents):
- A long-running command (
sleep 60,make, training jobs, package installs) keeps running on the remote host after the call returns. - To wait for completion, sleep on your side (your own timer / bash tool
outside this MCP), then call
ssh_get_screento read fresh output. Do not prefixsleep N;to the SSH command expecting it to block here. - Sending a second command before the first finishes queues bytes in the
remote shell's stdin and produces garbled, interleaved output. Poll with
ssh_get_screenuntil you see the prompt first. - For output you'd rather not stream through the screen, redirect to a file
(
cmd > /tmp/out 2>&1 &) and read it back withcat.
⚙️ Crush Configuration
Add to your project's crush.json or .crush.json:
{
"mcp": {
"ssh": {
"command": "ssh-mcp",
"args": ["--allowed-hosts=my-desktop,staging"],
"type": "stdio"
}
}
}
🤖 Claude Configuration
Claude Code
Register the server with the Claude Code CLI (writes to your MCP config):
claude mcp add ssh -- ssh-mcp --allowed-hosts=my-desktop,staging
Or add it manually to ~/.claude.json (global) or .mcp.json (project):
{
"mcpServers": {
"ssh": {
"command": "ssh-mcp",
"args": ["--allowed-hosts=my-desktop,staging"],
"type": "stdio"
}
}
}
Claude Desktop
Add to your claude_desktop_config.json:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"ssh": {
"command": "ssh-mcp",
"args": ["--allowed-hosts=my-desktop,staging"]
}
}
}
If ssh-mcp is not on your PATH, use the absolute path (e.g. the output of which ssh-mcp, typically ~/go/bin/ssh-mcp) as the command. Because the server authenticates via ssh-agent, ensure SSH_AUTH_SOCK is available to the Claude process; you can pass it explicitly:
{
"mcpServers": {
"ssh": {
"command": "/Users/you/go/bin/ssh-mcp",
"args": ["--allowed-hosts=my-desktop,staging"],
"env": {
"SSH_AUTH_SOCK": "/path/to/ssh-agent.sock"
}
}
}
}
Restart Claude Desktop after editing the config.
Flags
| Flag | Description |
|---|---|
--allowed-hosts |
Comma-separated list of allowed SSH host aliases |
If --allowed-hosts is not provided, falls back to config.json in the working directory.
How It Works
- Resolve — Looks up host alias in
~/.ssh/configfor connection details - Authenticate — Tries ssh-agent → key file → password (in order)
- Connect — Opens a PTY session with
xterm-256colorterminal - Emulate — Captures output in a virtual terminal emulator
- Expose — Returns rendered screen content (with ANSI) to the MCP client
Architecture
┌──────────────────────────────────────────────────┐
│ ssh-mcp │
│ │
│ ~/.ssh/config ──► Host Resolution │
│ │
│ SSH_AUTH_SOCK ──► Authentication │
│ │
│ Sessions: │
│ ├─ tai@10.0.1.50:22 (PTY + VT) │
│ ├─ admin@web1.example.com:22 (PTY + VT) │
│ └─ ... │
│ │
│ MCP Tools ◄──► stdio transport ◄──► AI Agent │
└──────────────────────────────────────────────────┘
Development
# Build
go build -o ssh-mcp .
# Test
go test ./...
# Lint
staticcheck ./...
Related Projects
- Crush — Charm's AI coding agent
- charmbracelet/x/vt — Virtual terminal emulator
- neocrush — LSP/MCP bridge for Crush + Neovim
License
ssh MCP 질문
ssh MCP는 어떤 도구를 제공하나요?
15개 도구를 제공합니다. 예: ssh_connect, ssh_exec, ssh_send_command, ssh_send_keys, ssh_get_screen.
서버가 원격 호스트와 인증하는 방법은 무엇인가요?
ssh-agent, gpg-agent 또는 ~/.ssh/id_ed25519나 ~/.ssh/id_rsa에 위치한 SSH private key를 통해 인증합니다.
이 서버를 사용하여 파일을 전송할 수 있나요?
네, 서버는 재귀적 전송을 포함하여 SFTP를 이용한 양방향 파일 및 디렉토리 전송을 지원합니다.
ssh_exec와 ssh_send_command의 차이점은 무엇인가요?
ssh_exec는 빌드나 git처럼 완료되어야 하는 명령에 사용되는 블로킹 도구이며, ssh_send_command는 비블로킹 방식으로 vim이나 htop 같은 대화형 TUI를 위해 설계되었습니다.