Let AI agents shop your store.CredentAgent makes them ask first.
CredentAgent is an open-source Node library for MCP servers. Put any tool — checkout, a 21+ item, a member price — behind proof from the shopper's phone wallet. The agent does the shopping; the human approves what matters, and your server enforces it.
npm i @openmobilehub/credentagent-gateApache-2.0 · Express + any MCP client (Claude, ChatGPT, Goose) · OpenID4VP · pre-1.0, honest status
Your tool returns a link, not a yes. The shopper's wallet decides.
When an agent calls a tool you've gated, the gate answers with what's required and an approve link. The shopper proves it on their phone, your server verifies it, and only then does the order complete.
- The shopper asks the agent: “Buy the Oak Whiskey.”
- The agent calls your checkout tool.
- Your server answers: needs
age_over_21+ payment, and here's the approve link. - The agent hands the link (or a QR) to the shopper.
- The shopper opens it and approves in their wallet.
- The wallet presents the credentials to your server (OpenID4VP).
- Your server verifies the proof and re-prices the order itself, then completes it.
- The agent sees the order settled and carries on.
See the gate fire before you write a line.
An agent shops on a real MCP storefront built with CredentAgent — and stops at the gate until you prove your age.
The same store is a hosted MCP connector. Add it to your own agent and order the whiskey — the age gate fires automatically.
https://credentagent.ai/marketplace/mcp
📱 To prove credentials on your device, install Multipaz Wallet (Android & iOS).
checkout tool returns an age_over_21 requirement. Prove it on your device; order completes.Want to customize it? Run locally: node examples/storefront.mjs — inject your catalog, own the code.
Tracking main? https://credentagent.ai/marketplace-dev/mcp runs the unreleased build.
Gate your first tool in three steps.
For an MCP server you already run. Starting from nothing? The storefront gives you a whole gated store instead.
Install the gate
One package, types included. It has no MCP SDK dependency, so it fits whichever MCP server you already use.
Wire the checkout once, at startup
orders.serve(app) adds the approve page and the wallet proof rails to your Express app.
Return an approve link from your checkout tool
Create the order with its policy and hand approveUrl back to the agent. A status tool reads orders.retrieve(id) — MCP has no push, so the agent polls it.
@openmobilehub/credentagent-gate
Gate the tools you already have — the three steps above. Bring your own catalog and order store with defineHost().
@openmobilehub/credentagent-storefront
A ready-to-run MCP store: nine shopping tools, a product widget and a gated checkout. Install it with the gate at the same version — npm i @openmobilehub/credentagent-gate@0.6.0 @openmobilehub/credentagent-storefront@0.6.0.
One policy line per rule your merchant needs.
Age, membership and payment are built in. Anything else a wallet can hold, you define.
Age-restricted goods
The agent can't complete a 21+ order until the shopper proves their age.
required(age.over(21))Member pricing
The member price applies when the shopper proves membership; checkout still works without it.
optional(membership.discount(10))Payment approval
The shopper approves this exact amount and payee in their wallet.
required(payment.in("usd"))Any credential
A prescription, a license, employee status — define the credential and gate the tool.
defineCredential({ id: "prescription", … })Today these wallet checks run at ⚠ presence-only-demo — real wire crypto, no issuer trust anchor yet. What that means →
Let the agent buy on its own — within limits the shopper signed.
When the checkout works, these are the next pieces merchants ask for: unattended purchases, your own catalog and order store, and a signal to fulfillment.
Approve once — with a signature. The human sets a bounded budget (how much, per purchase, and what), and the grant only becomes spendable after their phone wallet signs those exact limits. The agent then buys against it unattended, every rule re-checked server-side on every spend. Age is never delegated to the agent: a 21+ item needs the human's own proof — from their wallet while approving the grant, or live at checkout. Without it, the spend refuses.
Bring your own catalog and order store. Already have an Express + MCP server, a catalog, and an order store? defineHost() takes those three things and builds the rest — one completion choke point your own tools call, fail-closed on an incomplete setup.
Tell a different service when an order settles. A signed order.settled POST — HMAC-SHA256, replay-protected, retried at-least-once — verified on the other side with the familiar constructEvent idiom.
Gate on any credential a wallet can hold. defineCredential() takes a DCQL request, a claim check and the orders it applies to; it then sits in a policy next to the built-ins.
Pre-1.0. Here's exactly what's real, and what production still needs.
The site follows the SDK's own trust_level — it never claims more than the library enforces.
✓ Real today
- Passkey approvals — real WebAuthn, origin-bound, replay-protected
- Signed
order.settledwebhooks (HMAC-SHA256) - Wallet device signatures over a spending grant's exact limits
- Server-side enforcement: amount and policy re-derived on completion
⚠ Demo-grade today
- Wallet credentials (age, membership, payment) are presence-only-demo: the wire crypto is real, but with no issuer trust anchor a self-crafted credential would pass
- Wallet-signed grants: real signature, demo trust anchor
- Click-to-approve grants — for demos and CI only
→ Before production
- Issuer-verified trust — mdoc issuer/device signatures (Multipaz): the next milestone
- Or relay a real external verifier — the interface ships; no adapter yet
- Your deployment: a real
GATE_SECRET, publicwalletOrigin, shared stores —doctor()checks them
The full trust table, rail by rail
order.settled, replay-protecteddefineCredential(): OpenID4VP JWE + nonce + HPKE + mdoc parse, explicit positive claimsigning: "page") — the server takes the approver's word for it; for demos and CI with no phoneThe wire crypto is real; the issuer trust anchor is not yet — a self-crafted credential would still pass. Wallet-signed grants go one step further (the signature is real), but without an anchor they are still a demo. A presence-only gate is never sold as a real safety control. Branding can restyle the consent pages, but never the honesty footer.
Don't take our word for it — check a credential yourself
What the wallet sends isn't a CredentAgent token. It's a standard ISO 18013-5 mdoc: issuer-signed claims, a signed list of their digests, and a signature from the phone's own key. Independent tools from the OpenWallet Foundation's Multipaz project open it.
1 · Look inside
Paste any mdoc DeviceResponse into Multipaz Tools' viewer: document type, every disclosed claim, validity dates, per-claim digests, the device key. It decodes in your browser — nothing is uploaded.
Coming in the next gate release: inspectPresentations: true puts an Inspect this presentation link on the consent page (PR #223).
2 · Check the signatures
Multipaz Tools' verifier asks your wallet for a credential itself, then runs the Multipaz SDK's checks: the issuer's signature, each claim's digest, the device signature, and the validity window.
3 · See who signed it
Every credential carries the certificate that signed it — the payment page's Issuer certificate › link opens it in the X.509 viewer. Multipaz Wallet's built-in test credentials are signed by OWF Multipaz TEST IACA; the CredentAgent demo passes by Utopia Demo IACA (certificate). Both are test authorities, not trusted issuers.
What this shows: the credentials are real, standard, and signed. What it doesn't: that the issuer deserves trust — the demo CA is ours, and the gate itself doesn't check the issuer signature yet (presence-only-demo, above).
An OpenMobileHub project with the OpenWallet Foundation and the AAIF Foundation. Apache-2.0.