shell-mcp
Provides read-only git inspection tools including log, diff, blame, show, and status for exploring repository history and changes.
Enables Notion's MCP connector to interact with a development machine, allowing AI agents in Notion to execute shell commands, read/write files, search code, and manage git repositories remotely.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@shell-mcpsearch for 'TODO' in source files"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 +
/healthendpoint.Two execution modes: restricted (command allowlist, no shell operators) / unrestricted (full shell). Windows: unrestricted mode uses
cmd.exeor 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/ Windowstaskkill /T).Background tasks:
run_command(background="always")for dev servers / builds;task(action="wait"|"output"|"cancel"|"list")to manage.Sync-first by default:
run_commandwaits up toSHELL_MCP_WAIT_SECONDS(30s) then auto-backgrounds. Short commands return results inline.Safe editing:
edit_fileexact replacement + atomic write + unified diff;apply_patchmulti-file atomic;expected_sha256precondition prevents stale-read conflicts (returnsFILE_CHANGEDwithout 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 behindSHELL_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".
Related MCP server: MCP Remote Code
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.batClient 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
Start shell-mcp on your development machine (Windows/macOS/Linux).
Expose via Tailscale (
tailscale serve --bg 8000). The server stays on127.0.0.1— never exposed to the public internet. Tailscale handles TLS and authentication.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.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 viapi_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 settingsThat'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 |
| Execute a shell command. |
| Unified background task lifecycle. |
| Regex search. Structured results: |
| File pattern matching. Sort by |
| Directory listing with optional |
| Read a text file with paging. Returns |
| Batch read up to 20 files. Partial failures don't block other files. |
| Atomic write. Optional |
| Exact string replacement with |
| Multi-file patch ( |
| Change working directory (convenience; prefer per-call |
| Extract code symbols per language (regex-based, shebang-aware). |
| 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 |
|
|
|
|
Configuration
All via environment variables (see .env.example for full list):
Variable | Default | Description |
| (required) | Bearer token for auth |
|
| Bind address |
|
| Bind port |
|
| Working directory |
|
| Full shell vs. allowlist |
|
| Disable write/edit/patch tools |
|
| Default command timeout (seconds) |
|
| Sync-first wait before auto-background |
| (built-in) | Comma-separated command list (restricted mode) |
| (empty) | Comma-separated IP allowlist |
|
| Output/file encoding |
|
| Audit log path |
|
| Max bytes returned per call |
|
| Max lines returned per call |
|
| Hard cap on in-memory output |
|
| Max spilled output files kept |
|
| Expose low-level task/file tools |
|
| Expose git inspection tools |
|
| Enable pi coding agent bridge |
|
| Pi binary/command path |
|
| Extra arguments to pi |
|
| 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 8000Client 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). KeepSHELL_MCP_UNRESTRICTED=false.Tailscale serve forwards real client IPs (
100.x.y.z). Pin them withSHELL_MCP_ALLOWED_IPSfor 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 -vLicense
MIT — see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Scoped, audited SSH exec, sessions, and SFTP on your saved servers without exposing credentials
Remote shell and detached long-running jobs on your own machines — no SSH, open ports or VPN.
Run commands and read/write files on your servers over Termalin's keyless tunnels (hosted MCP).
Develop, manage, and debug Railway projects, services, and deployments from within agents.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables secure remote and local command execution via SSH, with session management and environment variable support.116 npm3MIT
- FlicenseNot gradedqualityDmaintenanceEnables agent-style remote development over SSH with file operations and command execution, exposing native tools for searching, editing, and transferring files on remote machines.1-
- AlicenseAqualityCmaintenanceEnables reading, writing, editing, searching, running commands, transferring files, and using git on a remote Linux server over SSH via MCP tools.223AGPL 3.0
- FlicenseNot gradedqualityCmaintenanceEnables secure remote workspace management over SSH, supporting file operations, shell commands, and profile configuration for agent-safe remote code environments.-