MCP server
Connecting an MCP client to your WhatsApp number — the endpoint, the OAuth flow, install for Claude Code, Claude Desktop and any other client, and the scopes the consent screen can and cannot offer.
A remote, multi-tenant MCP server at mcp.cosend.app/mcp, speaking Streamable HTTP. It exposes
one WhatsApp number as tools any MCP-capable agent can call.
The MCP page has the nineteen tools and the reason there is no bulk send. This page is how to connect one, and what the consent screen will ask you for.
The endpoint
https://mcp.cosend.app/mcp
It is stateless: no session header, no handshake, any request to any instance. There is no key to paste anywhere — the server is an OAuth 2.1 resource server and issues no tokens of its own.
Claude Code
claude mcp add --transport http cosend https://mcp.cosend.app/mcp
Then run /mcp inside Claude Code to complete the OAuth flow. Until you do, claude mcp list
shows the server as needing authentication.
Scope the installation to yourself or to a project:
claude mcp add --transport http cosend https://mcp.cosend.app/mcp --scope user
claude mcp add --transport http cosend https://mcp.cosend.app/mcp --scope project
For a team that commits its configuration, .mcp.json:
{
"mcpServers": {
"cosend": {
"type": "http",
"url": "https://mcp.cosend.app/mcp"
}
}
}
Claude Desktop and claude.ai
Settings → Connectors → Add custom connector → paste the URL. The browser runs the OAuth flow.
On a Team or Enterprise workspace an owner adds the connector at the organisation level before members can enable it. You do not need to paste a client ID or secret into the advanced settings: we support Client ID Metadata Documents and dynamic client registration, so the client registers itself. The field is there for enterprises that pre-register clients deliberately.
Any other client
Any MCP client that speaks Streamable HTTP with OAuth works against the same URL.
{
"mcpServers": {
"cosend": { "type": "streamable-http", "url": "https://mcp.cosend.app/mcp" }
}
}
What the consent screen asks for
The scopes are the same strings an organization API key carries. One vocabulary across the platform, so what you approve on the consent screen is exactly what the API enforces — two vocabularies for one permission model means the screen can drift from the enforcement.
| Scope | Grants | Risk |
|---|---|---|
messages:read | Conversations, threads and messages | low |
messages:write | Sending into a single existing conversation | high — it reaches a real person |
contacts:read | Contacts and their attributes | low |
contacts:write | Creating and updating contacts, tags and consent | medium |
templates:read | Templates and their review status | low |
templates:write | Drafting templates and submitting them to Meta | medium — it affects your quality rating |
automations:read | Automations, versions and validation reports | low |
automations:write | Creating, updating, deploying, enabling | high — delegated future sending |
runs:read | Run history and per-step traces | low |
runs:write | Triggering and cancelling runs | medium |
connectors:read / connectors:write | Connector accounts | medium — third-party data |
usage:read | Usage and billing counters | low |
Grant the ones the agent needs. messages:write and automations:write are the two worth
thinking about, and they are marked high for the same reason: one puts text on a stranger’s phone
now, the other arranges for text to be put on a stranger’s phone later.
Four scopes the screen will never offer
Not “will not use” — cannot obtain. A scope an agent cannot get is stronger than a scope it is told not to use, because there is nothing to leak, misconfigure or talk a model into.
| Withheld | Why |
|---|---|
keys:write | An agent that can mint API keys can escalate a scoped, revocable, audited consent into a permanent unaudited credential. The dashboard is the only place a key is created |
connections:write | Connecting or disconnecting a WhatsApp number is an Embedded Signup flow with a human in it. There is no agent-shaped version of it |
runtime:proxy | The Graph passthrough takes connection keys only, by design — a Graph request names its target with a path segment, and a broader credential would make that segment select a connection |
| Any wildcard | There is no cosend:*, no all and no full-access. Omnibus scopes are a named mistake in the protocol’s own security guidance |
The notify rail and webhook-endpoint management have no MCP surface at all, so their scopes are not requestable either.
Plan
The MCP server is not on the Free tier. An organization on Free that reaches it gets a 403
with the upgrade URL before any tool resolves —
plan_does_not_include. Every paid plan includes it; see
pricing.