# The Coding Agent Tool Surface Index

What coding agents can actually do: the declared tool surfaces of Claude Code, Codex, and other harnesses — captured from live traffic, grouped by blast radius, with a recommended out-of-box posture for each.

# The Coding Agent Tool Surface Index

Every agent harness that speaks a modern LLM API declares its **full tool list in every single request** — the model can't call a tool it can't see. That means an agent's real capability surface isn't in its documentation; it's in its traffic. This page indexes those surfaces, per client, **captured from live requests** — the declared surface, not the marketed one.

Surfaces drift: harnesses lazy-load tools mid-session, MCP servers connect, updates add families. The captures below are maintained by the same drift detection we run in production — when a client's declaration changes, this page is due an update.

*Verdicts follow the posture argued in [Which Claude Code tools should you deny out of the box?](/blog/which-claude-code-tools-to-deny-out-of-the-box): allow the core loop, deny the outward tail until first need, gate the irreversible.*

<div class="acp-shot-frame">
<img src="/assets/img/screenshots/tool-surface-table-rows.png" alt="The tool-surface control table for a live Claude Code agent: every declared tool a row with Allow / Flag / Deny / Approval controls, invoked vs never-invoked status, and a one-click suggested posture — deny 10 never-invoked outward-blast-radius tools" style="width:100%;height:auto;border:1px solid var(--line-2);border-radius:10px;box-shadow:0 20px 50px -24px rgba(0,0,0,0.9);margin:8px 0;" />
</div>

## At a glance

<div class="acp-post-wide-table">
<table>
<thead><tr><th>Client</th><th>Tools declared</th><th>Can send / publish</th><th>Can schedule itself</th><th>Spawns sub-agents</th><th>Browser control</th></tr></thead>
<tbody>
<tr><td><strong>Claude Code</strong> <span style="font-size:11px;color:#6b7280;">(v2.1, captured 2026-07)</span></td><td><strong>76</strong></td><td>Yes — messages, push, published web pages</td><td>Yes — cron + wakeups</td><td>Yes — local, remote, multi-agent workflows</td><td>Yes — 21 tools, acts in the user's logged-in browser when the extension is connected</td></tr>
<tr><td><strong>OpenAI Codex CLI</strong> <span style="font-size:11px;color:#6b7280;">(v0.142, captured 2026-07)</span></td><td><strong>17</strong></td><td>No first-party send/publish tools</td><td>No</td><td>No first-party spawn (plugins can add)</td><td>No</td></tr>
<tr><td><strong>OpenClaw / Zed / SDK agents</strong></td><td colspan="4" style="color:#6b7280;">Captures pending — same method applies to anything speaking the Messages or Responses API.</td><td></td></tr>
</tbody>
</table>
</div>

The headline isn't that one number is bigger. It's that the two harnesses embody different philosophies: Codex ships a tight execution core and pushes everything else to plugins; Claude Code ships a broad standing surface — including families most users have never watched it invoke.

## Claude Code — 76 tools declared

Captured from a live session, Claude Code 2.1.x with the Chrome extension and claude.ai connectors available. Three distinct layers:

### Core harness — 37 tools

The coding loop and its scaffolding. Grouped by blast radius, with the out-of-box verdict:

<div class="acp-post-wide-table">
<table>
<thead><tr><th style="white-space:nowrap;">Family</th><th>Tools</th><th style="white-space:nowrap;">Out of the box</th></tr></thead>
<tbody>
<tr><td style="white-space:nowrap;"><strong>Read-only</strong></td><td><code>Read</code> <code>Grep</code> <code>Glob</code> <code>CronList</code> <code>TaskList</code> <code>TaskGet</code> <code>TaskOutput</code> <code>ListMcpResourcesTool</code> <code>ReadMcpResourceTool</code> <code>ReadMcpResourceDirTool</code> <code>Monitor</code></td><td><span style="color:#0a7a52;font-weight:700;">ALLOW</span></td></tr>
<tr><td style="white-space:nowrap;"><strong>Local write</strong></td><td><code>Edit</code> <code>Write</code> <code>NotebookEdit</code> <code>TaskCreate</code> <code>TaskUpdate</code> <code>TaskStop</code> <code>EnterWorktree</code> <code>ExitWorktree</code></td><td><span style="color:#0a7a52;font-weight:700;">ALLOW</span></td></tr>
<tr><td style="white-space:nowrap;"><strong>Execution</strong></td><td><code>Bash</code></td><td><span style="color:#0a7a52;font-weight:700;">ALLOW</span> <span style="font-size:11px;color:#6b7280;">+ sandbox</span></td></tr>
<tr><td style="white-space:nowrap;"><strong>Network read</strong></td><td><code>WebFetch</code> <code>WebSearch</code></td><td><span style="color:#a16207;font-weight:700;">FLAG</span></td></tr>
<tr><td style="white-space:nowrap;"><strong>Send</strong></td><td><code>SendMessage</code> <code>PushNotification</code></td><td><span style="color:#b91c1c;font-weight:700;">DENY</span> <span style="font-size:11px;color:#6b7280;">until needed</span></td></tr>
<tr><td style="white-space:nowrap;"><strong>Publish</strong></td><td><code>Artifact</code> <span style="font-size:11px;color:#6b7280;">(hosted public pages)</span> <code>DesignSync</code> <code>ReportFindings</code></td><td><span style="color:#b91c1c;font-weight:700;">DENY</span></td></tr>
<tr><td style="white-space:nowrap;"><strong>Schedule</strong></td><td><code>CronCreate</code> <code>CronDelete</code> <code>ScheduleWakeup</code></td><td><span style="color:#b91c1c;font-weight:700;">DENY</span></td></tr>
<tr><td style="white-space:nowrap;"><strong>Spawn</strong></td><td><code>Agent</code> <code>Workflow</code> <code>RemoteTrigger</code></td><td><span style="color:#a16207;font-weight:700;">FLAG</span> <span style="font-size:11px;color:#6b7280;">local ok · deny remote</span></td></tr>
<tr><td style="white-space:nowrap;"><strong>Interaction / meta</strong></td><td><code>AskUserQuestion</code> <code>Skill</code> <code>EnterPlanMode</code> <code>ExitPlanMode</code></td><td><span style="color:#0a7a52;font-weight:700;">ALLOW</span></td></tr>
</tbody>
</table>
</div>

<p style="font-size:12.5px;color:#6b7280;">The live capture counted 76 declared at session start; the enumeration above includes two tools that registered later in the session.</p>

### Browser control — 21 tools (when the Chrome extension is connected)

`navigate`, `computer` (click/type/screenshot), `form_input`, `file_upload`, `javascript_tool`, `read_page`, `get_page_text`, `read_console_messages`, `read_network_requests`, tab management, shortcuts, GIF recording, and more.

This is the largest single grant in the surface and the least discussed: **these tools act as the user, in the user's logged-in browser.** A `form_input` + `javascript_tool` pair is authenticated action on any site the user has a session with. Verdict: <span style="color:#5b21b6;font-weight:700;">ASK</span> — the reads (screenshot, page text) are defensible to allow; anything that clicks, types, uploads, or executes JS deserves a human gate.

### Connectors — 20 tools (claude.ai MCP servers)

OAuth flows and actions for Gmail, Google Calendar, Google Drive, Notion, Canva, job boards, and custom servers. Each `authenticate` pair is the doorway to a whole account. Verdict: <span style="color:#5b21b6;font-weight:700;">ASK</span>, case-by-case — a connector your workflow doesn't use is pure downside standing open.

## OpenAI Codex CLI — 17 tools declared

Captured from Codex 0.142.x via the Responses API. A deliberately tighter core:

<div class="acp-post-wide-table">
<table>
<thead><tr><th style="white-space:nowrap;">Family</th><th>Tools</th><th style="white-space:nowrap;">Out of the box</th></tr></thead>
<tbody>
<tr><td style="white-space:nowrap;"><strong>Execution</strong></td><td><code>exec_command</code> <code>write_stdin</code> <code>apply_patch</code></td><td><span style="color:#0a7a52;font-weight:700;">ALLOW</span> <span style="font-size:11px;color:#6b7280;">+ sandbox</span></td></tr>
<tr><td style="white-space:nowrap;"><strong>Network read</strong></td><td><code>web_search</code></td><td><span style="color:#a16207;font-weight:700;">FLAG</span></td></tr>
<tr><td style="white-space:nowrap;"><strong>Planning / goals</strong></td><td><code>update_plan</code> <code>create_goal</code> <code>get_goal</code> <code>update_goal</code></td><td><span style="color:#0a7a52;font-weight:700;">ALLOW</span></td></tr>
<tr><td style="white-space:nowrap;"><strong>Media</strong></td><td><code>image_generation</code> <code>view_image</code></td><td><span style="color:#0a7a52;font-weight:700;">ALLOW</span></td></tr>
<tr><td style="white-space:nowrap;"><strong>Plugins / MCP</strong></td><td><code>tool_search</code> <code>list_available_plugins_to_install</code> <code>request_plugin_install</code> <code>list_mcp_resources</code> <code>list_mcp_resource_templates</code> <code>read_mcp_resource</code></td><td><span style="color:#a16207;font-weight:700;">FLAG</span> <span style="font-size:11px;color:#6b7280;">plugin install = surface growth</span></td></tr>
<tr><td style="white-space:nowrap;"><strong>Interaction</strong></td><td><code>request_user_input</code></td><td><span style="color:#0a7a52;font-weight:700;">ALLOW</span></td></tr>
</tbody>
</table>
</div>

Two things worth noticing. First, no first-party send/schedule/publish family at all — Codex's outward surface arrives via plugins, which makes `request_plugin_install` the tool to watch: it's not dangerous itself, it's how the surface *grows*. Second, `exec_command`/`write_stdin` are a full interactive shell — the sandbox posture carries all the weight.

## How to capture your own

You don't need special tooling to check any of this: dump one request body from your harness (a logging proxy or mitmproxy session will do), list the `tools` array, and you have your real surface. Diff it across sessions and you have drift detection.

Doing that continuously — every declaration captured, every change diffed, every tool a click to allow, flag, deny, or gate — is what [ACP](/) does. One command, and this page's tables become a live, governable view of your own agents:

```bash
curl -sf https://agenticcontrolplane.com/install.sh | bash
```

The full walkthrough of what that install gives you — the per-session bill, the cost X-ray, the control table — is on [ACP for coding agents](/for-coding-agents).

## Quick answers



## Postures in depth

The tables above give a verdict per family. These pieces argue the verdicts, family by family, with the incidents behind them.

**Setting the policy**

- [Which Claude Code tools should you deny out of the box?](/blog/which-claude-code-tools-to-deny-out-of-the-box) — the full argument behind this page's verdicts, from blast radius
- [AI agent tool allowlists: deny by default, scope per task, audit everything](/blog/ai-agent-tool-allowlist) — the reference page, with Claude Code, Codex, and MCP config
- [Claude Code's deny list can be bypassed](/blog/claude-code-deny-list-bypass) — where client-side rules stop holding, and what a real boundary looks like
- [`--dangerously-skip-permissions` disables every control hook](/blog/claude-code-dangerously-skip-permissions) — the documented opt-out, including of our own hook
- [How to govern AI agent tool calls (before they run)](/blog/how-to-govern-ai-agent-tool-calls) — the deterministic gate, and why it needs narrow typed tools
- [Agent access control: least-privilege scoped tools](/blog/agent-access-control-scoped-tools) — why the narrow surface is the precondition for everything else
- [When to use a control plane, and when to reach for a sandbox](/blog/when-to-use-an-agentic-control-plane) — the honest boundary map

**Per-client setup**

- [Log and control every Claude Code tool call in 60 seconds](/blog/governance-for-claude-code) — the Claude Code install, end to end
- [Codex CLI hooks: PreToolUse & PostToolUse reference](/blog/codex-cli-hooks-reference) — what Codex's hook surface covers, and what it doesn't
- [Claude Code cost tracking: token counters vs per-action attribution](/blog/claude-code-cost-tracking) — pricing the surface you just captured

**The incidents, one family at a time** — the [Stop Your Agent From… series](/series/stop-your-agent):

- [running `rm -rf`](/blog/stop-your-agent-from-running-rm-rf) · [deleting your production database](/blog/stop-your-agent-from-deleting-your-database) · [touching files outside your project](/blog/stop-your-agent-from-touching-files-outside-your-project) · [rewriting git history](/blog/stop-your-agent-from-rewriting-git-history)
- [leaking `.env` secrets](/blog/stop-your-agent-from-leaking-env-secrets) · [leaking PII through tool calls](/blog/stop-your-agent-from-leaking-pii-through-tool-calls) · [being weaponized by a malicious package](/blog/stop-your-agent-from-being-weaponized-by-a-malicious-package)
- [burning your API budget](/blog/stop-your-agent-from-burning-your-api-budget) · [making payments without approval](/blog/stop-your-agent-from-making-payments-without-approval) · [dropping a Kubernetes namespace](/blog/stop-your-agent-from-dropping-a-kubernetes-namespace) · [escalating IAM permissions](/blog/stop-your-agent-from-escalating-iam-permissions)

All the first-party numbers behind these pages — the captures, the metered calls, the benchmark — live on [the data page](/data), with method and provenance for each.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Dataset",
  "name": "The Coding Agent Tool Surface Index",
  "url": "https://agenticcontrolplane.com/tool-surfaces",
  "description": "Declared tool surfaces of AI coding agents, captured from live API traffic: Claude Code v2.1 declares 76 tools at session start (35 core harness — 37 with two that registered mid-session — 21 browser control, 20 connectors); OpenAI Codex CLI v0.142 declares 17. Grouped by blast radius with a recommended allow/flag/deny posture per family.",
  "creator": { "@type": "Organization", "name": "Agentic Control Plane", "url": "https://agenticcontrolplane.com" },
  "temporalCoverage": "2026-07",
  "license": "https://creativecommons.org/licenses/by/4.0/",
  "isAccessibleForFree": true
}
</script>

---

*Captures dated 2026-07. Surfaces change with client versions — if you spot a drift we haven't indexed yet, [tell us](/community).*
