Skip to content
Get an API key

Get started

MCP server

Operate WhatsApp from an AI agent: Claude Code, Cursor or your own agent calls Nodium through the Model Context Protocol, with your API key.

Nodium serves its own MCP server at https://nodium.io/api/v1/mcp. An agent connected to it reads everything (numbers, conversations, contacts, templates, broadcasts, clients, the journal), sends messages one person at a time and keeps contacts up to date — as tools, without writing an HTTP client. It is the API, nothing more: each tool calls the matching route with your key, so roles, client isolation, quotas, rate limits and the request log apply exactly as they do to your code.

Not to be confused with Muse (MCP): there, Nodium serves *your* API to Meta's assistant, at /api/v1/apps/{id}/mcp, with OAuth for your end users. Here, *your* agent operates *Nodium*, with your account's key.

Connect an agent

Shell

# Claude Codeclaude mcp add --transport http nodium https://nodium.io/api/v1/mcp \ --header "Authorization: Bearer $NODIUM_KEY"# Acting for one of your clients by default (the tools can still name another)claude mcp add --transport http nodium-crm-4187 https://nodium.io/api/v1/mcp \ --header "Authorization: Bearer $NODIUM_KEY" --header "Nodium-Tenant: crm-4187"

JSON

// .cursor/mcp.json, or the "mcpServers" block of any MCP client{ "mcpServers": { "nodium": { "url": "https://nodium.io/api/v1/mcp", "headers": { "Authorization": "Bearer nod_…" } } }}
  • No mass or configuration writes. Broadcasts, templates, clients and connect links are not tools: an agent reads messages written by anyone, and an instruction slipped into one of them must never trigger a send to everyone or change your account. Those stay with the API, called by your code.
  • The key decides what the agent may do. Give an agent that answers customers an agent key (read and send) and a reporting agent a member key (read-only). Tools the key cannot use are not even listed.
  • A key pinned to one client (POST /keys with clientId) confines the agent to that client, whatever it asks.
  • Keep the key out of prompts and repositories: put it in the environment of the agent, as above.

The tools

  • Numbers: list_channels, get_channel, diagnose_channel.
  • Conversations and messages: list_conversations, get_conversation, list_messages, get_message, send_message, mark_read.
  • Contacts: list_contacts, get_contact, update_contact.
  • Templates and Flows: list_templates, get_template, list_flows.
  • Broadcasts: list_broadcasts, get_broadcast, preview_broadcast (who it would reach; sends nothing).
  • Clients: list_clients, get_client.
  • Everything else: search, read_journal, get_billing_summary.

Each tool takes the fields of its route — its schema and description are drawn from this reference — plus an optional tenant: the client to act on, by Nodium id or your externalId. Without it, the Nodium-Tenant header of the connection applies, then the key's default client. Reads are marked read-only for the agent; writes are not.

What the agent receives

  • A success returns the content of data, as JSON text. A refusal returns isError: true with the API's { "error": { "code", "message", … } }: the agent branches on code like your code does (window_closed → send a template; rate_limited → wait).
  • send_message needs your own idempotencyKey (8 to 200 characters): the agent reuses it when it retries, never for a new message.
  • A long answer is cut at 100,000 characters with a note: ask for fewer items (limit) or the next page (cursor).

Protocol

  • Streamable HTTP, revisions 2025-06-18 and 2025-03-26: initialize, ping, tools/list, tools/call. POST only — no server stream, and no session (Mcp-Session-Id is never issued): every call carries the key.
  • Without a valid key: 401 with a JSON-RPC error. A call from a web page (an Origin other than Nodium's) is refused: a key never lives in a browser.
  • 600 calls per minute per address on the endpoint, then the usual limits of each route (600 per minute per client, 6,000 per key).

Without an MCP client

Shell

curl -X POST https://nodium.io/api/v1/mcp \ -H "Authorization: Bearer $NODIUM_KEY" \ -H "Content-Type: application/json" \ -H "MCP-Protocol-Version: 2025-06-18" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "send_message", "arguments": { "channelId": "4c1d…", "to": "+33612345678", "type": "text", "text": "Your order has shipped.", "idempotencyKey": "order-4187-shipped", "tenant": "crm-4187" } } }'# → { "jsonrpc": "2.0", "id": 1,# "result": { "isError": false, "content": [{ "type": "text",# "text": "{\"conversationId\":\"…\",\"message\":{\"status\":\"sent\",…},\"duplicate\":false}" }] } }