Sponsored by Deepsite.site

Verify Action

Created By
Armada735a month ago
Verify AI agent tool calls with content-addressed, HMAC-attested receipts. Free third-party verification API for AI agents. Call verify_action(claim, evidence) to get an independent integrity check on whether your claimed action matches the actual evidence. Useful for catching silent failures: incorrect SQL operations, file-op mismatches, API call inconsistencies, and code-diff scope creep. Five specialized verifier kinds: - code_diff: verb / path / identifier coherence with unified diff - db_op: row delta + SQL operation + ID match - file_op: existence state + line/size delta - api_call: request body and response status coherence - generic: conservative fallback Returns: - aar_verdict: verified | contradicted | insufficient_evidence | unsafe_to_verify - verdict: ok | mismatch | uncertain (legacy 3-value alias) - reasoning, confidence - receipt: verify_action_receipt.v0 with HMAC-SHA256 signature, content-addressed via SHA-256 hashes of claim and evidence Cross-vendor: works with Claude Code, Cursor, Cline, Codex, Codeium, and any MCP-compatible harness. Stateless, per-request, no API key, no registration. Pure Python stdlib (no pip install). Anonymized telemetry only — no PII, no model fingerprint, no raw claim/evidence retention. Honest scope: this is a small reference implementation, not a canonical inter-vendor standard. v0 receipts use HMAC-SHA256 (symmetric, single-issuer); v1 with ed25519 + multi-issuer is on the roadmap. The hosted endpoint has no SLA — self-host for stability (git clone && ./start.sh). 90-day probe with explicit kill criteria. If adoption appears, v1 schema work begins. If response is null, the null is itself a publishable data point.
Overview

verify-action-mcp

When your AI agent says "I deleted user 12345" but the row count didn't change — this catches it. A small third-party verification service for AI agent tool-call evidence: submit (claim, evidence), get back a verdict and an HMAC-attested receipt.

License: MIT Tests

🇯🇵 日本語版は ↓ ページ後半 を参照してください。


English

Why

AI agents commonly assert success when reality didn't match:

  • "I deleted user 12345" — but the row count didn't actually change.
  • "I added a null check" — but the diff also rewrote 5 unrelated functions.
  • "I sent the welcome email to alice@example.com" — but the request body actually targeted bob@example.com.

These silent successes don't show up in benchmarks (which score "did the model say it succeeded?"). They surface when something downstream breaks — sometimes hours or days later.

verify-action-mcp is a small third-party that catches that drift before downstream tools commit to it. It's a post-action evidence verifier — the receipt proves what was checked, not what is true. Existing pre-action policy admission control products from major vendors operate on a different lane; this one runs after the agent has done the work, with the artifacts.

Quick start

MCP (Claude Code, Cursor, Cline, Codex, etc.)

// claude_desktop_config.json or your harness's MCP config
{
  "mcpServers": {
    "verify-action": {
      "transport": {"type": "http", "url": "https://verify.armadalab.dev/mcp"}
    }
  }
}

The agent now has a verify_action tool available. It can self-call before reporting completion, or you can invoke it from your harness logic.

REST

curl -X POST https://verify.armadalab.dev/verify \
  -H 'Content-Type: application/json' \
  -d '{
    "claim": "Deleted user 12345",
    "evidence": {
      "before_count": 100,
      "after_count": 99,
      "operation": "DELETE FROM users WHERE id=12345",
      "affected_rows": 1
    }
  }'

Response (receipt truncated; full shape below):

{
  "verdict": "ok",
  "aar_verdict": "verified",
  "reasoning": "Row count decreased by exactly 1; SQL operation matches DELETE semantics; user id matches claim.",
  "confidence": 0.92,
  "verifier_used": "db_op_v1",
  "kind_dispatched": "db_op",
  "receipt": {
    "schema": "verify_action_receipt.v0",
    "verdict": "verified",
    "claim_hash": "sha256:<64-hex>",
    "evidence_manifest_hash": "sha256:<64-hex>",
    "kid": "v0-default",
    "issued_by": "aar:reference-impl@v0",
    "signature": "hmac-sha256:<base64>",
    "_full": "(see Receipts section)"
  }
}

Self-host

git clone https://github.com/Armada735/verify-action-mcp
cd verify-action-mcp
./start.sh   # binds 127.0.0.1:8092
./stop.sh

Pure Python stdlib. No pip install. Tested on Linux.

What it verifies

A dispatcher routes by kind (or auto-infers from evidence shape):

KindEvidence shapeCritical signal that forces mismatch
code_diff{diff: "<unified diff>"}All claimed paths absent from diff
db_op{before_count, after_count, operation, affected_rows}Claim ID not in SQL ID
file_op{path, exists_before, exists_after, line_count?, size_bytes?}Numeric divergence > 50% or > 50 absolute
api_call{request, response_status, response_body}Email target mismatch (claim ↔ request body)
genericany object(conservative; usually returns insufficient_evidence)

Each verifier looks at:

  • Verb in claim ↔ direction of state change (delete = -1, insert = +1, update = 0)
  • Specific identifiers / paths / emails / URLs
  • Counts / line counts / sizes
  • HTTP status semantics
  • "Critical signals" that force mismatch regardless of pos/neg balance

Verdicts (dual format)

FieldValuesNotes
aar_verdictverified / contradicted / insufficient_evidence / unsafe_to_verify4-value canonical (verify_action_receipt.v0)
verdictok / mismatch / uncertain3-value legacy alias for backwards compatibility

unsafe_to_verify is returned when the verifier itself raised an exception (cannot examine evidence) — distinct from insufficient_evidence (evidence examined, ambiguous).

Receipts (verify_action_receipt.v0)

Every /verify call also issues an HMAC-SHA256-attested receipt as a nested receipt field. Full shape:

FieldTypeDescription
schemastring"verify_action_receipt.v0"
kidstringKey id; v0 ships with "v0-default". Operators rotate keys with fresh kids.
issued_bystringIssuer identifier (this reference impl: "aar:reference-impl@v0")
issued_atstringRFC 3339 UTC timestamp
verifier_idstring"verify-action-mcp@<version>"
verifier_methodstring"rule_based.<kind>" (e.g. rule_based.db_op)
claim_hashstring"sha256:<64-hex>" — content-addressed; raw claim is not stored
evidence_manifest_hashstring"sha256:<64-hex>" — same
verdictstringOne of the 4 aar_verdict values
confidencenumber0–1
reason_codesarray of stringsFree-form diagnostic codes (v0 unrestricted)
policy_or_oracle_refsarray of stringsOptional refs to policy / oracle inputs (usually [])
caller_contextobjectOptional caller_context echoed back (max 8 keys, 64-char strings)
signaturestring"hmac-sha256:<base64-no-padding>"

What the receipt asserts: that this specific service issued this specific verdict for this content-addressed (claim, evidence) pair at this time, signed under a known key id (kid).

What the receipt does NOT assert: factual truth of the claim, legal admissibility in any forum, or warranty of any kind.

Trust model in v0: HMAC is symmetric — the receipt verifies that a private key under our control signed it. It is not a third-party attestation in the cryptographic sense. Treat v0 receipts as a content-addressed log entry from this service. Schema upgrade path for v1 (asymmetric ed25519, multi-issuer) is documented in aar/SCHEMA_UPGRADES.md.

API

MethodPathPurpose
GET/ /aboutProject description (HTML)
GET/healthcheckLiveness probe
GET/specTool schema + verifier kinds (JSON)
GET/statsAggregate counters since process start
GET/privacyPrivacy notice (HTML)
GET/tosTerms of service (HTML)
POST/verifyREST: {claim, evidence, kind?, context?, caller_context?} → verdict + receipt
POST/mcpMCP JSON-RPC 2.0 endpoint

MCP methods

  • initialize{protocolVersion: "2024-11-05", capabilities: {tools: {}}, serverInfo: {name, version}}
  • tools/list{tools: [{name: "verify_action", description, inputSchema}]}
  • tools/call (name=verify_action) → {content: [...], isError, _structured_result: {verdict, aar_verdict, reasoning, confidence, receipt, ...}}
  • notifications/initialized, ping → empty result

Examples

code_diff — coherent

curl -X POST https://verify.armadalab.dev/verify -H 'Content-Type: application/json' -d '{
  "claim": "Added null check for user.email in src/user.py",
  "evidence": {
    "diff": "--- a/src/user.py\n+++ b/src/user.py\n@@ -10,3 +10,5 @@\n def get_email(user):\n+    if user.email is None:\n+        return None\n     return user.email"
  }
}'
# → aar_verdict: verified (legacy: ok), confidence ~0.9

file_op — line count mismatch

curl -X POST https://verify.armadalab.dev/verify -H 'Content-Type: application/json' -d '{
  "claim": "Created /tmp/output.txt with 200 lines",
  "evidence": {"path":"/tmp/output.txt","exists_before":false,"exists_after":true,"line_count":50}
}'
# → aar_verdict: contradicted (legacy: mismatch) — claim said 200 lines, evidence says 50

api_call — target email mismatch (critical signal)

curl -X POST https://verify.armadalab.dev/verify -H 'Content-Type: application/json' -d '{
  "claim": "Sent welcome email to alice@example.com",
  "evidence": {
    "request": {"to":"bob@example.com","subject":"Welcome!"},
    "response_status": 200, "response_body": "{\"sent\":true}"
  }
}'
# → aar_verdict: contradicted — target email differs from claim

Privacy

  • IP addresses are SHA-256-hashed with a salt (rotates per server install). Plaintext IPs are never persisted.
  • Submitted claims and evidence are written to private trace logs marked untrusted_payload. Aggregate findings may be published; individual traces stay private.
  • 30-day log retention is enforced by the included purge_old_logs.sh script (operator installs as a daily cron — see monitor/CRON.md for the entry).
  • A PII guard rejects payloads containing JP My Number-shape (12-digit) sequences, passport-shape strings, or credit-card-shape digits (with Luhn check). Detection is structural — the guard does NOT confirm any number is a real personal identifier.
  • traces/ is chmod 600.

See /privacy and /tos for the user-facing notice.

Phase 1 limitations

  • Rule-based only — no LLM-as-judge. The 4 specialized verifiers handle their kinds well; the generic axis is conservative (often returns insufficient_evidence).
  • No sub-claim decomposition — 1 claim → 1 verifier.
  • No cross-trace correlation — each call is independent.
  • HMAC-attested receipts only — symmetric, single-issuer. Asymmetric / multi-issuer path documented in aar/SCHEMA_UPGRADES.md.
  • No SLA, no rate-limit guarantee, no uptime promise on the hosted endpoint. Self-host (above) for stability.

Who this is for / not for

For:

  • Agent harness developers wanting a quick post-action sanity check
  • Multi-agent pipeline operators wanting an integrity boundary between steps
  • Anyone evaluating "did this agent do what it said it did?" patterns

Not for:

  • Security-critical attestation (HMAC v0 is not third-party-strong; wait for v1 ed25519)
  • High-throughput production with strict SLA (run self-hosted, expect to maintain it)
  • Domain-specific reasoning the rule-based verifiers don't cover (extend by writing a custom verifier kind under verifiers/)

Roadmap

  • Schema v1: ed25519 + multi-issuer (aar/SCHEMA_UPGRADES.md)
  • LLM-augmented generic verifier (opt-in)
  • Sub-claim decomposition for multi-step actions
  • Cumulative observation API ("this harness mismatches on file_op X% of the time")
  • Custom verifier registration

This is a 90-day probe. If meaningful adoption appears, v1 schema work begins.

License

MIT — see LICENSE.

Contact

Maintained by Armada (@Ardev_lab). Issues / questions: GitHub Issues, or hello@armadalab.dev.


日本語

これは何

AI エージェントが「user 12345 を削除しました」と言うのに DB の行数が変わってない — そういう silent な不整合を捉える、小さい第三者検証 service です。

エージェントから (claim, evidence) を受け取って、整合判定 (verdict) と HMAC 署名付き受領証 (verify_action_receipt.v0) を返します。

想定する失敗パターン(一般論として)

  • 「user 12345 を削除しました」と言うが、DB の行数は変わってない
  • 「null チェックを追加した」と言うが、diff には無関係な 5 関数の rewrite が混ざってる
  • alice@example.com に welcome メールを送った」と言うが、実際の request body は bob@example.com

ベンチマークは「モデルが成功と言ったか」を見ますが、「実際の状態が claim と整合的に更新されたか」は別軸の問題です。後者は agent 運用上の重要な観点の一つです。

verify-action-mcp は、その差分を downstream のツールが confirm する前に 捉える層を担います。既存の pre-action 許可制御(policy admission control / ツール呼び出し前の許可)とは独立した、post-action 証拠検証 という別レイヤを提供します。

業界標準を主張せず、reference implementation として位置づけます。receipt schema (verify_action_receipt.v0) は fork できる程度に小さく設計しています。

使い方

MCP(Claude Code / Cursor / Cline / Codex 等)

{
  "mcpServers": {
    "verify-action": {
      "transport": {"type": "http", "url": "https://verify.armadalab.dev/mcp"}
    }
  }
}

これでエージェントの tools 一覧に verify_action が現れます。エージェントが完了報告の直前に self-call するパターンを想定しています。

REST

curl -X POST https://verify.armadalab.dev/verify -H 'Content-Type: application/json' -d '{
  "claim": "user 12345 を削除しました",
  "evidence": {
    "before_count": 100, "after_count": 99,
    "operation": "DELETE FROM users WHERE id=12345",
    "affected_rows": 1
  }
}'

応答(抜粋。receipt の完全形は下の Receipt 節参照):

{
  "verdict": "ok",
  "aar_verdict": "verified",
  "reasoning": "Row count decreased by exactly 1; SQL operation matches DELETE semantics; user id matches claim.",
  "confidence": 0.92,
  "receipt": { "schema": "verify_action_receipt.v0", "...": "..." }
}

4 値判定 (aar_verdict)

意味
verifiedclaim と evidence が整合
contradictedclaim と evidence に決定的な不一致あり
insufficient_evidenceevidence は examined されたが判定材料が足りない
unsafe_to_verifyverifier が例外で evidence を examine できなかった

旧 3 値 (ok / mismatch / uncertain) も verdict フィールドで返るため、既存 client の互換性は維持されます。

Receipt(HMAC 署名付き受領証)

/verify の応答には署名された verify_action_receipt.v0 受領証が receipt ネスト下で返ります。主な field:

field内容
schema"verify_action_receipt.v0"
kid鍵 id(v0 default は "v0-default"、operator は rotation 時に新しい kid を発行)
issued_by発行者識別子(reference impl は "aar:reference-impl@v0"
issued_atRFC 3339 UTC タイムスタンプ
verifier_id"verify-action-mcp@<version>"
verifier_method"rule_based.<kind>"(例: rule_based.db_op
claim_hash"sha256:<64-hex>" — claim 本文は保存しない
evidence_manifest_hash"sha256:<64-hex>" — evidence 本文は保存しない
verdict4 値のいずれか
confidence0..1
reason_codes自由形式の診断コード配列
signature"hmac-sha256:<base64>"

receipt の意味: 「このインスタンスが、この時刻に、この (claim, evidence) ペア(hash 参照)に対して、この verdict を発行した」だけです。claim 自体の真実性、いかなる法的手続における証拠能力(admissibility)、品質保証も主張するものではありません。

v0 の trust model: HMAC は対称鍵のため、receipt は「当 service が(既知の private 鍵で)署名した」ことしか証明しません。第三者証明としての強度は v1(ed25519 + multi-issuer)以降で達成予定です。schema 拡張 path は aar/SCHEMA_UPGRADES.md を参照。

Privacy

  • IP は SHA-256 + salt で 16 文字に hash 化(生 IP は保存しない) ※ハッシュ化済 IP からは特定の個人を識別しません。
  • claim / evidence は private trace ログに untrusted_payload として記録、集計指標のみ公表します
  • 30 日でログ自動削除(purge_old_logs.sh を operator が daily cron として運用)
  • マイナンバー等の特定個人情報らしき桁数列、passport-shape 文字列、credit-card-shape の数字(Luhn check 込)を含む payload は受領証発行を停止します(検出は形式のみで、番号確定をするものではありません)。
  • traces/chmod 600

詳細は /privacy /tos 参照。

現時点の制約

  • stdlib only / rule-based: LLM-as-judge は不実装。generic 軸は意図的に弱め
  • sub-claim 分解なし: 1 claim → 1 verifier
  • cross-trace correlation なし: 各 call は独立判定
  • HMAC(対称鍵)のみ: 多発行体対応 / asymmetric は v1 で(aar/SCHEMA_UPGRADES.md
  • hosted endpoint に SLA / uptime / rate-limit の保証はありません: 安定性が必要なら self-host を推奨

想定読者

  • agent harness 開発者で、完了報告前の sanity check を仕込みたい人
  • multi-agent pipeline 運用者で、ステップ間に integrity boundary を置きたい人
  • 「agent が言ったとおりに本当にやったか」を継続観察したい人

ロードマップ

90 日 probe として運用、事前に commit した kill criteria に基づいて継続 / 縮小 / 撤退を判断します。adoption が現れたら schema v1(ed25519 + multi-issuer)から着手。

ライセンス・連絡先

  • License: MITLICENSE 参照)
  • 維持者: Armada (@Ardev_lab)
  • Issue / 質問: GitHub Issues または hello@armadalab.dev
  • ※現時点では無料で提供しています(将来の有料化についてはアナウンス予定)

Server Config

{
  "mcpServers": {
    "verify-action": {
      "url": "https://verify.armadalab.dev/mcp"
    }
  }
}
Recommend Servers
TraeBuild with Free GPT-4.1 & Claude 3.7. Fully MCP-Ready.
Y GuiA web-based graphical interface for AI chat interactions with support for multiple AI models and MCP (Model Context Protocol) servers.
CursorThe AI Code Editor
Visual Studio Code - Open Source ("Code - OSS")Visual Studio Code
BlenderBlenderMCP connects Blender to Claude AI through the Model Context Protocol (MCP), allowing Claude to directly interact with and control Blender. This integration enables prompt assisted 3D modeling, scene creation, and manipulation.
Amap Maps高德地图官方 MCP Server
Playwright McpPlaywright MCP server
Zhipu Web SearchZhipu Web Search MCP Server is a search engine specifically designed for large models. It integrates four search engines, allowing users to flexibly compare and switch between them. Building upon the web crawling and ranking capabilities of traditional search engines, it enhances intent recognition capabilities, returning results more suitable for large model processing (such as webpage titles, URLs, summaries, site names, site icons, etc.). This helps AI applications achieve "dynamic knowledge acquisition" and "precise scenario adaptation" capabilities.
AiimagemultistyleA Model Context Protocol (MCP) server for image generation and manipulation using fal.ai's Stable Diffusion model.
DeepChatYour AI Partner on Desktop
EdgeOne Pages MCPAn MCP service designed for deploying HTML content to EdgeOne Pages and obtaining an accessible public URL.
WindsurfThe new purpose-built IDE to harness magic
Tavily Mcp
MCP AdvisorMCP Advisor & Installation - Use the right MCP server for your needs
Howtocook Mcp基于Anduin2017 / HowToCook (程序员在家做饭指南)的mcp server,帮你推荐菜谱、规划膳食,解决“今天吃什么“的世纪难题; Based on Anduin2017/HowToCook (Programmer's Guide to Cooking at Home), MCP Server helps you recommend recipes, plan meals, and solve the century old problem of "what to eat today"
ChatWiseThe second fastest AI chatbot™
MiniMax MCPOfficial MiniMax Model Context Protocol (MCP) server that enables interaction with powerful Text to Speech, image generation and video generation APIs.
Baidu Map百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Serper MCP ServerA Serper MCP Server
RedisA Model Context Protocol server that provides access to Redis databases. This server enables LLMs to interact with Redis key-value stores through a set of standardized tools.
Jina AI MCP ToolsA Model Context Protocol (MCP) server that integrates with Jina AI Search Foundation APIs.