
Aperture MCP
io.github.jaysinailabsPublished by GitHub account jaysinailabsv0.2.0Updated Oct 24, 2026
Flag when a tracked commitment vanishes verbatim between two versions. A signal, not a judge.
Overview
A local MCP server that lets an assistant check whether a tracked commitment disappeared verbatim between two versions of a decision document.
- What you can do
- Compare two text states of a decision document and flag tracked commitments that vanished word for word, returning a structured status such as ok, degraded or DROPPED_SILENTLY alongside the violations found. Match commitments as case-insensitive substrings, so reworded, softened, paraphrased or translated wording is missed or abstained on. Report its own blind spots in the result so a human can audit the gaps. The same check is also available as a CLI and a git pre-commit hook or CI step.
- When to use it
- Useful when AI agents edit repo-resident decision documents such as specs, plans, ADRs, charters or AGENTS.md files and you want an in-task check that a named commitment was not silently deleted. It is a narrow tripwire, not a judge of whether a change was right; the git hook is the more reliable surface for catching drops on commit.
- Requirements
- Runs locally over stdio as a Python package installed from PyPI (aperture-mcp), either as the aperture-mcp command or via uvx. Needs a watchlist of commitments per file, configured in a .aperture.toml. No authentication, environment variables or network access are declared; it makes no network calls.
Installation
In SourceWeft
- Open Aperture MCP in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
Aperture
A commitment tripwire · git hook · CI · CLI · MCP
Did an agent quietly drop a commitment from your spec — and no one noticed?
[PyPI] [MCP] [License] [status]
English · 简体中文
AI agents now rewrite the documents that govern your work — specs, plans, ADRs, charters,
AGENTS.md files. Somewhere in the edit, a constraint you set earlier can quietly disappear.
Aperture is a commitment tripwire. You name the commitments you care about; it flags — word for word — when one of them vanishes between two versions of a decision document.
Catching "a commitment silently vanished" is a tripwire job: it should fire on an event, deterministically, without asking permission. So Aperture ships that check on the surface that fits it best first — a git pre-commit hook / CI check that runs with no LLM, offline — and also as a CLI and an MCP server for agents to call mid-task. MCP is one adapter, not the whole product.
A signal, not a judge. It trips; you investigate. Opt-in · runs locally · never trains on your data.
What it is (and what it is not)
Aperture compares two text states of the same decision — an earlier version and a later one — and surfaces a narrow, specific kind of decision drift: when a tracked commitment’s exact text disappeared. One engine, several surfaces:
- git pre-commit hook / CI check — the deterministic form. Fires on the commit / PR event with no model in the loop, and blocks (or warns) automatically.
aperture checkCLI — run the same check by hand between any two git states.- MCP server — so an agent can call the check while it edits (weaker as a tripwire, since it only runs if the agent chooses to call it — but useful mid-task).
What the engine does and doesn’t do:
- ✅ It does: flag when a commitment you listed verbatim is present in version A and gone from version B — across commits, sessions, or authors. It returns a structured, comparable result with its own blind spots written on the label.
- ❌ It does not: understand meaning. It matches text as a case-insensitive substring, so it
misses a commitment that was reworded / softened / paraphrased (it looks dropped-free even
though the promise weakened); it declines/abstains on a commitment that was merely translated
(it can’t compare verbatim across scripts, so it returns
degradedrather than false-flag); and it can still false-flag a commitment that was merely reformatted (the words moved, the meaning didn’t). It does not rank options, score quality, or tell you a change was wrong. That judgment stays with you. Moving to the deterministic git-hook makes the check fire reliably — it does not widen what it can see. Same narrow, verbatim signal.
If you want one sentence: Aperture is grep for vanished commitments, wired to fire on commit —
and honest enough to admit what it can’t see.
Quickstart (≈2 minutes)
The PyPI package is named
aperture-mcpbecause the bare nameaperturewas already taken on PyPI. The-mcpsuffix is a historical package-name artifact — the product is Aperture, and MCP is only one of its surfaces. Onepip installgives you all three below.
1. The deterministic tripwire — git pre-commit hook / CI (no LLM, offline)
Create a .aperture.toml — a watchlist of the commitments that must not silently vanish, per file:
aperture check compares two git states and flags any watched commitment that disappeared
verbatim:
Exit code 1 blocks the commit when a watched commitment dropped (the default);
--warn-only prints the finding but never blocks. It’s stdlib-only, makes no network calls, and runs
no model.
Wire it as a pre-commit hook — either through the pre-commit framework
(uses this repo’s .pre-commit-hooks.yaml):
…or as a standalone .git/hooks/pre-commit:
…or run it in CI as a GitHub Action on every PR (needs fetch-depth: 0 so both
sides are available — see examples/github-action/aperture-check.yml):
Kick the tires first with the bundled fixture (clone the repo): it trips on a dropped commitment against checked-in before/after docs, no setup, fully offline —
python3 examples/git_decision_drift/git_decision_drift.py.
2. Mid-task, from an agent — the MCP server
The same check, callable by an agent while it edits. (An MCP tool only fires if the agent chooses to call it — a weaker delivery for a tripwire than the git-hook, but handy mid-task.)
Prefer zero-install? Point the client at
uvxinstead:{ "command": "uvx", "args": ["aperture-mcp"] }.
3. Or from your own Python
A scene you’ll recognize
On a long task, your agent keeps rewriting the doc it works from — a plan, a spec — across sessions and edits. And every so often, a line that mattered just… vanishes.
“Always ask before you delete anything.” Gone. “User data never leaves the device.” Gone. “The free tier stays free.” Gone.
Nobody meant to drop them; nobody reads all 400 lines of the diff.
Aperture watches the exact lines you name. Put it on the commit — a hook that fires before the drop lands — and it won’t try to understand the doc or judge it; it just tells you which promise was there, word for word, and now isn’t. A tripwire, not a judge — and honest about the rest: soften a line, reword it, or change a number instead of deleting it, and it’ll slip past. Better you hear that now.
What trips it — and what slips past
Aperture is a heuristic. We measured it on our own gold corpus and we publish the numbers instead of a single flattering score, because knowing where it’s blind is the product — recall 0.400, precision 0.667 on a 100-case corpus, labeled by an isolated LLM-judge panel (it catches 26 of 65 real drifts; ~1 flag in 3 is noise), full breakdown in docs/measured-limits.md:
The deterministic surface doesn’t widen the aperture. The git-hook fires reliably — but it still only catches verbatim deletion. Every ❌ / ⚠️ row above is exactly as blind through the hook as through MCP. What you gain is when it checks (on the commit, without anyone remembering to ask), not what it can see.
Anchor style matters for that last row: the abstain applies to a natural-language anchor. A code-identifier anchor (the
ci-gates-greenstyle the quickstart teaches) is treated as translation-stable — Aperture keeps checking it across languages, so if that exact token disappears it still flagsDROPPED_SILENTLY(usually what you want for a stable identifier).
Takeaway: treat every flag as “look here,” never as “this is wrong” — and never assume silence means nothing drifted. Aperture catches the verbatim disappearance case well and is honest that it catches little else. That narrow, reliable signal is useful precisely because it doesn’t pretend to be more.
Hit one of those misses on your own docs? That's the single most useful thing you can send us — report it in ~30s (your wording is optional). Real misses guide what we fix next.
Why not just
git diff/grep? You can reproduce the core check by hand. What Aperture adds is that it’s wired to fire on the commit / PR event (as a hook or CI check) and callable mid-task by an agent (over MCP); it returns a structured, directional result (ok/degraded/DROPPED_SILENTLY/ …); and it reports its own blind spots in the result so a human can audit the gaps. It’s ergonomics + honesty around a simple, legible check — not a smarter detector.
Why this exists
Long-running and multi-agent workflows drift. A constraint set in turn 3 / session 1 / by agent A gets quietly edited away forty turns later, in another session, by agent B — and nobody notices until it ships. Aperture is a preflight you can put on the documents agents maintain: name the commitments that must not silently vanish, and get a tripwire when one does — ideally on the commit itself, before the drop ever lands.
It is deliberately small and legible. It is not an AI that decides for you; it is a signal that helps you stay consistent with yourself.
Who it’s for
Teams and builders who (a) let AI agents edit repo-resident decision documents — specs, plans,
ADRs, charters, and AGENTS.md files — and (b) keep those documents under version control.
If your agents touch text that encodes promises, Aperture gives you a cheap, honest tripwire — on the
commit, in CI, or mid-task — on the ones you can’t afford to lose silently.
Privacy
- Opt-in and local. Aperture runs on your machine — the git-hook, the CLI, and the MCP server alike. It makes no network calls.
- Never trains on your data. Your decision text is yours; it never leaves your process.
- Usage logging is off by default and, when enabled, records only metadata (timestamp, tool, status, counts) — never your decision text or commitment wording.
Honesty about the demo
The repository ships a small hand-authored fixture ADR (a before/after pair under
examples/git_decision_drift/fixtures/), where Aperture
correctly flags a commitment we deliberately retired and stays quiet on one we kept. It is a faithful
illustration of the mechanism — but it is a sample of one that we author and judge ourselves. It
demonstrates how the tripwire works, not that the signal is strong. For the latter, see the
measured per-family numbers above and in
docs/measured-limits.md.
We have zero external adopters yet — if you run Aperture on your own decision docs, we’d love to
hear what it caught and what it missed.
Project status
Early, pre-1.0, not yet a production gate. The compare contract (v0.2) is frozen and covered
by a conformance suite; the package API may still move. See VERSIONING.md for the
compatibility policy and CHANGELOG.md for changes.
Hit a miss? Help it improve
Aperture will miss things — that's by design (it's blind to reworded, softened, and translated commitments, on every surface). When it misses a drift you cared about, or false-flags a rewrite, telling us is the single most valuable contribution:
- ~30 seconds, no account/usage data, your wording is optional → open a drift-case report.
- Real misses tell us which blind spot to fix next, and — only if you choose to share the wording —
can become cases in the gold corpus that keeps the numbers in
docs/measured-limits.mdhonest.
We never auto-collect anything (see Privacy); this happens only when you choose to share. Questions, or "is this the right tool for my case?" → GitHub Discussions.
More ways to help: CONTRIBUTING.md.
License
Source: README.md at commit cc67c32
Tools
0Version history
1- v0.2.0LatestSep 16, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts