# Recette : serveur MCP payant

> Facturez les outils d’un serveur MCP à l’appel, en crédits. Une personne achète un pack une fois ; chaque appel consomme, puis s’exécute.

Les agents ne devraient pas payer seuls. Une personne achète un pack de crédits dans son navigateur, puis chaque appel d’outil vérifie le solde, consomme des crédits avec une clé d’idempotence et s’exécute. Sans crédits, l’outil répond avec un lien de recharge que l’agent affiche. Pas de x402, pas de portefeuille dans l’agent, rien n’est débité tout seul.

> **Note:** Avec un assistant : le skill `paid-mcp-tools` du plugin Perly Pay réalise cette recette dans votre projet. L’exemple exécutable est `examples/paid-mcp-server` (MIT) dans le dépôt du plugin.

## Comment ça marche

1. **Un pack de crédits** — Comme dans [Crédits API](https://pay.perly.io/docs/recipe-api-credits.md). Donnez un coût à chaque outil et indiquez-le dans sa description.
2. **Qui appelle** — Un serveur hébergé associe la clé API de chaque appelant à un `external_id` client. Seul votre serveur détient `PERLY_PAY_SECRET_KEY`.
3. **Facturer, puis exécuter** — `credits.consume` avec le nom de l’outil comme `action` et une nouvelle clé que votre serveur crée pour chaque appel, puis le travail.
4. **Solde insuffisant ?** — Renvoyez un résultat d’outil avec `isError: true` et le lien de recharge, pas une erreur de protocole : les clients l’affichent.
5. **Aides gratuites** — Des outils `balance` et `top_up`, pour qu’un agent puisse expliquer ce qui se passe.

**A paid tool**

```js
server.registerTool("summarize", { description: "Costs 3 credits.", inputSchema: { text: z.string() } }, async ({ text }, extra) => {
  const refused = await charge(userId, 3, "summarize", extra.requestId); // credits.consume, or a top-up message
  if (refused) return { isError: true, content: [{ type: "text", text: refused }] };
  return { content: [{ type: "text", text: summarize(text) }] };
});
```

## Lancez l’exemple

1. **Installez** — `npm install` dans `examples/paid-mcp-server` (Node 20.12+).
2. **Clé** — Copiez `.env.example` vers `.env` et mettez une clé de test (`sk_test_…`) dans `PERLY_PAY_SECRET_KEY`.
3. **Préparez** — `npm run setup` crée le produit et le prix avec votre clé et affiche leurs ids pour `.env`.
4. **Lancez** — `npm start` (ou `npm run dev`), comme l’indique son README.
5. **Payez sans portefeuille** — Ajoutez-le à Claude Code (`claude mcp add paid-tools -- npx tsx "$PWD/src/server.ts"`), lancez `word_stats` : il répond avec une page de recharge. Choisissez le pack, touchez **Simulate payment** et relancez.

## Pièges

- Mettre `PERLY_PAY_SECRET_KEY` dans une config MCP que d’autres copient. Hébergez le serveur, ou faites-le appeler votre backend.
- Facturer après le travail : un échec de facturation signifie alors du travail gratuit.
- Baser la clé de facturation sur l’id JSON-RPC : le client le choisit, et le même id renvoie la première facturation, donc l’outil tourne à nouveau gratuitement.
