Fully local — mcidrac + a local model on a DGX Spark
Everything mcidrac touches is sensitive in a quiet way: BMC credentials, service tags, SEL contents, the shape of your network. Point a cloud model at it and all of that becomes someone else’s inference log. A DGX Spark — the GB10 Grace Blackwell desktop with 128 GB of unified memory — is enough machine to close that loop entirely: the model runs on your desk, mcidrac runs beside it, and the whole conversation about your servers stays on your LAN.
The pieces are a local model served by Ollama, opencode as the MCP-speaking agent, and mcidrac as the tool provider.
1. Serve a model on the Spark
Section titled “1. Serve a model on the Spark”Follow the Spark site’s run a local LLM how-to — Ollama has native ARM64 + CUDA support and exposes an OpenAI-compatible API on port 11434.
Model choice is not a matter of taste here. These tools power-cycle servers, so the only property that matters is reliable tool calling: the model must emit valid JSON arguments, respect required parameters, and stop when a tool says stop. opencode also wants a 64k+ context window, and MCP tool results (an inventory dump, a SEL page) are chunky.
Two reasonable starting points, both comfortable in the Spark’s memory budget at 4-bit (~0.5 bytes per parameter, per the Spark site’s unified memory explainer):
ollama pull qwen3-coder:30b # MoE, few active params — fast, agentic-tunedollama pull gpt-oss:120b # more headroom, still fits at ~60 GBDon’t take my word — or anyone’s benchmark — for whether your pick is good enough. Step 4 measures it against fake hardware.
2. Install mcidrac and opencode
Section titled “2. Install mcidrac and opencode”curl -LsSf https://astral.sh/uv/install.sh | sh # if uv isn't there yetuv tool install mcidraccurl -fsSL https://opencode.ai/install | bashmcidrac is pure Python with one dependency, so arm64 is a non-event — nothing to compile, no wheels to fight.
3. Wire them together
Section titled “3. Wire them together”~/.config/opencode/opencode.json — the provider block points opencode
at Ollama, and the mcp block spawns mcidrac over stdio:
{ "$schema": "https://opencode.ai/config.json", "model": "ollama/qwen3-coder:30b", "provider": { "ollama": { "npm": "@ai-sdk/openai-compatible", "name": "Ollama (local)", "options": { "baseURL": "http://127.0.0.1:11434/v1" }, "models": { "qwen3-coder:30b": { "name": "Qwen3 Coder 30B" } } } }, "mcp": { "idrac": { "type": "local", "command": ["uvx", "mcidrac", "--transport", "stdio"], "enabled": true, "environment": { "MCIDRAC_CONFIG": "/home/YOU/.config/mcidrac/mockup.toml", "R740_LAB_PASS": "your-idrac-password" } } }}Note what MCIDRAC_CONFIG is pointing at: the mockup registry, not
your real one. That’s deliberate, and it’s the next step.
4. Prove the model on fake hardware first
Section titled “4. Prove the model on fake hardware first”This is the part other setups can’t offer. mcidrac ships an integration harness that serves Dell’s real iDRAC9 and iDRAC10 Redfish captures as six fake BMCs, plus a behavioral simulator for the write paths — see the mockup lab. Point your local model at those and let it flail with zero consequences:
git clone https://git.supported.systems/warehack.ing/mcidrac.gitcd mcidrac && scripts/mockup-up.sh allcp .mockup/idracs.toml ~/.config/mcidrac/mockup.tomlThen start opencode and work the model through a real session:
“List my iDRACs, then give me a health summary of each one.”
“Which box has the most memory, and what’s its service tag?”
“Mount http://192.0.2.50/test.iso on r660xs, then unmount it.”
What you’re watching for is not whether the answers are pretty. It’s
whether the model calls the right tool with valid arguments, passes
the idrac name it was given rather than inventing one, reads the
result before narrating it, and stops cleanly instead of looping. A
model that garbles arguments against a fake R660xs would garble them
against your real R740 — you just get to find out for free.
If it stumbles: try a larger quantization, raise num_ctx in Ollama
(tool results are big), or move up a model tier. This is a measurement,
not a vibe.
5. Graduate to real hardware
Section titled “5. Graduate to real hardware”Once the model has earned it, point MCIDRAC_CONFIG at your real
registry (see configuration) and restart
opencode.
Two habits worth keeping:
Start read-only. Ask for health checks, inventories, SEL tails, and firmware audits for a while before you let it touch power or media. The safety model explains what the server refuses on its own — wrong-box SCP imports, unverified boot configs — but a local model is a new operator, and new operators earn write access.
Keep a human in the loop for destructive calls. Every destructive
tool carries the MCP destructiveHint annotation, and opencode’s
permission settings can require confirmation before an agent acts.
Configure it to ask, at least until you trust the pairing.
Also: share one endpoint over HTTP
Section titled “Also: share one endpoint over HTTP”If you want the Spark to serve other machines’ clients too, run mcidrac as a persistent HTTP service instead of a per-session stdio process. A user-level systemd unit does it without root:
[Unit]Description=mcidrac — Dell iDRAC MCP serverAfter=network-online.target
[Service]EnvironmentFile=%h/.config/mcidrac/envExecStart=%h/.local/bin/mcidrac --transport http --host 127.0.0.1 --port 7903Restart=on-failureRestartSec=5
[Install]WantedBy=default.targetsudo loginctl enable-linger "$USER" # survive logoutsystemctl --user daemon-reload && systemctl --user enable --now mcidracPut credentials in ~/.config/mcidrac/env (mode 0600), one
VAR=value per line.
The HTTP transport has no authentication — network reachability is
authorization, and this process holds credentials that can power off
your servers. Hence the 127.0.0.1 bind. Reach it from elsewhere over
an SSH tunnel, or over Tailscale as the Spark site’s
network access guide
recommends:
ssh -N -L 7903:127.0.0.1:7903 spark &claude mcp add idrac --transport http http://127.0.0.1:7903/mcpA bonus of centralizing: the per-host session cap lives in the server process, so however many clients connect, the iDRAC still sees at most three concurrent sessions from mcidrac (architecture).
Why this is worth the trouble
Section titled “Why this is worth the trouble”An air-gapped rack still leaks through its management plane the moment you paste a SEL dump into a cloud chat window. This setup closes that: the model, the tools, the credentials, and the hardware all sit inside one boundary you control — and the only thing crossing it is your own curiosity.
More Spark operational lore — networking, clustering units, recovery — lives at dgx-spark.warehack.ing.