Uteke can be used as a complementary memory layer for Hermes Agent ecosystems.
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.
curl -fsSL https://raw.githubusercontent.com/codecoradev/uteke/main/install.sh | shuteke init --agent hermesThis generates the plugin directly to ~/.hermes/plugins/uteke-tool/ with:
plugin.yamlβ manifesttool.pyβ Python entry point (stdlib only, norequestsdependency)README.mdβ usage guide
uteke-serve --port 8767The plugin loads automatically.
# 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")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")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/mcpThe 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)
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"
}
}
}{
"mcpServers": {
"uteke": {
"url": "http://127.0.0.1:8767/mcp"
}
}
}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"
}
}
}# Register with Hermes using HTTP transport (requires uteke-serve running)
hermes mcp add uteke --url http://127.0.0.1:8767/mcpOr with stdio transport:
# Register with Hermes using stdio transport
hermes mcp add uteke --command uteke-mcpTip: 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.
| 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) |
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.
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=ctoAll endpoints that accept parameters use POST with JSON body, not GET with query strings.
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-providerThis 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).
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.
| 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.)
- 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 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.
| 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.
curl -fsSL https://raw.githubusercontent.com/codecoradev/uteke/main/install.sh | shThe 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}"; doneOr generate from uteke init:
uteke init --agent hermesIn ~/.hermes/profiles/<profile>/config.yaml (or global config.yaml):
plugins:
enabled:
- uteke-memoryNo hooks: config needed. No memory.provider config needed. Just enable the plugin.
hermes plugins list
# Should show: uteke-memory ... enabled
# Start a new session β recall should work automatically
hermes chatConfig 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
}- 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 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.
- 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)