Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
作者提供的说明(英文原文)
Verify timestamp proofs offline, anchor hashes through ProofLedger, keep agent run receipts.
这三项永远不会合并成一个分数:意见、测量和人气是不同的东西。
我们还没有为它写通俗的介绍。下面是我们从注册中心读取到的事实。
选择你使用的 AI 应用,然后复制设置。
你需要
你用的是哪个应用?
在上方选择你的应用。我们会记住它,下次按钮会显示“安装到 …”。
打开 Claude Desktop → Settings → Developer → Edit Config,把下面的内容粘贴到 claude_desktop_config.json
{
"mcpServers": {
"verify-proof": {
"command": "uvx",
"args": [
"verify-proof"
]
}
}
}在终端中运行这条命令
claude mcp add verify-proof -- uvx verify-proof粘贴到项目中的 .cursor/mcp.json,或 ~/.cursor/mcp.json
{
"mcpServers": {
"verify-proof": {
"command": "uvx",
"args": [
"verify-proof"
]
}
}
}浏览器会先询问是否打开应用,然后应用会显示设置并请你确认。密钥的值会留空,由你自己填写。
粘贴到项目中的 .vscode/mcp.json
{
"servers": {
"verify-proof": {
"type": "stdio",
"command": "uvx",
"args": [
"verify-proof"
]
}
}
}浏览器会先询问是否打开应用,然后应用会显示设置并请你确认。密钥的值会留空,由你自己填写。
这个服务器在你的电脑上运行,而 ChatGPT 只能连接互联网上的服务器。请选择其他应用。
你的选择通过 Cookie 保存在这台设备上,无需账户。
这些设置是根据作者在注册中心的条目生成的。如果 README 的写法不同,请以 README 为准。
它在你的电脑上运行;安装后,工具列表会显示在你的 AI 应用中。
我们检查的是任何人都能看到的信息;我们没有阅读代码。不适用的检查项不计入总数。 · 检查于 2026年11月8日
发布者(csolomon0704-prog)不是仓库所有者(Fulcrum-Enterprises);可能是其他人代为上架的
我们还没有从 GitHub 读取这个仓库
我们还没有从 GitHub 读取这个仓库
它在你的电脑上运行,没有互联网端点
在你的电脑上运行,改用本地设置
它在你的电脑上运行;我们只能读取互联网端点的工具列表
与注册中心里这个分类中所有活跃的服务器比较。只有当发布者拥有该仓库时,星标数才计入。
它在 1 项适用的基础检查中通过了 0 项。我们没有阅读代码。在添加密钥或令牌之前,请先看看这个服务器要求哪些权限,并使用只具备所需权限的密钥。
注册中心没有列出必需的密钥,不过有些服务器会在首次使用时要求你登录。
它在你的电脑上运行。你的 AI 应用会在需要时启动它,数据不会经过作者的服务器(除非它自己调用在线服务)。
GitHub 仓库最后更新于–,最新版本(0.4.0)于20天前进入注册中心。
支持 MCP 的应用,例如 Claude Desktop、Claude Code、Cursor 和 VS Code。你的电脑上还需要有 Python (uv)。
同一分类中有:Spec Driven Development, Remote Desktop Commander, Happo
同一分类中其他作者的服务器,按星标数排序。
如何看卡片:★ GitHub 星标i三大支柱:评价 · 检查 · 使用情况i更新 = 最新版本发布到注册中心的时间i
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Review Happo's visual and accessibility diffs: inspect comparisons, accept or reject, report flakes.
按原文从作者的仓库复制。PopNx MCP 没有审查或背书其内容。HTML、图片和脚本已被移除。链接会离开本站。
Check a blockchain timestamp proof on your own machine, and make one through an API.
verify-proof recomputes a file's SHA-256 hash and checks it against a proof bundle, so you can confirm that this exact file existed by the time it was anchored and has not changed by a single byte since. Verification is pure computation: it needs the file and the bundle, no account and no network call. Creating a proof is the one command that goes online, through ProofLedger's API with a free key. Free, MIT licensed, Python standard library only.
Also available for Node.js:
npm install verify-proof, a zero-dependency port sharing the same proof format and semantics, tested against the same fixtures. Seejs/.
The sections below are the questions people ask, each answered with the shortest code that does it.
pip install verify-proof
The base install pulls no dependencies (it uses only the Python standard library) and gives you a verify-proof command:
verify-proof --help
To use it as an MCP server for Claude Desktop or Cursor, install the optional extra instead (details below):
pip install "verify-proof[mcp]"
Prefer to run from source? Clone it; the CLI works the same:
git clone https://github.com/Fulcrum-Enterprises/verify-proof.git
cd verify-proof python verify_proof.py --help
Hash the file locally, anchor the hash in a public blockchain transaction, and keep the record of that transaction next to the file. The transaction's block time is the "no later than" date; the hash ties it to these exact bytes. The file itself never leaves your machine.
This package does the hashing and the verifying; ProofLedger does the anchoring, on Polygon, usually within a minute, with a free API key (100 API proofs a month on the Free plan):
Get a free key at proofledger.io
From the command line:
export PROOFLEDGER_API_KEY=sk_... # Account > API Keys
verify-proof create contract.pdf verify-proof create contract.pdf --no-filename # send only the hash
Only the 64-character SHA-256 digest leaves your machine, plus the filename unless you pass --no-filename. Then save the proof's bundle next to the file; the offline verify command below works on it from then on, without ProofLedger:
curl -H "Authorization: Bearer $PROOFLEDGER_API_KEY" \
"https://proofledger.io/api/v1/proof/42/bundle?download=1" -o contract.pdf.proof.json
From Python, with the small API client the package carries (standard library only):
from proofledger_api import submit_proof, get_bundle
from verify_proof import hash_file import json
proof = submit_proof(hash_file("contract.pdf"), filename="contract.pdf", external_id="contract-2026-10") # key from PROOFLEDGER_API_KEY print(proof["id"], proof["certificate_url"])
bundle = get_bundle(proof["id"]) # once the anchor has landed json.dump(bundle, open("contract.pdf.proof.json", "w"), indent=2)
From Node.js:
import { hashFile, ProofLedger } from "verify-proof";
const pl = new ProofLedger({ apiKey: process.env.PROOFLEDGER_API_KEY }); const proof = await pl.createProof({ sha256: hashFile("contract.pdf"), externalId: "contract-2026-10" }); const bundle = await pl.getBundle(proof.id); // once the anchor has landed
Or straight at the API: POST https://proofledger.io/api/v1/proof with {"sha256": "<64 hex>"} and a Bearer sk_... header. The API is documented at proofledger.io/api, with an OpenAPI spec at /openapi.json.
external_id is your own record id: sending the same one again returns the existing proof instead of making a new one, so a retried job never double-anchors.
verify-proof verify contract.pdf --proof bundle.json
The check runs locally: it hashes the file, compares the result with the hash in the bundle, computes the Merkle root if the bundle has a path, and reports the transaction to look up on a block explorer. It does not read the chain, so until you look that transaction up, the anchor is what the bundle says. Nothing is sent anywhere, so it works the same whether or not the service that issued the proof still exists.
The same check from Python:
from verify_proof import hash_file, load_proof, verify_proof
result = verify_proof(hash_file("contract.pdf"), load_proof("bundle.json")) print(result["verified"], result["tx_id"], result.get("explorer_url"))
And from Node.js: verifyProof(hashFile("contract.pdf"), loadProof("bundle.json")).
A test you can run on any vendor's proof: block the vendor's domain, then verify. If the check still passes, the proof is yours; if it needs the vendor's server to say "valid", you are relying on them staying in business.
verify-proof hash contract.pdf
A successful verify prints one line to stderr saying where to make proofs like it. It is suppressed whenever the output is piped or redirected, so scripts never see it, and stdout is unchanged either way. To silence it everywhere:
export VERIFY_PROOF_NO_HINT=1
A Merkle path is the list of sibling hashes between your leaf (the file's hash) and the root that was recorded on chain. Validating it means folding your hash up through the siblings and comparing the result with the root in the transaction. The rule this package uses, in full:
import hashlib
def merkle_root(leaf_hex: str, path: list[dict]) -> str: current = leaf_hex for step in path: # [{"hash": " ", "position": "left" | "right"}, ...] sibling = step["hash"] combined = sibling + current if step.get("position") == "left" else current + sibling current = hashlib.sha256(bytes.fromhex(combined)).hexdigest() return current
Each level concatenates the two hashes as raw bytes, in the order the position says, and hashes the result with SHA-256. verify_proof() runs exactly this when a bundle carries a merkle_path, returns the root as merkle_root, and prints it so you can compare it with the root recorded in the transaction. The comparison with the chain is yours to make: this package never reads the chain.
On Polygon, ProofLedger anchors each proof in its own transaction, so merkle_path is empty and the hash in the transaction is your file's hash directly. Bitcoin-anchored proofs from other services, and the few ProofLedger proofs anchored on Bitcoin before 2026-10-15, carry a path.
Up to 100 hashes in one call, each with your own external_id, so a re-run returns the proofs that already exist instead of anchoring twice:
from proofledger_api import submit_batch, get_proof_by_external_id
from verify_proof import hash_file
result = submit_batch([ {"sha256": hash_file("invoice-1001.pdf"), "external_id": "invoice-1001", "filename": "invoice-1001.pdf"}, {"sha256": hash_file("invoice-1002.pdf"), "external_id": "invoice-1002"}, ]) print(result["summary"]) # created / exists / invalid counts for item in result["items"]: print(item["result"], (item.get("proof") or {}).get("id"))
later = get_proof_by_external_id("invoice-1001") # None if you never anchored it
Node.js: await pl.createProofs(items) takes the same list, and pl.getProofByExternalId(id) looks one up. From an AI assistant, the create_proofs_batch MCP tool does this for a list of files, using each file's name as its record id.
Items are checked first and written together; a batch is Polygon only. For plain request retries there is also an optional Idempotency-Key header on the creating endpoints (the same key and body within 24 hours replays the stored response), but external_id is the simpler way to make submissions safe to retry.
Register a public https URL once; ProofLedger then POSTs a signed JSON event, proof.polygon.anchored, when a proof's Polygon anchor lands. The event carries the proof's bundle, so your handler can save it next to the file with nothing further to fetch.
import { ProofLedger, verifyWebhookSignature } from "verify-proof";
const pl = new ProofLedger({ apiKey: process.env.PROOFLEDGER_API_KEY }); const hook = await pl.registerWebhook("https://example.com/proofledger", ["proof.polygon.anchored"]); // hook.secret is shown once; keep it for the check below
Check every delivery before trusting it. The header is ProofLedger-Signature: t= ,v1= over t + "." + raw body; pass the body exactly as received:
from proofledger_api import verify_webhook_signature
ok = verify_webhook_signature(secret, request.headers["ProofLedger-Signature"], request.get_data())
Node.js: verifyWebhookSignature(secret, header, rawBody). Both are pure computation, no network. Failed deliveries are retried seven times over almost two days, then the endpoint is switched off and the account emailed. Webhooks fire only for proofs created after the endpoint was registered. Management endpoints: POST /api/v1/webhooks, GET to list, DELETE /api/v1/webhooks/:id, POST /api/v1/webhooks/:id/test.
Yes. ProofLedger Community is the same proof core as an open-source (AGPL-3.0) Node + SQLite server you run with your own Polygon key: the same v1 API shapes (single and batch proofs with external_id, bundles, lists, public verify, certificates, signed webhooks, Idempotency-Key, per-key rate limits), writing the same transaction shape as proofledger.io, so this tool checks its bundles the same way.
只显示了开头部分;其余内容请在仓库中阅读