Hermes Plugin Integration

August 5, 2026 · View on GitHub

Uteke can be used as a complementary memory layer for Hermes Agent ecosystems.

Architecture

Uteke integrates with Hermes in two modes. Pick the one that matches how you want memory to behave.

Hermes Agent
├── Mode A: uteke-tool (manual)    → agent calls uteke(action=...) for explicit remember/recall
├── Mode C: uteke-memory (plugin)  → automatic recall via pre_llm_call hook every turn
└── ~~Mode B: memory-provider~~     → removed 2026-06-29
Mode A (uteke-tool)Mode C (uteke-memory plugin)Mode B (memory-provider)
Installuteke init --agent hermesPlugin at ~/.hermes/plugins/uteke-memory/removed
InvocationAgent calls uteke(action="recall")Automatic (plugin hook)Automatic (provider)
CaptureAgent decides what to storeManual (uteke remember via Mode A)Auto-extract on session end
TransportHTTP to uteke-servesubprocess or HTTPCLI subprocess
DaemonRequires uteke-serveNo (subprocess) / optional (HTTP)No
Rooms / multi-agentYesYesNo
Best forExplicit, on-demand memoryLightweight auto-recallDrop-in replacement

Recommended: Mode A + Mode C side by side — automatic recall via plugin hook, manual store via tool. Both read the same uteke store.

Mode A — uteke-tool (manual actions, multi-agent rooms)

Quick Setup

1. Install uteke

curl -fsSL https://raw.githubusercontent.com/codecoradev/uteke/main/install.sh | sh

2. Auto-install Hermes plugin (v0.3.0+)

uteke init --agent hermes

This generates the plugin directly to ~/.hermes/plugins/uteke-tool/ with:

  • plugin.yaml — manifest
  • tool.py — Python entry point (stdlib only, no requests dependency)
  • README.md — usage guide

3. Start the server

uteke-serve --port 8767

4. Start a new Hermes session

The plugin loads automatically.

Usage

Memory Operations

# Store a memory
uteke(action="remember", content="User prefers dark mode", tags="preference,ui")

# Semantic recall
uteke(action="recall", content="user preferences")

# Keyword search
uteke(action="search", content="dark mode")

# List memories
uteke(action="list", limit=10)

# Delete a memory
uteke(action="forget", id="abc12345")

# Stats
uteke(action="stats")

Room Operations (v0.3.0+, #395, #410)

Rooms enable multi-agent collaborative memory — multiple agents share a room and contribute memories with author attribution.

# Create a shared room
uteke(action="room_create", room_id="sprint-planning", title="Sprint Planning")

# Add a memory to a room (with author attribution)
uteke(action="room_remember", room_id="sprint-planning", content="Deploy scheduled for Friday", author="agent1")

# Add a reference document to a room
uteke(action="room_summary_document", room_id="sprint-planning", content="Architecture spec: ...", title="Arch Spec")

# Recall from a room (semantic search — query is required)
uteke(action="room_recall", room_id="sprint-planning", content="deploy deadline")

# List all rooms (cross-namespace)
uteke(action="room_list")

# Room analytics
uteke(action="room_stats", room_id="sprint-planning")
uteke(action="room_summary", room_id="sprint-planning")

# Delete a room (memories preserved)
uteke(action="room_delete", room_id="sprint-planning")

MCP Server (Alternative)

For MCP-compatible agents, use the uteke MCP server instead of the HTTP plugin:

# Register with Hermes
hermes mcp add uteke --command uteke-mcp

# Or use the HTTP transport
hermes mcp add uteke --url http://127.0.0.1:8767/mcp

The MCP server provides the same tools via JSON-RPC (protocol version 2025-06-18):

  • uteke_remember — store memory (supports type, room, author, tags)
  • uteke_recall — semantic search (supports tags filter, min_score)
  • uteke_list — list memories (supports pagination via offset)
  • uteke_forget — delete memory
  • uteke_stats — store statistics
  • uteke_room_memories — list memories in a room (#569)

MCP Client Configuration Examples

Claude Desktop (stdio transport)

Create or edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "uteke": {
      "command": "uteke-mcp"
    }
  }
}

Claude Desktop (HTTP transport)

{
  "mcpServers": {
    "uteke": {
      "url": "http://127.0.0.1:8767/mcp"
    }
  }
}

Cursor

Create or edit .cursor/mcp.json in your project root:

{
  "mcpServers": {
    "uteke": {
      "command": "uteke-mcp"
    }
  }
}

Or with HTTP transport:

{
  "mcpServers": {
    "uteke": {
      "url": "http://127.0.0.1:8767/mcp"
    }
  }
}

Hermes Native MCP Client (HTTP transport)

# Register with Hermes using HTTP transport (requires uteke-serve running)
hermes mcp add uteke --url http://127.0.0.1:8767/mcp

Or with stdio transport:

# Register with Hermes using stdio transport
hermes mcp add uteke --command uteke-mcp

Tip: HTTP transport is recommended when uteke-serve is already running — it avoids subprocess overhead and works across machines. Stdio transport is simpler for local, single-agent setups where no daemon is desired.

Available Actions

ActionDescription
rememberStore a new memory
recallSemantic search
searchKeyword search
listList memories (with namespace filter)
forgetDelete memory
statsNamespace or global statistics
room_rememberStore memory in a room with author attribution
room_summary_documentStore a reference document in a room
room_createCreate a room
room_recallSemantic search within a room (requires query)
room_listList all rooms (cross-namespace)
room_summaryRoom topic summary with clusters and highlights
room_statsRoom statistics (memory count, participants)
room_deleteDelete a room (memories preserved)
namespace_listList all namespaces
namespace_statsStatistics for a specific namespace
tags_listList all tags
tags_renameRename a tag across all memories
tags_deleteDelete a tag from all memories
consolidateMerge similar memories (with threshold)
agingAging cleanup of old memories
importImport memories from JSON
importanceRecompute importance scores
doctorHealth check (alias for /health)

Valid Memory Types

When using remember, room_remember, or room_summary_document, the type parameter accepts these values:

TypeDescription
factA factual statement or observation
procedureA how-to, process, or workflow
preferenceA user or system preference
decisionA decision that was made
contextBackground context for a topic
noteA general note
insightAn insight or conclusion
referenceA reference document (default for room_document)
eventA time-based event

Warning: Using an invalid type (e.g., document) causes HTTP 500. Use reference instead of document.

HTTP API Notes

The uteke HTTP server (uteke-serve) uses exact path matching — query parameters are NOT part of the route. This means:

# ✅ Correct — POST with JSON body
curl -X POST http://127.0.0.1:8767/stats \
  -H 'Content-Type: application/json' \
  -d '{"namespace": "cto"}'

# ❌ Wrong — GET with query params returns 404
curl http://127.0.0.1:8767/stats?namespace=cto

All endpoints that accept parameters use POST with JSON body, not GET with query strings.

Memory-Provider for Other Agents

The --memory-provider pattern also works for non-Hermes agents (#575, #577):

# pi (pi.dev)
uteke init --agent pi --memory-provider

# Claude Code
uteke init --agent claude --memory-provider

# Cursor
uteke init --agent cursor --memory-provider

This installs uteke as the agent's default memory provider — relevant memories are recalled and injected automatically every turn. No daemon needed; talks to the uteke binary directly via subprocess.

Note: For Hermes, use Mode A (uteke-tool) or Mode C (uteke-memory plugin) instead — the Hermes memory-provider plugin has been removed (see Mode B).

Mode B — memory-provider (deprecated)

DEPRECATED for Hermes (removed 2026-06-29). Use Mode A + Mode C instead.

The --memory-provider pattern remains supported for pi, Claude Code, and Cursor. See Memory-Provider for Other Agents. The template source lives at extensions/hermes-memory-provider/.

Historical reference: Mode B made uteke Hermes's long-term memory backend via uteke init --agent hermes --memory-provider + memory.provider: uteke config. Automatic recall every turn, auto-extract facts on session end. No daemon needed.

Configuration (uteke-tool)

Environment VariableDefaultDescription
UTEKE_SERVER_URLhttp://127.0.0.1:8767uteke server URL

(For memory-provider configuration, see the reference table under Mode B.)

How It Works (uteke-tool)

  • Remember: POST to /remember — content is embedded (EmbeddingGemma Q4, 768d) and stored in SQLite + HNSW vector index. Supports type param (see Valid Memory Types)
  • Recall: POST to /recall — semantic search via hybrid RRF (vector + FTS5), returns ranked results
  • Room Remember: POST to /room/remember — stores memory and links to room in a single call. Requires room_id (not room). Use type="reference" for documents (not document — causes 500)
  • Rooms: Cross-namespace collaboration spaces — rooms span namespaces, enabling multi-agent coordination
  • MCP: JSON-RPC over stdio or HTTP — standard MCP protocol for AI agent integration

The memory-provider plugin (Mode B) skips the HTTP layer entirely and shells out to the uteke binary: recall --json for prefetch, import --extract for session-end distillation.

Mode C — uteke-memory plugin (pre_llm_call hook, automatic recall)

Mode C is the recommended auto-recall integration: a Hermes Python plugin that registers a pre_llm_call hook. Every turn, before the LLM call, it runs uteke recall on the user message and injects the results into the user message — no shell hook, no daemon, no memory-provider config.

Why a Plugin Instead of a Shell Hook?

AspectOld shell hookPlugin (pre_llm_call)
Registrationhooks.pre_llm_call in config.yamlctx.register_hook("pre_llm_call", cb)
Runs inSubprocess (separate process)Gateway process (in-process)
Env vars❌ Does NOT bridge HERMES_SESSION_*✅ Full gateway process env
Contextvar access❌ No access to contextvars✅ Full access (thread_id, platform, etc.)
BlockingYes (subprocess.run)Yes, but faster (no process spawn)
Agent name detectionHacky (cwd in payload)Reliable (HERMES_HOME, ctx.profile_name)
PerformanceProcess spawn per turnIn-process function call

The plugin approach replaces both the old Mode B (MemoryProvider, removed) and the Mode C shell hook. It runs inside the gateway process, has full access to contextvars, avoids subprocess spawn overhead, and is the standard Hermes plugin pattern.

Quick Setup

1. Install uteke

curl -fsSL https://raw.githubusercontent.com/codecoradev/uteke/main/install.sh | sh

2. Install the plugin

The plugin files live at extensions/hermes-memory-provider/ in the uteke repo. Copy them to your Hermes plugins directory:

# Copy from uteke repo
cp -r extensions/hermes-memory-provider ~/.hermes/plugins/uteke-memory/
# Remove .tmpl extension
cd ~/.hermes/plugins/uteke-memory/
for f in *.tmpl; do mv "$f" "${f%.tmpl}"; done

Or generate from uteke init:

uteke init --agent hermes

3. Enable in Hermes config

In ~/.hermes/profiles/<profile>/config.yaml (or global config.yaml):

plugins:
  enabled:
    - uteke-memory

No hooks: config needed. No memory.provider config needed. Just enable the plugin.

4. Verify

hermes plugins list
# Should show: uteke-memory ... enabled

# Start a new session — recall should work automatically
hermes chat

Plugin Config

Config via ~/.hermes/uteke.json (preferred) or environment variables:

VariableDefaultDescription
UTEKE_BIN(search PATH)Path to uteke binary
UTEKE_HOME(inherit)HOME dir for uteke store (~/.codecora/uteke)
UTEKE_NAMESPACE(agent profile name)Memory namespace
UTEKE_SERVER_URL(empty = subprocess)uteke-serve HTTP URL
UTEKE_TOKEN(empty)Auth token for uteke-serve
UTEKE_RECALL_LIMIT5Memories to recall per turn
UTEKE_RECALL_MIN_SCORE0.40Min score to include
UTEKE_RECALL_TIMEOUT15Max seconds per recall call

Example ~/.hermes/uteke.json:

{
  "server_url": "http://uteke:8767",
  "token": "your-bearer-token",
  "recall_limit": 5,
  "recall_min_score": 0.40
}

How It Works

  1. On plugin load (register(ctx)), the recall manager initializes: loads config, resolves transport (subprocess vs HTTP), finds uteke binary.
  2. On every turn, Hermes calls _pre_llm_call(**kwargs) in-process.
  3. The hook truncates the user message to 500 chars, runs uteke recall, filters results by min_score, and formats them as <recalled-memories> XML.
  4. Hermes injects the returned {"context": "..."} into the user message before sending to the LLM. This preserves the system prompt cache prefix.
  5. A circuit breaker pauses recall after 5 consecutive failures for 120 seconds.

Mode Comparison Summary

Mode AMode CMode B
WhatManual toolPlugin hook (recall only)Full memory provider
RecallAgent calls uteke(action="recall")Automatic (via plugin hook)Automatic
ExtractionManual uteke(action="remember")Manual (combine with Mode A)Automatic (session end)
Daemonuteke-serve requiredNo (subprocess) / optional (HTTP)No
Replaces Hermes memoryNoNoYes
Best forOn-demand memory, multi-agent roomsLightweight auto-recallDrop-in replacement

Recommended: Mode A + Mode C — automatic recall via plugin, manual store via tool. Keeps Hermes's built-in memory while adding uteke recall.

Requirements

  • uteke v0.3.0+ (includes uteke-mcp binary)
  • Mode A (uteke-tool): uteke-serve running (daemon mode)
  • Mode C (plugin hook): uteke binary on PATH, no daemon
  • Python 3.7+ (stdlib only — no pip install needed)