Drop-in memory provider for Hermes Agent. Local-first via embedded SQLite with FTS5. Structured five-tier memory model. Multi-tenant by construction. Open-source, MIT. Built for the pains 99 Hermes user stories already documented.
We read 99 user stories from the Hermes ecosystem. Five of seven biggest documented gaps are solved natively by what Sibyl Memory Plugin already does. The plugin productizes that.
| Gap they documented | How the plugin solves it |
|---|---|
| "73% of every API call is fixed overhead. Long conversations were making the agent slow and forgetful."token-overhead pain | HOT / WARM / COLD / REFERENCE / ARCHIVE tier auto-compression. Old conversations summarize into structured cards. Retrieval scoped by tier. |
| "I want per-group specialization. Per-session same personality, system prompt, CLAUDE.md, working directory." Users hack this with Telegram topics today.partitioning pain | Multi-tenant by tenant_id namespace. One parameter at construction. Each role / project / channel gets isolated memory enforced at the DB layer. |
| "112 of 129 audited sessions violated approval protocol. For multi-user servers, kid-facing bots, compliance. I want a human-in-the-loop gate."compliance pain | Tamper-proof audit log on every memory write. Cascade-delete for GDPR. Self-host path for air-gapped requirements. EU AI Act export ready. |
| "Users want agents to adapt style and preferences but the current system only recalls."persona pain | Schema accepts persistent personality scaffolding (identity, voice, soul, diary). Cross-session retention validated at #2 on LongMemEval Oracle. |
| "Built a memory provider plugin connecting agentmemory to Hermes. Covers cross-agent memory."federation pain | Polymorphic SDK. Same Postgres schema usable from Hermes, Claude Code, Cursor, anywhere with database access. Federation by design, not by hack. |
"I built my own stack independently and we converged on the same architecture. Background self-improvement, persistent memory, CLAUDE.md project context, reusable skills." Hermes user · public story
Three packages on PyPI · sibyl-memory-cli is the entry point.
sibyl-memory-client (the SDK), sibyl-memory-hermes (the Hermes provider), and sibyl-memory-cli (the sibyl command). Installing the CLI pulls all three. Install via curl one-liner (curl -fsSL https://install.sibyllabs.org | sh) or pip (pip install sibyl-memory-cli). MIT licensed.
Open-source under MIT. Activation provisions a Sibyl Labs account and initializes a local
SQLite database with FTS5 full-text search at ~/.sibyl-memory/memory.db.
All memory operations execute locally. No data leaves your machine on the free tier.
$ curl -fsSL https://install.sibyllabs.org | sh ✓ Python: Python 3.12.3 ✓ pip available Installing sibyl-memory-cli (pulls sibyl-memory-client + sibyl-memory-hermes) Successfully installed sibyl-memory-cli-0.1.2 sibyl-memory-hermes-0.3.1 sibyl-memory-client-0.3.3 ✓ sibyl binary on PATH: /Users/you/.local/bin/sibyl Next: sibyl init $ sibyl init Sibyl Memory Plugin · activation Session: 8f3a2c1e…89bc4 Opening: https://auth.sibyllabs.org/8f3a2c1e-9b4d-4a07-b6f1-e2d5c3a89bc4 Sign in with your wallet, email + code, or send USDC from any mobile wallet. This terminal will pick up automatically. ⠹ waiting for browser activation … 9:42 left ✓ Activated. Account: a1b2c3d4…e5f6 Tier: FREE (local, hard-capped at 2 MB · run `sibyl upgrade` to lift) Wallet: 0x4069...49fBe Credentials: ~/.sibyl-memory/credentials.json (mode 0600) Activate Sibyl in Hermes: sibyl-memory-hermes install-plugin # then edit ~/.hermes/config.yaml: # memory: # provider: sibyl
The sibyl command ships with the sibyl-memory-cli package (installed alongside the plugin). Three activation paths in the browser: SIWE (sign a one-line message with any Ethereum wallet) for wallet-native desktop users, email + 6-digit pairing code printed in your terminal (no magic-link email provider in the loop, no wallet needed), or USDC-send from any mobile wallet (sub-cent USDC on Base proves wallet control; works on mobile Safari/Chrome without an injected wallet). All three bind the same way and produce the same credentials file.
The plugin generates a session token locally, prints an activation URL, and polls for binding. The browser handles auth. The plugin picks up the result. Nothing exotic. Seven steps end-to-end.
On first run of sibyl init, the plugin generates a UUIDv4 session token, saves it to local state, and begins polling https://api.sibyllabs.org/api/plugin/check?session=... every 3 seconds with a 10-minute timeout.
Plugin prints https://auth.sibyllabs.org/<session-uuid> (dedicated short-URL auth subdomain, since cli 0.3.3). User opens it in any browser on any machine. Page reads the session token from the URL and ensures the sibyl_plugin.sessions row exists via https://api.sibyllabs.org/api/plugin/nonce. Legacy sibyllabs.org/plugin/activate?session=... still resolves for users on older CLI builds.
Page presents three paths: Sign-In With Ethereum (SIWE) for desktop users with an injected wallet, email + 6-digit pairing code printed in the terminal for any device without a wallet (no magic-link email provider — the hash of the code goes to the server, the code itself stays on the user's machine), or send sub-cent USDC on Base from any mobile wallet (the backend watcher matches the on-chain transfer to the session and binds the sender wallet). All three bind to the same account model.
https://api.sibyllabs.org/api/plugin/bind verifies the SIWE signature, atomically consumes the nonce, upserts a row in sibyl_plugin.accounts by wallet (or email), and binds the session token to the account in sibyl_plugin.sessions. First-time bindings record a first_activation entry in the activation log.
account_id is returned. Total_activations increments, no duplicate row.The next https://api.sibyllabs.org/api/plugin/check response returns { bound: true, credentials: {...} }. The plugin writes ~/.sibyl-memory/credentials.json with mode 0600 and initializes the local SQLite database with the schema (10 tables + 2 FTS5 virtual tables).
The new account flows into the lab's onboarding queue via the Discord activation webhook + funnel-stage events captured at every step. Wallet (if SIWE), OS / Python / Hermes version, install method, country, source attribution.
Wire the provider into your Hermes agent in two lines. From here on, every memory read and write routes locally through the SQLite database. Periodic heartbeats to https://api.sibyllabs.org/api/plugin/heartbeat ping capacity + machine-fingerprint signals. No memory content leaves the device.
The Hermes provider is a thin adapter over the lower-level SDK. sibyl-memory-client is
the storage + multi-tenant primitive layer (5-tier model, FTS5 search). sibyl-memory-hermes
binds it to Hermes' v0.13.0 memory contract. Both are zero-config and dependency-light.
├── pyproject.toml # declares sibyl-memory-client >= 0.1.0 dep ├── README.md # getting-started ├── LICENSE # MIT ├── CHANGELOG.md # version history ├── src/sibyl_memory_hermes/ │ ├── __init__.py # public exports: SibylMemoryProvider, Credentials, load_credentials │ ├── provider.py # Hermes v0.13.0 provider · routes to the 5 memory tiers │ └── credentials.py # credentials.json read/write (mode 0600) └── tests/ └── test_smoke.py # 21 tests · construction, tier routing, FTS, multi-tenant
├── pyproject.toml # zero runtime dependencies ├── src/sibyl_memory_client/ │ ├── __init__.py # public exports: MemoryClient, Storage, DEFAULT_TENANT │ ├── client.py # MemoryClient · polymorphic constructor · 5-tier API surface │ ├── storage.py # SQLite connection + per-instance thread-local pool │ ├── schema.sql # 10 tables + 2 FTS5 virtual tables · idempotent bootstrap │ └── exceptions.py # typed exception hierarchy (SibylMemoryError + subclasses) └── tests/ └── test_smoke.py # 10 tests · schema, CRUD, FTS5, multi-tenant isolation
The sibyl init / sibyl status / sibyl upgrade commands ship in a third sibling package, sibyl-memory-cli (in build). All three install together when you pip install sibyl-memory-hermes.
Embedded SQLite (WAL mode + FTS5 full-text search) holds your memory. Permissions 0700 on the directory,
0600 on the credentials file. Your existing Hermes memory files are not modified.
├── memory.db # SQLite database · 10 tables + 2 FTS5 virtual tables · canonical store ├── memory.db-wal # write-ahead log (WAL mode) ├── memory.db-shm # shared-memory file (WAL mode) └── credentials.json # account_id, tenant_id, tier, email, wallet, issued_at, session_token
Your Hermes agent's existing memory files (MEMORY.md, USER.md, Hermes' default
FTS5 db) are not modified. The plugin replaces the memory provider at the framework layer. An optional
one-time migration command will ship with sibyl-memory-cli for users who want to import existing context.
The plugin auto-loads credentials from ~/.sibyl-memory/credentials.json. No env vars required.
No config files. Sane defaults. The provider implements Hermes' v0.13.0 memory contract end-to-end.
memory: provider: sibyl
Each turn, the plugin injects a structured memory context block into the agent's system prompt. Compressed, tenant-scoped, audit-logged. Replaces the FTS5 dump that Hermes ships by default.
[BEGIN MEMORY CONTEXT - Sibyl Memory Plugin v0.3.1] Tenant: t-abc123 (local SQLite) Tier active: HOT Memory size: 2,847 entities · 12,431 journal entries · 47 active rules · 184MB # Recent entities (top 5 by recency) - project/atlas status=active last_modified=2h ago - person/jane role=collaborator context=working on Atlas project - product/atlas-v1.2 status=staging gate=jane signoff before prod - decision/error-budget threshold=2% last_referenced=4h ago - relationship/jane trust_level=high interaction_count=47 # Recent journal (top 5) - 2026-05-08T10:23 deployed atlas v1.2 to staging - 2026-05-08T08:51 jane requested rollback if errors >2% - 2026-05-07T19:14 shipped retry logic for queue worker - 2026-05-07T15:02 pair-debugged with jane on atlas batch processor - 2026-05-07T11:30 daily standup notes captured # Active rules (top 3 by relevance) - never deploy to production without jane's signoff - escalate any error rate >5% to operator - session bridging: end every session with a forward list [END MEMORY CONTEXT]
Free users never touch our cloud for memory operations. The plugin embeds SQLite (WAL mode, FTS5) and runs every read, write, and retrieval against the local database. Our cloud is in the path only for activation, telemetry, and paid-tier features (cross-device sync, team federation, enterprise audit export. On the roadmap).
Enterprise self-host (roadmap): the same SDK accepts a Postgres connection string in place of the local SQLite path, so a customer can run the entire stack against their own Postgres (RDS, Aurora, self-managed). Schema migrates idempotently. Customer fully owns the data; Sibyl Labs licenses + supports.
Free tier runs locally with a hard 2 MB cap on the SQLite database. Server-authoritative
cap-check fires only at the boundary, so under-cap writes stay local-first. Past the cap,
writes are rejected with an upgrade prompt. Two upgrade paths: stake $SIBYL on
Base (no recurring fee) or subscribe in USDC (monthly, quarterly, or annual). Cloud-tier
services are branded as Sibyl Sync.
/api/plugin/check-write; under-cap writes never phone homeConversion logic by user type: crypto-native users see Sibyl Stake as the natural option (wallet already connected at activation). Mainstream developers pick Sibyl Cloud if they need sync or team features. Subscription-averse devs pick Sibyl Local Lifetime. Pay once, own it. Compliance-driven orgs go through sales for Enterprise self-host. One product surface, four upgrade doors matched to how each segment actually buys.
v0.3.1 of both packages is built and live on PyPI (6/6 verification phases passed,
740 KB footprint after a 3-day simulated workflow). PyPI publish, the public install
command at install.sibyllabs.org, and the Resend-backed email magic-link
path go live within days of this page going up. If you run a Hermes Agent in production
and want first-wave access, reply with your use case and we will reach out the moment
the public install endpoint flips on.