<!-- Generated from /guides/hermes by scripts/make-markdown.mjs. The page is the source. -->

# Screen tool calls in Hermes Agent

Hermes Agent starts each MCP server in its configuration as a local process and talks to it over stdio. agent-chaperone goes in front of that process, and a plugin puts the same screens in front of the tools Hermes runs itself: its terminal, its file edits and its web fetches.

This page covers both. The plugin needs 0.4.0 or later, and so does `wrap` for Hermes's YAML configuration.

## Install it

```
npm install -g agent-chaperone
```

A global install means Hermes starts the proxy directly, and it is where the plugin below finds the command and its own files.

## Put a server behind it

Hermes reads servers from `~/.hermes/config.yaml`, under `mcp_servers`. `agent-chaperone wrap` makes the edit. It prints what it would change and writes nothing until you add `--write`, keeps the original beside the file, and writes back only the entries it changed, so the comments in the file stay.

```
agent-chaperone wrap ~/.hermes/config.yaml
agent-chaperone wrap ~/.hermes/config.yaml --write
```

A server entry before and after:

```
mcp_servers:
  filesystem:
    command: npx
    args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/me/project"]
```

```
mcp_servers:
  filesystem:
    command: agent-chaperone
    args:
      - --server
      - filesystem
      - --
      - npx
      - -y
      - "@modelcontextprotocol/server-filesystem"
      - /home/me/project
```

Everything after `--` is the server that would have run anyway. `--server` names the section of the policy file that applies, after the name you gave the server in Hermes. Keys such as `env`, `timeout` and `enabled` are kept as they were. `--unwrap` takes it all back out.

## Give it the API key

The model screens need `TYPESAFE_API_KEY`. Hermes does not hand a server its own environment: a stdio server gets a short list of safe variables, such as `PATH` and `HOME`, plus whatever the entry's `env` names. A key exported in your shell does not reach the proxy on its own.

Put the key in `~/.hermes/.env` and name it in the entry. Hermes fills in `${...}` from that file when it starts the server, so the key itself stays out of `config.yaml`:

```
mcp_servers:
  filesystem:
    command: agent-chaperone
    args: ["--server", "filesystem", "--", "npx", "-y", "@modelcontextprotocol/server-filesystem", "/home/me/project"]
    env:
      TYPESAFE_API_KEY: "${TYPESAFE_API_KEY}"
```

The proxy removes its own keys before it starts the server behind it, so the server never receives `TYPESAFE_API_KEY`.

Without a key the proxy still starts, the deterministic rules still run, and every judgment records that no model was asked. It never refuses to start because a key is missing.

## Screen Hermes's own tools

The terminal, file edits and web fetches Hermes runs itself never cross an MCP connection. A plugin reaches them. Hermes ignores what a shell hook prints after a tool has run, so only a plugin can change what the model reads, and this one hands each call and each result to `agent-chaperone hook pre` and `hook post`. It ships in the npm package:

```
cp -R "$(npm root -g)/agent-chaperone/integrations/hermes" ~/.hermes/plugins/agent-chaperone
hermes plugins enable agent-chaperone
```

Hermes loads no plugin until it is enabled, which is what the second line does. It adds the name to `plugins.enabled` in `config.yaml`, and you can write that by hand instead.

A held call goes to Hermes's own approval prompt. Its "always" answer is remembered for that exact call, so it never allows every later use of the tool. Hermes approves the prompt by itself when `approvals.mode` is `off` or YOLO mode is on, and refuses the call when nobody is there to answer.

A result judged unsafe is withheld: the plugin hands Hermes a notice in place of the tool's result. The tools it screens, and what each command answers, are in [the hooks reference](https://agentchaperone.dev/docs/hooks#hermes-agent). MCP tools are left to the proxy, so a wrapped server is not screened twice.

The plugin starts the command with Hermes's own environment, which includes `~/.hermes/.env`, so the key from the step above reaches it too.

## Check that it is working

```
hermes mcp test filesystem
hermes plugins list
```

The first connects to the wrapped server, which starts the proxy in front of it. If it fails, `hermes logs mcp` shows what the process printed. The second should show `agent-chaperone` as enabled.

Then use the server and the terminal once from the agent, and read what was decided:

```
agent-chaperone log
```

Each line is one call or result, with the decision and, in shadow mode, what enforcing would have done instead. Calls from the plugin are recorded under the server name `built-in`. A line ending in `[not screened]` was decided without a model, which means the key did not arrive.

## What this does not cover

- **A live run, yet.** The plugin and the YAML support were written against Hermes Agent 0.16.0's published contract and its source, and tested on payloads in its shape. They have not been checked in a live run of Hermes yet.
- **A result that is not a string.** A tool that returns images alongside text hands Hermes a structure rather than a string, and the plugin leaves it as it came, unscreened.
- **A failure of the plugin's own.** A missing `agent-chaperone`, a crash, or an answer that does not parse lets the call through rather than blocking it. The plugin waits 25 seconds, under the 30 Hermes allows a plugin before it refuses the call itself.
- **A server that authenticates with headers.** Headers written in the Hermes entry stay with Hermes and never reach the proxy, which is why `wrap` leaves such an entry alone. Put it behind the proxy by hand, as [the MCP guide](https://agentchaperone.dev/guides/mcp-security#wrap) shows, and pass the token with `--header-env`.
- **What a server or a tool does rather than what the call says.** This is not a sandbox. It reads the call and the result, and a tool that does something its arguments did not describe is outside it.

## Next

It starts in shadow mode, which blocks nothing. [The MCP guide](https://agentchaperone.dev/guides/mcp-security) covers what each screen asks, how to read a shadow-mode log, and when to switch to enforce. The exact wording of every question is in [the design document](https://agentchaperone.dev/docs/design).

---

Source: https://agentchaperone.dev/guides/hermes
Put Hermes Agent's MCP servers behind agent-chaperone, get the API key past its filtered environment, and screen its own tools with the plugin.
