ganjineh
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., "@ganjinehsearch our team notes for anything about the login flow"
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.
English · فارسی · 🌐 Live demo · 📦 Release v0.1.1 · 🗒 Changelog
In one sentence: when you and a teammate each use an AI helper on the same project, the two helpers know nothing about each other. ganjineh is a shared team notebook that your AIs fill in and read by themselves, so one person's AI doesn't redo, or contradict, what another person's AI already did.
Everyday picture: two cooks share one kitchen but never talk. One bakes the bread, the other bakes it again an hour later. Put a notebook on the wall: "bread: done, 3 loaves." Now the second cook looks first. ganjineh is that wall notebook for AI helpers.
It is ganjineh (گنجینه, Persian for "treasury"; pronounced gan-jee-neh). The notebook is just a folder of small text files in a git repo you own (git is the tool most programmers already use to share code). No server, no account, no extra AI bill.
Contents: Why · Install · Quick start · Real output · Per-AI setup · How it works · Privacy · Limits & honesty · Alternatives · Roadmap · Contributing · License
🎯 Why
Say you use an AI helper for coding, and your team does too. One person works on the screens people see (frontend), another on the part behind the scenes (backend). Each person's AI only remembers its own chats. So the frontend AI builds a fake login service that already exists, or suggests storing passwords the way the backend person just decided not to.
ganjineh turns those chats into one shared notebook the whole team's AIs can search:
Automatic. When an AI session ends, a small helper script (a "hook": a program your AI tool runs by itself at set moments) writes a short note. Nobody has to remember. You can still add a note by hand with
ganjineh note.Shared through git. Each session becomes one small file, and only its author writes it, so people never overwrite each other. Your team already uses git, so there is nothing new to set up or pay for.
No extra AI. The notes are made by plain rules, not by another AI. So no extra cost, and your chats are not sent to anyone new.
Secrets are blanked first. Passwords, keys, card numbers and Iranian mobile numbers are replaced with
[REDACTED]before anything is saved. You cannot switch this off for secrets.Understands Persian. Search treats the different ways of typing ی/ک, half-spaces and Persian digits as the same, so «ورود» and "login" both find the right note.
Related MCP server: Engram
📦 Install
Python 3.9+, standard library only. It is not on PyPI yet:
pipx install git+https://github.com/mrzroot/ganjineh # or: pip install git+https://github.com/mrzroot/ganjineh
ganjineh --help🚀 Quick start
Create an empty private repo for the team brain (any git host: GitHub, GitLab, a bare repo on a shared box). Then, once per teammate, inside each project checkout:
ganjineh init --brain git@github.com:your-team/team-brain.git --area backend # --codex also wires Codex (user-level)
git add .ganjineh.json CLAUDE.md AGENTS.md GEMINI.md .github .cursor .mcp.json .gemini .vscode .claude/settings.json
git commit -m "Add ganjineh" && git pushTeammates pull that commit and run ganjineh init --area frontend (their own area; the brain URL is read from .ganjineh.json). That is all: from then on
Session start: the agent is briefed with recent teammate work.
Each prompt: if teammates' notes match it, up to 3 are added to the context (never your own notes).
Session end / compaction: the transcript is digested, scrubbed, committed and pushed in the background.
Everything is also available by hand: ganjineh search "refund screen", ganjineh who server/routes/auth.py, ganjineh recall, ganjineh show <id>, ganjineh doctor, ganjineh uninstall.
🎬 Real output
Produced by examples/demo.py (two teammates, a local bare repo, no network); the full transcript is in docs/demo.txt. Excerpt:
[reza] $ ganjineh search --pull refund screen
[7b88d6deca] 2026-03-02 maryam (claude-code) · backend · Add a refund endpoint for orders. Use POST /api/orders/refund … (score 3.194)
files: server/routes/refunds.py, server/models/refund.py
api: POST /api/orders/refund
decision: We decided to store only the last four digits because PCI scope is out of budget.
[reza] $ ganjineh search ورود login
[d737c50590] 2026-03-02 maryam (claude-code) · backend · ایجاد API ورود با ایمیل و رمز: POST /api/login (score 2.753)
decision: تصمیم گرفتیم توکن JWT را در کوکی httpOnly بگذاریم چون ذخیره در localStorage امن نیست.
sk_live in git history: False | commits: 2 # the fake key in maryam's chat was masked firstA stored entry is plain markdown with a small JSON front-matter, so you can read, grep and review it in a pull request like any file.
🧩 Per-AI setup
What ganjineh init writes, and how far each tool was actually verified (details in docs/VERIFICATION.md):
Tool | Capture (write) | Recall (read) | Verified how |
Claude Code | hooks: | briefing + per-prompt injection + MCP | real CLI 2.1.197 against a mock API: transcript captured, briefing and teammate notes seen in the request body |
Codex |
| MCP server + | real CLI 0.164.0 against a mock API: notify captured the real rollout, MCP tool listed |
Gemini CLI |
| MCP + | real CLI 0.65.0: |
Cursor |
|
| config files only, not run |
Copilot (VS Code) |
|
| config files only, not run |
any other MCP client |
|
| MCP protocol tested over stdio in unit tests |
⚠️ No live model session with a real API key was run. The real CLIs were driven against mock APIs, which proves the plumbing (hooks fire, files are written, text lands in the request) but not how well a real model uses the context.
⚙️ How it works
Claude Code / Codex hook ─▶ parse transcript ─▶ digest (rules) ─▶ scrub ─▶ entries/<project>/<area>/<date>-<author>-<tool>-<id>.md
│ git commit, fetch, rebase, push (retries)
▼
prompt ─▶ BM25 over local markdown (+ who-knows) ◀─ git pull ◀──────────────── your team-brain repoDigest. Heuristics pull out what was asked, the outcome, sentences with decision/gotcha markers (English and Persian), TODOs, touched files, API endpoints and commands. Areas (frontend / backend / infra / docs) come from file globs, overridable in
.ganjineh.json.Storage. One markdown file per session, only its author writes it, so concurrent pushes cannot conflict. Re-capturing a session overwrites its own file.
INDEX.mdis generated locally and gitignored.Search. BM25 with field weights, prefix expansion and Persian normalization. No embeddings, no daemon, no database. On a small corpus BM25 scores are tiny, so the per-prompt hook uses a gate: a score threshold or at least two distinct query terms found in the entry.
Sync. commit, fetch,
rebase origin/<branch>, push, up to 4 retries. Offline is fine: entries stay local and go out on the next sync. Codex firesnotifyevery turn, so its push is debounced by 45 s.MCP.
ganjineh mcpis a stdio JSON-RPC server:search_memory,read_entry,add_note,who_knows_about,recent.
🔒 Privacy and the scrubber
Scrubbing runs on every field before anything is written, so secrets never reach git history.
Always masked: AWS, GitHub, GitLab, Slack, Stripe, Anthropic, OpenAI, Google, npm, SendGrid, Twilio, Telegram tokens, JWTs, private-key blocks,
scheme://user:pass@URLs,Bearer …,password=/secret=-style assignments, long high-entropy blobs, and Luhn-valid card numbers (Latin or Persian digits).PII (on by default,
"pii": falsein.ganjineh.jsonto relax): Iranian mobile numbers. Emails are not masked unless you set"mask_email": true.Opt out per session: write
#private,ganjineh:offor#نهانin a prompt and that session is skipped entirely.Opt out per file:
.ganjinehignore(gitignore-style; the older name.brainignorestill works) removes matching file paths from entries.Your repo, your access control. Use a private brain repo. Entries describe your code and decisions, so treat read access like read access to the code.
The scrubber is pattern-based. It will miss secrets with unusual shapes. Do not rely on it as the only control; see Limits.
⚖️ Limits & honesty
Heuristic digest, not a summarizer. It extracts and quotes; it does not understand. Some notes will be noisy or miss the point. Read an entry with
ganjineh show <id>before trusting it.Search is lexical. BM25 will not match synonyms that share no words. Persian/English mixed queries work only when the entry contains the term.
Scrubbing is best-effort. It will not catch every secret or personal detail, and anything a teammate types is visible to the whole team.
Verification is partial. See the table above and docs/VERIFICATION.md. Not tested: any live model with real keys, Windows, macOS, a real GitHub remote (a local bare repo was used), Cursor and Copilot behavior, Gemini's real chat files.
Codex hooks are user-level, which means
init --codexedits~/.codex/config.toml(inside a marked block;uninstall --codexremoves it). Claude hooks are project-level and committed.Claude Code and Gemini gates: project-scoped MCP servers need your approval in Claude Code; Gemini needs a trusted folder.
No CI yet. The token used to publish this repo had no GitHub Actions (workflow) scope, so there is no
.github/workflows. Run the tests locally:pip install pytest && PYTHONPATH=src pytest tests.Young project (v0.1.1). Expect rough edges and format changes before 1.0.
🔍 Alternatives and where this fits
This is a crowded space and several projects are good. If one of them fits, use it. A non-exhaustive map from a search on 2026-10-25 (details and caveats in NOVELTY.md):
Project | Shape | Difference to ganjineh |
gitmem (dev-boz) | git-synced team memory | the closest; see NOVELTY.md for how the two differ and where it may be better for you |
team-memory (blain3white), ai-memory (akitaonrails) | shared memory for agents | different storage/retrieval choices |
TeamBrain, Krimto, Knowit, CrewMemory, Commonwealth | team/shared memory, various | several are hosted or use a server or an LLM |
claude-mem-sync | syncs claude-mem across machines | builds on a different local store |
iHow Memory, mex | memory / project-context tools | different goal (personal or scaffold context) |
What ganjineh bets on: passive hook capture → LLM-free digest → mandatory scrubber → plain markdown in git → local BM25, in one stdlib-only Python package with Persian handled as a first-class case. If you want embeddings, a web UI, hosted sync or LLM-written summaries, it deliberately does not do that.
🗺️ Roadmap
Verify with live sessions and a real GitHub remote; publish the results.
A real Gemini chat-file parser once the format is confirmed, plus Cursor/Copilot capture.
ganjineh prune/ retention, and a read-only static HTML export of the brain.Optional LLM digest (off by default, bring your own key), only if the scrubber stays in front of it.
PyPI release and CI, once the publishing token allows workflows.
🤝 Contributing
Small, honest PRs are welcome: false-negative secrets for the scrubber, transcript formats for other tools, digest misses. See CONTRIBUTING.md. Please never paste a real secret into an issue.
📄 License
MIT © Mohammadreza Zare. See LICENSE. If it helps your research or team, CITATION.cff has a citation.
This server cannot be deployed
Maintenance
Related MCP Connectors
Markdown-based note-taking with a hosted MCP server. Your notes serve you and your AI.
One memory, every AI. A shared, user-owned markdown memory your AI clients read and write over MCP.
Hosted markdown project wikis your team's AI assistants read, search, and update over MCP.
- WitWikiOAuthapp.witwiki
A shared team wiki your coding agents read and write — across every repo and every MCP client.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceA local MCP server that provides a shared context and learning foundation across multiple AI tools (Claude, Copilot, Codex) for multiple projects, enabling persistent knowledge, decisions, and gap reflection through note storage.MIT
- AlicenseAqualityBmaintenanceA self-hosted MCP server that gives AI agents shared, long-term memory over a git-backed folder of markdown, enabling persistent knowledge search, read, and write without a database.169 npm17MIT
- AlicenseNot gradedqualityBmaintenanceAn MCP server that lets coding agents search, retrieve, and add development notes as plain markdown, capturing and sharing knowledge during live coding sessions.1MIT
- AlicenseAqualityCmaintenanceA stateless MCP server providing persistent, structured project memory for AI coding agents via a markdown folder. It allows agents to record decisions, plans, and notes, which are stored and synced with git.53 npmMIT