Skip to main content
Glama

English · فارسی · 🌐 Live demo · 📦 Release v0.1.1 · 🗒 Changelog

version python deps server llm tests license

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 push

Teammates 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

  1. Session start: the agent is briefed with recent teammate work.

  2. Each prompt: if teammates' notes match it, up to 3 are added to the context (never your own notes).

  3. 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 first

A 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: SessionStart, UserPromptSubmit, Stop, SessionEnd, PreCompact in .claude/settings.json

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

notify hook (user-level ~/.codex/config.toml, via init --codex), rollout read from ~/.codex/sessions

MCP server + AGENTS.md

real CLI 0.164.0 against a mock API: notify captured the real rollout, MCP tool listed

Gemini CLI

ganjineh capture --format gemini (no hooks; best-effort parser)

MCP + GEMINI.md

real CLI 0.65.0: mcp list shows it Connected. Chat-file parser not verified against real files

Cursor

ganjineh note / MCP add_note

.cursor/mcp.json + .cursor/rules

config files only, not run

Copilot (VS Code)

ganjineh note

.vscode/mcp.json + copilot-instructions.md

config files only, not run

any other MCP client

add_note tool

search_memory, read_entry, who_knows_about, recent

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 repo
  • Digest. 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.md is 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 fires notify every turn, so its push is debounced by 45 s.

  • MCP. ganjineh mcp is 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": false in .ganjineh.json to relax): Iranian mobile numbers. Emails are not masked unless you set "mask_email": true.

  • Opt out per session: write #private, ganjineh:off or #نهان in a prompt and that session is skipped entirely.

  • Opt out per file: .ganjinehignore (gitignore-style; the older name .brainignore still 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 --codex edits ~/.codex/config.toml (inside a marked block; uninstall --codex removes 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.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A 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
  • A
    license
    A
    quality
    B
    maintenance
    A 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.
    16
    9 npm
    17
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    A 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.
    5
    3 npm
    MIT