WhatsApp API for AI agents: MCP server, llms.txt
Connect Claude, Cursor or VS Code to the WhatsApp Business API with the Genuka WA MCP server, plus llms.txt, Markdown docs and an OpenAPI spec.
To let an AI agent work with WhatsApp through Genuka WA, add the @genuka/whatsapp-mcp MCP server
to your client with an API key: Claude, Cursor or VS Code can then list your numbers, send
templates and run campaigns. To have an assistant write the integration code instead, point it at
/llms.txt, the .mdx pages and /openapi.json.
Last updated October 8, 2026
What can an AI agent do with Genuka WA?
Genuka WA is a REST API for the official WhatsApp Business Platform (Meta's Cloud API). Genuka is a Meta Tech Provider: you connect your own WhatsApp Business number through Meta's Embedded Signup, then send notifications, one-time codes and campaigns over HTTP. An agent can use it in two ways, and most teams end up with both:
| You want the agent to… | Use | What it gets |
|---|---|---|
| Act on your account: send a message, create a template, launch a campaign, check a number's health | The MCP server @genuka/whatsapp-mcp | 17 tools, each mapped to one /api/v1 endpoint |
| Write code in your repo that calls Genuka WA | /llms.txt, .mdx pages, /openapi.json, /pricing.md | The documentation and the API contract, in formats a model reads without a browser |
MCP is the open standard AI applications use to connect to external tools; Claude, ChatGPT, VS Code and Cursor all support it.
How do I install the Genuka WA MCP server?
Create an API key
In the dashboard, open the API keys page and create a
key (pk_live_…). It is shown once. If the agent only works for one of your businesses, pick that
business when you create the key: the agent will not be able to see or touch the others (see
Authentication).
You need Node.js 20 or later: the client starts the server with npx.
Add the server to your client
claude mcp add --env GENUKA_WA_API_KEY=pk_live_xxx --transport stdio genuka-wa -- npx -y @genuka/whatsapp-mcpTo share it with your team without committing the key, put this .mcp.json at the root of the
repo; Claude Code expands ${GENUKA_WA_API_KEY} from each developer's environment:
{
"mcpServers": {
"genuka-wa": {
"command": "npx",
"args": ["-y", "@genuka/whatsapp-mcp"],
"env": { "GENUKA_WA_API_KEY": "${GENUKA_WA_API_KEY}" }
}
}
}GENUKA_WA_BASE_URL is optional and defaults to https://wa.genuka.com.
Check the connection
In Claude Code, claude mcp list or /mcp shows the server as connected. Then ask the agent
"List my WhatsApp numbers": it calls list_numbers, which returns each number's id (the
connectionId every other tool needs), its business and its quality rating. If the key is
missing or wrong, the tool answers with the reason instead of failing silently.
Which tools does the MCP server expose?
| Tool | What it does | Sends or changes something? |
|---|---|---|
list_numbers | Connected numbers and their health | No |
get_number_health | Live quality rating, messaging limit tier, throughput, alerts | No |
send_text_message | Free-form text, inside the 24-hour window | Sends a message |
send_template_message | An approved template: variables, header, buttons, one-time code | Sends a message |
send_media_message | Image, video, audio, document or sticker | Sends a message |
list_templates / get_template | Templates, their status and Meta's review outcome | No |
create_template | Submits a template to Meta for review | Yes |
list_webhooks / create_webhook | Webhook endpoints; creation returns the signing secret once | Creation sends your account's events, customer messages included, to the URL |
test_webhook | Signed sample events sent to your endpoint | Calls your endpoint |
list_campaigns / get_campaign / list_campaign_recipients | Campaigns and per-recipient delivery | No |
create_campaign | A draft: one template, one number, a recipient list | Yes, sends nothing |
launch_campaign | Sends the campaign to every pending recipient | Sends messages |
get_subscription | Plan, usage and limits (account-wide key only) | No |
Each tool declares the MCP hints readOnlyHint, destructiveHint and idempotentHint, so your
client can approve reads automatically and ask you before anything that sends. Errors come back to
the agent with the API's own code (plan_limit_messages, connection_not_found,
meta_rejected…), Meta's code and trace id when there is one, and what to do next.
The server reads; it does not receive. Customer replies and delivery statuses arrive on your webhooks — see Receive WhatsApp replies and statuses via webhook.
What should I check before letting an agent send messages?
- It is a real message, to a real person. A send from the agent leaves from your number, like
one from your backend. Keep your client's confirmation prompt on for the tools that send, and
ask for the campaign to be shown to you before
launch_campaign. - A webhook is a data exit.
create_webhookforwards every event it subscribes to, including your customers' phone numbers and messages, to its URL for as long as the endpoint stays active. Keep the confirmation prompt on for it too, and check that the URL is one you gave the agent, not one it read in a web page or a file. The server tells the agent the same. - The 24-hour window. When a customer messages you, a 24-hour customer service window opens;
once it closes, only pre-approved templates can be sent
(Meta).
When Genuka WA cannot confirm that the window is open, the send result carries a
warning, and the server puts it at the top of what the agent reads, so it reaches you. - What it costs. Each message counts against your plan's allowance for the billing period
(plans,
/pricing.md). Meta charges for a template message when it is delivered, and non-template messages are free (Meta); Meta bills your own WhatsApp Business Account, with no markup from Genuka. - The key. Keep it out of git with the
${…}variables shown above, give the agent a key restricted to one business when that is enough, and revoke it from the dashboard when you are done.
How do I give my coding assistant the Genuka WA docs?
When the agent's job is to write your integration, it needs the contract more than the tools. Everything below is public, needs no API key, and stays in sync with the published docs:
| URL | Contents | When to use it |
|---|---|---|
/llms.txt | Index of every page (English, French, SDK) with one line each, following the llms.txt proposal | The first file to hand an agent |
/llms-full.txt | Every page's Markdown in a single file | Load the whole documentation into context at once |
Any page + .mdx | One page in Markdown, e.g. /en/docs/messages.mdx | Point to exactly the page that matters |
/openapi.json | OpenAPI 3.1 description of /api/v1 | Generate a typed client, or let the agent check field names |
/pricing.md | Plans, prices and limits in Markdown, generated from the billing catalog | Answer "how much will this cost me?" |
curl https://wa.genuka.com/llms.txt
curl https://wa.genuka.com/en/docs/webhooks.mdxWhat prompt should I give the assistant?
Name the product, the framework and the event, and let it read the docs. For example:
Add WhatsApp order-shipped notifications to my Next.js app with Genuka WA. Read https://wa.genuka.com/llms.txt first.
A good result has three parts: a UTILITY template such as order_shipped, submitted once and
approved by Meta; server-side code that calls POST /api/v1/messages when the order ships; and a
webhook route that verifies X-Genuka-Signature before trusting a status. With the order_shipped
template of the order notifications guide (three body
variables and a tracking-link button), the call looks like this. The values must match the
template's variables one for one, or Meta refuses the message (error 132000):
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": "order_shipped",
"language": "en",
"body": ["Awa", "ORD-1042", "DHL"],
"buttons": [{ "type": "url", "text": "ORD-1042" }]
}
}'The full walkthrough (template, idempotency, delivery tracking) is in WhatsApp order notifications from your backend.
What should I put in AGENTS.md?
AGENTS.md, CLAUDE.md or .cursor/rules are read by the assistant before every task. These
lines spare it the mistakes we see most often in WhatsApp integrations:
## 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
Does the MCP server send real WhatsApp messages?
Yes. send_text_message, send_template_message, send_media_message and launch_campaign send
from your connected number to real recipients, and count against your plan's allowance. Reads
(list_*, get_*) change nothing.
Is the MCP server free?
The @genuka/whatsapp-mcp package is MIT-licensed and free. It uses your Genuka WA account, billed
as a subscription per WhatsApp number (plans). Meta bills delivered template
messages to your own WhatsApp Business Account, with no markup from Genuka.
Which AI clients does it work with?
Any MCP client that can start a local (stdio) server: Claude Code, Claude Desktop, Cursor, VS Code and Windsurf are covered above. The server needs Node.js 20 or later.
Can the agent read my customers' replies?
Not through the MCP server: it has no tool for incoming messages. Replies and delivery statuses are
pushed to your webhook endpoint, which the agent can create with create_webhook (at a URL you
give it) and check with test_webhook.
How do I limit what the agent can reach?
Give it a key restricted to one business. Lists then return only that business's rows, any other
id answers 404, and get_subscription is refused — see Authentication.
Sources
- Meta — Send messages (customer service window)
- Meta — Pricing on the WhatsApp Business Platform
- Model Context Protocol — What is MCP?
- The /llms.txt proposal
- Claude Code — Connect Claude Code to tools via MCP
- MCP — Connect to local MCP servers (Claude Desktop)
- Cursor — Model Context Protocol
- VS Code — MCP configuration reference
- Devin Desktop (formerly Windsurf) — MCP
- Devin Desktop FAQ — Windsurf becomes Devin Desktop
How much does a WhatsApp message cost in Africa? (2026)
How much a WhatsApp Business message costs in Africa in 2026: Meta's rates by country and category, in USD, EUR and CFA francs, with a worked example.
API reference
One API to drive everything programmatically: numbers, templates, messages, campaigns and your subscription.