Agent access (CLI and MCP)
How an outside AI agent reaches AgencyCore. The ac CLI works today as a user seat. An MCP server is planned and not designed.
Agent access (CLI and MCP)
TODO. This page is a stub, not a design.
It records what exists today, what is missing, and which decisions are still open. Nobody has designed the MCP server. Do not treat anything below the "What works today" section as agreed.
An outside AI agent is a third kind of caller. It is not a person in a conversation, and it is not a machine reporting an event. It acts for a person, with that person's authority, and it decides its own steps.
Two shapes exist.
| Shape | Status |
|---|---|
The agent runs a shell, and calls the ac CLI | works today |
| The agent speaks MCP, and calls an AgencyCore server | planned, not designed |
What works today
The ac CLI plus the ac-cli Claude Code plugin is a working path. The plugin ships from ac-cli-plugin through the marketplace, and its SKILL.md tells the agent which commands exist.
The agent reaches the ordinary product API, and it can already start runs:
POST /api/v1/agents/runs
POST /api/v1/workflows/{workflow_id}/runs
Both routes converge on one POST /api/v1/agentic/runs. See the migration note in surfaces. The ac CLI drives them, so it changes in the same branch.
The agent holds a user seat. ac auth login signs in with an email and a password through Supabase, and caches the returned access token. Every later call carries that token.
This has one good consequence and one bad one.
- Good. Nothing special happens. The caller resolves to a normal user
Principal, admission policy applies, approvals go to the approval inbox, spans and cost land on the run, and the run boundary holds. An AI agent is already inside the platform's guarantees. - Bad. The credential is a human password. It is per seat, it cannot be scoped down, it cannot be revoked separately from the person, and an unattended agent must hold it. Machine identity does not exist.
What is missing
- A server surface.
ToolSpec.kindisLiteral['internal', 'mcp', 'vendor'], and every one of those is outbound. MCP today means an approved remote server that we call, with an organization connection and a vault credential.ToolRegistryhas no path to publish outward. - Machine identity. There is no client registration, no OAuth, and no scoped machine token.
Principalcarries a user or a trigger, and nothing else. An external caller has no identity kind of its own, and V1 deliberately has no service principal table. - Per-client limits.
agent.cost_ceilingsholds cost ceilings only, and rate and concurrency live in Inngest flow control. A per-client rate limit is therefore new machinery, not configuration. - An output boundary. External and MCP output is already treated as untrusted input on the way in. Nothing covers what we hand out to a customer's model.
- A capability manifest. Whatever we expose needs a stable, published, versioned description.
ToolSpecis close to the right shape and is not that document.
Open decisions
1. Do we expose tools, or capabilities?
This is the decision everything else waits on.
| Option | What the agent calls | Consequence |
|---|---|---|
| Tools | crm.search, email.send | The customer's model becomes the reasoning loop inside our boundary. There is no run to admit, so admission policy has nothing to act on, and every call is a bare action. It needs a new external-session concept and a synthetic run. |
| Capabilities | signals_search.start, email_sequence.start | Each call becomes a StartRunCommand. Policy, approvals, spans, cost and idempotency all work as written. The customer's model stays outside the run boundary. |
Leaning: capabilities. It is close to a new producer in front of the existing boundary, not a new subsystem. Tool-level exposure is a larger change than it looks, and it moves the reasoning loop somewhere we cannot observe or bill. This is not decided.
2. What identity does an external agent carry?
A scoped service principal, a delegated user grant, or both. Whatever it is, the grant must stay an intersection, and it must be revocable without disabling the person.
3. Where do approvals go?
The approval inbox is the guaranteed floor, and it stays the floor. Whether the calling agent may also receive and resolve an approval, and under whose authority, is undecided.
4. How is cost attributed and capped?
Runs a customer's agent starts spend our model budget. Accrual policy already stops a run at its ceiling. Per client and per seat ceilings do not exist.
5. Does the front door stay out of the path?
If the agent already reasoned, a second reasoning hop is waste. A capability call should go straight to RunManager, not through the front door. Confirm this against the one-agentic-hop rule before building.
Invariants any design must keep
RunManagerstays the only run boundary. A new caller is a new producer in front of it, never a private path around it.- An agent still reaches the world only through a tool. Exposing a surface outward does not exempt the caller from the tool boundary.
- The grant is an intersection. An external caller can never hold more authority than the person it acts for.
- Policy is live. Revoking a client takes effect at the next checkpoint, not at the next run.
- Every call is on the record. One run row, one span for each unit of work, one cost meter.
The platform contract says the platform has two entry paths. That claim describes what is built. The invariant worth defending is one run boundary, not two entry paths. Reword the claim when this page becomes a design.
Next step
Scope the customer's actual need before designing. Claude Code plus the ac CLI may already answer it, and the answer changes if the agent must run unattended or serve more than one seat.