Sepia (remote knowledge-graph memory server)
You are connected to the user's personal memory server over MCP
(https://sepia.fly.dev/mcp). It stores a knowledge graph in namespaces
(default personal): entities (nodes: people, projects, tools, concepts,
repos), relations (directed edges), memories (facts/observations/
preferences/instructions with importance scores).
Types & tags (use the canonical values)
- Entity type (
manage_entity): person | project | tool | concept |
repo. Unknown types are auto-normalized to concept + tag.
- Memory type (
manage_memory): fact (verified/decided) | observation
(what you saw happen) | preference (user's stated or observed choice) |
instruction (how to behave).
- Tags (both): short lowercase hyphenated topical labels
(e.g.
user-experience, auth, performance) — add 1-4 per write when the
topic is recurring. Search and query can filter by tags.
When to recall (READ) — ALMOST EVERY MESSAGE
Default to search on every turn — only skip for trivial chitchat ("hi", "thanks", "bye") with zero durable content. If in doubt, search.
- Before you answer (every turn except trivial chitchat), call
search with 2-5 keywords from the user's current message + task (e.g. search query="rate limiting" namespace="personal").
- If results are sparse, also
traverse_graph from the most relevant entity to pull its neighborhood.
- Weave recalled facts into your answer naturally. Cite what came from memory when it matters ("From your memory: ...").
- If a search returns nothing, say so — never fabricate memories.
Two Sepia calls per turn is normal and expected: search before you answer, persist after you answer.
When to write (WRITE) — ALMOST EVERY MESSAGE
Persist in the same turn after your response when you learned something durable and reusable:
- Preferences ("prefers tabs over spaces", "wants PRs under 400 lines")
- Decisions and their rationale ("chose Neon over Supabase because...")
- Project facts ("mcp-showcase deploys via Vercel")
- People and roles, tools and stacks, conventions and constraints
- User corrections ("actually we use pnpm, not npm")
Do not store: ephemeral chat content, code snippets, credentials, secrets, or anything transient.
"Save to memory" → Sepia (not editor memory)
When the user says "save to memory", "remember this", "save this", "remember that", "save this for later", or any variant — ALWAYS write to Sepia (manage_memory + manage_entity if needed), NOT just the editor's built-in memory. Editor memory is ephemeral/session-local; Sepia (personal namespace by default) is the durable source of truth across sessions, editors, and AIs. Treat "save to memory" as an explicit instruction to call manage_memory create immediately in the same turn.
How to write
- Search first, update second — avoid duplicates. If a matching
entity/memory exists,
manage_entity action=update or manage_memory
action=update it.
- Entities before memories: ensure the entity exists (
manage_entity
action=find, else action=create with a short summary).
- Link memories to entities via
manage_memory action=create's
entity_ids field (1-3 entities max; prefer the most specific).
- Connect the graph with
manage_relation (e.g. project →uses→
tool, user →prefers→ thing). One relation per directed pair.
- Mass edits: to fix many rows at once (reclassify types, add tags), use
manage_entity/manage_memory action=batch_update with a where filter
(type, namespace, query/q, tags) + update — returns the count changed.
- Importance scoring (0-1):
- 0.9+: identity, core preferences, non-negotiables
- 0.6-0.8: active project facts, decisions, conventions
- 0.3-0.5: normal observations, people
- <= 0.2: transient details (will decay first)
- Namespaces: default
personal. Only create a new namespace if the user
asks for separation (e.g. work vs personal).
Conversation migration (handoff digests)
When the user says "save this conversation", "hand off to another AI",
"migrate my context", or is switching assistants mid-task, use
manage_memory action=ingest with a conversation payload. The departing
agent distills — you have the context, you are the best distiller.
The server atomically saves a bundle: a digest (entry point, auto-tagged
conversation, importance 0.85, protected from consolidation) + constituent
memories (the evidence) + entities (find-or-create).
Rules:
- One digest per major topic, all grouped by the same
conversation_id.
Multiple digests = one conversation. Search q="" + tags=["conversation"]
lists them all.
- Always give a human-readable
title (e.g. "Auth migration — Neon vs
Supabase") and a status: active (resume me) | paused | done. This is
how conversations are told apart when resuming — never skip it.
summary ≤4000 chars — context, decisions, open questions, pointers.
Anti-dump: if it doesn't fit, split into more digests — never pad.
- Keep evidence VERBATIM in
decisions / preferences / instructions /
observations: exact errors, paths, IDs, commands. Never soften them.
transcript is optional — only if the raw log actually exists (online
chat models may not expose one). source.ref (session path or share URL)
is the primary fidelity pointer.
open_questions become observation memories tagged open-question —
the next agent's starting point.
When the user says "load my context" / "continue from my last
conversation" / "what did we do last session": search with
q="" + tags=["conversation"] first, read the digest, then pull
constituents via query (tags) or the digest's entity links.
Resume flow: prefer the digest with status=active (or the most recent).
When a conversation is finished, update its digest metadata.status to done
(get the digest first, then update with the full metadata + new status —
metadata REPLACES). When resuming a paused one, set it back to active.
Examples
- User says "we went with Bun for the server because cold start matters"
→
manage_entity find/create Bun (type=tool, summary="JS runtime");
manage_memory create content="chose Bun over Node for cold start" type=decision
importance=0.7 entity_ids=[bun-entity-id]
- User asks "what do we know about the memory server plan?"
→
search query="memory server" → read top memories/entities → answer
with recalled facts, then traverse_graph if the user wants the full picture.
Edge cases
- Duplicate write: always search before create; if unsure, update the
existing item and mention the merge in your reply.
- Conflicting facts: create the new memory with importance equal to the old
one, note the conflict in your reply, and let
consolidate handle decay.
- Sensitive data: refuse to store credentials/secrets; tell the user the
memory server is not a vault.
- Wrong namespace: if the user is clearly working in
work context but no
such namespace exists, ask before creating it.
Reference
For full tool schemas and action enums, see references/tools.md.
1---2name: sepia3description: Use when the user's AI assistant should recall or persist long-term knowledge about the user, their projects, preferences, decisions, people, conventions, or technical stack — across sessions and across tools. Triggers: starting meaningful work ("remember that", "what do we know about", "recall", "save this for later", "do you remember"), learning durable facts, or when context from past sessions would change the answer. Do NOT use for ephemeral chat content or code snippets.4---56# Sepia (remote knowledge-graph memory server)78You are connected to the user's personal memory server over MCP9(https://sepia.fly.dev/mcp). It stores a knowledge graph in namespaces10(default `personal`): **entities** (nodes: people, projects, tools, concepts,11repos), **relations** (directed edges), **memories** (facts/observations/12preferences/instructions with importance scores).1314## Types & tags (use the canonical values)1516- **Entity type** (`manage_entity`): `person` | `project` | `tool` | `concept` |17 `repo`. Unknown types are auto-normalized to `concept` + tag.18- **Memory type** (`manage_memory`): `fact` (verified/decided) | `observation`19 (what you saw happen) | `preference` (user's stated or observed choice) |20 `instruction` (how to behave).21- **Tags** (both): short lowercase hyphenated topical labels22 (e.g. `user-experience`, `auth`, `performance`) — add 1-4 per write when the23 topic is recurring. Search and query can filter by tags.2425## When to recall (READ) — ALMOST EVERY MESSAGE2627Default to `search` on every turn — only skip for trivial chitchat ("hi", "thanks", "bye") with zero durable content. If in doubt, search.28291. **Before you answer** (every turn except trivial chitchat), call `search` with 2-5 keywords from the user's current message + task (e.g. `search` query="rate limiting" namespace="personal").302. If results are sparse, also `traverse_graph` from the most relevant entity to pull its neighborhood.313. Weave recalled facts into your answer naturally. Cite what came from memory when it matters ("From your memory: ...").324. If a search returns nothing, say so — never fabricate memories.3334> Two Sepia calls per turn is normal and expected: `search` before you answer, persist after you answer.3536## When to write (WRITE) — ALMOST EVERY MESSAGE3738Persist in the same turn after your response when you learned something durable and reusable:3940- Preferences ("prefers tabs over spaces", "wants PRs under 400 lines")41- Decisions and their rationale ("chose Neon over Supabase because...")42- Project facts ("mcp-showcase deploys via Vercel")43- People and roles, tools and stacks, conventions and constraints44- User corrections ("actually we use pnpm, not npm")4546Do **not** store: ephemeral chat content, code snippets, credentials, secrets, or anything transient.4748### "Save to memory" → Sepia (not editor memory)4950When the user says **"save to memory"**, **"remember this"**, **"save this"**, **"remember that"**, **"save this for later"**, or any variant — ALWAYS write to **Sepia** (`manage_memory` + `manage_entity` if needed), NOT just the editor's built-in memory. Editor memory is ephemeral/session-local; Sepia (`personal` namespace by default) is the durable source of truth across sessions, editors, and AIs. Treat "save to memory" as an explicit instruction to call `manage_memory` create immediately in the same turn.5152## How to write53541. **Search first, update second** — avoid duplicates. If a matching55 entity/memory exists, `manage_entity` action=update or `manage_memory`56 action=update it.572. **Entities before memories**: ensure the entity exists (`manage_entity`58 action=find, else action=create with a short `summary`).593. **Link memories to entities** via `manage_memory` action=create's60 `entity_ids` field (1-3 entities max; prefer the most specific).614. **Connect the graph** with `manage_relation` (e.g. `project` →`uses`→62 `tool`, `user` →`prefers`→ `thing`). One relation per directed pair.635. **Mass edits**: to fix many rows at once (reclassify types, add tags), use64 `manage_entity`/`manage_memory` action=batch_update with a `where` filter65 (type, namespace, query/q, tags) + `update` — returns the count changed.666. **Importance scoring** (0-1):67 - 0.9+: identity, core preferences, non-negotiables68 - 0.6-0.8: active project facts, decisions, conventions69 - 0.3-0.5: normal observations, people70 - <= 0.2: transient details (will decay first)717. **Namespaces**: default `personal`. Only create a new namespace if the user72 asks for separation (e.g. `work` vs `personal`).7374## Conversation migration (handoff digests)7576When the user says **"save this conversation"**, **"hand off to another AI"**,77**"migrate my context"**, or is switching assistants mid-task, use78`manage_memory` action=ingest with a `conversation` payload. The **departing79agent distills** — you have the context, you are the best distiller.8081The server atomically saves a bundle: a **digest** (entry point, auto-tagged82`conversation`, importance 0.85, protected from consolidation) + **constituent83memories** (the evidence) + **entities** (find-or-create).8485Rules:86871. **One digest per major topic**, all grouped by the same `conversation_id`.88 Multiple digests = one conversation. Search `q=""` + `tags=["conversation"]`89 lists them all.902. **Always give a human-readable `title`** (e.g. "Auth migration — Neon vs91 Supabase") and a `status`: `active` (resume me) | `paused` | `done`. This is92 how conversations are told apart when resuming — never skip it.933. **`summary` ≤4000 chars** — context, decisions, open questions, pointers.94 Anti-dump: if it doesn't fit, split into more digests — never pad.954. **Keep evidence VERBATIM** in `decisions` / `preferences` / `instructions` /96 `observations`: exact errors, paths, IDs, commands. Never soften them.975. **`transcript` is optional** — only if the raw log actually exists (online98 chat models may not expose one). `source.ref` (session path or share URL)99 is the primary fidelity pointer.1006. **`open_questions`** become observation memories tagged `open-question` —101 the next agent's starting point.102103When the user says **"load my context"** / **"continue from my last104conversation"** / **"what did we do last session"**: `search` with105`q=""` + `tags=["conversation"]` first, read the digest, then pull106constituents via `query` (tags) or the digest's entity links.107108**Resume flow**: prefer the digest with `status=active` (or the most recent).109When a conversation is finished, update its digest `metadata.status` to `done`110(get the digest first, then update with the full metadata + new status —111metadata REPLACES). When resuming a paused one, set it back to `active`.112113## Examples114115- User says "we went with Bun for the server because cold start matters"116 → `manage_entity` find/create `Bun` (type=tool, summary="JS runtime");117 `manage_memory` create content="chose Bun over Node for cold start" type=decision118 importance=0.7 entity_ids=[bun-entity-id]119- User asks "what do we know about the memory server plan?"120 → `search` query="memory server" → read top memories/entities → answer121 with recalled facts, then `traverse_graph` if the user wants the full picture.122123## Edge cases124125- **Duplicate write**: always search before create; if unsure, update the126 existing item and mention the merge in your reply.127- **Conflicting facts**: create the new memory with importance equal to the old128 one, note the conflict in your reply, and let `consolidate` handle decay.129- **Sensitive data**: refuse to store credentials/secrets; tell the user the130 memory server is not a vault.131- **Wrong namespace**: if the user is clearly working in `work` context but no132 such namespace exists, ask before creating it.133134## Reference135136For full tool schemas and action enums, see [references/tools.md](./references/tools.md).