使用说明
SSH 只读 MCP 服务器
一个安全的模型上下文协议(MCP)服务器,支持远程SSH命令执行,并严格实施只读策略。非常适合在安全地将SSH访问权限委托给Claude的同时,防止意外或恶意的写入操作。
特点/特性
✅ 只读命令强制执行 – 仅允许安全的、只读命令
✅ SSH 连接池 – 支持多个同时连接
✅ 命令验证 – 阻止危险模式和写入操作
✅ 多播发现 – 在网络上自动广播以便轻松发现
✅ 灵活运输 – 标准I/O(Stdio)、HTTP或可流式传输的HTTP模式
✅ 全面日志记录 – 完整的审计追踪记录 ssh_mcp.log
✅(这个符号通常表示“正确”、“确认”或“完成”的意思,但具体含义可能根据上下文有所不同) 环境配置 – 可通过.env文件完全配置
安装
先决条件
- Python 3.8及以上版本
uv包管理器
设置
# Clone or create project directory
mkdir ssh-mcp-server
cd ssh-mcp-server
# Initialize uv project (if needed)
uv init
# Install dependencies
uv pip install fastmcp paramiko python-dotenv
或者使用 pyproject.toml:
[project]
name = "ssh-mcp-server"
version = "0.1.0"
dependencies = [
"fastmcp>=0.1.0",
"paramiko>=3.0.0",
"python-dotenv>=1.0.0",
]
然后安装:
uv sync
配置
创建一个 .env 项目根目录中的文件:
# Transport mode: stdio (default), http, or streamable-http
MCP_TRANSPORT=stdio
# Server identification
MCP_SERVER_NAME=SSH Read-Only MCP Server
# HTTP mode settings (if using http/streamable-http)
MCP_HOST=0.0.0.0
MCP_PORT=3000
# Multicast discovery
MCP_ENABLE_BROADCAST=true
MCP_BROADCAST_INTERVAL=30
环境变量
| 变量 | 默认值 | 描述 |
|---|---|---|
MCP_TRANSPORT |
stdio |
通信传输: stdio, http,或者 streamable-http |
MCP_SERVER_NAME |
SSH Read-Only MCP Server 服务器的显示名称 |
|
MCP_HOST |
0.0.0.0 |
HTTP模式下的绑定地址 |
MCP_PORT |
3000 |
HTTP模式的端口 |
MCP_ENABLE_BROADCAST |
true |
启用多播发现公告 |
MCP_BROADCAST_INTERVAL |
30 |
广播公告之间的间隔时间(秒) |
使用方法
启动服务器
标准I/O模式(默认):
uv run ssh_readonly_fastmcp_mcast.py
使用多播发现的HTTP模式:
MCP_TRANSPORT=http MCP_PORT=3000 uv run ssh_readonly_fastmcp_mcast.py
非广播模式下的HTTP:
MCP_ENABLE_BROADCAST=false MCP_TRANSPORT=http MCP_PORT=3000 uv run ssh_readonly_fastmcp_mcast.py
可用工具
1. ssh_connect
建立与远程机器的SSH连接。
参数:
host(必填)– 远程主机IP或主机名username(必填)– SSH 用户名port(可选,默认:22)– SSH 端口key_filename(可选)– 私钥文件路径(推荐)password(可选)– SSH 密码(备用)
示例:
Connect to 192.168.1.100 as user 'admin' with private key
host: 192.168.1.100
username: admin
key_filename: /home/user/.ssh/id_rsa
2. ssh_execute
在连接的远程机器上执行只读命令。
参数:
host(必需)– 远程主机(必须先连接)username(必填)– SSH 用户名command(必需)– 执行只读命令port(可选,默认:22)– SSH 端口
示例:
Run 'ls -la /home' on connected server
host: 192.168.1.100
username: admin
command: ls -la /home
3. ssh_disconnect
关闭SSH连接。
参数:
host(必填)– 远程主机username(必填)– SSH 用户名port(可选,默认值:22)– SSH 端口
4. ssh_list_connections
查看所有活动的SSH连接。
参数: 无
5. ssh_get_allowed_commands
获取允许的只读命令列表。
参数: 无
允许的命令
服务器允许以下只读操作:
- 文件操作:
cat,ls,file,head,tail,find,locate - 系统信息:
ps,top,df,du,free,uname,hostname,uptime - 网络:
netstat,ss,ifconfig,ip,curl,wget,dig,nslookup,ping,traceroute - 流程管理:
lsof,systemctl,service - 文本处理:
grep,awk,sed,wc - 并且还有许多只读实用程序
阻塞操作: rm, mv, cp, chmod, chown, mkdir, touch, kill, shutdown, reboot, sudo以及任何写入/修改命令。
多播发现
当以启用广播的HTTP模式运行时,服务器会在多播组中宣布自己的存在:
- 地址:
239.255.255.250 - 端口:
5353 - 间隔: 可配置(默认:30秒)
发现公告包括:
- 服务器UUID
- 服务器名称
- 本地IP和端口
- 运输类型
- 协议版本
记录日志
所有活动均被记录到 ssh_mcp.log:
2025-10-17 10:30:45,123 [INFO] ssh_mcp - Starting MCP server with transport=http
2025-10-17 10:30:46,456 [INFO] ssh_mcp - Starting multicast broadcaster on 239.255.255.250:5353
2025-10-17 10:30:47,789 [INFO] ssh_mcp - Successfully connected to admin@192.168.1.100:22
安全考虑事项
🔒(锁形符号,通常表示安全、保密或锁定的状态) 只读强制执行:
- 仅允许白名单中的命令
- 危险模式(管道、重定向、子shell)被阻止
- 在命令级别上阻止写操作
⏱️(这个符号本身没有直接对应的中文翻译,它通常表示时间或倒计时,可以意译为“倒计时”或根据上下文具体解释为“时间紧迫”等。在这里,我将其意译为“时间紧迫”以表达其含义。) 超时设置:
- 每条命令30秒的执行超时时间
- 防止挂起命令阻塞服务器
🔐 表示“锁”或“密码保护”的符号。 认证:
- 建议使用SSH密钥认证而非密码
- 密码仅存储在内存中,从不持久化保存
📋 表格/清单 审计轨迹/审计路径
- 所有连接和命令都被记录下来
- 评论
ssh_mcp.log用于安全审计
故障排除
连接被拒绝
Error: Connection failed: [Errno 111] Connection refused
- 验证远程主机是否可达:
ping <host> - 检查远程机器上的SSH是否正在运行
- 验证端口号(默认22)
认证失败
Error: Connection failed: Authentication failed
- 验证用户名是否正确
- 对于密钥认证:检查密钥文件路径和权限(
chmod 600) - 对于密码认证:验证凭据
- 确保SSH公钥在远程服务器上已授权
~/.ssh/authorized_keys)
命令不允许
Error: Command not allowed for security reasons
- 该命令包含被阻止的模式或不在允许列表中
- 使用
ssh_get_allowed_commands查看允许的命令 - 对于写操作,请直接使用SSH代替
广播无法正常工作
- 验证
MCP_ENABLE_BROADCAST=true - 检查网络是否支持多播(大多数企业网络会阻止多播)
- 验证防火墙是否允许在5353端口上使用UDP
- 检查
ssh_mcp.log对于广播错误
发展
在调试模式下运行
DEBUG=true uv run ssh_readonly_fastmcp_mcast.py
测试
# Test connection
uv run -c "from ssh_readonly_fastmcp_mcast import is_command_safe; print(is_command_safe('ls -la'))"
# Should print: True
# Test blocked command
uv run -c "from ssh_readonly_fastmcp_mcast import is_command_safe; print(is_command_safe('rm -rf /'))"
# Should print: False
项目结构
ssh-mcp-server/
├── ssh_readonly_fastmcp_mcast.py # Main server implementation
├── .env # Configuration file
├── .env.example # Configuration template
├── ssh_mcp.log # Server logs (auto-generated)
├── pyproject.toml # Project metadata
└── README.md # This file
API响应格式
所有工具均返回一致的JSON响应:
成功:
{
"status": "success",
"host": "192.168.1.100",
"command": "ls -la /home",
"exit_code": 0,
"output": "total 24\ndrwxr-xr-x 3 root root 4096...",
"error": null
}
错误:
{
"status": "error",
"message": "Command not allowed for security reasons",
"reason": "Only read-only commands are permitted"
}
许可证
麻省理工学院(MIT)
做出贡献
欢迎投稿!请确保:
- 所有更改均保持只读强制执行
- 代码已正确记录
- 安全验证测试通过
支持
对于问题或疑问:
- 检查
ssh_mcp.log查看错误详情 - 查看故障排除部分
- 验证环境配置
- 检查与远程主机的网络连接
