| Protocol site & spec | agentreceipts.ai |
| Tooling docs | obsigna.dev |
| Daemon setup & migration guide | obsigna.dev/getting-started/daemon-setup/ |
| API reference | Go · TypeScript · Python |
| Blog | Your AI Agent Just Sent an Email · Every MCP Tool Call My AI Makes Now Gets a Signed Receipt |
| Go | sdk/go · mcp-proxy · dashboard |
| npm | @obsigna/sdk-ts |
| PyPI | obsigna |
Agent Receipts is an open protocol for producing cryptographically signed, tamper-evident records of AI agent actions. It defines the receipt format, signing scheme, chain structure, and taxonomy of action types. Anyone can implement it — in any language, in any runtime.
Obsigna is the reference toolset that implements the protocol:
| Tool | What it does |
|---|---|
obsigna-mcp |
MCP stdio proxy — signs every tool call, adds policy hooks |
obsigna-daemon |
Out-of-process signing daemon — holds the key, owns the audit chain |
obsigna-hook |
PostToolUse hook for Claude Code and other runtimes |
obsigna |
CLI for browsing and verifying receipt databases |
sdk/go, @obsigna/sdk-ts, obsigna (Python) |
SDKs for embedding receipt creation in your own code |
Both paths below require the daemon — it holds the signing key and owns the audit chain. Install it first:
brew install agent-receipts/tap/obsigna
obsigna daemon startFastest path — PostToolUse hook (Claude Code): one config snippet and every tool call gets a signed receipt automatically:
{
"hooks": {
"PostToolUse": [{ "matcher": "", "hooks": [{ "type": "command", "command": "obsigna-hook" }] }]
}
}Add that to ~/.claude/settings.json, then inspect the audit trail:
obsigna list
obsigna show <seq>
obsigna verifyMore control — MCP proxy: wraps any MCP server and adds policy hooks and risk scoring on top of signed receipts:
| Project | Description |
|---|---|
spec/ |
Protocol specification, JSON schemas, governance |
sdk/go/ |
Go SDK |
sdk/ts/ |
TypeScript SDK |
sdk/py/ |
Python SDK |
daemon/ |
Signing daemon — out-of-process key custody, shared audit chain |
mcp-proxy/ |
MCP proxy with receipt signing, policy engine, intent tracking |
hook/ |
PostToolUse hook binary for Claude Code and other runtimes |
cross-sdk-tests/ |
Cross-language verification tests |
docs/adr/ |
Architecture Decision Records |
| dashboard | Local web UI for browsing and verifying receipt databases |
| openclaw | Agent Receipts plugin for OpenClaw |
Choose your trust model. The snippets below keep the signing key inside the agent process — a deliberate deployment model where the agent host is trusted and tamper-evidence is aimed at downstream parties. In this model, anyone with code execution in the agent can forge receipts. To defend against a compromised agent, use the daemon-mediated path, where a separate daemon owns the key and your app only sends events over a socket. See the Trust Model page for the full spectrum (in-process → daemon-isolated → HSM/KMS).
go get github.com/agent-receipts/ar/sdk/goimport "github.com/agent-receipts/ar/sdk/go/receipt"
keys, _ := receipt.GenerateKeyPair()
unsigned := receipt.Create(receipt.CreateInput{
Issuer: receipt.Issuer{ID: "did:agent:my-agent"},
Principal: receipt.Principal{ID: "did:user:alice"},
Action: receipt.Action{Type: "filesystem.file.read", RiskLevel: receipt.RiskLow},
Outcome: receipt.Outcome{Status: receipt.StatusSuccess},
Chain: receipt.Chain{Sequence: 1, ChainID: "chain_1"},
})
signed, _ := receipt.Sign(unsigned, keys.PrivateKey, "did:agent:my-agent#key-1")npm install @obsigna/sdk-tsimport {
createReceipt,
generateKeyPair,
signReceipt,
} from "@obsigna/sdk-ts";
const keys = generateKeyPair();
const unsigned = createReceipt({
issuer: { id: "did:agent:my-agent" },
principal: { id: "did:user:alice" },
action: { type: "filesystem.file.read", risk_level: "low" },
outcome: { status: "success" },
chain: { sequence: 1, previous_receipt_hash: null, chain_id: "chain_1" },
});
const signed = signReceipt(unsigned, keys.privateKey, "did:agent:my-agent#key-1");pip install obsignafrom obsigna import (
create_receipt, generate_key_pair, sign_receipt,
CreateReceiptInput, Issuer, Principal, Outcome, Chain,
)
from obsigna.receipt.create import ActionInput
keys = generate_key_pair()
unsigned = create_receipt(CreateReceiptInput(
issuer=Issuer(id="did:agent:my-agent"),
principal=Principal(id="did:user:alice"),
action=ActionInput(type="filesystem.file.read", risk_level="low"),
outcome=Outcome(status="success"),
chain=Chain(sequence=1, previous_receipt_hash=None, chain_id="chain_1"),
))
signed = sign_receipt(unsigned, keys.private_key, "did:agent:my-agent#key-1")See the Python SDK README for the full quick start and daemon delivery.
See CONTRIBUTING.md for development setup and PR guidelines.
See SECURITY.md to report vulnerabilities. The threat model documents trust boundaries, in-scope and out-of-scope threats, and the mitigation roadmap.
Apache License 2.0 -- see LICENSE.
The protocol specification in spec/ is licensed under MIT.