Skip to main content

MCP Shell Server

codecov smithery badge

MseeP.ai Security Assessment Badge

A secure shell command execution server implementing the Model Context Protocol (MCP). This server allows remote execution of whitelisted shell commands with support for stdin input.

mcp-shell-server MCP server

Features

  • Argv-based Command Execution: Allowed commands run via subprocess argv without shell-string interpretation
  • Standard Input Support: Pass input to commands via stdin
  • Comprehensive Output: Returns stdout, stderr, exit status, and execution time
  • Safe Pipeline Support: Pipelines preserve and validate argv segments instead of invoking a shell
  • Execution Limits: Server-side default timeout, maximum timeout, and output byte caps are enforced
  • Contained Redirection: <, >, and >> targets must stay inside the requested working directory
  • Minimal Child Environment: Child processes receive a small allowlisted environment instead of inheriting all server secrets
  • Structured Audit Logging: Success, rejection, timeout, output-cap, and process-error outcomes are logged with redaction

MCP client setting in your Claude.app

Published version

code ~/Library/Application\ Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "shell": {
      "command": "uvx",
      "args": [
        "mcp-shell-server"
      ],
      "env": {
        "ALLOW_COMMANDS": "ls,cat,pwd,grep,wc,touch,find"
      }
    },
  }
}

Local version

Configuration

code ~/Library/Application\ Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "shell": {
      "command": "uv",
      "args": [
        "--directory",
        ".",
        "run",
        "mcp-shell-server"
      ],
      "env": {
        "ALLOW_COMMANDS": "ls,cat,pwd,grep,wc,touch,find"
      }
    },
  }
}

Installation

Installing via Smithery

To install Shell Server for Claude Desktop automatically via Smithery:

npx -y @smithery/cli install mcp-shell-server --client claude

Manual Installation

pip install mcp-shell-server

Usage

Starting the Server

ALLOW_COMMANDS="ls,cat,echo" uvx mcp-shell-server
# Or using the alias
ALLOWED_COMMANDS="ls,cat,echo" uvx mcp-shell-server

The ALLOW_COMMANDS (or its alias ALLOWED_COMMANDS ) environment variable specifies which commands are allowed to be executed. Commands can be separated by commas with optional spaces around them.

Valid formats for ALLOW_COMMANDS or ALLOWED_COMMANDS:

ALLOW_COMMANDS="ls,cat,echo"          # Basic format
ALLOWED_COMMANDS="ls ,echo, cat"      # With spaces (using alias)
ALLOW_COMMANDS="ls,  cat  , echo"     # Multiple spaces

ALLOW_PATTERNS can be used for comma-separated regular expressions that match command names. Each pattern is applied with full-match semantics, so ALLOW_PATTERNS="ls" allows only the command name ls and does not allow lsof or ls -la. Patterns and command names containing whitespace or shell metacharacters are rejected; do not use ALLOW_PATTERNS to describe shell command strings or argument-level policies.

ALLOW_PATTERNS="python[0-9.]*,node"    # Command-name patterns only

Allowlisting a command name is not a sandbox for that program's own argument-level execution features. The server applies default argument hardening even when the binary is allowed: known exec-capable vectors such as find -exec, shell/interpreter launchers, awk system(), tar --checkpoint-action=exec, env, xargs, command-wrapper tools such as timeout/nice/nohup, shell-escape tools such as sed/less/vim/ssh, common alternate names such as gfind/gawk/gtar/gsort, GNU sort options that select an external program, output path, external file list, or external temporary directory (--compress-program, -o/--output, --files0-from, and -T/--temporary-directory, including abbreviated and clustered forms such as --co, --o, -ro FILE, and -rT DIR), all Git command-scoped configuration overrides, and persistent git config writes are rejected before subprocess creation. For example, ALLOW_COMMANDS="git" does not permit git -c user.name=Example status, git -c alias.pwn=!sh -c "touch marker" pwn, or git config alias.pwn '!sh -c "touch marker"'; every global git -c <name=value> and git -c<name=value> override is rejected regardless of its key or value.

Write sorted output with the server's contained redirection instead of sort -o: ["sort", "input", ">", "output"] keeps the target inside the requested working directory, while sort -o would write directly to any process-accessible path. Option-like filenames stay usable after the -- delimiter, for example ["sort", "--", "--output=data"].

This hardening is best-effort defense in depth, not a complete sandbox for arbitrary untrusted command execution. For untrusted clients or broad command allowlists, run the server inside an OS/container sandbox with least-privilege filesystem and network access.

Child process environment

Commands run with an isolated child environment. The server does not pass the full parent process environment to child commands, so unrelated variables such as API tokens, credentials, and SECRET_TOKEN are absent by default.

By default the child environment contains only the minimal launch keys needed for command execution: PATH on POSIX systems, plus Windows process-launch keys when applicable (COMSPEC, PATHEXT, SYSTEMROOT, and WINDIR).

Use MCP_SHELL_CHILD_ENV_ALLOWLIST to explicitly allow additional environment variable names to be inherited from the parent process or accepted from per-command environment overrides. The allowlist is comma-separated and uses exact environment variable names:

MCP_SHELL_CHILD_ENV_ALLOWLIST="LANG,LC_ALL,MY_TOOL_HOME" \
ALLOW_COMMANDS="printenv,my-tool" \
uvx mcp-shell-server

Only keys named in MCP_SHELL_CHILD_ENV_ALLOWLIST are forwarded. Secret-like names are treated defensively in logs and should not be allowlisted unless you intentionally want a child command to read that secret.

Structured audit logs

Each command invocation emits one mcp-shell-server.audit log event named shell_execution_audit. Audit records cover successful execution, validation rejection before subprocess creation, timeout, output-cap termination, and process errors including subprocess creation failures.

Audit metadata includes:

  • timestamp, duration, and result_type
  • command name and redacted argv
  • resolved working directory
  • redirection flags for stdin/stdout/stdout append
  • redacted per-call environment override metadata, when supplied
  • effective timeout and output_limit
  • stdout_bytes and stderr_bytes
  • return_code when available
  • rejection_reason or error_type where applicable

Audit logs intentionally do not include raw stdout or stderr bodies. Secret-like argv and environment names or values containing markers such as SECRET, TOKEN, PASSWORD, PASSWD, API_KEY, ACCESS_KEY, PRIVATE_KEY, KEY, CREDENTIAL, or AUTH are replaced with [REDACTED]. Long non-numeric values are represented by a short SHA-256 digest instead of the raw value.

Request Format

The directory argument is optional. If omitted, commands run in the MCP server process current working directory (server process CWD). Relative directory values are resolved from that same server process CWD. This base is not the MCP client CWD; it is the working directory of the process that launched mcp-shell-server.

# Basic command execution in the server process CWD
{
    "command": ["ls", "-l"]
}

# Command with a relative working directory resolved from the server process CWD
{
    "command": ["pwd"],
    "directory": "subproject"
}

# Command with stdin input
{
    "command": ["cat"],
    "stdin": "Hello, World!"
}

# Command with timeout
{
    "command": ["long-running-process"],
    "timeout": 30  # Maximum execution time in seconds
}

# Command with working directory and timeout
{
    "command": ["grep", "-r", "pattern"],
    "directory": "/path/to/search",
    "timeout": 60
}

Response Format

Successful response:

{
    "stdout": "command output",
    "stderr": "",
    "status": 0,
    "execution_time": 0.123
}

Error response:

{
    "error": "Command not allowed: rm",
    "status": 1,
    "stdout": "",
    "stderr": "Command not allowed: rm",
    "execution_time": 0
}

Security

The server implements several security measures, but it is not an OS sandbox. A command-name allowlist reduces accidental exposure, but allowed binaries may still read accessible files, consume CPU, or perform behavior allowed by the operating system. For hostile workloads, run the server inside an external sandbox such as a container, VM, or OS policy boundary.

  1. Command Whitelisting: Only explicitly allowed command names or full-matching ALLOW_PATTERNS entries can be executed.
  2. Default Argument Hardening: Known exec-capable vectors such as shells/interpreters, env, xargs, find -exec, awk system(), tar --checkpoint-action=exec, GNU sort --compress-program/-o/--files0-from/-T, Git external-program options, and every global git -c <name=value> or git -c<name=value> configuration override are rejected by default even when the command name is allowlisted.
  3. No Shell-String Execution: Normal commands and pipelines are executed with asyncio.create_subprocess_exec(*argv); user-controlled strings are not passed to a shell.
  4. Contained Redirection: Redirection paths must be relative to directory; absolute paths, .. traversal, and symlink escapes are rejected before files are opened.
  5. Environment Isolation: Children receive a minimal environment plus names listed in MCP_SHELL_CHILD_ENV_ALLOWLIST. Parent secrets such as tokens are not inherited by default. Per-call envs values are only accepted for explicitly allowlisted names.
  6. Execution Limits: MCP_SHELL_DEFAULT_TIMEOUT_SECONDS defaults to 30 seconds, MCP_SHELL_MAX_TIMEOUT_SECONDS defaults to 300 seconds, and MCP_SHELL_OUTPUT_LIMIT_BYTES defaults to 1 MiB per captured stdout/stderr stream. Client timeouts are clamped to the server maximum; omitted timeouts receive the default. Processes that time out or exceed the output cap are terminated and reaped before an explicit timeout/output-cap error is returned.
  7. Audit Logging: Each invocation emits structured audit metadata for success, rejection, timeout, output cap, and process error outcomes. Secret-like argv values are redacted; stdout/stderr content is not logged.
Variable Default Description
ALLOW_COMMANDS / ALLOWED_COMMANDS empty Comma-separated command names to allow
ALLOW_PATTERNS empty Comma-separated regex patterns matched with fullmatch() against command names
MCP_SHELL_DEFAULT_TIMEOUT_SECONDS 30 Timeout used when the client omits timeout
MCP_SHELL_MAX_TIMEOUT_SECONDS 300 Maximum effective timeout accepted from clients
MCP_SHELL_OUTPUT_LIMIT_BYTES 1048576 Maximum captured stdout/stderr bytes per process
MCP_SHELL_CHILD_ENV_ALLOWLIST empty Comma-separated parent or per-call environment variables allowed in children
MCP_SHELL_SAFE_PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin PATH supplied to children

Development

Setting up Development Environment

  1. Clone the repository
git clone https://github.com/yourusername/mcp-shell-server.git
cd mcp-shell-server
  1. Install dependencies including test requirements
pip install -e ".[test]"

Running Tests

pytest

API Reference

Request Arguments

Field Type Required Description
command string[] Yes Command and its arguments as array elements
stdin string No Input to be passed to the command
directory string No Working directory; omitted uses the server process CWD, and relative paths resolve from that server process CWD
timeout integer No Maximum execution time in seconds

Response Fields

Field Type Description
stdout string Standard output from the command
stderr string Standard error output from the command
status integer Exit status code
execution_time float Time taken to execute (in seconds)
error string Error message (only present if failed)

Requirements

  • Python 3.11 or higher
  • mcp>=1.1.0

License

MIT License - See LICENSE file for details

Metadata

Release files for mcp-shell-server 1.1.12

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mcp-shell-server 1.1.12
File Size Uploaded Provenance
mcp_shell_server-1.1.12.tar.gz 173.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for mcp-shell-server 1.1.12
File Interpreter ABI Platform
mcp_shell_server-1.1.12-py3-none-any.whl Python 3 none any Details

Total release size: 201.7 kB

Release files / mcp_shell_server-1.1.12.tar.gz

Download URL mcp_shell_server-1.1.12.tar.gz
Size 173.3 kB
Tags Source
SHA-256 checksum
How to use checksums
f3ac012d905fe24230f724981ad80afea17006e364d31767cf6603f658a3f331
BLAKE2b-256 checksum
How to use checksums
5a185ea563dcdd61392101d2f35b0599da9eb8532bdde080cd909c7d8d69b379
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / mcp_shell_server-1.1.12-py3-none-any.whl

Download URL mcp_shell_server-1.1.12-py3-none-any.whl
Size 28.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e860e0232b8090a2a2db2f2391a72819ca00132a70dc2a8bf8552627524c5a59
BLAKE2b-256 checksum
How to use checksums
f9d3e135a72d961e103c492ca6228914bba8c84d7413d4d4d59d52bc966e796e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for mcp-shell-server 1.1.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page