# Hermes Agent

> Connect Hermes Agent to Golem with its plugin, so each tool call is checked against your rules and recorded.

When you [install Golem](/install) on a machine that has Hermes Agent, the Golem agent downloads its Hermes plugin, checks it against the release checksums, and enables it. The plugin uses nothing but Hermes's own hooks, so every Hermes session works the same way whether it started in the CLI, Telegram, Discord, Slack or another gateway. Restart Hermes after the first install.

## What Golem adds

| Where | What |
|---|---|
| `~/.hermes/plugins/golem/` | The Golem plugin. Golem also runs `hermes plugins enable golem`, because Hermes leaves general plugins off until they are enabled. |
| `mcp_servers` in `~/.hermes/config.yaml` | Golem's two MCP servers, `golem-witness` and `golem-context`. Only those two entries are edited, so your comments and other servers are kept. |
| `~/.hermes/skills/` | Golem's skills, including `/safely`. |

To install or refresh the plugin by hand:

```bash
golem install hermes-plugin
```

Running it again is the update path, as is `golem update hermes-plugin`. The new copy is unpacked beside the old one and swapped in, so a failed download leaves the working plugin in place. The command refuses if there is no Hermes on the machine (no `~/.hermes` and no `hermes` on the `PATH`). If `hermes` is not on the `PATH`, the files still land and the command prints the one step left:

```bash
hermes plugins enable golem
```

## What a block and a hold look like

Before each tool call, the plugin asks the Golem agent for a decision. A **block** refuses the call, and Hermes shows the reason, which names the rule:

```text
policy block: no-force-push-to-main
```

A rule set to Ask becomes Hermes's own approval prompt, with the same reason. The approval is scoped to that rule, so answering *always* for one Golem rule does not approve every other Golem rule on the same tool.

Hermes puts every held call to the person at the keyboard, including one a rule gives to your team or to Golem's reviewer agent.

Type `/safely` to restrict a session to a read-only profile; the plugin sends your prompt to the Golem agent, which clamps the session itself. A machine you [quarantine](/response#quarantine-a-machine) is held to its locked-down toolset on the same check. See [Safely](/response#safely) and [Block, hold and contain](/response).

## What is recorded

| Hermes hook | What Golem does |
|---|---|
| `pre_llm_call` | Sends the prompt to the Golem agent, which arms `/safely` from it and answers with fleet context and messages from other agents for the turn. The prompt itself is not recorded. |
| `pre_tool_call` | Checks the call against your rules, and screens any URL or host in its arguments, including one inside a shell command, against the threat-intelligence feeds the workspace has set, if any. |
| `post_tool_call` | Records the call: its arguments, how long it took, the size of its result, and whether it worked. |
| `post_llm_call` | Records the agent's reply, as text. |

The plugin deliberately leaves out the tool's output and Hermes's error message, which is cut from that output. Only the kind of error is recorded. Each entry is signed into the session's [record](/record) under the agent `hermes-agent`. Several sessions can run at once across gateways; each keeps its own chain.

### Settings

Nothing is required. To change anything, add a block to `~/.hermes/config.yaml`:

```yaml
plugins:
  entries:
    golem:
      settings:
        enforce: true
        timeout_seconds: 3.0
```

| Setting | Default | What it does |
|---|---|---|
| `witness_url` | `GOLEM_WITNESS_URL`, or `http://127.0.0.1:39393` | Where the Golem agent listens. |
| `timeout_seconds` | `3.0` | How long to wait for the Golem agent. Every timeout allows the call. |
| `enforce` | `true` | `false` records without ever refusing, for an observe-first rollout. |
| `inject_context` | `true` | Whether fleet context and other agents' messages are added to a turn. |
| `capture_responses` | `true` | Whether the agent's replies are recorded. |
| `host_id` | `GOLEM_HOST_ID`, or the hostname | The machine name in the record. |
| `agent_id` | `hermes-agent` | The agent name in the record. |
| `bash_tools` | `terminal`, `shell`, `bash`, `run_command` | Tools whose arguments are checked as shell commands. |

## Check that it is working

```bash
hermes plugins
```

The list should include `golem`. Every hook fails open, so a machine with no Golem agent, one that never enrolled, and a working install all look the same from inside Hermes. The plugin tells them apart at startup, and `/golem` prints the same line mid-session:

| What it prints | What it means |
|---|---|
| `nothing is recording this session` | No Golem agent is answering. The message lists the setup steps for your OS. |
| `running but NOT ENROLLED` | The Golem agent is installed but not in a workspace, so nothing it records is accepted. Run `golem join --key glk_...` with a key from the console. |
| `agent <version> on <host>, enforce=…` | Working. |
| `N entries buffered` | Delivery is failing upstream. Run `golem doctor`. |

Then open **Conversations** in the console at [app.golem.team](https://app.golem.team) and look for the agent `hermes-agent`.

## Limits

- **It fails open.** A Golem agent that is down, slow or not wired lets the call run, and recording is dropped rather than stall Hermes.
- **Keep the timeout short.** Hermes refuses a tool call when a `pre_tool_call` hook outruns its own `plugins.hook_callback_timeout` (30 seconds by default). Above 10 seconds, the plugin warns at startup.
- **Every Ask goes to the person at the keyboard.** A rule meant for your team or the reviewer agent is decided by whoever answers Hermes's prompt.
- **Only the arguments of `bash_tools` are read as shell commands.** A shell tool with another name is checked as an ordinary tool; add it to `bash_tools`.
- **The shell jail does not apply.** It covers Claude Code on macOS. See [Shell jail and sandbox](/shield).

More in [Coverage](/coverage) and [Limits](/limits).

## Remove it

`golem setup-client --remove` removes the plugin, servers and skills from every AI client on the machine, Hermes included, and records the choice so the periodic check does not put them back. To remove Golem entirely, see [Uninstall](/install#uninstall).
