ghl-mcp-server-v2
A comprehensive MCP server covering the full GoHighLevel API surface with 651 tools, enabling management of contacts, opportunities, calendars, invoices, and more through natural language, with multi-tenant support and read-only safety defaults.
README
ghl-mcp-server-v2 — The Definitive GoHighLevel MCP Server
A from-the-ground-up MCP server covering the full public GoHighLevel API surface: 667 unique operations enumerated from the complete official OpenAPI spec corpus (84 spec files, legacy + v3 tiers). 651 tools registered; the other 16 are explicit, itemized exceptions (see api-coverage-checklist.md) — never silent omissions.
Built 2026-07-16 in a Cowork session (orchestrator + 8 parallel domain-audit sub-agents), following the mcp-builder skill's four-phase workflow. TypeScript, stdio transport, multi-tenant (locationId/companyId are call-time parameters — nothing tenant-specific is hardcoded).
Why this exists
The previous production connector (MCP_Servers/_to_delete/ghl-mcp-server-v1-retired) was a thin wrapper with silently incomplete coverage. Confirmed failures, all fixed here and locked in as regression checks (verified per-domain in docs/audits/):
| Old connector failure | This server |
|---|---|
update_opportunity dropped assignedTo, pipelineId, forecastExpectedCloseDate, forecastProbability, customFields |
ghl_opportunity_update exposes all 9 documented body fields |
update_contact dropped assignedTo, customFields, tags, dnd/dndSettings/inboundDndSettings, address fields, dateOfBirth, source, website, timezone |
ghl_contact_update exposes all 20 documented body fields |
create_task always returned 422 |
Root-caused: the API requires title, dueDate AND completed on create; the schema now enforces exactly that (and exposes assignedTo) |
list_opportunities could never page past record 100 (ignored startAfter/startAfterId/page) |
ghl_opportunity_search exposes all ~20 filter/cursor params; cursors pass through verbatim |
list_media 422'd (no way to pass required type) |
ghl_media_list_files requires type, altType, altId, sortBy, sortOrder per spec |
Single hardcoded Version header |
Version header resolved per operation from the spec that documents it (494 tools send v3, 117 send 2021-07-28, 10 send 2021-04-15, 30 send none — e.g. store ops) |
Social create_post regressed |
Schema verified faithful to spec; tool description carries a warning that the live endpoint had a server-side regression as of 2026-07-04 |
Architecture — how "no silently dropped field" is guaranteed
Tools are generated from the official OpenAPI specs, not hand-transcribed:
scripts/extract-operations.mjsparses every spec file, fully dereferences$refs, dedupes byMETHOD /path(v3 spec variant preferred; legacy-only operations keep their legacyVersionheader), and emitssrc/generated/operations.jsonwith request schemas verbatim.src/registry.tsbuilds one MCP tool per operation: path/query/header params become top-level arguments; the request body schema is carried verbatim under abodyargument. Missing path-param declarations in the spec are inferred from the URL template.src/overrides/*.ts— eight domain-audit modules (one per sub-agent) carrying curated tool names, Version-header corrections, content-type overrides (multipart, form-urlencoded), agency-token warnings, and the 16 skip-with-reason exceptions.
Because the schema pipeline is mechanical, a field can only be missing if it is missing from GoHighLevel's own published spec — and the three known cases of that are documented in the audits (POST /contacts/search, object-record create/update, POST /forms/upload-custom-files), each exposed with a permissive body rather than dropped.
Setup
npm install
npm run build # tsc + copies src/generated into build/
npm start # stdio server
npm run inspect # MCP Inspector smoke test
Client config (e.g. Claude Desktop / Cowork):
{
"mcpServers": {
"ghl-v2": {
"command": "node",
"args": ["<path>/ghl-mcp-server/build/index.js"],
"env": { "GHL_API_KEY": "...", "GHL_ENABLE_WRITES": "false" }
}
}
}
Environment variables
| Var | Default | Meaning |
|---|---|---|
GHL_API_KEY (fallback HD_GHL_API_KEY) |
— | Private-integration token / OAuth access token. Env-only, never hardcoded. |
GHL_ENABLE_WRITES (fallback HD_GHL_ENABLE_WRITES) |
unset = read-only | The dry-run safety gate. Unless set to true/1, every non-GET call is blocked with an explanatory error (arguments are still validated, so you can dry-run writes). Default-safe because this can point at a live healthcare-business CRM. |
GHL_ENABLED_DOMAINS |
all | Comma-separated spec basenames (e.g. contacts,opportunities,calendars) to expose a subset of the 651 tools — useful to keep client context small. |
GHL_BASE_URL |
https://services.leadconnectorhq.com |
Override for testing. |
GHL_TIMEOUT_MS |
30000 |
Request timeout. |
GHL_SPECS_DIR |
(PPC corpus path) | Only used by npm run extract to regenerate operations.json when GHL ships spec updates. |
Conventions
- Tool names:
ghl_<resource>_<action>(snake_case, ≤64 chars), curated per domain (e.g.ghl_contact_update,ghl_opportunity_search,ghl_calendar_appointment_create,ghl_invoice_schedule_cancel). - Annotations:
readOnlyHint(GET),destructiveHint(DELETE),idempotentHint(GET/PUT/DELETE),openWorldHintalways true. - Multi-tenant: pass
locationId/companyId/altIdper call. ~44 platform ops require an agency-level (Company) token — their descriptions say so. - Multipart uploads: pass file fields as
{ "filePath": "...", "filename?": "...", "mimeType?": "..." }insidebody; the server builds the multipart request. - Responses:
structuredContent = { status, ok, data }plus pretty-printed text; errors return real HTTP status + body + actionable hints.
Deliverables map
api-coverage-checklist.md— all 667 operations, per-row status, exceptions itemized. This is the proof of coverage.docs/audits/*.md— the 8 domain audit reports (regression verifications, renames, spec bugs found).docs/evaluation.xml— 10 verified evaluation Q&A pairs (mcp-builder Phase 4 format).docs/generated-names.json—"METHOD /path"→ tool-name map.
Not done here (operator steps)
- Live testing. This was a docs-driven build; no live GHL call was made. Smoke-test read-only against a real location, then enable writes deliberately.
- Registering the server in a live MCP config (kept separate from the existing
ghl-mcp-serverregistration — do not overwrite it without deciding to retire the old one). - Re-run
npm run extract && npm run buildwhen GHL ships API changes; the checklist regenerates from the same pipeline.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。