模型上下文协议服务器

mcp-shell是一个容器化的模型上下文协议(MCP)服务器,提供丰富的工具集供LLM调用,支持文档/代码工具、搜索/转换、shell等功能,并运行在用户控制的Docker沙箱中。

  • by gaspardpetit
  • Go
  • 本地部署
  • 更新于
在 GitHub 查看 gaspardpetit/mcp-shell

使用说明

mcp外壳

mcp-shell 是集装箱 模型上下文协议(MCP)服务器 展示LLM可以调用的丰富工具集。它被构建为能够(文档/代码工具、搜索/转换、shell),但包含在您控制的Docker沙箱中。

运输: http (可流式传输,默认)· sse · stdio
预设: minimal · standard · full


概述

  • 目的:让LLM运行命令,检查/转换文件,处理文档(Word/Excel/Power/PDF),并使用常见的CLI(Python、Node.js、Git、jq/yq、ripgrep、ImageMagick、ffmpeg、Tesseract、Pandoc、Poppler、DuckDB CLI等)。
  • 主要工具: shell.exec, python.run, node.run, sh.script.write_and_run,包管理器(apt.install, pip.install, npm.install), git.* (克隆、状态、提交、拉取、推送等), fs.* (列表、统计、读取、写入、搜索、哈希等), archive.*,文本实用程序,如 text.diff 和 text.apply_patch,文档助手,例如 doc.convert, pdf.extract_text, spreadsheet.to_csv, doc.metadata,媒体工具,如 image.convert, video.transcode, ocr.extract,以及网络工具,如 http.request, web.download, web.search,以及 md.fetch,以及处理工具,如 proc.spawn, proc.stdin, proc.wait, proc.kill, proc.list.
  • 依赖项: fs.search 依赖于 rg 二进制(ripgrep);文档工具依赖于 pandoc. 开发依赖关系列在 scripts/deps.txt 并且可以通过以下方式安装 scripts/install-deps.sh.
  • 函数参考:参见 doc/functions.md 支持的功能。
  • 安全模型:执行仅限于容器中的非root用户。您可以控制:
    • 主机装载(只读与读写)。
    • 网络出口(在运行时启用/禁用)。
    • 资源限制(CPU、RAM、pids)。
  • 可审计性:工具调用被JSONL记录到 /logs/mcp-shell.log (当 /logs 已安装)。默认上限:超时60秒;每个流1 MiB(stdout/stderr)。
  • 可观测性:Prometheus指标公开于 GET /metrics.

构建

工具层是预先构建的,并使用 tools- 标签前缀。主要 Dockerfile只是将编译后的服务器添加到这些层之一之上:

# Standard image using the latest tool layer
docker build -t mcp-shell:std \
  --build-arg BASE_IMAGE=ghcr.io/<owner>/mcp-shell:tools-std-latest .

# Light image
docker build -t mcp-shell:mini \
  --build-arg BASE_IMAGE=ghcr.io/<owner>/mcp-shell:tools-light-latest .

# Full image
docker build -t mcp-shell:full \
  --build-arg BASE_IMAGE=ghcr.io/<owner>/mcp-shell:tools-full-latest .

重建底层工具层本身(通常仅在以下情况下需要 工具更改),使用 Dockerfile.tools:

docker build -f Dockerfile.tools -t ghcr.io/<owner>/mcp-shell:tools-std \
  --build-arg PRESET=standard .

可选OCR语言或地区(对 standard/full)申请时 构建工具层:

# Extra OCR languages (English `eng` is always installed)
docker build -f Dockerfile.tools -t ghcr.io/<owner>/mcp-shell:tools-std \
  --build-arg PRESET=standard \
  --build-arg TESS_LANGS_EXTRA="tesseract-ocr-fra tesseract-ocr-deu" .

# Extra locales (English en_US.UTF-8 is always enabled)
docker build -f Dockerfile.tools -t ghcr.io/<owner>/mcp-shell:tools-std \
  --build-arg PRESET=standard \
  --build-arg EXTRA_LOCALES="fr_CA.UTF-8 de_DE.UTF-8" .

跑

A) 服务模式(HTTP,默认)

图像默认为 --transport=http,继续听 ${PORT:-3333} 和服务 /mcp 加 /healthz.

docker run --rm -d --name mcp-shell \
  --user 10001:10001 \
  --read-only \
  --tmpfs /tmp:rw,nosuid,nodev,size=512m \
  --tmpfs /run:rw,nosuid,nodev,size=64m \
  --cap-drop=ALL \
  --security-opt no-new-privileges \
  --pids-limit=2048 \
  --memory=4g --cpus=2 \
  --init \
  -e EGRESS=1 \
  -p 3333:3333 \
  -v "$PWD/workspace":/workspace:rw \
  -v "$PWD/logs":/logs:rw \
  mcp-shell:std

笔记:

  • 将某物装入 /workspace 如果你想 shell.exec 向 ls 真实文件。
  • EGRESS=1 只是为你的服务器/工具设定意图;实际的网络策略取决于你如何运行Docker。
  • 包管理器(apt.install, pip.install, npm.install)被禁用,除非 EGRESS=1 或者服务器以以下方式启动 --allow-pkg.
  • SHELL_EXEC_DENY 和 SHELL_EXEC_ALLOW 可以配置阻止/允许模式 shell.exec。全局并发性的上限为 MAX_CONCURRENCY;每个工具的使用率限制 RATE_LIMIT_<TOOL> 环境变量(默认为5 RPS)。

B) 气隙模式(STDIO)

如果您根本不喜欢网络,请保持容器空闲,并通过stdio启动MCP会话:

# Idle container with no network
docker run -d --name mcp-stdio --rm \
  --user 10001:10001 \
  --read-only \
  --tmpfs /tmp:rw,nosuid,nodev,size=512m \
  --tmpfs /run:rw,nosuid,nodev,size=64m \
  --cap-drop=ALL \
  --security-opt no-new-privileges \
  --pids-limit=2048 \
  --memory=4g --cpus=2 \
  --network=none \
  --init \
  -e EGRESS=0 \
  -v "$PWD/workspace":/workspace:rw \
  -v "$PWD/logs":/logs:rw \
  mcp-shell:std tail -f /dev/null

# Start a one-off MCP stdio session (single client)
docker exec -i mcp-stdio /app/mcp-server --transport=stdio

健康检查

在HTTP模式下,容器公开:

  • GET /healthz (顶级)
  • GET /mcp/health (内置)

Docker HEALTHCHECK 在内部探测这些端点;无需采取任何行动。

快速手动检查:

curl -fsS http://127.0.0.1:3333/healthz | jq

测试(HTTP/可流式传输)

流式HTTP是 基于会话.第一次通话 initialize 获得a Mcp-Session-Id,然后发送 notifications/initialized,并将会话重新用于后续请求。

# 1) Initialize (creates session)
INIT_RES_HEADERS=$(mktemp)
curl -sS -D "$INIT_RES_HEADERS" \
  -H 'content-type: application/json' \
  -H 'accept: application/json' \
  -X POST http://127.0.0.1:3333/mcp/ \
  -d '{
    "jsonrpc":"2.0",
    "id":"1",
    "method":"initialize",
    "params": { "protocolVersion": "2025-06-18", "capabilities": {} }
  }' >/dev/null

# Extract session id from response headers
SID=$(awk -F': ' 'BEGIN{IGNORECASE=1} /^Mcp-Session-Id:/ {print $2}' "$INIT_RES_HEADERS" | tr -d '\r')
echo "Session: $SID"

# 2) Notify ready
curl -sS -H 'content-type: application/json' \
  -H "Mcp-Session-Id: $SID" \
  -X POST http://127.0.0.1:3333/mcp/ \
  -d '{"jsonrpc":"2.0","method":"notifications/initialized"}' >/dev/null

# 3) List tools (expect "shell.exec" and "fs.*" tools)
curl -sS -H 'content-type: application/json' -H "Mcp-Session-Id: $SID" \
  -X POST http://127.0.0.1:3333/mcp/ \
  -d '{"jsonrpc":"2.0","id":"2","method":"tools/list"}' | jq .

# 4) Run a command
curl -sS -H 'content-type: application/json' -H "Mcp-Session-Id: $SID" \
  -X POST http://127.0.0.1:3333/mcp/ \
  -d '{
    "jsonrpc":"2.0","id":"3","method":"tools/call",
    "params":{"name":"shell.exec","arguments":{"cmd":"ls -la","cwd":"/workspace"}}
  }' | jq .

SSE 变体:以开头 --transport=sse,打开事件流(GET /mcp/sse),然后将POST消息发送到 /mcp/message 具有相同的会话id。

标准输入输出 烟雾测试:

docker run -i --rm mcp-shell:std --transport=stdio <<'JSON'
{"jsonrpc":"2.0","id":"1","method":"tools/list"}
{"jsonrpc":"2.0","id":"2","method":"tools/call","params":{"name":"shell.exec","arguments":{"cmd":"ls -la","cwd":"/workspace"}}}
JSON

项目目的

实用 LLM工具箱 MCP服务器:

  • 能力:涵盖90%实际任务的广泛、实用的CLIs和库。
  • 安全:非root用户、只读rootfs选项、最小权限和显式挂载。
  • 可扩展性:根据需要添加新的工具或apt/pip/npm包。

免责声明

使用风险由您自行承担——您可以决定授予哪些挂载、网络和限制。如果启用网络访问,代理可能会访问容器可见的内部主机。将其保存在容器中;除非你真正知道自己在做什么,否则不要直接在主机上运行它。