Integrations V3
Sibyl Memory Plugin is framework-agnostic. The Hermes provider gets the most attention because it was the first wrapper to ship, but the underlying SDK is plain Python and works with anything. This page covers the three real integration paths and the clients each one unlocks.
Pick your path
Most agents fall into one of three categories. Pick the one that matches your stack:
All paths read from and write to the same local ~/.sibyl-memory/memory.db. Run two clients side
by side and they share state — useful for hybrid agents.
Path 1 · MCP server (Claude Code, Codex, Cursor, Continue, anything that speaks MCP)
The cleanest path for anything that consumes Model Context Protocol. We ship sibyl-memory-mcp — a Python MCP server that wraps the local SDK and exposes 8 memory tools over stdio.
1.1 · Install the MCP server
$ pip install sibyl-memory-mcp
This pulls in sibyl-memory-client and sibyl-memory-hermes automatically. If you haven't already activated:
$ sibyl init
1.2 · Wire it into your client
Each client expects the MCP server declared in its config. The command is always sibyl-memory-mcp — what changes is the file you put it in.
{
"mcpServers": {
"sibyl-memory": {
"command": "sibyl-memory-mcp"
}
}
}
[[mcp_servers]]
name = "sibyl-memory"
command = "sibyl-memory-mcp"
{
"mcpServers": {
"sibyl-memory": {
"command": "sibyl-memory-mcp"
}
}
}
{
"experimental": {
"modelContextProtocolServers": [
{
"transport": {
"type": "stdio",
"command": "sibyl-memory-mcp"
}
}
]
}
}
Restart the client. The 8 tools are available immediately — no further setup.
1.3 · What the agent can now do
| Tool name | What it does | Tier |
|---|---|---|
memory_remember | Store an entity by (category, name) | free + paid |
memory_recall | Read an entity by exact key | free + paid |
memory_search | FTS5 search across all entities | free + paid |
memory_list | List entities in a category | free + paid |
memory_forget | Archive an entity (recoverable) | free + paid |
memory_set_state | Write a HOT-tier state document | free + paid |
memory_get_state | Read a HOT-tier state document | free + paid |
memory_record_event | Append a COLD-tier journal event | free + paid |
Self-learning and the memory check-up tools are not exposed on the free tier; they activate as MCP tools after sibyl upgrade.
1.4 · Try it in Claude Code
After the config above, the next time you start Claude Code in any project:
The agent decides which tools to call. No prompt engineering required — the tool descriptions are written so the model picks the right one for memory-shaped requests.
Path 2 · Direct Python SDK (Hermes, LangChain, LlamaIndex, custom orchestration)
For Python-based agents and frameworks. Import the SDK, instantiate a client, call methods. Same surface area as the MCP tools, just exposed as method calls instead of MCP RPC.
2.1 · Hermes (the canonical wrapper)
from sibyl_memory_hermes import SibylMemoryProvider
from hermes_agent import Agent
agent = Agent(memory=SibylMemoryProvider())
The provider auto-reads ~/.sibyl-memory/credentials.json, opens the local SQLite, and routes all of Hermes' memory operations through the same engine the MCP server uses.
2.2 · LangChain (BYO wrapper)
LangChain doesn't have a native Sibyl Memory adapter yet. The shape is small — wrap MemoryClient in a
BaseChatMessageHistory subclass:
from sibyl_memory_client import MemoryClient
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.messages import BaseMessage, message_to_dict, messages_from_dict
class SibylChatHistory(BaseChatMessageHistory):
def __init__(self, session_id: str):
self.client = MemoryClient.local("~/.sibyl-memory/memory.db")
self.session_id = session_id
@property
def messages(self) -> list[BaseMessage]:
doc = self.client.get_state(f"chat:{self.session_id}")
return messages_from_dict(doc["messages"]) if doc else []
def add_message(self, message: BaseMessage) -> None:
existing = self.messages
existing.append(message)
self.client.set_state(
f"chat:{self.session_id}",
{"messages": [message_to_dict(m) for m in existing]},
)
def clear(self) -> None:
self.client.set_state(f"chat:{self.session_id}", {"messages": []})
Drop into any chain that accepts a BaseChatMessageHistory.
2.3 · LlamaIndex (BYO wrapper)
Same pattern, different base class — implement BaseChatStore:
from sibyl_memory_client import MemoryClient
from llama_index.core.storage.chat_store import BaseChatStore
from llama_index.core.llms import ChatMessage
class SibylChatStore(BaseChatStore):
def __init__(self):
self.client = MemoryClient.local("~/.sibyl-memory/memory.db")
def get_messages(self, key: str) -> list[ChatMessage]:
doc = self.client.get_state(f"llama:{key}")
return [ChatMessage(**m) for m in (doc or {}).get("messages", [])]
def set_messages(self, key: str, messages: list[ChatMessage]) -> None:
self.client.set_state(f"llama:{key}", {"messages": [m.dict() for m in messages]})
def delete_messages(self, key: str) -> None:
self.client.set_state(f"llama:{key}", {"messages": []})
2.4 · Custom Python orchestration
The lowest-friction path. Just call the SDK directly from wherever you're running:
from sibyl_memory_client import MemoryClient
client = MemoryClient.local("~/.sibyl-memory/memory.db")
# Store something
client.set_entity("projects", "atlas", {
"status": "shipping v2 next week",
"owner": "alice",
"blockers": ["vendor SAML cert"],
})
# Read it back
project = client.get_entity("projects", "atlas")
# Search across everything
results = client.search_entities("SAML", limit=10)
# Record what happened
client.write_event("decision", {
"chose": "saml over oidc",
"reason": "vendor support timeline",
}, category="projects", name="atlas")
Path 3 · Shell-out via the sibyl CLI (any agent that can exec)
The escape hatch. If your agent can run shell commands but doesn't speak MCP and can't import Python, use the
sibyl CLI as a thin RPC layer.
The CLI today covers activation + status + upgrade + health. Memory read/write via CLI is on the roadmap (see CLI reference); until then, the MCP server is the right path for non-Python agents.
Compatibility matrix
| Client | Path | Setup | Status |
|---|---|---|---|
| Claude Code | MCP | ~/.claude/settings.json mcpServers block |
live |
| Codex CLI | MCP | ~/.codex/config.toml [[mcp_servers]] table |
live |
| Cursor | MCP | ~/.cursor/mcp.json mcpServers block |
live |
| Continue | MCP | config.json experimental.modelContextProtocolServers | live |
| Hermes | Native provider | Agent(memory=SibylMemoryProvider()) |
live |
| LangChain | SDK wrapper | ~30 lines · custom BaseChatMessageHistory |
live · BYO |
| LlamaIndex | SDK wrapper | ~30 lines · custom BaseChatStore |
live · BYO |
| Any Python agent | Direct SDK | pip install sibyl-memory-client |
live |
| Shell-only agent | sibyl CLI subprocess |
activation only today · memory ops on roadmap | partial |
Mix and match
All paths share the same local SQLite. Common configurations:
- Use Claude Code via MCP for interactive coding, and a Hermes agent in the same project for autonomous overnight runs. Both see the same memory.
- Activate the MCP server in your editor (Claude Code or Cursor) AND import the SDK in scripts. The CLI installation includes everything; the choice of access pattern is per-context.
- Run two MCP-equipped agents simultaneously (e.g. Claude Code + Codex). SQLite WAL mode handles concurrent reads cleanly; serialized writes through the SDK's connection pool.
What gets persisted
Regardless of which path you use, every write lands in the same five-tier model:
- HOT · state documents (
memory_set_state/set_state) — overwritten frequently - WARM · entities (
memory_remember/set_entity) — keyed by (category, name), idempotent - COLD · journal events (
memory_record_event/write_event) — append-only audit trail - REFERENCE · canonical docs (paid tier; written via SDK)
- ARCHIVE · soft-deleted entities (via
memory_forget/archive_entity)
See How memory works for the full mental model.
One install, one identity
Every integration path reads from ~/.sibyl-memory/credentials.json and writes to the same
~/.sibyl-memory/memory.db. There's nothing per-client to activate or pay for. Your free-tier 2 MB
cap (or your paid uncapped allowance) applies across every integration uniformly.
If you want isolated memory per project (work vs side projects, multiple identities on one machine), point each
client at a different directory via the SIBYL_MEMORY_DB + SIBYL_CREDENTIALS environment
variables. The MCP server respects both; the Python SDK accepts an explicit path on
MemoryClient.local().
Troubleshooting
"unknown command: sibyl-memory-mcp"
The pip install succeeded but the entry-point isn't on PATH. Check which sibyl-memory-mcp;
if empty, add Python's user-bin to your PATH (e.g. export PATH="$HOME/.local/bin:$PATH") or use the
full module form in your client config: "command": "python", "args": ["-m", "sibyl_memory_mcp"].
"no credentials found" when the agent first calls a tool
Run sibyl init in a terminal. The MCP server picks up the new credentials on the next tool call —
no need to restart Claude Code / Codex / etc.
"CAP_EXCEEDED" on a write
Your free tier has filled the 2 MB local cap. Run sibyl upgrade. The MCP server sees the new tier on
the very next call (it re-reads credentials each time).
Tool calls work but the agent ignores the memory
Tool availability is one thing; the agent deciding to use them is another. If your agent has system prompt customization, add a line like "You have access to long-term memory via the memory_* tools. Call memory_recall when the user references something they told you before; call memory_remember when they share something worth keeping." Most agents pick this up on their own after a few interactions.