Skip to main content

License: MIT IETF Draft PyPI

protect-mcp-adk

Ed25519 receipt signing plugin for Google ADK agents. Every tool call produces a cryptographic receipt following the IETF Internet-Draft format.

Install

pip install protect-mcp-adk

Usage

from google.adk import Agent
from google.adk.tools import FunctionTool
from protect_mcp_adk import ReceiptPlugin, ReceiptSigner

# Generate signing keys (or load from file)
signer = ReceiptSigner.generate()

# Add the plugin to your agent
agent = Agent(
    model="gemini-2.0-flash",
    tools=[FunctionTool(my_tool)],
    plugins=[ReceiptPlugin(signer, auto_export_path="receipts.jsonl")],
)

# After execution, verify the receipt chain:
# npx @veritasacta/verify@0.2.5 receipts.jsonl --key <public-key-hex>

What It Does

Every tool call your ADK agent makes produces a signed receipt:

{
  "payload": {
    "type": "protectmcp:decision",
    "spec": "draft-farley-acta-signed-receipts-01",
    "tool_name": "search",
    "tool_input_hash": "sha256:ff7e27...",
    "decision": "allow",
    "output_hash": "sha256:a3f8c9...",
    "issued_at": "2026-04-06T21:30:00.000Z",
    "session_id": "sess_a1b2c3d4e5f6",
    "sequence": 1,
    "previousReceiptHash": null,
    "agent_name": "research_agent",
    "invocation_id": "inv_xyz"
  },
  "signature": {
    "alg": "EdDSA",
    "kid": "sb:adk:de073ae64e43",
    "sig": "3da3162da83e..."
  }
}

Privacy-preserving: Tool inputs and outputs are SHA-256 hashed, not stored raw. The receipt proves what happened without exposing what was said.

Chain-linked: Each receipt includes previousReceiptHash, creating a tamper-evident chain. If any receipt is modified or removed, the chain breaks.

Offline verifiable: Receipts verify without contacting any server:

npx @veritasacta/verify@0.2.5 receipts.jsonl --key <public-key-hex>
# Exit 0 = valid, 1 = invalid (tampered), 2 = error (malformed)

API

ReceiptSigner

# Generate a new keypair
signer = ReceiptSigner.generate()

# Load from a key file
signer = ReceiptSigner.from_key_file("keys/agent.json")

# Save keys for reuse
signer.save_key("keys/agent.json")

# Access public key (for verification)
print(signer.public_key_hex)
print(signer.kid)

ReceiptPlugin

plugin = ReceiptPlugin(
    signer,
    auto_export_path="receipts.jsonl",  # Auto-export as receipts are produced
    log_receipts=True,                   # Log each receipt to Python logger
)

# After execution
print(plugin.receipt_count)
plugin.export_receipts("audit-bundle.jsonl")
print(plugin.get_verification_command())

Plugin Callbacks

Callback When What it signs
after_tool_callback After every tool execution Tool name, input hash, output hash, decision
on_tool_error_callback On tool execution error Tool name, input hash, error reason
before_tool_callback Before tool execution Override for policy evaluation (Cedar)

Interoperability

Receipts produced by this plugin verify against the same tooling as:

Three independent implementations have been verified to produce interoperable receipts.

Algorithm Note

This plugin uses Ed25519 (RFC 8032) for signing. The receipt envelope's signature.alg field supports algorithm negotiation. For environments requiring post-quantum signatures (NIST FIPS 204), the same envelope format works with ML-DSA-65 by changing the alg field. See the IETF draft for algorithm agility details.

Related

Metadata

Release files for protect-mcp-adk 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for protect-mcp-adk 0.1.0
File Size Uploaded
protect_mcp_adk-0.1.0.tar.gz 9.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for protect-mcp-adk 0.1.0
File Interpreter ABI Platform
protect_mcp_adk-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 18.2 kB

Release files / protect_mcp_adk-0.1.0.tar.gz

Download URL protect_mcp_adk-0.1.0.tar.gz
Size 9.2 kB
Tags Source
SHA-256 checksum
How to use checksums
88c474850f196b4f676d831cec8e1c2dbc8d8c49e498f03127ef046a3d0c6d87
BLAKE2b-256 checksum
How to use checksums
aa6b11add042fb414c17a2238bac2bba7f717835a4c7c2d7231eb4cd736c5b06
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release files / protect_mcp_adk-0.1.0-py3-none-any.whl

Download URL protect_mcp_adk-0.1.0-py3-none-any.whl
Size 9.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
161f4f9e30b3dab67885ce56957740f610d8fa9f046ef8684f2c823823573dea
BLAKE2b-256 checksum
How to use checksums
da53544ccb2cf55090480c0af2f82ff1cb46f83d669744ddb991968ca05429d6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.3

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page