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

# Hermes

> Run durable, cited Nimble Agent API V2 research runs from inside the Hermes agent using the standalone hermes-nimble-agent plugin.

The [`hermes-nimble-agent`](https://pypi.org/project/hermes-nimble-agent/) plugin connects [Hermes](https://hermes-agent.nousresearch.com/) to Nimble [Agent API V2](/nimble-sdk/web-search-agents/overview). It lets a Hermes user start a research run, walk away, and retrieve a cited answer later from any session.

Agent API V2 is not a single search or extract call. It runs a stateful, asynchronous research workflow on Nimble's infrastructure. The plugin returns durable identifiers the moment a run starts, then the research continues after Hermes returns. Any later Hermes session can resume the run using those identifiers.

<Note>
  The standalone plugin is the recommended path. A [production MCP fallback](#production-mcp-fallback) exists for clients that cannot install the plugin, but it does not offer full parity.
</Note>

## Overview

The plugin adds five tools and one skill to Hermes:

* **Five tools** cover the run lifecycle: discover an agent, create one from a template if needed, start a run, check status, and fetch the result.
* **One skill**, `nimble-agent:agent-research`, teaches Hermes the reuse-first, poll-later workflow so runs are handled correctly without manual prompting.

Every run returns an answer with a trust block: overall confidence, per-claim citations, and verbatim source excerpts. That trust model is the reason to use Agent API V2 instead of a raw search result.

The workflow is asynchronous by design:

1. Start a run. The plugin returns `agent_id` and `run_id` immediately and never blocks.
2. The research continues on Nimble's infrastructure.
3. Check status later, from the same session or a new one, using the two identifiers.
4. Fetch the terminal result once the run completes.

## Prerequisites

<AccordionGroup>
  <Accordion title="Hermes 0.19 or later">
    The plugin is built and tested against `hermes-agent==0.19.0`. Install it into the **same Python environment** as `hermes-agent`.
  </Accordion>

  <Accordion title="Python 3.11 or later">
    Supported on Python 3.11, 3.12, and 3.13. The plugin depends on `nimble-python>=1.0.0,<2`, which pip installs automatically.
  </Accordion>

  <Accordion title="Nimble account and API key">
    Create a Nimble account and generate an API key from [Account Settings > API Keys](https://online.nimbleway.com/account-settings/api-keys). A free trial is available. No extra subscription, quota, or availability tier is required beyond a valid key.
  </Accordion>
</AccordionGroup>

## Installation

Install the plugin, then enable it in Hermes.

```bash theme={"system"}
pip install hermes-nimble-agent==0.1.0   # same environment as hermes-agent
hermes plugins enable nimble-agent
```

The plugin slug is `nimble-agent`. Enabling adds it to the Hermes allow-list. Plugins are opt-in and stay disabled until enabled.

<Warning>
  Enabling takes effect on the next session. Start a new Hermes session before the tools become visible.
</Warning>

Verify that the plugin and its five tools loaded:

```bash theme={"system"}
hermes plugins list
```

If the tools do not appear, run `HERMES_PLUGINS_DEBUG=1 hermes plugins list` to see discovery details.

## Authentication

The plugin reads your key from the `NIMBLE_API_KEY` environment variable. It is never passed as a tool argument.

```bash theme={"system"}
export NIMBLE_API_KEY="your-nimble-api-key"
```

<Warning>
  Use a placeholder or an environment variable. Never commit a real key or paste one into a prompt or config file.
</Warning>

Two behaviors protect the key:

* **Tools stay hidden when the key is missing.** All five tools are gated on `NIMBLE_API_KEY`. If it is absent or empty, Hermes does not show them to the model. Set the key and start a new session to reveal them.
* **The key is scrubbed from errors.** The plugin never stores, logs, or echoes the key, and replaces it with `[REDACTED]` in any error text before returning it.

The plugin also tags every request with the header `X-Client-Source: hermes` automatically. Nothing to configure.

## Available tools

The toolset name is `nimble_agent`. Each tool returns a JSON string and never raises.

| Tool                      | Purpose                                                         | Required inputs      | Optional inputs            |
| ------------------------- | --------------------------------------------------------------- | -------------------- | -------------------------- |
| `nimble_agents_list`      | List account agents. Discover an existing agent to reuse.       | none                 | `limit` (1-50), `offset`   |
| `nimble_agent_bootstrap`  | List prebuilt templates, or create a persistent agent from one. | none                 | `template`, `display_name` |
| `nimble_agent_run_start`  | Start an async run. Returns identifiers immediately.            | `agent_id`, `task`   | `effort`                   |
| `nimble_agent_run_status` | Check run status using the identifiers alone.                   | `agent_id`, `run_id` | none                       |
| `nimble_agent_run_result` | Fetch the terminal answer and trust metadata.                   | `agent_id`, `run_id` | none                       |

How they connect:

* `nimble_agents_list` and `nimble_agent_bootstrap` produce an `agent_id` (`wsa_...`). Reuse an existing agent before creating a new one.
* `nimble_agent_run_start` takes that `agent_id` plus a `task` (the research question) and returns a `run_id` (`task_run_...`).
* `nimble_agent_run_status` and `nimble_agent_run_result` take both identifiers. They work from any session, so the two identifiers are all a later session needs.

### The agent-research skill

The plugin bundles a skill named `nimble-agent:agent-research`. It teaches the full lifecycle: reuse before create, return identifiers within the turn, avoid tight polling, resume from identifiers alone, handle `not_ready` and failed runs, and present answers with citations and confidence.

Plugin skills are opt-in and do not appear in the system-prompt skill index. Load it explicitly when you want Hermes to follow the workflow:

```text theme={"system"}
skill_view('nimble-agent:agent-research')
```

## Complete asynchronous workflow

This example uses placeholder identifiers and a generic research question. Identifier values shown are illustrative.

<Steps>
  <Step title="Select or create an agent">
    List existing agents and reuse one when possible:

    ```text theme={"system"}
    nimble_agents_list()
    ```

    If none fits, list templates and create an agent from one:

    ```text theme={"system"}
    nimble_agent_bootstrap()                           # lists available templates
    nimble_agent_bootstrap(template="<template-name>") # creates an agent from a listed template
    ```

    Use a `template` value from the list the first call returns. Both paths yield an `agent_id` such as `wsa_xxxxxxxxxxxx`.
  </Step>

  <Step title="Start a research run">
    Start a medium-effort run. `effort` is optional; omit it to use the agent's default.

    ```text theme={"system"}
    nimble_agent_run_start(
      agent_id="wsa_xxxxxxxxxxxx",
      task="Summarize the main approaches to retrieval-augmented generation and cite sources.",
      effort="medium"
    )
    ```

    The response returns immediately:

    ```json theme={"system"}
    {
      "run": { "run_id": "task_run_xxxxxxxxxxxx", "agent_id": "wsa_xxxxxxxxxxxx", "status": "queued", "effort": "medium", "is_active": true },
      "agent_id": "wsa_xxxxxxxxxxxx",
      "run_id": "task_run_xxxxxxxxxxxx",
      "next": "Save both identifiers. Check status later with nimble_agent_run_status."
    }
    ```
  </Step>

  <Step title="Preserve the identifiers">
    Record `agent_id` and `run_id`. They are the only state needed to resume. You can now end the session or move on to other work.
  </Step>

  <Step title="Check status later">
    From the same session or a new one:

    ```text theme={"system"}
    nimble_agent_run_status(agent_id="wsa_xxxxxxxxxxxx", run_id="task_run_xxxxxxxxxxxx")
    ```

    `status` is `queued` or `running` while active, and `completed`, `failed`, or `cancelled` when terminal.
  </Step>

  <Step title="Fetch the result">
    Once the run is `completed`:

    ```text theme={"system"}
    nimble_agent_run_result(agent_id="wsa_xxxxxxxxxxxx", run_id="task_run_xxxxxxxxxxxx")
    ```

    The result carries the answer and its trust block. Present the answer, then list the sources and per-claim citations.
  </Step>
</Steps>

<Note>
  Medium and higher efforts can take several minutes. Return the identifiers to the user rather than holding a tool call open, and space status checks tens of seconds apart.
</Note>

## Result and trust model

`nimble_agent_run_result` returns the answer wrapped in the plugin's result envelope:

```json theme={"system"}
{
  "success": true,
  "output": {
    "type": "text",
    "content": "Retrieval-augmented generation combines...",
    "trust": { "confidence": "high", "reasoning": "...", "sources": [ ... ], "claims": [ ... ] }
  },
  "sources_count": 7,
  "claims_count": 7,
  "agent_id": "wsa_xxxxxxxxxxxx",
  "run_id": "task_run_xxxxxxxxxxxx"
}
```

Envelope specifics:

* **`output.type`** is `text` for a prose answer, or `json` when the agent is configured with an output schema. Structured runs return `content` as an object or array.
* **`sources_count`** and **`claims_count`** are always present integers.

The `trust` block (overall confidence, per-claim citations, primary and secondary source classification, and verbatim excerpts) follows the standard Agent API V2 trust model. See [Trust](/nimble-sdk/web-search-agents/trust) for how grades and citations work, and the [run result schema](/api-reference/public-api/get-agent-run-result) for every field.

<Warning>
  The trust block is present but its detail varies with effort. A `low`-effort run may consult few or no live sources, in which case it honestly reports low confidence with zero sources. Use `medium` or higher when citations matter.
</Warning>

## Errors and recovery

Every failure returns a structured envelope: `{ "success": false, "error_type": "...", "error": "...", "retriable": true|false }`. The `agent_id` and `run_id` are preserved even on validation errors, so a run is never lost to a client-side error.

| `error_type`       | Meaning                                   | Action                                                                  | Retriable |
| ------------------ | ----------------------------------------- | ----------------------------------------------------------------------- | --------- |
| `not_ready`        | Result requested before the run finished. | Check status, then retry the result later.                              | Yes       |
| `terminal_failure` | Run failed or was cancelled.              | Read the server message. Start a new run if appropriate.                | No        |
| `auth`             | API key missing or invalid.               | Set a valid `NIMBLE_API_KEY`.                                           | No        |
| `permission`       | Key lacks access to the resource.         | Check account permissions.                                              | No        |
| `not_found`        | Unknown `agent_id` or `run_id`.           | Confirm the identifiers.                                                | No        |
| `validation`       | Bad or missing arguments.                 | Fix the arguments and retry.                                            | No        |
| `rate_limited`     | Too many requests.                        | Back off, then retry. See [Rate limits](/nimble-sdk/admin/rate-limits). | Yes       |
| `timeout`          | Request timed out in transit.             | Retry. The run may still be active.                                     | Yes       |
| `connection`       | Network error reaching Nimble.            | Retry. The run may still be active.                                     | Yes       |
| `dependency`       | `nimble-python` is not installed.         | Install it in the Hermes environment.                                   | No        |
| `protocol`         | Unexpected API response shape.            | Retry status or result. Report if it persists.                          | No        |

<Note>
  A transport error such as `timeout` or `connection` does not necessarily end the server-side run. The run keeps going on Nimble's infrastructure. Check status again with the same identifiers before starting over.
</Note>

Poll considerately. Space status checks tens of seconds apart rather than in a tight loop.

## Effort and runtime guidance

`nimble_agent_run_start` accepts an optional `effort` (`low`, `medium`, `high`, `x-high`, `max`). Omit it to use the agent's default. Higher effort reads more sources and takes longer, from seconds at `low` to many minutes at higher tiers.

See [Efforts](/nimble-sdk/web-search-agents/efforts) for the full tier list, typical run times, pricing, and the default. The bundled skill suggests `medium` or higher when citations matter.

Because a run can take minutes, the plugin returns `agent_id` and `run_id` immediately rather than holding a tool call open. Let the model report the identifiers, then check status later and space checks tens of seconds apart.

## Plugin or MCP?

| Consideration        | Standalone plugin                                             | Production MCP fallback                   |
| -------------------- | ------------------------------------------------------------- | ----------------------------------------- |
| Recommended status   | Primary                                                       | Secondary fallback                        |
| Installation         | PyPI plus `hermes plugins enable`                             | `~/.hermes/config.yaml` MCP server entry  |
| Run lifecycle        | Five dedicated tools (list, bootstrap, start, status, result) | Generic Nimble agent MCP tools            |
| Identity requirement | Requires `agent_id`                                           | Requires `agent_id`                       |
| Resumable runs       | Yes, from identifiers alone                                   | Yes, same durable identifiers             |
| Trust and citations  | Full trust block mapped for you                               | Raw API result; presentation is up to you |
| Attribution          | `X-Client-Source: hermes` sent automatically                  | Set the header manually in config         |
| Tool filtering       | Fixed five-tool toolset                                       | Allowlist you define                      |
| Credential redaction | Built in                                                      | Not provided                              |
| Bundled skill        | `nimble-agent:agent-research` included                        | Not included                              |

The plugin is the recommended path. Generic MCP connectivity to Nimble does not by itself provide the plugin's lifecycle handling, trust mapping, credential redaction, or bundled skill.

## Production MCP fallback

Use this path only when installing the plugin is not possible. It connects Hermes to the production Nimble MCP server over Streamable HTTP. Treat the block below as a starting configuration and validate it against your Hermes and Nimble MCP versions before relying on it.

Add the server to `~/.hermes/config.yaml`:

```yaml theme={"system"}
mcp_servers:
  nimble:
    url: "https://mcp.nimbleway.com/mcp"
    headers:
      Authorization: "Bearer ${NIMBLE_API_KEY}"
      X-Client-Source: "hermes"
    timeout: 60
    tools:
      include:
        - nimble_agents_list
        - nimble_agents_run
        - nimble_agents_run_status
        - nimble_agents_run_result
```

Notes:

* **Authentication** uses a bearer token. Keep the key in the `NIMBLE_API_KEY` environment variable and reference it with `${NIMBLE_API_KEY}`.
* **Attribution** over MCP is manual. Add `X-Client-Source: hermes` to the headers as shown. It is not sent automatically the way the plugin sends it.
* **The tool allowlist** limits Hermes to the agent run lifecycle. Confirm the exact tool names against your server's advertised tool list, since a name that does not match is silently filtered out, and adjust the list to your needs.
* **Timeouts** should allow for research that runs for minutes. Runs continue server-side even if a request times out.
* Reload the server mid-session with `/reload-mcp`, or restart Hermes.

<Warning>
  The MCP fallback requires an explicit `agent_id`, the same as the plugin. It does not provide the plugin's trust mapping, credential redaction, or bundled skill, and is not a full-parity replacement. See the [Nimble MCP Server](/integrations/mcp-server/mcp-server) docs for the full server reference.
</Warning>

## Troubleshooting

| Symptom                           | Cause                                        | Action                                                                      |
| --------------------------------- | -------------------------------------------- | --------------------------------------------------------------------------- |
| Plugin does not appear            | Not enabled                                  | Run `hermes plugins enable nimble-agent`, then start a new session.         |
| Tools are hidden                  | `NIMBLE_API_KEY` missing                     | Set the key, then start a new session.                                      |
| Enabled but no tools this session | Enabling applies to the next session         | Start a new Hermes session.                                                 |
| Wrong Python environment          | Plugin not in the `hermes-agent` environment | Reinstall in the same environment. Confirm with `hermes plugins list`.      |
| `auth` error                      | Key missing or invalid                       | Set a valid `NIMBLE_API_KEY`.                                               |
| Run stays `queued` or `running`   | Research still in progress                   | Wait and check status again. Higher effort takes longer.                    |
| Lost identifiers                  | `agent_id` or `run_id` not saved             | Use `nimble_agents_list` to find the agent. Preserve identifiers next time. |
| Result says `not_ready`           | Run not finished                             | Check status, then retry the result.                                        |
| `rate_limited`                    | Too many requests                            | Back off, then retry.                                                       |
| MCP auth or timeout failure       | Bad header or short timeout                  | Check the `Authorization` header and raise `timeout`.                       |

## Related resources

<CardGroup cols={2}>
  <Card title="PyPI package" icon="python" href="https://pypi.org/project/hermes-nimble-agent/">
    Install `hermes-nimble-agent` from public PyPI.
  </Card>

  <Card title="GitHub repository" icon="github" href="https://github.com/Nimbleway/hermes-nimble-agent">
    Source, README, and release notes.
  </Card>

  <Card title="Search Agent" icon="bullseye-pointer" href="/nimble-sdk/web-search-agents/overview">
    Learn how Nimble Agent API V2 research runs work.
  </Card>

  <Card title="Trust and citations" icon="shield-check" href="/nimble-sdk/web-search-agents/trust">
    How confidence, sources, and per-claim citations are produced.
  </Card>

  <Card title="Nimble MCP Server" icon="server" href="/integrations/mcp-server/mcp-server">
    Full reference for the production MCP fallback.
  </Card>

  <Card title="Hermes plugins" icon="feather" href="https://hermes-agent.nousresearch.com/docs/user-guide/features/plugins">
    How Hermes discovers and enables plugins.
  </Card>
</CardGroup>
