Samuel Birhanu
software engineer — agentic AI, Addis Ababa, Ethiopia
mcp-ops-agent, in plain English
AI agents that can run commands and poke at servers are genuinely useful, and genuinely dangerous. Give an agent too much freedom and one bad day becomes a deleted database.
mcp-ops-agent is my version of doing this properly. The agent gets real tools — it can search files, run a few harmless commands, and read the state of a Kubernetes cluster. But it can't do damage: the safety rules aren't a polite suggestion in the prompt, they're built into the tools themselves, so the agent has no way to argue its way past them. In the trace report you can watch three real runs step by step, including the moments the agent tried something it shouldn't and got blocked.
Under the hood
An MCP server (official mcp SDK, stdio transport) exposes six tools, and
a LangGraph ReAct agent uses them:
- Tools:
search_files,read_file,run_shell, and read-onlykubectl_get/kubectl_describe/kubectl_logs— the kubectl tools are fixed-argv constructions, so model-supplied values only fill validated slots. - Guardrails live in the tool layer, not the prompt: every path is
realpath-resolved and must stay inside the demo workspace (blocks
.., symlink traversal,~); the shell is parsed withshlex(noshell=True), runs on a read-only allowlist of binaries (ls cat head tail wc grep find du stat sort uniq date), rejects shell metacharacters, chaining, redirection, and command substitution, and denies destructive binaries likerm,curl,sudo. - Denials are first-class: a blocked call is returned to the model as an
observation and written to the trace as a
guard_deniedevent — highlighted in red in the report. - Traceable by construction: every step (LLM request/response, tool call, args, result, denial) streams to a JSONL trace, rendered as a self-contained HTML report.
- Reproducible: runs with a mocked LLM (deterministic, zero API spend) or a
real one (OpenRouter, flash-class); the kubectl scenarios read a real local k3d
cluster where a
payments-apipod is deliberately crash-looping, so the diagnosis task is real.