SafeShell MCP服务器
SafeShell允许AI助手在执行安全护栏的同时运行shell命令:命令被分类,受保护的路径被硬封锁,危险的操作需要人工批准,敏感的环境变量会从输出中自动编辑。
特性
- 命令分类 --命令分为安全(自动执行)或危险(需要批准)
- 受保护的路径执行 --硬块写入系统目录(
/etc,/boot,C:\Windows等等) - 循环中的人类 --通过MCP启发提示批准危险命令
- 连锁指挥分析 --管道/链中的每个子命令都是独立分类的
- Symlink保护 --在保护检查之前,路径被规范化
- 输出限制 --带截断报告的可配置最大输出大小
- 秘密编辑 --敏感的环境变量值被替换为
[REDACTED]在输出 - 并发控制 --基于信号量的并发执行限制
- 双重运输 --支持stdio和流式HTTP(SSE)
- 平滑关闭 --带有子进程清理的信号处理
- 跨平台 --macOS、Linux、Windows
建筑
┌──────────────────────────────────────────────┐
│ MCP Client │
│ (Claude Desktop, Cursor, VS Code, etc.) │
└────────────────┬─────────────────────────────┘
│
stdio or HTTP/SSE
│
┌────────────────▼─────────────────────────────┐
│ SafeShell MCP Server │
│ │
│ Tools: │
│ • execute_command │
│ • get_system_path │
│ • list_safe_commands │
│ • list_protected_paths │
│ │
│ ┌────────────────────────────────────────┐ │
│ │ Safety Pipeline │ │
│ │ │ │
│ │ 1. Parse ─► Tokenize, resolve paths │ │
│ │ │ │ │
│ │ 2. Classify ─► Safe or Dangerous │ │
│ │ │ │ │
│ │ 3. Location Guard ─► Protected paths │ │
│ │ │ (hard block) │ │
│ │ │ │ │
│ │ 4. Permission Gate ─► User approval │ │
│ │ │ (elicitation) │ │
│ │ │ │ │
│ │ 5. Execute ─► Run, sanitize output │ │
│ │ │ │
│ └────────────────────────────────────────┘ │
│ │
│ Platform Layer (macOS / Linux / Windows) │
│ • Safe command allowlists │
│ • Protected path definitions │
└──────────────────────────────────────────────┘安装
预构建二进制文件
下载自 :
| 平台 | 二进制 |
|---|---|
| macOS(苹果硅) | safeshell-mcp-macos-arm64 |
| Linux(x86_64) | safeshell-mcp-linux-x86_64 |
| Linux(ARM64) | safeshell-mcp-linux-arm64 |
| Windows(x86_64) | safeshell-mcp-windows-x86_64.exe |
| Windows(x86) | safeshell-mcp-windows-x86.exe |
从源代码构建
需要Rust 1.85+(2024版)。
cargo install --path .或者构建一个发布二进制文件(针对大小进行了优化):
cargo build --release
# Binary at target/release/safeshell-mcp快速开始
1.使用stdio传输运行(默认)
safeshell-mcp服务器从stdin读取MCP消息并写入stdout。这是MCP客户端集成的标准传输方式。
2.使用HTTP传输运行
safeshell-mcp --transport http默认情况下,侦听打开 127.0.0.1:3456.用覆盖 --bind:
safeshell-mcp --transport http --bind 0.0.0.0:80803.连接MCP客户端
看 MCP客户端集成 下面是Claude Desktop、Claude Code、Cursor和VS Code配置。
工具
SafeShell公开了四种MCP工具:
execute_command
通过安全管道运行shell命令。
参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
command | string | yes | -- | 要运行的命令 |
args | string\[\] | 否 | [] | 命令参数 |
working_directory | string | no | cwd | 命令的工作目录 |
timeout_seconds | integer | 否 | 30 | 最大执行时间(秒) |
例子:
{
"command": "ls",
"args": ["-la", "/tmp"],
"working_directory": "/home/user",
"timeout_seconds": 60
}管道: 命令在执行前经过五个阶段:
- 解析 --对命令进行标记,拆分链(
&&,||,|,;),决心~以及相对路径到绝对路径 - 分类 --将每个子指挥部归类为安全或危险;如果任何一个子命令是危险的,那么整个链条都是危险的
- 位置保护 --检查已解析的路径(包括重定向目标,如
> /etc/shadow)针对受保护的目录;在检查之前规范化对称链接;硬块违规 - 许可门 --对于危险命令,通过MCP引导提示用户批准;如果客户端不支持启发式,则默认为DENY
- 执行 --通过配置的shell运行,强制超时,截断输出到
max_output_bytes,编辑敏感的环境变量值
get_system_path
列出中的所有目录 PATH 环境变量。
退货: path_entries (目录路径数组), os, arch.
list_safe_commands
显示所有预先批准为对当前操作系统安全的命令,以及任何 additional_safe_commands 从配置。
退货: commands (阵列与 name 和 description), additional_safe_commands, os, count.
list_protected_paths
显示当前操作系统上受命令执行保护的所有目录,以及任何 additional_protected_paths 从配置。
退货: paths (阵列与 path, read_allowed, reason), additional_protected_paths, os, count.
安全模型
SafeShell通过多个独立层实现深度防御:
命令分类
每个命令都根据内置的allowlist进行分类。明确列为安全的命令立即执行。其他所有内容,包括未知命令,都被归类为 危险的 并且需要用户批准。
危险命令进一步分为两级:
第1级:灾难性(永远不可列入白名单)
这些命令的破坏性太大,无法自动批准。即使添加到 additional_safe_commands,他们是 被忽视 并记录警告。
| 类别 | 命令 |
|---|---|
| 特权升级 | sudo, su, doas, pkexec, runas |
| 磁盘销毁 | mkfs, dd, shred, fdisk, parted, lvm |
| 系统控制 | shutdown, reboot, halt, poweroff, init |
第2级:可列入白名单的危险
这些是危险但合法的开发工具。它们可以通过以下方式预先批准 additional_safe_commands 在配置或 SAFESHELL_SAFE_COMMANDS env var。当您的MCP客户端不支持启发式时,这很有用。
| 类别 | 命令 |
|---|---|
| 文件操作 | rm, rmdir, chmod, chown, chgrp, truncate |
| 网络命令 | curl, wget, nc, ncat, netcat, ssh, scp, sftp, rsync, ftp |
| 包管理器 | apt, apt-get, yum, dnf, pacman, brew, choco, pip, npm, cargo |
| 系统服务 | systemctl, launchctl, kill, killall, pkill, mount, umount |
| 壳牌口译员 | bash, sh, zsh, fish, csh, tcsh, dash, ksh, python, python3, perl, ruby, node |
当执行列入白名单的Tier 2命令时,工具响应包括一个注释:
⚠️ 通过附加_安全_命令配置预先批准。未请求交互式批准。
当一个未列入白名单的危险命令因无法获取启发而被拒绝时,拒绝消息中会包含如何预先批准它的说明。
对于链式命令(ls | grep foo && rm file),每个子命令都是独立分类的。如果 任何 子命令很危险,整个链都需要批准。审批提示显示每个子命令的分类详细信息。
受保护的路径执行
位置保护会检查所有解析的路径参数(包括重定向目标,如 > /etc/shadow)针对特定于操作系统的受保护目录。
- 安全命令 (只读):允许访问受保护的路径,其中
read_allowed: true(例如。,cat /etc/hosts允许) - 危险指令 (写入):阻止所有受保护的路径,无论
read_allowed - Symlink分辨率:路径通过规范化
fs::canonicalize()在检查之前防止符号链接旁路攻击(例如。,/tmp/link → /etc/shadow) - 空字节注入:路径包含
\0被拒绝 /proc/self/root遍历 (Linux):路径/proc/self/root或 `/proc/
/root` 被阻止以防止chroot逃逸
受保护的路径违规包括 硬封锁 --它们不能被用户批准覆盖。
人在环审批
通过位置保护的危险命令通过MCP呈现给用户 引出用户可以看到完整的命令及其被标记的原因,并且必须明确批准执行。
如果MCP客户端不支持启发式,则命令为 默认拒绝.
输出净化
执行后,stdout和stderr为:
- 截断的 到
max_output_bytes每个流(默认值:100 KB),带有[OUTPUT TRUNCATED]标记 - 已编辑 --与敏感名称模式匹配的环境变量值将替换为
[REDACTED]
内置敏感图案匹配: SECRET, PASSWORD, PASSWD, TOKEN, API_KEY, PRIVATE_KEY, ACCESS_KEY, AUTH, CREDENTIAL, DATABASE_URL, CONNECTION_STRING, SMTP。跳过小于4个字符的值以避免误报。可以通过以下方式添加其他图案 redact_env_patterns 在配置中。
并发控制
信号量将同时执行的命令限制为 max_concurrency (默认值:1)。多余的请求会立即收到错误,而不是排队。
平滑关闭
信号处理程序(Unix上的SIGINT/SIGTERM,Windows上的CTRL_C)触发优雅关机。所有被跟踪的子进程都会在服务器退出之前终止。
配置
SafeShell是通过TOML文件配置的。所有字段都是可选的——适用合理的默认值。
配置文件搜索顺序
| 优先级 | 位置 |
|---|---|
| 1 | 路径输入 $SAFESHELL_CONFIG 环境变量 |
| 2 | ./safeshell.toml (当前工作目录) |
| 3 | ~/.config/safeshell/config.toml |
如果找不到配置文件,则使用所有默认值。
完整配置参考
# Command timeout (seconds)
default_timeout_seconds = 30
# Max output per stream in bytes (stdout/stderr each)
max_output_bytes = 102400
# Max concurrent command executions
max_concurrency = 1
# Additional commands treated as safe (beyond built-in list)
additional_safe_commands = ["make", "just", "nx"]
# Additional regex patterns for env var names to redact
redact_env_patterns = ["(?i)MY_COMPANY_.*"]
# Override shell (auto-detected if unset)
# shell = "/bin/bash"
# HTTP bind address (used with --transport http when --bind is not set)
# http_bind = "127.0.0.1:3456"
# Log level filter (e.g. "debug", "info", "warn", "safeshell_mcp=debug")
# log_level = "info"
# Path to an additional log file (logs always go to stderr too)
# log_file = "/var/log/safeshell.log"
# Additional protected paths
[[additional_protected_paths]]
path = "/data/production"
read_allowed = true
[[additional_protected_paths]]
path = "/secrets"
read_allowed = false配置默认值
| 设置 | 默认值 | 说明 |
|---|---|---|
default_timeout_seconds | 30 | 每个命令的最大执行时间 |
max_output_bytes | 102400 (100 KB) | 截断前每个输出流的最大字节数 |
max_concurrency | 1 | 最大并发命令执行数 |
additional_safe_commands | [] | 视为安全的额外命令(一级灾难性命令,如 sudo, dd, shutdown 不能被覆盖;第2层命令,如 rm, curl, npm 可以被列入白名单) |
additional_protected_paths | [] | 需要保护的额外目录 |
redact_env_patterns | [] | 敏感环境变量名称的额外正则表达式模式 |
shell | 自动检测 | 用于执行的Shell二进制文件 |
http_bind | "127.0.0.1:3456" | HTTP侦听地址(使用时 --transport http) |
log_level | "info" | 日志过滤器(通过 RUST_LOG env或config) |
log_file | none | 日志输出的可选文件路径 |
环境变量
可以通过以下方式覆盖单个配置字段 SAFESHELL_* 环境变量。这些值优先于配置文件值。
| 变量 | 配置字段 | 描述 |
|---|---|---|
SAFESHELL_CONFIG | -- | 配置文件的路径(文件位置的最高优先级) |
SAFESHELL_TIMEOUT | default_timeout_seconds | 命令超时(秒) |
SAFESHELL_MAX_OUTPUT | max_output_bytes | 每个流的最大输出(字节) |
SAFESHELL_MAX_CONCURRENCY | max_concurrency | 最大并发执行数 |
SAFESHELL_SHELL | shell | 外壳二进制路径 |
SAFESHELL_HTTP_BIND | http_bind | HTTP侦听地址 |
SAFESHELL_LOG_LEVEL | log_level | 日志筛选器字符串 |
SAFESHELL_LOG_FILE | log_file | 日志文件路径 |
SAFESHELL_SAFE_COMMANDS | additional_safe_commands | 以逗号分隔的附加安全命令列表(不能覆盖第1级灾难性命令) |
SAFESHELL_REDACT_PATTERNS | redact_env_patterns | 用于环境变量编校的逗号分隔的正则表达式模式列表 |
RUST_LOG | -- | 日志级别筛选器(被覆盖 log_level / SAFESHELL_LOG_LEVEL) |
SHELL (Unix) | -- | 默认shell shell 未设置 |
COMSPEC (Windows) | -- | 默认shell shell 未设置 |
优先: 环境变量>配置文件>默认值。
无效的数值(用于 SAFESHELL_TIMEOUT, SAFESHELL_MAX_OUTPUT, SAFESHELL_MAX_CONCURRENCY)被记录为警告并被忽略。
示例——通过MCP客户端中的环境进行配置:
{
"mcpServers": {
"safeshell": {
"command": "/path/to/safeshell-mcp",
"env": {
"SAFESHELL_TIMEOUT": "120",
"SAFESHELL_SAFE_COMMANDS": "make,just,nx",
"SAFESHELL_LOG_LEVEL": "debug"
}
}
}
}推荐的安全命令配置文件
预定义的 SAFESHELL_SAFE_COMMANDS 常见用例的值。这些白名单中的第2级危险命令适用于每个角色——第1级灾难性命令(sudo, dd, mkfs, shutdown等等)总是被阻止而不管配置如何。
开发者 --构建工具、包管理器、解释器:
SAFESHELL_SAFE_COMMANDS="cargo,npm,pip,python3,node,bash,sh,curl,wget,rm,chmod,kill"# safeshell.toml
additional_safe_commands = ["cargo", "npm", "pip", "python3", "node", "bash", "sh", "curl", "wget", "rm", "chmod", "kill"]DevOps/SRE --开发人员命令和系统管理:
SAFESHELL_SAFE_COMMANDS="cargo,npm,pip,python3,node,bash,sh,curl,wget,rm,chmod,chown,kill,killall,pkill,systemctl,launchctl,mount,umount,apt,apt-get,brew,rsync,ssh,scp"# safeshell.toml
additional_safe_commands = [
"cargo", "npm", "pip", "python3", "node", "bash", "sh",
"curl", "wget", "rm", "chmod", "chown",
"kill", "killall", "pkill", "systemctl", "launchctl",
"mount", "umount", "apt", "apt-get", "brew",
"rsync", "ssh", "scp",
]限制性 --不受信任环境的最小白名单:
SAFESHELL_SAFE_COMMANDS="npm,cargo,pip"# safeshell.toml
additional_safe_commands = ["npm", "cargo", "pip"]推荐的编辑模式
内置的编校模式涵盖了常见的敏感变量名(SECRET, PASSWORD, TOKEN, API_KEY, AUTH等等)。通过添加自定义图案 SAFESHELL_REDACT_PATTERNS 或 redact_env_patterns 根据您组织的命名约定。
常见补充:
SAFESHELL_REDACT_PATTERNS="(?i).*KEY.*,(?i).*TOKEN.*,(?i).*AUTH.*,(?i).*CERT.*,(?i).*SIGNING.*"# safeshell.toml
redact_env_patterns = [
"(?i).*KEY.*", # Matches: AWS_KEY, SIGNING_KEY, MY_API_KEY_V2, etc.
"(?i).*TOKEN.*", # Matches: GITHUB_TOKEN, REFRESH_TOKEN, etc.
"(?i).*AUTH.*", # Matches: OAUTH_SECRET, AUTH_HEADER, etc.
"(?i).*CERT.*", # Matches: TLS_CERT, CLIENT_CERT_PATH, etc.
"(?i).*SIGNING.*", # Matches: SIGNING_SECRET, JWT_SIGNING_KEY, etc.
]企业/法规遵从性繁重的环境:
SAFESHELL_REDACT_PATTERNS="(?i).*KEY.*,(?i).*TOKEN.*,(?i).*AUTH.*,(?i).*CERT.*,(?i).*SIGNING.*,(?i).*ENCRYPT.*,(?i).*PRIVATE.*,(?i).*WEBHOOK.*,(?i).*DSN.*,(?i).*SENTRY.*"外壳自动检测
当 shell 未在配置中设置:
| 平台 | 检测顺序 |
|---|---|
| Unix | $SHELL env 是 → /bin/sh 回退 |
| 窗户 | %COMSPEC% env 是 → cmd.exe 回退 |
外壳标志会自动检测: -c 对于POSIX贝壳和鱼, -Command 对于PowerShell/pwsh, /C 对于cmd.exe。
MCP客户端集成
所有支持的MCP主机的准备复制配置文件都可以在 示例/ 目录。
克劳德桌面版
添加 ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)或 %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"safeshell": {
"command": "/path/to/safeshell-mcp"
}
}
}克劳德代码
添加到您的项目 .mcp.json:
{
"mcpServers": {
"safeshell": {
"command": "/path/to/safeshell-mcp"
}
}
}或者使用HTTP传输:
{
"mcpServers": {
"safeshell": {
"type": "http",
"url": "http://127.0.0.1:3456/mcp"
}
}
}光标
添加 .cursor/mcp.json 在您的项目中:
{
"mcpServers": {
"safeshell": {
"command": "/path/to/safeshell-mcp"
}
}
}VS代码(副本)
添加 .vscode/mcp.json:
{
"servers": {
"safeshell": {
"command": "/path/to/safeshell-mcp"
}
}
}具有自定义配置
通过环境变量指向配置文件:
{
"mcpServers": {
"safeshell": {
"command": "/path/to/safeshell-mcp",
"env": {
"SAFESHELL_CONFIG": "/path/to/safeshell.toml"
}
}
}
}安全命令
内置的安全命令因操作系统而异。使用 list_safe_commands 工具查看您平台的完整列表。
通用安全命令(所有平台): echo, date, whoami, hostname
Unix(macOS+Linux): cat, ls, head, tail, wc, pwd, uname, which, printenv, df, uptime
窗户: dir, type, where, ver, set, cd
默认情况下,不在安全列表上的命令被归类为危险命令,需要用户批准。
许可证
麻省理工学院
