Second Brain
Mercury has a persistent, structured memory that grows with every conversation. When enabled, it learns what is true about you — and how you like to work — as beliefs with evidence, retrieves what is relevant to each message, and tells you when it learned something that changes how it behaves.
The Owner Model: beliefs, not just facts
Since 1.4.1 Mercury holds beliefs about you rather than a pile of facts. A belief is a claim ("prefers one command over many manual steps") with evidence for and against it, a confidence that fades unless it is seen again, the context it applies in (everywhere, one project, one channel, one domain), and a status: candidate (seen once) → held (seen in two sessions) → confirmed (you said so). Two beliefs that cannot both be true are contested and Mercury asks you once. What you state outright never fades; what Mercury inferred does, unless it keeps being true.
What it learns are working traits that change how Mercury behaves: reply length, when to ask before acting (per project or domain), options vs a recommendation, tone, your expertise and risk appetite per domain, when you are usually around, and how you give feedback. It never infers personality types, health, religion, politics or sexuality, never stores passwords or keys, and never generalises about other people beyond what you said.
How it learns. After each turn, a small model call turns the turn into belief operations — or nothing, which is the usual outcome. Mercury's own replies are never evidence about you. Every hour of activity (and at shutdown) a reflection pass reads your messages across sessions, infers traits, merges duplicates, flags contradictions and rewrites the owner brief. The brief — About you and How to work with you — is in every prompt, together with the beliefs relevant to the current message.
What you see. When something behaviour-changing is learned, the reply ends with one line: ☿ Noted: you'd rather I just run things here without asking. Say "forget that" to undo. From any chat:
| Command | What it does |
|---|---|
/memory learned [days] | What Mercury learned recently, numbered |
/memory beliefs | Traits by dimension, then confirmed preferences |
/memory contested | Pairs Mercury can't settle; /memory settle <n> a|b |
/memory confirm <n> · /memory forget <n> · /memory correct <n> <what is true> | Act on a numbered item |
/forget <text> · "forget that" | Forget the best match, or the last ☿ Noted line |
~/.mercury/soul/owner.md holds the same brief in plain text; anything you write under My notes is read back as something you stated. The dashboard's Memory page shows what was learned with Confirm / Forget, and a Quarantined list: rows the old extractor saved by mistake (Mercury's own replies stored as your preferences), hidden but restorable.
How it works
- Extraction — After each turn, a strict extractor turns what you said and did into belief operations: create, support, contradict, or nothing at all. Mercury's own replies are never evidence about you.
- Retrieval — Before each message, up to 5 beliefs relevant to it (with their confidence and context) go into the prompt, and the "About you" / "How to work with you" brief sits in every prompt.
- Reflection — After every hour of activity and at shutdown, one model pass reads your messages across sessions: it infers working traits, merges duplicates, flags contradictions, rewrites the brief, and lets faded beliefs retire.
- Decay — Confidence fades per kind (a fact over a year, a preference over months, a trait over weeks) unless the belief is seen again; what you stated outright never fades. A belief retires only when it faded and was contradicted or went stale for two half-lives.
One source. Every view of your memory — /memory, the dashboard, the search_memory and save_memory tools, the bots, cloud sync — reads and writes the same belief store. Who you are (your name, email, handles) lives in identity.owner in mercury.yaml, the one place it is set; Mercury never stores it as a belief.
Upgrading from an older Mercury. The first boot after the upgrade copies second-brain.db to second-brain.pre-owner-model.db next to it, then moves your memories into beliefs: real ones become candidates (or held, when they had been seen more than once); rows that were Mercury's own replies, credentials or templated filler are quarantined, never deleted, and wait in the dashboard under Quarantined with a Restore button. Nothing you could see before disappears, /memory and the dashboard keep working, and a reflection pass two minutes after that boot judges the migrated candidates against your real sessions.
Memory Tiers
Mercury models memory in two tiers, mirroring how human memory works:
| Tier | Scope values | Behavior |
|---|---|---|
| Conscious | durable, active | Always available for retrieval. Top-of-mind. |
| Subconscious | subconscious | Out of active recall. Confidence does not decay here. Recalled automatically when relevant to the current conversation. |
Subconscious mechanics
- After 30 days without being referenced, an active memory is moved to the subconscious instead of being deleted.
- Subconscious memories are preserved with their original confidence — no further decay applies while they sit there.
- During retrieval, if conscious results are weak, Mercury also searches the subconscious and surfaces the strongest matches. When a subconscious memory is recalled into a relevant conversation, it is promoted back to the conscious tier.
- Subconscious memories are only hard-deleted if explicitly dismissed. Otherwise they remain available forever.
This is why Mercury can resurface "I told you that two years ago" facts without polluting day-to-day reasoning.
Memory Types
| Type | Default scope | What it stores |
|---|---|---|
identity | durable | Who you are — name, role, background |
preference | durable | What you like and dislike |
goal | active | What you're working toward |
project | active | What you're building |
habit | durable | Behavioral patterns and routines |
decision | active | Decisions and choices you've made |
constraint | durable | Rules and constraints you follow |
relationship | durable | People and connections |
episode | active | Specific events and experiences |
reflection | durable | System-generated insights from patterns |
Conflict Resolution
When Mercury detects opposing memories (e.g. "prefers TypeScript" vs "prefers Python"), the higher-confidence one wins. If equal, the newer one wins. Negation mismatches ("likes X" vs "does not like X") are detected and resolved automatically.
Evidence Kinds
- direct — Explicitly stated by you (highest confidence)
- inferred — Pattern Mercury detected (decays over time)
- manual — Added via
/memorycommand or the web UI - system — Auto-generated reflections from consolidation
Web Dashboard Views
The Second Brain is exposed through four interconnected pages in the web dashboard.
Memory (/second-brain/memory)
A full browser for every memory item.
- Scope filter — toggle between
consciousandsubconsciousviews. A 💤 badge marks subconscious entries. - Search — full-text search across memory summaries; results merge conscious and subconscious matches.
- Inline edit — change summary, type, importance, confidence, or scope.
- Add memory — manually create a memory with type, summary, and evidence.
- Delete — soft-dismiss a memory (only explicit dismissal hard-deletes; otherwise items just move to subconscious).
Persons (/second-brain/persons, /second-brain/persons/:id)
People Mercury has encountered are extracted into a structured table.
- The listing shows each person's name, last-seen timestamp, and the number of memories associated with them.
- Click a person to open their detail page with their facts, related memories, and links to other persons (via
relationshipmemories).
Goals (/second-brain/goals)
A tabbed view that filters memories by type:
- Goals tab — every memory with
type: goal - Projects tab — every memory with
type: project
You can add new goals/projects directly from this page — they are stored as standard memories so the agent can reason over them.
Graph (/second-brain/graph)
A force-directed graph visualization that draws nodes for memories, persons, and goals, and edges for their relationships. Useful for spotting clusters (e.g. all goals connected to a particular project, or all persons connected to a company).
Managing Memory from chat channels
Use /memory in any channel:
| Action | CLI | Telegram |
|---|---|---|
| Overview | Arrow-key menu → Overview | Inline button: 📋 Overview |
| Recent memories | Arrow-key menu → Recent | Inline button: 🔍 Recent |
| Subconscious | Arrow-key menu → Subconscious | Inline button: 💤 Subconscious |
| Search | Arrow-key menu → Search | Not available (ask Mercury to search) |
| Pause learning | Arrow-key menu → Pause | Inline button: ⏸ Pause |
| Resume learning | Arrow-key menu → Resume | Inline button: ▶ Resume |
| Clear all | Arrow-key menu → Clear (with confirmation) | Inline button: 🗑 Clear → Yes |
API Endpoints
The web dashboard talks to the brain through a small REST surface:
GET /api/brain/status
GET /api/brain/memory # ?scope=conscious|subconscious
GET /api/brain/memory/search?q=...
GET /api/brain/memory/:id
PUT /api/brain/memory/:id
DELETE /api/brain/memory/:id
POST /api/brain/memory # manual add
GET /api/brain/persons
GET /api/brain/persons/:id
GET /api/brain/persons/:id/memories
GET /api/brain/graph
Goals and projects are not a separate resource — they are memories filtered by type=goal or type=project against /api/brain/memory.
Which model learns
Extraction and reflection are strict-JSON jobs; a weak free-tier model misses most of what you say or returns nothing. Point them at a capable provider without changing your chat model:
memory:
learning:
provider: anthropic # any name from `providers`; falls back to the default when unusable
(LEARNING_PROVIDER=anthropic does the same.) A Haiku-class model is plenty; each turn costs one small call and each hour of activity one reflection.
Enable / Disable
Second Brain is enabled by default. To disable it:
- Environment variable:
SECOND_BRAIN_ENABLED=false - Config file: set
memory.secondBrain.enabled: falsein~/.mercury/mercury.yaml
When disabled, Mercury falls back to basic long-term fact search (JSONL, text-match only). No extraction, no consolidation, no SQLite.
All data is stored locally in ~/.mercury/memory/second-brain/second-brain.db (SQLite). Nothing leaves your machine.
Troubleshooting
Native module version mismatch
If you see NODE_MODULE_VERSION mismatch errors in logs, the better-sqlite3 native addon was compiled against a different Node.js version than your runtime. Fix with:
npm rebuild better-sqlite3
When better-sqlite3 fails to load, Second Brain silently falls back to disabled — memory extraction and consolidation will not run. Check daemon logs (mercury logs) for SQLite-related errors if memories aren't being stored.