# shellmcp An MCP server (stdio, Python stdlib only) with one tool, `run`: a bash command, its exit code and its output. Gives any MCP client's model a terminal. python3 shellmcp.py [--mode readonly|all] [--cwd DIR] [--timeout 60] [--max-output 8000] [--hide PATH]... - `--mode readonly` (default): every command runs in bubblewrap. The filesystem is read-only except a private /tmp; no network; no other processes visible; ~/.ssh, ~/.gnupg and each `--hide PATH` look empty. Needs `bwrap`. - `--mode all`: the user's full permissions (here: wheel and docker, so effectively root). Use it only with a client that asks before each tool call. The tool description names the host, user, directory, limits and which modern tools (rg, fd, jq, ...) are installed, so the model prefers them. ## Where commands run Wherever this process runs. The client starts it (stdio), so with `"command": "python3"` the commands run on the client's machine. To act on the GPU host from any machine, start it over ssh (key login needed): "command": "ssh", "args": ["fabian@192.168.2.169", "python3", "/home/fabian/coding/misc/shellmcp/shellmcp.py", "--mode", "readonly"] ## Clients ollmcp with gemma4 on vLLM (`examples/ollmcp.json` registers `shell` and `shell-rw`): ollmcp -p openai -H http://127.0.0.1:8000/v1 -m gemma4 -j examples/ollmcp.json Claude Code: claude mcp add shell -- python3 /home/fabian/coding/misc/shellmcp/shellmcp.py --mode readonly OpenAI-API apps without MCP (Open WebUI and the like): wrap it as an OpenAPI server with `uvx mcpo --port 8001 -- python3 shellmcp.py --mode readonly`. ## Test python3 -m unittest -v test_shellmcp