MCP Connector

Securely Execute Shell Commands for AI

Go MCP server giving an LLM controlled filesystem and Git access via typed tools by default - no raw shell command unless opted in.

Works with githubdocker

88
Spark score
out of 100
Updated 7 days ago
Source checked Sep 15, 2026
Version 1.1.0
Models
universal

Add to Favorites

Why it matters

Bridge AI assistants with your shell environment by providing secure, auditable execution of shell commands. Offers fine-grained control over command execution through allowlists, blocklists, and environment variable configuration.

Outcomes

What it gets done

01

Execute shell commands with customizable security restrictions.

02

Generate structured JSON output including stdout, stderr, and exit codes.

03

Leverage Docker for secure, isolated command execution.

04

Audit all command executions for security and compliance.

Source

Get it from source

Spark does not host a copy of it.

Open source

Reports

Agent outcome reports

No reports yet

Capabilities

Tools your agent gets

shell_command

Executes shell commands with customizable security restrictions, returning structured output with stdout, stderr, and exit codes.

Overview

Shell MCP Server

mcp-shell is a Go MCP server that gives an LLM typed, path-confined tools for reading files and inspecting or modifying a Git repository, with an opt-in unrestricted raw-shell mode for local development. Use it when an LLM needs controlled, auditable filesystem and Git access; avoid the unrestricted shell_exec mode outside local development since it runs arbitrary commands with no validation.

What it does

mcp-shell is an MCP server, written in Go on top of mark3labs/mcp-go, that gives an LLM a controlled way to interact with a filesystem and Git repository. It boots in a secure mode by default that exposes only typed, purpose-built tools - no raw shell command - and can optionally be switched to a fully unrestricted mode that hands the model a single shell_exec tool running bash -c with no validation.

When to use - and when NOT to

Use it when you want an LLM to read files, search code, inspect Git history, or, opt-in, write files and make commits, with every action confined to a configured working_directory and audited. Do not enable MCP_SHELL_ALLOW_UNSAFE=1 outside local development: unrestricted mode removes all validation and path confinement, running arbitrary shell commands built by the model itself.

Capabilities

Secure mode always registers read-only tools - read_file, list_dir, glob, grep, stat, diff_files, system_info - plus read-only Git inspection (git_status, git_log, git_diff, git_show, git_blame, git_branches, git_tags, git_rev_parse, git_ls_files, git_stash_list, git_remotes). Setting writes_enabled: true additionally exposes file and Git write tools (write_file, edit_file, mkdir, move, delete, git_add, git_commit, git_switch, git_restore, git_stash), and a non-empty scripts map in the config exposes operator-defined commands through a single run_script tool whose argv the client cannot alter. Every path parameter is resolved against working_directory with symlinks followed, and anything resolving outside it is rejected; Git paths and refs are passed positionally and validated, with a leading - rejected to prevent flag injection, and Git runs with a minimized, sandboxed environment (GIT_CONFIG_NOSYSTEM=1, neutralized hooks, pager, and fsmonitor). There are no network Git tools - push, fetch, and clone are not offered. Child processes only inherit PATH, HOME, and LANG, never the server's own environment or .env secrets.

How to install

Run it with Docker:

docker run -it --rm -v /tmp/mcp-workspace:/tmp/mcp-workspace sonirico/mcp-shell:latest

Or build from source:

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

To customize the security policy, point MCP_SHELL_SEC_CONFIG_FILE at a YAML file setting working_directory, max_execution_time, max_output_size, audit_log, writes_enabled, and optional scripts. To run fully unrestricted instead, set MCP_SHELL_ALLOW_UNSAFE=1, which disables secure mode entirely and leaves shell_exec as the only registered tool. The Docker image runs as non-root on Alpine and is recommended for production, ideally paired with OS-level sandboxing (read-only filesystem, dropped capabilities) as defense-in-depth.

Who it's for

Teams building coding agents or automation that need an LLM to read code, search a repository, and inspect or make Git commits under a tightly scoped, auditable security policy - without granting it an open shell.

Source README

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 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_exec

To customize the policy, point to a YAML config:

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

Secure 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 image

Security

  • 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.


FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.