Introduce mcp-server/ — a stdio Model Context Protocol server that wraps the /api/v1 public API so MCP clients (Claude, Cursor, etc.) can drive a self-hosted wacrm instance in natural language. - Thin wrapper over the existing REST API; all auth, scoping, and rate limiting stay server-side. No new backend surface. - Read-only by default: write and broadcast tools are only registered when WACRM_ENABLE_WRITES / WACRM_ENABLE_BROADCASTS are set, layered on top of the API key's own scopes. send_broadcast also requires an explicit confirm and is marked destructive. - Registry-ready: server.json manifest, package.json mcpName linked to it (io.github.arnasdon/wacrm-mcp), and glama.json for discovery. - Docs: docs/mcp.md + README bullet + mcp-server/README.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| src | ||
| .env.example | ||
| .gitignore | ||
| glama.json | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| server.json | ||
| tsconfig.json | ||
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
- A running wacrm instance (your own self-hosted deploy).
- 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:
- 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. - 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
forbiddenerror. Issue a read-only key for a read-only assistant. - Explicit broadcast confirmation.
send_broadcastrefuses to run unless called withconfirm: true, and is markeddestructiveso 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.