Mycel manual
Everything you need to run Mycel, write in it, and let your AI maintain it. Five minutes to deploy, one page to learn.
Getting started
You need Docker (for Postgres + pgvector) and uv. Then:
git clone <your-fork> mycel && cd mycel
cp .env.example .env # or edit the provided .env
docker compose up -d # Postgres 17 + pgvector on :5442
uv sync
uv run python manage.py migrate
uv run python manage.py init_kb # seeds the KB Schema note
uv run uvicorn config.asgi:application --port 8000
Open http://127.0.0.1:8000/app/. The root / is
the public landing page; the app lives under /app/.
- Everything self-hosted: your Postgres, your markdown, your keys. Nothing leaves the machine unless you enable it.
- One process: uvicorn serves the app (HTTP + websocket) and the MCP endpoint together.
The home screen
The app home (/app/) is a single prompt over your living
knowledge graph — every dot is a real note, drifting. Hover a node to see
its title; click to open it.
- Type — instant search over your vault. Exact matches and semantic neighbors, fused into one list.
- Enter — ask mycel. AI answers the question from your notes, with numbered citations that link to the sources (see Ask mode).
- + — new note. If a search finds nothing, you can turn the query itself into a note title with one click.
Writing notes
Notes are block documents, Notion-style. Click the title to rename —
every [[wikilink]] pointing at the old title is rewritten for
you, so the graph never shatters.
Keyboard
| Keys | Action |
|---|---|
| Enter | Split the block at the caret (new block below) |
| Shift+Enter | Line break inside the block |
| Backspace (at start) | Merge into the previous block |
| / | Block type menu — Text · Heading · List · Code · Quote |
| Alt+↑ / Alt+↓ | Move the block up / down |
| ↑ / ↓ (at edges) | Walk into the previous / next block |
| ⋮⋮ drag | Reorder by dragging the handle |
Links and ghosts
Wrap any concept in double brackets — [[Solo founder
economics]] — to link it. The target doesn't have to exist:
unwritten references appear on the graph as dashed ghost nodes,
a running list of pages worth creating. The moment you create a note with
that title, every ghost link snaps onto it.
Conflicts
If an agent (or another window) changes a block you're editing, you get an inline conflict card showing both versions — keep yours or theirs. No silent overwrites, ever.
The graph
- On every note — a local neighborhood graph (2 hops) plus a backlinks panel. The amber node is the note you're on.
- Full graph —
/graph/shows the whole vault, Obsidian-style: every live note, every link, ghosts dashed. Drag nodes, hover to highlight a neighborhood, click to open.
Connect your AI (MCP)
Mycel is agent-native: anything you can do in the UI, an agent can do over MCP — through the same write path, so every agent edit is attributed, versioned, and revertible.
The endpoint is http://127.0.0.1:8000/mcp (streamable
HTTP). For Claude Code:
claude mcp add --transport http mycel http://127.0.0.1:8000/mcp
Exposed to the network? Set MYCEL_SHARED_TOKEN and send it
as Authorization: Bearer <token>.
Note kinds
| kind | Meaning |
|---|---|
| wiki | LLM-owned synthesis pages (default). Agents create, edit, reorganize freely. |
| raw | Immutable sources (articles, transcripts). The server rejects agent writes — synthesis goes in wiki notes that cite the raw. |
| schema | The KB Schema note itself. |
Tools
| Tool | What it does |
|---|---|
| search | Hybrid keyword + semantic search |
| read_note | Full markdown, or mode="outline" for cheap orientation |
| list_notes | Catalog of every note — the vault's index |
| related_notes | Semantic neighbors — where new info should integrate |
| list_backlinks | Notes linking to a note |
| ingest | Store a source as immutable raw + get an integration checklist |
| lint_kb | Health check: orphans, ghosts, stale-but-cited, near-duplicate pairs |
| create_note / append_blocks / update_block / move_block / delete_block(s) / update_note_meta | Writes — same single write path as the UI |
| list_recent_changes / get_change_group_status / revert_change_group | History and undo |
The maintenance loop
- Ingest — new source → raw note → integrate key claims into related wiki notes → create pages for new concepts.
- Query — answer from the vault, then file valuable answers back as wiki notes so knowledge compounds.
- Lint — run
lint_kbperiodically; link orphans, write ghost pages, resolve contradictions, merge duplicates.
Ask mode
Press Enter on the home prompt and mycel answers from your notes, never from thin air:
- With an Anthropic key — Claude synthesizes an answer strictly from the retrieved notes, with [n] citations linking back.
- Without a key — you still get an extractive digest of the strongest passages. Same citations, no LLM required.
# .env
ANTHROPIC_API_KEY=sk-ant-...
MYCEL_ASK_MODEL=claude-sonnet-5 # optional
If the LLM call ever fails, Ask degrades to the digest — the home screen never hard-fails.
History & safety
- Append-only history. Every change is snapshotted and
grouped; any group can be reverted from
/changes/(partial conflicts are reported, not forced). - Bulk-destructive gate. An agent deleting more than 10 blocks needs your approval first — pending requests appear in the changes feed.
- Optimistic concurrency. Stale writes return a conflict (to agents: a structured payload; to you: the inline card), never a silent overwrite.
- Raw immutability.
kind: rawnotes reject agent writes at the server.
Import from Obsidian
uv run python manage.py import_vault --path ~/vault
- Frontmatter and
[[wikilinks]]are preserved; links resolve (or become ghosts) automatically. - Skip-and-flag: files that can't import are listed with reasons, the rest proceed.
- The whole import is one change group — revert it in one click if it wasn't what you wanted.
Configuration
Everything is an environment variable (read from .env):
| Variable | Default | Purpose |
|---|---|---|
| DB_NAME / DB_USER / DB_PASSWORD / DB_HOST / DB_PORT | pgvec · 127.0.0.1 · 5442 | Postgres connection (docker-compose maps 5442) |
| MYCEL_SHARED_TOKEN | (empty) | Bearer token gate for
/mcp. Empty = localhost-only trust. |
| ANTHROPIC_API_KEY | (empty) | Enables synthesized Ask answers; empty = extractive digest. |
| MYCEL_ASK_MODEL | claude-sonnet-5 | Model used for Ask. |
| MYCEL_EMBEDDER | (built-in) | Dotted path to a real embedding model (e.g. BGE-M3). Default is a deterministic hashing embedder — swap it for true semantic recall. |
| MYCEL_VECTOR_MAX_DIST | 0.75 | Relevance floor for the vector arm of search. |
| MYCEL_INLINE_EMBED | true | Embed small backlogs inline so semantic search works without a worker. |
| MYCEL_IDLE_MERGE_SECONDS | 300 | Idle window that merges consecutive edits into one history group. |
| MYCEL_BULK_THRESHOLD | 10 | Deletes above this count require owner approval. |
The markdown contract
Your data is markdown, round-trippable by design:
- Every block exports with an Obsidian-compatible
^anchor; the stored content itself is anchor-free, so editors and agents never see (or corrupt) identity. - Exports carry a
pgvec_basefrontmatter stamp. Re-importing an edited export updates matched blocks, creates new ones, soft-deletes missing ones — and reports a conflict if the note changed underneath. - Export → edit anywhere → re-import is a supported loop, not a hack.