Pebble is a local-first, append-only memory substrate for AI coding agents.
Stop losing your agent's context. Pebble provides a durable, research-backed memory layer that injects a "hot cache" of relevant facts, skills, and preferences into every session.
Pebble isn't a simple file-syncer. It's built on a "known-good" architecture derived from the 2026 agentic memory research wave:
- EverMemOS (
2601.02163) β MemCell schema & atomic fact extraction. - AutoSkill (
2603.01145) β Automated skill extraction from user queries. - SwiftMem (
2601.08160) β Query-aware indexing and context caching.
Four packages live here:
| Package | What it is |
|---|---|
pebble-mcp/ |
The core: MCP server + SQLite projection + markdown renderers + CLI |
claude-code-plugin/ |
Claude Code plugin: slash commands, hooks, skills, reviewer subagent |
factory-droid-plugin/ |
Factory Droid plugin: commands, hooks, skills, reviewer droid |
gemini-cli-plugin/ |
Gemini CLI extension: TOML commands, hooks, skills, reviewer sub-agent |
Current status: MVP tagged pebble-mvp-v0.0.1. Live memory for the author is at ~/.pebble/ (12 cells, 12 events, 28 facts as of this writing).
graph LR
A[Agent] -- "memory_assert" --> L(π JSONL Log)
L -- "Projecting" --> D[(ποΈ SQLite DB)]
D -- "Rendering" --> V[π Obsidian Vault]
D -- "Hot Cache" --> A
V -- "User Edit" --> L
Most memory tools focus on file synchronization. Pebble focuses on state management.
| Feature | Pebble | Claude Obsidian |
|---|---|---|
| Architecture | Append-only Event Log | Simple File Sync |
| Performance | SQLite + FTS5 Indexing | Brittle File Watching |
| Integrations | MCP, Claude Code, Gemini CLI | Claude Desktop Only |
| Research | Based on EverMemOS | N/A |
- Log (
~/.pebble/log.jsonl) β every assertion, retraction, skill write, profile update is a single JSONL line. Never rewritten. - Projection (
~/.pebble/projection.db) β SQLite view of the log:cells,facts,scenes,skills,foresight,events, plus an FTS5 index. - Vault (
~/.pebble/vault/*.md) β human-readable markdown rendered from the projection:profile.md,skills/*.md,scenes/*.md,_foresight.md,_contradictions.md,_index.md. - Hot cache β at session start each plugin injects a compact block (profile + active skills + current foresight + recent cells) so the agent begins every conversation already-oriented.
- Reviewer loop β after every assistant turn, a
Stophook fires and a lightweight reviewer extracts new preferences/projects/profile updates and callsmemory_assertto persist them. No manual curation required.
# 1) core
cd pebble-mcp
bun install
bun run init # creates ~/.pebble/{log.jsonl,projection.db,vault,trace.jsonl}
bun link # installs `pebble-mcp` on PATH
bun test # 74 tests
# 2) Claude Code
claude plugins marketplace add /absolute/path/to/agent-memory/claude-code-plugin
claude plugins install pebble@pebble-local
# 3) Factory Droid
# Edit ~/.factory/plugins/known_marketplaces.json + installed_plugins.json to point at
# factory-droid-plugin/, enable the plugin in ~/.factory/settings.json, and add the MCP
# server entry to ~/.factory/mcp.json:
# "pebble": { "command": "/ABS/PATH/TO/bun", "args": ["run", "/ABS/PATH/.../pebble-mcp/src/index.ts", "serve"] }
# 4) Gemini CLI
gemini extensions link /absolute/path/to/agent-memory/gemini-cli-plugin
# or from the repo root: `gemini extensions install /absolute/path/to/agent-memory/gemini-cli-plugin`pebble-mcp serve # MCP stdio server (11 tools)
pebble-mcp init # create ~/.pebble structure
pebble-mcp verify # replay log β projection, confirm consistency
pebble-mcp status # counts: cells, events, skills
pebble-mcp hot-cache-for-cc # system-prompt block (Claude Code format)
pebble-mcp hot-cache-for-droid # system-prompt block (Droid format)
pebble-mcp hot-cache-for-gemini # system-prompt block (Gemini CLI format)
pebble-mcp render-vault # materialize full markdown vault
pebble-mcp commit-turn <arg> # CC/Droid plugin hook helper
pebble-mcp review-turn <arg> # extract facts from a transcript
pebble-mcp seed-test-fixture # seed synthetic data (tests/demos)
| Tool | Purpose |
|---|---|
memory_assert |
Write a new MemCell (profile / preference / project / episodic / skill / transient) |
memory_query |
Hybrid BM25 + recency + confidence search over cells |
memory_touch |
Record a retrieval hit against a cell |
memory_retract |
Mark a cell retracted (append-only, still in log) |
memory_read_cell |
Read a single cell by id |
profile_read |
Dump the derived profile |
profile_update |
Merge new facts into profile |
skill_save |
Save a SKILL.md-compatible skill |
skill_list |
List saved skills |
skill_read |
Read a skill by name |
trace_read |
Retrieval-trace tail for observability |
Four paths, pick whichever fits your flow:
- Dashboard β run
pebble-mcp statusor query~/.pebble/projection.dbdirectly for a live view. - Hot cache β
pebble-mcp hot-cache-for-cc/...-droidprints the exact block the plugins inject at session start. - Vault β
pebble-mcp render-vaultmaterializes~/.pebble/vault/{profile,_foresight,_contradictions,_index}.md+skills/*.md+scenes/*.md. Open in Obsidian for a graph view, or any editor. - Log β
tail -f ~/.pebble/log.jsonlfor the raw event stream.
agent-memory/
βββ README.md # this file
βββ docs/ # planning + design notes
βββ pebble-mcp/ # core library + MCP server + CLI
β βββ src/
β β βββ index.ts # dispatcher
β β βββ server.ts # MCP stdio server
β β βββ cli/ # init, verify, status, hot-cache, render-vault, commit-turn, review-turn
β β βββ memory/ # cell/fact/scene types + storage
β β βββ projection/ # SQLite schema + projector
β β βββ render/ # profile/skill/scene/foresight/contradictions/index renderers
β β βββ hotcache/ # hot-cache builder (CC + Droid targets)
β β βββ review/ # deterministic MVP reviewer + transcript parser
β β βββ paths.ts # ~/.pebble layout
β βββ tests/ # 74 tests across 17 files
βββ claude-code-plugin/ # `pebble@pebble-local` for Claude Code
β βββ plugin.json # manifest + MCP server entry
β βββ commands/ # /pebble, /remember, /forget, /recall, /profile
β βββ agents/ # pebble-reviewer subagent
β βββ skills/ # pebble, pebble-query, pebble-save
β βββ hooks/ # SessionStart, PostToolUse, PostCompact, Stop
βββ factory-droid-plugin/ # `pebble@pebble-local` for Factory Droid
β βββ plugin.json # manifest (MCP in ~/.factory/mcp.json β see docs/)
β βββ commands/ # /pebble, /remember, /forget, /recall, /profile
β βββ droids/ # pebble, pebble-reviewer
β βββ skills/ # pebble, pebble-query, pebble-save
β βββ hooks/ # SessionStart, PostToolUse, Stop
βββ gemini-cli-plugin/ # `pebble` extension for Gemini CLI
βββ gemini-extension.json # manifest + embedded MCP server
βββ GEMINI.md # context file (loaded into system prompt)
βββ commands/ # *.toml β /pebble, /remember, /forget, /recall, /profile
βββ agents/ # pebble-reviewer sub-agent
βββ skills/ # pebble, pebble-query, pebble-save
βββ hooks/ # SessionStart, AfterTool, AfterAgent, PreCompress
- Append-only log β the JSONL file is the source of truth. Everything else is derived and can be rebuilt via
pebble-mcp verify. - Markdown round-trip β editing a vault
.mdfile in Obsidian emits auser_editevent back into the log, so the user stays in the loop. - Two-way hydration β session-start injection pulls from memory; the Stop-hook reviewer pushes new facts into memory. No manual
/rememberrequired, though the slash command exists for explicit writes. - Local-first β every byte lives under
~/.pebble/. No network, no remote store. Portable JSONL + SQLite. - Plugin-agnostic core β
pebble-mcpknows nothing about Claude Code or Droid; the plugins are thin wrappers.
cd pebble-mcp
bun test # 74 tests, 136 expect() calls
bun run typecheck # tsc --noEmitEach plugin also has a smoke test at <plugin>/scripts/smoke.sh.
| Tag | What it ships |
|---|---|
pebble-mcp-mvp-v0.0.1 |
Core library + MCP server + CLI |
pebble-cc-plugin-mvp-v0.0.1 |
Claude Code plugin |
pebble-droid-plugin-mvp-v0.0.1 |
Factory Droid plugin |
pebble-mvp-v0.0.1 |
Umbrella release |
MIT License