> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codezero.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Hermes Agent

> Set up cordon to give Hermes Agent secure API access without exposing secrets.

Cordon integrates with [Hermes Agent](https://hermes-agent.nousresearch.com/) so your AI agent can make authenticated API calls without holding real credentials.

## Scope

Hermes setup treats the default `~/.hermes/` profile as its own cordon project. It stores config at `~/.hermes/cordon.toml` and writes proxy env vars to `~/.hermes/.env`, so Hermes is isolated from unrelated repository configs while still working across projects.

Hermes does not expose `--scope`, and setup rejects the generic user-scope config at `~/.config/cordon/cordon.toml`. If you need follow-up commands such as `cordon route`, `cordon start`, `cordon env`, or `cordon service`, pass `--config ~/.hermes/cordon.toml`. Automated setup only supports the default profile in v1; `HERMES_HOME` must be unset or point at `~/.hermes`.

See [Scopes](/configuration/overview#scopes) for path details and trade-offs.

## Automated setup

The fastest way to get started:

```bash theme={null}
cordon setup hermes
```

This:

1. Generates CA certificates (if not already present)
2. Creates a scaffold `~/.hermes/cordon.toml`
3. Creates `tokens.toml` with a default token (if one doesn't already exist), plus a `hermes` client token wired into the tokenized proxy URL — see [Token migration](/guides/token-migration)
4. Writes the standard proxy and CA env vars from `cordon env --config ~/.hermes/cordon.toml` to Hermes's `~/.hermes/.env`
5. Installs a cordon agent skill to `~/.hermes/skills/devops/cordon/SKILL.md`
6. Offers to add routes and store secrets interactively (post-setup wizard)

Your existing `.env` is backed up to `.env.cordon.bak` before any changes are made.

`cordon setup hermes` also prompts "Install as a background service so cordon starts automatically?" (default No). Answer yes, or pass `--service` to install non-interactively. If you skipped it, run `cordon service install --config ~/.hermes/cordon.toml` afterward.

### Remove the setup

```bash theme={null}
cordon integration disable hermes
```

## Adding routes

After setup, add a route for your LLM provider with [`cordon route add --config ~/.hermes/cordon.toml`](/cli/route) and, if using the keyring secret source, store the credential with [`cordon secret set`](/cli/secret). Pass `--config ~/.hermes/cordon.toml` to `cordon route`, `cordon start`, and `cordon service` commands so they target the Hermes config.

<Warning>
  Anthropic uses `type: header` with `header_name: x-api-key` and no `scheme`. Using an `Authorization` header will result in 401 errors.
</Warning>

## Provider auto-detection

Hermes uses env vars to auto-detect which LLM provider to use. Since cordon injects the real API key at the network layer, Hermes still needs a dummy key to select the right provider. Add a placeholder to `~/.hermes/.env`:

```bash theme={null}
# Hermes sees this and selects the Anthropic provider.
# Cordon strips it and injects the real key from the keychain.
ANTHROPIC_API_KEY=dummy-replaced-by-cordon
```

Without this, Hermes won't know which provider to use and will fail to make API calls even though cordon has the real credentials ready to inject.

## Manual setup

Prefer `cordon setup hermes` for the default Hermes profile. It writes the proxy and CA settings, generates the combined CA bundle, and backs up the existing `.env` before changing it. If setup cannot cover your environment, copy the values from [`cordon env --config ~/.hermes/cordon.toml`](/cli/env) to the relevant Hermes `.env` file manually:

```bash theme={null}
HTTPS_PROXY="http://<audience>:<token>@127.0.0.1:<PORT>"
HTTP_PROXY="http://<audience>:<token>@127.0.0.1:<PORT>"
https_proxy="http://<audience>:<token>@127.0.0.1:<PORT>"
http_proxy="http://<audience>:<token>@127.0.0.1:<PORT>"
SSL_CERT_FILE="/path/to/combined-ca.pem"
REQUESTS_CA_BUNDLE="/path/to/combined-ca.pem"
CURL_CA_BUNDLE="/path/to/combined-ca.pem"
```

Use the exact authenticated proxy URL from `cordon env --config ~/.hermes/cordon.toml`; do not hand-type or commit the tokenized URL.

Automated setup does not write to custom `HERMES_HOME` locations in v1. See [Any tool (generic)](/guides/generic) for the full env-var contract when configuring non-default profiles by hand.

## How it works

Hermes uses Python's `httpx` library for HTTP, which honors `HTTPS_PROXY` by default (`trust_env=True`). The OpenAI, Firecrawl, and Exa SDKs all use `httpx` or `requests` internally, and Hermes's own Tavily client uses `httpx` directly, so all HTTP traffic routes through cordon automatically. No code changes or monkeypatching required.

For Cordon's matched-route TLS behavior and certificate troubleshooting, see [TLS](/configuration/tls).

### Sandboxed environments

Hermes supports several sandboxed execution backends (`TERMINAL_ENV`): `docker`, `singularity`, `modal`, `daytona`, and `ssh`. These environments run in isolated network namespaces where `127.0.0.1` refers to the container's or remote host's loopback, not the developer's machine. The cordon proxy running on the host is not reachable from inside these sandboxes without network bridging.

For local execution (`TERMINAL_ENV=local`), cordon works out of the box. For sandboxed backends, network reachability varies by backend and has not been fully tested. Docker may reach the host via `host.docker.internal` on macOS/Windows, but other backends (Modal, Daytona, SSH) have their own networking models. A remote cordon proxy with network-accessible binding would be needed for full support (not yet available).

## Workflow

Once configured, the workflow is:

1. Start cordon: `cordon start --config ~/.hermes/cordon.toml` (or use the background service)
2. Start Hermes as usual
3. When Hermes makes API calls that fully match configured routes, cordon transparently injects credentials
4. Hermes never sees or logs real API keys

<Tip>
  Use `cordon doctor` to diagnose any setup issues. It checks config validity, cert paths, trust store status, and port availability.
</Tip>

## Troubleshooting

<AccordionGroup>
  <Accordion title="401 Unauthorized errors">
    1. **Wrong header config**: Anthropic uses `type: header` with `header_name: x-api-key` and no `scheme`. Check your `cordon.toml` route configuration.
    2. **Missing dummy key**: Hermes won't select a provider without its API key env var set. Add `ANTHROPIC_API_KEY=dummy-replaced-by-cordon` to `~/.hermes/.env`.
    3. **Check the secret source**: HTTP route secrets are fetched per-request — if you changed a secret, the next request picks it up automatically.
    4. **Verify the secret is stored**: `cordon secret set anthropic`
  </Accordion>

  <Accordion title="Certificate errors">
    Verify `~/.hermes/.env` includes the CA bundle values from [`cordon env --config ~/.hermes/cordon.toml`](/cli/env), then follow [TLS troubleshooting](/configuration/tls#troubleshooting-certificate-errors).
  </Accordion>

  <Accordion title="Proxy not being used">
    Verify the env vars are in `~/.hermes/.env`:

    ```bash theme={null}
    cat ~/.hermes/.env
    ```

    Hermes loads this file at startup via `load_hermes_dotenv()`. If the file exists but Hermes isn't routing through the proxy, use the shared [proxy not running checks](/guides/process-management#proxy-not-running-checks) with `--config ~/.hermes/cordon.toml`.
  </Accordion>

  <Accordion title="Provider not detected">
    If Hermes can't determine which LLM provider to use, it's likely missing the dummy API key env var. Add the appropriate key to `~/.hermes/.env`:

    ```bash theme={null}
    ANTHROPIC_API_KEY=dummy-replaced-by-cordon    # for Anthropic
    OPENAI_API_KEY=dummy-replaced-by-cordon       # for OpenAI
    ```
  </Accordion>

  <Accordion title="Service restart required after config changes">
    Restart Cordon after adding or editing route definitions. See [Routes: route changes and secret rotation](/configuration/routes#route-changes-and-secret-rotation).
  </Accordion>
</AccordionGroup>
