muneebakhter/WSLShellMCP
If you are the rightful owner of WSLShellMCP and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
Shell MCP is a minimal Model Context Protocol (MCP) server designed to safely execute shell commands with enhanced control and security features.
Shell MCP
A minimal Model Context Protocol (MCP) server that exposes a safe, configurable way to run shell commands via a single tool: shell_run.
It uses /bin/bash -lc under the hood, supports a configurable working directory, timeouts, output truncation, and optional sudo with password injection.
Note: This repo contains the MCP server code in
shell-mcp/shell_mcp. You typically run this server from inside theshell-mcp/folder.
Features
shell_runtool: Execute commands with/bin/bash -lc.- Controlled environment:
- Working directory:
SHELL_MCP_WORKDIR(defaults to current directory on launch) - Timeout per command:
SHELL_MCP_TIMEOUT(default:120seconds) - Output truncation:
SHELL_MCP_MAX_OUTPUT(default:65536bytes)
- Working directory:
- Optional
sudosupport:- If a
sudopassword is provided, the server injects-Sand writes the password to stdin for commands includingsudo. - Password can be set directly with
SHELL_MCP_SUDO_PASSWORDor read from file viaSHELL_MCP_SUDO_PASSWORD_FILE.
- If a
- Stdio MCP server built with
FastMCPfrom themcplibrary.
Project layout
WSLShellMCP/
├─ README.md # This file
└─ shell-mcp/
├─ requirements.txt # pip dependencies (mcp >= 1.13.0)
└─ shell_mcp/
├─ __init__.py
├─ __main__.py # Entry point: `python -m shell_mcp`
└─ server.py # FastMCP server exposing `shell_run`
Prerequisites
- Python 3.8+ (virtual environment recommended)
- A Linux-compatible shell (
/bin/bash) — works on Linux and WSL
Quick start
- Clone and enter the project directory
git clone https://github.com/muneebakhter/WSLShellMCP.git
cd WSLShellMCP/shell-mcp
- Create and activate a virtual environment (optional but recommended)
python3 -m venv .venv
source .venv/bin/activate
- Install dependencies
pip install -r requirements.txt
- Run the MCP server (stdio)
python -m shell_mcp
This process runs an MCP server over stdio. In practice, an MCP-compatible client (e.g., an editor or app that speaks MCP) will launch and communicate with this server automatically.
Important: always use the MCP shell tool (not direct CLI)
For all command execution tasks, use the MCP shell server’s tool (shell_run) instead of running commands directly in a terminal. This ensures consistent behavior, logging, timeout control, sudo handling, and output truncation.
- Do: invoke commands via the MCP client calling
shell_run(see examples below). - Don’t: run commands directly in your shell prompt for workflows meant to be automated or audited.
Examples:
- Listing files (no shell usage): see “Programmatic example: list files without a shell”.
- Installing software (e.g., using
curl | sh): call the installer throughshell_runand, if it needs sudo, provideSHELL_MCP_SUDO_PASSWORD_FILEorSHELL_MCP_SUDO_PASSWORDso the tool can inject-Sand supply credentials non-interactively.
Configuration
Configure behavior via environment variables:
SHELL_MCP_WORKDIR(string):- Directory to execute commands in. Defaults to the process working directory.
SHELL_MCP_TIMEOUT(float, seconds):- Per-command timeout. Default:
120.
- Per-command timeout. Default:
SHELL_MCP_MAX_OUTPUT(int, bytes):- Truncation limit for
stdoutandstderr. Default:65536.
- Truncation limit for
SHELL_MCP_SUDO_PASSWORD(string):- If set, commands containing
sudowill have-Sinjected (if missing) and the password is written to stdin.
- If set, commands containing
SHELL_MCP_SUDO_PASSWORD_FILE(string, path):- Alternative to the above—if provided and readable, the server loads the sudo password from this file.
Example (Linux/WSL):
export SHELL_MCP_WORKDIR="$HOME"
export SHELL_MCP_TIMEOUT=180
export SHELL_MCP_MAX_OUTPUT=$((128 * 1024))
# Choose ONE of the following options (prefer the file for security):
# export SHELL_MCP_SUDO_PASSWORD='your-password-here'
export SHELL_MCP_SUDO_PASSWORD_FILE="$HOME/.config/shell-mcp/sudo.pw"
python -m shell_mcp
Security tips:
- Avoid putting sudo passwords directly into shell histories; prefer using a file with restrictive permissions (e.g.,
chmod 600). - Use least-privilege—only provide
sudowhen absolutely necessary.
Tool: shell_run
Description:
- Execute a shell command using
/bin/bash -lcwithin the configured working directory. - Returns a JSON-like result with
exit_code,stdout,stderr, andtruncatedflags.
Input parameters:
command(string): the shell command to run.timeout(optional float): per-invocation override forSHELL_MCP_TIMEOUT.
Behavior notes:
- If
sudois present in the command and a password is configured, the server injects-S(if not already present) and writes the password to stdin. - Output may be truncated if it exceeds
SHELL_MCP_MAX_OUTPUT. - On timeout, the process is killed and
exit_codeis set to124, with a note appended tostderr.
Using with an MCP client
This server speaks standard MCP over stdio. Typical integration patterns:
- Tools that support MCP (e.g., editor integrations) can launch the server with
python -m shell_mcpand communicate over stdio. - Ensure the environment variables above are set in the client’s launch environment if you need custom behavior.
Since MCP client configuration varies by tool, consult your client’s documentation for how to register an MCP server executable.
Programmatic example: list files without a shell
If you want to use the server’s tool directly in Python (without opening a shell or terminal), you can import the function and call it:
from shell_mcp.server import shell_run
# List all files in the current working directory (including dotfiles)
result = shell_run('ls -a')
print(result['stdout'])
Notes:
- This uses the same implementation that the MCP server exposes as the
shell_runtool. - The execution context honors environment variables like
SHELL_MCP_WORKDIR,SHELL_MCP_TIMEOUT, andSHELL_MCP_MAX_OUTPUTif they’re set in the process environment. - You can pass a per-call timeout override:
shell_run('ls -a', timeout=10).
To try this locally with the provided virtual environment:
cd shell-mcp
. .venv/bin/activate
python - <<'PY'
from shell_mcp.server import shell_run
print(shell_run('ls -a'))
PY
This demonstrates running ls -a via the MCP server’s tool implementation without manually invoking a shell.
Troubleshooting
- Command times out (exit code 124):
- Increase
SHELL_MCP_TIMEOUTor pass a highertimeouttoshell_run.
- Increase
- Output truncated:
- Increase
SHELL_MCP_MAX_OUTPUT.
- Increase
sudoprompts for a password:- Set
SHELL_MCP_SUDO_PASSWORDorSHELL_MCP_SUDO_PASSWORD_FILE. Ensure the command includessudo(the server injects-Sautomatically for the firstsudo).
- Set
- Permission denied / working directory issues:
- Verify
SHELL_MCP_WORKDIRexists and you have the necessary permissions.
- Verify
Development
- Code lives in
shell-mcp/shell_mcp/. - Entry point is
__main__.pywhich callsserver.main(). - The server implementation is in
server.py, built onFastMCPfrom themcppackage.
License
No license file is currently provided. If you plan to distribute or modify, consider adding a license (e.g., MIT, Apache-2.0).