Skip to content
Agentic Control Plane

Hermes Agent permissions: governing every tool call with ACP

David Crowe David Crowe · · Updated · 4 min read
governance hermes-agent nous-research coding-agents agentic-control-plane plugin-launch
Share X HN LinkedIn

Hermes Agent, the terminal coding agent from Nous Research, works with ACP through the acp-hermes Python plugin. Three commands install it:

pip install acp-hermes
hermes plugins enable acp
acp-hermes login   # if this errors about editor/ACP mode, use: python -m acp_hermes.cli login

After a restart, every Hermes tool call is checked against your ACP workspace before it runs. That includes terminal, file, web, browser, vision, cron and your own skills. There is no feature flag and no second connector to cover the tools the hook can’t see.

Of the harnesses we’ve wired up, Hermes was the simplest. Here is why.

Hook coverage differs a lot between harnesses

ACP works with about fifteen coding-agent harnesses (see the coverage matrix for the current list). They differ in how many tools their pre-call hook sees. A few examples, as of November 2026:

Harness What the pre-call hook sees
Claude Code All native tools and MCP
Codex CLI Shell, apply_patch edits, MCP and other local tools on current builds. Shell only on older builds. Hosted tools like web search never reach a hook.
Cursor Most native tools. Some built-ins don’t emit events (bugs filed).
Hermes Everything, native and custom.

This matters because “my agent is governed” means different things on each one. If the hook doesn’t fire for a tool, your rules never see that tool. On Hermes there is no such gap to work around.

Why Hermes ended up this way

Hermes hooks are Python callbacks. A plugin’s register(ctx) hands Hermes a function, and Hermes calls it in-process before it runs a tool. The hook gets the tool name, the arguments and the session ID. If it returns {"action": "block", "message": ...}, Hermes skips the call.

That design has three results:

  1. Coverage is automatic. Every tool goes through the same dispatcher. Adding a new built-in or custom skill doesn’t open a gap.

  2. Hooks are synchronous. The tool waits until the hook answers. A governance hook should work that way.

  3. The plugin has to be a Python module. We couldn’t reuse the govern.mjs hook file we ship for other harnesses. In a connected setup, the installer now finds Hermes, picks the right Python interpreter, installs acp-hermes and enables it. A direct pip install acp-hermes still works for local or manual setups.

What the plugin does

Two hooks, calling the same gateway endpoints as the other harness plugins:

  • pre_tool_call posts to /govern/tool-use and gets back allow, ask or deny. A deny or an ask blocks the call and shows a message. An allow passes through. The plugin sends X-GS-Client: hermes-plugin/<version>, so per-client rules and dashboard filters work as they do elsewhere.

  • post_tool_call posts to /govern/tool-output. The gateway scans and logs the result, but Hermes ignores what this hook returns, so ACP can’t rewrite the result before the model reads it. Hermes does have a transform_tool_result hook that could do it. The plugin doesn’t register it yet.

The plugin has no dependencies beyond Python’s standard library (urllib). Fewer dependencies means less supply-chain exposure for something that handles credentials.

What you see in the dashboard

A hermes-plugin row on cloud.agenticcontrolplane.com/agents, with activity grouped by Hermes’s task_id. Each row has:

  • tool_name, such as terminal, web_search, read_file or a custom skill
  • tool_input, the arguments the model passed
  • tool_output, truncated to 200 KB
  • duration_ms
  • the usual ACP fields: workspace, user, decision

These are the same fields the Claude Code, Codex and Cursor rows have, and the same rules apply. A team can mix harnesses in one workspace.

Two limits

ACP can’t rewrite tool output on Hermes today. Say a terminal command prints a secret. ACP logs the finding, but the secret still reaches the model. Claude Code can swap in a redacted result. Stop most problems at the pre-call check, before the command runs.

A hold becomes a block. Hermes only knows block or don’t block. When the gateway answers ask, the plugin blocks the call with a message saying approval is required. You approve it on the Approvals page or from the approval email, then ask the agent to retry. An unanswered request expires and counts as denied. Only Claude Code shows a hold as an in-session prompt today.

Try it

pip install acp-hermes
hermes plugins enable acp
acp-hermes login

The full guide is at /integrations/hermes. If you already use ACP with another harness, acp-hermes login sees your existing ~/.acp/credentials and skips the sign-in. One workspace covers every harness.

Running Hermes? One command adds a hook. Each tool call it sees is recorded, and a force-push, destructive SQL or curl | sh is blocked until you approve it on the console or from the email.

macOS · Linux · WSL
curl -fsSL https://agenticcontrolplane.com/install.sh | bash
Windows · PowerShell
irm https://agenticcontrolplane.com/install.ps1 | iex

What the installer writes  ·  Hermes guide  ·  free up to 5 agents

Share X HN LinkedIn
Get the next data drop
What agents actually cost, new tool-surface captures, and the occasional incident post-mortem — sent when we publish something worth your inbox, not on a schedule. Unsubscribe anytime.
Share: Twitter LinkedIn
Related posts

← back to blog