shell-mcp

shell-mcp

Enables remote shell command execution and file operations with restricted/unrestricted modes, background tasks, safe editing, and code search.

Category
访问服务器

README

shell-mcp

Remote shell + file operations MCP server. Core is pure stdlib (fully unit-testable); only server.py depends on mcp / starlette / uvicorn.

Features

  • Streamable HTTP at /mcp (POST). No long-lived connections, safe behind buffered reverse proxies.
  • Bearer token auth (constant-time compare) + optional IP allowlist + /health endpoint.
  • Two execution modes: restricted (command allowlist, no shell operators) / unrestricted (full shell). Windows: unrestricted mode uses cmd.exe or PowerShell; POSIX: $SHELL -lc.
  • Reliable process execution: stdout+stderr merged in real order; output streamed to temp file (bounded memory, no pipe deadlock); children in their own process group; timeout kills the entire process tree (POSIX killpg / Windows taskkill /T).
  • Background tasks: run_command(background="always") for dev servers / builds; task(action="wait"|"output"|"cancel"|"list") to manage.
  • Sync-first by default: run_command waits up to SHELL_MCP_WAIT_SECONDS (30s) then auto-backgrounds. Short commands return results inline.
  • Safe editing: edit_file exact replacement + atomic write + unified diff; apply_patch multi-file atomic; expected_sha256 precondition prevents stale-read conflicts (returns FILE_CHANGED without touching files).
  • Code search: grep (ripgrep preferred, pure-Python fallback) + glob (sort by path or modified time).
  • Encoding consistency: auto-detect (UTF-8 / Windows code pages / GB18030), preserve original encoding on write.
  • Output governance: line+byte caps, tail truncation, full output spilled to OS temp dir (shell-mcp-spool/), auto-pruned.
  • Machine-readable errors: all failures return code (e.g. OLD_TEXT_NOT_FOUND, FILE_NOT_FOUND) + structured fields.
  • Audit log: JSON lines, auto-rotated.
  • Git inspection: git_log/diff/blame/show/status — all read-only, gated behind SHELL_MCP_EXPOSE_GIT=true.
  • Pi bridge: dispatch prompts to the pi coding agent with session continuity. Gated behind SHELL_MCP_PI_ENABLED=true.
  • Cross-platform: Windows / macOS / Linux. Platform-specific code gated behind os.name == "nt".

Quick Start

pip install -r requirements.txt
cp .env.example .env   # fill SHELL_MCP_TOKEN (openssl rand -hex 32)
# macOS / Linux:
./run.sh
# Windows:
run.bat

Client config (Streamable HTTP):

{
  "url": "http://127.0.0.1:8000/mcp",
  "headers": { "Authorization": "Bearer <SHELL_MCP_TOKEN>" }
}

Print a ready-to-paste client snippet (with real token + auto-detected Tailscale URL):

python -m shell_mcp.server --print-client

Real-World Stack: Notion + shell-mcp + pi + Tailscale

This project is commonly used as the backend of a four-layer AI coding stack:

┌─────────────────────────────────────┐
│  Notion                             │  ← You write prompts here
│  (MCP connector → AI agent)         │
├─────────────────────────────────────┤
│  shell-mcp (this server)            │  ← Executes commands, reads/writes files
├─────────────────────────────────────┤
│  pi (coding agent, optional)        │  ← Handles complex multi-step tasks
├─────────────────────────────────────┤
│  Tailscale (secure tunnel)          │  ← Connects everything remotely
└─────────────────────────────────────┘

How it works

  1. Start shell-mcp on your development machine (Windows/macOS/Linux).
  2. Expose via Tailscale (tailscale serve --bg 8000). The server stays on 127.0.0.1 — never exposed to the public internet. Tailscale handles TLS and authentication.
  3. Configure Notion's MCP connector to point at your Tailscale URL (https://<machine>.<tailnet>.ts.net/mcp). Notion passes your prompts to an AI model (e.g. Claude), which calls shell-mcp's tools to read files, run commands, search code, and make edits — all on your machine.
  4. Enable pi bridge (optional, SHELL_MCP_PI_ENABLED=true) for complex coding tasks. When the AI at the Notion layer decides a task is too large for one-shot tools, it dispatches the prompt to pi via pi_run. Pi handles multi-step reasoning, file editing, and debugging autonomously, and returns the result.

Why this works

Layer Role Why it matters
Notion Prompt interface Your existing Notion workspace becomes an AI coding environment. No separate chat app.
shell-mcp Execution runtime File read/write, shell commands, code search, git inspection — all the tools an AI needs to work on a real codebase.
pi Autonomous agent Handles complex multi-step tasks that require planning, iteration, and debugging. Session continuity across calls.
Tailscale Secure transport Zero-config VPN. No open ports, no public IPs, no firewall rules. Works across NAT, on any network.

Quick setup

# 1. Server (your dev machine)
git clone https://github.com/takereshui/shell-mcp.git
cd shell-mcp
pip install -r requirements.txt
cp .env.example .env
# Edit .env: set SHELL_MCP_TOKEN, optionally SHELL_MCP_PI_ENABLED=true

# 2. Start
./run.sh  # or run.bat on Windows

# 3. Expose via Tailscale
tailscale serve --bg 8000

# 4. Print client config (includes Tailscale URL + token)
python -m shell_mcp.server --print-client

# 5. Copy the JSON into Notion's MCP connector settings

That's it. Your Notion workspace can now read, edit, test, and debug code on your machine — remotely, securely, with AI assistance at every step.

Tools

Default surface (13 tools):

Tool Description
run_command Execute a shell command. background="auto" (default): sync-first, auto-backgrounds after wait_seconds. Optional cwd, timeout, detail level.
task Unified background task lifecycle. action: wait / output / cancel / list.
grep Regex search. Structured results: [{path, line, text}]. Ripgrep preferred, pure-Python fallback.
glob File pattern matching. Sort by path (stable) or modified (newest first).
list_dir Directory listing with optional depth recursion.
read_file Read a text file with paging. Returns sha256 + next_start_line. Images (png/jpeg/gif/webp) returned as image content.
read_files Batch read up to 20 files. Partial failures don't block other files.
write_file Atomic write. Optional expected_sha256 precondition. append mode supported.
edit_file Exact string replacement with {old, new, replace_all?}. Returns unified diff.
apply_patch Multi-file patch (*** Begin Patch envelope): add / update / delete / move. All-or-nothing.
set_workdir Change working directory (convenience; prefer per-call cwd).
outline Extract code symbols per language (regex-based, shebang-aware).
review_file One-shot audit: read file + recent commits + diff (parallel via anyio).

Low-level tools (task_output, kill_task, list_tasks, delete_file, make_dir, rename_file) hidden by default; enable with SHELL_MCP_EXPOSE_LOWLEVEL=true.

Gated tools:

Gate Tools
SHELL_MCP_EXPOSE_GIT=true git_log — commit log with path filter, git_diff — working tree/staged diff, git_blame — line annotations, git_show — commit details, git_status — working tree status
SHELL_MCP_PI_ENABLED=true pi_run — dispatch prompt to pi (sync-first, auto-session), pi_status — check running task, pi_cancel — kill running task

Configuration

All via environment variables (see .env.example for full list):

Variable Default Description
SHELL_MCP_TOKEN (required) Bearer token for auth
SHELL_MCP_HOST 127.0.0.1 Bind address
SHELL_MCP_PORT 8000 Bind port
SHELL_MCP_WORKDIR ./default Working directory
SHELL_MCP_UNRESTRICTED false Full shell vs. allowlist
SHELL_MCP_READONLY true Disable write/edit/patch tools
SHELL_MCP_TIMEOUT 120 Default command timeout (seconds)
SHELL_MCP_WAIT_SECONDS 30 Sync-first wait before auto-background
SHELL_MCP_ALLOWLIST (built-in) Comma-separated command list (restricted mode)
SHELL_MCP_ALLOWED_IPS (empty) Comma-separated IP allowlist
SHELL_MCP_ENCODING auto Output/file encoding
SHELL_MCP_LOG shell-mcp-audit.log Audit log path
SHELL_MCP_MAX_OUTPUT 51200 Max bytes returned per call
SHELL_MCP_MAX_LINES 2000 Max lines returned per call
SHELL_MCP_MAX_CAPTURE 5242880 Hard cap on in-memory output
SHELL_MCP_SPOOL_MAX_FILES 50 Max spilled output files kept
SHELL_MCP_EXPOSE_LOWLEVEL false Expose low-level task/file tools
SHELL_MCP_EXPOSE_GIT false Expose git inspection tools
SHELL_MCP_PI_ENABLED false Enable pi coding agent bridge
SHELL_MCP_PI_COMMAND pi Pi binary/command path
SHELL_MCP_PI_ARGS "" Extra arguments to pi
SHELL_MCP_PI_WAIT_SECONDS 120 Default wait for pi_run

Exposing via Tailscale

Keep SHELL_MCP_HOST=127.0.0.1 (never bind to public interfaces). Let tailscaled handle TLS:

# Tailnet-only (auto-HTTPS):
tailscale serve --bg 8000

# Public internet (Funnel; requires Funnel enabled in admin console):
tailscale funnel --bg 8000

# Check status / stop:
tailscale serve status
tailscale funnel --bg off 8000

Client URL: https://<machine>.<tailnet>.ts.net/mcp

Security notes:

  • Funnel = anyone on the internet can reach this port. Use a long random token (openssl rand -hex 32). Keep SHELL_MCP_UNRESTRICTED=false.
  • Tailscale serve forwards real client IPs (100.x.y.z). Pin them with SHELL_MCP_ALLOWED_IPS for token+IP dual defense (tailnet only; don't use with Funnel).
  • Funnel only supports ports 443/8443/10000 for HTTPS. TLS terminated by Tailscale.
  • Audit log records commands and paths. Restrict file permissions on the log.

Architecture

shell_mcp/
├── config.py          # env → Config; SessionState
├── errors.py          # ToolFailure → MCP isError
├── paths.py           # Path resolution + sandbox enforcement
├── encoding.py        # Auto-detect encoding (UTF-8 / Windows / GB18030)
├── output.py          # Line+byte truncation, spool spill, pruning
├── process.py         # Command parse/execute: merged output, file capture, tree kill
├── tasks.py           # Background task registry
├── mutation_queue.py  # Per-path serialized write queue
├── editing.py         # Transactional edits: validate → atomic write → diff
├── audit.py           # JSON lines audit log
├── tools/
│   ├── shell.py       # run_command / task
│   ├── files.py       # File tools (read/write/edit/patch)
│   ├── search.py      # grep / glob
│   ├── audit.py       # outline / review_file / git_* tools
│   └── pi.py          # pi_run/status/cancel (gated)
└── server.py          # FastMCP + auth middleware (only third-party deps)

spool:// Resources

Truncated command output and background task logs are served as spool://<name> MCP resources. Tool results include full_output_resource / log_resource fields. Files live in the OS temp directory (shell-mcp-spool/) and are auto-pruned.

Design: Stale-Read Protection

read_file(path) → {text, sha256}
write_file(path, content, expected_sha256=<from read>)
→ server re-reads file, computes sha256(disk)
→ match? write. mismatch? FILE_CHANGED (file untouched)

No server-side cache. The SHA256 is computed from disk at read time and re-verified at write time. This is optimistic concurrency (ETag/If-Match pattern), not a cache.

Tests

Core is dependency-free; run directly:

python3 -m unittest discover -s tests -v

License

MIT — see LICENSE.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选