╔══════════════════════════════════════════════════════════╗
║ ║
║ █████╗ ████████╗████████╗███████╗███████╗████████╗ ║
║ ██╔══██╗╚══██╔══╝╚══██╔══╝██╔════╝██╔════╝╚══██╔══╝ ║
║ ███████║ ██║ ██║ █████╗ ███████╗ ██║ ║
║ ██╔══██║ ██║ ██║ ██╔══╝ ╚════██║ ██║ ║
║ ██║ ██║ ██║ ██║ ███████╗███████║ ██║ ║
║ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ ╚═╝ ║
║ ███╗ ███╗ ██████╗██████╗ ║
║ ████╗ ████║██╔════╝██╔══██╗ ║
║ ██╔████╔██║██║ ██████╔╝ ║
║ ██║╚██╔╝██║██║ ██╔═══╝ ║
║ ██║ ╚═╝ ██║╚██████╗██║ ║
║ ╚═╝ ╚═╝ ╚═════╝╚═╝ ║
║ ║
╚══════════════════════════════════════════════════════════╝
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."
Metadata
Release files for attestmcp 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| attestmcp-0.1.0.tar.gz | 39.6 kB | Without provenance | Details for attestmcp-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| attestmcp-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for attestmcp-0.1.0-py3-none-any.whl |
Total release size: 71.9 kB
Release files / attestmcp-0.1.0.tar.gz
| Download URL | attestmcp-0.1.0.tar.gz |
|---|---|
| Size | 39.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6e7f5e896406654065541a6df974a8bedd2164b64c988e42a26678dbe7601f45
|
|
BLAKE2b-256 checksum How to use checksums |
eed0bf77c101fcde465670c176fba6d816a9b90a257d161e80d5bb82d47baf92
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / attestmcp-0.1.0-py3-none-any.whl
| Download URL | attestmcp-0.1.0-py3-none-any.whl |
|---|---|
| Size | 32.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ca5601684c68072a5d3bd1a93b841d92968eed857bc5a6db57e774d63e33bdd6
|
|
BLAKE2b-256 checksum How to use checksums |
41d38fc93bf17e01600c4ab14a58e279c6b2a49b77f4c2d2f7e38d1942c65bf8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Security for attestmcp 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.