Ask for proof, never hold the data
Put verified identity on your site, let AI agents act for people within the limits they sign, and sell to those agents — with web components and one MCP server. No identity documents and no keys on your side.
npm create @leagle/app@latest myapp.localhostA project wired end to end — then npm run dev and open http://myapp.localhost:3737
Three ways in, one wallet on the other side
- 01For your site
Continue with Leagle.id
Ask a visitor's wallet for a verified Passport. You get the proof; their documents and keys never reach you.
@leagle/sdk-web - 02For AI agents
Act for a person, within limits
An MCP server that lets an agent book, buy and order on a plan the person signed — without holding their identity.
leagle mcp - 03For Services
Sell to people's agents
Verify what an agent presents, check it against the person's cap, and sign the receipt for every sale.
@leagle/cli/service
A verified Passport in three steps
The visitor approves every request in their wallet. You never see their documents — only the proof you asked for.
- 01
Get a Developer License
In the Leagle.id wallet, turn on Developer Mode in Settings, then add a Developer License from Home. Its card shows the two values your project reads. Keep the secret key on your server only.
.env.local LEAGLE_ID_ROOT_LICENSE='{"attributes":[…]}' LEAGLE_ID_SECRET_KEY='…' - 02
Scaffold a project
Pass the *.localhost subdomain your license is scoped to. You get a project wired end to end, and the next steps for the package manager you used.
npm create @leagle/app@latest myapp.localhost - 03
Ask for a Passport
Two halves: your server issues a Certificate saying what you ask for, and <leagle-id-certificate> takes it to the visitor's wallet. They approve in a popup; you get their Passport and Vault back to verify on your server.
<leagle-id-certificate certificate-url="/api/certificate"> <button>Continue with Leagle.id</button> </leagle-id-certificate>
Adding it to an existing app instead? Install the package — ESM and CommonJS builds, with TypeScript types. @leagle/sdk-web on npm
npm install @leagle/sdk-webAgents that act within a signed plan
Add the MCP server to any client that runs stdio servers. The person approves each step in their wallet; the agent never holds their identity or their Master Key.
claude mcp add leagle-id -- npx -y @leagle/cli mcpNeeds Node 20 or later · also runs with pnpm dlx, yarn dlx and bunx
connect01Connect this chat
The wallet issues an Agent Vault for this chat only, on a fresh Privacy Passport. It grants nothing yet.
approved in the walletpropose_plan02Propose a plan
One line per Service the agent will spend at, each with a cap, plus a deadline. Approving it is the consent.
approved in the walletshortlist_options03Shortlist real offers
Only offers on the right Service and within the cap get a certificate — one per option.
present04Present one option
A short-lived certificate revealing that option and its cap. Nothing about the other lines or the person.
purchase05Buy and keep the receipt
Every Sale Receipt is signed by the Service and goes into the Agent Ledger.
close_plan06Seal the ledger
The ledger is sealed and sent to the wallet once, which checks every booking against the plan.
Accept agents, sign every sale
Your own sales code — never an AI tool — verifies the presentation, runs your stock and price checks, and signs a receipt the person's wallet can check.
- Your agent asks for a 90-day Service License with request_service_license — you prove the domain with a well-known file or a DNS record
- A Service sees its own line, the one option in front of it and a pseudonym — never the plan's total or who the person is
- Revoke a leaked key by removing the proof from your domain: it stops renewing
Rather not write it? Have your agent scaffold_service_mcp — or let createSalesHandler run the endpoint. @leagle/cli on npm
npm install @leagle/cliimport {
createChallenges,
signSaleReceipt,
verifyPresentation,
} from '@leagle/cli/service';
const challenges = createChallenges(); // single-use, in memory
// POST /challenge → { challenge: challenges.issue() }
// POST /present →
const sale = await verifyPresentation(certificate, challenges, {
issuer, // the Leagle.id wallet's Passport issuer key
domain: 'alternate.nl',
priceMinor: 77900,
});
// Your own checks here: stock and price against your records. Refuse any
// amount over sale.capMinor BEFORE taking payment, then charge.
const receipt = await signSaleReceipt({
presented: certificate,
sale,
amountMinor: 77900,
vault, // your Service Agent Vault (issue_service_agent_vault)
key, // its Service Agent Key: kept in your sales system only
});Entry points
Pre-release (0.x): APIs and formats may change between minor versions until 1.0.
@leagle/sdk-web/certificateBrowser<leagle-id-certificate>: ask the visitor's wallet for a Passport
@leagle/sdk-web/connectBrowser<leagle-id-connect>: a peer-to-peer connection to the visitor's wallet
@leagle/sdk-web/contact-pickerBrowser<leagle-id-contact-picker>: let the visitor pick a contact from their wallet
@leagle/sdk-web/serverNodeIssue Client Licenses and Certificates; verify certificates, chains and agent certificates
@leagle/cli/serviceNodeVerify agent presentations, sign Sale Receipts, run sales and access endpoints
leagle mcpstdioThe MCP server: connect, plan, shortlist, present, purchase, close
| Import | What | Runs in |
|---|---|---|
| @leagle/sdk-web/certificate | <leagle-id-certificate>: ask the visitor's wallet for a Passport | Browser |
| @leagle/sdk-web/connect | <leagle-id-connect>: a peer-to-peer connection to the visitor's wallet | Browser |
| @leagle/sdk-web/contact-picker | <leagle-id-contact-picker>: let the visitor pick a contact from their wallet | Browser |
| @leagle/sdk-web/server | Issue Client Licenses and Certificates; verify certificates, chains and agent certificates | Node |
| @leagle/cli/service | Verify agent presentations, sign Sale Receipts, run sales and access endpoints | Node |
| leagle mcp | The MCP server: connect, plan, shortlist, present, purchase, close | stdio |
Web components, no framework
The browser entries are custom elements. ESM and CommonJS builds, with TypeScript types.
No keys on your side
Every approval is signed in the person's wallet. Your secret key only signs what you ask for.
Open source, with an SBOM
Apache-2.0 (the proof system under its own terms), with a CycloneDX SBOM of everything bundled.
Your first proof is one command away
Turn on Developer Mode in the wallet, add a Developer License, and scaffold a project scoped to your *.localhost subdomain.