mcp-shell-server
The mcp-shell-server is a secure shell command execution server that allows:
Execute Whitelisted Commands: Run specific commands (
ls,cat,grep,find,echo,pwd,wc,touch) securely, configurable via environment variables.Input via stdin: Pass input to commands through standard input.
Set Working Directory: Specify a directory for command execution.
Control Execution Time: Define a timeout to limit command execution duration.
Secure Execution: Prevent shell injection by validating commands against the whitelist.
Detailed Output: Receive stdout, stderr, exit status, and execution time for each command.
Code coverage reporting integration shown by the codecov badge in the README header, displaying test coverage metrics for the project.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-shell-serverlist files in the current directory with details"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Shell Server
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.
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 directoryMinimal 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
Related MCP server: Shell MCP Server
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 claudeManual Installation
pip install mcp-shell-serverUsage
Starting the Server
ALLOW_COMMANDS="ls,cat,echo" uvx mcp-shell-server
# Or using the alias
ALLOWED_COMMANDS="ls,cat,echo" uvx mcp-shell-serverThe 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 spacesALLOW_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 onlyAllowlisting 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-serverOnly 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, andresult_typecommand name and redacted
argvresolved working
directoryredirection flags for stdin/stdout/stdout append
redacted per-call environment override metadata, when supplied
effective
timeoutandoutput_limitstdout_bytesandstderr_bytesreturn_codewhen availablerejection_reasonorerror_typewhere 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.
Command Whitelisting: Only explicitly allowed command names or full-matching
ALLOW_PATTERNSentries can be executed.Default Argument Hardening: Known exec-capable vectors such as shells/interpreters,
env,xargs,find -exec,awk system(),tar --checkpoint-action=exec, GNUsort --compress-program/-o/--files0-from/-T, Git external-program options, and every globalgit -c <name=value>orgit -c<name=value>configuration override are rejected by default even when the command name is allowlisted.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.Contained Redirection: Redirection paths must be relative to
directory; absolute paths,..traversal, and symlink escapes are rejected before files are opened.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-callenvsvalues are only accepted for explicitly allowlisted names.Execution Limits:
MCP_SHELL_DEFAULT_TIMEOUT_SECONDSdefaults to 30 seconds,MCP_SHELL_MAX_TIMEOUT_SECONDSdefaults to 300 seconds, andMCP_SHELL_OUTPUT_LIMIT_BYTESdefaults 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.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.
Security-related environment variables
Variable | Default | Description |
| empty | Comma-separated command names to allow |
| empty | Comma-separated regex patterns matched with |
|
| Timeout used when the client omits |
|
| Maximum effective timeout accepted from clients |
|
| Maximum captured stdout/stderr bytes per process |
| empty | Comma-separated parent or per-call environment variables allowed in children |
|
| PATH supplied to children |
Development
Setting up Development Environment
Clone the repository
git clone https://github.com/yourusername/mcp-shell-server.git
cd mcp-shell-serverInstall dependencies including test requirements
pip install -e ".[test]"Running Tests
pytestAPI 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
Available Tools
1 toolshell_executeA
Execute a shell command Allowed commands: pwd, grep, cat, ls, wc Allowed patterns: Default timeout: 30s; maximum timeout: 300s; output cap: 1048576 bytes
| Name | Required | Description | Default |
|---|---|---|---|
| stdin | No | Input to be passed to the command via stdin | |
| command | Yes | Command and its arguments as array | |
| timeout | No | Maximum execution time in seconds; clamped to server maximum | |
| directory | No | Optional working directory. Omit to use the MCP server process current working directory; relative paths are resolved from that same server process CWD. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses the allowed commands, default/maximum timeout, and output cap, providing useful behavioral context. However, it omits details about stderr handling, output truncation behavior, or the fact that all allowed commands are read-only, preventing a perfect score.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is brief and front-loaded with the primary action, followed by key constraints. However, the 'Allowed patterns: ' line is empty and incomplete, which introduces a minor structural flaw and reduces clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description captures the essential constraints (allowed commands, timeout, output cap) and parameter semantics are handled by the schema. Yet it does not describe the return format, stderr handling, or exit code behavior, and the incomplete 'Allowed patterns' field leaves a gap in coverage for a shell execution tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides complete descriptions for all four parameters (100% coverage), so the baseline is 3. The description adds marginal value by mentioning the default timeout (30s) and maximum timeout (300s), which aligns with the 'timeout' parameter but does not elaborate on other parameters beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Execute a shell command' and lists the allowed commands (pwd, grep, cat, ls, wc), making the tool's purpose specific and unambiguous. Even without siblings, the allowed-command list defines scope clearly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description communicates constraints via 'Allowed commands' and 'Allowed patterns', indicating when the tool is appropriate. However, it does not explicitly state when to use this tool versus alternatives (there are none listed) or provide a 'when not to use' guideline, leaving usage context somewhat implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
1 tool update
v1.1.0- Changed
shell_execute4 fields changed- changed
Input schema / properties / directory / descriptionPrevious value: -"Absolute path to a working directory where the command will be executed"New value: +"Optional working directory. Omit to use the MCP server process current working directory; relative paths are resolved from that same server process CWD." - changed
Input schema / properties / timeout / descriptionPrevious value: -"Maximum execution time in seconds"New value: +"Maximum execution time in seconds; clamped to server maximum" - changed
Input schema / properties / timeout / minimumPrevious value: -0New value: +1 - changed
Input schema / requiredPrevious value: -[ - "command", - "directory" -]New value: +[ + "command" +]
1 tool update
- First observed
shell_execute
TDQS
Only one tool exists, so there is no possibility of confusion or overlap. Every action goes through the single shell_execute tool.
The tool name shell_execute follows a clear verb_noun pattern, consistent with common MCP naming conventions. Even with a single tool, the name is predictable and descriptive.
With only one tool, the set feels thin, but for a restricted shell executor it could be acceptable. The scope is narrow, making the tool count borderline rather than clearly excessive or insufficient.
The tool covers the allowed commands (pwd, grep, cat, ls, wc), but the restricted set excludes many typical shell operations like file writing or process control. This suggests notable gaps for a server named 'shell', though the explicit allowlist mitigates some issues.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Remote MCP server for supportsheep: run AI interviews and manage support content for your blog.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Enable secure connectivity between Sentry issues and debugging data, and LLM clients, using a Model Context Protocol (MCP) server.
Model Context Protocol server for the Apideck Unified API. Connect any MCP-compatible agent framework to 100+ accounting systems, HRIS platforms, file storage providers, and more through one integration. More information https://www.apideck.com/mcp-server
Related MCP Servers
- AlicenseBqualityDmaintenanceA secure MCP server for executing whitelisted shell commands with resource and timeout controls, designed for integration with Claude and other MCP-compatible LLMs.203897MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that allows LLMs to execute shell commands and receive their output in a controlled manner.7MIT
- AlicenseBqualityDmaintenanceA secure terminal execution server that enables controlled command execution with security features and resource limits via the Model Context Protocol (MCP).11211MIT
- AlicenseCqualityDmaintenanceA secure server that implements the Model Context Protocol (MCP) to enable controlled execution of authorized shell commands with stdin support.1MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/tumf/mcp-shell-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server