Skip to content

Repository files navigation

shell-mcp

A deliberately small MCP server that exposes a single tool, run_shell, for executing arbitrary shell commands over Streamable HTTP.

It uses the stable v2 Model Context Protocol TypeScript SDK (@modelcontextprotocol/server and @modelcontextprotocol/node) and runs on Node.js 20+.

Warning

run_shell has the same operating-system permissions as the shell-mcp process. Treat access to this server as equivalent to shell access. The default bind address is loopback-only. A bearer token is required if you bind to a non-loopback address.

Tool

run_shell

Input Required Description
command yes Command string to execute.
shell no Shell executable/path, e.g. bash, sh, zsh, pwsh, powershell.exe, or cmd.exe. Defaults to the platform shell.
cwd no Working directory. Defaults to the server process working directory.
env no Environment variables to add or override for the command.
timeoutMs no Command timeout in milliseconds. Defaults to 30 seconds.

The result includes stdout, stderr, exit code, terminating signal, duration, timeout state, and whether the output limit was exceeded.

Run

npm install
npm run build
npm start

The MCP endpoint defaults to:

http://127.0.0.1:3000/mcp

For development:

npm run dev

Configuration

Environment variable Default Purpose
HOST 127.0.0.1 HTTP listen address.
PORT 3000 HTTP listen port.
SHELL_MCP_TOKEN unset Optional bearer token on loopback; required for non-loopback binds.
SHELL_MCP_DEFAULT_TIMEOUT_MS 30000 Default command timeout.
SHELL_MCP_MAX_TIMEOUT_MS 600000 Maximum timeout accepted by the tool.
SHELL_MCP_MAX_OUTPUT_BYTES 1048576 Maximum combined stdout/stderr retained before the command is terminated.

Example network bind:

HOST=0.0.0.0 \
SHELL_MCP_TOKEN='use-a-long-random-secret' \
npm start

Configure the MCP client to send:

Authorization: Bearer use-a-long-random-secret

For anything beyond a trusted local network, put the endpoint behind TLS and an authenticated reverse proxy rather than exposing the Node process directly.

Examples

Bash:

{
  "command": "uname -a && pwd",
  "shell": "bash"
}

PowerShell:

{
  "command": "Get-ChildItem Env: | Select-Object -First 5",
  "shell": "pwsh"
}

Development

npm run check

Design

  • One MCP tool; no resources or prompts.
  • Streamable HTTP only; no stdio transport.
  • Stateless MCP handler with a fresh McpServer per request, following the v2 SDK serving model.
  • Explicit shell invocation for POSIX shells, PowerShell, and cmd.exe.
  • Process-tree termination on timeout or output overflow.
  • Loopback binding by default, with bearer authentication required for non-loopback binds.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages