https://github.com/madeinoz67/hermes-memory-muninndb
munnindb memory plugin
https://github.com/madeinoz67/hermes-memory-muninndb
hermes hermes-agent hermes-plugin munnindb
Last synced: about 1 month ago
JSON representation
munnindb memory plugin
- Host: GitHub
- URL: https://github.com/madeinoz67/hermes-memory-muninndb
- Owner: madeinoz67
- Created: 2026-05-28T03:36:44.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-06-08T14:23:54.000Z (about 2 months ago)
- Last Synced: 2026-06-08T16:19:34.098Z (about 2 months ago)
- Topics: hermes, hermes-agent, hermes-plugin, munnindb
- Language: Python
- Homepage:
- Size: 28.3 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# MuninnDB — Knowledge Graph Memory Plugin for Hermes Agent
Persistent semantic memory via MuninnDB knowledge graph with entity tracking,
hierarchical organization, enrichment pipeline, and automatic turn syncing.
Connects to a MuninnDB MCP server over streamable-http transport.
## Features
- Semantic search with cross-vault recall
- Automatic turn storage (sync_turn) after each agent turn
- Entity extraction and relationship tracking
- Knowledge graph navigation and traversal
- Hierarchical memory organization (parent/child)
- Enrichment pipeline for memory quality
- Circuit breaker resilience for MCP failures
- Session-aware with per-profile vault scoping
- 33 tools covering lifecycle, knowledge graph, entity management, quality, audit, and enrichment
## Prerequisites
1. **Hermes Agent** installed and working
2. **MuninnDB MCP server** running and accessible (https://github.com/madeinoz67/muninndb)
3. Python `requests` library (usually already available in Hermes venv)
## Installation
### 1. Copy the plugin to Hermes plugins directory
```bash
mkdir -p ~/.hermes/plugins/memory/muninndb
cp __init__.py plugin.yaml config.py tools.py circuit_breaker.py mcp_client.py formatter.py lifecycle.py ~/.hermes/plugins/memory/muninndb/
```
Or if Hermes is installed at a custom location:
```bash
mkdir -p /opt/data/plugins/memory/muninndb
cp __init__.py plugin.yaml config.py tools.py circuit_breaker.py mcp_client.py formatter.py lifecycle.py /opt/data/plugins/memory/muninndb/
```
### 2. Configure the connection
Create a `muninndb.json` in your Hermes home directory:
```bash
cat > ~/.hermes/muninndb.json << 'EOF'
{
"mcp_url": "http://YOUR_HOST:8750/mcp"
}
EOF
```
### 3. Restart Hermes
```bash
hermes restart
```
## Configuration
| Key | Description | Default |
|-----|-------------|---------|
| `mcp_url` | MuninnDB MCP server URL | **required** |
| `vault_prefix` | Vault name prefix | `hermes` |
| `activate_limit` | Max memories per prefetch | `10` |
| `activate_min_score` | Min relevance score 0-1 | `0.3` |
| `prefetch_context_tokens` | Token budget for prefetch output | `800` |
| `trivial_message_min_words` | Skip sync for short messages | `5` |
| `circuit_breaker_threshold` | Failures before opening circuit | `5` |
| `circuit_breaker_timeout_s` | Seconds before half-open | `60` |
| `request_timeout_s` | HTTP request timeout | `15.0` |
| `skip_patterns` | Base skip patterns for turn filtering | `[]` |
| `skip_patterns_extra` | Additional user-extensible skip patterns | `[]` |
| `tool_priority_filter` | Tool families to expose: all/p0/p0-p1/p0-p2 | `all` |
| `enable_audit_tools` | Enable P2 audit/debug tools | `false` |
### Alternative Configuration Methods
**Via `config.yaml` (mcp_servers section):**
```yaml
mcp_servers:
muninndb:
url: http://YOUR_HOST:8750/mcp
```
**Via environment variable:**
```bash
export MUNINNDB_MCP_URL=http://YOUR_HOST:8750/mcp
```
Priority order: `muninndb.json` > `config.yaml` mcp_servers > env var.
### Optional Authentication
```bash
export MUNINNDB_MCP_TOKEN=your_token_here
```
## Tool Reference (33 tools)
### Core Memory (3)
#### `muninn_search` — Semantic search across MuninnDB long-term memory
```
muninn_search(query="project architecture")
```
**Parameters:**
- `query` (required) — What to search for
- `limit` — Max results (default: 10)
- `mode` — Recall mode: semantic, recent, balanced, deep (default: balanced)
#### `muninn_remember` — Persist a fact, preference, decision, or observation
```
muninn_remember(content="Project uses pytest for testing", memory_type="fact")
```
**Parameters:**
- `content` (required) — The information to remember
- `memory_type` — Type: fact, decision, observation, preference, issue, task, procedure, event, goal, constraint, ephemeral, milestone (default: fact)
- `summary` — One-line summary
#### `muninn_entities` — List known entities sorted by mention count
```
muninn_entities(limit=20)
```
**Parameters:**
- `limit` — Max results (default: 20)
### P0 — Lifecycle (6)
#### `muninn_where_left_off` — Session resumption with recent memories
```
muninn_where_left_off()
```
**Parameters:**
- `limit` — Max recent memories (default: 10)
#### `muninn_forget` — Soft-delete a memory by ID
```
muninn_forget(id="mem_abc123")
```
**Parameters:**
- `id` (required) — Memory ID to forget
- `reason` — Optional reason for deletion
#### `muninn_evolve` — Update memory content without creating duplicates
```
muninn_evolve(id="mem_abc123", content="Updated content")
```
**Parameters:**
- `id` (required) — Memory ID to update
- `content` (required) — New content
- `reason` — Optional reason for update
#### `muninn_remember_batch` — Atomic multi-memory storage
```
muninn_remember_batch(memories=[{"content": "fact 1"}, {"content": "fact 2"}])
```
**Parameters:**
- `memories` (required) — Array of memory objects, each with `content` and optional `type`, `summary`, `entities`
#### `muninn_contradictions` — Find conflicting memories
```
muninn_contradictions()
```
**Parameters:**
- `limit` — Max pairs to return (default: 10)
#### `muninn_status` — Vault health summary
```
muninn_status()
```
### P1 — Knowledge Graph (4)
#### `muninn_link` — Create typed relationship between memories
```
muninn_link(source_id="mem_a", target_id="mem_b", relation="supports")
```
**Parameters:**
- `source_id` (required) — Source memory ID
- `target_id` (required) — Target memory ID
- `relation` (required) — Relationship type (e.g. supports, contradicts, derived_from)
#### `muninn_merge` — Consolidate fragmented observations
```
muninn_merge(source_ids=["mem_a", "mem_b"], target_content="Unified content")
```
**Parameters:**
- `source_ids` (required) — IDs of memories to merge
- `target_content` (required) — Consolidated content
#### `muninn_traverse` — Explore memory graph from a starting point
```
muninn_traverse(start_id="mem_abc123", direction="both", max_depth=3)
```
**Parameters:**
- `start_id` (required) — Starting memory ID
- `direction` — forward, backward, both (default: both)
- `max_depth` — Maximum traversal depth (default: 3)
#### `muninn_decide` — Record a decision with rationale
```
muninn_decide(decision="Use SQLite", rationale="Simpler for self-hosted")
```
**Parameters:**
- `decision` (required) — The decision made
- `rationale` (required) — Why it was made
- `alternatives` — Alternatives considered but not chosen
### P1 — Entity Management (8)
#### `muninn_find_entity` — Fast entity lookup by name
**Parameters:** `name` (required) — Entity name
#### `muninn_entity_snapshot` — Full aggregate entity view
**Parameters:** `name` (required) — Entity name
#### `muninn_entity_versions` — Entity evolution over time
**Parameters:** `name` (required) — Entity name
#### `muninn_entity_clusters` — Discover implicit entity relationships
**Parameters:** `top_n` — Number of top clusters (default: 20)
#### `muninn_similar_entities` — Find potential duplicate entities
No required parameters.
#### `muninn_merge_entity` — Deduplicate entity names
**Parameters:** `source` (required), `target` (required) — Source merges into target
#### `muninn_entity_state` — Entity lifecycle state transitions
**Parameters:** `name` (required), `state` (required: active/archived/merged), `type` (optional)
#### `muninn_forget_entity` — Remove entity from knowledge graph
**Parameters:** `name` (required), `cascade` — Also delete associated memories (default: false)
### P1 — Quality Assurance (3)
#### `muninn_classify` — Classify memory confidence level
**Parameters:** `id` (required), `classification` (required: verified/inferred/untrusted)
#### `muninn_trust` — Set trust level on a memory
**Parameters:** `id` (required), `level` (required: verified/inferred/untrusted)
#### `muninn_feedback` — Signal recall usefulness for relevance tuning
**Parameters:** `query` (required), `memory_ids` (required), `useful` (required)
### P2 — Audit & Debug (4)
#### `muninn_audit_trail` — Change history for a memory
```
muninn_audit_trail(id="mem_abc123")
```
**Parameters:** `id` (required) — Memory ID to get audit trail for
#### `muninn_debug_recall` — Explain why recall returned specific results
```
muninn_debug_recall(query="project architecture")
```
**Parameters:** `query` (required), `limit` — Max results to analyze (default: 5)
#### `muninn_vault_health` — Detailed vault health diagnostics
```
muninn_vault_health()
```
No required parameters. Returns memory count, storage size, index health, enrichment stats.
#### `muninn_export_graph` — Export entity graph
```
muninn_export_graph(format="json")
```
**Parameters:** `format` — Output format: json or dot (default: json)
### P2 — Hierarchical Memory (3)
#### `muninn_parent` — Set parent memory for hierarchy
```
muninn_parent(child_id="mem_child", parent_id="mem_parent")
```
**Parameters:** `child_id` (required), `parent_id` (required)
#### `muninn_child` — Set child memory for hierarchy
```
muninn_child(parent_id="mem_parent", child_id="mem_child")
```
**Parameters:** `parent_id` (required), `child_id` (required)
#### `muninn_level` — Navigate memory hierarchy
```
muninn_level(id="mem_abc123", direction="up")
```
**Parameters:** `id` (required), `direction` (required: up/down)
### P2 — Enrichment Pipeline (2)
#### `muninn_get_enrichment_candidates` — Find memories missing enrichment stages
```
muninn_get_enrichment_candidates()
```
No required parameters. Returns list of memory IDs with missing enrichment stages.
#### `muninn_replay_enrichment` — Run enrichment pipeline on memories
```
muninn_replay_enrichment(ids=["mem_a", "mem_b"])
```
**Parameters:** `ids` — Memory IDs to enrich. If omitted, enriches all candidates.
## How It Works
### Automatic Behaviors
1. **Prefetch** — Before each turn, performs semantic search to surface relevant memories from the vault
2. **Turn Sync** — After each turn, stores key facts as observations automatically
3. **Memory Mirror** — Built-in `memory()` tool writes are mirrored to MuninnDB
4. **Session End** — On `/new`, `/reset`, or session expiry, flushes remaining insights
5. **Delegation Tracking** — Subagent task+result pairs are recorded for continuity
### Vault Scoping
- Default profile: `hermes`
- Named profile: `hermes_`
- Cross-vault search: profile vault + base vault merged, deduplicated by score
### Circuit Breaker
The plugin uses a circuit breaker to prevent cascading failures when the MCP server is unavailable:
- **Closed** (normal): All requests pass through
- **Open** (tripped): After N consecutive failures, all requests return error immediately
- **Half-open**: After timeout, allows one probe request to test recovery
### Tool Priority Filtering
Use `tool_priority_filter` in config to control which tool families are exposed:
- `all` — All 33 tools (default)
- `p0` — Only core + P0 lifecycle (9 tools)
- `p0-p1` — Core + P0 + P1 (24 tools)
- `p0-p2` — Same as `all` (33 tools)
Audit tools (audit_trail, debug_recall, vault_health, export_graph) are additionally gated by `enable_audit_tools` and default to off.
## Troubleshooting
### Plugin not loading
```bash
hermes logs | grep -i muninndb
```
### Not working as expected
1. Verify MuninnDB MCP server is running: `curl http://YOUR_HOST:8750/mcp`
2. Check the MCP URL in muninndb.json or config.yaml
3. Ensure `type: streamable-http` is set in mcp_servers config
4. Restart Hermes after config changes
### Tools not appearing
1. Check `tool_priority_filter` setting
2. Verify `enable_audit_tools` is `true` if audit tools are missing
3. Gateway restart required — tool list is frozen at session start
## Development
```bash
git clone https://github.com/madeinoz67/hermes-memory-muninndb
cd hermes-memory-muninndb
ln -sf $(pwd) ~/.hermes/plugins/memory/muninndb
hermes restart
```
## License
MIT