diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json new file mode 100644 index 00000000..493c7c04 --- /dev/null +++ b/.claude-plugin/marketplace.json @@ -0,0 +1,59 @@ +{ + "$schema": "https://json.schemastore.org/claude-code-marketplace.json", + "name": "nevermined", + "description": "Nevermined's AI coding skills: monetize an agent with the Payments SDK, or let one buy from external x402 / MPP services through the Nevermined Router.", + "owner": { + "name": "Nevermined", + "url": "https://nevermined.ai" + }, + "plugins": [ + { + "name": "nevermined-payments", + "displayName": "Nevermined Payments", + "description": "Charge for your AI agent or API. Covers the Nevermined Payments SDK (TypeScript and Python), the x402 protocol, payment plans and credits, and middleware for Express, FastAPI, Strands, MCP and Google A2A.", + "author": { + "name": "Nevermined", + "url": "https://nevermined.ai" + }, + "homepage": "https://nevermined.ai/docs/development-guide/build-using-nvm-skill", + "license": "MIT-0", + "category": "development", + "keywords": [ + "payments", + "x402", + "agents", + "monetization", + "mcp" + ], + "source": "./skills", + "strict": false, + "skills": [ + "./nevermined-payments" + ] + }, + { + "name": "nevermined-router", + "displayName": "Nevermined Router", + "description": "Let your agent pay external services it has no account with. Covers discovering services in the Agent Services Catalog, creating a capped spending Delegation, paying any x402 or MPP endpoint through the Nevermined Router, reading the payment ledger, and the guardrails an autonomous buyer must respect.", + "author": { + "name": "Nevermined", + "url": "https://nevermined.ai" + }, + "homepage": "https://nevermined.ai/docs/products/router/overview", + "license": "MIT-0", + "category": "development", + "keywords": [ + "payments", + "x402", + "mpp", + "agents", + "autonomous-buying" + ], + "source": "./skills", + "strict": false, + "skills": [ + "./nevermined-router" + ] + } + ] +} diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 3ffe90e9..6e624f75 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,6 +1,6 @@ -# Nevermined Payments — GitHub Copilot Instructions +# Nevermined — GitHub Copilot Instructions -This repository contains documentation for Nevermined, an AI payment infrastructure platform. When assisting with code that integrates Nevermined payments, follow these patterns. +This repository contains documentation for Nevermined, an AI payment infrastructure platform. It covers two halves: **receiving** payments (the SDK and REST patterns below) and **spending** at external x402 / MPP services through the **Nevermined Router** (last section). When assisting with code that integrates Nevermined, follow these patterns. ## SDK Packages @@ -95,6 +95,85 @@ Card payments: `scheme: "nvm:card-delegation"`, `network: "stripe"`. A human is - **Delegation first:** create a spending delegation (`POST /delegation/create` with `provider` + `currency` + `spendingLimitCents` + `durationSecs`, or SDK `createDelegation`) and reuse its `delegationId`. The inline create-on-the-fly `delegationConfig` (passing limits without a `delegationId`) is **deprecated since `@nevermined-io/payments` 1.8.0** — it only emits a runtime warning now; always pass an explicit `delegationId`. - **Seller analytics:** discover your `orgId` from `.orgId` on `GET /protocol/plans` / `/protocol/agents` records (no separate lookup endpoint). A malformed/placeholder `orgId` returns a silent 200-of-zeros; a non-Premium org returns `403 BCK.ORGANIZATIONS.0022`; a non-admin org returns `403 BCK.AUTH.0004`. +## Nevermined Router — paying external services + + +Use the Router when the agent must **pay** a service it has no account with — any x402 agent or MPP merchant. Everything above is the other half: *receiving* payments and buying Nevermined plans. Plain HTTP, no SDK: `Authorization: Bearer $NVM_API_KEY` against `$NVM_API_URL` (`https://api.sandbox.nevermined.app` sandbox, `https://api.live.nevermined.app` live). **Never send `NVM_API_KEY` to the merchant** — it authenticates you to Nevermined only; the merchant's own auth goes in `headers`. + +The Router pays a price quoted **on the wire**. A service answering `401`/`403` rather than `402` wants authentication, not payment — say so, don't route it. + +### 1. Create a Delegation (the budget) + +```bash +curl -sX POST "$NVM_API_URL/api/v1/delegation/create" \ + -H "Authorization: Bearer $NVM_API_KEY" -H "Content-Type: application/json" \ + -d '{"provider":"erc4337","currency":"usdc","spendingLimitCents":500,"durationSecs":604800}' +# → { "delegationId": "5e7481c3-…" } +``` + +All four fields are required — no defaults. `erc4337` is the crypto-funded Delegation both stablecoin rails need. Create it once and reuse the id. `allowedRecipients` is optional and **omitting it means no recipient restriction at all** — the budget can pay any merchant the Router can reach, bounded only by the cap and expiry. + +### 2. Fund the buyer wallet + +Both rails **pull** from your own custodial wallet: a Delegation authorizes a spend, it does not supply funds. Read the address off the live Delegation every time — `GET /api/v1/delegation/{id}` → `providerPaymentMethodId` — and fund it with the payment asset on the network you intend to pay on. **Never reuse a cached address**: a stale one is the most common cause of `402 BCK.ROUTER.0009`, and that error deliberately does not echo the address it checked. + +### 3. Discover a service (public catalog, no API key) + +```bash +curl -s "$NVM_API_URL/api/v1/catalog/services?protocol=x402&search=web+search" +``` + +- Only `protocol` of `x402` or `mpp` is routable — filter for them. +- **`targetUrl` is the default endpoint's complete URL, not a base** (it may already carry the path), so concatenating yields `/search/search`. Resolve instead: + +```ts +const url = endpoint ? new URL(endpoint.path, service.targetUrl).toString() : service.targetUrl +``` + +### 4. Pay + +```bash +curl -sX POST "$NVM_API_URL/api/v1/router/route" \ + -H "Authorization: Bearer $NVM_API_KEY" -H "Content-Type: application/json" \ + -d '{"delegationId":"'"$NVM_DELEGATION_ID"'","url":"https://service.example/api/resource", + "method":"POST","body":{"query":"…"},"requestId":"search-nevermined-router-v1"}' +# → { "status": 200, "body": {…}, "paid": true, +# "payment": { "paymentId": "…", "settlement": { "approxCents": "1" }, "status": "Settled" } } +``` + +The Router probes the merchant, auto-detects the protocol from the 402, pays and relays. `status`/`body` are the merchant's own; `paid: false` with no `payment` block means the resource was free — handle that. For streaming use `ALL /api/v1/router/proxy` with `X-Router-Target-Url`, `X-Router-Delegation-Id` and `X-Router-Request-Id` headers. + +- **`requestId` is an idempotency key, not a request counter.** Use one stable id per logical purchase, reused across retries of that purchase. **A fresh `uuid4()` per HTTP attempt is how an agent double-spends.** Note what a same-id retry actually returns: `409 BCK.ROUTER.0002` carrying the original `paymentId` — **not the resource**. That is the protection working. **Never answer that 409 by minting a fresh id**, which is exactly the double-spend you avoided a moment ago; if the purchase genuinely failed, report it. +- Budget is debited in **whole cents, rounded up** — 1000 calls at $0.001 costs $10.00, not $1.00. `settlement.approxCents` is what was actually reserved; trust it over any catalog `priceLabel`. + +### 5. Read what you spent + +`GET /api/v1/router/payments` (filters `delegationId`, `from`, `to`, `format=csv`) and `/api/v1/router/payments/summary`. `amount` is the asset's smallest unit, not cents. A record at `Issued` is **not** an error — the money moved; do not retry it. + +### Guardrails — a refusal is the system working + +| Code | Status | Meaning | Retry? | +| --- | --- | --- | --- | +| `BCK.ROUTER.0001` | 400 | Bad input / no fundable option / non-allowlisted asset; `details` names it | No | +| `BCK.ROUTER.0002` | 409 | `requestId` already used; the original `paymentId` is in the response | No | +| `BCK.ROUTER.0003` | 402 | Delegation over cap, expired, exhausted or revoked | No — **stop** | +| `BCK.ROUTER.0006` | 500 | Transient failure building the payments summary | **Yes** | +| `BCK.ROUTER.0007` | 429 | Too many concurrent routed requests in flight | **Yes**, after backoff | +| `BCK.ROUTER.0008` | 403 | Legacy API key — create a new one | No | +| `BCK.ROUTER.0009` | 402 | Wallet short on the target network; nothing was signed | No — **stop** | +| `BCK.ROUTER.0010` | 500 | Internal: the rail reported an unusable charge amount | **No — never blind-retry** | +| `BCK.ROUTER.0011` | 402 | Card rail: needs cardholder 3-D Secure, which an agent can't complete. Nothing charged, no usable credential | No — **needs a human** | + +**Neither `0010` nor `0011` may be auto-retried, and the HTTP status won't tell you that** — one is a 500, the other a 402 that reads like a routine payment error. Read the code, not the status. + +**`0011`** means the card issuer wants 3-D Secure and the agent has no browser to answer it. Nothing was charged. Don't loop: 3DS is often mandated per charge, so each attempt re-demands it and strands a fresh single-use card credential. Surface it to a human. + +**`0010` is the one 500 you must not retry.** A payment credential **was already minted** before it failed, and because no payment record was written your `requestId` will *not* suppress a retry — so retrying re-mints a fresh credential and fails identically. Report it instead. (`0006`, the retryable 500, is only ever raised by the payments *summary* read — never by a payment. On the paying path `0007` is the only code worth retrying at all.) + +**Never widen a Delegation, and never create a second one, to get past a refusal.** The cap is the user's decision, not a runtime obstacle; minting a fresh Delegation to escape an exhausted one defeats the whole mechanism. Report and stop. **On the paying path `0007` is the only retryable code** — `0006` can only come from the summary read, so any *other* 500 from `/route` is a stop. Everything else is a decision, and retrying it unchanged gives the same answer. Delegations also expire silently, so check `expiresAt` before diagnosing a `0003` as anything else. + ## Full Reference See `skills/nevermined-payments/SKILL.md` for complete integration patterns (Track A = operate autonomously via REST; Track B = add payments to your code via SDK). + +See `skills/nevermined-router/SKILL.md` and its `references/` for the Router half — discovery, mode A vs mode B, the ledger, and every guardrail. diff --git a/AGENTS.md b/AGENTS.md index 8eba8eda..f3e73f54 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ -# Nevermined Payments SDK +# Nevermined — Payments SDK and Router -This repository contains documentation for Nevermined, an AI payment infrastructure platform. When assisting with code that integrates Nevermined payments, follow these patterns. +This repository contains documentation for Nevermined, an AI payment infrastructure platform. It covers two halves: **receiving** payments (the SDK and REST patterns below) and **spending** at external x402 / MPP services through the **Nevermined Router** (last section). When assisting with code that integrates Nevermined, follow these patterns. ## SDK Packages @@ -82,6 +82,82 @@ await payments.a2a.start({ port: 3005, basePath: '/a2a/', agentCard, executor }) When an agent must act on its own behalf at runtime (buy a plan, enroll a card, check credits/revenue), call the REST API directly with `Authorization: Bearer $NVM_API_KEY` against `https://api.sandbox.nevermined.app` (sandbox) or `https://api.live.nevermined.app` (live). Buy in two calls — `POST /api/v1/x402/permissions` (→ `accessToken`) then `POST /api/v1/x402/settle` (→ `creditsRedeemed`, `remainingBalance`). Crypto uses `scheme: "nvm:erc4337"` / `network: "eip155:84532"`; cards use `scheme: "nvm:card-delegation"` / `network: "stripe"`. A human is needed only for one-time setup — the first API key, plus card enrollment if paying by card (the stablecoin path needs neither). Full runbook: `skills/nevermined-payments/references/autonomous-operations.md`. +## Nevermined Router — paying external services +{/* Keep this Router section in sync with the identical one in .github/copilot-instructions.md (and vice-versa). MDX comment syntax is deliberate — Mintlify parses this file and rejects HTML comments. */} + +Use the Router when the agent must **pay** a service it has no account with — any x402 agent or MPP merchant. Everything above is the other half: *receiving* payments and buying Nevermined plans. Plain HTTP, no SDK: `Authorization: Bearer $NVM_API_KEY` against `$NVM_API_URL` (`https://api.sandbox.nevermined.app` sandbox, `https://api.live.nevermined.app` live). **Never send `NVM_API_KEY` to the merchant** — it authenticates you to Nevermined only; the merchant's own auth goes in `headers`. The Router pays a price quoted **on the wire**, so a service answering `401`/`403` rather than `402` wants authentication, not payment — say so, don't route it. + +### 1. Create a Delegation (the budget) + +```bash +curl -sX POST "$NVM_API_URL/api/v1/delegation/create" \ + -H "Authorization: Bearer $NVM_API_KEY" -H "Content-Type: application/json" \ + -d '{"provider":"erc4337","currency":"usdc","spendingLimitCents":500,"durationSecs":604800}' +# → { "delegationId": "5e7481c3-…" } +``` + +All four fields are required — no defaults. `erc4337` is the crypto-funded Delegation both stablecoin rails need. Create it once and reuse the id. `allowedRecipients` is optional and **omitting it means no recipient restriction at all** — the budget can pay any merchant the Router can reach, bounded only by the cap and expiry. + +### 2. Fund the buyer wallet + +Both rails **pull** from your own custodial wallet: a Delegation authorizes a spend, it does not supply funds. Read the address off the live Delegation every time — `GET /api/v1/delegation/{id}` → `providerPaymentMethodId` — and fund it with the payment asset on the network you intend to pay on. **Never reuse a cached address**: a stale one is the most common cause of `402 BCK.ROUTER.0009`, and that error deliberately does not echo the address it checked. + +### 3. Discover a service (public catalog, no API key) + +```bash +curl -s "$NVM_API_URL/api/v1/catalog/services?protocol=x402&search=web+search" +``` + +Only `protocol` of `x402` or `mpp` is routable — filter for them. **`targetUrl` is the default endpoint's complete URL, not a base** (it may already carry the path), so concatenating yields `/search/search`. Resolve instead: + +```ts +const url = endpoint ? new URL(endpoint.path, service.targetUrl).toString() : service.targetUrl +``` + +### 4. Pay + +```bash +curl -sX POST "$NVM_API_URL/api/v1/router/route" \ + -H "Authorization: Bearer $NVM_API_KEY" -H "Content-Type: application/json" \ + -d '{"delegationId":"'"$NVM_DELEGATION_ID"'","url":"https://service.example/api/resource", + "method":"POST","body":{"query":"…"},"requestId":"search-nevermined-router-v1"}' +# → { "status": 200, "body": {…}, "paid": true, +# "payment": { "paymentId": "…", "settlement": { "approxCents": "1" }, "status": "Settled" } } +``` + +The Router probes the merchant, auto-detects the protocol from the 402, pays and relays. `status`/`body` are the merchant's own; `paid: false` with no `payment` block means the resource was free — handle that. For streaming use `ALL /api/v1/router/proxy` with `X-Router-Target-Url`, `X-Router-Delegation-Id` and `X-Router-Request-Id` headers. + +- **`requestId` is an idempotency key, not a request counter.** Use one stable id per logical purchase, reused across retries of that purchase. **A fresh `uuid4()` per HTTP attempt is how an agent double-spends.** Note what a same-id retry actually returns: `409 BCK.ROUTER.0002` carrying the original `paymentId` — **not the resource**. That is the protection working. **Never answer that 409 by minting a fresh id**, which is exactly the double-spend you avoided a moment ago; if the purchase genuinely failed, report it. +- Budget is debited in **whole cents, rounded up** — 1000 calls at $0.001 costs $10.00, not $1.00. `settlement.approxCents` is what was actually reserved; trust it over any catalog `priceLabel`. + +### 5. Read what you spent + +`GET /api/v1/router/payments` (filters `delegationId`, `from`, `to`, `format=csv`) and `/api/v1/router/payments/summary`. `amount` is the asset's smallest unit, not cents. A record at `Issued` is **not** an error — the money moved; do not retry it. + +### Guardrails — a refusal is the system working + +| Code | Status | Meaning | Retry? | +| --- | --- | --- | --- | +| `BCK.ROUTER.0001` | 400 | Bad input / no fundable option / non-allowlisted asset; `details` names it | No | +| `BCK.ROUTER.0002` | 409 | `requestId` already used; the original `paymentId` is in the response | No | +| `BCK.ROUTER.0003` | 402 | Delegation over cap, expired, exhausted or revoked | No — **stop** | +| `BCK.ROUTER.0006` | 500 | Transient failure building the payments summary | **Yes** | +| `BCK.ROUTER.0007` | 429 | Too many concurrent routed requests in flight | **Yes**, after backoff | +| `BCK.ROUTER.0008` | 403 | Legacy API key — create a new one | No | +| `BCK.ROUTER.0009` | 402 | Wallet short on the target network; nothing was signed | No — **stop** | +| `BCK.ROUTER.0010` | 500 | Internal: the rail reported an unusable charge amount | **No — never blind-retry** | +| `BCK.ROUTER.0011` | 402 | Card rail: needs cardholder 3-D Secure, which an agent can't complete. Nothing charged, no usable credential | No — **needs a human** | + +**Neither `0010` nor `0011` may be auto-retried, and the HTTP status won't tell you that** — one is a 500, the other a 402 that reads like a routine payment error. Read the code, not the status. + +**`0011`** means the card issuer wants 3-D Secure and the agent has no browser to answer it. Nothing was charged. Don't loop: 3DS is often mandated per charge, so each attempt re-demands it and strands a fresh single-use card credential. Surface it to a human. + +**`0010` is the one 500 you must not retry.** A payment credential **was already minted** before it failed, and because no payment record was written your `requestId` will *not* suppress a retry — so retrying re-mints a fresh credential and fails identically. Report it instead. (`0006`, the retryable 500, is only ever raised by the payments *summary* read — never by a payment. On the paying path `0007` is the only code worth retrying at all.) + +**Never widen a Delegation, and never create a second one, to get past a refusal.** The cap is the user's decision, not a runtime obstacle; minting a fresh Delegation to escape an exhausted one defeats the whole mechanism. Report and stop. **On the paying path `0007` is the only retryable code** — `0006` can only come from the summary read, so any *other* 500 from `/route` is a stop. Everything else is a decision, and retrying it unchanged gives the same answer. Delegations also expire silently, so check `expiresAt` before diagnosing a `0003` as anything else. + ## Full Reference See `skills/nevermined-payments/SKILL.md` for complete integration patterns (Track A = operate autonomously via REST; Track B = add payments to your code via SDK) and its reference files. + +See `skills/nevermined-router/SKILL.md` and its `references/` for the Router half — discovery, mode A vs mode B, the ledger, and every guardrail. diff --git a/CLAUDE.md b/CLAUDE.md index a8a3dc45..01df71da 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -43,11 +43,25 @@ They give AI coding assistants (Claude Code, Cursor, Copilot, Codex, Windsurf, C | `.windsurf/rules/.md` | payments, router (**6,000-char limit per file**) | | `.clinerules/.md` | payments, router | | `.amazonq/rules/.md` | payments, router | -| `.github/copilot-instructions.md` | payments only — single file, no skill segment | -| `AGENTS.md` | payments only — single file, no skill segment | +| `.github/copilot-instructions.md` | payments + a condensed Router section — single file, no per-skill split | +| `AGENTS.md` | payments + a condensed Router section — single file, no per-skill split | + +⚠️ **`AGENTS.md` is parsed by Mintlify as MDX, so it must not contain HTML comments.** A `` there fails the Mintlify Deployment check with *"Unexpected character `!` … to create a comment in MDX, use `{/* text */}`"* — verified on docs#289. Use `{/* … */}` in `AGENTS.md`. `.github/copilot-instructions.md` is **not** in Mintlify's content set (it appears in no `docs.json` route and there is no `.mintignore`), so plain HTML comments are fine there — which is why the two files legitimately differ on this one point. `.cursor/` is otherwise gitignored; `.gitignore` re-includes `.cursor/rules/` specifically, because those files are published — users `curl` them from `main`, so one that fails to commit becomes a 404 in their editor. Both `development-guide/build-using-nvm-skill.mdx` (the install page) and its "Supported Tools at a Glance" table must be updated when this set changes. +### Plugin and registry distribution + +Both skills are also distributed as **Claude Code plugins** via `.claude-plugin/marketplace.json` at the repo root (`/plugin marketplace add nevermined-io/docs`), and to the **ClawHub** registry by `.github/workflows/publish-skill-clawhub.yml`. The install page must be updated for these surfaces too. + +The marketplace entries use `source: "./skills"` with an explicit per-plugin `skills` array. **`source` is a copy boundary, not just a lookup path**: it is the directory copied into `~/.claude/plugins/cache///`, and it becomes that plugin's root. With `source: "./"` every plugin would carry the entire repo — `video/` and `images/` are ~94% of it — and would carry it *again* for the second plugin. Scoped to `./skills`, each plugin carries the skills tree only (~200 KB against ~32 MiB for the repo). Do not change it to `"./"`. + +⚠️ **Do not justify this by the download size, and do not expect `marketplace add` to get smaller.** `/plugin marketplace add` materializes a **full-content snapshot of the repo's default branch** into `~/.claude/plugins/marketplaces//` — every top-level directory, no `.git` — *regardless of what `source` says* (verified against the installed `anthropics/claude-plugins-official`). So the repo lands on disk either way; what `source` controls is what each installed **plugin** copies and loads on top of that. A maintainer who adds the marketplace, watches ~32 MiB arrive anyway, and concludes "the `source` trick does nothing" would be drawing the right conclusion from the wrong claim — which is why the argument here is about plugin content, not bandwidth. + +⚠️ **Nothing enforces that.** `claude plugin validate` checks the manifest's *shape* only — verified by mutation, it passes a `source` of `"./"`, a removed `strict`, and even a `skills` entry pointing at a directory that does not exist. Run it to catch malformed JSON, but the `source`/`skills` invariant is on the reviewer. The honest test is a round trip: add the marketplace from a local path, install, and check the footprint with `du -sh ~/.claude/plugins/cache//*/*/`. + +`strict: false` is load-bearing too: it tells the marketplace entry — rather than a `plugin.json` inside the skill directory — to define which skills the plugin exposes. The skill directories have no `plugin.json`, so removing `strict` would leave the entries claiming components nothing declares. + --- ## Content Tone & Voice diff --git a/development-guide/build-using-nvm-skill.mdx b/development-guide/build-using-nvm-skill.mdx index 7abfc489..b0099354 100644 --- a/development-guide/build-using-nvm-skill.mdx +++ b/development-guide/build-using-nvm-skill.mdx @@ -1,6 +1,6 @@ --- title: "AI Coding Skill" -description: "Import Nevermined payment knowledge into your AI coding assistant and start building monetizable agents in minutes." +description: "Import Nevermined payment and Router knowledge into your AI coding assistant — build agents that charge, and agents that buy." icon: "wand-magic-sparkles" --- @@ -15,17 +15,17 @@ There are two, and which one you want depends on which side of the payment you'r | Skill | Your agent is… | Covers | | --- | --- | --- | | **`nevermined-payments`** | **receiving** money, or buying a Nevermined plan | SDK integration, middleware, plans, credits — the rest of this page | -| **`nevermined-router`** | **spending** money at external services | Discovering services in the catalog, creating a spending Delegation, paying any x402 or MPP endpoint through the [Nevermined Router](/products/router/overview) | +| **`nevermined-router`** | **spending** money at external services | Discovering services in the catalog, creating a spending Delegation, paying any x402 or MPP endpoint through the [Nevermined Router](/products/router/overview), and the guardrails an autonomous buyer must respect | -Installing both is fine — they don't overlap. How you install the Router one depends on your tool: +Installing both is fine — they don't overlap. Every supported tool can now reach the Router: -- **Claude Code, Cursor, Windsurf, Cline, Amazon Q** — swap `nevermined-payments` for `nevermined-router` in the paths below, or run the extra command shown in each tab. -- **Codex CLI** — its `AGENTS.md` route is a *single* file with no skill name in it, and that file carries the **payments** guidance only. Use the tab's **"install as a Codex skill"** alternative instead: `.agents/skills/` takes a skill directory, so `nevermined-router` works there. -- **GitHub Copilot** — `.github/copilot-instructions.md` is a single file with nothing to swap, and it carries the **payments** guidance only. Until that changes, use the [full skill on GitHub](https://github.com/nevermined-io/docs/tree/main/skills/nevermined-router) or paste it in manually. +- **Claude Code** — install them as plugins, one command each. See the tab below. +- **Cursor, Windsurf, Cline, Amazon Q** — swap `nevermined-payments` for `nevermined-router` in the paths below, or run the extra command shown in each tab. +- **Codex CLI and GitHub Copilot** — `AGENTS.md` and `.github/copilot-instructions.md` are *single* files with no skill name to swap, so each one carries **both** halves: the payments guidance and a condensed Router section. Take the whole file. Codex can also install `nevermined-router` as a proper skill directory under `.agents/skills/` — see its tab. ## What's Included -The skill provides your coding assistant with: +The skills provide your coding assistant with: - **SDK initialization** patterns for TypeScript and Python - **Framework-specific middleware** (Express.js, FastAPI, Strands, MCP, Google A2A) @@ -34,6 +34,13 @@ The skill provides your coding assistant with: - **Client-side** integration — ordering plans, generating tokens, calling protected APIs - **Troubleshooting** for common errors (402, `-32003`, `-32002`) +And, from the Router skill: + +- **Service discovery** in the public Agent Services Catalog +- **Spending Delegations** — creating a capped budget and funding the buyer wallet +- **Paid calls** over x402 and MPP through one endpoint, with the protocol auto-detected +- **Guardrails** — every `BCK.ROUTER.*` code, what's retryable, and why a refusal must not be worked around + ## Install the Skill Choose your AI coding tool below for step-by-step installation instructions. @@ -42,7 +49,22 @@ Choose your AI coding tool below for step-by-step installation instructions. ### Claude Code - **Commands to install** from the Nevermined repository: + Install from the Nevermined plugin marketplace — two commands, and Claude Code keeps the skills up to date for you: + + ```text + /plugin marketplace add nevermined-io/docs + + /plugin install nevermined-payments@nevermined # charging for your agent + /plugin install nevermined-router@nevermined # buying from external services + ``` + + Those are Claude Code commands — type them in Claude Code, not in a shell. + + Install either or both. The marketplace is named `nevermined` (that's the `@nevermined` suffix); `nevermined-io/docs` is just the repository it's served from. + + Claude Code loads each skill when it's relevant to your work, and refreshes it in the background when we publish changes. To update by hand it takes two steps — `/plugin marketplace update nevermined` refreshes the catalogue, then `/plugin update nevermined-router@nevermined` updates the installed plugin itself (restart to apply). + + **Alternative — copy the files directly.** Use this if you'd rather take a snapshot you control, or you're on a Claude Code build without plugin support: ```bash mkdir -p ~/.claude/skills @@ -57,27 +79,34 @@ Choose your AI coding tool below for step-by-step installation instructions. cd - rm -rf "$tmpdir" + ``` + Claude Code discovers skills automatically from `~/.claude/skills/` (personal) and `.claude/skills/` (project). Copied this way they're a snapshot — you re-run the command to update. + + + + ### ClawHub + + Both skills are published to the [ClawHub](https://clawhub.ai) registry under the `nevermined-io` publisher, so any tool that reads a `skills/` directory can pull them with one command: + + ```bash + npx clawhub install nevermined # the payments skill + npx clawhub install nevermined-router # buying through the Router ``` - This downloads the `SKILL.md` and all reference files into your local Claude Code skills directory. Claude Code automatically loads the skill when it's relevant to your work. + This writes to `skills//` in the current directory. `--dir` sets a different target — it's a global flag, so it goes **before** the subcommand: + + ```bash + npx clawhub --dir ~/.claude/skills install nevermined-router + ``` - **Alternative — manual installation:** + You don't need an account to install. `npx clawhub update --all` pulls the latest published versions (the bare `update` errors — it wants a slug or `--all`), and `npx clawhub inspect nevermined-router` shows what you'd get without installing it. - 1. Clone or download the skill files: - ```bash - git clone https://github.com/nevermined-io/docs.git /tmp/nvm-docs - ``` - 2. Copy to your personal skills directory: - ```bash - cp -r /tmp/nvm-docs/skills/nevermined-payments ~/.claude/skills/ - ``` - 3. Or copy to a project-specific location: - ```bash - cp -r /tmp/nvm-docs/skills/nevermined-payments .claude/skills/ - ``` + The install lock is per working directory, so if you installed with `--dir`, run the update from that same directory with the same flag: `npx clawhub --dir ~/.claude/skills update --all`. - Claude Code discovers skills automatically from `~/.claude/skills/` (personal) and `.claude/skills/` (project). + + Two ClawHub surprises worth knowing. The payments skill is published under the slug **`nevermined`**, not `nevermined-payments` (the Router skill's slug matches its name). And the version `clawhub inspect` reports for the payments skill won't match the `Skill version` in its own `SKILL.md` header — the registry assigns its own numbering. Trust the registry's version for "is my copy current", and the file's for what changed. + @@ -238,13 +267,18 @@ Choose your AI coding tool below for step-by-step installation instructions. | Tool | Config File | Router available? | Auto-Activates | |---|---|---|---| -| **Claude Code** | `~/.claude/skills//SKILL.md` | Yes | Yes — when relevant | +| **Claude Code** | plugin, or `~/.claude/skills//SKILL.md` | Yes | Yes — when relevant | | **Cursor** | `.cursor/rules/.mdc` | Yes | Yes — on `.ts`, `.js`, `.py` files | | **Windsurf** | `.windsurf/rules/.md` | Yes | Yes — model decides | -| **GitHub Copilot** | `.github/copilot-instructions.md` | **No** — single file, payments only | Yes — always | -| **Codex CLI** | `AGENTS.md` or `.agents/skills//` | Yes — via `.agents/skills/`; **not** via `AGENTS.md` (single file, payments only) | Yes — always or when relevant | +| **GitHub Copilot** | `.github/copilot-instructions.md` | Yes — condensed, in the same single file | Yes — always | +| **Codex CLI** | `AGENTS.md` or `.agents/skills//` | Yes — condensed in `AGENTS.md`, in full via `.agents/skills/` | Yes — always or when relevant | | **Cline** | `.clinerules/.md` | Yes | Yes — on `.ts`, `.js`, `.py` files | | **Amazon Q** | `.amazonq/rules/.md` | Yes | Yes — always | +| **Any** (ClawHub) | `skills//SKILL.md` | Yes | Depends on the tool | + + +The Copilot and Codex files are **condensed** — they carry the buy loop, the money traps and every `BCK.ROUTER.*` retry decision, but not the full reference set: they omit `0004`/`0005`, everything the Router refuses outright (MPP splits, internal targets, redirects, forged `X-Router-*`), and the relay limits. For the complete Router skill, install it as a directory (Claude Code plugin, ClawHub, or `.agents/skills/`). + ## Example Prompts