tumf/mcp-shell-server

分类General
作者Community
星标503
定价Free

简介

mcp-shell-server 是一个将终端执行能力赋予 AI 的 MCP 服务端。它打破了 LLM 仅能生成代码的限制,让 AI 能在受控环境下直接运行 Shell 命令并获取实时回显。对于开发者而言,这意味着你不再需要手动复制粘贴命令,AI 即可帮你完成文件管理、系统状态查询或运行脚本等实际操作。它在能力上是对 AI 编码助手的重要补充,上手门槛极低,只需简单配置即可将 IDE 或 AI 客户端转化为具备系统操作权的智能终端。

核心亮点

  • 让 AI 直接执行 Shell 命令并获取实时结果
  • 消除手动复制粘贴,实现从代码生成到运行的闭环
  • 适用于快速文件操作、系统诊断和脚本自动化
  • 轻量级部署,快速集成至支持 MCP 的 AI 客户端

完整文档

MCP Shell Server

![codecov](https://codecov.io/gh/tumf/mcp-shell-server)
![smithery badge](https://smithery.ai/server/mcp-shell-server)

![MseeP.ai Security Assessment Badge](https://mseep.ai/app/tumf-mcp-shell-server)

一个实现了 Model Context Protocol (MCP) 的安全 shell 命令执行服务器。该服务器允许远程执行白名单中的 shell 命令,并支持 stdin 输入。

<a href="https://glama.ai/mcp/servers/rt2d4pbn22"><img width="380" height="200" src="https://glama.ai/mcp/servers/rt2d4pbn22/badge" alt="mcp-shell-server MCP server" /></a>

Features* 基于 Argv 的命令执行:允许的命令通过 subprocess argv 运行,无需经过 shell 字符串解析

  • 标准输入支持:可通过 stdin 向命令传递输入
  • 详尽的输出:返回 stdout、stderr、退出状态和执行时间
  • 安全的管道支持:管道会保留并验证 argv 段,而不是调用 shell
  • 执行限制:强制执行服务端默认超时时间、最大超时时间以及输出字节上限
  • 受限的重定向<>>> 的目标必须留在请求的工作目录内
  • 最小化子进程环境:子进程接收一个精简的白名单环境,而不是继承所有服务端密钥
  • 结构化审计日志:记录成功、拒绝、超时、输出上限和进程错误的结果,并进行脱敏处理

Claude.app 中的 MCP 客户端设置

已发布版本
shell
code ~/Library/Application\ Support/Claude/claude_desktop_config.json

json
{
  "mcpServers": {
    "shell": {
      "command": "uvx",
      "args": [
        "mcp-shell-server"
      ],
      "env": {
        "ALLOW_COMMANDS": "ls,cat,pwd,grep,wc,touch,find"
      }
    },
  }
}
### 本地版本

#### 配置

shell
code ~/Library/Application\ Support/Claude/claude_desktop_config.json

json
{
  "mcpServers": {
    "shell": {
      "command": "uv",
      "args": [
        "--directory",
        ".",
        "run",
        "mcp-shell-server"
      ],
      "env": {
        "ALLOW_COMMANDS": "ls,cat,pwd,grep,wc,touch,find"
      }
    },
  }
}
## 安装

通过 Smithery 安装

要通过 Smithery 自动为 Claude Desktop 安装 Shell Server:

bash
npx -y @smithery/cli install mcp-shell-server --client claude
### 手动安装
bash
pip install mcp-shell-server
## 使用方法

启动服务器
bash
ALLOW_COMMANDS="ls,cat,echo" uvx mcp-shell-server

Or using the alias

ALLOWED_COMMANDS="ls,cat,echo" uvx mcp-shell-server
ALLOW_COMMANDS(或其别名 ALLOWED_COMMANDS)环境变量用于指定允许执行的命令。命令可以用逗号分隔,逗号前后可包含可选空格。

ALLOW_COMMANDSALLOWED_COMMANDS 的有效格式:

bash
ALLOW_COMMANDS="ls,cat,echo"          # Basic format
ALLOWED_COMMANDS="ls ,echo, cat" # With spaces (using alias)
ALLOW_COMMANDS="ls, cat , echo" # Multiple spaces
ALLOW_PATTERNS 可用于定义以逗号分隔的、匹配命令名称的正则表达式。每个模式均采用全匹配语义,因此 ALLOW_PATTERNS="ls" 仅允许命令名称 ls,而不允许 lsofls -la。包含空格或 shell 元字符的模式和命令名称将被拒绝;请勿使用 ALLOW_PATTERNS 来描述 shell 命令字符串或参数级策略。
bash
ALLOW_PATTERNS="python[0-9.]*,node"    # Command-name patterns only
将命令名称加入白名单并不意味着该程序自身的参数级执行特性也处于沙箱中。即使二进制文件被允许,服务器仍会应用默认的参数加固:在创建子进程之前,所有已知的具备执行能力的向量都会被拒绝,例如 find -exec、shell/解释器启动器、awk system()tar --checkpoint-action=execenvxargs、命令包装工具(如 timeout/nice/nohup)、shell 转义工具(如 sed/less/vim/ssh)、常见的替代名称(如 gfind/gawk/gtar)、所有 Git 命令范围的配置覆盖以及持久化的 git config 写入。例如,ALLOW_COMMANDS="git" 并不允许 git -c user.name=Example statusgit -c alias.pwn=!sh -c "touch marker" pwngit config alias.pwn '!sh -c "touch marker"';无论键或值是什么,所有全局的 git -c <name=value>git -c<name=value> 覆盖都会被拒绝。

这种加固是尽力而为的深度防御,而非针对任意不可信命令执行的完整沙箱。对于不可信的客户端或宽泛的命令白名单,请将服务器运行在具有最小权限文件系统和网络访问权限的 OS/容器沙箱中。

子进程环境

命令在隔离的子环境中运行。服务器不会将完整的父进程环境传递给子命令,因此 API 令牌、凭据和 SECRET_TOKEN 等无关变量默认均不存在。默认情况下,子环境仅包含命令执行所需的最小启动键:POSIX 系统上的 PATH,以及适用时的 Windows 进程启动键(COMSPECPATHEXTSYSTEMROOTWINDIR)。

使用 MCP_SHELL_CHILD_ENV_ALLOWLIST 来显式允许从父进程继承或从单条命令的环境覆盖中接受额外的环境变量名称。该白名单以逗号分隔,并使用精确的环境变量名称:

bash
MCP_SHELL_CHILD_ENV_ALLOWLIST="LANG,LC_ALL,MY_TOOL_HOME" \
ALLOW_COMMANDS="printenv,my-tool" \
uvx mcp-shell-server
只有在 MCP_SHELL_CHILD_ENV_ALLOWLIST 中命名的键会被转发。类密钥(Secret-like)的名称在日志中会被防御性处理,除非你有意让子命令读取该密钥,否则不应将其加入白名单。

结构化审计日志

每次命令调用都会发出一个名为 shell_execution_auditmcp-shell-server.audit 日志事件。审计记录涵盖:执行成功、子进程创建前的验证拒绝、超时、输出上限终止,以及包括子进程创建失败在内的进程错误。

审计元数据包括:

  • timestampdurationresult_type
  • 命令名称和脱敏后的 argv
  • 解析后的工作 directory
  • stdin/stdout/stdout append 的重定向标志
  • 提供的脱敏单次调用环境覆盖元数据
  • 生效的 timeoutoutput_limit
  • stdout_bytesstderr_bytes
  • 可用的 return_code
  • 适用的 rejection_reasonerror_type

审计日志特意包含原始的 stdout 或 stderr 正文。包含 SECRETTOKENPASSWORDPASSWDAPI_KEYACCESS_KEYPRIVATE_KEYKEYCREDENTIALAUTH 等标记的类密钥 argv 和环境名称或值会被替换为 [REDACTED]。较长的非数字值将由简短的 SHA-256 摘要代替原始值。

请求格式directory 参数是可选的。如果省略,命令将在 MCP 服务器进程的当前工作目录(server process CWD)中运行。相对 directory 值将基于该服务器进程 CWD 进行解析。此基准目录不是 MCP 客户端的 CWD,而是启动 mcp-shell-server 的进程的工作目录。
python
# Basic command execution in the server process CWD

{ "command": ["ls", "-l"] }

Command with a relative working directory resolved from the server process CWD

{ "command": ["pwd"], "directory": "subproject" }

Command with stdin input

{ "command": ["cat"], "stdin": "Hello, World!" }

Command with timeout

{ "command": ["long-running-process"], "timeout": 30 # Maximum execution time in seconds }

Command with working directory and timeout

{ "command": ["grep", "-r", "pattern"], "directory": "/path/to/search", "timeout": 60 }
### 响应格式

成功响应:

json
{
"stdout": "command output",
"stderr": "",
"status": 0,
"execution_time": 0.123
}
错误响应:
json
{
"error": "Command not allowed: rm",
"status": 1,
"stdout": "",
"stderr": "Command not allowed: rm",
"execution_time": 0
}
## 安全性

该服务器实现了多项安全措施,但它并非 OS 沙箱。虽然命令名称白名单减少了意外暴露,但允许的二进制文件仍可能读取可访问的文件、消耗 CPU 或执行操作系统允许的行为。对于敌对工作负载,请在外部沙箱(如容器、VM 或 OS 策略边界)中运行服务器。1. 命令白名单:仅允许执行明确授权的命令名称或完全匹配 ALLOW_PATTERNS 条目的命令。
2. 默认参数加固:即使命令名称在白名单中,默认也会拒绝已知的可执行向量,例如 shell/解释器、envxargsfind -execawk system()tar --checkpoint-action=exec、Git 外部程序选项,以及所有全局 git -c <name=value>git -c<name=value> 配置覆盖。
3. 禁止 Shell 字符串执行:普通命令和管道通过 asyncio.create_subprocess_exec(*argv) 执行;用户控制的字符串不会传递给 shell。
4. 受限重定向:重定向路径必须相对于 directory;在打开文件前,将拒绝绝对路径、.. 遍历和符号链接逃逸。
5. 环境隔离:子进程接收最小化环境以及 MCP_SHELL_CHILD_ENV_ALLOWLIST 中列出的名称。默认不继承父进程的 token 等机密信息。单次调用中的 envs 值仅在名称被明确列入白名单时才被接受。
6. 执行限制MCP_SHELL_DEFAULT_TIMEOUT_SECONDS 默认为 30 秒,MCP_SHELL_MAX_TIMEOUT_SECONDS 默认为 300 秒,MCP_SHELL_OUTPUT_LIMIT_BYTES 每个捕获的 stdout/stderr 流默认为 1 MiB。客户端超时时间将被限制在服务器最大值之内;未指定超时时间则使用默认值。超时或超过输出上限的进程将在返回明确的超时/输出上限错误前被终止并回收。
7. 审计日志:每次调用都会针对成功、拒绝、超时、输出上限和进程错误结果发送结构化审计元数据。类机密的 argv 值将被脱敏;stdout/stderr 内容不记录在日志中。### 安全相关环境变量

| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| ALLOW_COMMANDS / ALLOWED_COMMANDS | empty | 以逗号分隔的允许执行的命令名称 |
| ALLOW_PATTERNS | empty | 以逗号分隔的正则模式,通过 fullmatch() 与命令名称进行匹配 |
| MCP_SHELL_DEFAULT_TIMEOUT_SECONDS | 30 | 当客户端省略 timeout 时使用的超时时间 |
| MCP_SHELL_MAX_TIMEOUT_SECONDS | 300 | 客户端可设置的最大有效超时时间 |
| MCP_SHELL_OUTPUT_LIMIT_BYTES | 1048576 | 每个进程捕获的 stdout/stderr 最大字节数 |
| MCP_SHELL_CHILD_ENV_ALLOWLIST | empty | 以逗号分隔的允许传递给子进程的父级或单次调用环境变量 |
| MCP_SHELL_SAFE_PATH | /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin | 提供给子进程的 PATH |

开发

设置开发环境

1. Clone 仓库

bash
git clone https://github.com/yourusername/mcp-shell-server.git
cd mcp-shell-server
2. 安装依赖项(包括测试需求)
bash
pip install -e ".[test]"
### 运行测试
bash
pytest
## API 参考

请求参数

| 字段 | 类型 | 必填 | 描述 |
|-----------|------------|----------|-----------------------------------------------|
| command | string[] | 是 | 命令及其参数,以数组元素形式提供 |
| stdin | string | 否 | 传递给命令的输入 |
| directory | string | 否 | 工作目录;若省略则使用服务器进程的 CWD,相对路径将基于该服务器进程 CWD 解析 |
| timeout | integer | 否 | 最大执行时间(秒) |

响应字段

| 字段 | 类型 | 描述 |
|----------------|---------|---------------------------------------------|
| stdout | string | 命令的标准输出 |
| stderr | string | 命令的标准错误输出 |
| status | integer | 退出状态码 |
| execution_time | float | 执行耗时(秒) |
| error | string | 错误消息(仅在失败时出现) |

环境要求

许可证

MIT License - 详情请参阅 LICENSE 文件

查看官方来源