Local MCP server for recording and querying the reasoning, outcomes, and history behind AI-generated code changes.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent โ or use 1-click editor setup below.
We haven't yet run this listing's install command through our automated sandbox check. This isn't a red flag โ we're steadily working through the catalog.
๐ก Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Inspect callable tools, capabilities, and parameters exposed to AI agents by Selvedge.
log_changeRecord a change event with entity, diff, and reasoning. `rename_from` + `change_type="rename"` records the dual-event rename pattern; `change_type="supersede"` re-opens a reverted decision (append-only); optional `constraint` / `stale_when` keep the decision's principle and its invalidation conditiโฆ
diffHistory for an entity or entity prefix, each row annotated with `superseded_by
blameMost recent change + context for an exact entity, plus the derived decision `status` (active / reverted / reopened)
historyFiltered history across all entities
changesetAll events grouped under a named feature/task slug
searchFull-text search across all events
selvedge.sh ย ยทย PyPI ย ยทย GitHub
Long-term memory for AI-coded codebases โ including what was already tried and rejected.
Line attribution tells you who wrote something. Selvedge tells your agent
what not to write next: the approaches this codebase already tried,
reverted, and why. It's a git blame for AI agents, for the why rather
than which model touched which line โ captured live, by the agent, as the
change happens, so nothing downstream has to guess at it.
Selvedge is a local MCP server. AI coding agents (Claude Code, Cursor,
Copilot) call it as they work to log structured change events with
reasoning. Your data stays in a SQLite file under .selvedge/ next to
your code.
Local-first by default, team-server by choice, zero-LLM always.
Six months ago, your AI agent added a column called user_tier_v2. You don't
know why. git blame points to a commit from claude-code with a generated
message that says "Update schema." The session that made the change is long
gone โ and so is the prompt that produced it.
With Selvedge, you run this instead:
That reasoning was captured by the agent in the moment โ written into Selvedge from the same context that produced the change. Not inferred from the diff afterward by a second LLM. Not a hand-typed commit message.
Selvedge has two audiences. Same tool, same pip install, same SQLite
file under .selvedge/. Different scale of pain.
Teams running long-term, AI-coded codebases.
When the project is big enough that you (or someone else) will touch it
again in six months, twelve months, three years โ but most of it was written
by an agent whose context evaporated the day each PR shipped. git blame
tells you what changed. Selvedge tells you why โ even after the agent
session, the prompt template, the developer who asked for it, and the model
version are all long gone. This is the original use case: production
codebases, schema decisions, migrations, dependency changes that need an
audit trail that survives turnover.
Solo developers using Claude Code on everyday projects.
Side projects, weekend builds, the small internal tool you keep poking at.
You don't need enterprise governance โ you just need to remember why you (or
your agent) did the thing you did yesterday, last week, last sprint. Run
selvedge init once. Add four lines to your CLAUDE.md. From then on,
selvedge blame is muscle memory โ a way to talk to your past self when
your past self was an LLM.
If you've ever come back to your own AI-built project and thought "what was this for again?", Selvedge is the missing piece.
Human-written code leaks intent everywhere โ commit messages, PR descriptions, inline comments, the Slack thread that preceded it. AI-written code doesn't. The agent has perfect clarity about why it made each decision, but that context lives in the prompt and evaporates when the conversation ends.
Six months later, your team is debugging a schema decision with no trail.
git blame tells you what changed and when. It can't tell you why.
Selvedge captures the why โ live, by the agent itself, as the change is made. The diff is git's job. The why is Selvedge's.
Abandoned alternatives are first-class, and the log can prove itself.
Rejections and reverts are now stated outcomes, not inferences.
change_type="reject" records "we considered this and decided against it"
without writing the change โ the counterpart to revert for paths never
taken. prior_attempts reads both as a new confidence: "exact" tier; the
old proximity heuristic drops to tiebreaker. And the expires_when column
that shipped dormant in v0.3.8 gets its evaluator: a closed, machine-checkable
grammar โ library:NAME>=VERSION, entity:PATH:changes, date:ISO,
manual:LABEL โ validated at write time, evaluated locally by
selvedge stale with no network and no LLM. A rejection stored with the
condition that would invalidate it is a decision that knows when to die.
The event log is now tamper-evident. Every logged event gets a SHA-256
chain record in a sidecar table, same transaction, over every field except the
late-bound git_commit (git already witnesses that one). Two new
selvedge verify checks: chain_intact fails hard when a chained row was
edited, deleted, or reordered out-of-band โ the check names the exact sequence
number โ and chain_coverage warns (never fails) about rows that predate the
chain. Legitimate operations append boundary records instead of breaking the
chain, so migrate-paths and a destructive-gated prune verify clean while a
silent sqlite3 edit does not. selvedge verify --json publishes the
attestation manifest. Honest scope, stated in the module itself: this detects
casual and accidental modification and produces an independently verifiable
export; it is not proof against a motivated local attacker.
Also: the PreCompact reminder now distinguishes "edited with no log" from
"log exists but was truncated," and both hook surfaces have their determinism
pinned byte-for-byte in tests; capture-time nudges suggest recording the
invalidating condition when a reject/revert lands without one;
selvedge supersede gains -d/--diff, --revisit-after, and
--expires-when (#31); and an id-less supersede no longer re-opens every
earlier revert on the path (#30). Tests 984 โ 1114.
The memory comes to the agent, and the store gets its dials. Two themes, shipped together because the config half is what the rest needed to read settings from.
Delivery. Selvedge already blocked re-edits of reverted entities. What was missing was delivery when there is nothing to veto. Two new hooks:
Both are quiet when they have nothing to say, size-capped, read-only, and templated. Neither can block anything โ PreCompact deliberately declines the veto the hook API offers it. This is the answer to a measured failure mode: "Delivery, Not Storage" (arXiv:2607.20972) recorded a pull-model memory tool going unused entirely (zero voluntary memory operations across 114 turns against a pre-seeded store) while deterministic injection landed every time.
selvedge export --format markdown renders the store as a reviewable
digest to commit next to it, so captured intent shows up in a pull request
instead of hiding inside a binary. Deterministic โ regenerating with no new
events is a zero-line diff.
Config. .selvedge/config.toml is now first-class, with a canonical
precedence chain that selvedge doctor prints per setting. It brings:
selvedge prune --include-events โ the first path that can delete
captured reasoning, so it needs both a confirmation and
SELVEDGE_DESTRUCTIVE=1. Neither alone is enough, because --yes in a cron
entry defeats a prompt and a shell profile defeats an env var. Events
retention defaults to never.diff_bytes, reasoning_bytes) that truncate loudly
โ a marker in the text, a warning at write time, a count in selvedge stats.log_change, extendable via
redaction_patterns, plus a doctor row that scans what's already stored.
Warn, never reject.Also: five review issues closed. The enforcement hook's allow path is
40% faster (33.6 ms โ 20.1 ms per gated call) and SELVEDGE_HOOK_DISABLE=1
finally short-circuits before the imports it was documented to skip;
log_change no longer discards revisit_after / constraint / stale_when
on renames and supersedes; the CLI's --json and the MCP tools now return
identical structures; and the Docker image no longer ships the maintainer's
own database. Tests 826 โ 984.
Factual signals from GitHub, npm, and our automated checks โ not a rating.
No reviews yet โ be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/masondelan-selvedge)<a href="https://allmcps.com/mcp/masondelan-selvedge"><img src="https://allmcps.com/api/badge/masondelan-selvedge?style=directory" alt="Selvedge on AllMCPs" /></a>