Connect your AI (MCP)

BottleCRM ships a Model Context Protocol (MCP) server, bcrm-mcp, that lets an AI assistant — Claude Desktop, Cursor, or any MCP-capable agent — work directly inside your CRM. Ask it to "show my open leads this week", "create a contact for Acme Corp", or "convert that lead to an opportunity", and it does the work through your CRM's API.

The agent acts as you: it authenticates with a personal access token and inherits exactly your role and your organization's data — never more. Every request is checked by the same permissions, validation, and tenant isolation that guard the web app.

Availability. The MCP server is part of the open-source community edition. There are two ways to connect: the hosted HTTP endpoint at https://api.bottlecrm.io/mcp (nothing to install — just a URL and your token; recommended), or the local stdio server you run yourself with uvx bcrm-mcp. Both authenticate with the same personal access token and expose the same tools.

How it works

The MCP server is a thin layer over the BottleCRM REST API. It holds no database of its own and stores no data — it forwards each tool call to the API and returns the result.

You, in your AI client          MCP server                   Your BottleCRM
──────────────────────          ──────────                   ──────────────
"Show my open leads"  ─▶  https://api.bottlecrm.io/mcp  ─▶  REST API (auth +
                          (or local `uvx bcrm-mcp`)          permissions + RLS +
"Here are 12 leads…"  ◀─  formats the response          ◀─   validation)

With the hosted endpoint, each request carries your token in its Authorization header, so the server acts strictly as you for that call — it never holds a shared identity. Because every action goes through the API, the AI cannot bypass any security rule. The backend is the only trust boundary.

Step 1 — Create a personal access token

  1. Open the BottleCRM app (https://app.bottlecrm.io, or your own app domain) and go to Settings → API Tokens.
  2. Click Create token, give it a recognizable name (e.g. "My Claude Desktop"), and optionally set an expiry.
  3. Copy the token (it starts with bcrm_pat_) immediately — it is shown only once and can never be retrieved again.

A token carries your identity. Anyone who has it can do what you can do in your org, so treat it like a password. You can revoke it from the same page at any time, and the next request from that token will fail.

Step 2 — Add the server to your AI client

Pick one of the two methods. The hosted endpoint needs nothing installed; the local server runs on your machine. The Settings → API Tokens page in the app shows both, pre-filled with your token.

Option A — Hosted endpoint (recommended, no install)

Point your client at the remote URL and send your token in the Authorization header. Nothing to install — no Python, no uv.

{
  "mcpServers": {
    "bottlecrm": {
      "type": "http",
      "url": "https://api.bottlecrm.io/mcp",
      "headers": {
        "Authorization": "Bearer bcrm_pat_…"
      }
    }
  }
}

Use your own API domain in place of https://api.bottlecrm.io if you self-host (the path is always /mcp). Most MCP clients that support remote servers use this url + headers shape; a few name the field serverUrl or omit "type" — check your client's docs if it doesn't connect.

Option B — Local server with uvx (stdio)

Run the server locally; the client launches it and passes your CRM URL and token as environment variables. Claude Desktop, Cursor, and Gemini CLI use the same mcpServers JSON — only the config file differs. Codex CLI uses TOML.

Client Config file
Claude Desktop claude_desktop_config.json (Settings → Developer → Edit Config)
Cursor ~/.cursor/mcp.json, or .cursor/mcp.json per project
Gemini CLI ~/.gemini/settings.json
Codex CLI ~/.codex/config.toml

For the JSON clients (Claude Desktop, Cursor, Gemini CLI):

{
  "mcpServers": {
    "bottlecrm": {
      "command": "uvx",
      "args": ["bcrm-mcp"],
      "env": {
        "BCRM_BASE_URL": "https://api.bottlecrm.io",
        "BCRM_TOKEN": "bcrm_pat_…"
      }
    }
  }
}

For Codex CLI (TOML):

[mcp_servers.bottlecrm]
command = "uvx"
args = ["bcrm-mcp"]

[mcp_servers.bottlecrm.env]
BCRM_BASE_URL = "https://api.bottlecrm.io"
BCRM_TOKEN = "bcrm_pat_…"
Variable Description
BCRM_BASE_URL The API host — https://api.bottlecrm.io for hosted BottleCRM, or your own API domain if self-hosting.
BCRM_TOKEN The bcrm_pat_… token you created in Step 1.

Step 3 — Restart and start asking

Restart your AI client so it picks up the new server. With the hosted endpoint it connects straight to the URL; with the local option it launches bcrm-mcp automatically. Either way it discovers the available tools — just talk to it in plain language and it chooses the right tool for each request.

What the AI can do

The server exposes a small set of generic tools that work across your main CRM records: leads, contacts, accounts, opportunities, tasks, cases, invoices, and solutions.

Tool Purpose
crm_search List and search records, with filters. Results are capped per call to stay efficient.
crm_get Fetch the full detail of one record.
crm_create Create a record (validated by the API).
crm_update Update fields on a record.
crm_delete Delete a record — requires explicit confirmation.
crm_action Run non-CRUD actions, e.g. convert a lead, add a comment, send an invoice. Outward-facing actions like sending an invoice require explicit confirmation.
crm_describe Discover an entity's fields and valid values from the live schema.
list_actions List the non-CRUD actions available per entity.

Security & safety

  • Acts as you, never more. The agent inherits your role and org. A sales rep's agent is limited to what the rep can do; it cannot see another team's or another company's data.
  • Tenant isolation is enforced server-side. PostgreSQL row-level security scopes every query to your organization.
  • Destructive and outward-facing actions need confirmation. The agent must explicitly confirm a delete — and outward-facing actions like sending an invoice (which emails a customer) — so nothing irreversible happens by accident.
  • Bounded reads. Searches are limited per call, preventing bulk data dumps.
  • Revocable and expirable. Cut off an agent instantly by revoking its token, or set an expiry up front.
  • Tokens stay secret. Only a hash is stored — the raw token is shown once and never logged. Keep BCRM_TOKEN out of source control and shared configs.

Troubleshooting

  • The agent says it isn't authorized / sees no data. On the hosted endpoint, check the Authorization header reads Bearer bcrm_pat_… and the URL ends in /mcp. On the local option, check that BCRM_TOKEN is current (not revoked or expired) and that BCRM_BASE_URL points at the CRM host with no trailing /api. In both cases a missing or malformed token is rejected before any data is touched.
  • The token was lost. Tokens can't be recovered — create a new one and revoke the old.
  • A tool can't find a field. Ask the agent to describe the entity first; crm_describe reads the live field list and valid values.