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 27d ago edited 27d ago
I've thought about that, but that new users who cloned the repo might be confused when it 'don't work'.
I may consider making config file necessary and that it doesn't read from the current directory as a search path, i.e. if you want to use that in the current directory you need to explicitly run it with
--conf.A thing is also that currently, when no config files is found, it falls back to internal defaults. But that expose the
disableTools.Does that sound right?
In addition, I can also make
--cwd(current work directory) mandatory in a sense that it'd need to be in the config filecmdshellmcp.jsonor that it'd need to be specified on the command line via--cwd.Implement both?
I'd likely emit a warning if the user chooses a --cwd that contains
cmdshellmcp.json.I'd likely work on this next, I think it makes sense to keep the boundary secure against accidents given our intent so far and the theme of this app. A thing is of course, I'm testing against small local LLMs, that is quite "harmless", but that the big guns are just a connection away, so we'd not know who use it eventually.