Purpose
mcp-shell is an MCP (Model Context Protocol) server that gives AI assistants the ability to perform operations while letting users retain control over "what runs" and "how it runs." It runs shell-command-like operations, but by default it does not provide a raw shell; instead, it exposes typed tools. The project is built on mark3labs/mcp-go and written in Go.
Main capabilities
Safe mode (default): if the server starts without a configuration file, it automatically enters safe mode and only registers typed tools. The argv for each command is constructed by the server itself; the client never provides a shell string. These tools cover file reading, grep / glob, git inspection, as well as file/git writes and operator-defined scripts that require explicit enablement.
Path restrictions: every path argument is resolved based on working_directory (following symlinks), and any path that resolves outside that directory is rejected.
Git hardening: Git paths are passed after --, refs are passed after --end-of-options, and refs beginning with - are rejected. When Git runs, it sets GIT_CONFIG_NOSYSTEM=1, GIT_CONFIG_GLOBAL=/dev/null, and neutralizes core.fsmonitor, core.pager, core.hooksPath, and enables --no-ext-diff --no-textconv on log/diff/show/blame.
Minimal environment: child processes receive only PATH, HOME, and LANG, and do not inherit the server's own environment or secrets from .env.
Writes and scripts require explicit enablement: writes_enabled: true is required to expose file/git write tools; a non-empty scripts mapping is required to expose run_script. Both are disabled by default.
No network tools: push, fetch, and clone are not provided.
Usage
Docker (the simplest option) runs with safe mode as the default. It can be started without a configuration file. To customize policy, point to a YAML configuration file. When integrating with Claude Desktop, add the corresponding entry in the MCP configuration; when using a custom configuration, mount the file and set the corresponding environment variable.
To run completely unrestricted, you must explicitly enable it: set MCP_SHELL_ALLOW_UNSAFE=1. In this case, the only registered tool is shell_exec, which runs commands via bash -c without validation and is suitable only for local development; in other scenarios it is dangerous.
Suitable scenarios
Suitable for development and automation scenarios where you want to give AI controlled file access, code search, git inspection, and similar capabilities while maintaining auditability. The Docker image is based on Alpine and runs as non-root; it is recommended for production, preferably combined with OS-level sandboxing (read-only filesystem, dropped capabilities) as defense in depth.
Limitations
In safe mode there is no raw shell command; only typed tools are available. File/git writes and custom scripts are disabled by default and must be explicitly enabled. There are no network-type tools (push, fetch, clone). When migrating from 0.x, safe mode no longer validates shell_exec command strings, and the configuration file's security: block no longer accepts certain old keys; if the configuration still sets these keys, startup will fail and report the corresponding key names. There is no longer a "legacy mode" or a security-legacy.yaml example. If you need raw shell access, you can only set MCP_SHELL_ALLOW_UNSAFE=1 to get shell_exec, and it is no longer constrained by the security: block. For the threat model, guarantees, and vulnerability reporting scope, see SECURITY.md; read it before submitting an advisory.