memory-wiki
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@memory-wikiRemember that I prefer dark mode for coding."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Personal Memory Wiki
A persistent personal memory system for Claude, exposed as an MCP server. It accumulates, organizes, and surfaces a single user's knowledge over time. All data is plain Markdown in a git repo: no database, no embeddings, no RAG. Git history is the audit log and the undo button.
The idea: while you talk to Claude, it captures notes into a fast "short-term" layer. A nightly dream then distils those captures into curated long-term pages, the same way memory consolidates during sleep. You can read and edit everything through a private web console.
It is a standalone Python service: a Docker image, an HTTP MCP endpoint, and a
named volume holding the wiki. The code is path-agnostic via the WIKI_ROOT
environment variable, so it runs the same locally or on any host behind a
TLS-terminating reverse proxy.
MCP tools (what Claude calls)
A deliberately small surface (a small surface is easier for the model to use correctly):
prime()- call FIRST: loads the grounding context (theself/pages, then the long-term and short-term indexes) in one call.read(path)- read any file: a page, an index, or a short-term entry. Tolerant of paths and suggests alternatives on a miss.search(query_text, max_results?)- full-text search, returningpath:line: textmatches.remember(content, summary?, tags?, due?, type?)- capture into short-term memory;due/typefile dated items (todo, reminder, event) intotemporal/.GET /health- liveness probe for the Docker healthcheck (public, not a tool).
Writing to long-term memory is intentionally not an MCP tool. It happens
through the web console or the nightly dream, never from a live conversation.
This keeps structural edits deliberate. All tools honour the owner allow-list
and a path guard, so long_term/private/ is never read or searched.
Related MCP server: claude-memory
How memory is organized
short-term (
short_term/): the open, fast-to-write layer. Everyrememberappends an entry here.long-term (
long_term/): curated pages, including aself/section (identity, grounding) and aprivate/section never exposed over MCP.temporal (
temporal/): dated, transient items (todo / reminder / event) that live until their due date, then are archived. A durable fact with no expiry belongs on a long-term page instead.index: each layer has a one-line-per-page index, regenerated by code so it cannot drift from the contents.
The dream (nightly consolidation)
The dream reads short-term memory plus a policy file (DREAM.md, editable in the
console) and decides how to fold captures into long-term pages. It runs as a
three-stage pipeline so no single call ever needs the whole memory (cost
scales with the number of captures, not the wiki size):
triage - cluster and route each capture;
decide - per unit, reading only the touched pages, choose the action;
write - produce each page's final content and its index line.
It has two modes, set from the console (/ui/dream):
dry-run - stops after stage 2 and writes a report to
dream_reports/, changing nothing.execute - runs stage 3 and applies everything in one revertible git commit (writes pages, files temporal items, drops consumed short-term entries, expires past-due items). It never deletes long-term content.
A built-in scheduler thread can run the dream once a night (off /
dry-run / execute, stored in dream_schedule.json). "Once a day" is enforced
by the presence of the day's report, so restarts never double-run and a missed
night is caught up. The model is WIKI_DREAM_MODEL (defaults to Opus,
overridable per stage via _TRIAGE / _DECIDE / _WRITE) and needs
ANTHROPIC_API_KEY. The three stage prompts are editable files
(prompts/{triage,decide,write}.md) viewable at /ui/prompts; the JSON schema
is injected by code, so editing the guidance cannot break the contract.
Web console (/ui)
A private, browser-facing console served by the same process:
/ui- lists every markdown file under the wiki (the structure)./ui/page/{path}- view a page rendered from markdown./ui/edit?path=...- edit a page (or create one when path is empty).POST /ui/save,POST /ui/delete- write or soft-delete, committed with amanual:prefix (soft-delete keeps history)./ui/dream,/ui/prompts- run/schedule the dream and edit its prompts.
Markdown is rendered with raw HTML disabled, so stored content cannot inject markup. Forms carry a signed CSRF token.
Authentication: GitHub OAuth + owner allow-list
The server uses FastMCP's GitHubProvider (an OAuth proxy running the OAuth 2.1
PKCE flow Claude.ai expects). On top of "any valid GitHub login", an allow-list middleware restricts access to a single account (
WIKI_ALLOWED_GITHUB_LOGIN), so the wiki stays private to its owner. The browser console uses the same OAuth app.
Configuration (environment variables)
Variable | Required | Purpose |
| yes (prod) | GitHub OAuth; the server refuses to start without them unless auth is disabled |
| prod | the public base URL of the server, e.g. |
| yes (prod) | the single GitHub login allowed to use the wiki |
| recommended | stable random value so tokens survive restarts |
| for the dream | the model calls in the consolidation pipeline |
| no | dream model overrides |
| no | where the wiki lives (default |
| dev only | run open, no secrets needed |
Provide these through your deployment's environment (a .env file, container
secrets, an orchestrator, etc.). They are configuration, not committed to the
repo.
GitHub OAuth app setup (one time)
Create a GitHub OAuth App (Settings -> Developer settings -> OAuth Apps) with:
Homepage URL:
https://YOUR_DOMAINAuthorization callback URL:
https://YOUR_DOMAIN/(GitHub accepts any subpath, so both/auth/callbackfor Claude and/ui/auth/callbackfor the console work). Secret names must not start withGITHUB_, which GitHub reserves.
Architecture
Transport: Streamable HTTP, MCP mounted at
/mcp, listening on:8765.Data: the wiki lives under
WIKI_ROOT(default/srv/wiki), intended to be a persistent volume. The entrypoint seeds it fromseed/only if empty, thengit inits it, so restarts never clobber data.Public URL:
https://YOUR_DOMAIN/mcp, behind a reverse proxy that terminates TLS (Caddy, nginx, Traefik, etc.).
memory-wiki/
Dockerfile
docker-entrypoint.sh # seed-if-empty + git init, then run the server
pyproject.toml
src/wiki_server/
server.py # FastMCP app: tools + /health
store.py, query.py # read / search / write over the markdown tree
paths.py # path validation under WIKI_ROOT, refuses private/
temporal.py # dated items
dream/ # the staged consolidation pipeline + scheduler
ui.py, prompts.py # web console and editable dream prompts
seed/ # initial wiki content, copied into the volume once
tests/Run locally
The fast way, with auth disabled (no OAuth needed; the dream needs an Anthropic key, but the read/write tools do not):
docker build -t memory-wiki .
docker run --rm -p 8765:8765 \
-e WIKI_AUTH_DISABLED=1 \
-v "$PWD/.localwiki:/srv/wiki" \
memory-wikiThen:
curl -s localhost:8765/health # -> {"ok": true}
npx @modelcontextprotocol/inspector
# connect to: http://localhost:8765/mcp
# call prime(), then read("self/identity.md")The local volume is seeded from seed/ on first run, so you get a working wiki
to poke at.
Tests
The logic (store, temporal items, the dream pipeline, path guard, prime) is covered by a fast pytest suite that runs against a throwaway wiki, with git commits and model calls stubbed. No API key or network needed. Runs in CI on every push.
pip install pytest # or: pip install -e ".[dev]"
pytest -qDeployment
The image is built from the included Dockerfile. A GitHub Actions workflow
(.github/workflows/ci.yml) runs the tests and, on main, builds and pushes
the image to GHCR. From there, deploy the container however you like: any Docker
host works, as long as the MCP endpoint sits behind a reverse proxy that
terminates HTTPS at your public URL and the env vars above are supplied.
Two things to remember in production:
mount a persistent volume at
WIKI_ROOTso the wiki survives restarts;point a DNS record for your domain at the host, and let the reverse proxy handle the certificate.
Connect Claude.ai
In Claude.ai: Settings -> Connectors -> Add custom connector.
URL:
https://YOUR_DOMAIN/mcp.Claude redirects you to GitHub to log in and consent. Only the allow-listed GitHub account can use the tools.
Ask Claude to call
prime(), thenread("self/identity.md").
Roadmap
Built so far: OAuth, remember() plus the lean read/search tools, temporal
items, the web console, and the staged dream (dry-run, execute, editable
prompts, per-stage model, automatic nightly schedule).
Still open: a weekly digest (a periodic summary of what changed and what is coming up). Optional later: notifications, and a "reorg" dream to fold residual duplicate pages.
This server cannot be deployed
Maintenance
Related MCP Connectors
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
- TaprootOAuthcom.taproothq
Persistent memory layer for AI tools. Save and recall notes across Claude and other MCP clients.
Persistent memory for Claude Code and Cursor. Stop re-explaining your project every session.
Persistent memory for AI agents across Claude, ChatGPT and any MCP client.
Related MCP Servers
- AlicenseAqualityDmaintenancePersistent memory and automatic git snapshots for Claude Code, capturing decisions, patterns, and architecture across sessions.1037 npm98MIT
- AlicenseNot gradedqualityDmaintenanceCross-machine memory system for Claude Code that records sessions as searchable markdown, syncs across machines via Git, and exposes full-text search, semantic search, session summarization, and a knowledge graph through an MCP server.5 npmMIT
- AlicenseNot gradedqualityBmaintenanceA self-hosted memory layer for Claude using plain markdown files, enabling persistent context across different Claude accounts.5 npmMIT
- AlicenseAqualityCmaintenanceA git-backed per-repo memory layer for Claude Code, enabling persistent, version-controlled storage and retrieval of memories to build a self-evolving skill.4MIT