Sendveo for AI agents
Sendveo speaks the Model Context Protocol (MCP). Add it to Claude, Cursor, ChatGPT or any MCP-capable agent, then ask in plain language: list my numbers, connect this one, reply to that chat. The agent calls Sendveo for you.
What it is
The Sendveo MCP server is a small bridge between your AI assistant and your Sendveo account. It exposes the same actions as the API and the dashboard, as tools the assistant can call. Everything runs under your own account: you sign in with your Sendveo email and password, or, for a script or a command-line tool, you use an API key from your dashboard.
There are two ways to connect, and both expose the same tools. Hosted: paste one URL into the assistant and sign in, with nothing to install and no key to copy. Local: the assistant runs a small Sendveo command on your machine with an API key, which never leaves it.
What you can do
One tool per action, grouped as the guide groups them: numbers, messages, conversations, contacts, groups, health and profile, labels, webhook, billing. Operator features are not exposed: the server is limited to the account the connection belongs to.
| Tool | What it does |
|---|---|
| Numbers | |
| list_numbers | List your WhatsApp numbers, their status and their health. |
| get_number | Look up one number by id, with its health. |
| connect_number | Connect a new number. Returns a QR image to scan, or an 8-character code to type into WhatsApp. |
| refresh_qr | Get a fresh QR or code while a number is still pairing (they rotate). |
| reconnect_number | Re-link a number whose session dropped. |
| disconnect_number | Stand a number down. Frees its slot and keeps the number. |
| remove_number | Permanently remove a number. |
| Messages | |
| send_message | Send a WhatsApp message (text, files, a voice note, a location, contact cards, a quoted reply) to a phone number or into an existing conversation. |
| get_messages | Read stored inbound and outbound messages: text, type, delivery status, files, reactions. |
| get_message | Read one message by id, as it now stands. |
| get_attachment | Fetch a file from a message. An image comes back as an image you can see; anything else as its details plus a Sendveo link. |
| react_to_message | React to a message with one emoji. |
| remove_reaction | Take your reaction back. |
| forward_message | Forward a message into another conversation you already have. |
| delete_message | Delete a message for everyone. This cannot be undone. |
| mark_chat_read | Mark a conversation read, or unread. |
| send_typing | Show a typing indicator for a moment before a message. |
| Conversations | |
| list_chats | List your conversations: name, unread count, archived, muted, last message, labels. |
| get_chat | Read one conversation in full, including who is in it and its labels. |
| archive_chat | Archive a conversation. |
| unarchive_chat | Take a conversation back out of the archive. |
| mute_chat | Mute a conversation's notifications. |
| unmute_chat | Turn a conversation's notifications back on. |
| sync_chat_history | Pull older messages into what get_messages returns. |
| Contacts | |
| get_contact | What WhatsApp discloses about one number: on WhatsApp or not, name, business, status line. |
| get_contact_picture | A contact's profile picture, as an image you can see or as a Sendveo link. |
| lookup_numbers | Which of up to 50 numbers are on WhatsApp (yes or no, and nothing else). |
| Groups | |
| list_groups | List the groups your numbers are in. |
| get_group | Read one group: subject, picture and members. |
| get_group_picture | A group's picture, as an image or as a Sendveo link. |
| create_group | Create a group with a subject, members and an optional first message. |
| add_group_members | Add people to a group, the whole list in one call, checked before anybody joins. A refusal partway through leaves the earlier numbers in, and the error names them. |
| remove_group_member | Remove someone from a group (never yourself: use leave_group). |
| leave_group | Take your own number out of a group. |
| Health and profile | |
| get_number_health | Is this number working? Its status, its health and what has happened to it. |
| list_number_events | The health history on its own. Page through it with a cursor. |
| get_number_profile | What your own line publishes about itself: name, about, business, picture. Read-only. |
| get_number_picture | Your own line's picture, as an image you can see or as a Sendveo link. |
| Labels | |
| list_labels | Your labels, with how many conversations carry each. |
| create_label | Create a label: a name and an optional colour from a fixed palette. |
| update_label | Rename a label or change its colour. |
| delete_label | Delete a label. It comes off every conversation carrying it. |
| add_chat_label | Put a label on a conversation, by id or by name (a new name creates it). |
| remove_chat_label | Take one label off one conversation. |
| Webhook | |
| get_webhook | View the URL Sendveo posts inbound messages to. |
| set_webhook | Set or replace that URL. |
| Billing | |
| get_billing | See your credit and your slots: the credit available on your account, slots by card and by credit, any unpaid monthly renewal, and whether you can buy by card or activate numbers with your credit. |
connect_number, refresh_qr and reconnect_number accept an optional method. qr (the default) returns a QR to scan from WhatsApp under Linked devices, Link a device. code returns an 8-character code to type under Link with phone number: use it when you are on the same phone that holds the number and cannot scan the screen. Both expire and rotate, so ask for a fresh one if it stops working.
Option A: paste the URL and sign in (recommended)
Add Sendveo to your assistant as a remote MCP server. You need one value, the Sendveo MCP URL. There is nothing to install and no key to paste: your assistant opens a Sendveo page where you sign in and approve the connection.
https://mcp.sendveo.com/mcpIn Claude
- Open Settings, then Connectors, and choose Add custom connector.
- Paste the Sendveo MCP URL above and save. Your assistant finds the rest on its own.
- A Sendveo page opens in your browser. Sign in with the email and password you use for the dashboard.
- Read what the assistant is asking for and the address it will send you back to, then press Allow. Press Refuse and nothing is granted.
The assistant receives a connection tied to your account, carrying the permissions shown on that approval screen. It expires after an hour and renews itself quietly while the connection is in use. You never paste a key into the assistant, and nothing you approve reaches another account, the operator console, or your password.
To disconnect, remove the connector in your assistant. A connection you remove on the Sendveo side stops working immediately, for good.
If no sign-in page opens, check that the URL ends in /mcp. If your assistant reports that it could not reach the sign-in service, Sendveo is unreachable from your network, the same check as loading the dashboard.
ChatGPT, Cursor and other MCP-capable assistants use the same URL in their own remote MCP server settings, and sign you in the same way.
Option B: local (runs on your machine)
If you prefer to keep the key on your own machine, run the Sendveo MCP server locally. It needs Node.js 22 or newer. The assistant starts it with npx @sendveo/mcp and passes your key through the SENDVEO_API_KEY environment variable.
Add the block below to your assistant's MCP configuration. In Claude Desktop that is claude_desktop_config.json; in Claude Code run claude mcp add or edit .mcp.json; Cursor uses .cursor/mcp.json. The block is the same everywhere.
{
"mcpServers": {
"sendveo": {
"command": "npx",
"args": ["-y", "@sendveo/mcp"],
"env": {
"SENDVEO_API_KEY": "YOUR_SENDVEO_API_KEY"
}
}
}
}Replace the placeholder with your key, restart the assistant, and ask it to list your Sendveo numbers. If the server exits immediately, check that SENDVEO_API_KEY is set.
With an API key instead of signing in
Signing in is the normal way to use the hosted URL. If your tool cannot do that, a script, a curl call, or a client that only lets you set headers, the same URL also accepts a Sendveo API key sent as a bearer token. Each request is authenticated on that key alone and is limited to that key's account.
https://mcp.sendveo.com/mcpAuthorization: Bearer YOUR_SENDVEO_API_KEYScopes
Every connection carries scopes, and each tool needs one. When you sign in, the approval screen lists them in plain language before you press Allow. A new API key is granted every scope except the read-only shortcut, so it works with all tools out of the box. If a tool reports a missing scope, adjust the key under API keys in your dashboard, or connect again and approve the missing permission.
| Scope | Tools |
|---|---|
| numbers:read | list_numbers, get_number, get_billing, get_number_health, list_number_events, get_number_profile, get_number_picture |
| numbers:write | connect_number, refresh_qr, reconnect_number, disconnect_number, remove_number |
| messages:read | get_messages, get_message, get_attachment |
| messages:send | send_message, send_typing |
| messages:manage | react_to_message, remove_reaction, forward_message, delete_message, mark_chat_read |
| chats:read | list_chats, get_chat, list_labels |
| chats:manage | archive_chat, unarchive_chat, mute_chat, unmute_chat, sync_chat_history, create_label, update_label, delete_label, add_chat_label, remove_chat_label |
| contacts:read | get_contact, get_contact_picture, lookup_numbers |
| groups:read | list_groups, get_group, get_group_picture |
| groups:manage | create_group, add_group_members, remove_group_member, leave_group |
| webhooks:manage | get_webhook, set_webhook |
| *:read | Every read scope at once (a read-only connection): the tools of numbers:read, messages:read, chats:read, contacts:read and groups:read, and nothing that writes. |
messages:manage, chats:read, chats:manage, contacts:read, groups:read and groups:manage were added on 16 September 2026. An API key created before that date has none of them and cannot be given them: create a new key in your dashboard, or reconnect the assistant and approve the permissions. Everything else keeps working on the old key.
Billing is read-only and is covered by numbers:read: there is no separate billing scope.
Safety
- Signing in never gives the assistant your password, and no API key is stored by the hosted server. Each request is authenticated with the credential it carries, and the server keeps none of its own.
- Every request is isolated to the account behind the connection. Operator features are not reachable through MCP.
- Rate limits apply, per key and per source. A
429response means slow down and retry shortly. - Treat the key like a password. Prefer a key scoped to what the assistant needs, and revoke it from the dashboard if it leaks.
Troubleshooting
| You see | What to do |
|---|---|
401 or Invalid or missing Sendveo API key | Your connection was revoked or could not renew itself, or the API key is wrong, unset, or not sent as Authorization: Bearer .... Connect again, or copy a fresh key from your dashboard. |
No available slot | You have used all your number slots. Buy a slot by card or activate one with your credit under Billing in your dashboard, then retry connect_number. |
429 or Rate limit exceeded | Too many requests in a short time. Wait a moment and retry, and ask the assistant to make fewer calls at once. |
does not have the scope required | Grant the missing scope on the key under API keys, or create a new key with every scope. |