The agent is the interface. A reasoning loop calls the same verbs a human would, over the kernel’s MCP door — so the agent gains no special powers; it is bounded by exactly the verb surface its bearer can reach.
The owned agent loop
scripts/opbox_agent.py is the owned agent loop. Given a message, it:
- Lists the verbs the kernel’s MCP
tools/listexposes for its bearer — no client-side filtering. The kernel governs which calls actually succeed. - Runs a tool-calling loop: the model picks a verb, the loop calls it over
/mcp, feeds the result back, and repeats until the model answers.
It serves two shapes: a synchronous POST / and a streaming POST /chat/stream that emits AG-UI events
(RUN_STARTED, TOOL_CALL_*, TEXT_MESSAGE_*, RUN_FINISHED) — one loop, two projections.
The cage
The agent is untrusted. Its only path to firm or matter data is the kernel’s verb surface; native shell, python, and web access are stripped, and egress is locked. The kernel — not any agent hook — enforces authz, audit, and budget.
The caged Hermes engine is now exercised, not just planned. An unmodified upstream Nous Hermes
agent (NousResearch/hermes-agent) runs caged: its only tools
are the always-on Core kernel verbs over MCP (~68 verbs) plus an in-memory todo tool. It has no terminal, browser, web,
file, or code-exec access. This was verified end to end: the caged agent made a real kernel tool-call and
returned the live result. The owned opbox_agent.py loop coexists as a driver and a fallback; the cage is
what makes consuming an upstream engine safe, so the substrate stays owned while the reasoning engine is
commodity.
The model is provider-configurable and engine-agnostic. The active default is cloud GLM-4.6 via z.ai’s coding endpoint; a local Ollama model is the no-egress fallback; any OpenAI-compatible provider works by config. Model inference egresses to the chosen provider, but that is independent of the tool cage: the agent’s tool surface is the kernel verbs no matter which model reasons over them.
MCP is the agent door
INV-3 denies a HUMAN identity over the MCP door — MCP is the agent door, HTTP is the human door. This is
load-bearing for the chat design: a browser user’s SESSION bearer authenticates them at the HTTP door, but the
agent cannot be that human over MCP.
The bounded chat-agent
Because the agent executes over MCP under its own identity, that identity must be bounded. The public chat
runs under a dedicated chat-agent provisioned as org.agent.create role=WORKER with autonomy 1 and a
MEMBER tier — never the OWNER Chief-of-Staff key. Autonomy 1 is the real bound: it permits reads and writes
but denies every sensitive or owner operation, regardless of verb scope.
The human SESSION bearer is the access gate (who may chat); the bounded WORKER is the execution identity (what the chat may do). This split, and the rule that the standing OWNER key never backs a public chat, is a fixed design rule of the agent-chat surface.
Provisioning
The genesis ceremony mints the Chief-of-Staff agent (the org root, OWNER over MCP) and, acting as the CoS, creates the bounded WORKER chat-agent. See Genesis.