The problem: MCP tool calls are invisible
Model Context Protocol (MCP) is quickly becoming the standard way AI agents interact with tools. Your agent calls search_web, send_email, query_database -- each one triggers a real action on a real system.
But MCP has a blind spot: there is no built-in mechanism to prove what actually happened during a tools/call.
Your MCP server logs say the tool ran. Your client trusts that. But if something goes wrong -- a payment is disputed, a wrong email is sent, an audit asks "what did the agent do on March 3rd?" -- you're relying on the same system that executed the action to tell you what happened.
That's self-reporting, not auditability.
What OWASP says about this
The OWASP Top 10 for Agentic Applications (2026) lists inadequate logging and monitoring as a top risk for AI agent systems. The prescribed mitigation? Signed audit logs per tool call.
Not "more logs." Signed, tamper-evident records that an independent party can verify.
This maps directly to what we call an Agent Action Receipt (AAR): a cryptographic proof that tool X was called with arguments Y and returned result Z, at a certified time, signed by a neutral third party.
Before and after
Here is a typical MCP server that calls two external APIs:
# your_mcp_server.py -- BEFORE
import httpx
from mcp.server import Server
server = Server("my-tools")
@server.call_tool()
async def handle_tool(name: str, arguments: dict):
if name == "search_web":
resp = await httpx.post(
"https://search-api.example.com/search",
json=arguments
)
return resp.json()
if name == "send_email":
resp = await httpx.post(
"https://mail-api.example.com/send",
json=arguments
)
return resp.json()
Your agent calls these tools. The calls happen. You have logs on your server. But nothing independently proves what was sent, what was received, or when.
Now, the same server with cryptographic receipts:
# your_mcp_server.py -- AFTER
import httpx
from mcp.server import Server
TRUST_LAYER = "https://trust.arkforge.tech/v1/proxy"
API_KEY = "mcp_free_xxxx..." # free: 500 proofs/month, no card
server = Server("my-tools")
async def certified_call(target: str, payload: dict, tool_name: str) -> dict:
"""Route any outbound call through Trust Layer. Returns the upstream response."""
resp = await httpx.post(
TRUST_LAYER,
headers={
"X-Api-Key": API_KEY,
"X-Agent-Identity": tool_name,
},
json={
"target": target,
"method": "POST",
"payload": payload,
"description": f"MCP tool call: {tool_name}",
},
timeout=30,
)
result = resp.json()
# result["proof"]["id"] -> publicly verifiable receipt
return result["response"]
@server.call_tool()
async def handle_tool(name: str, arguments: dict):
if name == "search_web":
return await certified_call(
"https://search-api.example.com/search", arguments, "search_web"
)
if name == "send_email":
return await certified_call(
"https://mail-api.example.com/send", arguments, "send_email"
)
What changed: One helper function. One line difference per tool. Every outbound call now produces a signed, timestamped receipt.
What each receipt contains
Every Agent Action Receipt (AAR) includes:
| Field | What it proves |
|---|---|
request_hash |
SHA-256 of the exact payload sent to the upstream API |
response_hash |
SHA-256 of the exact response received |
timestamp |
RFC 3161 certified by an independent Timestamp Authority |
signature |
Ed25519, verifiable with ArkForge's public key (GET /v1/pubkey) |
rekor_log_id |
Entry in Sigstore Rekor, a public append-only transparency log |
Three independent witnesses for every tool call: ArkForge's signature, an external TSA, and a public transparency log. No single point of trust.
Why this matters for multi-agent systems
In a single-model setup, you might get away with trusting your own logs. In a multi-agent architecture -- where Claude orchestrates, Mistral handles retrieval, and a custom model runs analysis -- no single provider can certify the full chain.
AWS certifies AWS calls. Anthropic certifies Claude calls. But when your agent chains calls across three providers and two cloud platforms, who certifies the handoffs?
A neutral proxy that works across any model, any provider, any infrastructure. That's the gap.
The more heterogeneous your agent stack, the more this matters. Multi-agent system adoption is growing at a 48.5% CAGR (Grand View Research). The auditability gap grows with it.
Getting started
Step 1: Get a free API key (no card required)
curl -X POST https://trust.arkforge.tech/v1/keys/free-signup \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com"}'
# -> {"api_key": "mcp_free_xxxx...", "plan": "free", "limit": "500 proofs/month"}
Step 2: Add the certified_call helper to your MCP server (code above)
Step 3: Verify any receipt
curl https://trust.arkforge.tech/v1/proof/prf_20260303_161853_4d0904
Every proof has a public HTML page with a color-coded verification badge. Share it with your client, your compliance team, or your auditor.
The compliance angle
If you're building agents that fall under EU AI Act (Article 12: logging for high-risk AI), DORA (Article 11: ICT incident management), or NIS2 (Article 21: traceability), signed audit logs are not optional -- they're prescribed.
OWASP's Top 10 for Agentic Applications specifically calls out the need for signed, per-tool-call audit trails. An AAR satisfies this requirement with zero changes to your MCP client and minimal changes to your server.
What this is not
This is not a replacement for your application logs. Keep those. This is an independent, third-party attestation layer that sits alongside your logs and gives them teeth.
Your logs say what happened. An AAR proves it.
ArkForge Trust Layer is open-source (MIT). Free tier: 500 proofs/month, no card required. GitHub | Live API
Top comments (0)