# API WhatsApp pour agents IA : serveur MCP, llms.txt

URL: https://wa.genuka.com/docs/guides/ai-agents
Language: French

> Connectez Claude, Cursor ou VS Code à l'API WhatsApp Business avec le serveur MCP de Genuka WA, llms.txt, la doc en Markdown et la spec OpenAPI.

Pour qu'un agent IA travaille avec WhatsApp via Genuka WA, ajoutez le serveur MCP
`@genuka/whatsapp-mcp` à votre client avec une clé API : Claude, Cursor ou VS Code peuvent alors
lister vos numéros, envoyer des templates et lancer des campagnes. Pour qu'un assistant écrive
plutôt le code d'intégration, donnez-lui `/llms.txt`, les pages `.mdx` et `/openapi.json`.

*Mis à jour le 8 octobre 2026*

## Que peut faire un agent IA avec Genuka WA ?

Genuka WA est une API REST pour la WhatsApp Business Platform officielle (la Cloud API de Meta).
Genuka est Meta Tech Provider : vous connectez votre propre numéro WhatsApp Business via
l'Embedded Signup de Meta, puis vous envoyez notifications, codes à usage unique et campagnes en
HTTP. Un agent peut s'en servir de deux façons, et la plupart des équipes finissent par utiliser
les deux :

| Vous voulez que l'agent…                                                                                            | Utilisez                                                      | Ce qu'il obtient                                                                        |
| ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| Agisse sur votre compte : envoyer un message, créer un template, lancer une campagne, vérifier la santé d'un numéro | Le serveur MCP `@genuka/whatsapp-mcp`                         | 17 outils, chacun relié à un endpoint `/api/v1`                                         |
| Écrive dans votre dépôt du code qui appelle Genuka WA                                                               | `/llms.txt`, les pages `.mdx`, `/openapi.json`, `/pricing.md` | La documentation et le contrat d'API, dans des formats qu'un modèle lit sans navigateur |

[MCP](https://modelcontextprotocol.io/docs/getting-started/intro) est le standard ouvert qui relie
les applications d'IA à des outils externes ; Claude, ChatGPT, VS Code et Cursor le prennent en
charge.

## Comment installer le serveur MCP de Genuka WA ?

1. ### Créez une clé API

   Dans le dashboard, ouvrez la [page des clés API](https://wa.genuka.com/dashboard/settings) et
   créez une clé (`pk_live_…`). Elle ne s'affiche qu'une fois. Si l'agent ne travaille que pour l'une
   de vos entreprises, choisissez-la à la création de la clé : l'agent ne pourra ni voir ni modifier
   les autres (voir [Authentification](https://wa.genuka.com/docs/authentication)).

   Il vous faut Node.js 20 ou plus récent : le client lance le serveur avec `npx`.

2. ### Ajoutez le serveur à votre client

   **Claude Code**

   ```bash
   claude mcp add --env GENUKA_WA_API_KEY=pk_live_xxx --transport stdio genuka-wa -- npx -y @genuka/whatsapp-mcp
   ```

   Pour partager la configuration avec l'équipe sans committer la clé, placez ce `.mcp.json` à la
   racine du dépôt ; Claude Code remplace `${GENUKA_WA_API_KEY}` par la variable d'environnement de
   chaque développeur :

   ```json title=".mcp.json"
   {
     "mcpServers": {
       "genuka-wa": {
         "command": "npx",
         "args": ["-y", "@genuka/whatsapp-mcp"],
         "env": { "GENUKA_WA_API_KEY": "${GENUKA_WA_API_KEY}" }
       }
     }
   }
   ```

   **Claude Desktop**

   **Settings → Developer → Edit Config** ouvre `claude_desktop_config.json`
   (`~/Library/Application Support/Claude/` sur macOS, `%APPDATA%\Claude\` sur Windows). Ajoutez le
   serveur, enregistrez, puis quittez et relancez Claude Desktop.

   ```json title="claude_desktop_config.json"
   {
     "mcpServers": {
       "genuka-wa": {
         "command": "npx",
         "args": ["-y", "@genuka/whatsapp-mcp"],
         "env": { "GENUKA_WA_API_KEY": "pk_live_xxx" }
       }
     }
   }
   ```

   **Cursor**

   Dans `~/.cursor/mcp.json` (tous les projets) ou `.cursor/mcp.json` (ce projet). `${env:…}` lit la
   clé dans votre environnement :

   ```json title=".cursor/mcp.json"
   {
     "mcpServers": {
       "genuka-wa": {
         "command": "npx",
         "args": ["-y", "@genuka/whatsapp-mcp"],
         "env": { "GENUKA_WA_API_KEY": "${env:GENUKA_WA_API_KEY}" }
       }
     }
   }
   ```

   **VS Code**

   Dans `.vscode/mcp.json`, ou via **MCP: Open User Configuration** pour tous les espaces de travail.
   VS Code demande la clé une fois et ne l'écrit pas dans le fichier :

   ```json title=".vscode/mcp.json"
   {
     "inputs": [
       { "type": "promptString", "id": "genuka-wa-api-key", "description": "Clé API Genuka WA", "password": true }
     ],
     "servers": {
       "genuka-wa": {
         "type": "stdio",
         "command": "npx",
         "args": ["-y", "@genuka/whatsapp-mcp"],
         "env": { "GENUKA_WA_API_KEY": "${input:genuka-wa-api-key}" }
       }
     }
   }
   ```

   **Windsurf**

   Windsurf s'appelle Devin Desktop depuis le 2 juin 2026. Dans le panneau Cascade, ouvrez le menu
   `…`, puis **Open MCP config file** :

   ```json title="mcp_config.json"
   {
     "mcpServers": {
       "genuka-wa": {
         "command": "npx",
         "args": ["-y", "@genuka/whatsapp-mcp"],
         "env": { "GENUKA_WA_API_KEY": "pk_live_xxx" }
       }
     }
   }
   ```

   `GENUKA_WA_BASE_URL` est facultatif ; sa valeur par défaut est `https://wa.genuka.com`.

3. ### Vérifiez la connexion

   Dans Claude Code, `claude mcp list` ou `/mcp` affiche le serveur comme connecté. Demandez ensuite à
   l'agent « Liste mes numéros WhatsApp » : il appelle `list_numbers`, qui renvoie l'`id` de chaque
   numéro (le `connectionId` dont tous les autres outils ont besoin), son entreprise et sa note de
   qualité. Si la clé manque ou est fausse, l'outil répond avec la raison au lieu d'échouer en
   silence.

## Quels outils le serveur MCP expose-t-il ?

| Outil                                                          | Ce qu'il fait                                                                         | Envoie ou modifie quelque chose ?                                                     |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `list_numbers`                                                 | Les numéros connectés et leur santé                                                   | Non                                                                                   |
| `get_number_health`                                            | Note de qualité, palier de limite d'envoi, débit et alertes, en direct                | Non                                                                                   |
| `send_text_message`                                            | Un texte libre, dans la fenêtre de 24 heures                                          | Envoie un message                                                                     |
| `send_template_message`                                        | Un template approuvé : variables, en-tête, boutons, code à usage unique               | Envoie un message                                                                     |
| `send_media_message`                                           | Image, vidéo, audio, document ou sticker                                              | Envoie un message                                                                     |
| `list_templates` / `get_template`                              | Les templates, leur statut et le verdict de Meta                                      | Non                                                                                   |
| `create_template`                                              | Soumet un template à la validation de Meta                                            | Oui                                                                                   |
| `list_webhooks` / `create_webhook`                             | Les endpoints de webhooks ; la création renvoie le secret de signature une seule fois | La création envoie les événements du compte, messages des clients compris, vers l'URL |
| `test_webhook`                                                 | Des événements d'exemple signés, envoyés à votre endpoint                             | Appelle votre endpoint                                                                |
| `list_campaigns` / `get_campaign` / `list_campaign_recipients` | Les campagnes et la livraison destinataire par destinataire                           | Non                                                                                   |
| `create_campaign`                                              | Un brouillon : un template, un numéro, une liste de destinataires                     | Oui, sans rien envoyer                                                                |
| `launch_campaign`                                              | Envoie la campagne à tous les destinataires en attente                                | Envoie des messages                                                                   |
| `get_subscription`                                             | Abonnement, consommation et limites (clé de compte uniquement)                        | Non                                                                                   |

Chaque outil déclare les indications MCP `readOnlyHint`, `destructiveHint` et `idempotentHint` :
votre client peut approuver les lectures automatiquement et vous demander confirmation avant tout
envoi. Les erreurs reviennent à l'agent avec le code de l'API (`plan_limit_messages`,
`connection_not_found`, `meta_rejected`…), le code et le trace id de Meta quand il y en a un, et
la marche à suivre.

Le serveur lit, il ne reçoit pas. Les réponses des clients et les statuts de livraison arrivent sur
vos webhooks — voir [Recevoir messages et statuts WhatsApp par webhook](https://wa.genuka.com/docs/guides/receive-messages-webhooks).

## Que vérifier avant de laisser un agent envoyer des messages ?

* **C'est un vrai message, à une vraie personne.** Un envoi de l'agent part de votre numéro, comme
  un envoi de votre backend. Gardez la demande de confirmation de votre client pour les outils qui
  envoient, et demandez à voir la campagne avant `launch_campaign`.
* **Un webhook fait sortir des données.** `create_webhook` transmet chaque événement auquel il est
  abonné, numéros et messages de vos clients compris, à son URL tant que l'endpoint reste actif.
  Gardez la demande de confirmation pour lui aussi, et vérifiez que l'URL est bien celle que vous
  avez donnée à l'agent, pas une URL lue dans une page web ou un fichier. Le serveur le dit aussi à
  l'agent.
* **La fenêtre de 24 heures.** Quand un client vous écrit, une fenêtre de service client de
  24 heures s'ouvre ; une fois fermée, seuls des templates préapprouvés peuvent être envoyés
  ([Meta](https://developers.facebook.com/documentation/business-messaging/whatsapp/messages/send-messages)).
  Quand Genuka WA ne peut pas confirmer que la fenêtre est ouverte, le résultat de l'envoi porte un
  `warning`, et le serveur le place en tête de ce que l'agent lit : il vous parvient.
* **Ce que ça coûte.** Chaque message est décompté du quota de votre abonnement pour la période
  facturée ([offres](https://wa.genuka.com/#pricing), [`/pricing.md`](https://wa.genuka.com/pricing.md)). Meta facture un message template
  quand il est délivré, et les messages hors template sont gratuits
  ([Meta](https://developers.facebook.com/documentation/business-messaging/whatsapp/pricing)) ;
  Meta facture votre propre compte WhatsApp Business, sans marge de Genuka.
* **La clé.** Gardez-la hors de git avec les variables `${…}` ci-dessus, donnez à l'agent une clé
  limitée à une entreprise quand cela suffit, et révoquez-la depuis le dashboard une fois le
  travail fini.

## Comment donner la doc de Genuka WA à mon assistant de code ?

Quand l'agent doit écrire votre intégration, il a besoin du contrat plus que des outils. Tout ce qui
suit est public, sans clé API, et suit la documentation publiée :

| URL                                | Contenu                                                                                                                        | Quand l'utiliser                                                       |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
| [`/llms.txt`](https://wa.genuka.com/llms.txt)           | L'index de toutes les pages (anglais, français, SDK), une ligne chacune, selon la proposition [llms.txt](https://llmstxt.org/) | Le premier fichier à donner à un agent                                 |
| [`/llms-full.txt`](https://wa.genuka.com/llms-full.txt) | Le Markdown de toutes les pages dans un seul fichier                                                                           | Charger toute la documentation dans le contexte d'un coup              |
| N'importe quelle page + `.mdx`     | Une page en Markdown, par exemple [`/docs/messages.mdx`](https://wa.genuka.com/docs/messages.mdx)                                                   | Pointer exactement la page utile                                       |
| [`/openapi.json`](https://wa.genuka.com/openapi.json)   | La description OpenAPI 3.1 de `/api/v1`                                                                                        | Générer un client typé, ou laisser l'agent vérifier les noms de champs |
| [`/pricing.md`](https://wa.genuka.com/pricing.md)       | Offres, prix et limites en Markdown, générés depuis le catalogue de facturation                                                | Répondre à « combien ça va me coûter ? »                               |

```bash
curl https://wa.genuka.com/llms.txt
curl https://wa.genuka.com/docs/webhooks.mdx
```

## Quel prompt donner à l'assistant ?

Nommez le produit, le framework et l'événement, et laissez-le lire la doc. Par exemple :

> Ajoute des notifications WhatsApp « commande expédiée » à mon app Next.js avec Genuka WA. Lis
> d'abord [https://wa.genuka.com/llms.txt](https://wa.genuka.com/llms.txt).

Un bon résultat a trois parties : un template `UTILITY` comme `commande_expediee`, soumis une fois
et approuvé par Meta ; du code serveur qui appelle `POST /api/v1/messages` à l'expédition de la
commande ; et une route de webhook qui vérifie `X-Genuka-Signature` avant de croire un statut. Avec
le template `commande_expediee` du [guide des notifications de commande](https://wa.genuka.com/docs/guides/order-notifications)
(trois variables dans le corps et un bouton de suivi), l'appel ressemble à ceci. Les valeurs doivent
correspondre une à une aux variables du template, sinon Meta refuse le message
([erreur 132000](https://wa.genuka.com/docs/errors/132000)) :

**curl**

```bash
curl -X POST https://wa.genuka.com/api/v1/messages \
  -H "Authorization: Bearer $GENUKA_WA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "connectionId": "con_1",
    "to": "+237690000001",
    "template": {
      "name": "commande_expediee",
      "language": "fr",
      "body": ["Awa", "CMD-1042", "DHL"],
      "buttons": [{ "type": "url", "text": "CMD-1042" }]
    }
  }'
```

**Node.js**

```ts title="lib/whatsapp.ts"
export async function notifyOrderShipped(phone: string, firstName: string, orderNumber: string, carrier: string) {
  const response = await fetch("https://wa.genuka.com/api/v1/messages", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.GENUKA_WA_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      connectionId: process.env.GENUKA_WA_CONNECTION_ID,
      to: phone, // E.164 : "+237690000001"
      template: {
        name: "commande_expediee",
        language: "fr",
        body: [firstName, orderNumber, carrier], // {{1}}, {{2}}, {{3}} dans l'ordre
        buttons: [{ type: "url", text: orderNumber }], // complète le lien de suivi
      },
    }),
  });
  const result = await response.json();
  if (!response.ok) throw new Error(`${result.error}: ${result.message ?? ""}`);
  return result.data.messageId as string; // accepté par Meta, pas encore délivré
}
```

**Python**

```python title="whatsapp.py"
import os
import requests

def notify_order_shipped(phone: str, first_name: str, order_number: str, carrier: str) -> str:
    response = requests.post(
        "https://wa.genuka.com/api/v1/messages",
        headers={"Authorization": f"Bearer {os.environ['GENUKA_WA_API_KEY']}"},
        json={
            "connectionId": os.environ["GENUKA_WA_CONNECTION_ID"],
            "to": phone,  # E.164 : "+237690000001"
            "template": {
                "name": "commande_expediee",
                "language": "fr",
                "body": [first_name, order_number, carrier],  # {{1}}, {{2}}, {{3}} dans l'ordre
                "buttons": [{"type": "url", "text": order_number}],  # complète le lien de suivi
            },
        },
        timeout=30,
    )
    result = response.json()
    if not response.ok:
        raise RuntimeError(f"{result['error']}: {result.get('message', '')}")
    return result["data"]["messageId"]  # accepté par Meta, pas encore délivré
```

**PHP**

```php title="whatsapp.php"
<?php
function notifyOrderShipped(string $phone, string $firstName, string $orderNumber, string $carrier): string
{
    $ch = curl_init('https://wa.genuka.com/api/v1/messages');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . getenv('GENUKA_WA_API_KEY'),
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS => json_encode([
            'connectionId' => getenv('GENUKA_WA_CONNECTION_ID'),
            'to' => $phone, // E.164 : "+237690000001"
            'template' => [
                'name' => 'commande_expediee',
                'language' => 'fr',
                'body' => [$firstName, $orderNumber, $carrier], // {{1}}, {{2}}, {{3}} dans l'ordre
                'buttons' => [['type' => 'url', 'text' => $orderNumber]], // complète le lien de suivi
            ],
        ]),
    ]);
    $result = json_decode(curl_exec($ch), true);
    $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    if ($status >= 400) {
        throw new RuntimeException($result['error'] . ': ' . ($result['message'] ?? ''));
    }
    return $result['data']['messageId']; // accepté par Meta, pas encore délivré
}
```

Le guide complet (template, idempotence, suivi de livraison) est dans
[Notifications de commande WhatsApp depuis votre backend](https://wa.genuka.com/docs/guides/order-notifications).

## Que mettre dans AGENTS.md ?

`AGENTS.md`, `CLAUDE.md` ou `.cursor/rules` sont lus par l'assistant avant chaque tâche. Ces lignes
lui évitent les erreurs que nous voyons le plus souvent dans les intégrations WhatsApp. Elles sont
en anglais, la langue que ces fichiers partagent le plus souvent dans une équipe :

```md title="AGENTS.md"
## WhatsApp (Genuka WA)

- WhatsApp goes through the Genuka WA REST API: base URL https://wa.genuka.com/api/v1,
  header `Authorization: Bearer $GENUKA_WA_API_KEY`. Server-side only: never ship the key to a
  browser or a mobile app. We do not call Meta's Graph API directly.
- Docs for agents: https://wa.genuka.com/llms.txt; append `.mdx` to any docs URL for Markdown;
  API contract: https://wa.genuka.com/openapi.json.
- `connectionId` is the `id` returned by `GET /api/v1/connections`. It lives in config
  (`GENUKA_WA_CONNECTION_ID`), never hard-coded.
- Phone numbers are E.164: `+237690000001`.
- Business-initiated messages (order updates, reminders, codes) are templates. Free-form `text`
  is only delivered within 24 hours of the customer's last message.
- Templates are created once (`POST /api/v1/templates`) and reviewed by Meta; only `approved`
  ones can be sent. Use the template's exact `language`.
- A 200 from `POST /api/v1/messages` means Meta accepted the message, not that it was delivered.
  Delivery and replies arrive on webhooks; verify `X-Genuka-Signature` on the raw body first.
- Errors are `{ "error": "code", "message": "…" }`. Never retry `plan_limit_messages`; when the
  body has `meta.retryable: false`, change the request instead of retrying it.
```

## FAQ

### Le serveur MCP envoie-t-il de vrais messages WhatsApp ?

Oui. `send_text_message`, `send_template_message`, `send_media_message` et `launch_campaign`
envoient depuis votre numéro connecté à de vrais destinataires, et sont décomptés de votre quota.
Les lectures (`list_*`, `get_*`) ne modifient rien.

### Le serveur MCP est-il gratuit ?

Le paquet `@genuka/whatsapp-mcp` est sous licence MIT et gratuit. Il utilise votre compte Genuka WA,
facturé en abonnement par numéro WhatsApp ([offres](https://wa.genuka.com/#pricing)). Meta facture les messages template
délivrés à votre propre compte WhatsApp Business, sans marge de Genuka.

### Avec quels clients IA fonctionne-t-il ?

Tout client MCP capable de lancer un serveur local (stdio) : Claude Code, Claude Desktop, Cursor,
VS Code et Windsurf sont couverts plus haut. Le serveur demande Node.js 20 ou plus récent.

### L'agent peut-il lire les réponses de mes clients ?

Pas via le serveur MCP : il n'a aucun outil pour les messages entrants. Les réponses et les statuts
de livraison sont poussés vers votre endpoint de webhook, que l'agent peut créer avec
`create_webhook` (à une URL que vous lui donnez) et tester avec `test_webhook`.

### Comment limiter ce que l'agent peut atteindre ?

Donnez-lui une clé limitée à une entreprise. Les listes ne renvoient alors que les lignes de cette
entreprise, tout autre identifiant répond `404`, et `get_subscription` est refusé — voir
[Authentification](https://wa.genuka.com/docs/authentication).

## Sources

* [Meta — Send messages (fenêtre de service client)](https://developers.facebook.com/documentation/business-messaging/whatsapp/messages/send-messages)
* [Meta — Pricing on the WhatsApp Business Platform](https://developers.facebook.com/documentation/business-messaging/whatsapp/pricing)
* [Model Context Protocol — What is MCP?](https://modelcontextprotocol.io/docs/getting-started/intro)
* [La proposition /llms.txt](https://llmstxt.org/)
* [Claude Code — Connect Claude Code to tools via MCP](https://code.claude.com/docs/en/mcp)
* [MCP — Connect to local MCP servers (Claude Desktop)](https://modelcontextprotocol.io/docs/develop/connect-local-servers)
* [Cursor — Model Context Protocol](https://cursor.com/docs/context/mcp)
* [VS Code — MCP configuration reference](https://code.visualstudio.com/docs/copilot/reference/mcp-configuration)
* [Devin Desktop (ex-Windsurf) — MCP](https://docs.devin.ai/desktop/cascade/mcp)
* [FAQ Devin Desktop — Windsurf devient Devin Desktop](https://docs.devin.ai/desktop/devin-desktop-faq)
