CRM MCP Server

CRM MCP Server

A self-hosted Model Context Protocol server for GoHighLevel CRM, built for agencies. It enables connecting multiple sub-accounts, selecting tools per client, and issuing unique revocable MCP URLs.

Category
访问服务器

README

CRM MCP — self-hosted, multi-sub-account MCP server

Built & maintained by Abdulrehman Moaz · XylatorAI — custom CRM integrations & AI systems for agencies.

A self-hosted Model Context Protocol server for your CRM, built for agencies. Connect any number of CRM sub-accounts, choose which tools each client can use, and hand every client a unique, revocable MCP URL.

  • Multiple sub-accounts — one deployment serves all your sub-accounts.
  • Per-client URLs — generate a unique /mcp/<token> link scoped to a single sub-account (or your whole agency).
  • Pick the tools — each link exposes only the tools you select.
  • Self-hosted — runs anywhere Docker runs; no third-party backend.
  • Secure by design — tokens are encrypted at rest, link secrets are hashed, and the dashboard is protected by Supabase Auth + Row Level Security.
  • MIT licensed — use it, modify it, ship it, commercial use included.

What you get

This repo is a complete, two-service product you can deploy as-is:

1. The MCP server (/)

  • An MCP server speaking Streamable HTTP (works with Claude, ChatGPT, and any MCP client) plus a stdio mode for local desktop use.
  • 550+ CRM tools across 37 API groups, covering the full HighLevel v2 API surface (contacts, conversations, calendars, opportunities, invoices, payments, products, social planner, and much more — see Tools).
  • Multi-tenant routing: one server instance serves all your sub-accounts; each tool call is routed to the right sub-account's token automatically.
  • Per-link security: every request carries a URL token that resolves to a specific set of sub-accounts and an allowed tool list.

2. The agency dashboard (dashboard/)

A Next.js (App Router) web app where you:

  • Sign in with Supabase Auth (email + password).
  • Add each sub-account with its Private Integration Token (encrypted on save — the raw token never touches the database in plaintext).
  • Generate client MCP links — choose the scope (one sub-account or the whole agency), pick exactly which tools to expose, and copy the one-time URL.
  • Revoke any link instantly.

3. The data layer (supabase/)

  • A single SQL migration that creates the subaccounts and mcp_links tables with Row Level Security, so each agency can only ever see its own rows.

4. Deployment + tooling

  • docker-compose.yml — bring up both services with one command.
  • render.yaml — one-click Render Blueprint for both services.
  • scripts/generate-tools.mjs — regenerate the entire tool set from HighLevel's official OpenAPI specs whenever their API changes.

Architecture

┌──────────────────────────┐        ┌──────────────────────────┐
│  Dashboard (Next.js)      │        │   MCP Server (Express)    │
│  - Supabase Auth login    │        │   - /mcp/<link-token>     │
│  - add sub-account PITs    │        │   - resolves token→subacct│
│  - generate client URLs   │        │   - per-link tool filter  │
│  - pick tools per link    │        │   - builds session pool   │
└────────────┬─────────────┘        └────────────┬─────────────┘
   writes (RLS, anon key)                reads (service-role key)
             └───────────────┬───────────────────┘
                             ▼
                      ┌──────────────┐
                      │   Supabase    │
                      │  (Postgres)   │
                      └──────────────┘

Repository layout

.
├── src/                       MCP server (TypeScript + Express)
│   ├── http-server.ts         Streamable HTTP server (hosted mode)
│   ├── server.ts              stdio server (local/desktop mode)
│   ├── crm/                   our CRM HTTP client + per-session client pool
│   ├── db/                    Supabase access (link resolution, token load)
│   ├── crypto/                AES-256-GCM token encryption
│   └── tools/
│       ├── generated/         550+ auto-generated tools (one file per group)
│       ├── accounts.ts        list_accounts / search_accounts
│       ├── tool-filter.ts     per-link tool whitelist
│       └── index.ts           registry + dispatch
├── dashboard/                 agency dashboard (Next.js App Router)
├── supabase/migrations/       database schema + RLS policies
├── scripts/generate-tools.mjs OpenAPI → tools generator
├── docker-compose.yml         run both services locally
└── render.yaml                one-click Render Blueprint

Sub-accounts authenticate to the CRM using Private Integration Tokens (PIT), which are long-lived, so there is no OAuth refresh machinery to run.


Prerequisites

  • Docker + Docker Compose
  • A Supabase project (free tier is fine)
  • A CRM Private Integration Token for each sub-account you want to connect

Setup

1. Create the database schema

In the Supabase dashboard → SQL Editor, run the contents of supabase/migrations/0001_init.sql. (Or apply it with the Supabase CLI: supabase db push.)

This creates the subaccounts and mcp_links tables and their RLS policies.

2. Configure environment

cp .env.example .env

Fill in:

Variable Where to find it Used by
SUPABASE_URL / NEXT_PUBLIC_SUPABASE_URL Supabase → Project Settings → API both
NEXT_PUBLIC_SUPABASE_ANON_KEY same page (anon public key) dashboard
SUPABASE_SERVICE_ROLE_KEY same page (service role key) server only
ENCRYPTION_KEY openssl rand -hex 32 both (must match)
NEXT_PUBLIC_MCP_BASE_URL your server's public URL dashboard

ENCRYPTION_KEY must be identical for the dashboard and the server, or PITs encrypted by the dashboard won't decrypt on the server.

3. Run

docker compose up --build
  • Dashboard → http://localhost:3000
  • MCP server → http://localhost:8000

4. Create your agency account, then lock down sign-up

The dashboard uses Supabase Auth. Out of the box, Supabase allows open public sign-up, which means anyone who can reach your dashboard URL could create an account. They would only ever get their own empty workspace — Row Level Security walls every agency off from the others, so a stranger can never see your sub-accounts, tokens, or links — but for a single-agency deployment you almost certainly want to turn sign-up off entirely.

Recommended one-time setup:

  1. Create your own account. Either:
    • Supabase → Authentication → Users → Add user (tick Auto Confirm User so no email is needed), or
    • sign in on the dashboard with the credentials you created above.
  2. Disable public sign-up: Supabase → Authentication → Sign In / Providers → turn off "Allow new users to sign up."
  3. (Optional) Email confirmation is controlled by the "Confirm email" toggle on the same Email provider page. If you auto-confirmed your user in step 1 you can leave this off and skip email entirely. If you keep it on for production, configure custom SMTP under Authentication → Emails → SMTP Settings — Supabase's built-in email is rate-limited and meant only for testing.

The login page is sign-in only — there is no sign-up button. Accounts are provisioned by you (the agency owner) in Supabase. This keeps the deployment single-tenant in practice even though the underlying schema is multi-tenant.


Deploy to Render (both services, one Blueprint)

Render doesn't run docker-compose, but the included render.yaml Blueprint deploys both services together.

  1. Run supabase/migrations/0001_init.sql in your Supabase project (one time).
  2. Push this repo to GitHub.
  3. In Render: New + → Blueprint → select your repo. Render detects render.yaml and creates both services.
  4. When prompted, fill in the secrets (same ENCRYPTION_KEY on both):
    • ghl-mcp-server: SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, ENCRYPTION_KEY
    • ghl-mcp-dashboard: NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, ENCRYPTION_KEY, NEXT_PUBLIC_MCP_BASE_URL
  5. One follow-up step: the dashboard needs the server's public URL at build time, which isn't known until the server's first deploy. After the first deploy, copy the ghl-mcp-server URL into the dashboard's NEXT_PUBLIC_MCP_BASE_URL and redeploy the dashboard. (Only needed once.)

On a plain VPS with Docker, docker compose up -d does all of this in a single command with no follow-up step.


Usage

  1. Open the dashboard, sign up / sign in.
  2. Sub-accounts → add each CRM sub-account: a name, its Location ID, and its Private Integration Token. The token is encrypted before it's stored.
  3. MCP Links → create a link:
    • Scope: a single sub-account (for a client) or all your sub-accounts.
    • Tools: expose all, or pick a specific subset.
    • Copy the generated URL — the token is shown only once.
  4. Give the client the URL. They add it to Claude / ChatGPT / any MCP client: https://your-host/mcp/<token>.

Revoke a link any time from the dashboard — access stops immediately.


Security model

Concern Mechanism
No unwanted accounts Public sign-up disabled in Supabase; owner provisions users
Agencies can't see each other's data Supabase RLS isolates every row by owner_id
Only the agency can write tokens Supabase Auth + RLS (owner_id = auth.uid())
Client URLs can't be guessed 256-bit random secret in the URL
DB leak doesn't expose live URLs only sha256(secret) is stored
PITs unreadable from a DB dump AES-256-GCM encryption at rest
Clients isolated to their sub-account location scope + pool membership check
Instant revocation revoked flag checked on every connect
Service role key never in browser server-only; browser uses anon key + RLS

Local (stdio) usage

For a single sub-account locally (e.g. Claude Desktop), no Supabase required:

npm install
npm run build
CRM_PIT_TOKEN=pit-xxxx CRM_LOCATION_ID=your-location-id npm run start:stdio

Or point it at a dashboard link with MCP_LINK_TOKEN (+ the Supabase env vars).


Development

# MCP server
npm install
npm run dev

# Dashboard
cd dashboard
npm install
npm run dev

Tools

The server exposes the full HighLevel v2 API surface — 550+ tools across 37 groups, generated directly from HighLevel's official OpenAPI specifications. Account-discovery tools (list_accounts, search_accounts) are always available; every other tool takes a locationId so the caller picks which sub-account to act on.

Groups: Ad Manager, Affiliate Manager, AI Agent Studio, Associations, Blogs, Brand Boards, Business, Calendars, Campaigns, Chat Widget, Companies, Contacts, Conversation AI, Conversations, Courses, Custom Fields, Custom Menus, Email, Email ISV, Forms, Funnels, Invoices, Knowledge Base, Trigger Links, Sub-Accounts, Media, Objects, Opportunities, Payments, LC Phone, Products, Proposals, SaaS, Snapshots, Social Planner, Store, Surveys.

Because the full list is large, give each client link a tool whitelist in the dashboard so it only exposes what that client needs.

Regenerating the tools

The tools under src/tools/generated/ are generated, not hand-edited. To refresh them against the latest HighLevel API:

git clone --depth 1 https://github.com/GoHighLevel/api-v2-docs .ghl-api-docs
node scripts/generate-tools.mjs
npm run build

The generator reads the OpenAPI specs (public domain / CC0) and emits one tool per endpoint plus the dashboard's tool catalog.


Contributing & repository safety

This is an open, public repository — but public means readable, not writable.

  • Nobody can push to this repo except the owner and explicitly invited collaborators. Everyone else has read-only access.
  • Outside changes arrive as Pull Requests. A contributor forks the repo, commits to their fork, and opens a PR. Nothing changes here until the maintainer reviews and merges it.
  • main is protected. Direct pushes are disabled; all changes — including the maintainer's — go through a reviewed PR with a passing build.
  • Secrets never live in the repo. All credentials come from environment variables and are git-ignored (.env, keys, MCP configs). See .env.example for the full list of variables.

To propose a change: fork → branch → commit → open a PR describing what and why.


Author & Maintainer

Abdulrehman Moaz — Founder, XylatorAI

Built and maintained by Abdulrehman Moaz, founder of XylatorAI — a founder-led agency building custom CRM integrations and AI automation systems for agencies and SaaS builders. 50+ custom integrations shipped, 40+ agencies served, 99%+ production uptime.

We can build for you:

  • Marketplace apps (OAuth, multi-tenant, review-ready)
  • Custom conversation providers (SMS, WhatsApp, voice, iMessage)
  • Custom payment providers (branded checkout, invoices, subscriptions)
  • Workflow actions & triggers, third-party API integrations, and custom dashboards
  • Bespoke MCP / AI-agent integrations like this one

Links

Need a custom CRM marketplace app, conversation/payment provider, AI agent, or a bespoke MCP integration? Book a 30-minute strategy call.

License

MIT © 2026 Abdulrehman Moaz (XylatorAI). Free to use, modify, and distribute — commercial use included.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选
mcp-server-qdrant

mcp-server-qdrant

这个仓库展示了如何为向量搜索引擎 Qdrant 创建一个 MCP (Managed Control Plane) 服务器的示例。

官方
精选