mcp-shell 🐚

by sonirico

94 stars
474 downloads
Not rated
GitHub

About

Execute secure shell commands from AI assistants and other MCP clients, with configurable security settings.

Details

Author
sonirico
GitHub stars
94
Downloads
474
Categories
Developer Tools, Other, Infrastructure, AI

- Executes shell commands as an MCP tool.
- Secure default mode with a strict executable allowlist (read‑only utilities).
- Configurable YAML policy for both secure and legacy shell‑execution modes.
- Docker deployment as a non‑root Alpine image.
- Tool response includes exit code, stdout, stderr, execution time, and security info.
- Audit logging and configurable timeouts and output size limits.

Setting up with Highlight

This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name mcp-shell 🐚
    Command (node, npx, python, etc.)

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository

Run via Docker (docker run -it --rm -v /tmp/mcp-workspace:/tmp/mcp-workspace sonirico/mcp-shell:latest) or from source (git clone, make install, then mcp-shell). Default is secure mode; customize with a YAML config file pointed to by MCP_SHELL_SEC_CONFIG_FILE. Wire into Claude Desktop by adding a shell server entry in its MCP config pointing to the Docker image or binary.

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

{
    "mcpServers": {
        "mcp-shell \ud83d\udc1a": {
            "mcp-shell": {
                "command": "docker",
                "args": [
                    "run",
                    "-it",
                    "--rm",
                    "-v",
                    "/tmp/mcp-workspace:/tmp/mcp-workspace",
                    "sonirico/mcp-shell:latest"
                ]
            }
        }
    }
}

McpServers

{
    "mcp-shell": {
        "command": "docker",
        "args": [
            "run",
            "-it",
            "--rm",
            "-v",
            "/tmp/mcp-workspace:/tmp/mcp-workspace",
            "sonirico/mcp-shell:latest"
        ]
    }
}

mcp-shell

Trust Score
glama

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:latest

From source:

git clone https://github.com/sonirico/mcp-shell && cd mcp-shell
make install
mcp-shell

---

Configure it

Secure mode is the default. With no config file, mcp-shell boots in secure
mode restricted to a narrow allowlist of read-only utilities (ls, cat,
grep, find, head, tail, ...). You only need a config file to widen or
change that policy. To run fully unrestricted you must opt in explicitly:

MCP_SHELL_ALLOW_UNSAFE=true mcp-shell   # disables all validation - do not use in production

To customize the policy, point to a YAML config:

export MCP_SHELL_SEC_CONFIG_FILE=/path/to/security.yaml
mcp-shell

Secure mode (recommended) — no shell interpretation, executable allowlist only:

security:
  enabled: true
  use_shell_execution: false
  allowed_executables:
    - ls
    - cat
    - grep
    - find
    - echo
  # WARNING: never add shell/language interpreters (bash, sh, python, perl,
  # ruby, node) or alias-capable tools (git) here - the interpreter executes
  # whatever it is handed, bypassing secure mode entirely. mcp-shell warns at
  # startup if it finds one.
  blocked_patterns:          # optional: restrict args on allowed commands
    - '(^|\s)remote\s+(-v|--verbose)(\s|$)'
  max_execution_time: 30s
  max_output_size: 1048576
  working_directory: /tmp/mcp-workspace
  audit_log: true

Legacy mode — shell execution, allowlist/blocklist by command string (vulnerable to injection if not careful):

security:
  enabled: true
  use_shell_execution: true
  allowed_commands: [ls, cat, grep, echo]
  blocked_patterns: ['rm\s+-rf', 'sudo\s+']
  max_execution_time: 30s
  audit_log: true

---

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"]
}

---

Tool API

| Parameter | Type | Description |
|-----------|------|-------------|
| command | string | Shell command to run (required) |
| base64 | boolean | Encode stdout/stderr as base64 (default: false) |

Response includes status, exit_code, stdout, stderr, command, execution_time, and optional security_info.

---

Environment variables

| Variable | Description |
|----------|-------------|
| MCP_SHELL_SEC_CONFIG_FILE | Path to security YAML (overrides built-in secure defaults) |
| MCP_SHELL_ALLOW_UNSAFE | Set true to disable all validation and run unrestricted (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 image

---

Security

- Default: Secure mode, restricted to a narrow allowlist of read-only utilities. No interpreters.
- Secure mode (use_shell_execution: false): the command is parsed into a shell AST and only a single, fully-literal simple command is accepted (no pipes, lists, substitution, redirection or globs); its executable must be on the allowlist. Interpreters (bash/sh/python) are hard-denied even if allowlisted, and per-tool policies strip escape hatches (git -c, find -exec, tar --checkpoint-action). This is an early-reject layer, not a sandbox.
- Unrestricted: Only via MCP_SHELL_ALLOW_UNSAFE=true. Full access; 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.

---

Contributing

Fork, branch, make fmt test, open a PR.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.