Skip to content
v0.11.2Since v0.10.13

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 KeyValuePurpose
org.peacprotocol/receipt_refsha256:<hex>Content-addressable receipt reference; sha256(receipt_jws)
org.peacprotocol/receipt_jwsCompact JWS stringThe signed receipt (EdDSA, peac-receipt/0.1 type)

JSON-RPC Response Example

A tool response carrying a PEAC receipt in _meta:

MCP tool responseJSON-RPC
{
  "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.

verify-ref.tsTypeScript
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.

HTTP response header
PEAC-Receipt: eyJhbGciOiJFZERTQSIsInR5cCI6InBlYWMtcmVjZWlwdC8wLjEifQ...

Size Limits

TransportCarrier LocationMax Size
stdio / JSON-RPC_meta fields64 KB (embed)
Streamable HTTPPEAC-Receipt header8 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

embed.tsTypeScript
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

extract.tsTypeScript
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.