A TypeScript implementation of a simple MCP server that exposes datetime information to agentic systems and chat REPLs
LetsBot is installed from its publisher's own source and answers where it runs, so this marketplace is not in the path of a single call. There is no address here to send one to, and a panel that pretended otherwise would be showing you an answer we made up. Install it and call it from your own client — the Installation tab has the entry for each one.
What it does
WhatsApp Business messaging, live chat, chatbots, campaigns and CRM for a LetsBot workspace.
Quickstart
# 1 — add it to Claude Code
claude mcp add --scope user --transport http letsbot-mcp https://letsbot.net/mcp
# 2 — ask your agent for something these tools do
# send_text_message, send_image, send_video and 92 more
LetsBot costs nothing on mcprush: there is no plan to choose here, no cap to set and nothing mcprush can bill you for.
Collected from a public index. Nobody has claimed this account, so nothing here was written by its author — claim it if it is yours.
Where are you running it?
Every route below installs the same thing and ends at the same approval screen. Nothing here runs on your machine and nothing runs on ours: this server answers at its publisher’s own address, and what you install is the connection straight to it.
This is a public server: it answers at its publisher’s own address and this marketplace is not in the path. Claude Code registers it in one command; --scope user makes it available in every project. The transport below is http, as the publisher's own manifest declares it. Its publisher asks you to sign in with OAuth: run /mcp in Claude Code and pick this server, and it opens a browser for that once.
claude mcp add --scope user --transport http letsbot-mcp https://letsbot.net/mcpReconnect, or start a new session, and the tools appear in the model’s tool list.
One config entry pointing straight at the publisher’s own address — this marketplace is not in the path, and nothing from this listing executes on your machine.
95 tools, with what each one reads, writes and reaches shown before you agree — the same list on every route above. Read the tool surface.
Tool surface
What the model actually sees. Descriptions are diffed on every release — see version history.
Send a text message to a contact on any connected platform: a WhatsApp number (international format without +, e.g. 201234567890), or the phone / chat_id of a website chat, Messenger, Instagram, Telegram, X or SMS contact exactly as get_conversations_awaiting_reply or get_contacts returns it. The message goes out on the platform the contact wrote from.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | WhatsApp number in international format without + (e.g. 201234567890), or the contact's phone / chat_id as listed (e.g. wc1-d838cd71… for a website chat visitor) |
| message | string | yes | The text message to send |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Send an image to a WhatsApp number with an optional caption.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | WhatsApp number in international format without + (e.g. 201234567890), or the contact's phone / chat_id as listed by get_conversations_awaiting_reply (website chat, Messenger, Instagram, Telegram…) |
| image_url | string | yes | URL of the image to send |
| caption | string | no | Optional caption for the image |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Send a video to a WhatsApp number with an optional caption.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | WhatsApp number in international format without + (e.g. 201234567890), or the contact's phone / chat_id as listed by get_conversations_awaiting_reply (website chat, Messenger, Instagram, Telegram…) |
| video_url | string | yes | URL of the video to send |
| caption | string | no | Optional caption for the video |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Send an audio file or voice note to a WhatsApp number.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | WhatsApp number in international format without + (e.g. 201234567890), or the contact's phone / chat_id as listed by get_conversations_awaiting_reply (website chat, Messenger, Instagram, Telegram…) |
| audio_url | string | yes | URL of the audio file to send |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Send a document/file to a WhatsApp number. file_url must be a DIRECT url to the file itself. If you generated the file yourself, or it is not already at a direct public url, call upload_file first (it takes the bytes as base64 and returns a url plus the filename to pass here). A Google Drive / Dropbox / OneDrive share link is not a direct url — it points at a download page, and the file arrives
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | WhatsApp number in international format without + (e.g. 201234567890), or the contact's phone / chat_id as listed by get_conversations_awaiting_reply (website chat, Messenger, Instagram, Telegram…) |
| file_url | string | yes | URL of the file to send |
| filename | string | no | Display name INCLUDING the extension (e.g. invoice.pdf). WhatsApp shows this name and uses the extension to pick the file type, so a name without one arrives as a generic "BIN" attachment the recipien |
| caption | string | no | Optional caption for the file |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Send a location to a WhatsApp number.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | WhatsApp number in international format without + (e.g. 201234567890), or the contact's phone / chat_id as listed by get_conversations_awaiting_reply (website chat, Messenger, Instagram, Telegram…) |
| latitude | string | yes | Latitude coordinate |
| longitude | string | yes | Longitude coordinate |
| name | string | no | Optional location name |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Send a contact card (vCard) to a WhatsApp number.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | WhatsApp number in international format without + (e.g. 201234567890), or the contact's phone / chat_id as listed by get_conversations_awaiting_reply (website chat, Messenger, Instagram, Telegram…) |
| contact_name | string | yes | Name on the contact card |
| contact_phone | string | yes | Phone number on the contact card |
| organization | string | no | Optional organization name |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Send a WhatsApp-approved message template to a number. Templates are required for sending messages outside the 24-hour window.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number in international format without + |
| template_name | string | yes | Name of the approved WhatsApp template |
| language | string | no | Template language code (e.g. ar, en) |
| components | object | no | Values for the template placeholders. Preferred shape is a map keyed by component: {"body": ["Acme Ltd", "one-line summary"]} — plain strings in the order the variables appear in the template text ({{ |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Send an interactive message with buttons to a WhatsApp number. Maximum 3 buttons.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | WhatsApp number in international format without + (e.g. 201234567890), or the contact's phone / chat_id as listed by get_conversations_awaiting_reply (website chat, Messenger, Instagram, Telegram…) |
| body | string | yes | Message body text |
| buttons | array | yes | Array of button objects with id and title |
| title | string | no | Optional header title |
| footer | string | no | Optional footer text |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Send an interactive list/menu message to a WhatsApp number.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | WhatsApp number in international format without + (e.g. 201234567890), or the contact's phone / chat_id as listed by get_conversations_awaiting_reply (website chat, Messenger, Instagram, Telegram…) |
| body | string | yes | Message body text |
| button_text | string | no | Text on the list button (e.g. "View Options") |
| sections | array | yes | Array of section objects with title and rows |
| title | string | no | Optional header title |
| footer | string | no | Optional footer text |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Send a carousel of cards (title, subtitle, image, up to 3 buttons each; max 10 cards) to a Messenger or Instagram contact. Provide the recipient PSID/IGSID and platform.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| recipient | string | yes | The contact PSID (Messenger) or IGSID (Instagram). |
| platform | string | no | Which Meta channel to send from. Defaults to messenger. |
| cards | array | yes | Up to 10 cards. |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Reply to a specific message in a conversation on any connected platform (WhatsApp, website chat, Messenger, Instagram, Telegram, …). Also replies inside a WhatsApp group when "phone" is the group's chat_id from get_groups (QR-connected numbers only), optionally tagging members with "mentions".
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | WhatsApp number in international format without +, or the contact's phone / chat_id as listed. To reply inside a WhatsApp group, the group's "chat_id" from get_groups (e.g. 120363041234567890@g.us). |
| message_id | string | yes | The WhatsApp message ID to reply to |
| text | string | yes | The reply text. In a group, every "@<number>" (international format, e.g. @5511970793770) tags that member. |
| mentions | array | no | Optional, WhatsApp groups on a QR-connected number only. Group members to tag (@mention) so WhatsApp highlights their name and notifies them: phone numbers in international format without + (e.g. "551 |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Add an emoji reaction to a message in a WhatsApp conversation.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | WhatsApp number in international format without + (e.g. 201234567890), or the contact's phone / chat_id as listed by get_conversations_awaiting_reply (website chat, Messenger, Instagram, Telegram…) |
| message_id | string | yes | The WhatsApp message ID to react to |
| emoji | string | yes | Emoji to react with (e.g. 👍, ❤️, 😂) |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Forward a message from one WhatsApp chat to another.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| message_id | string | yes | The WhatsApp message ID to forward |
| to_phone | string | yes | Phone number to forward to (international format without +) |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Put a file into LetsBot storage and get back a direct https url plus the filename to pass to send_file / send_group_file / send_image / send_video / send_audio. Two ways in — pass exactly one: source_url when the file is already online (a public link, including a Google Drive "Anyone with the link" share link or a Dropbox link; LetsBot downloads it server-side, max 20 MB), or content_base64 on
| Parameter | Type | Required | Notes |
|---|---|---|---|
| source_url | string | no | A public http(s) link to the file; LetsBot downloads it (max 20 MB, 20 s). Google Drive share links (drive.google.com/file/d/<id>/view) and Dropbox links (?dl=0) are converted to their direct download |
| content_base64 | string | no | The file contents, base64-encoded — only for a small file you generated yourself. Max 20 MB after decoding. A "data:...;base64," prefix is accepted and its declared type is ignored — the real type is |
| filename | string | yes | Name INCLUDING the extension, e.g. "invoice-2026-012.pdf". The extension must match what the bytes actually are. Any directory part is discarded; the stored object is given a random name. This name is |
Get a paginated list of WhatsApp contacts with optional search and filter.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| search | string | no | Search by name, phone, or username |
| filter | string | no | Filter contacts. "awaiting_reply" = the customer sent the last message and no reply has been sent since (a work backlog, not a read state). |
| page | integer | no | Page number (default: 1) |
Get detailed information about a specific WhatsApp contact including labels, moderators, last message, and the workspace's contact custom fields (custom_fields: every available field with its key, label, type, current value — null when empty — and allowed options for select fields). Use those keys with update_contact to set or clear a custom field.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number in international format without + |
Create a new WhatsApp contact in the system. Optionally set the workspace's contact custom fields in the same call (custom_fields: key → value).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number in international format without + |
| name | string | no | Contact name |
| string | no | Optional email address | |
| custom_fields | object | no | The workspace's own contact custom fields, as an object of field key → value (e.g. {"ficha_cliente": "Cliente desde 2024, prefiere entregas por la mañana"}). Keys are defined by the workspace, so call |
Update a contact's information: name, email, city, country, and the workspace's own contact custom fields (custom_fields: key → value, null clears). Call get_contact first to see which custom field keys exist, their types and allowed options. Only the fields you pass are changed.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number of the contact to update |
| name | string | no | New name for the contact |
| string | no | New email | |
| city | string | no | City |
| country | string | no | Country |
| custom_fields | object | no | The workspace's own contact custom fields, as an object of field key → value (e.g. {"ficha_cliente": "Cliente desde 2024, prefiere entregas por la mañana"}). Keys are defined by the workspace, so call |
Get the chats assigned to the person this connection acts as. A workspace-level connection (API key) gets every assigned chat.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| page | integer | no | Page number (default: 1) |
| search | string | no | Search by name or phone |
List conversations where the customer wrote last and nobody has replied yet, newest first. This is a backlog of work outstanding, NOT a read/unread state: it is derived from who spoke last, so it clears when a reply is sent from any device and returns if the customer writes again. It is unaffected by whether anyone has opened the chat. A customer who wrote to two of your WhatsApp numbers has one c
| Parameter | Type | Required | Notes |
|---|---|---|---|
| page | integer | no | Page number (default: 1) |
Pin or unpin a contact chat so it stays at the top of the list.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number in international format without + |
| pin | boolean | no | true to pin, false to unpin (default: true) |
Archive or unarchive a contact chat.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number in international format without + |
| archive | boolean | no | true to archive, false to unarchive (default: true) |
Block or unblock a WhatsApp contact.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number in international format without + |
| block | boolean | no | true to block, false to unblock (default: true) |
Permanently delete one contact (a one-to-one chat) together with its whole conversation: every message and media file is erased shortly after, and this cannot be undone. Same as Delete on the contact in the LetsBot panel. Requires confirm: call with confirm=false first to get a preview (name, message count, labels, assigned team members), show it to the user, then call again with confirm=true. It
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number of the contact in international format without + (e.g. 201234567890), or the chat id shown by get_contact. |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Assign or remove a label from a contact. Toggles the label — if already assigned it will be removed, if not assigned it will be added.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number of the contact |
| label_id | integer | yes | ID of the label to assign/remove |
Assign a team member (moderator) to a conversation, or remove them from it. Pass action=assign or action=unassign to say which; without action the call toggles (adds if absent, removes if present). The assigned member is notified. To move many conversations from one member to another at once, use reassign_conversations.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number of the contact |
| user_id | integer | yes | ID of the moderator/user to assign/remove |
| action | string | no | assign: add the member (no change if already assigned). unassign: remove them (no change if not assigned). toggle (default): flip. |
Move conversations from one team member to another in one step — e.g. "move Ahmed's waiting chats to Mona". By default only the conversations awaiting a reply (the customer wrote last) move; use scope=all for every open conversation the member holds, or waiting_longer_than_minutes for only the late ones. The giver is removed, the receiver is assigned and notified, and the change is recorded in the
| Parameter | Type | Required | Notes |
|---|---|---|---|
| from_user_id | integer | yes | Team member whose conversations move away. |
| to_user_id | integer | yes | Team member who receives them. |
| scope | string | no | awaiting_reply (default): only conversations where the customer is waiting for an answer. all: every non-archived conversation assigned to from_user_id. |
| waiting_longer_than_minutes | integer | no | Only conversations whose customer has been waiting at least this many minutes (implies awaiting_reply). E.g. 60 = waiting an hour or more. |
| limit | integer | no | Most conversations to move in this call, oldest wait first. Default 200, max 500. |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Read how new conversations are automatically given to team members (operators): the assignment mode (off / round robin / least open), which team receives them, whether only available operators count, the per-operator cap, reassigning a conversation when its operator does not reply in time, rebalancing, and the backup operator. Each setting comes with a plain-words explanation, plus the teams, oper
Takes no parameters.
Change how new conversations are automatically given to team members. Pass ONLY the settings to change; everything else stays as it is. Call get_assignment_rules first to see the current values, the teams and the operators you can use. Examples: turn it on with mode="round_robin"; cap each operator at 10 chats with max_open=10; move a chat nobody answered within 15 minutes with reassign_after_minu
| Parameter | Type | Required | Notes |
|---|---|---|---|
| mode | string | no | off = no automatic assignment by this rule; round_robin = operators take turns; least_open = operator with the fewest chats. |
| team_id | integer/null | no | Only members of this active team receive conversations; null = all operators with live-chat access. |
| only_available | boolean | no | true = skip operators who are away/offline. |
| max_open | integer/null | no | Max conversations one operator may hold (1-500); null = no cap. |
| on_reopen | boolean | no | true = a conversation the customer reopens is assigned again by this rule. |
| count_basis | string | no | What the cap counts: open = assigned open chats; awaiting = chats where the customer is waiting for a reply. |
| awaiting_window_days | integer | no | Days an unanswered chat keeps counting against its operator (1-90). Used with count_basis=awaiting. |
| reassign_after_minutes | integer/null | no | Move a chat to another operator when its operator has not replied after this many minutes (1-1440); null = never. |
| reassign_keep_previous | boolean | no | true = after such a move, the operator who did not reply stays on the chat too. |
| reassign_max_hops | integer | no | How many times one waiting chat may be moved (1-10). |
| after_last_hop | string | no | After the last move: stay = keep the last operator; fallback = give it to the backup operator. |
| rebalance | boolean | no | true = move chats off an operator who holds more than max_open. |
| when_full | string | no | When everyone is at the cap: wait = the chat waits until someone has room; fallback = give it to the backup operator. |
| fallback_user_id | integer/null | no | Backup operator id (from get_assignment_rules choices.operators); null = none. |
Add an internal note to a conversation — visible only to the merchant's team in the LetsBot inbox, never sent to the customer. Use it to leave context for colleagues (e.g. "customer wants a refund, waiting for the warehouse"). A note does not count as a reply to the customer. To alert teammates, mention them: write @Name in the body (e.g. "@Sara please call the customer") or pass their ids or name
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number (or chat id) of the contact. |
| body | string | yes | The note text (max 4000 characters). @Name mentions a teammate. |
| mentions | array | no | Optional teammates to notify: user ids (from get_moderators) or names, e.g. ["7", "Fatma"]. |
Summarise this LetsBot workspace's account in one call: (1) subscription — current plan, billing period, start and end/renewal date, status, whether it renews automatically and the next automatic charge, trial state and days left, any temporary plan boost, the line items and the add-ons/features included; (2) usage — messages sent in the rolling last 30 days against the plan's monthly message limi
Takes no parameters.
A short briefing of what needs the owner's attention in this LetsBot workspace right now, in one call: conversations where a customer is still waiting for a reply (how many, how long the oldest has waited, and the first few names), customer messages and new contacts in the last 24 hours, WhatsApp/Messenger/Instagram/Telegram channels that are disconnected or lost access, a plan or trial that ends
Takes no parameters.
Read one tab of the LetsBot Reports page for a period: KPI cards with the change vs the previous period, the main chart (labels + series), the table rows (max 100) and footnotes. Tabs: conversations (opened/closed/open), responses (reply speed), resolutions, messages (inbound/outbound, delivery), contacts (new contacts by channel, ads vs organic), assignments, lifecycle, calls (WhatsApp calls) and
| Parameter | Type | Required | Notes |
|---|---|---|---|
| tab | string | no | Which report tab. Omit to list the tabs available in this workspace and what each one shows. |
| period | string | no | Period preset in the workspace time zone. Default 30d. Use custom with from and to. |
| from | string | no | First day (YYYY-MM-DD) when period is custom. Max range 366 days. |
| to | string | no | Last day (YYYY-MM-DD, inclusive) when period is custom. |
| channel | string | no | Only this channel. Omit for all channels. |
| group_by | string | no | Table/chart grouping. Each tab supports only some values (listed in available_tabs[].group_by_options); an unsupported value falls back to the tab's default. |
List the WhatsApp message templates (Meta-approved message formats) of this workspace: name, exact language code, category (MARKETING / UTILITY / AUTHENTICATION), Meta review status and the rejection reason when Meta gave one, body text, header type, and the placeholders each template expects (numbered {{1}} or named {{customer_name}}). Each row says whether send_template can send it (only APPROVE
| Parameter | Type | Required | Notes |
|---|---|---|---|
| status | string | no | Only templates with this Meta status. APPROVED templates are the only ones that can be sent. |
| category | string | no | Only templates of this Meta category. |
| language | string | no | Exact Meta language code, e.g. "ar", "en", "en_US", "es", "pt_BR". |
| search | string | no | Text to find in the template name, Meta template id or language code. |
| page | integer | no | Page number (50 templates per page). Default 1. |
Create a new WhatsApp message template and submit it to Meta for review (Official WhatsApp / Cloud API workspaces only). A template is the only way to start a conversation or message a customer outside the 24-hour reply window; once Meta APPROVES it, send it with send_template. Inputs: name (lowercase letters, digits and underscores; Meta registers it as "nt_<name>"), language (any language Meta a
| Parameter | Type | Required | Notes |
|---|---|---|---|
| name | string | yes | Template name: lowercase letters, digits and underscores only (e.g. "order_shipped"). Unique per workspace. Meta registers it as "nt_<name>" — that is the name list_whatsapp_templates and send_templat |
| language | string | yes | Bare language code the template is written in: one of ar, en, pt, es, fr, af, sq, az, be, bn, bg, ca, zh, hr, cs, da, prs, nl, et, fil, fi, ka, de, el, gu, ha, he, hi, hu, id, ga, it, ja, kn, kk, rw, |
| category | string | yes | UTILITY (transactional, no promotion) or MARKETING (promotional, billed per message at Meta's marketing rate). Meta may re-categorise. AUTHENTICATION is refused here. |
| body | string | yes | Message text, up to 1024 characters. Placeholders as {{1}}, {{2}} … or {{customer_name}}. A placeholder cannot be the whole message, and the body cannot start or end with one (punctuation and emojis d |
| examples | object | no | Required by Meta: one realistic sample value per placeholder, keyed by the placeholder ({"1": "Sara", "2": "#1045"} or {"customer_name": "Sara"}). Also covers a named placeholder in a text header. |
| header | object | no | Optional header. {"type": "text", "text": "Your order"} (max 60 chars; a named template may use ONE {{placeholder}} in it), or {"type": "image"|"video"|"document", "media_url": "https://…"} — a PUBLIC |
| footer | string | no | Optional footer, max 60 characters, no placeholders (emojis are removed — Meta refuses them there). |
| buttons | array | no | Optional, up to 10 buttons (at most 2 url and 1 phone_number). Labels max 25 characters, no emojis. quick_reply: {"type":"quick_reply","text":"Track order"}. url: {"type":"url","text":"Open","url":"ht |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
List messages that are still waiting to go out to customers: pending store notifications from Salla, Zid and WooCommerce (order updates, abandoned-cart reminders, …) and the outgoing WhatsApp send queue (including failed sends that would be re-sent when the number reconnects). Use it when the merchant asks "what is about to be sent?" or wants to stop pending messages. Returns totals per source and
| Parameter | Type | Required | Notes |
|---|---|---|---|
| sources | array | no | Limit to these sources; omit for all. salla.notification / zid.notification / woo.notification = pending store notifications; message_queue = outgoing WhatsApp send queue. |
| phone | string | no | Only rows whose recipient phone STARTS with this (digits, e.g. "9665"). |
| date_from | string | no | Only rows created on/after this day (YYYY-MM-DD). |
| date_to | string | no | Only rows created on/before this day (YYYY-MM-DD). |
| page | integer | no | Page number, starting at 1 (default 1). |
| per_page | integer | no | Rows per page, 1-50 (default 50). |
Stop messages that are still waiting to be sent (as listed by list_scheduled_activity): either ONE row (pass source + source_id; it is cancelled immediately — stopping a send needs no approval) or ALL rows matching optional filters (pass all=true; this needs the user's confirmation — call first with confirm=false to get the count, then confirm=true). Pending store notifications (Salla / Zid / WooC
| Parameter | Type | Required | Notes |
|---|---|---|---|
| source | string | no | Source of the ONE row to cancel (from list_scheduled_activity). |
| source_id | integer | no | source_id of the ONE row to cancel (from list_scheduled_activity). |
| all | boolean | no | true = cancel EVERY pending row matching the filters below (all sources when no filter). Requires confirm. |
| sources | array | no | Limit to these sources; omit for all. salla.notification / zid.notification / woo.notification = pending store notifications; message_queue = outgoing WhatsApp send queue. |
| phone | string | no | Only rows whose recipient phone STARTS with this (digits, e.g. "9665"). |
| date_from | string | no | Only rows created on/after this day (YYYY-MM-DD). |
| date_to | string | no | Only rows created on/before this day (YYYY-MM-DD). |
| confirm | boolean | yes | For all=true: pass false first to get the count and a breakdown (nothing is cancelled), show it to the user, then true to cancel. Cancelling ONE row (source + source_id) needs no approval and happens |
Get messages from a WhatsApp conversation. Returns the most recent messages paginated.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number in international format without + |
| page | integer | no | Page number for pagination (default: 1) |
| per_page | integer | no | Messages per page (default: 15, max: 50) |
Check what WhatsApp actually did with messages you already sent — delivered, read, still pending, or FAILED with Meta's own reason. A send tool returning status "sent" only means Meta accepted the message; Meta can still refuse to deliver it seconds later, and this tool is the only way to learn that. Call it a minute or two after sending (pass the message_id values the send tools returned), or pas
| Parameter | Type | Required | Notes |
|---|---|---|---|
| message_ids | array | no | The message_id values returned by the send tools (WhatsApp wamids). Up to 200. Checked exactly, ignoring the time window. |
| phone | string | no | Alternative to message_ids: a contact phone number in international format without +. Reviews every message sent TO that contact inside the time window. Use this for the send tools that return no mess |
| minutes | integer | no | How far back to look when checking by phone. Default 60, maximum 1440 (24 hours). Ignored when message_ids is given. |
Search messages across all conversations (individual chats and groups), or within one specific contact chat or group.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| query | string | yes | Search query to find in message text |
| phone | string | no | Optional: limit search to a specific contact's individual chat. Group messages are excluded from this scope — use group_id for groups. |
| group_id | string | no | Optional: limit search to a specific group. Accepts the group chat_id (e.g. 120363041234567890@g.us), the id from get_groups, or the group name. |
| page | integer | no | Page number (default: 1) |
Mark a conversation as opened in the LetsBot inbox, and send a read receipt to the customer on channels that support one. This affects inbox read state ONLY. It does NOT clear the conversation from get_conversations_awaiting_reply — only sending a reply does that — so do not call this expecting the awaiting-reply backlog to go down.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number of the contact in international format without + |
Get a paginated list of WhatsApp group conversations. Read-only: listing groups never marks anything as read. Counts report what has not been opened in the LetsBot inbox, which is not the same as what the merchant has seen on their own phone. Use get_group_messages to read a group's history.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| search | string | no | Search groups by name |
| filter | string | no | Filter groups. "not_opened_in_inbox" = has inbound messages nobody has opened in the LetsBot inbox (inbox state only, not the merchant's phone). |
| membership | string | no | Membership filter: all (default — matches the live-chat list), joined (still a member), left (removed from or left the group) |
| page | integer | no | Page number (default: 1) |
Get messages from a WhatsApp group conversation, newest first, with the sender of each message. Read-only: reading a group NEVER marks its messages as read and sends no read receipts. Use get_groups to list groups and their ids.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| group_id | string | yes | The group to read. Accepts the group chat_id (e.g. 120363041234567890@g.us), the id returned by get_groups, or the group name. |
| page | integer | no | Page number for pagination (default: 1) |
| per_page | integer | no | Messages per page (default: 15, max: 50) |
Send one real WhatsApp text message from the workspace's WhatsApp number into one WhatsApp group, after the user confirms. Every member of that group (real people outside LetsBot) receives it, and a sent message cannot be recalled or edited. Works on a number connected to LetsBot by QR code (the number's own WhatsApp groups), and on an official green-tick Cloud API number (not Coexistence) for gro
| Parameter | Type | Required | Notes |
|---|---|---|---|
| group_id | string | no | The group's "chat_id" exactly as returned by get_groups (e.g. 120363041234567890@g.us), for ONE group. The digits without @g.us are also accepted. Group names and the numeric "id" field are refused. T |
| chat_id | string | no | Alias of "group_id", accepted because get_groups calls this value "chat_id". Pass the group in "group_id" OR "chat_id", not both. |
| message | string | yes | The text to post into the group. Every member of the group will see it. To tag (@mention) a member so WhatsApp notifies them, write @ followed by their full number in international format without + or |
| mentions | array | no | Optional, WhatsApp groups on a QR-connected number only. Group members to tag (@mention) so WhatsApp highlights their name and notifies them: phone numbers in international format without + (e.g. "551 |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Send one real file — a document such as a PDF, an image, or a video — from the workspace's WhatsApp number into one WhatsApp group, after the user confirms. Every member of that group receives it and it cannot be recalled. file_url must be a DIRECT url to the file: if the file is a Google Drive / Dropbox share link, or only exists as bytes you generated, call upload_file first (pass the link as
| Parameter | Type | Required | Notes |
|---|---|---|---|
| group_id | string | no | The group's "chat_id" exactly as returned by get_groups (e.g. 120363041234567890@g.us), for ONE group. The digits without @g.us are also accepted. Group names and the numeric "id" field are refused. T |
| chat_id | string | no | Alias of "group_id", accepted because get_groups calls this value "chat_id". Pass the group in "group_id" OR "chat_id", not both. |
| file_url | string | yes | Direct https url of the file — typically the url returned by upload_file. Not a Drive/Dropbox/OneDrive share page. |
| filename | string | no | Display name INCLUDING the extension (e.g. "proposal.pdf") — pass the filename upload_file returned. WhatsApp uses the extension to pick the file type, so a name without one arrives as an unopenable |
| caption | string | no | Optional text shown with the file in the group. |
| media_type | string | no | How WhatsApp shows it: "document" (default — a downloadable file with its name, right for PDFs and office files), "image" (shown inline; jpg/png/webp) or "video" (played inline; mp4). |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Get all labels/tags available in the account. Labels are used to categorize and organize contacts.
Takes no parameters.
Create a new label/tag for organizing contacts.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| name_ar | string | yes | Label name in Arabic |
| name_en | string | yes | Label name in English |
| color | string | yes | Label color in hex format (e.g., #25d366) |
Get all contacts that are assigned to a specific label.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| label_id | integer | yes | ID of the label |
| page | integer | no | Page number for pagination (default: 1) |
Get all moderators/agents available in the account. Moderators are team members who can handle conversations.
Takes no parameters.
Get all quick replies/canned responses available. Quick replies are pre-written message templates that can be sent quickly.
Takes no parameters.
Create a new quick reply/canned response. Quick replies let agents send pre-written messages instantly.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| title_ar | string | yes | Title/keyword in Arabic |
| title_en | string | yes | Title/keyword in English |
| text | string | yes | The quick reply message text |
| reply_type | string | no | Type of reply: text, image, file, audio, video, location |
Update an existing quick reply/canned response by ID. Only the provided fields change; everything else stays as it was. Run get_quick_replies first to find the quick reply ID.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | integer | yes | ID of the quick reply to update |
| title_ar | string | no | New title/keyword in Arabic |
| title_en | string | no | New title/keyword in English |
| text | string | no | New quick reply message text |
| body_ar | string | no | New quick reply body in Arabic |
| body_en | string | no | New quick reply body in English |
| reply_type | string | no | Type of reply: text, image, file, audio, video, location |
| status | boolean | no | Enable or disable this quick reply |
Delete a quick reply (canned response) by ID. Run get_quick_replies first to find the ID. To only hide it, use update_quick_reply with status=false instead.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | integer | yes | ID of the quick reply to delete |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Rename or recolour an existing contact label by ID. Only the fields you pass change. Run get_labels first to find the ID. Contacts keep the label; they just show the new name/colour.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| label_id | integer | yes | ID of the label to update |
| name_ar | string | no | New label name in Arabic |
| name_en | string | no | New label name in English |
| color | string | no | New colour as a hex code including the #, e.g. #25d366 |
Delete a contact label by ID. The label is removed from every contact that has it and from the inbox filters; the contacts themselves are not touched. Run get_labels first to find the ID.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| label_id | integer | yes | ID of the label to delete |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Return the recent conversation and contact context so the assistant can draft suggested replies. The assistant generates the reply suggestions from the returned context (nothing is sent).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number of the contact to suggest a reply for |
| additional_context | string | no | Optional additional context or instructions to steer the suggestions |
Return the recent conversation history with a contact so the assistant can summarize it (key topics, issues, and outcomes). The assistant writes the summary from the returned messages.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number of the contact |
| message_count | integer | no | Number of recent messages to include (default: 50, max: 100) |
Return a contact profile and recent conversation sample so the assistant can analyze the customer (engagement level, interests, recommendations). The assistant performs the analysis on the returned data.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number of the contact to analyze |
Return a draft message together with the desired tone and context so the assistant can rewrite it (grammar, tone, clarity) while keeping the original intent. The assistant produces the improved version.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| message | string | yes | The message text to improve |
| context | string | no | Optional conversation context for a better rewrite |
| tone | string | no | Desired tone: professional, friendly, formal, casual |
Return a message together with the requested target language so the assistant can translate it. The assistant produces the translation.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| message | string | yes | The message text to translate |
| target_language | string | yes | Target language (e.g., Arabic, English, French, Spanish) |
Return the customer messages of a conversation so the assistant can analyze sentiment (positive, negative, or neutral) and emotional indicators. The assistant performs the sentiment analysis on the returned messages.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number of the contact |
| message_count | integer | no | Number of recent customer messages to include (default: 20, max: 50) |
Return key dashboard metrics (contact counts, conversations awaiting a reply, active moderators, today's activity, recent contacts) plus guidance so the assistant can write an interpreted summary. The tool itself only computes the counts. It reports no read/unread state: nothing here indicates what the merchant has opened or seen on their own device.
Takes no parameters.
Get the status and details of an e-commerce order. Supports Salla and Zid platforms, and any other connected store that can look orders up (odoo, shopify, woocommerce). Orders are synced from the connected store.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| order_id | string | yes | The order ID/reference number |
| platform | string | no | E-commerce platform: salla, zid or odoo, shopify, woocommerce. If not specified, searches every connected store. |
Search for products in the connected e-commerce store. Searches by name in Salla and Zid product catalogs, and in every other connected store (odoo, shopify, woocommerce) by name, SKU or barcode.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| query | string | yes | Search query (product name or keyword) |
| platform | string | no | E-commerce platform: salla, zid or odoo, shopify, woocommerce. If not specified, searches every connected store. |
| limit | integer | no | Max results to return (default: 10) |
Get abandoned carts from the connected store (Salla, Zid, Shopify, WooCommerce or Magento) for the last N days, with a recovery summary: how many carts were abandoned and are still open, how many were recovered (bought later), how many of those were recovered after a WhatsApp reminder, the recovery rate and the recovered value. Each cart lists the customer name and phone, total, currency, items, c
| Parameter | Type | Required | Notes |
|---|---|---|---|
| days | integer | no | How many days back to look (1-365). Default 7. |
| platform | string | no | Only this store platform. If not specified, every store that has carts is included. |
| status | string | no | Which carts to list: open (abandoned, not bought yet), recovered (bought later) or all. Default all. The summary always covers both. |
| page | integer | no | Page number for the cart list (default: 1, 15 carts per page). |
List every automatic WhatsApp message this workspace sends to its store customers, and whether each one is ON or OFF: order/store event notifications (kind notification_template — e.g. order created, shipped, delivered, per store platform), abandoned-cart reminders (kind cart_reminder, plus older per-store ones as legacy_cart_reminder, read-only) and automation reminders (kind behavioral_reminder
| Parameter | Type | Required | Notes |
|---|---|---|---|
| kind | string | no | Optional: only this kind of automation. |
| platform | string | no | Optional: only automations for this store platform (e.g. salla, zid, shopify, woocommerce). |
| active | boolean | no | Optional: true = only those switched ON, false = only those switched OFF. |
Turn ONE automatic store message on or off — an order/store notification, an abandoned-cart reminder or an automation reminder — exactly like its toggle in the LetsBot panel. Get kind + id from list_store_automations first. Turning it ON makes LetsBot message the merchant's customers automatically every time the event happens (Meta bills each message on an official WhatsApp number), so only do it
| Parameter | Type | Required | Notes |
|---|---|---|---|
| kind | string | yes | The automation kind, as returned by list_store_automations. |
| id | integer | yes | The automation id, as returned by list_store_automations (ids are per kind). |
| active | boolean | yes | true = switch ON (starts automatic sends), false = switch OFF. |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Create a new bulk message campaign to send messages to multiple contacts. Messages can be targeted by label. Campaign will be scheduled and processed by the queue.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| text | string | yes | The message text to send |
| label_ids | array | yes | Array of label IDs to target. Contacts with these labels will receive the message. |
| send_now | boolean | no | Whether to dispatch immediately (true) or schedule for later (false). Default: false — a campaign must be dispatched explicitly. |
| sending_date | string | no | Scheduled date/time in YYYY-MM-DD HH:mm format. Required if send_now is false. |
| window_ack | boolean | no | Required (true) when this workspace sends through an official WhatsApp Cloud API number: this campaign is free-form text, which Meta delivers ONLY to contacts who messaged the business in the last 24 |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Get a list of bulk message campaigns. Shows campaign status, delivery stats, and scheduling info.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| status | string | no | Filter by status: all, pending, in_progress, done, canceled |
| page | integer | no | Page number for pagination (default: 1) |
Get detailed status of a specific bulk message campaign including per-contact delivery statistics.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| campaign_id | integer | yes | ID of the campaign |
Stop a bulk message campaign that is scheduled or sending right now. Recipients not reached yet will not get the message; those already sent are unaffected. Use it immediately when the merchant says a campaign is wrong or must stop. The campaign can be resumed later from the LetsBot panel (Bulk messages → the campaign).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| campaign_id | integer | yes | ID of the campaign (from get_campaigns or create_campaign). |
Resume a bulk campaign that was stopped (cancel_campaign / Cancel in the panel), finished with recipients left unsent, stopped because its template header file was missing, or paused because the plan's monthly message limit was used up (resume it after the plan is upgraded). Sends the campaign to every recipient who has not received it yet — real WhatsApp messages that Meta charges for. Requires c
| Parameter | Type | Required | Notes |
|---|---|---|---|
| campaign_id | integer | yes | ID of the campaign (from get_campaigns). |
| window_ack | boolean | no | Required (true) only when the campaign is not an approved template and the workspace uses an official WhatsApp Cloud API number: Meta then delivers it only to contacts who messaged in the last 24 hour |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Send a bulk campaign again to the recipients whose message is stuck at "sent" — WhatsApp accepted it but it was never confirmed delivered (phone offline, number inactive). Delivered and read recipients are NOT messaged again. Recipients who never got it yet are included. Real WhatsApp messages that Meta charges for, and someone who did receive it without a delivery receipt may get it twice. Requir
| Parameter | Type | Required | Notes |
|---|---|---|---|
| campaign_id | integer | yes | ID of the campaign (from get_campaigns). |
| window_ack | boolean | no | Required (true) only when the campaign is not an approved template and the workspace uses an official WhatsApp Cloud API number: Meta then delivers it only to contacts who messaged in the last 24 hour |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Get the current bot status and settings. Shows whether the bot is active, AI mode, default reply settings, and match percentage.
Takes no parameters.
Toggle the bot on or off for a specific contact. When bot is disabled for a contact, automated replies will not be sent.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| phone | string | yes | Phone number of the contact |
| enabled | boolean | yes | Whether to enable (true) or disable (false) the bot for this contact |
| pause_duration | string | no | Optional, only when enabled is false: how long the bot stays off. A number of minutes as a string (e.g. "60" or "240", at most "43200"), "end_of_day" (until the end of today in the workspace time zone |
Get all bot auto-reply conversations/rules. Shows configured triggers and their responses.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| enabled_only | boolean | no | If true, only return enabled conversations (default: true) |
| page | integer | no | Page number for pagination (default: 1) |
Create a simple bot auto-reply rule. When a customer sends a message matching the trigger keyword, the bot replies with the specified text. With "ask_contact" the reply asks for the customer's phone number or e-mail with a one-tap Messenger button (text only on other channels); "confirmation" is then sent once after the customer taps it.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| hear | string | yes | Trigger keyword or phrase that activates this reply |
| text | string | yes | Reply message text to send when triggered. With "ask_contact" it is the question shown above the button and may be "" (= a standard question in the workspace language). |
| match_message | boolean | no | If true, requires exact match. If false, partial/fuzzy match (default: false) |
| label_id | integer | no | Optional label ID to auto-assign to the contact when triggered |
| agent_id | integer | no | Optional moderator ID to auto-assign to the contact when triggered |
| channels | array | no | Optional. Channels this rule replies on, e.g. ["instagram", "messenger"]. Omit or [] = every channel (default). "whatsapp" covers both official and unofficial WhatsApp numbers. On other channels the m |
| ask_contact | string | no | Optional. Make the rule ask the customer for their phone number ("phone") or e-mail ("email") with one tap. On Facebook Messenger the reply text goes out with a quick-reply button pre-filled from the |
| confirmation | string | no | Optional, with an "ask_contact" rule only. Confirmation message sent ONCE on the same channel and in the same conversation right after the customer taps the Messenger button and shares the phone numbe |
Create an interactive bot conversation with buttons. When triggered, shows a message with clickable button options that lead to different responses.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| hear | string | yes | Trigger keyword or phrase |
| text | string | yes | Message body that appears with the buttons |
| title | string | no | Header title for the interactive message |
| footer | string | no | Footer text below the message |
| channels | array | no | Optional. Channels this rule replies on, e.g. ["instagram", "messenger"]. Omit or [] = every channel (default). "whatsapp" covers both official and unofficial WhatsApp numbers. On other channels the m |
| buttons | array | yes | Array of buttons (max 3) |
Update an existing bot auto-reply rule by ID. Only the provided fields change; everything else stays as it was. "channels" limits the rule to some channels ([] = every channel). Run get_bot_conversations first to find the conversation ID.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | integer | yes | ID of the bot conversation to update |
| hear | string | no | New trigger keyword or phrase that activates this reply |
| text | string | no | New reply message text to send when triggered |
| match_message | boolean | no | If true, requires an exact match. If false, partial/fuzzy match. |
| enabled | boolean | no | Enable or disable this auto-reply rule |
| label_id | integer | no | Label ID to auto-assign to the contact when triggered (use 0 to clear) |
| agent_id | integer | no | Moderator ID to auto-assign to the contact when triggered (use 0 to clear) |
| channels | array | no | Optional. Channels this rule replies on, e.g. ["instagram", "messenger"]. Omit or [] = every channel (default). "whatsapp" covers both official and unofficial WhatsApp numbers. On other channels the m |
| ask_contact | string | no | Optional. Make the rule ask the customer for their phone number ("phone") or e-mail ("email") with one tap. On Facebook Messenger the reply text goes out with a quick-reply button pre-filled from the |
| confirmation | string | no | Optional, with an "ask_contact" rule only. Confirmation message sent ONCE on the same channel and in the same conversation right after the customer taps the Messenger button and shares the phone numbe |
Get all bot and AI-related settings for the current account.
Takes no parameters.
Update bot settings. Only the settings you pass are changed; the others stay as they are. ai_mode chooses HOW the AI behaves ("standard" = full assistant, "cod_only" = only confirms cash-on-delivery orders); it does not switch AI replies on or off — use update_ai_assistant_settings with ai_replies_enabled for that.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| ai_mode | string | no | "standard" = the AI answers with its full capabilities. "cod_only" = the AI only confirms cash-on-delivery orders, and new contacts start with the bot paused. To turn AI replies on/off use update_ai_a |
| match_percentage | integer | no | How much of a keyword the customer must type for a bot rule to match (1-100, default 60). Higher = stricter matching. |
| enable_default_reply | boolean | no | Enable/disable the default reply sent when no bot rule matches. |
| default_reply_delay | integer | no | How long after a customer's previous message the default reply stays silent, as a number in default_reply_delay_unit (e.g. 1 with unit "hours"). If no unit is passed, the workspace's current unit is k |
| default_reply_delay_unit | string | no | Unit of default_reply_delay. |
Turn one bot flow (auto-reply conversation of any type: simple, buttons, template or list) ON or OFF by ID. An OFF flow stays saved but the bot stops answering its keywords. Asking for the state it is already in changes nothing. A buttons/template flow with no buttons, or a list flow with no sections, cannot be turned ON until it is completed in the panel. This does NOT switch the whole bot (use t
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | integer | yes | ID of the bot flow (from get_bot_conversations) |
| active | boolean | yes | true to turn the flow ON, false to turn it OFF |
Make a full copy of one bot flow (any type) by ID: the reply, its media, and all of its buttons, list sections and follow-up replies. The copy has the same keywords and the same ON/OFF state as the original, so two flows now answer the same keywords — change the copy's keyword with update_bot_conversation, or turn it off with set_bot_conversation_active. Each call creates a new copy. Run get_bot_c
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | integer | yes | ID of the bot flow to copy (from get_bot_conversations) |
Permanently delete one bot flow (any type) by ID, together with its buttons and list sections. The bot stops answering its keywords. This cannot be undone — to pause a flow instead, use set_bot_conversation_active with active=false. Call with confirm=false first to get a preview (keywords, buttons, sections) to show the user. Run get_bot_conversations with enabled_only=false to find IDs.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | integer | yes | ID of the bot flow to delete (from get_bot_conversations) |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Get the ad-lead auto-labeling configuration. Shows the label and moderator (if any) that the tenant has chosen to auto-apply to incoming contacts that arrive from a Meta Click-to-WhatsApp ad.
Takes no parameters.
Configure which label and moderator are auto-applied to contacts that arrive from a Meta Click-to-WhatsApp ad. Pass 0 for either field to clear that setting. Pass nothing to leave both as they were. Run get_labels and get_moderators first to find valid IDs.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| label_id | integer | no | ContactLabel ID to auto-apply on ad-lead arrival. 0 clears the setting (feature disabled for labels). |
| agent_id | integer | no | Moderator (User) ID to auto-assign on ad-lead arrival. 0 clears the setting (no moderator auto-assigned). |
Read ONE automatic store notification (order status, verification code/OTP, welcome, review request …) in full: its message text in every language, its image/video/file, whether it is on, and its WhatsApp (Meta) approval. Pass the id from list_store_automations (kind notification_template), or the store module + event slug (e.g. module "salla", slug "otp" or "completed").
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | integer | no | The template id (list_store_automations, kind notification_template). |
| module | string | no | Store module when looking up by slug, e.g. "salla". |
| slug | string | no | Event slug when no id is known, e.g. "otp", "completed", "customer_created". |
Edit ONE automatic store notification (order status, verification code/OTP, welcome, review request …) that LetsBot sends on WhatsApp to the store's real customers when that event happens: change its message text in one or more languages, which languages are sent, its image/video/file (an https link), and/or switch it on (customers start receiving it automatically) or off (they stop receiving it).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | integer | yes | The template id (get_notification_template / list_store_automations). |
| texts | object | no | New message text per language code, e.g. {"ar": "…", "en": "…"}. Only the languages given change. |
| enabled_languages | array | no | Optional: the languages this notification is sent in, e.g. ["ar"] or ["ar","en"]. |
| media_url | string | no | Optional: public https link of the new image/video/file (only for a media notification). |
| remove_media | boolean | no | Optional: true removes the current image/video/file. |
| active | boolean | no | Optional: true switches it ON (customers get it automatically), false OFF. |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Create a new abandoned-cart reminder step (omit id) or edit one (pass its id from list_store_automations, kind cart_reminder): when it is sent after the cart is abandoned (delay_value + delay_unit), its message text per language, the minimum cart total, and whether it is on. While it is on, LetsBot sends it automatically on WhatsApp to the store's real customers who leave a cart, so editing an act
| Parameter | Type | Required | Notes |
|---|---|---|---|
| id | integer | no | Omit to create a new reminder; pass the cart_reminder id to edit one. |
| title | string | no | Internal name the merchant sees in the panel, e.g. "First reminder". |
| texts | object | no | Message text per language code, e.g. {"ar": "…"}. Required (at least one language) when creating. |
| delay_value | integer | no | How long after the cart is abandoned, e.g. 2. |
| delay_unit | string | no | Unit of delay_value. |
| minimum_cart_total | number | no | Optional: only carts worth at least this much (0 = all carts). |
| active | boolean | no | true = ON (customers get it automatically), false = OFF. New reminders default to OFF. |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Build a keyword bot flow (menu, buttons, replies) from a description in the merchant's words, any language. It is created SWITCHED OFF in the bot builder so the merchant can review and edit it, then switch it on. Uses 1 AI credit. Put everything the merchant described into "description": the trigger words, the menu options and each reply.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| description | string | yes | What the flow does, in the merchant's words (10–2000 characters). |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Read how the AI assistant answers customers: whether AI replies are on, its instructions, its working hours and outside-hours message, when it hands the chat to a person (pause after hand-off / after a manual reply), what it does with voice notes, extra rules, timezone, and the Arabic dialect/tone when available.
Takes no parameters.
Change how the workspace's AI assistant automatically answers the business's real customers on WhatsApp (and any other connected chat channel it answers). The change applies to the next customer messages straight away, the previous values are overwritten, and turning ai_replies_enabled on makes the AI reply to customers by itself (each reply uses an AI credit). Pass ONLY the settings the merchant
| Parameter | Type | Required | Notes |
|---|---|---|---|
| settings | object | yes | The settings to change, e.g. {"voice_note_mode": "silent"}. |
| confirm | boolean | yes | Consent gate — REQUIRED on every call. Pass false first: the tool then performs no action and returns a preview of exactly what would happen. Show that preview to the user, get their explicit approval |
Answer "why are my messages failing / not arriving?": checks the WhatsApp number connection (QR logged out, access removed by Meta, test number, billing block), the reasons Meta gave for the latest failed messages, failed automatic store messages, and automatic messages whose WhatsApp template is not approved — each problem with its fix. Read-only.
Takes no parameters.
The step-by-step set-up of a store on LetsBot (Salla, Zid, Shopify, …): 1 connect the WhatsApp number, 2 store notifications (order status, verification code, welcome, review), 3 abandoned-cart reminders, 4 cash-on-delivery confirmation, 5 AI replies. Use it when the merchant asks to set up his store/account or "what is left"; then walk him through the first unfinished step.
Takes no parameters.
- Every tool — any call limit is its publisher’s, not ours
- No card, and mcprush charges nothing for it
- Runs at its publisher’s own address — this marketplace is not in the path
- Nothing to cap, because mcprush bills nothing
What counts against your monthly calls
| Tool | Unit | Calls used | Out of the allowance |
|---|
Nothing here is billable: mcprush charges nothing to install LetsBot or to call it, at any volume.
Two independent axes, because powerful and malicious are different questions. The grade is threat only. The capability level is blast radius, and it is never a penalty on the grade — it is priced as one subtract-only term in the score, where you can see it.
| Term | Level | What it prices | Points |
|---|---|---|---|
| capability-exposure | moderate | capability blast radius (moderate) — client exposure if the model is manipulated | −3 |
| coverage-honesty | manifest | inspection depth (manifest) — how much of the target the scan could see | −4 |
What the scan could actually read
A grade is only as meaningful as its coverage, so the scanner publishes its own depth before it publishes its result.
The scan read each tool’s name, description, input schema and annotations exactly as the server listed them the last time it answered us; no code was reviewed. We ask the server again about once a month, and a list that changed is graded again.
The implementation source was not read — this reflects the declared tool metadata only.
Capability — what it could do if the model were manipulated
Tags derived from each tool’s schema and the implementation, not from what the tool calls itself. moderate is the level these add up to.
| Tool | Capability tags | Why the tag was assigned |
|---|---|---|
| send_text_message | external-sink | external-sink: keyword "sms", declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| send_image | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| send_video | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| send_audio | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| send_file | untrusted-inputexternal-sink | untrusted-input: keyword "download"; external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| send_location | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| send_contact_card | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| send_template | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| send_buttons | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| send_list | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| send_carousel | external-sink | external-sink: parameter "recipient", declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| reply_to_message | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| send_reaction | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| forward_message | external-sink | external-sink: keyword "forward_message", declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| upload_file | untrusted-inputexternal-sink | untrusted-input: keyword "download"; external-sink: keyword "upload_file", declares readOnlyHint: false, openWorldHint: true |
| get_contacts | no tags | |
| get_contact | no tags | |
| create_contact | state-write | state-write: declares readOnlyHint: false |
| update_contact | state-write | state-write: declares readOnlyHint: false, destructiveHint: true |
| get_my_chats | no tags | |
| get_conversations_awaiting_reply | no tags | |
| pin_contact | state-write | state-write: declares readOnlyHint: false |
| archive_contact | state-write | state-write: declares readOnlyHint: false |
| block_contact | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| delete_contact | state-write | state-write: declares readOnlyHint: false, destructiveHint: true |
| assign_label | state-write | state-write: declares readOnlyHint: false |
| assign_moderator | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| reassign_conversations | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| get_assignment_rules | no tags | |
| update_assignment_rules | state-write | state-write: declares readOnlyHint: false, destructiveHint: true |
| add_note | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| get_account_overview | no tags | |
| get_owner_briefing | no tags | |
| get_report | no tags | |
| list_whatsapp_templates | no tags | |
| create_whatsapp_template | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| list_scheduled_activity | no tags | |
| cancel_scheduled_activity | state-write | state-write: declares readOnlyHint: false, destructiveHint: true |
| get_messages | no tags | |
| get_message_status | no tags | |
| search_messages | no tags | |
| mark_as_read | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| get_groups | no tags | |
| get_group_messages | no tags | |
| send_group_message | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| send_group_file | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| get_labels | no tags | |
| create_label | state-write | state-write: declares readOnlyHint: false |
| get_label_contacts | no tags | |
| get_moderators | no tags | |
| get_quick_replies | no tags | |
| create_quick_reply | state-write | state-write: declares readOnlyHint: false |
| update_quick_reply | state-write | state-write: declares readOnlyHint: false, destructiveHint: true |
| delete_quick_reply | state-write | state-write: declares readOnlyHint: false, destructiveHint: true |
| update_label | state-write | state-write: declares readOnlyHint: false, destructiveHint: true |
| delete_label | state-write | state-write: declares readOnlyHint: false, destructiveHint: true |
| ai_suggest_reply | no tags | |
| ai_summarize_conversation | no tags | |
| ai_analyze_contact | no tags | |
| ai_improve_message | no tags | |
| ai_translate_message | no tags | |
| ai_sentiment_analysis | no tags | |
| ai_dashboard_summary | no tags | |
| get_order_status | no tags | |
| search_products | no tags | |
| get_abandoned_carts | no tags | |
| list_store_automations | no tags | |
| set_store_automation_active | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| create_campaign | external-sink | external-sink: keyword "send_message", declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| get_campaigns | no tags | |
| get_campaign_status | no tags | |
| cancel_campaign | state-write | state-write: declares readOnlyHint: false |
| resume_campaign | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| resend_campaign | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| get_bot_status | no tags | |
| toggle_bot | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| get_bot_conversations | no tags | |
| create_simple_conversation | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| create_interactive_conversation | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| update_bot_conversation | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| get_bot_settings | no tags | |
| update_bot_settings | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| set_bot_conversation_active | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| duplicate_bot_conversation | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| delete_bot_conversation | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| get_ad_lead_settings | no tags | |
| update_ad_lead_settings | state-write | state-write: declares readOnlyHint: false, destructiveHint: true |
| get_notification_template | no tags | |
| update_notification_template | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| save_cart_reminder | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| draft_bot_flow | external-sink | external-sink: declares readOnlyHint: false, openWorldHint: true |
| get_ai_assistant_settings | no tags | |
| update_ai_assistant_settings | external-sink | external-sink: declares readOnlyHint: false, destructiveHint: true, openWorldHint: true |
| diagnose_messaging | no tags | |
| get_store_setup_checklist | no tags |
Toxic-flow graph
The lethal trifecta, checked as a graph rather than as a checklist: untrusted input, a sensitive source and an external sink have to meet before there is a path worth worrying about.
Supply chain and provenance
This is the first scan of this surface here, so there is nothing yet to compare it against.
Every result on this tab comes from one deterministic pass over the published package — offline, rule by rule, and auditable line by line above. Same methodology version, same bytes, same score.
Release history
This is an address its publisher runs: which release it serves is theirs to choose, so there is nothing here to pin. The history below is for reading; the current release on file is 1.0.0.
No release note was published with this version.
One review per account, from a signed-in account that does not publish this listing. Nothing else is asked — you can say what you think before you install it. Publishers can reply once per review, and a review can be edited or deleted by whoever wrote it.
Any signed-in account that does not publish LetsBot can review it, once — before installing it or after. A review from an account that has installed it is marked as one.
Nobody has reviewed this listing. The rating on the card is the mean of the reviews written here and nothing else, so there is no rating until somebody writes the first — which takes a signed-in account that does not publish it, and nothing else.