locket
Allows ingesting Google Photos Takeout exports to extract photo metadata, faces, and contextual facts from your personal photo library.
Allows ingesting Instagram DM exports to extract conversational data and personal facts from your direct messages.
Allows ingesting WhatsApp chat exports to extract messages, contacts, and personal facts from your conversations.
Click on "Install 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., "@locketWhen did I last see Sarah?"
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.
locket
A privacy-first personal context engine: it ingests your own photo and messaging exports (WhatsApp, Instagram DMs, SMS/MMS backups, Google Photos Takeout, iPhone backups' Messages history), extracts typed, provenance-cited facts about your life with an LLM pipeline, resolves the people and places those facts mention into stable entities, stores everything in Postgres+pgvector, and serves the resulting profile to other tools over MCP (Model Context Protocol) — so you can ask Claude Code or Claude Desktop things like "when did I last see Sarah?" and get an answer that cites the exact message it came from.
Architecture
flowchart LR
Sources["Your exports\n(WhatsApp/Instagram/SMS/Photos)"] --> Adapters["adapters/\npure parsers"]
Adapters --> RawItems[(RawItem stream)]
RawItems -- photos --> Vision["vision/\nSigLIP2 + RapidOCR + InsightFace\n(local, 100% of photos)"]
Vision -- curated subset --> VisionLLM["local Ollama qwen3-vl:8b\n(curated tail only)"]
RawItems --> Windowing["extraction/chunking.py"]
Windowing --> Extraction["extraction/graph.py\nLangGraph: Claude API\nstructured outputs"]
Extraction --> Resolution["resolution.py\ntiered entity resolution\n+ human confirm queue"]
Resolution --> Store[(Postgres + pgvector)]
Store --> Profile["profile.py\nsynthesized, cited profile"]
Profile --> Store
Store --> MCP["mcp_server.py\nsix tools, stdio"]
MCP --> Client["Claude Code /\nClaude Desktop"]Full stage-by-stage breakdown, module boundaries, and the dual-corpus design:
docs/architecture.md. 90-second walkthrough with
scripted questions and MCP registration commands:
docs/demo.md.
Related MCP server: Memex
Quickstart (against the committed synthetic demo corpus)
docker compose up -d db # Postgres + pgvector
uv sync # hand-edit pyproject.toml + `uv sync` to add deps — no `uv add`
uv run python -m locket.cli ingest demo_corpus/whatsapp/team.txt
uv run python -m locket.cli ingest demo_corpus/sms/backup.xml
uv run python -m locket.cli ingest demo_corpus/photos
# No ANTHROPIC_API_KEY needed — with no key set, extraction/resolution/
# profile all run against a local Ollama model by default (see "Running
# fully local" below). --skip-vision bypasses the local vision pre-pass +
# Ollama vision-LLM tail (~135s/image measured — see evals/BASELINE.md —
# worth skipping for a quick pass).
uv run python -m locket.cli pipeline run --skip-vision --corpus-dir demo_corpus
uv run python -m locket.cli profile build
claude mcp add --scope user locket -- uv run --directory "$(pwd)" python -m locket.mcp_serverFull command reference (every subcommand: ingest,
pipeline run [--skip-vision/--cap/--corpus-dir/--retry-failed],
pipeline retry-given-up, label-faces, resolve, eval extraction|rag,
profile build, stats [--json], serve, serve-ui [--host/--port])
and the exact Claude Desktop registration JSON block:
docs/demo.md.
To run against your own data instead of the demo corpus, set
LOCKET_CORPUS_DIR in a local .env (never inside this repo — see
.env.example) and point ingest / pipeline run --corpus-dir at it.
Running fully local (no API key)
Every LLM call locket makes — extraction, entity resolution, profile
rendering, and the MCP server's answer_question — goes through one
backend-selection seam, locket.llm.get_chat_model. It picks between two
backends:
anthropic(ChatAnthropic, real network calls to Claude, higher quality, costs money): used automatically whenANTHROPIC_API_KEYis set, or when you force it withLOCKET_LLM_BACKEND=anthropic.ollama(ChatOllama, a local Ollama server, free, no data leaves your machine): the default when no API key is present.locket pipeline runno longer refuses to run keylessly — it just uses this backend instead.
Requirements: an Ollama server running locally (ollama serve, or the
desktop app) with the text model pulled — ollama pull gemma3:12b (the
default, ~8GB) or set LOCKET_LOCAL_MODEL=qwen2.5:3b-instruct for a
smaller, already-common model. OLLAMA_HOST is respected if you want to
point at a different machine's Ollama (e.g. over Tailscale) instead of
localhost:11434 — locket does not read or override it itself.
Honest quality/speed tradeoff, measured on this project's dev machine
(CPU-only Ollama): the local backend is markedly slower and somewhat
lower-quality than the Claude API backend. gemma3:12b took roughly 10-130s
per extraction window (vs. sub-second-to-a-few-seconds for claude-haiku-4-5)
and produced fewer, though more information-dense, facts per window than a
smaller local model (qwen2.5:3b-instruct, ~10x faster but noisier — see
src/locket/llm.py's module docstring for the side-by-side). Vision
(qwen3-vl:8b) already ran local-only regardless of this setting, at its own
separately-measured ~135s/image. Full real pipeline-run numbers (fact
counts, wall time) for the local backend are in evals/BASELINE.md's
"local backend (informal)" section — the official baseline stays the
Claude API run, pending a real key.
Privacy posture
Stated plainly, not hand-waved:
Storage is fully local. Postgres+pgvector runs in your own Docker container. Nothing about your facts, entities, or profile is sent anywhere except the specific API calls described below. The container's port binds to
127.0.0.1only (seedocker-compose.yml) — never reachable from another device on your LAN.Text extraction uses the Claude API. Message/photo-OCR text is sent to Anthropic under their no-training API terms to extract structured facts (
claude-haiku-4-5, escalating toclaude-sonnet-5on repeated validation failures) and to render profile prose and answer questions. This is a real network call to a third party — disclosed honestly, not claimed as "fully private."Real photos are processed by local models only. EXIF/GPS, SigLIP2 zero-shot tagging, RapidOCR, and InsightFace face clustering all run locally on 100% of your photo library, for free. The one open-ended "describe this photo" step (the vision-LLM tail) runs against a small, curated subset using local Ollama
qwen3-vl:8b— never a cloud vision model, for real photos.Gemini's free tier is explicitly forbidden for real photos. Google's free-tier terms grant Google the right to train on and have humans review submitted content — unacceptable for private photos of your life. Using Gemini as an opt-in path for generating the synthetic demo corpus (where no privacy stakes exist — the faces are AI-generated, MIT-licensed SFHQ portraits, and every conversation is invented) is planned, not yet implemented — no code path calls it today. A paid Claude-API fallback for real photos behind an explicit
--cloud-okflag, for when local Ollama is unavailable, is likewise planned and not yet implemented — still Anthropic's no-training terms, never Gemini free tier, once it exists.Your real exports never enter this repository. They're read from
LOCKET_CORPUS_DIR, an env var pointing outside the repo, declared in a local, gitignored.env..gitignorealso blocksreal_corpus/and*.local.*(the pattern the real self-labeled eval gold set uses:evals/gold/real_gold.local.yaml). Everything underdemo_corpus/in this repo is synthetic — five invented personas, generated conversations, and staged photos of AI-generated faces — used for every test, CI run, and the public demo. No real data of any kind ships in this repository.
Eval results
locket ships two eval suites (evals/extraction_eval.py,
evals/rag_eval.py), both runnable via locket eval extraction|rag --json
and both gated in CI (.github/workflows/eval.yml, nightly + on-demand —
kept out of the free push/PR lint+test workflow since they cost real money
per run). Full methodology, every number's provenance, and the exact
commands to reproduce or extend each measurement: evals/BASELINE.md.
Metric | Value | Status |
Vision-LLM tail latency ( | ~135s/image mean (range 86–205s, n=6) | Measured live, Task 13 |
Entity-resolution similarity floor ( | Same-person variants 0.57–0.90 cosine; different-person 0.42–0.47 | Measured live, Task 14 |
Extraction P/R/F1 vs. the 60-fact synthetic gold set | — | Pending |
Ragas faithfulness / answer-relevancy / context-precision (25 questions) | — | Pending |
Real-corpus self-labeled gold set (100–200 facts, spec §4.1) | — | Noah-gated — needs his real exports + the API key, off-repo by design ( |
No number above is invented — where a measurement is blocked on a still-absent API key, the table says so plainly instead of filling in a plausible-looking placeholder.
License
MIT (LICENSE). Third-party model weights and assets carry their own,
narrower terms — see THIRD_PARTY_NOTICES.md before distributing or
monetizing anything built on this repo (notably: InsightFace's buffalo_l
face-analysis weights are non-commercial/research-personal use only, even
though the InsightFace code itself is MIT).
See Claude/specs/2026-07-30-locket-design.md (private planning vault, not
part of this repo) for the full design writeup.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityCmaintenancePrivacy-first personal knowledge database for your AI that ingests data exports (Google Takeout first) and exposes them via MCP tools like search and list items. Runs locally with no cloud or telemetry.Last updatedMIT
- FlicenseAqualityCmaintenanceA local-first, privacy-first MCP server that passively indexes personal digital activity (screenshots, clipboard, notes, downloads, links) into a local database, enabling LLMs like Claude to access your context without cloud storage.Last updated4
- Alicense-qualityBmaintenanceThe personal context layer for AI - one user owned profile plus files, read by any MCP client so you never re-introduce yourself.Last updated1MIT
- Alicense-qualityCmaintenanceA local-first file intelligence engine that indexes documents, code, and email on your machine using on-device models, and exposes that memory to any AI assistant over MCP for semantic search and structured fact retrieval.Last updated9Business Source 1.1
Related MCP Connectors
The personal context layer for AI: your profile and files, read by any MCP client over OAuth.
Private-by-default, local-first memory/context/task orchestrator for MCP apps and agents.
User-owned memory for AI agents, Copilot, Claude, IDEs, CLIs, and chat apps over remote MCP.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/noahejung/locket'
If you have feedback or need assistance with the MCP directory API, please join our Discord server