Aperture MCP

io.github.jaysinailabs由 GitHub 帳號 jaysinailabs 發布v0.2.0更新於 Oct 24, 2026

Flag when a tracked commitment vanishes verbatim between two versions. A signal, not a judge.

已驗證STDIO僅桌面知識與記憶開發者工具

概覽

AI 產生的概覽

一個本機 MCP 伺服器,讓助理檢查某項被追蹤的承諾是否在兩版決策文件之間逐字消失。

可以做什麼
比對同一份決策文件的兩個文字狀態,標出被追蹤承諾中逐字消失的部分,並回傳結構化狀態(例如 ok、degraded 或 DROPPED_SILENTLY)以及找到的違規項目。以不分大小寫的子字串方式比對承諾,因此改寫、弱化、轉述或翻譯後的措辭會被漏掉或回傳棄權結果。在結果中報告自身的盲點,方便人工核查遺漏。同一項檢查也提供命令列工具以及 git 預提交鉤子或 CI 步驟。
適用情境
適用於 AI 助理會修改儲存庫內的決策文件(例如規格、計畫、ADR、章程或 AGENTS.md 檔案),而你想在任務過程中確認某項指定承諾沒有被悄悄刪除的情況。它只是範圍很窄的警報線,不判斷變更是否正確;若要在提交時可靠攔截刪除,git 鉤子是更合適的入口。
執行需求
以 Python 套件形式從 PyPI 安裝(aperture-mcp),透過 stdio 在本機執行,可使用 aperture-mcp 指令或經由 uvx 啟動。需要在 .aperture.toml 中依檔案設定承諾監看清單。未宣告驗證、環境變數或網路存取需求;它不會發出網路請求。
安裝前請注意
偵測屬啟發式且範圍很窄:在作者自建語料上測得召回率 0.400、精確率 0.667,約每三個標記就有一個是雜訊,改寫、弱化、轉述或只改數字的承諾會被漏掉。應把每個標記視為「請查看」,而沒有標記不代表沒有漂移。版本在 1.0 之前,尚不適合作為正式上線的把關。它在本機執行且不會用你的資料訓練;使用紀錄預設關閉。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Aperture MCP,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

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 check CLI — 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 degraded rather 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)

sh
pip install aperture-mcp   # installs the `aperture` CLI + the MCP server (wire the CLI as a git hook — see below)

The PyPI package is named aperture-mcp because the bare name aperture was already taken on PyPI. The -mcp suffix is a historical package-name artifact — the product is Aperture, and MCP is only one of its surfaces. One pip install gives 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:

toml
fail_on_drop = true
[[watch]]path = "CHARTER.md"commitments = ["never train on your data", "data stays on the device"]

aperture check compares two git states and flags any watched commitment that disappeared verbatim:

sh
aperture check                                    # HEAD vs working tree (default)aperture check --staged                           # HEAD vs the staged index — for a pre-commit hookaperture check --ref-a origin/main --ref-b HEAD   # any two refs — for CI on a PR

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):

yaml
# .pre-commit-config.yamlrepos:  - repo: https://github.com/jaysinailabs/aperture-mcp    rev: v0.2.0    hooks:      - id: aperture-commitment-drift

…or as a standalone .git/hooks/pre-commit:

sh
#!/bin/shexec aperture check --staged

…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):

yaml
- uses: actions/checkout@v4  with: { fetch-depth: 0 }- run: pip install aperture-mcp- run: aperture check --ref-a ${{ github.event.pull_request.base.sha }} --ref-b ${{ github.sha }}

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.)

jsonc
{  "mcpServers": {    "aperture-mcp": { "command": "aperture-mcp" }  }}

Prefer zero-install? Point the client at uvx instead: { "command": "uvx", "args": ["aperture-mcp"] }.

3. Or from your own Python

python
from aperture import compare, Anchor, AnchorKind
result = compare(    state_a="We commit to: ci-gates-green before release; data-never-leaves-device.",    state_b="We commit to: data-never-leaves-device.",    anchors=[Anchor(kind=AnchorKind.COMMITMENT, id="ci-gates-green")],)print(result.status)            # DROPPED_SILENTLYprint(result.anchor_violations) # the commitment that vanished

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:

Kind of changeDoes Aperture flag it?
A watched commitment deleted verbatim✅ Reliably — this is the one thing it’s good at (24 of 24 in the corpus)
A commitment reworded / softened (“must” → “should”)❌ Missed — the text still “matches”
A commitment paraphrased / restructured❌ Missed
A number / scope / negation quietly changed❌ Missed
A commitment translated to another language⚠️ Declines (abstains) for a natural-language anchor — it can’t compare verbatim across scripts, so it returns degraded rather than false-flag (a commitment dropped and translated is missed)

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-green style the quickstart teaches) is treated as translation-stable — Aperture keeps checking it across languages, so if that exact token disappears it still flags DROPPED_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.md honest.

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

Apache-2.0.

來源:README.md,提交 cc67c32

工具

0
SourceWeft 尚未在沙箱中啟動過該軟體包,因此其工具未知。

版本歷史

1
  1. v0.2.0最新Sep 16, 2026

評分

已滿足適用檢查項的 50%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分

    請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。

  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具15 分

    請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。

  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分