Skip to content

Latest commit

 

History

History

README.md

wacrm MCP server

A Model Context Protocol server for wacrm — the self-hostable WhatsApp CRM. It lets MCP clients (Claude Desktop, Claude Code, Cursor, and others) drive your CRM in natural language:

"How many conversations are still open?" "Find the contact for +1 415 555 0123 and show the last few messages." "Draft and send an order-update template to Jane."

It's a thin wrapper over wacrm's public /api/v1 REST API. All auth, scoping, and rate limiting are enforced by your wacrm instance — this server just exposes the API as MCP tools.

Prerequisites

  1. A running wacrm instance (your own self-hosted deploy).
  2. An API key: in the dashboard go to Settings → API keys → New API key and grant only the scopes you need. The key is shown once.

Install & configure

The server reads two required environment variables and two optional write guards:

Variable Required Purpose
WACRM_BASE_URL yes Your instance URL, e.g. https://crm.example.com
WACRM_API_KEY yes An API key from the dashboard
WACRM_ENABLE_WRITES no true to expose contact writes + message sending
WACRM_ENABLE_BROADCASTS no true to expose mass broadcasts (needs WACRM_ENABLE_WRITES)

Claude Desktop / Claude Code / Cursor

Add to your MCP client config (e.g. claude_desktop_config.json, or .mcp.json for Claude Code):

{
  "mcpServers": {
    "wacrm": {
      "command": "npx",
      "args": ["-y", "wacrm-mcp"],
      "env": {
        "WACRM_BASE_URL": "https://crm.example.com",
        "WACRM_API_KEY": "wacrm_live_xxxxxxxxxxxxxxxxxxxxxxxx"
      }
    }
  }
}

That configuration is read-only — the safe default. To let the assistant change data or send messages, add the write guards:

"env": {
  "WACRM_BASE_URL": "https://crm.example.com",
  "WACRM_API_KEY": "wacrm_live_xxxxxxxxxxxxxxxxxxxxxxxx",
  "WACRM_ENABLE_WRITES": "true",
  "WACRM_ENABLE_BROADCASTS": "true"
}

Tools

Read tools are always available. Write and broadcast tools appear only when their guard is set.

Tool Group Scope needed What it does
whoami read (any valid key) Show the account + scopes the key carries
list_contacts read contacts:read List/search contacts (paginated)
get_contact read contacts:read Read one contact
list_conversations read conversations:read List conversations, filter by status/contact
get_conversation read conversations:read Read one conversation
list_messages read messages:read List a conversation's messages
get_broadcast read broadcasts:send Poll a broadcast's delivery status
send_message write messages:send Send a WhatsApp message (text/template/media)
create_contact write contacts:write Create (find-or-create) a contact
update_contact write contacts:write Update a contact / replace its tags
send_broadcast broadcast broadcasts:send Launch a template broadcast (requires confirm)

Safety model

Sending WhatsApp messages through an LLM is a real-world side effect, so the server layers three guards:

  1. Read-only by default. Write and broadcast tools are not even registered — the model can't see them — unless you opt in via WACRM_ENABLE_WRITES / WACRM_ENABLE_BROADCASTS.
  2. API-key scopes. Whatever the guards allow, your wacrm instance still enforces the key's scopes. A call without the right scope returns a clean forbidden error. Issue a read-only key for a read-only assistant.
  3. Explicit broadcast confirmation. send_broadcast refuses to run unless called with confirm: true, and is marked destructive so compliant clients prompt the user first.

Development

npm install
npm run build      # compile to dist/
npm run typecheck
npm start          # run the compiled server (needs the env vars)

Logs go to stderr — stdout is reserved for the MCP protocol.

License

MIT — same as wacrm.