# Prime Agent Tool-Call Control & Audit — Install Guide

Install ACP for Prime Agent via its native TypeScript extension. Every tool call — the ipython kernel, custom tools — policy-checked before it runs, with an audit record and inline output scanning. Prime Agent ships no permission framework; this adds one.

# Govern Prime Agent with Agentic Control Plane

<p style="font-size:17px;line-height:1.6;color:var(--acp-text);max-width:660px;margin:8px 0 6px;">See, control, and price <strong>every tool call Prime Agent makes</strong> — the ipython kernel where all its shell, file, and Python action happens, plus any custom tool — from one dashboard. Prime Agent ships <a href="/controls/prime-agent">no permission framework</a>; this native extension adds one, in one command.</p>

## TL;DR



The installer detects Prime Agent, drops the extension at `~/.prime/agent/extensions/acp.ts`, and opens your browser once to provision a workspace and save the key to `~/.acp/credentials`. Restart Prime Agent (or `/reload`) — every tool call is governed from the next session.

<p style="font-size:12.5px;color:var(--acp-text-faint);margin:8px 0 0;">MIT-licensed, zero dependencies, one readable file — <a href="https://github.com/agentic-control-plane/prime-agent-acp-plugin">read it before you run it</a>.</p>

## Why an extension (and why it's the whole story)

Prime Agent is a hard fork of pi-mono — and it kept pi's extension API while going even more minimal on tools: **one model-facing tool, `ipython`**, in a persistent kernel. Code is the action: shell, files, network, everything. There are no built-in approval prompts, no allowlist, no permission framework — [the docs name the permission gate as the canonical extension example](/controls/prime-agent) and leave writing it to you.

What it does have is the same typed event pipeline as pi: **every** tool dispatch flows through `tool_call` (before, blockable) and `tool_result` (after, rewritable). No MCP layer, no second tool path — MCP arrives as Python skills that execute inside ipython. One extension on that pipeline governs everything the agent does.

That coverage matters more here than in most harnesses: Prime Agent is built to run **unattended** — `/autonomous` mode with budget limits, daemon-backed always-on sessions, heartbeats and schedules, recursive subagents. Long-running unattended shell access is exactly the shape of agent that needs a decision ledger that lives off the machine.

## How it works

| event | ACP endpoint | What happens |
|---|---|---|
| `tool_call` | `POST /govern/tool-use` | `allow` proceeds · `ask` prompts (attended) or denies (unattended) · `deny` blocks with the reason in the transcript |
| `tool_result` | `POST /govern/tool-output` | audit record · DLP redaction rewrites what the model reads · a server block becomes corrective feedback |

Decisions come from the same workspace policies that govern [Claude Code](/integrations/claude-code), [pi](/integrations/pi), [dsh](/integrations/dsh), and the rest of your fleet — one policy plane, every harness, one place to answer *what happened and why*.

## The headless fix you get for free

Prime Agent 0.8.x reports `ctx.hasUI = true` even in headless print mode — its own docs say it should be false — and every CLI session, TUI and `-p` alike, runs inside a daemon worker where `hasUI` can't tell an attached human from an empty chair. An extension that trusts `hasUI` (as pi extensions correctly do on pi) would treat unattended runs as attended: fail-open on outages, approval prompts nobody can answer.

This extension resolves attendance instead of assuming it: **the prompt is the probe.** Every `ask` — and, on outages, the *"proceed ungoverned?"* question — goes through Prime Agent's own confirm dialog. An attached TUI user gets a real decision; the headless no-op UI cannot say yes, so the empty chair resolves to deny (verified live: an `ask` in `-p` ends as `Denied at approval prompt`). Tier labeling is conservative the same way: worker and headless processes report `background` unless `ACP_AGENT_TIER` says otherwise. Details in [the controls reference](/controls/prime-agent).

## Failure posture

- **Attended sessions fail open, loudly** — gateway unreachable means the call proceeds with an `[ACP] ⚠ UNGOVERNED` warning and a `~/.acp/lapse.log` entry.
- **Unattended runs fail closed** — including `/autonomous` and daemon-scheduled sessions, where the block is the safety net.
- Policy denies are unaffected; one transport retry precedes either posture.

## Manual install

```sh
mkdir -p ~/.prime/agent/extensions
curl -sf https://raw.githubusercontent.com/agentic-control-plane/prime-agent-acp-plugin/main/index.ts \
  -o ~/.prime/agent/extensions/acp.ts
```

Key goes in `~/.acp/credentials` (or `ACP_BEARER_TOKEN`). Prime Agent needs Node 22.8+. The global extensions path loads without a project-trust prompt, so governance is on before any repository is opened.

## Add the cost X-ray

The extension governs and audits tool calls; it never sees the model call, so it cannot price it. The installer drops a second extension, `~/.prime/agent/extensions/acp-proxy.ts`, that registers the `acp` provider (the proxy's base URL, key from the `ACP_KEY` environment variable) **only when `ACP_PROXY=1`**, and installs `prime-acp` next to `claude-acp` and `codex-acp`:

```bash
prime-acp
```

`prime-acp` reads your workspace key from `~/.acp/credentials`, sets `ACP_PROXY=1` and `--model acp/gemini-3.5-flash` for that launch only (`ACP_PRIME_MODEL=<id>` picks another), and starts plain Prime with a one-line note if the gateway is unreachable. Plain `prime` never loads the provider. Full walkthrough: [Turn on Cost X-Ray](/cost-tracking).

## Learn more

- [What ACP can see and control in Prime Agent](/controls/prime-agent) — the living controls reference
- [Which coding agent has the best native controls?](/controls) — the cross-harness comparison
- [The pi guide](/integrations/pi) — the upstream sibling; same seam, different paths
