41 lines
1.6 KiB
Markdown
41 lines
1.6 KiB
Markdown
# 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
|