Skip to main content
Glama
hiperbold

datacrazy-mcp

by hiperbold
README.md
# datacrazy-mcp

A local, **multi-tenant** [MCP](https://modelcontextprotocol.io) server for the **DataCrazy CRM**.

It exposes the DataCrazy REST API to AI assistants (Claude Code, Claude Desktop, or any MCP
client) as **63 auto-generated tools** — so you can just *ask* about your leads, conversations,
pipelines, response times, and deals in natural language, and the assistant reads the data
directly from your CRM.

It talks **straight to the DataCrazy REST API** (`api.g1.datacrazy.io`) — no middleware, no
third-party proxy. Tools are generated at startup from `openapi.json`, so the server stays in
sync with the API surface.

> **Not affiliated with DataCrazy.** Community project. You bring your own API key.

---

## Features

- **63 tools** covering leads, conversations, businesses (deals), pipelines & stages, tags,
  products, lists, attendants, activities, and more — generated from the OpenAPI spec.
- **Multi-tenant:** one server serves many clients/accounts. Drop a `.env.<client>` file and
  it's picked up automatically — no config change. Every tool takes a required `client` argument.
- **Zero secrets in the repo.** Keys live only in local `.env.<client>` files, which are
  git-ignored. You share keys out-of-band, never through the repo.
- **Cross-platform:** pure Node.js (macOS, Linux, Windows). No native deps.
- **Handles the API's quirks for you** (bracket-notation query params, pagination, etc.).

---

## Requirements

- **[Node.js](https://nodejs.org) 18 or newer** (20 LTS recommended). Check with `node -v`.
- **git** (to clone the repo).
- A **DataCrazy API key** for each account you want to query (see
  [Get your API key](#get-your-api-key)).
- An MCP client — e.g. **[Claude Code](https://claude.com/claude-code)** or **Claude Desktop**.

---

## Quick start

> **Receiving this repo from someone (e.g. your agency)?** The fastest path: clone it, then open
> **Claude Code** inside the folder and say *"install this MCP server following the README"*.
> Claude will run the steps below for you. You only need to paste your API key when asked.

Manual steps:

```bash
# 1. Clone
git clone https://github.com/hiperbold/datacrazy-mcp.git
cd datacrazy-mcp

# 2. Install dependencies
npm install

# 3. Create your client env file from the template and paste your key
cp .env.example .env.acme          # macOS/Linux  (Windows: copy .env.example .env.acme)
#   → open .env.acme and set  API_KEY=dc_...   (the key you were given)

# 4. Verify it can reach your CRM
node smoke-test.js acme            # expect: status 200 ✅ OK
```

Then [register it in your MCP client](#register-in-claude-code) and restart.

---

## Get your API key

In DataCrazy: **Configurações → API / Integrações → gerar chave.** The key starts with `dc_`.

⚠️ **This key grants full access to that account's CRM.** Treat it like a password. Store it only
in your local `.env.<client>` file. Never paste it into the repo, a chat, a screenshot, or a
commit. If a key leaks, revoke it in DataCrazy and generate a new one.

---

## Configure a client

Each account = one file named `.env.<client>` (lowercase, no spaces). The suffix becomes the
`client` value you pass to the tools.

```
# .env.acme
API_KEY=dc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

Add as many as you like (`.env.acme`, `.env.contoso`, …). The server discovers them all at
startup. All `.env.*` files are git-ignored except `.env.example`.

---

## Register in Claude Code

**Option A — CLI (recommended).** From the repo folder:

```bash
# macOS / Linux
claude mcp add datacrazy -s user -- node "$(pwd)/src/index.js"

# Windows (PowerShell)
claude mcp add datacrazy -s user -- node "$PWD\src\index.js"
```

`-s user` makes it available in every project. Restart Claude Code afterward.

**Option B — edit the config file manually.** Add this under `mcpServers` (use an **absolute**
path to `src/index.js`):

```json
{
  "mcpServers": {
    "datacrazy": {
      "command": "node",
      "args": ["/absolute/path/to/datacrazy-mcp/src/index.js"]
    }
  }
}
```

Config locations:
- **Claude Code:** `~/.claude.json` (user scope), or a project-level `.mcp.json`.
- **Claude Desktop:** `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) ·
  `%APPDATA%\Claude\claude_desktop_config.json` (Windows).

Verify end-to-end (optional):

```bash
node test-mcp.js acme
```

---

## Use it

Every tool takes a **required `client`** argument naming which account to query — so you can never
hit the wrong CRM by accident. In Claude you just mention the client and it fills it in:

- *"How many leads did **acme** get in the last 7 days?"*
- *"List **acme** leads that haven't been answered yet."*
- *"What's the response time on **acme**'s conversations this week?"*
- *"Show **acme**'s pipelines and how many deals are in each stage."*

Under the hood Claude calls tools like `leads_list({ client: "acme", ... })`,
`conversations_list({ client: "acme" })`, `pipelines_stages_list({ client: "acme", id })`.

**Pin a single client (optional).** To lock a server to one account (the `client` argument
disappears), register it with `--client`:

```bash
claude mcp add datacrazy-acme -s user -- node "$(pwd)/src/index.js" --client acme
```

---

## Tool naming

Names are derived from HTTP method + path:

| Tool | REST |
|---|---|
| `leads_list` | `GET /api/v1/leads` |
| `leads_get` | `GET /api/v1/leads/{id}` |
| `leads_create` / `leads_update` | `POST` / `PATCH /api/v1/leads` |
| `conversations_list` / `conversations_messages_list` | `GET /api/v1/conversations…` |
| `conversations_send_message` | `POST /api/v1/conversations/{id}/messages` |
| `businesses_move` / `businesses_win` / `businesses_lose` | `POST /api/v1/businesses/actions/*` |
| `pipelines_stages_list` | `GET /api/v1/pipelines/{id}/stages` |

Run `node smoke-test.js <client>` to print connectivity, or `node test-mcp.js <client>` to list
all generated tools over the MCP protocol.

---

## Example scripts

The `examples/` folder shows how to use the same REST layer directly (handy for reports/cron):

```bash
node examples/leads-response-status.js acme 15    # leads + response status, last 15 days
```

---

## Security

- **Keys never touch the repo.** `.gitignore` excludes every `.env.*` except `.env.example`.
- **Share keys out-of-band** (a password manager, a vault, an encrypted message) — not via git,
  email, or chat history.
- **Least privilege:** give each person only the key(s) for the account(s) they should see.
- A DataCrazy key = full CRM access for that account. Revoke + rotate in DataCrazy if exposed.
- **Write tools exist** (`*_create`, `*_update`, `businesses_move/win/lose`,
  `conversations_send_message`). If you want read-only usage, simply don't invoke those — or run
  a pinned server and instruct the assistant accordingly.

---

## Troubleshooting

- **`401 Unauthorized` in the MCP tools but `smoke-test.js` works.** The MCP server process reads
  the key **once at startup**. If you renewed the key, **restart your MCP client** so it reloads.
- **`401` everywhere (including smoke-test).** The key is wrong, expired, or revoked. Generate a
  new one in DataCrazy → Configurações → API/Integrações and update `.env.<client>`.
- **Rate limiting on large sweeps.** The messages endpoint (`/conversations/{id}/messages`) will
  throttle if you fetch hundreds quickly. Add a small delay (~250–400 ms) and retry with backoff;
  cache per conversation and re-run to fill gaps.
- **Tool says `client` is required.** In multi-tenant mode every call must name the `client`.
  Either pass it or register a pinned server with `--client <name>`.

---

## API quirks (for contributors)

- **Object/array query params use bracket notation**, not JSON — e.g.
  `filter[createdAtGreaterOrEqual]=…`. Sending a JSON string returns
  `400 "nested property filter must be either object or array"`. Handled in `src/qs.js`.
- **`/leads` returns `{ data: [...] }` with no total** → paginate with `skip`/`take` until a page
  has fewer than `take` rows. (`/conversations` and `/businesses` do include a `count`.)
- **Date filters** live inside `filter` (ISO 8601). Business filters also support
  `startDate/endDate`, `lastMovedAfter/Before`, `status` (`won`/`in_process`/`lost`).

---

## Project structure

```
datacrazy-mcp/
├── src/
│   ├── index.js        # MCP stdio server (multi-tenant; injects the `client` arg)
│   ├── env.js          # discovers & loads .env.<client> files
│   ├── generator.js    # openapi.json -> tool definitions + call metadata
│   └── qs.js           # bracket-notation query serializer
├── examples/
│   └── leads-response-status.js
├── openapi.json        # DataCrazy REST spec (source of truth for the tools)
├── smoke-test.js       # tool generation + live connectivity check
├── test-mcp.js         # end-to-end MCP protocol test
├── .env.example        # credentials template (copy to .env.<client>)
├── .gitignore          # ignores node_modules and all real .env.* files
├── package.json
└── LICENSE
```

## How to add support for a new API version

Replace `openapi.json` with the newer DataCrazy spec and restart — tools regenerate automatically.

## License

[MIT](./LICENSE) © Hiperbold. Not affiliated with or endorsed by DataCrazy.