ssh-mcp
Enables SSH interactive session management through MCP, supporting commands, menus, and session lifecycle operations.
README
SSH MCP
一个不依赖 Xshell 的 Python SSH MCP Server。它由 MCP Server 自己建立交互式 SSH PTY 会话,适合 CMSM/堡垒机菜单、进入 master、进入 pod 后复用当前 shell 状态的排障流程。
能力概览
open_session(profile, owner_label=None):按配置打开持久 SSH 会话,并返回对应的浏览器viewer_url。list_sessions():查看当前 MCP Server 实例内的活动会话和运行时信息。send_text(session_id, text, enter=True, wait_for="", timeout=30):向菜单或 shell 发送文本。execute_command(session_id, command, wait_for_prompt=True, timeout=30):在当前 shell 状态下执行命令。get_screen(session_id, lines=100):查看内存中最近的终端输出。get_transcript(session_id, tail=200):读取 JSONL 审计记录。interrupt(session_id):发送Ctrl+C。search_logs(...):在当前远端 shell 中执行find + grep日志搜索。
架构
Claude / Codex / MCP Client
-> ssh-mcp FastMCP Server
-> Paramiko SSH interactive shell channel
-> remote CMSM / master / pod shell
ssh-mcp Server
-> runtime/instances/<server_instance_id>/logs/ssh_mcp.log
-> runtime/instances/<server_instance_id>/transcripts/<session_id>.jsonl
-> local browser viewer
每个 MCP Server 进程都会生成独立的 server_instance_id。多个 LLM 窗口同时启动 MCP Server 时,默认写入不同的实例目录,避免日志和 transcript 混在一起。
安装
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e .
开发测试可直接使用:
.\.venv\Scripts\python.exe -m unittest discover -s tests -v
SSH 配置
复制配置模板:
Copy-Item .\config\profiles.example.json .\config\profiles.json
示例:
{
"profiles": {
"dev": {
"host": "10.0.0.10",
"port": 22,
"username": "your-user",
"key_filename": "C:/Users/you/.ssh/id_rsa",
"passphrase_env": "SSH_MCP_KEY_PASSPHRASE",
"allow_agent": true,
"look_for_keys": true,
"auto_add_host_key": true,
"term": "xterm-256color",
"width": 120,
"height": 40,
"keepalive_interval": 30
}
}
}
keepalive_interval 使用 Paramiko transport keepalive,只做 SSH 探活,不会向远端 shell 注入命令。
运行
直接启动:
.\.venv\Scripts\python.exe -m ssh_mcp.server --viewer-host 127.0.0.1 --viewer-port auto
常用环境变量:
SSH_MCP_CONFIG:profile 配置路径,默认config/profiles.json。SSH_MCP_RUNTIME_DIR:运行产物根目录,默认runtime。SSH_MCP_CLIENT_LABEL:当前 MCP Server 来源标签,例如claude-order-debug、codex-local。SSH_MCP_KEY_PASSPHRASE:私钥口令。SSH_MCP_KEEPALIVE_INTERVAL:默认 SSH keepalive 秒数,可被 profile 覆盖。
兼容旧配置:
- 显式设置
SSH_MCP_LOG_PATH时,运行日志写到该路径。 - 显式设置
SSH_MCP_TRANSCRIPTS_DIR时,transcript 写到该目录。
Claude / Codex 接入
仓库提供 .mcp.json 和 .codex/config.toml 示例。默认建议只设置:
SSH_MCP_CONFIGSSH_MCP_RUNTIME_DIRSSH_MCP_CLIENT_LABELSSH_MCP_KEY_PASSPHRASE
不要让多个 MCP Server 固定写同一个 logs/ssh_mcp.log 或 transcripts/,否则排查时很难区分不同 LLM 窗口。
启动 Claude Code 前可设置:
$env:SSH_MCP_KEY_PASSPHRASE = "<your-private-key-passphrase>"
$env:SSH_MCP_CLIENT_LABEL = "claude-payment-debug"
claude
open_session 时建议传入 owner_label:
{"profile": "lab", "owner_label": "payment-log-check"}
SSH_MCP_CLIENT_LABEL 标记 MCP Server 来源,owner_label 标记具体 SSH session 的用途。
浏览器 Viewer
MCP Server 启动时会同时启动本地 viewer。默认从 8765 附近自动选择可用端口。
/:按server_instance_id分组展示 sessions。/sessions/<session_id>:单个 session 的终端式页面。/api/sessions:返回 session 列表和 server 元数据。/api/sessions/<session_id>/events:长轮询读取 transcript 增量。
open_session 会返回准确的 viewer_url,不要手动猜 session URL。
也可以只启动历史 viewer:
.\.venv\Scripts\python.exe -m ssh_mcp.viewer --port 8765 --transcripts-dir transcripts
Runtime 目录
默认结构:
runtime/
instances/
<server_instance_id>/
server_meta.json
logs/
ssh_mcp.log
transcripts/
<session_id>.jsonl
server_meta.json 记录:
server_instance_id- pid
- cwd
- started_at
- client_label
- viewer_base_url
- log_path
- transcripts_dir
- config_path
旧的 transcripts/*.jsonl 仍可被 viewer 读取,并标记为 legacy。
Transcript 与安全
每个 SSH session 都有独立 JSONL 文件。首行是 session_meta,包含 profile、host、username、owner_label、server_instance_id、client_label、viewer_url 等信息。
示例事件:
{"dir":"session_meta","session_id":"lab-...","owner_label":"payment-log-check","server_instance_id":"ssh-mcp-..."}
{"dir":"send","tool":"send_text","text":"2\n"}
{"dir":"recv","text":"Logged in to master...\n"}
{"dir":"session_health","health_status":"unhealthy","health_error":"SSH transport is inactive"}
重要:send_text(..., sensitive=true) 不会脱敏,text 仍按原文写入 transcript。请保护 runtime/、logs/、transcripts/ 的文件权限。
SSH 心跳与断线处理
当前策略是“只探活,不自动重连”:
- 使用 Paramiko transport keepalive 保持 SSH 连接活跃。
- 后台 health monitor 定期检查 transport/channel。
- 断开后 session 会标记为
unhealthy或closed。 - 后续
send_text/execute_command返回可读错误。 - 不自动重放 CMSM -> master -> pod 路径,避免误以为恢复了原始 shell 状态。
本地 CMSM 测试环境
仓库内置 CMSM simulator:
lab/cmsm_simulator/
它模拟:
CMSM 菜单 -> master shell -> kubectl exec -> pod shell
部署和测试步骤见 lab/cmsm_simulator/README.md。
常见问题
为什么 viewer 端口不是 8765?
如果端口被占用,viewer 会自动选择后续可用端口。以 open_session 返回的 viewer_url 为准。
多个 Claude/Codex 窗口如何区分?
设置不同的 SSH_MCP_CLIENT_LABEL,并在 open_session 传入 owner_label。运行日志、server_meta 和 transcript 都会记录这些字段。
MCP 重启后 SSH session 还在吗?
不在。当前实现使用 Paramiko interactive shell channel,MCP Server 进程退出后 SSH 连接也会关闭。历史 transcript 会保留在 runtime 目录。
什么时候考虑 tmux?
如果需要 MCP 重启后仍能 attach 原 SSH 会话,可以在后续版本评估 tmux 底座。但 Windows 原生部署会更复杂,本项目当前优先保持 Python/Paramiko 的轻量实现。
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。