Connect an AI client to the global or EU WATI MCP server; browse the tool catalog, permissions, and messaging workflows.
The WATI MCP Server lets compatible AI clients work with WATI contacts, conversations, messages, templates, campaigns, segments and webhooks through a remote MCP connection. Linked accounts can also access Astra agent-building capabilities.
This is the product MCP service. It is different from
https://docs.wati.io/mcp, which provides the ReadMe API-reference MCP for looking up documentation.
Connect with OAuth
Use a client that supports remote MCP over Streamable HTTP and browser-based OAuth. Choose the endpoint for your WATI workspace's region:
| Workspace region | MCP server URL |
|---|---|
| Global | https://mcp.wati.io/mcp |
| EU | https://eu-mcp.wati.io/mcp |
For clients using an mcpServers configuration, add:
{
"mcpServers": {
"wati": {
"url": "https://mcp.wati.io/mcp"
}
}
}For an EU workspace, replace the URL with https://eu-mcp.wati.io/mcp. Reconnect, follow your client's sign-in prompt and complete OAuth in the browser. The hosted OAuth connection does not require you to paste a WATI API key into this configuration.
The server exposes OAuth discovery metadata on the selected host at /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource. For example, the EU authorization metadata is at https://eu-mcp.wati.io/.well-known/oauth-authorization-server. Let the client use that host's discovery information rather than combining endpoints from different regions.
Do not put bearer tokens or API keys in URLs, query parameters or chat messages. Let your MCP client manage the OAuth credentials in its supported secure storage.
Availability and permissions
The tools/list response for your signed-in session is authoritative. The catalogue below covers 58 WATI-prefixed tool registrations in the implementation reviewed for this documentation. It is not a promise that all 58 are deployed or enabled for every account, nor a fixed total for the whole MCP service.
- A WATI OAuth login can use the native WATI tool surface; a linked Astra account is needed for additional Astra capabilities.
- When connecting through an Astra-authorized session, WATI access depends on the granted WATI capability and a WATI account binding. Legacy connections can also be subject to rollout controls.
- Instagram comment tools and chatbot automation tools have additional rollout gates. OAuth consent alone does not enable those features.
- Workspace roles, underlying API permissions, product plans and channel permissions still apply. A listed tool can return an authorization or plan error.
Additional Astra tools can cover agents, knowledge, testing, voice, skills and integrations. Some are loaded on demand, so their count is not fixed. Use the tool definitions returned by your client; do not invent a tool name or assume every REST endpoint has an MCP equivalent.
Choose the correct workspace
WATI tools operate on the active workspace. Call wati_get_active_tenant before making a change. If you can access multiple workspaces, call wati_list_tenants, confirm the destination and use wati_switch_tenant.
Use tenant_id as the workspace's primary identifier; its WhatsApp phone number is a secondary label. Do not confuse a workspace phone number, a sending channel number and a customer's number.
The first switch to a workspace can require browser sign-in. If the result is sign_in_required, open the returned sign_in_url and complete the sign-in. The switch completes through that flow; do not repeatedly call the switch tool while waiting. Confirm the active workspace again afterward. Later switches can reuse a still-valid verified session.
Messaging rules and safe operation
For WhatsApp, free-form text, media and interactive session messages require an active 24-hour customer-service window. This applies to wati_send_message, wati_send_file_via_url and wati_send_interactive. Outside that window, use an already approved WhatsApp template through wati_send_template or wati_send_templates; do not try to bypass the restriction with a different session-message format.
Before sending, confirm the workspace, channel, recipient and exact content. For template sends, also confirm the approved template name and every variable value. For bulk sends, review the complete recipient set. Previewing a template or estimating its cost does not send a message.
A send accepted by WATI is not proof of delivery. For supported message sends, retain the returned message identifiers and check wati_get_message_status or delivery/failure webhooks. A newly accepted message can be temporarily absent from the message store; unknown is not a delivery failure or a reason to immediately send it again.
Changes to contacts, teams, assignments, status, webhooks and automation can affect live customers. Review their exact targets and values before executing them. An MCP tool's review hint is guidance to the client, not a substitute for your application's own approval controls.
Related REST documentation: send text, send media by URL, interactive messages, template messages and delivery webhooks. MCP parameter names can differ from the REST API; follow the MCP input schema.
WATI tool catalogue
The fields below are key inputs, not a replacement for the complete schema in tools/list. Use that schema and the returned validation guidance for required fields and valid combinations. On the hosted OAuth connection, credentials and workspace context are resolved from your session rather than supplied as ordinary tool arguments.
Workspaces — 3 tools
| Tool | What it does and key inputs |
|---|---|
wati_list_tenants | Lists accessible workspaces, workspace phone numbers, your roles and the active workspace. No business input required. |
wati_get_active_tenant | Reports the active workspace and your roles. Use before writes. No business input required. |
wati_switch_tenant | Switches the active workspace using tenant_id, or phone_number as an alternative. tenant_id takes precedence; omit both to discover choices. May return a browser sign-in step. |
Contacts and search — 9 tools
| Tool | What it does and key inputs |
|---|---|
wati_get_contacts | Lists contacts or looks up whatsapp_number; uses page and page_size (default 20, maximum 100). Follow the returned next-page hint. It is not a behavioral segment filter. |
wati_get_contact | Retrieves a contact record, including custom attributes and assignments. Requires target: a contact ID, phone number or supported channel-scoped identifier. |
wati_get_contact_count | Counts contacts, optionally filtered by creation date_from and date_to. This is not a conversation count. |
wati_get_contact_profile | Reads a CDP engagement profile using contact_id, or a channel-specific contact_number / instagram_id; select channel (whatsapp or instagram). Instagram linked conversations are filtered, but engagement metrics are a unified cross-channel profile. Missing metrics can be null. |
wati_search | Read-only contact and message search with query and optional limit. Phone-shaped queries use direct contact lookup. Message-text search covers a bounded recent-message window, not a complete historical export. It does not search templates, broadcasts or segments. |
wati_upload_contact | Creates or updates a contact identified by required whatsapp_number, with optional name and flat custom_params. This writes a contact; it does not send a message. |
wati_update_contact_attributes | Updates existing contacts using target or targets, plus flat custom_params. No merge/replace strategy input is supported. |
wati_assign_contact_teams | Requires target and teams. Replaces the entire team set, so include every team the contact should retain. |
wati_delete_contact | Requires target. Soft-deletes the contact through WATI's deletion flow; it is not physical GDPR erasure. Confirm the exact contact first. |
See contact details, update contacts and target formats for related REST concepts.
Conversations, messages and tags — 11 tools
| Tool | What it does and key inputs |
|---|---|
wati_get_conversations | Finds contacts with recent inbound activity and returns their conversation entries. Inputs: channel, start_date, end_date, timezone, page, page_size. Defaults to the last 7 days. This is a paginated recent-activity snapshot, not every historical conversation; total counts describe matching contacts. |
wati_get_messages | Reads WhatsApp/Instagram history using target (phone, conversation ID or Team Inbox URL), with legacy whatsapp_number also supported. Inputs include channel_phone_number, page, page_size. Results are newest-first; follow next_page for older messages. |
wati_send_message | Sends plain text using a recipient target (or legacy whatsapp_number) and message, with channel and relevant channel selectors. Text is limited to 4,096 characters. WhatsApp/Instagram use the supported conversation targets; Messenger requires channel="messenger" and a WATI OAuth user, not an API-token/direct-mode connection. Returns acceptance, not delivery confirmation. |
wati_get_message_status | Checks WhatsApp/Instagram message status using the same target and a returned message_id or local_message_id. Optional channel_phone_number selects the channel. It checks the newest message-store page; use delivery webhooks when the message is no longer on that page. |
wati_send_file_via_url | Sends WhatsApp media using target (or whatsapp_number and optional channel), required public file_url and optional caption. Requires the 24-hour window. voice and idempotency_key are not supported inputs. |
wati_send_interactive | Requires target and type (buttons or list), plus matching button_message or list_message. Supports 1–3 reply buttons with text up to 20 characters, or 1–10 list rows across sections. Requires the WhatsApp 24-hour window. |
wati_assign_operator | Requires conversation target; pass assignee_email for an operator. Omitting the email assigns the conversation to the bot. |
wati_update_conversation_status | Requires target and new_status: open, solved, pending or block. This changes live conversation state. |
wati_list_conversation_tags | Lists tags in use with CDP usage counts. Inputs: start_date, end_date, timezone; default last 7 days, maximum date range 366 days, default timezone UTC. The accepted channel input does not filter the current cross-channel result. |
wati_add_conversation_tag | Requires target_conv and exact existing tag_name. Idempotently applies the tag; it does not create a new tag definition. |
wati_remove_conversation_tag | Requires target_conv and exact tag_name. Removing an unapplied tag is a successful no-op, reported as removed=false. |
Do not use recent activity or bounded search results as an exact historical total. State the date range, pagination and any missing data when summarizing results.
Templates, campaigns and credits — 11 tools
| Tool | What it does and key inputs |
|---|---|
wati_list_templates | Lists WhatsApp templates and their names, language, category, status and body. Check that the chosen template is approved before sending. Inputs include page_number, page_size, channel and response_format. |
wati_get_template | Requires template_id; returns full template structure and variable slots. Optional response_format. Discover IDs from the template list. |
wati_send_template_dry_run | Previews an approved template_name with optional parameters, sample_recipients and channel. Substitutes variables without sending. |
wati_send_template | Sends one approved template. Requires whatsapp_number, template_name, broadcast_name; parameters is a flat variable map, with optional channel. Confirm recipient and variables first. |
wati_send_templates | Sends a template broadcast. Requires template_name, broadcast_name, recipients; optional channel. Each recipient contains phone_number and optional flat custom_params. Supports 1–10,000 recipients; review the full list before sending. |
wati_get_template_performance | Aggregates broadcast statistics for required template_id; optional date_from, date_to, channel. Returns zero totals when no matching broadcasts exist. |
wati_list_campaigns | Lists broadcast campaigns using page_number, page_size, optional channel, date_from, date_to, response_format. Dates filter created/scheduled time; omitted dates default to the trailing 90 days. |
wati_get_campaign | Requires campaign_id; returns metadata and sent, delivered, read, replied and failed statistics. Optional response_format. |
wati_retry_broadcast_failures | Requires broadcast_id. First use dry_run=true, review the returned failed-recipient snapshot, then send with its exact confirmation_token. Rejects a changed recipient set or payload; do not fabricate or reuse a token for another snapshot. |
wati_get_credit_balance | Reads account credit balances, currency and remaining free conversations. No business input required. |
wati_estimate_send_cost | Requires template_id and nonempty contact_ids. Estimates cost and compares available credit; does not send or reserve a delivery outcome. |
Related REST reference: campaign details, template details and cost estimate.
Segments — 5 tools
Custom Segments require an eligible Pro or Business plan. The MCP segment read/evaluation tools use the tenant-scoped CDP-backed API; they do not fall back to public V3 to bypass a plan rejection. Do not replace a rejected segment query with a contact scan, recent-conversation count or another metric.
| Tool | What it does and key inputs |
|---|---|
wati_create_segment | Requires name and refresh_type (1 static, 2 dynamic). Use groups for filter conditions; static segments can use contact_ids and/or filters. Also accepts description and use_uploaded_contact. Confirm the definition before saving. |
wati_list_segments | Lists segment summaries and deletion metadata. Inputs: page, page_size, source, sort_field, deleted_only, query; source 1 means custom and 2 system. |
wati_get_segment | Requires segment_id; reads its full filter definition and current member count. |
wati_evaluate_segment | Previews nonempty filter groups without saving; returns a total match count and paginated sample using page, page_size. Filter filter_type is 0 for a contact attribute or 1 for a profile signal. |
wati_list_segment_members | Requires segment_id; returns saved-segment contacts with page and page_size. Distinct from evaluating an unsaved filter. |
Here, groups means segment filter groups, not WhatsApp group conversations. See Create Custom Segment for the related REST contract.
Channels and webhooks — 7 tools
| Tool | What it does and key inputs |
|---|---|
wati_list_channels | Lists connected channels with page_number, page_size, optional response_format. A synthetic Default entry has an empty ID. Use the tool-specific channel name, ID or phone field; these are not interchangeable. |
wati_get_webhook_event_types | Lists event types available to the workspace. Call before selecting subscription events. No business input required. |
wati_subscribe | Creates a subscription with required phone_number (the sending channel), url and nonempty event_types. Confirm where customer data will be sent. |
wati_list_webhooks | Lists subscriptions, URLs, statuses and event types. No business input required. |
wati_get_webhook | Reads one subscription using required webhook_id. |
wati_update_webhook | Requires webhook_id and changes to url, event_types or status (Enabled / Disabled). |
wati_delete_webhook | Deletes required webhook_id; stops event delivery to that subscription. |
Related REST reference: channels, webhook event types and webhook subscriptions.
Instagram posts and comments — 7 tools
These tools require the Instagram rollout feature and appropriate connected-channel permissions. Start by selecting a channel and listing its posts; use returned identifiers rather than guessing them. Read operations do not imply permission to reply.
| Tool | What it does and key inputs |
|---|---|
wati_instagram_list_posts | Lists posts/reels using channel, optional media_type, page_number, page_size, response_format. Omitting the channel returns choices instead of guessing. Retain each postId and postAuthorIgId. |
wati_instagram_get_post | Requires post_id; supply post_author_ig_id or select channel for derivation. Optional response_format. Prefer IDs from the list; an ordinary post/reel URL is not automatically a resolvable ID. |
wati_instagram_list_comments | Requires post_id; uses post_author_ig_id or selected channel, plus pagination and optional response_format. Includes at most one level of flattened replies. Retain the comment's commentId, userId and userName. |
wati_instagram_get_post_unread_count | Requires post_id. Zero unread comments does not prove the post exists; confirm it with a list/detail operation. |
wati_instagram_check_permissions | Checks missing permissions for a selected channel; omit it to discover choices. Use before attempting a public or private reply. |
wati_instagram_reply_comment | Posts a real public reply using required comment_id, content, and post_author_ig_id or a selected channel. Confirm exact content first. |
wati_instagram_send_private_reply | Sends a real private reply using comment_id, selected channel, and the same comment's user_id / user_name, with type and corresponding text or template payload. The user identifiers belong to the commenter, not your business account. Confirm the destination and payload. |
See Instagram posts and private replies for related REST behavior.
Chatbot automation — 4 tools
These tools have a separate rollout gate. A saved flow is not the same as a published chatbot, and an enabled trigger can immediately affect inbound conversations.
| Tool | What it does and key inputs |
|---|---|
wati_draft_chatbot | Generates a stateless flow draft from required name and prompt. Does not save or publish it. Review the result before saving. |
wati_upsert_chatbot | Requires the complete builder-produced flow (name, flowNodes, flowEdges, transform). Omit chatbot_id to create or supply it to fully replace an existing chatbot. Does not implicitly publish. |
wati_create_chatbot_trigger | Requires name, chatbot_id, trigger_type, matching configuration and explicit enabled. Types: keyword, inbound_message, contact_field_change. Creation is not idempotent; verify a failed attempt before retrying. |
wati_set_chatbot_trigger_status | Requires returned trigger_id and boolean enabled. Enables or disables the trigger without replacing its definition. |
Capability feedback — 1 tool
| Tool | What it does and key inputs |
|---|---|
wati_report_feedback | Records a missing capability using question and description. It does not implement the missing action or send a customer message. Report a distinct gap once; authentication, not-found and rate-limit errors are not missing-capability reports. |
Example workflows
Read a conversation before replying
- Confirm the active workspace.
- Find the contact or recent conversation; read its messages using the returned identifier.
- Confirm the channel, recipient, exact reply and whether the required session window is active.
- Send the session message, or use an approved WhatsApp template outside the window.
- Report acceptance separately from delivery; check status or webhooks where available.
Send an approved template
- List templates and inspect the chosen template's variable slots.
- Preview it with
wati_send_template_dry_runand, when needed, estimate cost. - Show the template, exact recipients and substituted values for confirmation.
- Use the single-recipient or broadcast send tool, then review delivery outcomes.
Retry failed broadcast recipients
- Read the campaign and run
wati_retry_broadcast_failureswithdry_run=true. - Review the complete failed-recipient snapshot with the user.
- Send only with that preview's exact
confirmation_token. If the snapshot changes, preview and confirm again.
Troubleshooting
- 401 or a sign-in prompt: complete OAuth for the selected region and reconnect. Never paste a token into the server URL.
- A tool is absent: refresh your client's tool list. Check the account connection and feature availability; a linked Astra account or a specific rollout may be required. Absence is not permission to invoke a guessed tool.
- Wrong workspace or an expired workspace session: use the workspace tools to inspect state and switch explicitly. Complete any returned browser sign-in, then recheck the active workspace.
- Plan or permission rejection: check the applicable plan, role, API/channel permission or feature availability. Do not substitute another metric or route as a bypass.
- A message is accepted but not yet visible: allow asynchronous processing and inspect status/webhooks; do not automatically resend.
- Missing historical results: inspect the date range and next-page hints. Recent-activity and bounded-search tools are not complete historical exports.
- An Instagram reply is rejected: verify channel permissions and use identifiers returned for the same post/comment; a business account ID is not the commenter's ID.
For direct REST integrations, see the API introduction. The MCP connection uses OAuth and the tool schemas above; the REST API has its own authentication and request contracts.

