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) | ||
|---|---|---|---|
| Install | uteke init --agent hermes | Plugin at ~/.hermes/plugins/uteke-memory/ | |
| Invocation | Agent calls uteke(action="recall") | Automatic (plugin hook) | |
| Capture | Agent decides what to store | Manual (uteke remember via Mode A) | |
| Transport | HTTP to uteke-serve | subprocess or HTTP | |
| Daemon | Requires uteke-serve | No (subprocess) / optional (HTTP) | |
| Rooms / multi-agent | Yes | Yes | |
| Best for | Explicit, on-demand memory | Lightweight auto-recall |
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— manifesttool.py— Python entry point (stdlib only, norequestsdependency)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 memoryuteke_stats— store statisticsuteke_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-serveis 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
| Action | Description |
|---|---|
remember | Store a new memory |
recall | Semantic search |
search | Keyword search |
list | List memories (with namespace filter) |
forget | Delete memory |
stats | Namespace or global statistics |
room_remember | Store memory in a room with author attribution |
room_summary_document | Store a reference document in a room |
room_create | Create a room |
room_recall | Semantic search within a room (requires query) |
room_list | List all rooms (cross-namespace) |
room_summary | Room topic summary with clusters and highlights |
room_stats | Room statistics (memory count, participants) |
room_delete | Delete a room (memories preserved) |
namespace_list | List all namespaces |
namespace_stats | Statistics for a specific namespace |
tags_list | List all tags |
tags_rename | Rename a tag across all memories |
tags_delete | Delete a tag from all memories |
consolidate | Merge similar memories (with threshold) |
aging | Aging cleanup of old memories |
import | Import memories from JSON |
importance | Recompute importance scores |
doctor | Health check (alias for /health) |
Valid Memory Types
When using remember, room_remember, or room_summary_document, the type parameter accepts these values:
| Type | Description |
|---|---|
fact | A factual statement or observation |
procedure | A how-to, process, or workflow |
preference | A user or system preference |
decision | A decision that was made |
context | Background context for a topic |
note | A general note |
insight | An insight or conclusion |
reference | A reference document (default for room_document) |
event | A time-based event |
Warning: Using an invalid type (e.g.,
document) causes HTTP 500. Usereferenceinstead ofdocument.
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-providerpattern remains supported for pi, Claude Code, and Cursor. See Memory-Provider for Other Agents. The template source lives atextensions/hermes-memory-provider/.Historical reference: Mode B made uteke Hermes's long-term memory backend via
uteke init --agent hermes --memory-provider+memory.provider: utekeconfig. Automatic recall every turn, auto-extract facts on session end. No daemon needed.
Configuration (uteke-tool)
| Environment Variable | Default | Description |
|---|---|---|
UTEKE_SERVER_URL | http://127.0.0.1:8767 | uteke 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. Supportstypeparam (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. Requiresroom_id(notroom). Usetype="reference"for documents (notdocument— 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?
| Aspect | Old shell hook | Plugin (pre_llm_call) |
|---|---|---|
| Registration | hooks.pre_llm_call in config.yaml | ctx.register_hook("pre_llm_call", cb) |
| Runs in | Subprocess (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.) |
| Blocking | Yes (subprocess.run) | Yes, but faster (no process spawn) |
| Agent name detection | Hacky (cwd in payload) | Reliable (HERMES_HOME, ctx.profile_name) |
| Performance | Process spawn per turn | In-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:
| Variable | Default | Description |
|---|---|---|
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_LIMIT | 5 | Memories to recall per turn |
UTEKE_RECALL_MIN_SCORE | 0.40 | Min score to include |
UTEKE_RECALL_TIMEOUT | 15 | Max 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
- On plugin load (
register(ctx)), the recall manager initializes: loads config, resolves transport (subprocess vs HTTP), finds uteke binary. - On every turn, Hermes calls
_pre_llm_call(**kwargs)in-process. - The hook truncates the user message to 500 chars, runs
uteke recall, filters results by min_score, and formats them as<recalled-memories>XML. - Hermes injects the returned
{"context": "..."}into the user message before sending to the LLM. This preserves the system prompt cache prefix. - A circuit breaker pauses recall after 5 consecutive failures for 120 seconds.
Mode Comparison Summary
| Mode A | Mode C | ||
|---|---|---|---|
| What | Manual tool | Plugin hook (recall only) | |
| Recall | Agent calls uteke(action="recall") | Automatic (via plugin hook) | |
| Extraction | Manual uteke(action="remember") | Manual (combine with Mode A) | |
| Daemon | uteke-serve required | No (subprocess) / optional (HTTP) | |
| Replaces Hermes memory | No | No | |
| Best for | On-demand memory, multi-agent rooms | Lightweight auto-recall |
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-mcpbinary) - Mode A (
uteke-tool):uteke-serverunning (daemon mode) - Mode C (plugin hook):
utekebinary onPATH, no daemon - Python 3.7+ (stdlib only — no pip install needed)