llms.txt
An index of every docs page with a one-line summary, at the docs root.
Developers
One remote MCP server gives Claude, ChatGPT and any MCP client a verified owner, named agents under a spending policy, private facet proofs and x402 payment. A REST API and SDKs cover servers and merchants.
Quickstart
Connect the server. Verify the owner once. Create an agent with a policy. Let the agent pay a 402 endpoint. Each step shows the MCP call an assistant makes, and the same call from TypeScript, Python and cURL.
Add one URL to your assistant. The client discovers the authorization server and runs OAuth on its own. Servers and scripts use a secret key from the console instead.
// Claude: claude_desktop_config.json, or Settings > Connectors > Add custom connector // ChatGPT: Settings > Connectors > Create, then paste the same URL { "mcpServers": { "sils": { "type": "http", "url": "https://mcp.silsacommerce.com/mcp" } } }
// npm install @sils/sdk import { Sils } from "@sils/sdk"; const sils = new Sils({ apiKey: process.env.SILS_SECRET_KEY, // sk_test_... on testnet baseUrl: "https://api.silsacommerce.com/v1", }); const me = await sils.account.retrieve(); console.log(me.mode); // "test"
# pip install sils import os from sils import Sils sils = Sils( api_key=os.environ["SILS_SECRET_KEY"], # sk_test_... on testnet base_url="https://api.silsacommerce.com/v1", ) me = sils.account.retrieve() print(me.mode) # "test"
curl https://api.silsacommerce.com/v1/account \ -H "Authorization: Bearer $SILS_SECRET_KEY" # { "object": "account", "mode": "test", "networks": ["eip155:84532", ...] }
Verification happens once, off chain, with regulated identity partners. SILS returns a one-time link. The owner completes document and liveness checks in the browser and comes back with a .revo name. The chain stores a commitment, never the documents.8
// tools/call: sils.start_verification { "name": "rob", "level": "L2" } // result.structuredContent { "session": "ver_7Qm2xK", "verificationUrl": "https://verify.silsacommerce.com/s/ver_7Qm2xK", "expiresIn": 900 } // result.content[0].text // "Tap this link to verify." // tools/call: sils.status, after the owner returns { "session": "ver_7Qm2xK" } // => { "state": "verified", "name": "rob.revo", "level": "L2" }
const v = await sils.verifications.create( { name: "rob", level: "L2" }, { idempotencyKey: crypto.randomUUID() }, ); // Send the owner to v.verificationUrl. Then poll, or listen for identity.verified. const done = await sils.verifications.retrieve(v.session); console.log(done.state, done.name); // "verified" "rob.revo"
import uuid v = sils.verifications.create( name="rob", level="L2", idempotency_key=str(uuid.uuid4()), ) # Send the owner to v.verification_url. Then poll, or listen for identity.verified. done = sils.verifications.retrieve(v.session) print(done.state, done.name) # verified rob.revo
curl https://api.silsacommerce.com/v1/verifications \ -H "Authorization: Bearer $SILS_SECRET_KEY" \ -H "Idempotency-Key: 5d1f0c2a-8b7e-4c55-9a1d-2f3e6b7c8d90" \ -H "Content-Type: application/json" \ -d '{ "name": "rob", "level": "L2" }' # { "session": "ver_7Qm2xK", "verificationUrl": "https://verify.silsacommerce.com/s/ver_7Qm2xK" } curl https://api.silsacommerce.com/v1/verifications/ver_7Qm2xK \ -H "Authorization: Bearer $SILS_SECRET_KEY"
Each agent is a soulbound child name of its owner. The policy sets caps per transaction and per period, allowed categories, required counterparty facets, an approval threshold and an expiry. The agent cannot exceed it. The owner approves the creation with a passkey.
// tools/call: sils.create_agent { "parent": "rob.revo", "label": "shopping", "purpose": "Buy books and household items", "policy": { "perTx": "25.00 USDC", "perMonth": "200.00 USDC", "categories": ["retail", "books"], "counterpartyFacets": ["entity.verified"], "approvalOver": "40.00 USDC", "expires": "2027-01-01" } } // result, after the owner approves with a passkey { "agent": "shopping.rob.revo", "status": "active", "policyHash": "0x9c1e...4b7a", "explorer": "https://explorer.example/tx/0x31d0...a2" }
const agent = await sils.agents.create({ parent: "rob.revo", label: "shopping", policy: { perTx: "25.00", perMonth: "200.00", asset: "USDC", categories: ["retail", "books"], counterpartyFacets: ["entity.verified"], approvalOver: "40.00", expires: "2027-01-01", }, }, { idempotencyKey: crypto.randomUUID() }); console.log(agent.name, agent.policyHash); // shopping.rob.revo 0x9c1e...4b7a
agent = sils.agents.create(
parent="rob.revo",
label="shopping",
policy={
"per_tx": "25.00",
"per_month": "200.00",
"asset": "USDC",
"categories": ["retail", "books"],
"counterparty_facets": ["entity.verified"],
"approval_over": "40.00",
"expires": "2027-01-01",
},
idempotency_key=str(uuid.uuid4()),
)
print(agent.name) # shopping.rob.revo
curl https://api.silsacommerce.com/v1/agents \ -H "Authorization: Bearer $SILS_SECRET_KEY" \ -H "Idempotency-Key: 0b8e7f1c-3d2a-4e69-8f10-7a6b5c4d3e21" \ -H "Content-Type: application/json" \ -d '{ "parent": "rob.revo", "label": "shopping", "policy": { "perTx": "25.00", "perMonth": "200.00", "asset": "USDC", "categories": ["retail", "books"], "counterpartyFacets": ["entity.verified"], "approvalOver": "40.00", "expires": "2027-01-01" } }'
Point the agent at any x402 resource. SILS reads the PAYMENT-REQUIRED header, checks the policy, builds the payment and retries with PAYMENT-SIGNATURE. If the request breaks the policy, nothing moves.
// tools/call: sils.pay (annotated destructive) { "agent": "shopping.rob.revo", "resource": "https://acme.example/api/v1/report", "maxAmount": "25.00 USDC" } // result.structuredContent { "status": "settled", "amount": "24.00 USDC", "payTo": "sales.acme.revo", "receipt": "rcpt_4hT9wQ", "explorer": "https://explorer.example/tx/0x8a4c...19" } // result.content[0].text // "Paid 24.00 USDC to sales.acme.revo. Proof valid. Owner verified. Within policy."
// sils.fetch wraps fetch(). On 402 it pays within policy and retries once. const res = await sils.fetch("https://acme.example/api/v1/report", { agent: "shopping.rob.revo", maxAmount: "25.00", }); const report = await res.json(); const receipt = sils.receipts.fromResponse(res); // decoded PAYMENT-RESPONSE console.log(receipt.amount, receipt.payTo); // 24.00 USDC sales.acme.revo
res = sils.fetch(
"https://acme.example/api/v1/report",
agent="shopping.rob.revo",
max_amount="25.00",
)
report = res.json()
receipt = sils.receipts.from_response(res) # decoded PAYMENT-RESPONSE
print(receipt.amount, receipt.pay_to) # 24.00 USDC sales.acme.revo
# 1. Ask for the resource. The merchant answers 402. curl -i https://acme.example/api/v1/report # HTTP/1.1 402 Payment Required # PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6Mi... # 2. Have SILS build the payment for the agent, within policy. curl https://api.silsacommerce.com/v1/payments \ -H "Authorization: Bearer $SILS_SECRET_KEY" \ -H "Idempotency-Key: 9e2d4b6a-1c3f-4a5e-b7d9-0f1e2d3c4b5a" \ -H "Content-Type: application/json" \ -d '{ "agent": "shopping.rob.revo", "paymentRequired": "eyJ4NDAy..." }' # { "paymentSignature": "eyJ4NDAyVmVyc2lvbiI6Mi..." } # 3. Retry with the payload. curl -i https://acme.example/api/v1/report \ -H "PAYMENT-SIGNATURE: eyJ4NDAyVmVyc2lvbiI6Mi..." # HTTP/1.1 200 OK # PAYMENT-RESPONSE: eyJzdWNjZXNzIjp0cnVl...
Reference
Every tool returns a plain-language summary next to its structured fields, so the assistant can narrate without inventing. Every mutating tool returns an explorer link. Every tool is idempotent on retry. Read tools are annotated read-only. Value-moving tools are annotated destructive and ask the owner when policy requires it.
| Tool | Inputs | Returns | Signer | Status |
|---|---|---|---|---|
sils.start_verification | desired name, level (L1 or L2) | one-time verification URL, session id | Owner, in browser | In development |
sils.status | session id | verified or pending, .revo name, level, wallet address | Read-only | In development |
sils.create_agent | parent, label, purpose, optional policy | agent name, agent account, policy hash, explorer link | Owner passkey | In development |
sils.set_policy | agent, cap per tx and per period, categories, counterparty facets, approval threshold, expiry | new policy hash, delegation id | Owner passkey | In development |
sils.prove_facet | facet, verifier URL or address, challenge nonce | proof, nullifier, verification result | Agent session key | In development |
sils.pay | agent, resource URL or payTo name, amount or max, asset, memo | settlement status, receipt id, explorer link, fee | Agent session key, within policy | In development |
sils.resolve | any .revo name | owner chain, level, status, policy summary, created date | Read-only | In development |
sils.list_agents | owner name, optional status filter | agents with status and policy summary | Read-only | Planned |
sils.revoke_agent | agent name, reason | revocation record, effective at the next transaction | Owner passkey | Planned |
sils.fetch_receipt | receipt id or settlement id | amount, payTo, facets proven, timestamp. No payer data. | Read-only | Planned |
Illustrative. Tool names follow the MCP naming rules: 1 to 128 characters from letters, digits, underscore, hyphen and dot.3 Execution errors return isError: true with a readable message.
Security
The SILS MCP server follows the MCP specification revision 2025-11-25. It is a remote server over Streamable HTTP and an OAuth 2.1 protected resource.
POST /mcp HTTP/1.1
Host: mcp.silsacommerce.com
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.silsacommerce.com/.well-known/oauth-protected-resource"
// GET https://mcp.silsacommerce.com/.well-known/oauth-protected-resource { "resource": "https://mcp.silsacommerce.com/mcp", "authorization_servers": ["https://auth.silsacommerce.com"], "scopes_supported": ["identity:read", "agents:write", "proofs:create", "payments:create"], "bearer_methods_supported": ["header"] }
GET https://auth.silsacommerce.com/authorize ?response_type=code &client_id=https%3A%2F%2Fclient.example%2Fmetadata.json &redirect_uri=https%3A%2F%2Fclient.example%2Fcallback &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM &code_challenge_method=S256 &resource=https%3A%2F%2Fmcp.silsacommerce.com%2Fmcp &scope=agents%3Awrite+payments%3Acreate
Protocol
SILS Proof ships as a scheme inside x402 v2, not as a new protocol. The three v2 headers carry Base64-encoded JSON: PAYMENT-REQUIRED, PAYMENT-SIGNATURE and PAYMENT-RESPONSE.4, 5 The merchant can offer sils-proof next to exact. The agent picks one.
GET /api/v1/report HTTP/1.1 Host: acme.example Accept: application/json
// HTTP/1.1 402 Payment Required // PAYMENT-REQUIRED: base64(json below) { "x402Version": 2, "resource": { "url": "https://acme.example/api/v1/report", "description": "Quarterly market report", "mimeType": "application/json" }, "accepts": [ { "scheme": "sils-proof", "network": "eip155:<revolution-chain-id>", "asset": "USDC", "amount": "24000000", "payTo": "sales.acme.revo", "maxTimeoutSeconds": 60, "extra": { "facets": ["human.verified", "age.over.21", "jurisdiction.in:US"], "nonce": "b41f9a07c3e2...e0" } }, { "scheme": "exact", "network": "eip155:8453", "asset": "USDC", "amount": "24000000", "payTo": "0x5c1b...a9F2", "maxTimeoutSeconds": 60 } ] }
// GET /api/v1/report // PAYMENT-SIGNATURE: base64(json below) { "x402Version": 2, "accepted": { "scheme": "sils-proof", "network": "eip155:<revolution-chain-id>", "asset": "USDC", "amount": "24000000", "payTo": "sales.acme.revo" }, "payload": { "agent": "shopping.rob.revo", "nonce": "b41f9a07c3e2...e0", "facets": ["human.verified", "age.over.21", "jurisdiction.in:US"], "proof": "AAECAwQF...opaque...9f", "nullifier": "0x2e7d...c41b" } }
// HTTP/1.1 200 OK // PAYMENT-RESPONSE: base64(json below) { "success": true, "network": "eip155:<revolution-chain-id>", "settlement": "stl_Vb82kQ", "nullifier": "0x2e7d...c41b", "result": "Proof valid. Owner verified. Within policy." }
A settlement exists. It matches the stated amount, asset and recipient. It has not been presented before. It is bound to this merchant's nonce. Each requested facet holds. The proof system and circuit design are not published.8
| Endpoint | Role in the exchange | Status for sils-proof |
|---|---|---|
POST /verify | Checks the payload against the stated terms and the nullifier set before the merchant does work | In development |
POST /settle | Settles on chain, spends the nullifier and returns the settlement response | In development |
GET /supported | Lists supported scheme and network pairs, including sils-proof on Revolution | In development |
Endpoint names from the x402 v2 specification.4 SILS plans to use Revolution's open-source x402 facilitator.
Merchants
requireProof answers 402 with your terms. verifyPayment checks the retry through the facilitator. confirmOrder settles after you fulfil, so a failed order never charges the agent. Adapters are planned for Express, Hono and Next.js.8
import express from "express"; import { requireProof, verifyPayment, confirmOrder } from "@sils/sdk/merchant"; const app = express(); app.get( "/api/v1/report", requireProof({ payTo: "sales.acme.revo", amount: "24.00", asset: "USDC", facets: ["human.verified", "age.over.21", "jurisdiction.in:US"], }), async (req, res) => { const payment = await verifyPayment(req); // facilitator POST /verify const report = await buildReport(); const receipt = await confirmOrder(payment); // facilitator POST /settle res.set("PAYMENT-RESPONSE", receipt.header).json(report); }, );
import { Hono } from "hono"; import { requireProof, verifyPayment, confirmOrder } from "@sils/sdk/merchant/hono"; const app = new Hono(); app.get( "/api/v1/report", requireProof({ payTo: "sales.acme.revo", amount: "24.00", asset: "USDC", facets: ["human.verified", "age.over.21"] }), async (c) => { const payment = await verifyPayment(c.req.raw); const report = await buildReport(); const receipt = await confirmOrder(payment); c.header("PAYMENT-RESPONSE", receipt.header); return c.json(report); }, ); export default app;
// app/api/v1/report/route.ts import { requireProof, verifyPayment, confirmOrder } from "@sils/sdk/merchant/next"; const terms = { payTo: "sales.acme.revo", amount: "24.00", asset: "USDC", facets: ["human.verified", "age.over.21"], }; export async function GET(req: Request) { const challenge = await requireProof(req, terms); if (challenge) return challenge; // 402 with PAYMENT-REQUIRED const payment = await verifyPayment(req); const report = await buildReport(); const receipt = await confirmOrder(payment); return Response.json(report, { headers: { "PAYMENT-RESPONSE": receipt.header }, }); }
Reference
A facet is a yes or no claim about the owner, proven without the underlying data. The facet set is governance-set on Revolution. Parameterized facets take a value after a colon.8
| Facet | The merchant learns | Example | Status |
|---|---|---|---|
human.verified | A verified person stands behind the agent | human.verified | In development |
entity.verified | A verified business stands behind the agent | entity.verified | In development |
age.over.18 | The owner is over 18. Not the birth date. | age.over.18 | In development |
age.over.21 | The owner is over 21. Not the birth date. | age.over.21 | In development |
jurisdiction.in | The owner is in one of the listed countries. Not which one. | jurisdiction.in:US,CA,GB | In development |
jurisdiction.not.in | The owner is in none of the listed countries | jurisdiction.not.in:XX,YY | In development |
sanctions.clear | The owner passed sanctions screening | sanctions.clear | Planned |
investor.accredited | The owner holds an accreditation credential | investor.accredited | Planned |
reputation.above | The agent's SILS Score clears a threshold. Not the score. | reputation.above:700 | In development |
kya.certified | The agent holds a Know Your Agent credential | kya.certified | Planned |
mandate.covers | The purchase falls inside the owner's signed mandate. Not the budget. | mandate.covers | In development |
Illustrative. Facet strings from Revolution Network Whitepaper v2.0 §6.4 and §8.6. Threshold values and country codes in the examples are placeholders.
Platform
The REST API is Planned. These are the conventions it is designed around, so integrations stay predictable.
| Convention | Design | Status |
|---|---|---|
| Idempotency keys | Idempotency-Key header on every write: verifications, agents, proofs, payments. A replay returns the saved result. A reused key with different parameters returns an error. | Planned |
| Signed webhooks | SILS-Signature header with a timestamp and an HMAC-SHA256 signature. Retries with backoff. No ordering guarantee. Deduplicate by event id. | Planned |
| OpenAPI 3.1 | One public spec for the REST API. SDKs are generated from it. | Planned |
| Versioning | Date-based API versions. Semantic versions for SDKs. | Planned |
| Rate limits | Separate limits for sandbox and live keys, published per key and per MCP tool. 429 with Retry-After. Back off with jitter. | Planned |
// POST https://acme.example/webhooks/sils // SILS-Signature: t=1791043200,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd { "id": "evt_3Nc81z", "type": "settlement.finalized", "created": "2026-10-03T14:00:00Z", "data": { "settlement": "stl_Vb82kQ", "amount": "24000000", "payTo": "sales.acme.revo", "facets": ["human.verified", "age.over.21"] } }
Reference
Every error has a stable type and code, a sentence a person can read, and a request id for support. MCP tools return the same object inside a result marked isError: true.
{
"error": {
"type": "policy_error",
"code": "spend_cap_exceeded",
"message": "Shopping tried to spend 250.00 USDC. The cap is 200.00 USDC. Blocked.",
"param": "amount",
"agent": "shopping.rob.revo",
"requestId": "req_9Lx2Qe",
"docUrl": "https://docs.silsacommerce.com/errors/spend_cap_exceeded"
}
}
| Type | When | Example code |
|---|---|---|
auth_error | Missing, expired or wrong-audience token | token_audience_mismatch |
policy_error | The request breaks the agent's policy | spend_cap_exceeded |
proof_error | A facet does not hold, or the nullifier was already spent | nullifier_spent |
approval_required | The owner must approve with a passkey | over_approval_threshold |
idempotency_error | A key was reused with different parameters | key_reused |
rate_limit_error | Too many requests for this key or tool | rate_limited |
Sandbox
Test keys will not work on live networks. No real funds move. Each network is labeled with how SILS will verify payments on it.
| Network | CAIP-2 id | Use in sandbox | Status |
|---|---|---|---|
| Revolution Virtus testnet | eip155:<placeholder> | Names, agents, policy, facet proofs, sils-proof settlement | Planned |
| Base Sepolia | eip155:84532 | USDC payments with the exact scheme | Planned |
| Solana devnet | solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 | USDC payments, verified by labeled attestation | Planned |
Revolution's Virtus public testnet is in setup. Its chain id is not yet published.8 Base Sepolia and Solana devnet ids follow x402 network naming.7
Docs for agents
Most integrations will be written with an assistant in the loop. The docs are planned to be machine-readable from the start.8
An index of every docs page with a one-line summary, at the docs root.
Append .md to any docs URL to get clean Markdown with code intact.
Search and fetch the docs from Claude, ChatGPT or an IDE agent over MCP.
One button on each page opens it in an assistant with the page loaded as context.
# SILS > Verified owners, agent policy, private proofs and x402 payment for AI agents. ## Quickstart - [Connect the MCP server](https://docs.silsacommerce.com/quickstart/connect.md) - [Verify the owner](https://docs.silsacommerce.com/quickstart/verify.md) - [Create an agent](https://docs.silsacommerce.com/quickstart/agents.md) - [Pay a 402 endpoint](https://docs.silsacommerce.com/quickstart/pay.md) ## Reference - [MCP tools](https://docs.silsacommerce.com/reference/mcp-tools.md) - [sils-proof scheme](https://docs.silsacommerce.com/reference/sils-proof.md) - [Facets](https://docs.silsacommerce.com/reference/facets.md)
Changelog
The SILS site and design system went public. This page describes interfaces in development. No API is open yet.
Identity moved to .revo names on Revolution Name Service. Private payment proofs are specified as a scheme inside x402, published here as sils-proof.
Seven tools named and scoped: start_verification, status, create_agent, set_policy, prove_facet, pay and resolve. Three more planned.
A public status page is Planned.
Preview members get testnet keys as each network opens, and a say in the interface while it can still change.
Sources