Docs / Start
MCP server
The wuapi MCP server gives an AI client that speaks the Model Context Protocol, such as Claude, Cursor or VS Code, 51 tools over your wuapi account: send a message, show the QR code that links a number, read a conversation, add people to a group, set up a webhook, invite a customer. Each tool call is one request to the REST API with your API key, so the key's scope, the limit of 600 requests per minute per key and the dashboard Logs apply as for any other client.
| local (stdio) | hosted (Streamable HTTP) | |
|---|---|---|
| runs | on your machine: npx -y @wuapidev/mcp | at https://wuapi.dev/api/mcp |
| key | WUAPI_API_KEY environment variable | Authorization: Bearer wu_live_... header |
| needs | Node 20 or later | a client that sends a custom header |
Connect a client
Create a key under API keys in the dashboard. A project key limits the server to one project. Then add the server to your client:
# Local: runs on your machine
claude mcp add wuapi --env WUAPI_API_KEY=wu_live_... -- npx -y @wuapidev/mcp
# Hosted: nothing to install
claude mcp add --transport http wuapi https://wuapi.dev/api/mcp --header "Authorization: Bearer $WUAPI_API_KEY"The dashboard's MCP server screen (/app/mcp) builds these for you from one of your keys, with read-only and a project as options, one-click install links for Cursor and VS Code and a connection test. Claude Desktop reads claude_desktop_config.json (Settings, Developer, Edit Config). Cursor reads ~/.cursor/mcp.json, or .cursor/mcp.json in a project. VS Code reads .vscode/mcp.json and asks for the key once, so it stays out of the file. Any other client that starts a local command works with the stdio server and WUAPI_API_KEY in its environment; any client that sends a custom header works with the hosted one. Clients that reach remote servers only through OAuth, as some chat apps do, cannot use the hosted endpoint yet.
Configuration
| stdio variable | hosted header | does |
|---|---|---|
| WUAPI_API_KEY | Authorization: Bearer ... | Required. Your API key. |
| WUAPI_PROJECT | Wuapi-Project | Act inside one project: its id or ext:<externalId>. |
| WUAPI_MCP_READ_ONLY | Wuapi-Read-Only | true registers only the tools that read. The --read-only flag does the same. |
| WUAPI_BASE_URL | API base URL. Default https://api.wuapi.dev. Must be https, or http on localhost. |
Tools
| area | tools |
|---|---|
| Context | get_current_key |
| Accounts | list_accounts, get_account, get_account_qr_code, create_account, request_pairing_code, reconnect_account, list_proxy_locations |
| Messages | send_text, send_media, send_location, send_contact, send_poll, reply_to_message, react_to_message, get_message, list_messages, edit_message, delete_message, cancel_message |
| Chats | mark_chat_read, send_read_receipts, archive_chat, pin_chat, mute_chat |
| Contacts | check_numbers, lookup_contacts |
| Groups | list_groups, get_group, create_group, add_group_participants, remove_group_participants, promote_group_participants, demote_group_participants, get_group_invite_link, reset_group_invite_link, leave_group |
| Stories | post_story |
| Webhooks | list_webhooks, create_webhook, update_webhook, delete_webhook |
| Projects | list_projects, get_project, create_project |
| Invitations | create_invitation, list_invitations, get_invitation, cancel_invitation |
| Usage | get_usage, get_usage_by_project |
Every tool declares a JSON schema for its input and returns the API's own object as structured content, without nulls. Tools that read carry readOnlyHint. Tools that delete, revoke, cancel or leave carry destructiveHint and take confirm: true, which the model has to set on purpose and your client shows you before the call: delete_message, cancel_message, remove_group_participants, reset_group_invite_link, leave_group, delete_webhook, cancel_invitation. Sends take an optional idempotencyKey, so a retried call does not send twice. get_account_qr_code returns the QR code as an image the client can show.
Projects, invitations and usage need an organization key. Listing chats, sending a test webhook event and reading the request log have no public endpoint, so they are not tools; they are in the dashboard.
Resources and prompts
Resources a client can attach to the conversation: https://wuapi.dev/openapi.json, https://wuapi.dev/llms-full.txt, https://wuapi.dev/llms.txt and wuapi://webhook-events. Prompts, which Claude Code lists as slash commands: send_message (to, message), setup_webhook (url, events) and invite_customer (customer, externalId, email).
Examples
| you ask | the tools it calls |
|---|---|
| Send "Your order shipped" to +584241112233 from the Front desk number. | list_accounts, check_numbers, send_text, get_message |
| Link a new number that exits from Mexico City. | list_proxy_locations, create_account, get_account_qr_code |
| What did +584241112233 write today? Reply that we're on it. | list_messages, reply_to_message |
| Send my webhook the incoming messages at https://example.com/hooks/wuapi. | list_webhooks, create_webhook |
| Invite Northwind (customer_8812) to link their WhatsApp. | list_projects, create_project, create_invitation |
| How much did each customer use last month? | get_usage_by_project |
Security
- The key stays in your client's configuration or header. The server never logs it, never returns it and never puts it in an error. The hosted endpoint stores nothing: it checks the key with
GET /v1/mewhen a client connects, then passes it to the API on each call. - Tool results carry no secrets. A webhook endpoint's signing secret is returned by the API only when the endpoint is created;
create_webhookdrops it and tells you to reveal it in the dashboard. No tool creates API keys. - Narrow what the model can do: a project key reaches one project, and read-only mode removes every tool that writes.
- Media URLs are downloaded by the API, which refuses private and internal addresses; the MCP server fetches nothing on a tool's behalf.
- Every argument is checked against the tool's schema before any request. A base URL that is not https is refused, so the key never travels in clear text.
- A model can be steered by what it reads, including inbound messages. Keep your client's confirmation prompts on for tools that send or delete.
The source is the npm package @wuapidev/mcp (MIT), built on the TypeScript SDK. It also exports createWuapiMcpServer and a stateless HTTP handler, createWuapiMcpHttpHandler from @wuapidev/mcp/http, to host it yourself.
The tools call the REST API: every endpoint, error code and webhook event is in the docs and openapi.json.