Continuous compliance evidence for AI agent memory. A transparent MCP proxy that generates tamper-evident audit trails.
Project description
╔══════════════════════════════════════════════════════════╗
║ ║
║ █████╗ ████████╗████████╗███████╗███████╗████████╗ ║
║ ██╔══██╗╚══██╔══╝╚══██╔══╝██╔════╝██╔════╝╚══██╔══╝ ║
║ ███████║ ██║ ██║ █████╗ ███████╗ ██║ ║
║ ██╔══██║ ██║ ██║ ██╔══╝ ╚════██║ ██║ ║
║ ██║ ██║ ██║ ██║ ███████╗███████║ ██║ ║
║ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ ╚═╝ ║
║ ███╗ ███╗ ██████╗██████╗ ║
║ ████╗ ████║██╔════╝██╔══██╗ ║
║ ██╔████╔██║██║ ██████╔╝ ║
║ ██║╚██╔╝██║██║ ██╔═══╝ ║
║ ██║ ╚═╝ ██║╚██████╗██║ ║
║ ╚═╝ ╚═╝ ╚═════╝╚═╝ ║
║ ║
╚══════════════════════════════════════════════════════════╝
Continuous compliance evidence for AI agent memory.
Your agents remember everything. Now prove it.
┌─────────────────────┐
│ │
Agent Client ────▶│ AttestMCP Proxy │────▶ Memory Server
│ │ (Mem0, Zep,
◀── response ◀───│ ┌───────────────┐ │◀── Anthropic KG,
unchanged │ │ 🔐 Identity │ │ Hindsight...)
│ │ 📋 Policy │ │
│ │ 🔗 Evidence │ │
│ └───────┬───────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ Audit DB │ │
│ │ SHA-256 │ │
│ │ chained │ │
│ └───────────┘ │
└─────────────────────┘
The Problem
AI agent memory servers store what agents know. None of them can prove what agents did with that knowledge. Without audit trails:
❌ No SOC 2 attestation for agent behavior
❌ Enterprise deals blocked at security review
❌ No answer when auditors ask "who accessed what, when?"
❌ Cyber insurance carriers want documented AI controls
What AttestMCP Does
✅ Zero modification Agents and memory servers work exactly as before
✅ Identity attribution Every operation tied to a verified agent/user
✅ Hash-chained evidence Tamper-evident records detect any modification
✅ SOC 2 mapping Evidence mapped to CC6.1 / CC6.3 / CC7.2 / CC8.1
✅ HTML reports Self-contained evidence you hand to an auditor
✅ Any MCP memory server Mem0, Anthropic KG, Zep, Hindsight, any
Quick Start
pip
pip install attestmcp
# Point to your memory server
export ATTESTMCP_UPSTREAM_URL="http://localhost:8000/mcp"
# Start the proxy
attestmcp serve
Docker
docker run -d \
-e ATTESTMCP_UPSTREAM_URL="http://host.docker.internal:8000/mcp" \
-v attestmcp-data:/data \
-p 8080:8080 \
attestmcp/proxy
Then point your agent's MCP config to the proxy instead of the memory server directly.
How It Works
Every MCP JSON-RPC call through the proxy generates a tamper-evident audit record:
{
"record_id": "0192e4a1-7b3c-7def-8a12-4f6789abcdef",
"timestamp": "2026-04-15T14:32:01.847392+00:00",
"agent_identity": {
"source": "oauth_jwt",
"user": "deploy-bot@acme.com",
"agent_name": "support-agent-v2",
"org": "acme-corp",
"verified": true,
"trust_level": "verified"
},
"method": "tools/call",
"tool_name": "search_memories",
"params_hash": "a1b2c3d4e5f6...",
"policy_decision": "allow",
"result_hash": "f6e5d4c3b2a1...",
"chain_hash": "9f8e7d6c5b4a..."
}
Records are hash-chained — each record's chain_hash = SHA-256(previous_chain_hash + canonical_json(record)). Modify, delete, or reorder any record and the entire chain breaks:
Record 1 Record 2 Record 3
┌──────────┐ ┌──────────┐ ┌──────────┐
│ data │ │ data │ │ data │
│ │ │ │ │ │
│ hash: ■──┼─────▶│ hash: ■──┼─────▶│ hash: ■ │
└──────────┘ └──────────┘ └──────────┘
▲
genesis: 0x000...
CLI
attestmcp serve # Start the proxy
attestmcp verify # Verify chain integrity
attestmcp export --since 2026-01-01 # Export as JSON lines
attestmcp report -o evidence.html # HTML report for auditors
Python API
from attestmcp.proxy import create_app
from attestmcp.store import SQLiteAuditStore
from attestmcp.report import generate_report
from attestmcp.soc2 import map_controls
SOC 2 Control Mapping
AttestMCP maps every audit record to specific Trust Services Criteria:
┌────────┬──────────────────────────────┬──────────────────────────┐
│ Control│ Name │ What AttestMCP proves │
├────────┼──────────────────────────────┼──────────────────────────┤
│ CC6.1 │ Logical Access Controls │ Identity on every record │
│ CC6.3 │ Access Authorization │ Policy decisions logged │
│ CC7.2 │ System Monitoring │ Continuous audit trail │
│ CC8.1 │ Change Management │ Tamper-evident chain │
└────────┴──────────────────────────────┴──────────────────────────┘
Architecture
┌─────────────────────────────────────────────────────────┐
│ AttestMCP Proxy │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌────────────────┐ │
│ │ FastAPI │ │ Identity │ │ Prometheus │ │
│ │ POST /mcp │ │ JWT/JWKS │ │ GET /metrics │ │
│ └──────┬───────┘ └──────┬──────┘ └────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ Audit Pipeline │ │
│ │ parse → identify → hash → chain │ │
│ └──────────────┬───────────────────┘ │
│ │ │
│ ┌──────────────▼───────────────────┐ │
│ │ SQLite + WAL │ │
│ │ Synchronous writes │ │
│ │ SHA-256 hash chain │ │
│ └──────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────┐ │
│ │ httpx async → upstream │ │
│ │ Zero payload modification │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Configuration
All via environment variables (prefix ATTESTMCP_):
Variable Default Description
─────────────────────────────────────────────────────────────────────
ATTESTMCP_UPSTREAM_URL http://localhost:8000/mcp Memory server
ATTESTMCP_HOST 0.0.0.0 Bind address
ATTESTMCP_PORT 9090 Listen port
ATTESTMCP_DB_PATH attestmcp_audit.db SQLite path
ATTESTMCP_JWKS_URL (none) JWKS endpoint
ATTESTMCP_JWT_AUDIENCE (none) JWT audience
ATTESTMCP_JWT_ISSUER (none) JWT issuer
Development
git clone https://github.com/attestmcp/attestmcp.git
cd attestmcp
python3.12 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest -v # 107 tests including tamper detection
ruff check src/ tests/
mypy src/
Status
██████████████████████████████████████░░░░ Phase 1 Complete
✅ Shipped
- Core data models and canonical serialization (FROZEN spec)
- Hash-chained SQLite audit store with tamper detection
- MCP proxy (FastAPI + httpx transparent forwarding)
- JWT identity extraction (anonymous / claimed / verified)
- Prometheus observability metrics
- Evidence export (JSON lines)
- HTML evidence report generator
- SOC 2 control mapping (CC6.1, CC6.3, CC7.2, CC8.1)
- CLI (
attestmcp serve | verify | export | report) - Dockerfile (multi-stage, non-root, healthcheck)
🔜 Roadmap
- Live integration tests with Mem0 + Anthropic KG Memory
- OPA policy engine integration
- SSE streaming response support
- Drata / Vanta evidence push
- Multi-tenant PostgreSQL backend
License
Apache 2.0 — see LICENSE.
Built for the teams who hear:
"We love your AI product, but we can't pass security review."
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file attestmcp-0.1.0.tar.gz.
File metadata
- Download URL: attestmcp-0.1.0.tar.gz
- Upload date:
- Size: 39.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6e7f5e896406654065541a6df974a8bedd2164b64c988e42a26678dbe7601f45
|
|
| MD5 |
0f9b07be0f0c33697abf0f9648bae79b
|
|
| BLAKE2b-256 |
eed0bf77c101fcde465670c176fba6d816a9b90a257d161e80d5bb82d47baf92
|
File details
Details for the file attestmcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: attestmcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 32.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca5601684c68072a5d3bd1a93b841d92968eed857bc5a6db57e774d63e33bdd6
|
|
| MD5 |
43383388ad042688cfd80102c0029375
|
|
| BLAKE2b-256 |
41d38fc93bf17e01600c4ab14a58e279c6b2a49b77f4c2d2f7e38d1942c65bf8
|