MCP Integration
Carry verifiable interaction evidence through MCP tool responses using the Evidence Carrier Contract. Receipt references and compact JWS signatures travel in standard _meta fields, compatible with any MCP server or client.
Package: @peac/mappings-mcp
Install
pnpm add @peac/mappings-mcp
How It Works
The MCP evidence carrier attaches receipts to tool responses using two reserved keys in the JSON-RPC _meta object. The receipt reference is a SHA-256 hash of the compact JWS, enabling integrity verification at extraction time.
| _meta Key | Value | Purpose |
|---|---|---|
org.peacprotocol/receipt_ref | sha256:<hex> | Content-addressable receipt reference; sha256(receipt_jws) |
org.peacprotocol/receipt_jws | Compact JWS string | The signed receipt (EdDSA, peac-receipt/0.1 type) |
JSON-RPC Response Example
A tool response carrying a PEAC receipt in _meta:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "Tool output here"
}
],
"_meta": {
"org.peacprotocol/receipt_ref": "sha256:abc123...",
"org.peacprotocol/receipt_jws": "eyJhbGciOiJFZERTQSIsInR5cCI6InBlYWMtcmVjZWlwdC8wLjEifQ..."
}
}
}Integrity Verification
At extraction time, the consumer verifies that sha256(receipt_jws) == receipt_ref (DD-129). This ensures the JWS was not modified in transit. The receipt signature is then verified separately against the issuer's public key.
import { computeReceiptRef } from '@peac/schema';
const meta = response.result._meta;
const jws = meta['org.peacprotocol/receipt_jws'];
const ref = meta['org.peacprotocol/receipt_ref'];
// Verify receipt_ref matches the JWS content
const computed = computeReceiptRef(jws);
if (computed !== ref) {
throw new Error('receipt_ref mismatch: JWS was modified in transit');
}HTTP Transport
When using MCP Streamable HTTP transport, receipts can also be carried in the PEAC-Receipt HTTP header as a compact JWS. This is subject to the 8 KB HTTP header size limit.
PEAC-Receipt: eyJhbGciOiJFZERTQSIsInR5cCI6InBlYWMtcmVjZWlwdC8wLjEifQ...
Size Limits
| Transport | Carrier Location | Max Size |
|---|---|---|
| stdio / JSON-RPC | _meta fields | 64 KB (embed) |
| Streamable HTTP | PEAC-Receipt header | 8 KB (header) |
Security
Session Isolation
Each Streamable HTTP client receives an isolated McpServer instance with its own transport. This prevents cross-client state leakage (CVE-2026-25536 defense).
No Implicit Fetch (DD-55)
URLs in receipt fields (such as receipt_url) are locator hints only. The server and mapping layer never fetch URLs automatically, preventing SSRF.
Receipt Reference Binding (DD-129)
The receipt_ref is always sha256(receipt_jws). Extractors verify this before trusting the JWS content, preventing substitution attacks.
Embedding a Receipt
import { embedReceiptInMeta } from '@peac/mappings-mcp';
const toolResult = {
content: [{ type: 'text', text: 'Tool output here' }],
};
// Attach receipt to the tool response _meta
const resultWithEvidence = embedReceiptInMeta(toolResult, {
receipt_jws: 'eyJhbGciOiJFZERTQSIs...',
});
// resultWithEvidence._meta contains:
// "org.peacprotocol/receipt_ref": "sha256:..."
// "org.peacprotocol/receipt_jws": "eyJhbGciOiJFZERTQSIs..."Extracting a Receipt
import { extractReceiptFromMeta } from '@peac/mappings-mcp';
const carrier = extractReceiptFromMeta(response.result._meta);
if (carrier) {
console.log('Receipt ref:', carrier.receipt_ref);
console.log('Receipt JWS:', carrier.receipt_jws);
// Verify: sha256(receipt_jws) must match receipt_ref
// Then verify the JWS signature against the issuer's public key
}Links
Evidence Carrier Contract
The MCP integration implements the PeacEvidenceCarrier type and CarrierAdapter pattern shared across all PEAC integrations. The same receipt can travel through MCP, A2A, ACP, UCP, x402, and HTTP without coupling to any single transport.