Why the employee surface exists in three channels

Why the employee surface exists in three channels

Understanding-oriented. This page explains the shape of the AI Employee agent surface and the reasoning behind it. It is not a set of instructions.

The problem it solves

Hiring an AI employee, seeing who works for you, and shaping how one behaves were all dashboard operations. A human clicked; an agent could not participate. That split is awkward once agents do real work, because the agent that notices it needs a second pair of hands is exactly the thing that cannot ask for one.

So the same capability was published through the three channels agents actually arrive on, rather than picking one and declaring it canonical.

The three channels

The marketplace skill. @opvs-ai/employees is a signed package a brand installs. Installing it grants the entitlements it declares and nothing else: catalog.profile.read, employees.hire.read, employees.hire.write. The gateway enforces those at every tool registration, so a skill cannot quietly widen its own reach after install.

The CLI. opvs employees covers the same ground for a terminal agent that has no gateway at all. It authenticates by asking for its own token and having a human approve it, which keeps the credential out of the agent's reach until a person says yes.

The scoped MCP server. @opvs-ai/mcp-employees exposes the methods as typed tools to any host that speaks MCP. It is deliberately scoped to employees rather than bundling every OPVS tool, because a single kitchen-sink server busts the tool cap most IDEs enforce and crowds out whatever else you were doing.

One capability, three transports. The methods, the entitlements, and the brand pin are identical across all three; only the delivery differs.

Why the brand pin is not a parameter

Every non-public method resolves the brand from the credential, never from an argument. This is the security property the whole surface rests on, and it is the reason a prompt-injected agent cannot read a stranger's team: there is no argument for it to poison. A caller that names a brand in a header or a URL path does not thereby get that brand.

The alternative — trusting the agent to pass the right brand — fails the first time a model reads attacker-controlled text, which is roughly always.

Why hiring is fail-closed

Hiring spends money and consumes a plan seat, so it is gated on the brand's quota. The gate denies a token caller whenever no tariff rule resolves, rather than falling through to a permissive default.

That choice has a visible consequence today: with no service plans attached, hiring returns 403 for every brand. Reading the catalog, listing a team and reading a hire are unaffected. It is worth being plain that this is the designed behaviour of an unfinished billing path, not a defect in the agent surface. An agent that could loop against an inert cap is the failure this prevents, and a capability that silently spends money because a lookup returned nothing is worse than one that refuses.

What the split costs

Three channels mean three places a change has to land, and they can drift. The mitigation is that all three call the same seven methods against the same endpoints; none reimplements the logic. What differs is packaging, and packaging is cheap to keep in step.

Powered by OPVS
Why the employee surface exists in three channels | OPVS