Skip to content

Latest commit

 

History

History
157 lines (105 loc) · 12.8 KB

File metadata and controls

157 lines (105 loc) · 12.8 KB

Rembric — Hermes Agent plugin

Memory for Hermes Agent, backed by your self-hosted Rembric server.

Install

Use the TUI installer — the single recommended path. It runs the manual steps below for you and handles update/uninstall too:

curl -fsSL https://raw.githubusercontent.com/susomejias/rembric/main/install.sh | sh
# → Plugins → hermes → install

Manual install

Two commands, no git clone needed:

curl -fsSL https://raw.githubusercontent.com/susomejias/rembric/main/apps/plugin/.hermes-plugin/install.sh | sh
hermes plugins install rembric
hermes plugins enable rembric

hermes plugins install rembric prompts for the three values the plugin needs (declared in plugin.yaml::requires_env) and writes them to ${HERMES_HOME:-~/.hermes}/.env:

  • REMBRIC_SERVER_URL — base URL of your deployment, without the /mcp suffix. The bridge appends /mcp/<slug> itself when you wire it.
  • REMBRIC_API_TOKEN — Bearer token minted from the Rembric dashboard at /dashboard/tokens (plaintext shown exactly once). Marked secret: true in the manifest so the prompt hides the input.
  • REMBRIC_PROJECT_SLUG — default project slug for the provider and bridge.

If the three vars are already exported in the shell that launches hermes, the install skips the corresponding prompts.

Inspect the install script first if you prefer:

curl -fsSL https://raw.githubusercontent.com/susomejias/rembric/main/apps/plugin/.hermes-plugin/install.sh | less

Developing against a local rembric clone? Same script, local source:

PLUGIN_SRC="$(pwd)/apps/plugin/.hermes-plugin" sh apps/plugin/.hermes-plugin/install.sh

Configure

The plugin works in two complementary modes — wire both unless you really only want lifecycle without tool access:

Mode What you get Where it's configured
Memory provider Auto session create / summary-on-compact / end-on-close memory.provider: rembric (this plugin)
MCP server Full memory tool surface (save/search/get/context/judge/...) mcp_servers.rembric (the bundled bridge)

Drop this block into ~/.hermes/config.yaml. Replace <plugin-version> with the exact version printed by the TUI installer (or in ~/.hermes/plugins/rembric/plugin.yaml):

mcp_servers:
  rembric:
    command: npx
    args: ['-y', '@rembric/mcp-bridge@<plugin-version>']
    env:
      REMBRIC_SERVER_URL: ${REMBRIC_SERVER_URL}
      REMBRIC_API_TOKEN: ${REMBRIC_API_TOKEN}
      REMBRIC_PROJECT_SLUG: ${REMBRIC_PROJECT_SLUG}
    enabled: true

memory:
  provider: rembric

The three ${REMBRIC_*} env vars come from ~/.hermes/.env (written by hermes plugins install rembric). Hermes loads that file for the provider; the explicit env map forwards the values to the MCP bridge. The bridge and provider resolve a per-directory .rembric file first, then REMBRIC_PROJECT_SLUG; if neither is valid, lifecycle POSTs are skipped and the bridge uses path-less /mcp.

Environment variables

Variable Required Description
REMBRIC_SERVER_URL Base URL of your Rembric deployment, without the /mcp suffix. Example: https://memory.example.com. No trailing slash.
REMBRIC_API_TOKEN Bearer token minted from the Rembric dashboard at /dashboard/tokens.
REMBRIC_PROJECT_SLUG Optional default project slug. Overridden by a valid per-directory .rembric file.
HERMES_HOME Override Hermes's home dir (default ~/.hermes). Honoured by the installer.

Where credentials live

All three vars live in ${HERMES_HOME:-~/.hermes}/.env — single source of truth. The flow:

  1. hermes plugins install rembric reads the manifest's requires_env: list, prompts the user for each value not already set in the parent shell, and writes the answers via save_env_value to ~/.hermes/.env.
  2. Subsequent Hermes launches read ~/.hermes/.env into os.environ before plugins import. The provider sees the values via os.environ.get(...).
  3. The mcp_servers.rembric.env map explicitly forwards those values to the bundled MCP bridge.

To change a value after install:

  • Edit ~/.hermes/.env directly (it's a flat dotenv file), then restart Hermes.
  • Or re-run hermes plugins install rembric — it re-prompts for any var not already in the parent shell and rewrites the file via save_env_value.

The plugin does not read any plugin-private dotenv file (~/.rembric/.env, etc. are silently ignored). Earlier 0.3.x versions read ~/.rembric/.env as a workaround; that mechanism was removed in 0.4.0 once requires_env: proved sufficient.

Project slug resolution

Rembric scopes everything to a project slug. The provider and bridge use the same cascade — the first valid match wins:

  1. <cwd>/.rembricPROJECT_SLUG=<slug>.
  2. REMBRIC_PROJECT_SLUG from the environment (populated by Hermes from ~/.hermes/.env).
  3. No valid slug → the provider skips lifecycle POSTs with one diagnostic, while the bridge uses path-less /mcp.

Every candidate is validated against the slug regex ^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$. Non-matching values are discarded and the cascade continues. The server URL remains the bare deployment URL; a /mcp/<slug> suffix is not a fallback.

Lifecycle (what the plugin actually does)

The provider implements four lifecycle methods that map onto Rembric's HTTP session endpoints:

  • initialize(session_id, cwd)POST /api/<slug>/sessions with {id, cwd, agent: "hermes"}, then POST /api/<slug>/sessions/<id>/resume.
  • on_pre_compress(messages) → joins messages into a transcript, caps at 20,000 chars, POST /api/<slug>/sessions/<id>/summary.
  • on_session_switch(new_id, ...)POST /api/<slug>/sessions/<cached id>/end when the id actually changed, then the same ensure-and-resume pair for the new id.
  • on_session_end(messages)POST /api/<slug>/sessions/<id>/end.

The resume runs once per session id per process, always straight after that id's first ensure. It revives a row a previous Hermes process left ended (or the stale sweep left abandoned) so a session resumed from the CLI keeps attaching memories to its own row instead of writing them with a null session_id; on a row that is already active the server treats it as a no-op. A failed ensure suppresses it.

system_prompt_block() returns the unified Rembric nudge — the same SAVE/RECALL/SUMMARIZE text the server hands MCP clients via the initialize.instructions block. Hermes does not consume that MCP block and exposes no per-turn hook, so this method is its only nudging surface; the text is kept byte-identical to the server's buildInstructions() BASE.

The remaining MemoryProvider methods (prefetch, sync_turn, on_memory_write, queue_prefetch) are intentional no-ops — those operations live exclusively on the MCP surface, so the bridge (wired via mcp_servers.rembric) handles them when the agent calls memory.search / memory.context / memory.save directly.

Troubleshooting

Symptom Likely cause
hermes memory status shows rembric: Missing after install Plugin not enabled. Run hermes plugins enable rembric and restart Hermes.
hermes plugins install rembric didn't prompt for the env vars The three REMBRIC_* vars are already set in the parent shell, so Hermes skipped the prompts (this is by design). Verify via env | grep REMBRIC_. To force re-prompts: unset REMBRIC_SERVER_URL REMBRIC_API_TOKEN REMBRIC_PROJECT_SLUG then re-run the install.
stderr shows [rembric] no project slug for session ...; skipping session POST Neither .rembric nor REMBRIC_PROJECT_SLUG produced a valid slug. Confirm REMBRIC_PROJECT_SLUG is in ~/.hermes/.env. Edit the file and restart Hermes, or re-run hermes plugins install rembric.
stderr shows [rembric] POST /sessions failed: HTTPError 403 Token doesn't have write permission for the project. Inspect at /dashboard/tokens on the server; revoke and reissue scoped to the project with the default write permission.
stderr shows [rembric] POST /sessions failed: HTTPError 404 REMBRIC_SERVER_URL is path-scoped (ends in /mcp/<slug>). The provider needs the bare server URL — use REMBRIC_PROJECT_SLUG for the slug, NOT the URL. Edit ~/.hermes/.env and remove the /mcp/<slug> suffix.
MCP works (memory.save/search round-trip) but /dashboard/sessions never gets a row The provider isn't loaded OR the install never wrote credentials. Confirm memory.provider: rembric is in ~/.hermes/config.yaml, then cat ~/.hermes/.env | grep REMBRIC_ to verify the three vars are present.
You edited ~/.hermes/.env and Hermes didn't pick up the new value Hermes reads .env at startup, not on every session. Restart Hermes.

For deeper agent-side debug (hermes memory status, plugin-load trace), see Hermes's docs at https://hermes-agent.nousresearch.com/docs.

Updating

Use the TUI installer (Plugins → hermes → update). It refreshes the provider files and automatically migrates the documented legacy mcp-remote block, preserving config.yaml.rembric-mcp-remote.bak; custom blocks remain untouched and receive the exact fallback entry. No separate npm update is needed because the bridge is fetched by its exact npx pin.

Manual fallback — re-run the installer; the script is idempotent (overwrites the three files):

curl -fsSL https://raw.githubusercontent.com/susomejias/rembric/main/apps/plugin/.hermes-plugin/install.sh | sh

Then restart the gateway. If the installer reported that it could not recognize a custom MCP block, replace that entry with the exact fallback it printed. hermes plugins update rembric will not work because the plugin was not installed via hermes plugins install owner/repo (Hermes's installer doesn't accept monorepo subpaths today, verified against hermes_cli/plugins_cmd.py::_resolve_git_url at v0.4.x). The curl-installer is the canonical update path. Re-running hermes plugins install rembric after the file update re-runs the requires_env flow without overwriting existing values.

For a temporary rollback after a broken release, see the emergency plugin rollback runbook.

Uninstall

Use the TUI installer (Plugins → hermes → uninstall). Manual fallback — run the uninstaller; it removes the three installed plugin files, disables the plugin, and is idempotent:

curl -fsSL https://raw.githubusercontent.com/susomejias/rembric/main/apps/plugin/.hermes-plugin/uninstall.sh | sh

It deliberately leaves your credentials (${HERMES_HOME:-~/.hermes}/.env) and any .rembric project markers in place — it prints what it left so you can remove them by hand if you want. Honours HERMES_HOME like the installer.