Most agents should connect over MCP (see the Connecting agents doc,
gui/src/docs/agents.md) or, for chat, an OpenAI-compatible API (the
compatible provider kind — or hermes for a Hermes Agent's API server). The Custom agent bridge provider kind exists for the remainder: an
agent runtime with neither, wrapped in a few dozen lines of HTTP.
Commander is the client (commander/agent_link.py); you implement the server:
GET /health
-> {"agents": ["code", ...]} # names this bridge can invoke
POST /chat
{"agent": "code", "message": "...", "session": "jd-voice",
"safe_mode": false}
-> {"reply": "...", "agent": "code", "elapsed": 1.23}
- Auth is optional: if the provider has a token configured, Commander
sends it as an
X-Bridge-Tokenheader; reject requests without it. The voice loop (scripts/listen.py --check) reads the same secret from$BRIDGE_TOKENor a.bridge_tokenfile at the repo root (gitignored). - Sessions matter. Commander passes a stable
sessionstring so conversational context carries across utterances — "turn left" after "walk forward" means something. Keep per-session history server-side. - Take your time. Commander waits up to 180 s: the agent may be calling robot MCP tools mid-turn, and a gesture is seconds of real motion.
safe_modeis a hint to run the agent with restricted reach, if your runtime supports such a thing. Commander's own guardrails do not depend on it, and it defaults off.
A minimal bridge is a loop: pop message, hand it to your agent CLI/SDK with
the session's history, return the text. The agent moves the robot not through
this bridge but by calling Commander's MCP tools itself — so the bridge adds
no authority, and the guardrails in safety.md still apply to
every motion.