payments.initiate, then query audit.stream to confirm the event landed. This is the canonical path every production agent should follow.
Audience: agent authors who want to go beyond quickstart toy calls.
Prerequisites
- The axtior-neobank repo cloned locally with
pnpm installrun at the root. apps/mcprunning onlocalhost:3001(default port fromapps/mcp/src/server.ts).- Node 22+ and pnpm.
- A Glide OAuth client with
payments:initiateandaudit:streamscopes.
Steps
1. Clone the example
2. Set environment variables
3. Define the policy envelope (src/0-policy.ts)
AgentPolicyEnvelope is the 14-axis object evaluated by @glideco/policy-engine on every
agent tool call. All amount caps are integer cents (not dollar strings).
policy_id— stable UUID across version bumps;(vault_id, policy_id)is unique.policy_version— monotonic counter; cache invalidation key for the policy engine.amount_cap_cents_*— absent means no cap on that axis; the engine still evaluates other gates.counterparty_allowlist— non-empty array closes the gate (only listed counterparties allowed); empty array (or omitted) means no counterparty restriction. Match the source semantics inpolicy-engine/src/evaluate.ts.
4. Issue a scoped grant (src/1-grant.ts)
In production, your agent runtime calls the OAuth AS with client_credentials to get a
JWT. The mock below shows the shape the AS issues.
sub+act.sub— human principal and the agent acting on their behalf (RFC 8693 actor claim).aud.vault_id+aud.entity_id— both required; the gateway checks tenant isolation on every call.policy_version— pinned at issuance; the verifier re-checks against the live policy on each call.- Max TTL is 3600 seconds (enforced by
grantClaimsValidatedSchema).
5. Call payments.initiate and inspect the Receipt (src/2-pay.ts)
The MCP gateway runs on three category-scoped endpoints. Write tools live on /mcp/write.
paymentsInitiateOutput):
kind—accepted(enqueued) orpending_step_up(caller must complete biometric step-up first).pending_payment_id— UUID of the row inagent_pending_payments. Correlate withaudit.streamevents as they arrive.policy_version— pinned at evaluate time; the live policy may have advanced by settle time.risk_verdict—alloworallow_with_step_up. Deny verdicts come back as JSON-RPC errors, not as outputs.enqueued_at— when the gateway accepted the call.
Receipt row lands in activity_log and an AgentActivityEvent is emitted to the SSE audit stream. The fields you’ll read off the receipt:
receipt_id— primary key; use this to correlate againstaudit.streamevents.on_chain_tx— server-fetched from chain RPC, never from a facilitator response body (F1).risk_verdict—allow | allow_with_step_up. Denied calls do not produce receipts.vendor_used— connector slug that settled the tx (matchesConnectorManifest.slug).
payments.initiate returns JSON-RPC error code -32003 with step_up_url,
open that URL in the user’s browser, wait for Privy WebAuthn to complete,
then retry the call with the same idempotency_key.
6. Subscribe to the audit stream (src/3-audit.ts)
Read tools live on /mcp/read. audit.stream returns an sse_url and cursor — connect to the URL with EventSource (or any SSE client) to receive AgentActivityEvent rows as they’re written.
Run it
Extend it
- Set
amount_centsabovestep_up_amount_centsto trigger the step-up path —payments.initiatereturnskind: 'pending_step_up'with astep_up_urlto open in the browser. - Add a second counterparty address NOT in
counterparty_allowlistand confirm the policy engine rejects it. - Reduce
velocity_max_txs_per_hourto 1 and submit two calls in the same minute to hit the velocity gate. - Bump
policy_versionwithout updatingamount_cap_cents_per_tx— the grant’s pinnedpolicy_versionwill no longer match and calls will fail withPolicyStaleError.
Source
github.com/darshanbathija/axtior-neobank/tree/main/examples/agent-pays-vendorReading list
- AgentPolicyEnvelope schema — all 14 axes and validation rules.
- Grant schema — JWT claims shape,
actclaim, TTL cap. - Receipt schema — every field returned by write tools.
- MCP gateway —
/mcp/read,/mcp/write,/mcp/treasuryendpoint contracts. - Lifecycle — state machine from policy creation to grant expiry.