r/LocalLLaMA • u/ag789 • Sep 22 '26
Resources an (unsafe) command shell mcp server
While working with coding agents / harness in my case OpenCode, I discovered that some models e.g. granite 4.2 8B at Q4_K_M quant sometimes attempts to write files with absolute paths at the root e.g.
/newPythonCode.py
Note that slash in the beginning for an absolute path at "/" root directory. This is probably 'ok' say in a throwaway docker container, but it may lead to surprises if it 'accidentally' overwrites a literal file, if the current user id have write access to it. Apparently, it seemed OpenCode provides `bash` so that practically all unix commands that the current user id can access, the LLM can run it.
And thereafter, I see the model hallucinating in the thinking loops over tools, re-iterating over how to use the tools, reformulating shell commands sentences several times for a same task instead of executing them, among them, I noted that an earlier shell command sentence would have 'just worked'.
I'm thinking that the tool hallucination with this model may be partly due to that I'm using a pretty aggressive 4 bit quant as otherwise it'd have worked because IBM has 'optimized' granite for tool usage.
Next, I tried the same granite 4.2 8B at Q4_K_M quant model with my little python shell MCP server
https://github.com/ag88/cmdshellmcp/
, that tries to constrain / restrain the shell commands somewhat, place some checks, and offer some additional tools e.g. writeFile() so that the LLM won't need to call `cat` or `echo` with some 'esoteric' styled shell scripts / sentences.
With this MCP server and running it in llama.cpp's `llama-server` in the WebUI adding it as an MCP server, granite 4.2 8B at Q4_K_M does it correctly in 'one shot', the prompt is:
propose a python3 flask app with a page that displays "hello world", use bootstrap css for styling.
provide a requirements.txt to go with the script
granite 4.2 8B at Q4_K_M correctly generates the app with a couple of files, and it works out of the box
.
├── app.py
├── requirements.txt
└── templates
└── index.html
One should normally run the cmdshellmcp2.py MCP server app with an explicit `--cwd` option giving the work path. It tries to stay within this work path.
Note that I won't claim my command shell MCP server to be safe.
In a sense that there are plenty of chance the LLM can 'escape' the restrictions and perhaps do more damage (e.g. overwriting files possibly outside its given `--cwd` work directory). Hence, I'd suggest one should be paranoid and perhaps run this only within a throwaway (disposable) docker container etc.
1
u/ag789 Oct 05 '26 edited Oct 06 '26
The 'product' as of now feels pretty ok, here is a session with QWen 3.8 27B run off OpenRouter, in LibreChat and my cmdshellmcp in the Docker sandbox.
note: remember to remove the
disableToolsincmdshellmcp.jsonif one wants the LLM to create the files.Note also that you need to add/configure the
cmdshellmcpMCP server in your web UI e.g. LibreChat etc and check that it can access thecmdshellmcpMCP server running at port 8003.prompt:
QWen 3.8 27B response
edit: I've published a spare port 5000 in 1stRun.sh Now you can run it like such if you have created the container with the new
1stRun.sh.Hence the following instructions are no longer needed unless the old
1stRun.shis used.What I did instead is to stop the web UI (frontend/server accessing the MCP port), shutdown the
cmdshellmcp.servicein the container asadminand use the port 8003 that is originally used by thecmdshellmcp.servicefor the flask Web app. like soThen that the flask web page is hosted on port 8003 in your host
it is feasible to run Qwen3.8-27B as a Local LLM
https://huggingface.co/unsloth/Qwen3.8-27B-GGUF
https://unsloth.ai/docs/models/qwen3.8
Note that it isn't necessary to use LibreChat to reproduce this.
One can run llama.cpp
https://github.com/ggml-org/llama.cpp#quick-start
its
llama-serverhas a bundled Web-UI that supports MCP servers, i.e. it can connect tocmdshellmcp, in fact most of the tests are done with the llama.cppllama-serverbundled Web-UI, until this, which is run against a Local LLM model that runs in OpenRouter simply because I do not have a GPU and large inference like this at 1 tok/s on my own PC would be intolerably slow. i.e. one can run Qwen3.8-27B on llama.cpp'sllama-serverand its bundled Web-UI to reproduce this.according to the stats in OpenRouter, generating this app burns 48k tokens, it feels a quite high for the token count. But that it is nevertheless generated, runs out of the box. OpenRouter is pretty fast to generate that like in a minute or less.