The self-optimize MCP tools
ACP meters and decides every call an agent makes. The self-optimize surface turns that record around and hands it to the agent itself: nine MCP tools that answer “what have I been doing, what did it cost, and what should change?” — about the caller’s own activity, read-only.
Connect any MCP client (streamable HTTP, OAuth sign-in in the browser):
https://api.agenticcontrolplane.com/mcp
An ACP workspace exposes exactly these nine tools over MCP — the meta surface, not a tool catalog. Eight are read-only introspection; the ninth, acp_propose_rule, writes one thing: a draft rule that a human confirms or rejects in the console. Nothing on this surface applies policy or performs a data-plane action.
Scoping. Every tool defaults to the caller’s own principal — an agent sees its own runs, decisions, and spend. A key carrying the admin scope can request workspace-wide views. The one exception is the plan cap in acp_usage, which is intrinsically shared: the workspace limit constrains every member, so every member can see it.
The nine tools
| Tool | What it returns |
|---|---|
acp_check |
Advisory pre-check: pass a tool_name and tool_input, get back whether policy would allow the call. Ask before doing, without doing. |
acp_status |
Connectivity, enforcement state, and the caller’s budget: spent, remaining, and percent used of the identity’s spending cap. Poll it to pace a long task and wrap up before the cap cuts you off. |
acp_audit |
The caller’s recent decided calls — tool, decision (allow / deny / redact / rate), and the reason each decision was made. Filterable by decision, up to 100 rows. |
acp_usage |
The workspace’s monthly plan usage. Calls are unlimited on every plan; the meter counts initiating agents against the plan’s band (ok / nudge / at-limit / over) — plus calls used and the caller’s own contribution. |
acp_cost |
Model spend over a window (today / 7d / 30d): total dollars, run count, and a by-model breakdown. |
acp_recommendations |
Ranked, evidence-backed policy suggestions computed from the caller’s approval and decision history — e.g. a tool approved many times is a candidate for auto-allow. Read-only; applying happens in the console. |
acp_optimize |
The caller’s cost composition: prompt-cache hit rate, spend by model, growing-loop share, what fills the context (system vs history vs tool results), and which tools produce the most re-read output. Data for the agent to reason over, plus a short hint. |
acp_trace |
The step-by-step trace of one run — ordered steps with tool, kind (leaf / loop / tool), cost, and model, plus totals. Defaults to the caller’s most recent run. |
acp_propose_rule |
Stages a draft policy rule — tool, proposed permission (allow / ask / deny / flag / step_up), tier, a one-sentence rationale, and optional guidance shown to the agent when the rule fires. A human reviews and applies it in the console; nothing is enforced until they do. |
What acp_optimize looks like
A shape like this (example values):
{
"window": "7d",
"scope": "principal",
"runs": 42,
"totalCostUsd": 18.40,
"cacheHitRate": 61,
"inputDecompose": { "cacheRead": 8100000, "cacheWrite": 900000, "uncached": 4200000 },
"loopSharePct": 34,
"costByModelUsd": { "claude-sonnet-4-5": 15.10, "claude-haiku-4-5": 3.30 },
"contextBreakdownPct": { "system": 12, "history": 31, "toolResults": 57 },
"topToolsByOutput": [ { "tool": "Read", "mb": 9.80 }, { "tool": "Bash", "mb": 2.10 } ],
"hint": "uncached (true cache miss) share is 32% — a stable, byte-identical prompt prefix (system + tools) across turns is the biggest lever; cached reads bill at ~10% of full rate. toolResults dominating context → compact or drop stale tool output."
}
Two honesty notes built into the tool itself: the context-byte composition is captured on the ACP proxy path only, and the response says so explicitly when it’s empty rather than returning zeros that read as “nothing to optimize”; and runs that changed their prompt prefix mid-run are called out by count, because prefix churn is the cause of a low cache rate, not a separate symptom.
The advice is also tier-aware: “consider a subagent” only appears for autonomous runs — in an interactive session the growing loop is the work.
A realistic loop
An agent partway through a long autonomous task, running this on itself:
- Pace —
acp_status: 71% of the spending cap used. Enough left to finish, not enough to explore. - Attribute —
acp_optimize(window7d): cache-hit rate 61%,toolResultsat 57% of context,Readthe top producer by output bytes. - Adjust — the agent compacts its context, stops re-reading whole files, and routes leaf lookups to a cheaper model. All of that is within its own control; no human needed.
- Verify —
acp_traceon the next run: the loop steps got cheaper; the totals confirm it. - Propose —
acp_auditshows the same read-only command was approved by a human 14 times this week, so the agent runsacp_propose_rulewith permissionallowand a one-line rationale. The draft lands in the console; the human applies it (or doesn’t). Approval fatigue goes down without the agent ever touching policy.
That last step is the deliberate boundary of the whole surface: the agent can observe everything about itself and change nothing about its rules. Proposals end at a human.
Related
- The Agent Optimization Manual — measured field notes from running this loop on our own agents.
- Ways to set up ACP — the proxy step that unlocks the full cost composition.
- Policies & scopes — what the proposed rules land in.