Skip to main content
Glama
vait90
by vait90

SSH MCP 服务器 (paramiko)

基于 Paramiko 的 SSH MCP 服务器,可以通过 SFTP 在远程机器上执行命令并传输文件。可通过环境变量 / 开关选择两种传输方式:

  • http – MCP streamable-http 端点位于 /mcp 路径(Cherry Studio 连接到此端点),此外还有文档化的 OpenAPI/Swagger 界面(/docs、/openapi.json)。

  • stdio – 经典的 MCP stdio 传输(用于本地启动 / docker exec)。

FONTOS a portokról: 2222 是 MCP 服务器的端口,Cherry Studio 连接到此端口。这不是远程主机的 SSH 端口!远程主机的 SSH 端口通常是 22(SSH_PORT)。因此链路为:Cherry Studio → http://<host-IP>:2222/mcp → MCP 服务器 → paramiko → 远程主机的 22 号 SSH 端口。


可用的 MCP 工具

无状态(stateless)工具 — 简单、一次性操作

工具

说明

ssh_test

测试与远程主机的连接和认证。

ssh_execute

在新的连接中执行单条 shell 命令(stdout / stderr / 退出码)。没有记忆:cd / export 不会继承到下一次调用,也无法响应交互式提示。

ssh_upload

通过 SFTP 将本地文件上传到远程主机。

ssh_download

通过 SFTP 从远程主机下载文件。

有状态(stateful)、交互式会话工具 — 实时 shell

这些工具会保持一个实时 shell 打开,状态在多次调用之间得以保留(cd 之后的目录切换、export 的变量、交互式提示的处理:sudo 密码、apt [Y/n] 等)。

工具

说明

ssh_open_session

第 1 步 – 打开一个新的交互式 shell,返回一个 session_id。

ssh_send

第 2 步 – 向会话发送文本(命令或提示回答)。必须始终传入 session_id。

ssh_read

第 3 步(可选) – 在不发送的情况下读取更多输出(用于缓慢 / 长时间运行的命令)。

ssh_close_session

第 4 步 – 关闭会话。用完务必关闭。

ssh_list_sessions

列出已打开的会话(host、用户、空闲时间),例如在 session_id 丢失时。

工具描述(docstrings)刻意包含非常详细、简单的英文“USE THIS WHEN...”指南,以便调用模型清楚地知道何时以及如何使用每个工具。

每个工具的参数(host、port、username、password、private_key、private_key_path、passphrase、timeout)都可以通过以下方式给出:

  • 每次调用单独提供,或者

  • 在 .env 文件中提供默认值(SSH_* 变量)。调用中未指定的部分会从 SSH_* 环境变量中获取。

支持的认证方式:密码和密钥(内联 PEM 或文件路径,可选密码)。服务器会自动接受未知主机密钥(AutoAddPolicy),以确保自动化流程顺畅。


Related MCP server: SSH MCP Server

无状态 vs. 有状态(交互式)使用

何时选用哪种?

  • 单个独立命令(如 ls、uptime、df -h)→ 用 ssh_execute。每次调用都会打开新连接、执行一条命令,然后关闭。没有记忆:cd 和 export 不会保留到下一次调用,也无法响应交互式提示。

  • 任何交互式或多步操作(cd/export 后的状态保留、输入 sudo 密码、回答 apt [Y/n]、前后衔接的多条命令)→ 交互式会话:ssh_open_session → ssh_send → ssh_read → ssh_close_session。

推荐的会话工作流

  1. ssh_open_session → 获得一个 session_id(以及 initial_output 中的登录 banner / 第一个提示符)。

  2. ssh_send → 输入命令或回复提示。每次调用都必须传入 session_id。默认会同时发送一个回车。

  3. ssh_read(可选)→ 对于慢速/长时间运行的命令,在不发送的情况下收取更多输出。

  4. ssh_close_session → 完成后关闭会话。

如果 session_id 丢失,可随时用 ssh_list_sessions 查看已打开的会话(host、用户、空闲时间)。

示例(通过 REST 端点)

打开会话:

curl -X POST http://localhost:2222/api/ssh/session/open \
  -H "Content-Type: application/json" \
  -d '{"host":"192.168.1.100","username":"user","password":"secret"}'
# -> {"ok":true,"session_id":"<ID>", "initial_output":"...prompt..."}

切换目录并保留状态:

curl -X POST http://localhost:2222/api/ssh/session/send \
  -H "Content-Type: application/json" \
  -d '{"session_id":"<ID>","input":"cd /var/log && pwd"}'
# a következő ssh_send már a /var/log-ban futna

sudo 命令 + 回答密码提示:

# 1) elindítod a sudo parancsot
curl -X POST http://localhost:2222/api/ssh/session/send \
  -H "Content-Type: application/json" \
  -d '{"session_id":"<ID>","input":"sudo apt-get update"}'
# 2) a kimenetben megjelenik a "[sudo] password for user:" prompt -> beküldöd a jelszót
curl -X POST http://localhost:2222/api/ssh/session/send \
  -H "Content-Type: application/json" \
  -d '{"session_id":"<ID>","input":"my_sudo_password"}'

回答 apt 的 [Y/n] 问题:

curl -X POST http://localhost:2222/api/ssh/session/send \
  -H "Content-Type: application/json" \
  -d '{"session_id":"<ID>","input":"sudo apt-get install htop","read_timeout":5}'
# amikor jön a "Do you want to continue? [Y/n]" kérdés:
curl -X POST http://localhost:2222/api/ssh/session/send \
  -H "Content-Type: application/json" \
  -d '{"session_id":"<ID>","input":"Y"}'

关闭会话:

curl -X POST http://localhost:2222/api/ssh/session/close \
  -H "Content-Type: application/json" \
  -d '{"session_id":"<ID>"}'

超时 / 空闲 / 错误说明: 每个会话操作都会顺带关闭进入空闲状态超过 SSH_SESSION_IDLE_TIMEOUT(默认 600 秒)的会话,以及其通道已失效的会话。同时最多只能打开 SSH_MAX_SESSIONS(默认 20)个会话 —— 达到上限会给出明确的错误消息。如果某个 session_id 已不存在,响应会明确告诉你该怎么办(打开新会话,或用 ssh_list_sessions 查看)。


项目结构

ssh-mcp-server/
├── app/
│   ├── __init__.py
│   ├── ssh_ops.py     # paramiko SSH/SFTP műveletek (közös logika)
│   └── server.py      # MCP tool-ok + FastAPI/OpenAPI + transport választás
├── requirements.txt
├── Dockerfile
├── docker-compose.yml # 2222:2222 publikálás
├── .env.example
└── README.md

1. 使用 Docker 快速启动(推荐)

环境准备

cd ssh-mcp-server
cp .env.example .env
# szerkeszd a .env-et: add meg a távoli gép adatait (SSH_HOST, SSH_USERNAME, stb.)

Build 并启动(HTTP 模式)

docker compose up -d --build

这将以 HTTP 模式启动服务器,并把 2222 端口发布到主机上(ports: "2222:2222")。

验证

curl http://localhost:2222/health
# {"status":"ok","service":"ssh-mcp-server","mcp_endpoint":"/mcp"}
  • Swagger UI(浏览器中):http://localhost:2222/docs

  • OpenAPI JSON:http://localhost:2222/openapi.json

  • MCP 端点(Cherry Studio):http://<host-IP>:2222/mcp

停止

docker compose down

2. 手动运行 HTTP 模式(不使用 Docker,适合开发)

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
export TRANSPORT=http HOST=0.0.0.0 PORT=2222
python -m app.server

3. stdio 模式

容器内已运行服务器时,使用 docker exec:

docker exec -i -e TRANSPORT=stdio ssh-mcp-server python -m app.server

或者不使用 Docker,直接运行:

TRANSPORT=stdio python -m app.server

4. Cherry Studio 集成

A) HTTP(streamable-http)模式 — 推荐,可跨网络使用

容器在笔记本电脑的 Docker 中运行,Cherry Studio 则使用主机 IP和2222端口。

  1. 启动服务器:docker compose up -d --build

  2. 查明运行 Docker 的主机的 IP 地址:

    • Linux:hostname -I → 例如 192.168.1.50

    • 如果 Cherry Studio 运行在同一台机器上,使用 localhost / 127.0.0.1 即可。

  3. Cherry Studio → 设置(Settings) → MCP Servers → Add / 新建服务器。

  4. 填写以下内容:

    • Type / 类型: Streamable HTTP(如果没有该选项,则选 SSE / HTTP)

    • URL / Endpoint: http://<host-IP>:2222/mcp

      • 例如 http://192.168.1.50:2222/mcp

      • 同一台机器上:http://localhost:2222/mcp

  5. 保存并**启用(Enable)**该服务器。Cherry Studio 会加载 ssh_test、ssh_execute、ssh_upload、ssh_download 这些工具。

如果从远程机器连接,请确保 2222 端口可访问(放行防火墙),并确认 Docker 监听在 0.0.0.0(默认如此)。

B) stdio 模式

如果 Cherry Studio 需要启动一个 stdio MCP 服务器(作为命令启动):

  • Command(命令): docker

  • Arguments(参数):

    exec -i -e TRANSPORT=stdio ssh-mcp-server python -m app.server

(ssh-mcp-server 容器必须处于运行状态 — docker compose up -d。)


5. .env 配置

变量

说明

默认值

TRANSPORT

http 或 stdio

http

HOST

MCP HTTP 绑定的地址

0.0.0.0

PORT

MCP HTTP 端口(Cherry Studio 访问的端口)

2222

SSH_HOST

远程主机地址

–

SSH_PORT

远程主机的 SSH 端口

22

SSH_USERNAME

SSH 用户名

–

SSH_PASSWORD

SSH 密码(或使用密钥)

–

SSH_PRIVATE_KEY

内联私钥(PEM)

–

SSH_PRIVATE_KEY_PATH

私钥文件路径(容器内)

–

SSH_PASSPHRASE

私钥密码

–

SSH_TIMEOUT

连接超时(秒)

15

SSH_SESSION_IDLE_TIMEOUT

空闲交互会话自动关闭的秒数(0 = 无)

600

SSH_MAX_SESSIONS

同时打开交互式会话的最大数量

20

Docker 中的密钥认证

把密钥挂载进容器,然后设置路径。在 docker-compose.yml 中,取消 volumes 行的注释:

    volumes:
      - ./keys:/keys:ro

然后在 .env 中:

SSH_PRIVATE_KEY_PATH=/keys/id_ed25519

6. 用于测试的 REST 端点(OpenAPI)

HTTP 模式在 Cherry Studio 使用的 MCP 端点之外,还提供 REST 端点 — 它们执行相同的 SSH 操作,可通过 curl 或 Swagger UI 便捷使用:

方法

路径

操作

GET

/health

状态

GET

/

服务器信息

POST

/api/ssh/test

测试连接

POST

/api/ssh/execute

执行命令

POST

/api/ssh/upload

文件上传(SFTP)

POST

/api/ssh/download

文件下载(SFTP)

POST

/api/ssh/session/open

打开交互式会话(第 1 步)

POST

/api/ssh/session/send

向会话发送输入(第 2 步)

POST

/api/ssh/session/read

不发送时读取输出(第 3 步)

POST

/api/ssh/session/close

关闭会话(第 4 步)

GET

/api/ssh/session/list

列出已打开的会话

示例(无状态、单命令执行):

curl -X POST http://localhost:2222/api/ssh/execute \
  -H "Content-Type: application/json" \
  -d '{"host":"192.168.1.100","username":"user","password":"secret","command":"uname -a"}'

安全说明

  • 机密永远不会出现在代码中 —— 一切从 .env / 调用参数读取。

  • .env 文件会被 .dockerignore 和通常的 .gitignore 排除 —— 不要 将它提交到版本控制。

  • 服务器使用 AutoAddPolicy(自动接受未知的主机密钥)。 在封闭网络中很方便;在更严格的环境中,建议使用已知的主机密钥。

  • 2222 MCP 端口只在可信网络中开放。

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to securely execute commands, transfer files, and manage port forwarding on remote servers via SSH.
    183 npm
    37
    Apache 2.0
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables remote server management via SSH, including command execution, file transfer (SFTP), and interactive shell sessions, with support for multiple hosts.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to securely execute commands on remote hosts via SSH and SFTP, with persistent shells, file transfers, screenshots, and an audit log.
    4
    MIT