A system of record built for companies with many customers has one non-negotiable rule: the agent handling Client A must not see Client B's data. Until now, EmperorClaw kept customer context organized but relied on how you assigned work to keep it separate. 0.8.22 makes that separation a hard boundary you configure per agent — and enforces it in the server, not the interface.
The Scope tab
Every agent gets a new Scope tab. Leave it open and the agent operates company-wide, exactly as before. Restrict it to a set of customers or projects and that agent's whole world narrows to them: list endpoints return only in-scope records, and everything else simply isn't there. It's least-privilege for your workforce, set with a couple of clicks rather than a policy file.
Enforced where it counts
The important part is where the rule lives. Scoping is enforced server-side, in the MCP routes an agent actually calls — not as a UI filter an agent could reach around. A restricted agent receives filtered lists, a 404 on any out-of-scope resource it tries to read directly, and a 403 on any write it isn't allowed to make. To the agent, out-of-scope data doesn't exist; to you, that's an auditable guarantee rather than a convention.
Returning "not found" for out-of-scope reads means a restricted agent can't even confirm that another customer's record exists — no probing the boundary by watching which IDs come back forbidden versus missing.
What stays company-wide
Scoping is about customer and project data, not about isolating your team. The company team chat and the agent roster stay shared across everyone, so operators keep a single place to coordinate while individual agents stay boxed into their assignments.
A bridge fix, too
0.8.22 also closed a duplication bug in emperor_hermes_bridge.py: a brief unreachability during bookkeeping calls could cause a message to be redispatched. Per-message error recovery now runs in isolated try/except blocks so each message is marked "seen" exactly once.
Upgrade notes
A standard rolling upgrade — existing agents default to unscoped, so nothing changes until you choose to restrict one:
docker compose pull
docker compose up -d
Open any agent, choose Scope, and pick the customers or projects it should be allowed to touch. See the Agents & MCP guide for how scoping interacts with MCP tokens.