MCP server that lets Claude, Cursor, LangGraph, and other agents record AI decisions to a tamper-evident ledger.
Four well-named tools with strong descriptions (avg 180 chars) and complete JSON Schema input definitions. All parameters are typed and described. Tool names follow verb_noun pattern (record_, verify_, list_). Schemas include format constraints (uuid, date-time) and proper required field declarations. Output schemas are not explicitly documented in the visible code, and error handling lacks recovery guidance. No tool annotations (readOnlyHint/destructiveHint) present. Security-conscious design (hashing PII before transit, immutable storage) is well-documented in descriptions but not reflected in parameter-level security warnings.
List recorded AI decisions for the calling tenant within a time window. Returns newest first. The read key scopes the result to the caller's tenant — cross-tenant reads require an admin read key. Use this for compliance review, audit prep, or agent self-inspection of recent activity.
Record an AI decision to the audit ledger. Stores model version, hashed inputs, structured output, and human-review flag. The record is immutably sealed in S3 Object Lock for 7 years and queryable for the lifetime of the decision. Use this immediately after any AI decision that may need to be audited later — credit, hiring, fraud, customer routing, content moderation.
Detect whether any audit records have been deleted or omitted for the caller's tenant. Each successfully stored decision receives a per-tenant monotonic sequence number. This tool compares the ledger's counter against the rows actually present in DynamoDB and returns any sequence numbers that are missing. Use this when a regulator or compliance team asks 'can you prove the log is complete?' — verify_decision only proves an existing record was not altered; this proves no record has disappeared.
Verify a recorded AI decision has not been altered since it was written. The ledger fetches the queryable copy (DynamoDB) and the immutable copy (S3 Object Lock COMPLIANCE mode) independently and compares them. Returns integrity_verified=true if they match. Use this to satisfy a regulator request or to prove an audit trail to a compliance team.
Output schemas not documented. Tool descriptions explain what is returned (e.g., 'Returns integrity_verified=true if they match'), but formal output schema definitions are absent from visible code. LLMs cannot plan downstream operations without knowing response structure.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). record_decision is a WRITE operation with side effects; verify_decision and list_decisions are READ_ONLY. Annotations would help agents reason about safety and retry semantics.
Error handling lacks recovery guidance. src/index.ts catches AuditLedgerError and returns raw error messages ('Error: ...'). No categorization of retryable vs. fatal errors, no actionable next steps for the LLM (e.g., 'Try again in 30s' for 429, 'Check credentials' for 401).
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | 2026-07-28+ | v2 |
verify_completeness parameter 'tenant_id' is optional but its behavior is context-dependent ('Required only when calling with the admin read key'). This conditional requirement is not enforced in schema and could cause silent failures if an LLM omits it when needed.
list_decisions 'limit' parameter has no default stated in schema (description says 'default 100, max 500'), but JSON Schema does not declare a default value. LLMs may not infer the default and could pass no limit, causing unpredictable behavior.