mirror of
https://github.com/Luchexx/wacrm.git
synced 2026-11-02 17:29:45 +00:00
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>
115 lines
4.8 KiB
Markdown
115 lines
4.8 KiB
Markdown
# wacrm MCP server
|
|
|
|
A [Model Context Protocol](https://modelcontextprotocol.io) server for
|
|
**[wacrm](https://github.com/ArnasDon/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`](../docs/public-api.md)
|
|
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):
|
|
|
|
```jsonc
|
|
{
|
|
"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:
|
|
|
|
```jsonc
|
|
"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
|
|
|
|
```bash
|
|
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.
|