Veto/docs
Meow Gateway

Quickstart

Three minutes from install to a signed capsule flowing through a local MCP endpoint.

Goal: verifyReceiptChain returns ok: true against a chain you built on your own laptop, offline, in under three minutes.

0 · Prerequisites

  • Node 20+ (node --versionv20.x or higher)
  • That's it. No Meow sandbox token, no veto.so account.

1 · Run the offline demo (30s)

npx @veto/meow-gateway demo

This command does six things in one process:

  1. Generates an Ed25519 signing keypair under a temp dir
  2. Boots the gateway with the bundled ap_strict_v1 policy pack
  3. Upserts a bank beneficiary, computes its canonical hash
  4. Mints a signed Spend Capsule for meow.pay $500 ACH to Acme
  5. Consumes the capsule through a mock Meow upstream (no network)
  6. Fetches the per-entity receipt chain, runs verifyReceiptChain(), prints ok: true

Expected final output:

✓ Ed25519 capsule signed, verified, consumed
✓ Decision receipt chained off genesis
✓ Chain verified locally (no Veto-hosted service)

If you don't see that, something's wrong — please file a bug.

2 · Boot a persistent gateway (2 min)

Once the demo proves the pipeline, you probably want a gateway that sticks around.

# Generate signing keys once:
npx @veto/meow-gateway keygen

# Boot the server (defaults to localhost:3005):
npx @veto/meow-gateway start

The gateway serves:

  • GET /health + GET /ready
  • GET /.well-known/veto-keys.json — JWKS for your signing kid
  • POST /v1/capsules — mint
  • POST /v1/onboarding/applications — start a KYB application
  • POST /v1/routing/suggest — pick a rail
  • POST /meow/mcp — MCP server surface
  • POST /meow/consume — REST consume surface

3 · Mint a capsule via curl

curl -sX POST http://localhost:3005/v1/capsules \
  -H "content-type: application/json" \
  -d '{
    "entity_id": "ent_demo_0000000000000000",
    "agent_id": "agent_local",
    "tool": "meow.pay",
    "rail_allowlist": ["ach"],
    "counterparty_hash": "sha256:<hash>",
    "amount_ceiling": { "currency": "USD", "amount": "500.00" },
    "invoice_hash": "sha256:<invoice>",
    "workflow_id": "wf_demo0000000000000000abcd",
    "ttl_seconds": 300
  }'

Response includes the signed JWS. Inspect the three parts with any JWS decoder — the payload is the full canonical capsule.

4 · Consume it

curl -sX POST http://localhost:3005/meow/consume \
  -H "content-type: application/json" \
  -d '{
    "jws": "<paste JWS>",
    "tool": "meow.pay",
    "rail": "ach",
    "counterparty_hash": "sha256:<hash>",
    "amount": { "currency": "USD", "amount": "500.00" }
  }'

On allow, the response includes the upstream Meow result AND the newly-chained decision receipt.

5 · Connect veto.so (optional)

npx @veto/meow-gateway connect

This flips the gateway from local-only to hybrid mode: receipts and workflows still live locally (your disk is canonical), but a dashboard at veto.so/dashboard/meow mirrors them for team review + HITL approvals. Self-host stays sovereign — disconnecting is a single env var flip.

Where to go next