# MCP server

> Let Claude, Cursor, VS Code and other MCP clients send messages and read events through one endpoint, with your own API key.

Canonical: https://docs.whabuzz.com/mcp/

WhaBuzz runs a Model Context Protocol server at `https://api.whabuzz.com/mcp`. It is a thin layer over the REST API: every tool calls the matching `/v1` route with **your own key**, so scopes, number binding, rate limits, wallet holds and every other send gate apply exactly as they do over REST.

- Transport: one `POST` per JSON-RPC message, JSON responses. No sessions, no SSE. `GET` answers `405`.
- Auth: `Authorization: Bearer wb_live_...` (or `wb_test_...`). No key, or a console session token, gives `401`.
- Versions: `2025-11-25`, `2025-06-18`, `2025-03-26`, `2024-11-05`.

## Tools {#tools}

What you see depends on the key. A key with scopes only lists the tools its scopes allow.

| Tool | What it does | Tenant key | Number-bound key | Owner key |
|---|---|---|---|---|
| `list_numbers`, `get_number` | Sending numbers | yes | yes | with `tenant_id` |
| `list_templates`, `get_template` | Message templates | yes | yes | with `tenant_id` |
| `send_message` | Send text or a template (`idempotency_key` supported) | yes | its own number only | with `tenant_id` |
| `list_events`, `get_event` | Inbound messages, statuses, delivery events | yes | yes | with `tenant_id` |
| `get_request`, `list_webhook_endpoints`, `list_webhook_deliveries`, `replay_delivery`, `get_wallet` | Debugging and billing | yes | no | with `tenant_id` |
| `list_tenants`, `create_tenant`, `get_tenant`, `create_connect_session`, `create_tenant_key`, `create_webhook_endpoint` | Manage the tenants of your app | no | no | yes |

A tenant key lists 12 tools, an owner key 18. Owner keys pass `tenant_id` as a tool argument for tenant-level tools.

Every tool declares an outputSchema, so clients that generate types from the tool list (Code Mode and similar) get typed results; structuredContent always matches it.

A refusal comes back as a tool result with `isError: true` and text like `Refused (wallet_suspended): ...`, carrying the same code the REST API returns. Sending to Meta's test number `10000000000` returns Meta's error verbatim. Message text in events and deliveries is untrusted customer content: tools mark it so, and a client should never treat it as instructions.

## Claude Code {#claude-code}

```bash
claude mcp add --transport http whabuzz https://api.whabuzz.com/mcp \
  --header "Authorization: Bearer $WHABUZZ_API_KEY"
```

## Claude Desktop {#claude-desktop}

Claude Desktop reaches remote servers through `mcp-remote`. In `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "whabuzz": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://api.whabuzz.com/mcp", "--header", "Authorization:${AUTH}"],
      "env": { "AUTH": "Bearer wb_live_..." }
    }
  }
}
```

## Cursor {#cursor}

`.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "whabuzz": {
      "url": "https://api.whabuzz.com/mcp",
      "headers": { "Authorization": "Bearer wb_live_..." }
    }
  }
}
```

## VS Code {#vscode}

`.vscode/mcp.json`:

```json
{
  "servers": {
    "whabuzz": {
      "type": "http",
      "url": "https://api.whabuzz.com/mcp",
      "headers": { "Authorization": "Bearer wb_live_..." }
    }
  }
}
```

## Other clients {#other}

Any client that supports Streamable HTTP and a custom `Authorization` header works. Point it at the URL above. Use a key with only the scopes the agent needs, or a number-bound key, so a mistake can reach only one number.

## Limits {#limits}

Request bodies over 256 KB give `413`. A batch of JSON-RPC messages gives `400`. A tool result over 100,000 bytes is truncated with a hint to page with `limit` or a cursor. Ids that contain `/`, `..` or other path characters are refused before any route is called. Calls count against the same [rate limits](https://docs.whabuzz.com/guides/rate-limits.md) as REST, and a request that carries an `Origin` header from another site is refused.
