loading…
Search for a command to run...
loading…
Enables secure execution of shell commands via MCP with multiple security layers including command whitelisting and directory restrictions.
Enables secure execution of shell commands via MCP with multiple security layers including command whitelisting and directory restrictions.
A super-secure MCP (Model Context Protocol) server for running shell commands safely with a local LLM client.
Commands pass through 8 independent security layers — every one must pass:
| Layer | What it does |
|---|---|
| 1 | Zod schema validation — strict type checks before any processing |
| 2 | No-shell spawn — execFile with shell: false, no /bin/sh -c "..." ever |
| 3 | Hardcoded blocklist — rm, sudo, dd, curl, brew, docker, etc. permanently blocked |
| 4 | Argument inspection — rejects metacharacters, null bytes, suspicious patterns, per-command dangerous flags |
| 5 | Directory allowlist — every path must be inside --allow-dir |
| 6 | Symlink resolution — symlinks resolved before path check (no escape via symlink) |
| 7 | Resource limits — timeout, output size cap, concurrency limit |
| 8 | Sanitized environment — strips AWS_*, *_TOKEN, *_SECRET, all cloud provider secrets |
# Clone and build
git clone https://github.com/your-username/shell-mcp.git
cd shell-mcp
npm install
npm run build
# Run (must specify at least one --allow-dir)
node dist/index.js --allow-dir ~/projects --allow-dir ~/data
{
"shell-mcp": {
"command": "node",
"args": [
"/path/to/shell-mcp/dist/index.js",
"--allow-dir", "/home/user/projects",
"--allow-dir", "/home/user/data",
"--allow-cmd", "ls",
"--allow-cmd", "cat",
"--allow-cmd", "grep",
"--allow-cmd", "find",
"--allow-cmd", "python3",
"--timeout", "30",
"--log-file", "/home/user/.shell-mcp/audit.log"
]
}
}
| Flag | Description | Default |
|---|---|---|
--allow-dir <path> |
Permitted directory (required, repeatable) | none — server won't start |
--allow-cmd <cmd> |
Whitelist specific commands (repeatable) | all non-blocked |
--block-cmd <cmd> |
Extra commands to block | — |
--timeout <secs> |
Max execution time (1–300) | 30 |
--max-output <bytes> |
Max output size | 1048576 (1MB) |
--max-concurrent <n> |
Max parallel commands (1–10) | 3 |
--log-file <path> |
Audit log file path | stderr only |
--enable-write |
Enable write_file tool |
off |
--allow-overwrite |
Permit overwriting files | off |
--read-only-mode |
Disables all writes (overrides --enable-write) |
off |
--allow-network-cmds |
Unblock curl, wget, nc | off |
--allow-env-passthrough |
Forward full env to child processes | off (sanitized) |
run_commandRun a command with explicit arguments array. No shell — pipes and redirects won't work.
{
"command": "grep",
"args": ["-r", "TODO", "/home/user/projects/myapp"],
"cwd": "/home/user/projects/myapp",
"timeout": 10
}
read_fileRead a file's contents. Supports line ranges and binary (base64) output.
{
"path": "/home/user/projects/myapp/src/main.py",
"startLine": 1,
"endLine": 50
}
list_directoryList a directory with tree view, sizes, and permissions.
{
"path": "/home/user/projects/myapp",
"recursive": true
}
write_file (requires --enable-write)Write a file. Won't overwrite without --allow-overwrite.
{
"path": "/home/user/projects/myapp/notes.txt",
"content": "Hello world"
}
get_server_infoReturns current server config and restrictions. Useful for the LLM to understand its sandbox before acting.
These cannot be enabled by any flag:
rm, rmdir, shred, dd, mkfs, fdisk, diskutil, sudo, su, doas,
osascript, defaults, open, launchctl, crontab,
curl, wget, nc, ssh, scp, rsync,
brew, npm, yarn, pip, gem, cargo, docker,
gcc, clang, kill, killall, shutdown, reboot,
gpg, security (macOS keychain), ...and more
Every command attempt (allowed or denied) is logged in JSON:
{"timestamp":"2024-01-01T12:00:00.000Z","sessionId":"A3F9B2C1","event":"COMMAND_DENY","command":"rm","args":["-rf","/"],"denyLayer":3,"denyReason":"Command \"rm\" is on the hardcoded blocklist"}
{"timestamp":"2024-01-01T12:00:01.000Z","sessionId":"A3F9B2C1","event":"COMMAND_ALLOW","command":"ls","args":["-la"],"cwd":"/home/user/projects","exitCode":0,"durationMs":12,"outputBytes":1024}
npx @modelcontextprotocol/inspector node dist/index.js --allow-dir /tmp/test
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"shell-mcp": {
"command": "npx",
"args": []
}
}
}