Remnic MemoryProvider plugin for Hermes Agent
Project description
remnic-hermes
Remnic MemoryProvider plugin for Hermes Agent. Automatically injects memories into every LLM call and observes every conversation turn — no agent code changes required.
Why MemoryProvider
MCP tools give an agent the ability to call memory functions, but only when the agent decides to. With the MemoryProvider protocol, recall happens structurally on every turn before the LLM is called, and observation happens after every response. The agent cannot forget to recall because the hook is not optional. A plain MCP integration requires the LLM to recognize that it should search for memories and then choose to call the tool; the MemoryProvider removes that dependency entirely.
| Aspect | MCP Only | MemoryProvider |
|---|---|---|
| Recall | Agent must call remnic_recall |
Automatic on every turn |
| Observe | Agent must call remnic_store |
Automatic after every response |
| Latency | Tool call overhead | Pre-fetched, non-blocking |
| Reliability | Agent may forget to call | Structural — cannot be skipped |
Prerequisites
- Remnic daemon running and accessible on port
4318(default). See the Remnic repository for installation instructions. - Hermes Agent v0.7.0 or later — the MemoryProvider protocol was added in v0.7.0.
- Python 3.10 or later.
Quick start
-
Install the plugin:
pip install remnic-hermes
-
Wire Hermes to Remnic (starts the daemon if needed, generates an auth token, and writes the Hermes config entry):
remnic connectors install hermes
-
Restart Hermes so it picks up the new config entry.
-
Verify the connection:
hermes --version && pip show remnic-hermes
Your agent should now have access to
remnic_recall,remnic_store, andremnic_searchtools. Callremnic_recallwith any query to confirm memories are returned.
Manual configuration
If you prefer not to use remnic connectors install, add the following to your Hermes config.yaml directly:
plugins:
- remnic_hermes
remnic:
host: "127.0.0.1" # Remnic daemon host. Default: 127.0.0.1
port: 4318 # Remnic daemon port. Default: 4318
token: "" # Auth token. Leave empty to auto-load from ~/.remnic/tokens.json.
session_key: "" # Session identifier. Auto-generated as hermes-<12hex> if not set.
timeout: 30.0 # HTTP request timeout in seconds. Default: 30.0
A legacy engram: config block is also accepted during the Engram to Remnic transition. The plugin reads remnic: first and falls back to engram: when the remnic: key is absent, so existing configs continue working without edits.
Environment variable overrides
| Variable | Overrides | Description |
|---|---|---|
REMNIC_HOST |
remnic.host |
Daemon hostname or IP |
REMNIC_PORT |
remnic.port |
Daemon port number |
ENGRAM_HOST |
remnic.host |
Legacy fallback for REMNIC_HOST |
ENGRAM_PORT |
remnic.port |
Legacy fallback for REMNIC_PORT |
Environment variables are only consulted when the corresponding field is absent from the config block. Inline config values take precedence over environment variables.
The auth token is not read from an environment variable. It is either set inline (token: "...") or auto-loaded from the Remnic token store at ~/.remnic/tokens.json (falling back to ~/.engram/tokens.json during the compat window).
Token bootstrap
remnic connectors install hermes is the recommended way to get a token into place. It:
- Starts the Remnic daemon if it is not already running.
- Generates a dedicated per-connector auth token scoped to Hermes.
- Writes the token to
~/.remnic/tokens.json. - Adds the
remnic:block to your Hermesconfig.yaml. - Runs a health check against the daemon.
If you provision tokens manually, write a JSON file at ~/.remnic/tokens.json in the format:
{
"tokens": [
{ "connector": "hermes", "token": "remnic_hm_...", "createdAt": "2026-01-01T00:00:00Z" }
]
}
The plugin searches for a connector: "hermes" entry first, then falls back to connector: "openclaw".
What it does
| Method | Trigger | Behavior |
|---|---|---|
initialize |
Plugin loads | Opens an HTTP client to the Remnic daemon and pings /health. A failed health check is non-fatal — the daemon may start later. |
pre_llm_call |
Before every LLM call | Recalls up to 8 memories using the last user message as the query. Skipped if the user message is fewer than 3 words. Injects a <remnic-memory> block into the system prompt when results are found. |
sync_turn |
After every response | Sends the last 2 messages (user + assistant) to the Remnic daemon for real-time observation. |
extract_memories |
Session ends | Sends the full session transcript to the daemon for deep structured extraction. |
shutdown |
Plugin unloads | Closes the HTTP client. |
Tools it registers
| Tool name | Description |
|---|---|
remnic_recall |
Recall memories matching a natural language query |
remnic_store |
Store a memory explicitly |
remnic_search |
Full-text search across all stored memories |
During the Engram to Remnic compat window, three legacy aliases are also registered: engram_recall, engram_store, engram_search. These route to the same handlers. Their schema descriptions intentionally say "Engram" (not "Remnic") so that tool names and descriptions agree when a language model surfaces the legacy names. The engram_* aliases will be removed in a future major release. New integrations should use the remnic_* names.
Profiles and namespaces
Hermes isolates agent state per profile under ~/.hermes/profiles/<name>/. Each profile loads its own config.yaml, so you can run separate remnic: blocks with different session_key values to keep memory contexts distinct. See docs/plugins/hermes.md for a worked example.
Verify it is working
hermes --version && pip show remnic-hermes
Then start a session and call remnic_recall with a short phrase. If the daemon is healthy you will get a JSON response; if memories exist for that query they will appear in the context field. You can also check <remnic-memory> blocks in the Hermes debug log to confirm automatic recall is firing on each turn.
Troubleshooting
Daemon not running
remnic daemon status
remnic daemon install # installs and starts the launchd/systemd service
Token missing — calls return 401
Check that ~/.remnic/tokens.json exists and contains a hermes connector entry. Re-running remnic connectors install hermes regenerates the token and re-writes the file.
cat ~/.remnic/tokens.json
Import error — ModuleNotFoundError: No module named 'remnic_hermes'
The package must be installed in the same Python environment Hermes uses:
which python && pip show remnic-hermes
hermes --version
If they differ, install into the correct environment: <path-to-hermes-python> -m pip install remnic-hermes.
Memories not appearing in context
Memories are only injected when the last user message is 3 or more words and the daemon is reachable. Check daemon health first, then verify the query length. You can force a manual recall via the tool to confirm the round-trip works:
remnic daemon status
Uninstall
pip uninstall remnic-hermes
remnic connectors remove hermes
remnic connectors remove hermes revokes the token and removes the config entry from Hermes config.yaml.
Further reading
- Full reference: docs/plugins/hermes.md — complete config schema, recall/observe/extract internals, profile isolation examples, and migration notes from the Engram era.
- Remnic repository — daemon installation and overall architecture.
- Hermes Agent — the agent framework this plugin extends.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file remnic_hermes-1.0.1.tar.gz.
File metadata
- Download URL: remnic_hermes-1.0.1.tar.gz
- Upload date:
- Size: 8.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba82f9084a56ce901e304f96081b0907d13c768fe0e57d52cb37af325bcac5f4
|
|
| MD5 |
4430d72543cce459cd12f2ab6e7563e2
|
|
| BLAKE2b-256 |
4681ec4b4a30b7cd6ed0e951dde5aa268c1e488e6405c7943ed993e283c1e9cd
|
Provenance
The following attestation bundles were made for remnic_hermes-1.0.1.tar.gz:
Publisher:
hermes-python.yml on joshuaswarren/remnic
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
remnic_hermes-1.0.1.tar.gz -
Subject digest:
ba82f9084a56ce901e304f96081b0907d13c768fe0e57d52cb37af325bcac5f4 - Sigstore transparency entry: 1279021491
- Sigstore integration time:
-
Permalink:
joshuaswarren/remnic@e0009034978081f9555ffa015e658cb6df09ddc2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/joshuaswarren
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
hermes-python.yml@e0009034978081f9555ffa015e658cb6df09ddc2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file remnic_hermes-1.0.1-py3-none-any.whl.
File metadata
- Download URL: remnic_hermes-1.0.1-py3-none-any.whl
- Upload date:
- Size: 9.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b11f1bbb2dc9a77778f8203cdf9302b732d8c08eb09a79a22bf3027183d6b74f
|
|
| MD5 |
0206c7c3cb68aab66afb012f993d00fe
|
|
| BLAKE2b-256 |
8bd714c78c35d4b86412e785fd01e90f38e9126c6874928b54a670fe2c86b82d
|
Provenance
The following attestation bundles were made for remnic_hermes-1.0.1-py3-none-any.whl:
Publisher:
hermes-python.yml on joshuaswarren/remnic
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
remnic_hermes-1.0.1-py3-none-any.whl -
Subject digest:
b11f1bbb2dc9a77778f8203cdf9302b732d8c08eb09a79a22bf3027183d6b74f - Sigstore transparency entry: 1279021494
- Sigstore integration time:
-
Permalink:
joshuaswarren/remnic@e0009034978081f9555ffa015e658cb6df09ddc2 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/joshuaswarren
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
hermes-python.yml@e0009034978081f9555ffa015e658cb6df09ddc2 -
Trigger Event:
push
-
Statement type: