Wabery MCP server
Connect Claude, ChatGPT, Cursor, Codex, or another MCP client and build by describing the result. Use the hosted server with OAuth, or run a local server through the Wabery CLI.
Set either path up under Access → Connections. You can disconnect it there too.
The wabery_create_group and wabery_send_group_message tools require a
caller-generated stable idempotency key. If either returns an operation or
message_request with status: "processing", keep that key for
reconciliation; invoking the operation with a new key can create a duplicate
provider operation.
Hosted MCP server
Section titled “Hosted MCP server”Point your client here and sign in. No API key or CLI:
https://mcp.wabery.comThe standard MCP manifest is published at
https://wabery.com/.well-known/mcp.json
and https://mcp.wabery.com/server.json.
Transport is Streamable HTTP at https://mcp.wabery.com. The docs page you
are reading is the human tutorial; agents that POST JSON-RPC here get a
docs-oriented MCP handshake that points at the product server.
Unauthenticated clients can list tools and resources; calling write tools
requires OAuth. Public source for the CLI and Claude plugin lives on GitHub
at waberyhq/cli and
waberyhq/wabery-claude-plugin.
Use Wabery from ChatGPT. You sign in with your account, no key to copy.
Step 1 of 13
- 1Open ChatGPT in your browser and sign in. You need a paid plan for this: Plus, Pro, Business, or Enterprise.
| Client | Setup |
|---|---|
| Claude Code | claude mcp add --transport http wabery https://mcp.wabery.com, then /mcp to sign in. |
| Cursor | Customize → MCP → add a server with URL https://mcp.wabery.com, then click “Needs login”. |
| Codex CLI | Add [mcp_servers.wabery] with url = "https://mcp.wabery.com" and auth = "oauth" to ~/.codex/config.toml, then run codex mcp login wabery. |
Unlike the local server below, the hosted server has write tools enabled.
Your OAuth scopes decide what an agent is allowed to change. Broadcast delivery
uses the separate broadcasts:send scope. Every high-risk hosted action,
including destructive changes, publishing, function deployment, and broadcast
delivery, requests an MCP elicitation that the person must accept in the
client; an agent cannot approve its own request. Any MCP client that advertises
elicitation uses it, including local clients. A local client without elicitation
falls back to a confirmation_token; hosted clients without elicitation fail
closed.
Local MCP server (CLI)
Section titled “Local MCP server (CLI)”Prefer a local process? Install the Wabery CLI, then print an MCP server config for your agent and drop it into its config file — Claude Code, Codex, and OpenCode are supported:
wabery mcp-config claude --rawwabery mcp-config codex --rawwabery mcp-config opencode --rawThen just describe what you want:
The MCP server exposes the core Wabery primitives an agent needs to build an
integration: projects, channels, routing, contacts, registration intents,
conversations, message history, outbound messages, inbound media metadata,
templates, broadcasts, WhatsApp Flows, hosted functions, submissions, dispatches,
WhatsApp Groups, WhatsApp Calling control, automations, webhooks, config-as-code,
hosted-agent Drafts, and Meta Business Agent tools. The local server starts
read-only by default; pass --write
(or set WABERY_MCP_MODE=write) to allow mutations in a trusted local session.
When the external webhook is ready for the four group management event names,
call wabery_update_project with group_webhook_events_enabled: true. It stays
false by default so existing handlers do not receive group.lifecycle,
group.participants, group.settings, or group.status unexpectedly.
A project has one hosted AI agent with two versions. Live is what customers
currently use and is read-only. Draft is the only editable version and is
tested in Sandbox. wabery_validate_config, wabery_preview_config_diff, and
wabery_apply_config can only create or change that Draft. They cannot edit
Live or publish. Publishing to Live happens on Agent after review.
There is no MCP tool that publishes a hosted agent.
Hosted function MCP tools let an agent list, create, deploy, test, expose, invoke, tail logs, and delete project-scoped server-side handlers. Function write tools require confirmation: clients advertising elicitation use it, while local clients without elicitation use confirmation tokens in write mode.
For calls, use wabery_get_whatsapp_management to read calling_settings or
call_permissions, and wabery_manage_whatsapp to run
update_calling_settings or manage_call. wabery_send_message can send
call_permission_request and voice_call interactive messages. MCP transports
configuration and signaling data, not live audio; your WebRTC or SIP service
must handle media. Follow WhatsApp Calling for the
complete setup and approval-sensitive call sequence.
Eligible India and Singapore Payments API messages use
wabery_send_message. Put the regional order_details or order_status
interactive object in the tool’s REST-shaped body; Wabery preserves Meta’s
country-specific nested payment fields. See Regional payment
messages.
For media-aware agents, use wabery_list_conversation_messages to inspect
history. Retained inbound WhatsApp files appear as media/assets metadata with
short-lived signed URLs; download them promptly and treat expires_at as the
retention deadline.
Inbound WhatsApp message history distinguishes unavailable content from
mutations. An outer type: "unsupported" message normally means Cloud API did
not provide the original body (errors 131051/131060), but inspect its nested
unsupported.type: revoke and edit are delete/edit mutations, including
when the outer type remains unsupported. Never call wabery_send_message to
answer a revoke or edit; other unsupported subtypes may be handled as
unavailable content.
For template and locale-aware workflows, agents should inspect
publish_readiness on wabery_get_channel before creating templates. Templates
need a dedicated non-sandbox WhatsApp channel, Meta business verification, and a
Meta payment method; blockers such as BUSINESS_NOT_VERIFIED or
NO_PAYMENT_METHOD mean the template should not be submitted yet. When enrolling
contacts, set preferred_language if later flow sends should resolve a
locale-specific config key. After wabery_send_message, use wabery_get_message
to inspect queued/provider status and Meta failure details. Use
wabery_get_template with refresh: true, or wabery_wait_template in scripts,
to track template approval.
Groups tools are available for eligible Official Business Accounts using the
Cloud API. Group IDs are opaque group_id values, not phone numbers or to.
The MCP server keeps group reads safe by default and requires explicit write
confirmation for group creation, settings changes, invite-link resets, join
request approvals/rejections, participant removal, deletion, and group sends.
Meta limits groups to eight participants and 10,000 groups per number; group
only supports text, media including sticker, text/media templates, and pin or
unpin. wabery_list_groups and wabery_list_group_join_requests accept
limit 1–1024 (default 25) plus opaque starting_after/ending_before
cursors; after/before are aliases. Follow the returned next_cursor or
paging.cursors.after and never derive a cursor from an ID. Group sends do not
support location, reaction, contacts, commerce, interactive, calls, ephemeral,
view-once, authentication, edit, or delete operations. REST pin payloads use
pin.expiration_days (the SDK uses expirationDays), with the current 1–30
day bounds.
Group tool reference
Section titled “Group tool reference”These are the 13 group tools shipped by the MCP server. Read tools are
idempotent and do not require confirmation. Every write tool requires the
session’s write policy plus explicit confirmation. Any client that advertises
MCP elicitation uses client-controlled elicitation, including local clients;
local clients without elicitation use the confirmation_token fallback.
| Read tools | Purpose |
|---|---|
wabery_list_groups |
List groups with channel_id, limit, and opaque cursors. |
wabery_get_group |
Read one group’s settings, status, count, and participants. |
wabery_get_group_invite_link |
Read the current invite link. |
wabery_list_group_join_requests |
List pending join requests and their opaque IDs. |
Write tools:
| Write tools | Required inputs and behavior |
|---|---|
wabery_create_group |
channel_id, subject, optional description/join_approval_mode, stable idempotency_key; asynchronous and confirmed. |
wabery_update_group_settings |
channel_id, group_id, optional subject/description; confirmed, final result arrives via group.settings. |
wabery_update_group_profile_picture |
channel_id, group_id, base64 JPEG, optional filename/settings; confirmed, final result arrives via group.settings. |
wabery_reset_group_invite_link |
channel_id, group_id; confirmed and invalidates the old link. |
wabery_approve_group_join_requests |
channel_id, group_id, 1–8 join_request_ids; confirmed, partial failures are returned. |
wabery_reject_group_join_requests |
channel_id, group_id, 1–8 join_request_ids; confirmed, partial failures are returned. |
wabery_remove_group_participants |
channel_id, group_id, participants: [{ user }]; confirmed, partial failures are returned. |
wabery_delete_group |
channel_id, group_id; confirmed and irreversible at Meta. |
wabery_send_group_message |
channel_id, opaque group_id, exactly one supported body field, stable body.idempotency_key; confirmed. |
The create and send keys are caller-generated and must be reused for every
retry. A create result with object: "api_operation" and
status: "processing" has no group ID; keep the same key and wait for
group.lifecycle. The MCP server marks create/settings/profile-picture/
join-request/participant/delete tools as idempotent hints, while invite reset
and group send are non-idempotent hints. Treat those annotations as retry
guidance, not as permission to skip confirmation or to create a new key.
Broadcast campaigns
Section titled “Broadcast campaigns”Agents can operate the broadcast preparation and delivery workflow with these tools:
| Stage | Tools | Required scope |
|---|---|---|
| Find an audience | wabery_list_contacts, wabery_list_contact_imports, wabery_get_contact_import |
contacts:read |
| Inspect campaigns | wabery_list_broadcasts, wabery_get_broadcast, wabery_list_broadcast_recipients |
broadcasts:read |
| Build a draft | wabery_create_broadcast, wabery_prepare_broadcast_audience, wabery_duplicate_broadcast |
broadcasts:write |
| Deliver | wabery_send_broadcast, wabery_schedule_broadcast |
broadcasts:send |
| Stop remaining work | wabery_cancel_broadcast |
broadcasts:write |
The safe agent sequence is:
- Verify there is a dedicated WhatsApp channel and approved template variant for each intended language.
- Verify category-specific consent. A phone number or CSV row alone is not consent.
- Create a draft, then prepare exactly one audience source:
contact_ids,import_id, orfilter. - Poll
wabery_get_broadcastwhile status ispreparing. - At
ready, show the user the total/skipped counts and, when useful, inspect the frozen snapshot withwabery_list_broadcast_recipients. - Ask for explicit confirmation. The hosted MCP server then opens a client-controlled confirmation dialog before send or schedule executes.
Local stdio MCP uses the documented confirmation token fallback in explicit write mode. Canceling stops recipients that have not been dispatched, but messages already accepted by Meta cannot be recalled. Preparing an audience freezes it; duplicating a campaign copies only the template configuration, so the new draft needs a new preparation step.
OAuth authorization codes and refresh tokens are bound to the canonical MCP
resource. Redirect URIs must use HTTPS, except HTTP loopback callbacks for
installed clients. Refresh tokens rotate on every use; clients must persist the
new refresh token returned by the token endpoint. Hosted OAuth credentials work
only through the hosted MCP connector. Copying one into a direct REST request
does not authenticate.
CSV uploads are deliberately handled by the dashboard or CLI rather than passed
through an MCP prompt. Run wabery contacts import, poll with
wabery contacts import-status, then the agent can find the completed import
through wabery_list_contact_imports. For smaller manual audiences, enroll
contacts with wabery_enroll_contact.
See WhatsApp broadcasts for request bodies, lifecycle states, frequency safeguards, webhook events, and CLI/SDK examples.