audit-ledger-mcp
Description
Tamper-evident audit logging for AI decisions. Three tools (record_decision, verify_decision, list_decisions) write to a regulator-grade ledger built on AWS S3 Object Lock with 7-year retention. Designed for EU AI Act Article 12 and FCA SS1/23 evidence requirements. Try…
About
Tamper-evident audit logging for AI decisions. Three tools (record_decision, verify_decision, list_decisions) write to a regulator-grade ledger built on AWS S3 Object Lock with 7-year retention. Designed for EU AI Act Article 12 and FCA SS1/23 evidence requirements. Try zero-config: `npx audit-ledger-mcp` boots in…
Details
- Author
- shahidh68
- Categories
- Finance, Security, File Management, Other
Jump to
Setup
Install audit-ledger-mcp in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/shahidh68/audit-ledger-mcp
Follow the installation instructions in the repository README, then restart your MCP client.
Connect Claude, Cursor, LangGraph, or your own agent to theAI Audit Ledger.This MCP server gives an agent the tools to record, check, and list decisions in a tamper-evident log with one line of config.
It is built for teams that need a clear record of AI decisions: EU AI Act Article 12 logging, FCA SS1/23 model risk evidence, and GDPR data minimisation. Raw personal data is hashed locally before anything is sent, so the ledger only sees fingerprints.
The AI Audit Ledger family.This MCP server writes decisions to theledger, which proves what happened and whether the record was changed. TheAI Decision Evidence Hubsits above the ledger, read-only. It turns each lightweight decision record into an audit case file by showing what evidence is present, what is still missing, who owns each gap, and the current readiness score. Family:audit-ledger·audit-ledger-mcp·evidence-hub.
Try the live dashboard →· 30 synthetic decisions written via this MCP server, queryable and verifiable.
A LangGraph workflow callsrecord_decisionafter each agent step. Three audit events written to the live ledger; every one independently verifiable.
Exposes four tools to any MCP-compatible agent:
Each call ends up as a regulator-grade audit record in your deployed ledger — DynamoDB for query, S3 Object Lock COMPLIANCE mode for the immutable copy, 7-year retention by default.
That's it. With no environment variables, the server boots intosandbox modeand writes records to a shared public tenant on a hosted ledger. You can try every tool —record_decision,verify_decision,verify_completeness,list_decisions— without provisioning anything.
When sandbox mode is active, you'll see a banner on stderr:
[audit-ledger-mcp] ─────────────── SANDBOX MODE ─────────────── [audit-ledger-mcp] No AUDIT_API_URL configured. [audit-ledger-mcp] Using the public sandbox at sandbox-public. [audit-ledger-mcp] View: https://d2pfirb2397ixy.cloudfront.net [audit-ledger-mcp] Do NOT write real personal data...
Wire it into Claude Desktop with zero config
{ "mcpServers": { "audit-ledger-sandbox": { "command": "npx", "args": ["-y", "audit-ledger-mcp"] } } }
Restart Claude Desktop. The four tools appear in the MCP menu immediately. Try asking Claude to "record this decision: should X be approved?" and watch a record land in the sandbox dashboard.
For real workloads, deploy your own audit ledger and point the MCP server at it:
Configure with the API URL plus your tenant keys (any of them being set switches off sandbox mode).AUDIT_HMAC_KEYis technically optional for backwards compatibility but strongly recommended — see the note above the value below:
export AUDIT_API_URL="https://<api-id>.execute-api.<region>.amazonaws.com/prod" export AUDIT_WRITE_KEY="<your-tenant-write-key>" export AUDIT_READ_KEY="<your-tenant-read-key>" # Strongly recommended. Tenant-held secret used to HMAC PII and prompts # locally before sending. Generate once, store next to AUDIT_WRITE_KEY: # node -e "console.log(require('crypto').randomBytes(32).toString('hex'))" # If unset, the MCP falls back to plain SHA-256 and warns once (back-compat). export AUDIT_HMAC_KEY="<your-tenant-hmac-secret>" # Optional export AUDIT_TIMEOUT_MS=5000 # default 5000 export AUDIT_RETRY_ATTEMPTS=3 # default 3
The full template lives in.env.example.
Edit yourclaude_desktop_config.json(macOS:~/Library/Application Support/Claude/claude_desktop_config.json, Windows:%APPDATA%\Claude\claude_desktop_config.json):
{ "mcpServers": { "audit-ledger": { "command": "npx", "args": ["-y", "audit-ledger-mcp"], "env": { "AUDIT_API_URL": "https://<api-id>.execute-api.<region>.amazonaws.com/prod", "AUDIT_WRITE_KEY": "<your-tenant-write-key>", "AUDIT_READ_KEY": "<your-tenant-read-key>", "AUDIT_HMAC_KEY": "<your-tenant-hmac-secret>" } } } }
AUDIT_HMAC_KEYis the tenant secret used to keyed-hash PII locally before any payload leaves the MCP server process. Generate it once withnode -e "console.log(require('crypto').randomBytes(32).toString('hex'))"and store the result in theenvblock above. The MCP never transmits this value, only reads it.
Restart Claude Desktop. You'll see "audit-ledger" in the MCP tools menu. Ask Claude something like"Record this decision: I declined the application because…"and watch it callrecord_decisionautomatically.
{ "mcpServers": { "audit-ledger": { "command": "npx", "args": ["-y", "audit-ledger-mcp"], "env": { "AUDIT_API_URL": "https://<api-id>.execute-api.<region>.amazonaws.com/prod", "AUDIT_WRITE_KEY": "<your-tenant-write-key>", "AUDIT_READ_KEY": "<your-tenant-read-key>", "AUDIT_HMAC_KEY": "<your-tenant-hmac-secret>" } } } }
from langchain_mcp_adapters.client import MultiServerMCPClient from langgraph.prebuilt import create_react_agent from langchain_anthropic import ChatAnthropic import os client = MultiServerMCPClient({ "audit-ledger": { "command": "npx", "args": ["-y", "audit-ledger-mcp"], "transport": "stdio", "env": { "AUDIT_API_URL": os.environ["AUDIT_API_URL"], "AUDIT_WRITE_KEY": os.environ["AUDIT_WRITE_KEY"], "AUDIT_READ_KEY": os.environ["AUDIT_READ_KEY"], "AUDIT_HMAC_KEY": os.environ["AUDIT_HMAC_KEY"], }, } }) tools = await client.get_tools() agent = create_react_agent( ChatAnthropic(model="claude-sonnet-4-7-20251022"), tools, ) # The agent can now call record_decision, verify_decision, verify_completeness, list_decisions result = await agent.ainvoke({ "messages": [{"role": "user", "content": "Triage this loan application…"}] })
AUDIT_API_URL=... AUDIT_WRITE_KEY=... AUDIT_READ_KEY=... AUDIT_HMAC_KEY=... npx -y audit-ledger-mcp
The server speaks MCP over stdio. Sendinitialize,tools/list, andtools/callrequests per theMCP specification.
Agent audit-ledger-mcp AWS (your ledger) | | | |--- record_decision ----->| | | raw_user_input | (hash locally — no PII over | | raw_system_prompt | the wire from this point) | | decision_output | | | human_in_loop | | | |--- HTTPS POST /audit/events --->| | | {hashes + decision + | | | x-api-key} | | | | | |<--- 202 Accepted ---------------| | | { event_id, ... } | |<--- event_id ------------| | | recorded_at | | | note | |
Storage on the AWS side happens asynchronously through SQS → Processor Lambda → DynamoDB + S3 Object Lock. See themain repo's ARCHITECTURE.mdfor the full path.
Returns the DynamoDB record, the S3 record, andintegrity_verified: true/false.
Detect missing records. Sister tool toverify_decision: that one proves a record that exists has not been altered; this one proves no records have been deleted.
Returns the requested range, the expected vs found count, the list of missing sequence numbers, and a human-readable note.
{ "tenant_id": "acme-prod", "range": { "from": 1, "to": 142 }, "expected_count": 142, "found_count": 140, "missing": [47, 91], "note": "Found 2 missing sequence number(s) in range. Each gap represents a deleted, lost, or never-written record. Cross-check against burned_sequence log entries before treating as a deletion." }
List recent decisions for the calling tenant.
…
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.
