mcp-shell
Give hands to AI. MCP server to run shell commands securely, auditably, and on demand.
Documentation
mcp-shell
MCP server that runs shell commands. Your LLM gets a tool; you get control over what runs and how.
Built on mark3labs/mcp-go. Written in Go.
Run it
Docker (easiest):
docker run -it --rm -v /tmp/mcp-workspace:/tmp/mcp-workspace sonirico/mcp-shell:latestFrom source:
git clone https://github.com/sonirico/mcp-shell && cd mcp-shell
make install
mcp-shellConfigure it
Secure mode is the default. With no config file, `mcp-shell` boots in secure
mode and registers only typed tools: file reads, `grep`/`glob`, git inspection,
and (opt-in) file/git writes and operator-defined scripts. There is no raw
shell command. You only need a config file to change the defaults below. To
run fully unrestricted you must opt in explicitly:
MCP_SHELL_ALLOW_UNSAFE=1 mcp-shell # disables secure mode; the only tool is shell_execTo customize the policy, point to a YAML config:
export MCP_SHELL_SEC_CONFIG_FILE=/path/to/security.yaml
mcp-shellSecure mode (default) — typed tools only, every path confined to `working_directory`:
security:
enabled: true
working_directory: /tmp/mcp-workspace
max_execution_time: 30s
max_output_size: 1048576
run_as_user: ""
audit_log: true
# Expose file and git write tools (write_file, edit_file, mkdir, move,
# delete, git_add, git_commit, git_switch, git_restore, git_stash). Off by
# default.
writes_enabled: false
# Operator-defined scripts exposed through the run_script tool. The client
# picks a name; the argv is yours and cannot be altered.
# scripts:
# test: ["go", "test", "./..."]
# lint: ["golangci-lint", "run"]Wire it up
Claude Desktop — add to your MCP config:
{
"mcpServers": {
"shell": {
"command": "docker",
"args": ["run", "--rm", "-i", "sonirico/mcp-shell:latest"],
"env": { "MCP_SHELL_LOG_LEVEL": "info" }
}
}
}For custom config, mount the file and set the env:
{
"command": "docker",
"args": ["run", "--rm", "-i", "-v", "/path/to/security.yaml:/etc/mcp-shell/security.yaml", "-e", "MCP_SHELL_SEC_CONFIG_FILE=/etc/mcp-shell/security.yaml", "sonirico/mcp-shell:latest"]
}Tools
Secure mode (the default) registers these typed tools. `*` marks a required
parameter.
| Tool | Parameters | Available |
|---|---|---|
| `read_file` | path*, offset, limit, tail | always |
| `list_dir` | path, depth, include_hidden | always |
| `glob` | pattern*, path, newer_than, max_results | always |
| `grep` | pattern*, path, glob, ignore_case, context, files_only, count, max_results | always |
| `stat` | path* | always |
| `diff_files` | path_a*, path_b* | always |
| `system_info` | always | |
| `git_status` | always | |
| `git_log` | max_count, ref, path, author, grep, since, until, oneline, follow | always |
| `git_diff` | ref, ref_to, staged, path, stat_only, name_only | always |
| `git_show` | ref, path, stat_only | always |
| `git_blame` | path*, ref, line_start, line_end | always |
| `git_branches` | all, merged | always |
| `git_tags` | pattern | always |
| `git_rev_parse` | ref* | always |
| `git_ls_files` | path, untracked | always |
| `git_stash_list` | always | |
| `git_remotes` | always | |
| `write_file` | path*, content*, append | writes_enabled |
| `edit_file` | path*, old_string*, new_string*, replace_all | writes_enabled |
| `mkdir` | path* | writes_enabled |
| `move` | from*, to* | writes_enabled |
| `delete` | path*, recursive | writes_enabled |
| `git_add` | paths, all | writes_enabled |
| `git_commit` | message*, all | writes_enabled |
| `git_switch` | branch*, create | writes_enabled |
| `git_restore` | paths*, staged | writes_enabled |
| `git_stash` | action*, message | writes_enabled |
| `run_script` | name* | scripts |
Every path parameter is resolved against `working_directory` (symlinks
followed); anything outside it is rejected. Git paths and refs are passed
positionally and validated: a ref starting with `-` is rejected. There are no
network tools; push, fetch and clone are not offered.
Unrestricted mode: `shell_exec` exists only with `MCP_SHELL_ALLOW_UNSAFE=1`, runs the command through `bash -c` with no validation, by design, and it is the only tool registered in that mode.
Environment variables
| Variable | Description |
|---|---|
| `MCP_SHELL_SEC_CONFIG_FILE` | Path to security YAML (overrides built-in secure defaults) |
| `MCP_SHELL_ALLOW_UNSAFE` | Set `1` (or `true`) to disable secure mode and expose `shell_exec` instead of the typed tools (opt-in) |
| `MCP_SHELL_SERVER_NAME` | Server name (default: "mcp-shell 🐚") |
| `MCP_SHELL_LOG_LEVEL` | debug, info, warn, error, fatal |
| `MCP_SHELL_LOG_FORMAT` | json, console |
| `MCP_SHELL_LOG_OUTPUT` | stdout, stderr, file |
Development
make install dev-tools # deps + goimports, golines
make fmt test lint
make docker-build # build image locally
make release # binary + docker imageSecurity
- Default: Secure mode. The server builds every command's argv itself; the
client never supplies a shell string. Only typed tools are registered.
- Path confinement: every path parameter is resolved against
`working_directory`, symlinks followed, and anything that resolves outside
it is rejected.
- Git hardening: paths are passed after `--`, refs after
`--end-of-options`, and a ref starting with `-` is rejected. Git runs with
`GIT_CONFIG_NOSYSTEM=1`, `GIT_CONFIG_GLOBAL=/dev/null`, `core.fsmonitor`,
`core.pager` and `core.hooksPath` neutralised, and `--no-ext-diff
--no-textconv` on log/diff/show/blame.
- Minimal environment: child processes get only `PATH`, `HOME` and `LANG`,
never the server's own environment or `.env` secrets.
- Writes and scripts are opt-in: `writes_enabled: true` exposes the
file/git write tools; a non-empty `scripts` map exposes `run_script`. Both
are off by default.
- Unrestricted: only via `MCP_SHELL_ALLOW_UNSAFE=1`. The only tool
registered is `shell_exec`, which runs `bash -c` with no validation. Fine
for local dev, dangerous otherwise.
- Docker: Runs as non-root, Alpine-based. Use it in production. Best paired with an OS sandbox (read-only FS, dropped caps) as defense-in-depth.
Threat model, guarantees, and the scope for vulnerability reports live in SECURITY.md. Read it before opening an advisory.
Migrating from 0.x
Secure mode no longer validates a `shell_exec` command string; it exposes
typed tools instead. A config file's `security:` block no longer accepts:
| Removed key | Replacement |
|---|---|
| `use_shell_execution` | not needed; typed tools never shell out |
| `allowed_executables` | not needed; each tool runs a fixed, server-built argv |
| `allowed_commands` | not needed; same as above |
| `blocked_commands` | not needed; same as above |
| `blocked_patterns` | not needed; same as above |
Loading a config file that still sets one of these fails at startup with an
error naming the key. There is no more "legacy mode" and no
`security-legacy.yaml` example. If you need raw shell access, set
`MCP_SHELL_ALLOW_UNSAFE=1` to get `shell_exec` back; it is no longer
constrained by the `security:` block at all.
Contributing
Fork, branch, `make fmt test`, open a PR.
Frequently asked questions
What is mcp-shell?
mcp-shell is Give hands to AI. MCP server to run shell commands securely, auditably, and on demand.
How do I install mcp-shell?
Open the GitHub repository and follow its README. Most MCP servers are added to your client's MCP config, then called by your agent.
Is mcp-shell open source?
Yes — it is hosted on GitHub at https://github.com/sonirico/mcp-shell and has 102 stars.
Related MCP tools
mcp-language-server gives MCP enabled clients access semantic tools like get definition, references, rename, and diagnostics.
Query anything (GitHub, Notion, +40 more) with SQL and let LLMs (ChatGPT, Claude) connect to using MCP Go-based implementation. Trusted by 1300+ developers.
Unity MCP acts as a bridge between AI assistants and your Unity Editor. Give your LLM tools to manage assets, control scenes, edit scripts, and automate tasks within Unity.
AI Skills, MCP Tools, and CLI for Unity Engine. Full AI develop and test loop. Use cli for quick setup. Efficient token usage, advanced tools. Any C# method may be turned into a tool by a single line. Works with Claude Code, Gemini, Copilot, Cursor and any other absolutely for free.
AI-powered OSINT agent with interactive REPL, MCP server, and CLI. 19 tools. Works with Claude, GPT-4, or local models. For authorized security research only.
A desktop MCP client designed as a tool unitary utility integration, accelerating AI adoption through the Model Context Protocol (MCP) and enabling cross-vendor LLM API orchestration.
Run your own MCP server? See who uses it and what to fix.
Measure it with TrackMCP