Install
$ agentstack add mcp-jr-mccoy-breadcrumbs ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Breadcrumbs
Breadcrumbs — leave a trail your future self and your agents can follow back.
A portable, repo-local, human-readable ledger of durable project state for human–agent software work (the Project Continuity Memory capability).
> North-star. Project Continuity Memory is a repo-local, human-readable ledger > of durable project state: what was decided, what failed, what is active, what is > risky, what is unresolved, and what the next agent or human must know before > acting. It is not a transcript archive, not a vector database, and not > a replacement for source code, tests, current human instruction, or authoritative > docs.
It stores durable project state as typed, human-readable records inside a target project's .project-memory/ directory, so humans and agents can resume work across sessions, tools, devices, branches, and time without re-discovering decisions, repeating failed attempts, or trusting stale context.
- PyPI package name:
crumb-kit(pip install crumb-kit) - Import package / GitHub repo:
breadcrumbs - CLI binary name:
crumb - Formal capability name: Project Continuity Memory
Non-goals
This tool deliberately does not:
- Build a vector database as the source of truth (vectors are a later, disposable
search accelerator).
- Store full chat transcripts as memory (it extracts durable decisions, attempts,
handoffs, questions, traps, and evidence).
- Rely on one vendor's memory feature (Claude, Codex, Cursor, Gemini, and future
agents all read the same plain records).
- Require MCP, hooks, or a daemon for baseline functionality (plain files + CLI
work first).
- Use
AGENTS.md/CLAUDE.md/ Cursor / Gemini rules as the memory database
(those are signposts only).
- Store secrets, credentials, customer PII, or sensitive local notes in committed
project memory.
- Make capture so heavy that humans stop using it (routine capture targets under
90 seconds).
Install
breadcrumbs is a stdlib-only Python package (no third-party runtime dependencies) that installs a single crumb binary. The recommended path is pipx, which puts the CLI on your PATH in its own isolated environment:
pipx install crumb-kit # from PyPI
pipx install . # from a source checkout (this repo dir)
Plain pip works too (prefer a virtualenv):
python -m pip install . # or: pip install .whl
After install, the binary is on PATH and the .project-memory/ template tree ships inside the package (breadcrumbs/templates/), so init finds it wherever the package lives — there is no repo-relative path dependency:
crumb --version # breadcrumbs X.Y.Z (record schema_version N)
crumb init # locates bundled templates post-install
Versioning. The package uses semantic versioning. crumb --version prints the package version and the record schema_version (the manifest's schema_version: 1). These are independent: the package version moves with the code; the record schema version moves only on a breaking change to the on-disk record format, and a package MAJOR bump accompanies it.
Requires Python ≥ 3.9.
No npx (deliberate)
There is intentionally no npx/Node distribution. The tool is Python and ships via pipx/pip. JavaScript-ecosystem reach (an npx crumb wrapper) is a separately-justified future decision, not a default migration — it would only be added if dogfooding shows a concrete need, and would wrap the same Python core rather than reimplement it.
Quickstart
> Two invocation forms. Once installed (above), run crumb . > From a source checkout without installing, the equivalent is > python crumb.py (a thin shim over breadcrumbs.cli); the > per-command examples below use that source form. They are interchangeable.
crumb init # install .project-memory/ + manifest + .gitignore rules
crumb init --with-adapter --with-mcp --with-hooks # ...and wire it into your agent (see Integrations)
crumb validate # deterministically check the store (schema + invariants)
crumb schema # print the record contract (sections, vocab, rules)
crumb remember decision # capture a durable choice
crumb verify "finding#1" --status fixed # record a verification result (a finding about reality)
crumb mark-status "dec_…" stale --reason "superseded by reality" # record lifecycle mutation
crumb mark-status "trap_…" stale --reason "fixed in 2.1" # ...retire a trap the same way
crumb mark-status "q:…" answered --reason "see dec_…" # ...and answer an open question
crumb note question|trap|idea # leave a note for the next agent (no hand-editing)
crumb capture session # record session end (git-prefilled); updates handoff + current
crumb resume # print a bounded resume packet with computed staleness
crumb reindex # rebuild generated/ projections (mutations reindex automatically)
crumb search "auth middleware" # deterministic keyword/tag/file lookup over records
crumb guard "rewrite the auth middleware" # warn before repeating a known mistake
crumb audit # heuristic health/safety report (stale/unsafe/bloated)
crumb scan-secrets # block if committed memory holds token-like strings
crumb doctor # is memory actually wired into your agent?
crumb mcp serve | register | doctor # run / register / health-check the optional MCP server
In this build, init, validate, remember, capture session, resume, search, guard, audit, and scan-secrets are all implemented — the full MVP (capture → resume → trust). resume closes the capture → resume value loop (MVP-core); guard adds the "don't repeat the expensive mistake" capability that separates a continuity engine from a scrapbook; and audit + scan-secrets complete MVP-trust — the heuristic safety net (secrets, instruction-like text, generated-packet drift, staleness, bloat) that lets you trust the memory, not just use it.
crumb init
python crumb.py init # prompt for session policy (default: full)
python crumb.py init --session-tracking distillate # keep sessions/ local
python crumb.py init --no-commit-generated # keep generated/*.md local
python crumb.py init --project /path/to/repo --json # init elsewhere, JSON summary
python crumb.py init --force # replace an existing scaffold (DELETES all records)
init copies the .project-memory/ template tree into the target project, writes manifest.yml (recording the chosen tracking policies), and inserts a managed block into the project .gitignore. It runs on non-git folders too, printing a notice that git-derived record fields will use defined sentinels.
On a terminal, init also offers to wire the store into your agent (inject a signpost into CLAUDE.md/AGENTS.md, register the MCP server, install hooks). Default non-interactive init touches none of those and prints a one-line nudge. See Integrations below; flags: --with-adapter/--with-mcp/--with-hooks (and --no-*), --print-integrations (dry run), --remove-integrations.
Running init with any integration flag against a project that already has a .project-memory/ store applies just those integrations and leaves the store untouched — no --force needed (and none should be used: --force replaces the scaffold and deletes all existing records).
crumb validate
python crumb.py validate # human-readable report; exit 1 on problems
python crumb.py validate --json # structured findings + exit code
python crumb.py validate --verbose # also list the passing checks
python crumb.py validate --project /path/repo # validate elsewhere
validate is fully deterministic — it checks structural invariants only (manifest version, core files, record frontmatter, filename-canonical identity, status/privacy vocabularies, evidence/handoff/session requirements, generated markers). It performs no heuristic content scanning; secret and instruction-like-text detection live in audit / scan-secrets. Exit codes: 0 clean, 1 problems found, 2 no .project-memory/ store present.
crumb remember decision | attempt
# non-interactive (agent-friendly): title + sections + evidence as flags
python crumb.py remember decision \
--title "Use repo-local Markdown as source of truth" \
--set Context "needed a tool-independent store" \
--set Decision "Markdown + YAML frontmatter" \
--evidence commit abc1234 --evidence command "npm test" \
--tags memory,architecture
python crumb.py remember attempt --title "Tried a sqlite store" \
--set Result "too heavy for the value" --confidence low
Frontmatter is auto-derived (clock + git) and defaulted; you supply only a title and a few section lines (--set HEADING TEXT, repeatable). Run with no --title in a terminal for an interactive prompt. A decision/attempt must carry evidence or --confidence low (validate §16.9) — the command enforces this and refuses to write an invalid record. --json emits a machine summary.
remember attempt also accepts the fixed attempt vocabulary as named flags (--problem, --tried, --result, --why, --do-not-retry, --related), so the contract is visible in --help instead of discoverable only by rejection.
Titles can be as long as you like; filenames can't. The slug in .project-memory//-.md is capped at 60 characters (cut on a word boundary, -2/-3 collision suffixes included in the budget), so a sentence-length title never produces a sentence-length path. That keeps a store clonable on Windows, where the whole path is capped at 260 characters unless core.longpaths is on, and stops long titles from tripping Linux's 255-byte per-name limit. The full text stays in the record's title frontmatter, so nothing is lost. Records already on disk with longer names keep working — the cap applies when a name is generated, never when one is read.
The record's agent frontmatter says who wrote it. Without --agent, the CLI reads the environment (CLAUDECODE, CURSOR_AGENT, CODEX_SANDBOX, …) and records the harness it finds, or unknown when it finds none — it will not claim a human wrote a record just because the flag was missing. Pass --agent human to make that claim explicitly.
crumb verify
python crumb.py verify "perf-audit-2026-05-15#F1" \
--status fixed --method static \
--evidence file app/DoWhatApplication.kt:170 \
--note "DB validation moved to applicationScope.launch(ioDispatcher)"
Records a verification result — "I checked X; here is its state" — the most common agentic output in maintenance, audits, and "is this bug still real?" work. Without a home for it, agents either drop it or mis-file it as a decision/attempt and pollute those categories. --status is the outcome (fixed|open|regressed|not_applicable|inconclusive); --method is static|runtime|test. Like a decision/attempt it needs evidence or --confidence low. Verifications surface in the resume packet's Verifications section (actionable outcomes first) and are searchable with crumb search --type verification --status open (here --status filters on the outcome). Mirrored over MCP as memory_verify.
crumb schema
python crumb.py schema # the full record contract (human)
python crumb.py schema attempt --json # one record type, machine-readable
python crumb.py schema attempt --template # a copy-pasteable `remember` skeleton
schema prints the record contract — body sections per type, required/derived frontmatter, status/privacy/confidence vocabularies, and the evidence-or-low- confidence rule — straight from the source constants, with no .project-memory/ required. --template emits a fill-in command so an agent reads the contract once instead of probing --help repeatedly.
crumb note question | trap | idea
python crumb.py note question "Should age signals gate compliance?" --why "blocks export"
python crumb.py note trap "gradlew --stop corrupts R.jar lock" --area build --safe "kill by pid"
python crumb.py note idea "cache the resume packet" --set Idea "memoize across sessions"
note is the write-surface for the three record kinds that previously had no command: open questions, known traps, and ideas. question/trap append a parse-verified block to open-questions.md / known-traps.md; idea writes a validated record under ideas/. Each refreshes generated/resume-packet.md so the projection never lags the note. Mirrored over MCP as the memory_note tool.
crumb capture session
python crumb.py capture session --next "wire up the resume packet" # git-prefilled
python crumb.py capture session --fast --next "tired — resume here" # ~15s, no prompts
capture session reads git since the last session record and pre-fills Work Completed (git log), Files Touched (a one-line git diff --shortstat summary — N files changed, +X/-Y, not an inlined per-file list, so records stay small and the secret scanner never trips on path-shaped tokens), then asks only for narrative confirmation + a required Next Action. It writes the session record and refreshes handoff.md and current.md. --fast skips all prompts and any LLM, writing a git snapshot + the one-line --next. No path requires an LLM.
The bare form prompts, so it needs a terminal. To run it unattended, supply every section you want on the command line — --next plus --set "" "" for each narrative heading. That keeps the git prefill, unlike --fast, which drops narrative entirely:
crumb capture session --next "wire the parser" \
--set "Decisions Made" "kept the projection rebuild on the write path"
The prefill window is bounded: since..HEAD from the newest session record's commit, or — when that is more than 20 commits back, or there is no prior record — the last 20 commits. Either way the record names the window it used, so a large diff can be read for what it is instead of taken as one sitting's work. With session_tracking: distillate, the session file is written locally but stays gitignored — promote durable items with remember to commit them.
crumb resume
python crumb.py resume # full bounded packet (writes generated/resume-packet.md)
python crumb.py resume --fast # git snapshot + focus + next action + staleness (print-only)
python crumb.py resume --json # structured packet (sections + warnings) for agents
python crumb.py resume --stale-days 14 # tighten the age cutoff (default 21)
python crumb.py resume --task "verify the perf audit" # scope likely-files to matching records (print-only)
resume assembles a bounded, paste-anywhere packet (≤5k tokens) from the canonical records — project/branch/commit, current focus, next action, active decisions (id + one-line rationale), failed attempts to avoid (id + do-not-retry), known traps, open questions, likely files, verifications (recorded results, actionable outcomes first), and verification commands — followed by computed staleness warnings:
- handoff age + commit-distance ("handoff is 6 days old, written 14 commits
behind current HEAD") — the primary "train of thought went cold" signal, carried in --json as handoff_age_days / handoff_commit_distance, separately from the stale_after_days threshold they are compared against;
- aged-unresolved open questions and active decisions older than the
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: jr-mccoy
- Source: jr-mccoy/breadcrumbs
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.