# Mindpouch Hermes Provider A Python plugin that makes Mindpouch the active external memory provider for Hermes: automatic context prefetch before turns, provider-owned tools, and explicit-only writes. This is Tier 3 of [the Hermes integration plan](../../docs/hermes-integration-plan.md). Tiers 1 (skills + CLI) and 2 (MCP tools) coexist with other providers and need nothing from this package. ## Layout ```text plugin/ __init__.py plugin.yaml # provider metadata provider.py # MindpouchMemoryProvider — runtime-agnostic core hermes_native.py # MindpouchHermesProvider — subclasses Hermes' MemoryProvider ABC transport.py # call(op, params) seam over CLI subprocesses tests/ test_provider.py # integration tests against the real CLI ``` ## How it works - All Mindpouch access goes through `CliTransport.call(op, params)`, which runs one `node --json` subprocess per call. Swapping in a long-lived `mindpouch-mcp` session later means implementing the same `call` interface — provider logic does not change. - `prefetch(query)` runs recall and returns the epistemically labeled Markdown block (lanes, accepted relationships, unreviewed proposals, confirmed-false entries, coverage gaps), or `None` when the vault has nothing to say — no wasted tokens. Before recall it reindexes incrementally if the last index run is older than `reindex_seconds` (default 300). - `system_prompt_block()` describes the vault (note/relationship/open-proposal counts from doctor) and tells the agent how to read recall labels. - **Write policy:** `sync_turn` is a no-op — turns are never captured automatically. Writes happen only through `on_memory_write` (→ `mindpouch remember`, new reviewable notes in the capture dir) and the explicit `mindpouch_remember` tool. `auto_capture` is reserved for a future conservative mode. - Tools mirror the MCP server: recall, search, remember, probe, relationships, relate, propose relationships, propose consolidation, list/accept/reject proposals (kind-aware), ask/questions/answer/drop question (prospective memory), status. - Prefetch also injects when an open question strictly matches the turn even with no context blocks — that is the prospective-memory trigger ("you wanted to find out X"). Question-only turns render the questions alone, so imprecise any-term context can never ride along. Operators control it granularly in provider.json: `inject_questions` (include questions at all, default true), `inject_questions_alone` (question-only matches trigger injection, default true), `inject_questions_max` (cap, default 3; 0 disables). The cap is passed into the recall request (`--max-questions`), so the engine renders exactly what is configured — no post-hoc text editing. ## Configuration One Mindpouch config file is shared by the CLI, the MCP server, and this provider. Defaults: `$MINDPOUCH_CONFIG`, else `$HERMES_HOME/mindpouch/config.json`, else `~/.hermes/mindpouch/config.json`. Provider config keys (see `get_config_schema()`): `vault`, `index`, `config_path`, `mindpouch_repo` or `cli_path`, `node_bin`, `recall_limit`, `capture_dir`, `scope`, `auto_index`, `reindex_seconds`, `inject_questions`, `inject_questions_alone`, `inject_questions_max`, `auto_capture` (reserved). `save_config({vault: ...})` runs `mindpouch setup agent`, which writes the shared config and performs the initial index. ## Requirements - Node ≥ 22 on PATH and a built Mindpouch checkout (`pnpm install && pnpm -r build`). - Python ≥ 3.9, standard library only. ## Tests ```bash pnpm -r build python3 -m unittest discover packages/adapters-hermes/tests ``` ## Wiring into Hermes `hermes_native.py` subclasses Hermes' actual `MemoryProvider` ABC (from `agent.memory_provider`) and adapts the contracts: cheap `is_available` (no subprocesses; doctor runs in `initialize`), `prefetch` returning `""` and preferring results cached by `queue_prefetch`, OpenAI-format tool schemas, JSON-string tool results, and `on_memory_write(action, target, content)` mirroring built-in memory writes into the capture dir (primary agent context only). Prefetch errors degrade to `""` so memory never breaks a turn. Install as a user plugin — no changes to the hermes-agent checkout: ```text $HERMES_HOME/plugins/mindpouch/ __init__.py # shim: loads plugin/ from the Mindpouch checkout under a # unique module name and re-exports MindpouchHermesProvider plugin.yaml ``` Optional operator config at `$HERMES_HOME/mindpouch/provider.json` (`cli_path`, `node_bin`, `scope`, `reindex_seconds`, ...). The Mindpouch config the CLI/MCP share lives beside it at `$HERMES_HOME/mindpouch/config.json`; the provider reports itself unavailable with instructions until that exists. Verify with `hermes memory status` (mindpouch should appear under installed plugins) and activate with `hermes memory setup`.