Ask your teammates when they're not around.
Every engineer on a team carries context nobody wrote down — why the retry lives in the worker, what was tried before Redis, which idea died in review and why. MindSync gives each person a mind built from their own approved words. Teammates can question it from the web or from inside Claude Code. It answers in their voice, cites where the answer came from, and says "I don't know" instead of guessing.
Live app · Install the plugin · How it works · Design decisions
Two minds asked the same question. One answers with citations to the PRs it came from; the other has no approved material and declines rather than guessing, offering to send the question to the real person. Sample data.
Claude Code sessions ─┐
├─→ ingestion ─→ approval queue ─→ per-person store ─→ mind agent ─┬─→ Claude Code plugin
GitHub PRs & reviews ─┘ (split, (you keep (Azure AI Search, (retrieve, └─→ web app
scan, tag, or discard) tagged chunks) weigh,
embed) answer or refuse)
Sources. Merged PR bodies, review comments, and commit messages come from a GitHub App — material that already passed a human's eyes. Claude Code sessions add voice: how someone actually writes, captured by a hook.
Ingestion is a queue-triggered pipeline: split human turns from assistant text, scan for secrets, drop junk, chunk, tag with a trust level, embed. Nothing goes straight to the store.
The approval queue is the consent surface. Every chunk waits there until its owner keeps or discards it. Nobody — not even a team owner — approves material into someone else's mind.
The queue, grouped by repo and keyboard-driven. The item at the top was quarantined by the secret scanner — it can only enter the queue redacted. Sample data.
The mind agent runs hybrid search (BM25 + vector) over that person's approved chunks
only, weighs each hit by trust tag × freshness × relevance, and compares the result to a
per-person refusal threshold. Above it, one model call writes an answer in their voice
with numbered citations. Below it, the mind declines and offers to ask the real person —
whose reply becomes authored material, so the mind can answer it forever after.
This is the Claude Code plugin — the client half, MIT licensed and installable today.
plugin/
├── index.js MCP server: 4 tools, zero runtime dependencies
├── lib/
│ ├── mcp.js JSON-RPC over stdio, written from scratch
│ ├── splitter.js keeps your turns, discards Claude's — the safety-critical file
│ ├── pasted.js drops what you pasted but didn't write
│ ├── secrets.js scrubs credential-shaped text before upload
│ └── capture.js incremental session capture with content-hash watermarks
├── hooks/ Stop + SessionEnd capture hooks
├── skills/ the "consult your colleagues" skill
└── test/ 49 tests, including the one that gates every splitter change
The backend is a private repo — Azure Functions API + queue worker + Bicep infra, 176 tests total. Happy to walk through it in an interview: the ingestion pipeline, trust-weighted retrieval, and the nightly reconciliation job are the parts I'd want to talk about.
Stack: Azure Functions · Cosmos DB · Azure AI Search (hybrid + vector) · Azure OpenAI · Static Web Apps · Key Vault · Bicep · TypeScript · GitHub Apps + webhooks · MCP
/plugin marketplace add atillacanuslu/mindsync-plugin
/plugin install mindsync@mindsync
Then get a token — sign in at the web app, open Profile, click Generate token — and save it:
echo '{"apiKey": "cak_..."}' > ~/.claude/mindsync.json && chmod 600 ~/.claude/mindsync.jsonNo npm install, no restart: the plugin has zero runtime dependencies and reads the
token per call. Verify with /mcp (four tools) and /context (the skill).
Other ways to configure it
An env var works too (export MINDSYNC_API_KEY=cak_...), but needs a Claude Code
restart since the environment is captured at launch. Self-hosting? Add "apiUrl" to the
config file, or set MINDSYNC_API_URL. Configs under the product's former name
(~/.claude/colleague.json, COLLEAGUE_API_KEY) are still read, so existing setups keep
working.
Four MCP tools. ask_mind answers in a teammate's voice with citations, or declines.
get_file_authors and who_knows_about are direct reads — a database query, no model,
~0.4s — so Claude can check ownership without a noticeable pause. escalate_question
sends what a mind couldn't answer to the real person.
A skill. Before substantially changing code someone else wrote, Claude checks authorship and consults their mind, reporting it as "their mind says…" — never as the person. It stays quiet for trivial edits and your own files.
Session capture. Two hooks upload your turns as you work, so your mind learns how you actually talk.
The interesting problems here weren't the plumbing.
Half a mind turned out to be Claude's writing. An audit found ~50% of one person's
indexed chunks were assistant-drafted commit messages. That is the failure that kills the
product — every mind converges on the same voice. The fix was a new assisted trust tier:
the material stays as evidence (you endorsed it by committing it) but is barred from
voice examples entirely. The downweight is a nicety; the voice exclusion is load-bearing.
A semantic reranker made retrieval worse, and the reason generalizes. Azure's reranker is a language model, so it rewards text that reads like a well-formed document — which in this corpus meant assistant-drafted commits, promoted above where trust weighting could reach them. Terse human commits ("Attempt for Firestore Failed, moving on") lost every time. Measured on 10 real questions, then rejected.
Supersession had to be tuned far past "balanced." A nightly job marks old chunks contradicted by newer ones. Its first run marked three pairs, all wrong in the same way: the newer material moved past the older rather than falsifying it. The asymmetry is the whole design rule — a missed supersession costs almost nothing (the agent already discloses conflicting evidence), while a false one silently deletes someone's words from their own mind. So the judge must now say yes twice, independently, and is asked whether the older text's main point is false, not whether any sentence in it is.
"Only your words leave your machine" is a test, not a promise. The splitter is an
allowlist — only entries provably typed by the human survive — and a gating test plants
markers in assistant text, thinking blocks, tool output, subagent prompts, and
post-compaction summaries, then asserts zero survive. The last two were real leaks found
in review: both wear the user role in the transcript while carrying Claude's words.
Retrieval is scoped to the repo you're in. Measurement first: sitting in one repo,
"how do you store embeddings?" returned 0 of 12 chunks from that repo — a
confident, correctly-cited answer about an entirely different system. But a hard filter
was wrong too, since some questions genuinely belong to another repo. It's now repo-first
with a fallback that must disclose it ("I'm drawing on other-repo here").
The whole product rests on one promise, so it's enforced in code and gated by tests.
| Guarantee | How |
|---|---|
| Claude's words never leave your machine | Allowlist splitter (lib/splitter.js) + a test that asserts zero assistant text survives |
| Only your prose, not what you pasted | lib/pasted.js drops terminal dumps, docs, and assistant replies handed back for editing |
| Secrets never travel | Scrubbed client-side before upload (lib/secrets.js), scanned again server-side, quarantined before embedding |
| Only your team's repos | Capture checks the repo against your teams' allow-list and fails closed if it can't |
| You can audit what left | Every upload is appended to ~/.claude/mindsync-uploads.log |
| You can turn it off | MINDSYNC_DISABLED=1 |
| Nothing enters a mind unapproved | Everything lands in your approval queue first |
npm install # dev only — vitest; the plugin itself has zero runtime deps
npm test # 49 tests, including THE SPLITTER TESTMIT licensed. Built by @atillacanuslu.


