Meta Cloud API MCP Server
This MCP server lets MCP clients like Claude, Cursor, and other assistants send WhatsApp messages and manage templates, media, flows, and the business profile through the WhatsApp Cloud API.
Send text, template, image, and interactive button/list messages, and mark messages as read
Upload, inspect, download, and delete media files
Create, list, update, and delete WhatsApp message templates
Manage WhatsApp Business Profile details and phone numbers
Request verification codes, verify, register, and deregister phone numbers
View WhatsApp Business Account status and subscribe/unsubscribe WABA webhooks
Create, retrieve, update, publish, deprecate, and delete WhatsApp Flows
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Meta Cloud API MCP Server Send a template message to +15551234567"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
What is this?
This server wraps the meta-cloud-api SDK (v3.8+) and exposes it as MCP tools over stdio. Once connected you can ask your assistant things like:
"Send the
order_updatetemplate in English to +1 415 555 2671 with order number 4821""Send a message to +14155552671 with Yes / No buttons asking to confirm tomorrow's appointment"
"Upload
~/Desktop/menu.pdfand send it as a document""List my approved marketing templates"
"What is the quality rating of our phone number?"
Related MCP server: WAHA WhatsApp MCP Server
Requirements
Node.js 20.12 or later
A Meta app with the WhatsApp product, and a WhatsApp Business Account
An MCP client (Claude Desktop, Claude Code, Cursor, ...)
Environment variables
Variable | Required | Where to find it |
| yes | App Dashboard > WhatsApp > API Setup (use a System User token for anything long-lived) |
| yes | App Dashboard > WhatsApp > API Setup > Phone number ID |
| for template, phone-number list, WABA and flow tools | App Dashboard > WhatsApp > API Setup > WhatsApp Business Account ID |
| no | Graph API version, e.g. |
The server starts without credentials so clients can list its tools; a tool call then returns a ConfigError naming the missing variable. The access token is never logged, and is redacted from tool output (Meta sometimes echoes it back in error messages). DEBUG is ignored on purpose, because the SDK's debug logger prints part of the token.
Install
There is nothing to install globally: MCP clients run the server with npx.
npx -y meta-cloud-api-mcp # speaks MCP on stdin/stdout; normally launched by your clientClaude Code
claude mcp add whatsapp \
-e CLOUD_API_ACCESS_TOKEN=your_access_token \
-e WA_PHONE_NUMBER_ID=your_phone_number_id \
-e WA_BUSINESS_ACCOUNT_ID=your_waba_id \
-- npx -y meta-cloud-api-mcpAdd --scope user to make it available in every project, or --scope project to write a shareable .mcp.json (keep real tokens out of version control). Check it with claude mcp list or /mcp inside Claude Code.
Claude Desktop
Settings > Developer > Edit Config, then add to claude_desktop_config.json and restart Claude Desktop:
{
"mcpServers": {
"whatsapp": {
"command": "npx",
"args": ["-y", "meta-cloud-api-mcp"],
"env": {
"CLOUD_API_ACCESS_TOKEN": "your_access_token",
"WA_PHONE_NUMBER_ID": "your_phone_number_id",
"WA_BUSINESS_ACCOUNT_ID": "your_waba_id"
}
}
}
}Cursor
Add to ~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project):
{
"mcpServers": {
"whatsapp": {
"command": "npx",
"args": ["-y", "meta-cloud-api-mcp"],
"env": {
"CLOUD_API_ACCESS_TOKEN": "your_access_token",
"WA_PHONE_NUMBER_ID": "your_phone_number_id",
"WA_BUSINESS_ACCOUNT_ID": "your_waba_id"
}
}
}
}Any other stdio MCP client works the same way: command npx, args ["-y", "meta-cloud-api-mcp"], plus the env vars above.
Tools (34)
Every tool validates its input with zod before calling Meta, and is annotated as read-only, write or destructive so clients can ask for confirmation. Failures come back as isError results with the SDK error class (WhatsAppAuthorizationError, WhatsAppSendMessageError, WhatsAppThrottlingError, ...), Meta's error code, fbtrace_id, and a hint for common cases such as an expired token or the 24-hour window.
Messages
Free-form messages only reach users who wrote to you in the last 24 hours. Outside that window, send a template.
Tool | Description |
| Send a text message (optional link preview, optional quoted reply) |
| Send an approved template with variable components |
| Send an image, video, audio, document or sticker by |
| Send up to 3 quick-reply buttons with optional header and footer |
| Send a list menu (up to 10 rows across sections) |
| Mark an incoming message as read, optionally with a typing indicator |
Templates
Tool | Description |
| List templates, filtered by name, status, category or language |
| Get one template with its components |
| Create a template and submit it for review |
| Edit components or category (re-submits for review) |
| Delete a template, or one language version via |
Media
Tool | Description |
| Upload a local file and get a media ID |
| Get the download URL, MIME type, size and hash of a media ID |
| Download media from that URL to a local file |
| Delete uploaded media |
Business profile and phone numbers
Tool | Description |
| Get about, address, description, email, websites, vertical, picture |
| Update any of those fields |
| List phone numbers in the WABA |
| Get details of the configured sender number |
| Request a verification code by SMS or voice |
| Verify the number with the received code |
| Register the number with a 6-digit PIN |
| Deregister the number |
WhatsApp Business Account
Tool | Description |
| Get account status, review and verification status, limits |
| Subscribe your app to WABA webhooks (optional callback override) |
| Unsubscribe your app |
Flows
Tool | Description |
| List Flows |
| Get a Flow with status and validation errors |
| Create a Flow (inline JSON or clone) |
| Rename, recategorize or change the endpoint |
| Upload a new Flow JSON |
| Publish a draft Flow |
| Deprecate a published Flow |
| Delete a draft Flow |
Upgrading from 1.x
send_image_messagewas replaced bysend_media_message(type: "image").get_media_infowas renamed toget_media_url.Node.js 20.12+ is required (inherited from meta-cloud-api 3.x).
Development
git clone https://github.com/froggy1014/meta-cloud-api-mcp.git
cd meta-cloud-api-mcp
npm install
npm run typecheck
npm test # vitest, with the SDK mocked
npm run buildTry it interactively with the MCP Inspector:
npx @modelcontextprotocol/inspector node dist/index.jsRelated
meta-cloud-api: the TypeScript SDK this server wraps
License
MIT, see LICENSE.
Available Tools
31 toolscreate_flowA
Create a new WhatsApp Flow. Optionally provide flow_json inline or clone from an existing flow.
Inputs: name (required), publish, waba_id, flow_json, +3 more.
create_templateA
Create a new WhatsApp message template. Components array should follow Meta template component schema (HEADER, BODY, FOOTER, BUTTONS).
Inputs: name (required), language (required), category, components, +2 more.
delete_flowA
Delete a WhatsApp Flow. Only DRAFT flows can be deleted.
Inputs: flow_id (required).
delete_mediaB
Delete a media file from WhatsApp servers by media ID
Inputs: media_id (required).
delete_templateA
Delete a WhatsApp message template by name. Optionally specify hsm_id to delete a specific language version.
Inputs: name (required), hsm_id.
deprecate_flowA
Deprecate a PUBLISHED WhatsApp Flow. This is irreversible — the flow can no longer be used.
Inputs: flow_id (required).
deregister_phoneB
Deregister a WhatsApp Business phone number
Inputs: no named parameters.
download_mediaA
Download media content from a WhatsApp media URL. Use get_media_info first to obtain the URL.
Inputs: media_url (required), save_path (required).
get_business_profileA
Get the WhatsApp Business Profile — about, address, description, email, websites, profile picture URL
Inputs: fields.
get_flowA
Get details of a WhatsApp Flow by ID, including status, categories, and validation errors
Inputs: flow_id (required), fields.
get_media_infoA
Get metadata for a media object by ID — returns URL, MIME type, file size, and SHA-256 hash
Inputs: media_id (required).
get_phone_numberB
Get information about the configured WhatsApp Business phone number — display number, verified name, quality rating, status
Inputs: fields.
get_templateA
Get a single WhatsApp message template by ID with full definition including components
Inputs: template_id (required).
get_waba_accountA
Get WhatsApp Business Account information — name, status, health, verification, messaging limits
Inputs: fields.
list_flowsA
List all WhatsApp Flows for a WhatsApp Business Account
Inputs: waba_id.
list_phone_numbersA
List all phone numbers associated with the WhatsApp Business Account
Inputs: no named parameters.
list_templatesA
List WhatsApp message templates with optional filters (name, status, category, language)
Inputs: name, limit, status, category, +1 more.
publish_flowA
Publish a DRAFT WhatsApp Flow. Once published, the flow JSON cannot be modified.
Inputs: flow_id (required).
register_phoneB
Register a WhatsApp Business phone number with a 6-digit PIN
Inputs: pin (required), data_localization_region.
request_verification_codeA
Request a verification code for the WhatsApp Business phone number via SMS or voice call
Inputs: language (required), code_method (required).
send_image_messageA
Send an image message via WhatsApp. Provide either an image_id (from media upload) or image_link (public URL).
Inputs: to (required), caption, image_id, image_link, +1 more.
send_template_messageA
Send a pre-approved template message via WhatsApp. Templates must be created and approved before sending.
Inputs: to (required), language_code (required), template_name (required), components.
send_text_messageB
Send a text message via WhatsApp to a phone number
Inputs: to (required), body (required), reply_message_id.
subscribe_waba_webhookA
Subscribe your app to WABA webhooks. Optionally override the callback URL and verify token.
Inputs: verify_token, override_callback_uri.
unsubscribe_waba_webhookA
Unsubscribe your app from WABA webhooks
Inputs: no named parameters.
update_business_profileA
Update the WhatsApp Business Profile fields — about, address, description, email, websites, vertical
Inputs: about, email, address, vertical, +2 more.
update_flow_jsonC
Upload or update the Flow JSON definition for a WhatsApp Flow. Accepts JSON as a string or object.
Inputs: flow_id (required), flow_json (required).
update_flow_metadataA
Update metadata of an existing WhatsApp Flow (name, categories, endpoint URI)
Inputs: flow_id (required), name, categories, endpoint_uri.
update_templateA
Update an existing WhatsApp message template. Only components and category can be updated. Template is resubmitted for review.
Inputs: template_id (required), category, components.
upload_mediaA
Upload a media file to WhatsApp. Returns a media ID that can be used in messages. Supported: image (5MB), video (16MB), audio (16MB), document (100MB), sticker (500KB).
Inputs: file_name (required), file_path (required), mime_type (required).
verify_phone_codeA
Verify the WhatsApp Business phone number with the code received via SMS or voice call
Inputs: code (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 31 tools
Each tool targets a distinct resource and action, with clear boundaries between list/get, send types, media operations, and phone management. Even similar-sounding tools like update_flow_metadata vs update_flow_json are well-differentiated by their descriptions.
All tool names follow a consistent verb_noun pattern with lowercase snake_case. Verbs are clear and uniform (list, get, create, update, delete, send, upload, download, subscribe, etc.), and no mixed conventions like camelCase or vague verbs appear.
At 31 tools, the count exceeds the 25-tool threshold for 'too many', which can overwhelm agents and increase selection complexity. While the broad scope of the WhatsApp Cloud API justifies some breadth, the sheer number makes the toolset feel heavy for an MCP server.
The toolset covers templates, flows, media, business profile, webhooks, and phone numbers thoroughly, but messaging is limited to text, template, and image. Missing send_video, send_audio, send_document, and sticker message types create significant gaps that will likely cause agent failures.
Maintenance
Related MCP Connectors
WhatsApp for Claude, ChatGPT or any AI agent: search, reply and send. Personal or Business API.
Your own WhatsApp in Claude and ChatGPT: read chats, draft replies, send messages you approve.
WhatsMCP connects Claude and other MCP-compatible AI agents directly to WhatsApp. Send and receive text, images, documents, and voice notes; manage groups (create, add/remove members, promote admins); look up contacts and profiles; follow channels; and read call and message history — all through a standard MCP interface. For voice use cases, WhatsMCP offers SIP-based calling plans (inbound-only, or full inbound/outbound) so AI voice agents can answer and place WhatsApp calls, plus low-latency WebSocket integrations with voice agent providers like ElevenLabs. Multiple WhatsApp accounts can be paired and managed per workspace, with webhook support for real-time inbound message delivery to your own infrastructure.
Business WhatsApp from Claude: read chats, reply to customers, pause the AI agent, edit its prompt.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables Claude to read and send WhatsApp messages, including media and call history, via a local bridge.13MIT
- AlicenseAqualityDmaintenanceEnables Claude to interact with WhatsApp through a unified backend API, providing 20 tools for messaging, media, groups, contacts, and chat management.2222 npmMIT
- AlicenseAqualityDmaintenanceEnables LLMs to interact with WhatsApp via the official WhatsApp Cloud API, providing tools for sending messages, templates, media, and managing conversations.1313 npmMIT
- FlicenseNot gradedqualityAmaintenanceEnables a Claude Code session to send and receive WhatsApp messages through either a linked-device pairing or the official Cloud API, including media, local voice-note transcription, and @-mentions. It also gates inbound chats with pairing codes, allowlists and per-group policies, and lets users approve or deny tool requests with an emoji reaction.-