# Self-Optimize MCP Tools — Your Agent Reads Its Own Meter

Nine read-only MCP tools that let an agent inspect its own footprint — decisions, spend, cache economics, traces — and propose (never apply) policy changes. Endpoint, what each tool returns, and a realistic optimization loop.

# 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):

```json
{
  "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:

1. **Pace** — `acp_status`: 71% of the spending cap used. Enough left to finish, not enough to explore.
2. **Attribute** — `acp_optimize` (window `7d`): cache-hit rate 61%, `toolResults` at 57% of context, `Read` the top producer by output bytes.
3. **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.
4. **Verify** — `acp_trace` on the next run: the loop steps got cheaper; the totals confirm it.
5. **Propose** — `acp_audit` shows the same read-only command was approved by a human 14 times this week, so the agent runs `acp_propose_rule` with permission `allow` and 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](/agent-optimization-manual) — measured field notes from running this loop on our own agents.
- [Ways to set up ACP](/docs/setup) — the proxy step that unlocks the full cost composition.
- [Policies &amp; scopes](/docs/policies) — what the proposed rules land in.
