Skip to content
Conduit

mcp server

unitares-host-adapter

Thin client bindings that mount UNITARES governance into agent hosts: Hermes Agent, and OpenAI-compatible clients through a governance proxy

cirwel/unitares-host-adaptercommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

Before you start

  • uv (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "unitares-host-adapter": {
      "command": "uvx",
      "args": [
        "unitares-host-adapter"
      ]
    }
  }
}

same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12

Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs

README

synced Oct 21, 2026

UNITARES for Hermes

Host integrations for UNITARES, self-hosted accountability infrastructure for long-running AI agents.

UNITARES connects process identities, claims, evidence, reviews, and outcomes in an operator-owned record that survives restarts, context loss, and handoffs. This package connects Hermes Agent and OpenAI-compatible clients to that server through lifecycle hooks or a request proxy.

The default Hermes plugin creates an identity for each active session and reports completed turns. Selected findings, evidence, reviews, and outcomes require explicit agent calls or additional integration. The server provides those capabilities; installing the adapter does not automatically capture them or reconstruct earlier work.

Start with the Hermes setup below. For the broader product and evidence behind its claims, see the UNITARES README and evidence and limits.

Hermes Agent

Coming from the Hermes plugin catalog? Start here. The catalog installs a reviewed commit; a direct repository install can contain newer, unreleased behavior.

Installation sourceVersion and behavior
Catalog entry, checked 2026-10-140.3.3, pinned to bf534cf: session identity and fixed turn reports.
This repository's master0.4.0a1, an unpublished continuity candidate: adds lineage links, numeric turn observations, and best-effort presence release. See candidate behavior.

The catalog page renders the README from its pinned commit. Editing this repository's README does not update that page or change what existing catalog installs run.

Install and enable

You need Hermes Agent 0.21.0 or later and a reachable UNITARES Streamable HTTP MCP server. The plugin does not start a server for you. If you need one, follow the UNITARES Docker install; its default local endpoint is http://127.0.0.1:8767/mcp/.

Install the reviewed version from the catalog UI or CLI:

hermes plugins install unitares

When prompted, set UNITARES_MCP_URL to your server's endpoint, including /mcp/ and its trailing slash. Accept the package dependency installation when Hermes asks; it builds this library and installs mcp and httpx into the Hermes environment. A separate pip install is unnecessary for the directory plugin.

If you skipped configuration, set these values in your active Hermes profile's .env file (normally ~/.hermes/.env):

UNITARES_MCP_URL=http://127.0.0.1:8767/mcp/
# Only needed when your server requires a token:
# UNITARES_BEARER=your-server-token

There is no default server. Hermes checks the required URL before loading the plugin; the library also refuses to send anything while it is unset. The default loopback Docker server needs no bearer token. For a protected server, use a token accepted by its UNITARES_MCP_BEARER_TOKENS setting.

Enable the plugin if you did not enable it during installation, then check its status:

hermes plugins enable unitares
hermes plugins list

The plugin name is unitares, even though the repository and Python package are named unitares-host-adapter. Restart your Hermes CLI process after enabling it. If you use the gateway, run hermes gateway restart.

For deliberate testing of the unpublished candidate, hermes plugins install cirwel/unitares-host-adapter installs directly from the repository. This is a different source from the reviewed catalog pin; check the installed version with hermes plugins list before comparing behavior.

For a server on another machine or in another container, 127.0.0.1 refers to the machine/container running Hermes. Use an address Hermes can reach and configure the server's allowed hosts and authentication as described in the MCP client guide.

Verify it is working

Start a Hermes conversation and complete one assistant turn. On your UNITARES dashboard, look for an identity labelled Hermes Agent and check-in activity after the completed turn. In catalog version 0.3.3, onboarding can happen on session start or lazily at the first turn. In 0.4.0a1, it waits for the first turn so Hermes can supply lineage; merely opening a session creates no server identity. Both versions reuse the binding for later turns while that session remains active in the same process.

Installing this plugin does not add agent-callable tools or a chat command. It reports automatically; a successful install alone does not prove the server is reachable.

What the catalog plugin sends (0.3.3)

EventSent to your configured UNITARES server
New active sessionA fresh identity request with label Hermes Agent, model type hermes-agent, and a client hint containing the Hermes platform and model name.
Completed assistant turnThe fixed marker Hermes assistant turn completed, fixed complexity 0.2, and metadata identifying the report as a host observation (substrate_interpretation). The server-issued session binding accompanies the check-in.
Session finalize or resetLocal adapter state is cleared; this version sends no server-side close or presence-release call.

Default hooks send no user, assistant, or tool text, tool names, arguments, or results. Version 0.3.3 sends no tool counts or duration measurements. Per-tool outcomes remain opt-in. These automatic markers describe host activity; they are not agent-authored reflections or independent evidence that a task succeeded.

Version 0.3.3 has no persisted session-to-identity mapping or lineage declaration. A new process onboards a fresh identity even if it resumes an earlier Hermes conversation.

Continuity candidate (0.4.0a1)

The code on master adds the following behavior. It is not included in the current catalog pin:

  • Deferred onboarding: on_session_start does not mint an identity. The first turn binds the session after Hermes has supplied its parent information.
  • Lineage: when a parent UUID is known, new identities declare subagent, compaction, or explicit lineage. A mapped session resumed in a new process becomes an explicit successor. In-place compaction keeps the current binding; unknown parents do not produce invented lineage.
  • Local continuity hints: up to 200 Hermes session IDs, their UNITARES UUIDs, and timestamps are retained in <HERMES_HOME>/plugin-data/unitares/sessions.json. No client_session_id or proof tokens are persisted. This records ancestry; it does not let a new process act as the predecessor.
  • Numeric observations: received tool callbacks are counted locally. Turn reports include tool-call and error counts, accumulated tool duration, and elapsed time since the turn-start hook, in milliseconds when available. Counting makes no network call and sends no tool text.
  • Presence release: finalize/reset attempts to release server presence when supported, then drops the in-memory binding. The lineage map remains for a later successor.

If the lineage map is missing, unreadable, or its parent entry has been dropped from the bounded history, work continues with a fresh identity. Candidate coverage is exercised in continuity tests; those tests do not establish a successful live rollout.

The candidate remains alpha and unpublished. Before a catalog update, validate one exact revision through clean installation, delegation, resume after finalization, in-place compaction, finalization, and server outage. Earlier soak results from another revision do not establish this candidate's readiness.

Failures and policy actions

In both versions, verdicts are recorded on the server, but the default plugin does not show them to the agent or enforce them. Hook failures are fail-open: Hermes continues after a governance error. The hooks are synchronous, so a slow or unreachable server can still delay a turn. Transport defaults are 10 seconds for connection and 30 seconds for each tool operation; discovery and onboarding may require multiple operations, so these are not a single deadline for the whole hook. After three consecutive failed guarded operations, the adapter stops retrying for that session until finalize/reset clears its failure state.

Troubleshooting

Check hermes plugins list and warnings in your active profile's logs/ directory (normally ~/.hermes/logs/errors.log).

SymptomWhat to check
Plugin installed but inactiveEnable unitares, accept dependency installation, and restart the CLI or gateway.
Missing UNITARES_MCP_URLSet it in the active profile's .env; restart Hermes so the process sees the change. There is no fallback endpoint.
No identity or check-insComplete a turn, check the URL and server availability, and inspect hook warnings. Confirm the dashboard is connected to the same server.
HTTP 421 / refused HostAdd the hostname and port used in the client URL to the server's UNITARES_MCP_ALLOWED_HOSTS, then restart the server. Version 0.3.2 names this setting in its warning; older catalog pins may only log an exception type.
Authentication failureSet UNITARES_BEARER to a token accepted by your server and restart Hermes.
Hook warnings followed by silenceThree consecutive failures open the session's circuit breaker. Fix the cause, then reset the session or restart Hermes.
Public tool contract incompatibilityThe server must advertise sync_state and either onboard or start_session. Check the server version and advertised tool configuration.
No lineage or numeric turn observationsCheck the installed version. The reviewed 0.3.3 plugin does not implement the 0.4.0a1 candidate features.

Let the agent call UNITARES tools

Automatic lifecycle reporting and direct MCP access are independent. If you want the agent to inspect state, write findings, or request reviews itself, also add your server to Hermes's MCP configuration:

# ~/.hermes/config.yaml (use your active profile's config)
mcp_servers:
  unitares:
    url: http://127.0.0.1:8767/mcp/
    tools:
      resources: false
      prompts: false

This example is for the default local server without authentication. For bearer headers and remote servers, use the MCP client guide. Restart Hermes after changing the configuration. Direct MCP access makes tools available; the agent decides when to call them.

Advanced: manual binding and per-tool modes

The example below targets this checkout's 0.4.0a1 candidate. For a custom Hermes plugin, install this checkout into the Python environment Hermes uses:

python3 -m pip install .

Create a plugin that delegates to the binding. Use this as an alternative to the repository plugin so you do not register duplicate lifecycle hooks:

# ~/.hermes/plugins/unitares/plugin.yaml
manifest_version: 1
name: unitares
kind: standalone
version: 0.4.0a1
description: UNITARES governance lifecycle adapter for Hermes
provides_hooks:
  - pre_llm_call
  - post_llm_call
  - post_tool_call
  - on_session_start
  - on_session_finalize
  - on_session_reset
# ~/.hermes/plugins/unitares/__init__.py
from unitares_host_adapter.bindings.hermes import register as register_unitares

def register(ctx):
    register_unitares(ctx)

Set UNITARES_MCP_URL and optional UNITARES_BEARER as above, enable unitares, and restart Hermes.

Per-tool modes require explicit registration and matching hook declarations in the custom plugin manifest:

Registration optionAdd to provides_hooksBehavior
enable_gate=Truepre_tool_callAsk governance before a tool call; block on a blocking verdict. Errors remain fail-open.
enable_ambient=Truetransform_tool_resultAppend governance annotations to tool results the agent sees.
enable_outcomes=Truepost_tool_callSend tool success/failure observations.

For example, after ensuring all three hooks are declared in the manifest (post_tool_call is already present in the candidate example):

register_unitares(ctx, enable_gate=True, enable_ambient=True, enable_outcomes=True)

The default privacy disclosure above applies to light mode. Per-tool modes send additional context: gate and ambient check-ins include tool names and argument previews; outcomes include tool names and status/error metadata. Review these modes before enabling them for your workload.

Other hosts

Claude Code and Codex

Use UNITARES for Claude Code and Codex for those hosts' installation steps, hooks, and skills. This Hermes adapter does not install their integrations. Its uhaa helper only exposes --version and spec.

Any MCP-capable host (explicit-only fallback)

Add your UNITARES server's MCP endpoint (for example http://127.0.0.1:8767/mcp/) to your host's MCP config. No adapter needed for explicit mode; install this package only if you want ambient or gated delivery.

Direct MCP access lets the agent publish selected findings and evidence, inspect its working state, request reviews, and record outcomes. The agent decides when to call these tools. Automatic lifecycle reporting requires a host binding or the proxy below.

OpenAI-compatible clients — Ollama, Open WebUI, Cursor (governance proxy)

For clients that speak the OpenAI-compatible chat-completions protocol but expose no lifecycle hooks, run the governance proxy in front of the model server and point the client's base URL at it. This example pins the same 0.3.3 source revision as the reviewed Hermes catalog entry:

python3 -m pip install "unitares-host-adapter[proxy] @ git+https://github.com/cirwel/unitares-host-adapter@bf534cf031593f785b6022f0edf0fc594c2aa912"
UNITARES_MCP_URL=http://127.0.0.1:8767/mcp/ \
UNITARES_PROXY_UPSTREAM=http://localhost:11434 \
uhaa-proxy            # listens on http://127.0.0.1:11435  -> point your client at /v1

The proxy uses one UNITARES identity for the proxy process. It reports requests to /v1/chat/completions; other routes pass through without check-ins. Reports contain the requested model name and message count, rather than conversation text. Multiple clients sharing a proxy also share that identity, so this does not identify each client or agent process separately.

The default UNITARES_PROXY_MODE=observe submits a check-in after the response without blocking the model request. In enforce mode, the proxy checks policy before forwarding and returns a refusal when the server reports a blocking action. Both modes are fail-open on governance errors. The proxy can gate model requests; it cannot intercept tools that the client later executes. Use a host's pre-tool hook for tool-call gating.

Set UNITARES_BEARER if the governance server requires authentication. The model request, including conversation text, is forwarded to UNITARES_PROXY_UPSTREAM; the smaller model-name/message-count summary is what goes to UNITARES. If the proxy cannot onboard at startup, it forwards requests without governance for that process lifetime; restart it after restoring server access.

These reports make runtime activity visible to the operator. They do not establish task correctness, preserve selected evidence, or record reviews and outcomes automatically.

Library delivery modes

ModeWho initiatesWhen it firesDefault depth
ExplicitAgent (via MCP tool call)When the agent asksauto
AmbientHost (tool-result hook)Every tool calllite
GatedHost (pre-tool-call hook)Before any tool callN/A (block or pass)

These are library capabilities. The default Hermes plugin uses automatic turn reporting, with ambient, gated, and outcome hooks disabled. See SPEC.md for the delivery-surface contract.

Repository map

PathPurpose
plugin.yaml, __init__.pyInstallable Hermes directory plugin and runtime entrypoint.
src/unitares_host_adapter/bindings/hermes.pyHermes lifecycle hooks and opt-in tool modes.
src/unitares_host_adapter/bindings/openai_proxy.pyOpenAI-compatible governance proxy.
SPEC.mdHost-agnostic delivery-surface specification.
tests/Core, transport, binding, and plugin contract tests.

The UNITARES server owns the durable record of identities, claims, evidence, governed reviews, and outcomes, and returns runtime policy actions at checkpoints. The separate governance plugin packages Claude/Codex hooks, skills, and guidance. This repository supplies host bindings and requires a server for governance operations.

Status

v0.4.0a1 — unpublished alpha candidate. Signatures may change before 1.0.

Version 0.3.3 reads current UNITARES sync_state decision envelopes (action_summary and state_summary) as well as older canonical verdict responses. Opt-in gates respect the final policy action and typed AGENT_PAUSED refusals on later calls; an advisory cold-start pause deferred by policy does not block a tool. Guided decisions remain visible in ambient annotations. Contract fixtures were generated by UNITARES's actual envelope builder at commit f5cb44268, covering minimal, compact, standard, mirror, and full responses. This validates response compatibility; it is not an end-to-end Hermes deployment test.

Supported integrations:

IntegrationAvailable behavior
Hermes directory pluginSession identity and automatic turn reporting.
Custom Hermes bindingOpt-in tool gating, annotations, and outcome observations.
OpenAI-compatible proxyChat-completion request reporting and optional request gating under one proxy identity.
Direct MCP configurationAgent-initiated access to server tools, independent of the adapter.

Claude Code and Codex lifecycle hooks are provided by the separate governance plugin. The Python package is installed from GitHub; it is not published on PyPI.

License

Apache License 2.0. See LICENSE and NOTICE.

↑↓ navigate openesc close