MCP Server
The @peac/mcp-server package exposes PEAC Protocol as MCP tools. AI agents can verify receipts, inspect claims, decode tokens, issue new receipts, and create evidence bundles -- all through the standard Model Context Protocol interface.
The MCP server is extensively tested. Every tool handler, error path, and security boundary has coverage.
Install
npm install @peac/mcp-server
Quick start
npx peac-mcp-server
The server starts on stdio transport by default, ready for any MCP client.
Tools
The MCP server exposes 5 tools in two security tiers.
Pure tools
Available immediately, no secrets required.
| Tool | Input | Output |
|---|---|---|
peac_verify | Receipt JWS + issuer URL | Verification result with 12 checks |
peac_inspect | Receipt JWS | Decoded header, payload, metadata |
peac_decode | Raw JWS string | Base64url-decoded parts |
Privileged tools
Disabled by default. Require explicit capability configuration.
| Tool | Input | Output |
|---|---|---|
peac_issue | Claims + signing config | Signed receipt JWS |
peac_create_bundle | Receipt array + issuer | Evidence bundle file |
Set PEAC_MCP_PRIVILEGED=true and provide signing keys to enable peac_issue and peac_create_bundle.
Usage examples
Verify a receipt
{
"tool": "peac_verify",
"arguments": {
"receipt": "eyJhbGciOiJFZERTQSIs...",
"issuer_url": "https://api.example.com"
}
}
{
"verified": true,
"checks": [
{ "id": 1, "name": "signature_valid", "passed": true },
{ "id": 2, "name": "algorithm_allowed", "passed": true },
{ "id": 3, "name": "type_header_present", "passed": true }
],
"claims": {
"iss": "https://api.example.com",
"sub": "agent:claude-123",
"peac": { "type": "api.request", "status": "executed" }
},
"_meta": {
"serverVersion": "0.10.13",
"policyHash": "sha256:abc...",
"protocolVersion": "peac-receipt/0.1"
}
}
Inspect a receipt
{
"tool": "peac_inspect",
"arguments": {
"receipt": "eyJhbGciOiJFZERTQSIs..."
}
}
Returns the decoded header (alg, typ, kid), payload (all claims), and signature metadata without performing verification.
Issue a receipt
{
"tool": "peac_issue",
"arguments": {
"issuer": "https://api.example.com",
"subject": "agent:claude-123",
"type": "tool.call",
"attestation_type": "interaction",
"status": "executed"
}
}
Returns a signed JWS string ready for delivery.
Configuration
Environment variables
# Enable privileged tools
PEAC_MCP_PRIVILEGED=true
# Signing key for peac_issue
PEAC_PRIVATE_KEY=<base64url-ed25519-private-key>
PEAC_KID=peac-2026-02
# Optional: policy file path
PEAC_POLICY_PATH=/path/to/policy.json
Policy file
Fine-grained capability control:
{
"capabilities": {
"verify": true,
"inspect": true,
"decode": true,
"issue": false,
"bundle": false
},
"issuer": {
"url": "https://api.example.com",
"kid": "peac-2026-02"
}
}
Structured outputs
Every tool response includes _meta for traceability and auditability:
{
"_meta": {
"serverVersion": "0.10.13",
"policyHash": "sha256:<canonical-hash-of-loaded-policy>",
"protocolVersion": "peac-receipt/0.1"
}
}
The policyHash is deterministic -- same policy always produces the same hash.
Security model
The MCP server is designed with defense-in-depth:
| Measure | Description |
|---|---|
| No ambient key discovery | Keys must be explicitly configured via env vars |
| Static policy | Policy loaded at startup, never fetched at runtime |
| SSRF prevention | No outbound network requests from tool handlers |
| Buffer growth cap | Bounded memory allocation for all inputs |
| Capability-based access | Privileged tools require explicit opt-in |
| Handler-transport separation | Core logic is transport-neutral, tested independently |
Integration with Claude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"peac": {
"command": "npx",
"args": ["peac-mcp-server"],
"env": {
"PEAC_MCP_PRIVILEGED": "false"
}
}
}
}
Once configured, Claude can verify any PEAC receipt you paste into the conversation.