Ghl
FreeNot checkedMCP server for GoHighLevel CRM — agency-grade, single static binary, built on the official rmcp SDK
About
MCP server for GoHighLevel CRM — agency-grade, single static binary, built on the official rmcp SDK
README
The agency-grade GoHighLevel toolkit for Rust and AI agents.
One typed SDK. One static-binary MCP server. Every location in your agency — no Node runtime, no per-location reconnecting, no waiting on official coverage.
| Crate | What it is |
|---|---|
| ghl-sdk | Async, typed Rust client for the GoHighLevel API — OAuth 2.0 + Private Integration Tokens, automatic token refresh, rate-limit-aware retries, pagination as Streams, webhook signature verification |
| ghl-models | 2,417 generated DTOs for every API module, both API versions, feature-gated per module |
| ghl-mcp | MCP server exposing GoHighLevel to Claude, ChatGPT, Gemini, and any MCP host — built on the official rmcp SDK, ships as a single binary |
Complete API coverage. Generated from HighLevel's official OpenAPI specs:
| Count | |
|---|---|
| Typed Rust methods | 1,203 — one per endpoint, API v2 and v3 |
| Typed data models (DTOs) | 2,417 (v2 + v3) |
| API modules covered | 45 across both versions |
| MCP tools | 21 (16 typed + 3 meta-tools + 2 utility) |
You never have to leave the library. Every endpoint in both API versions is a real method with typed parameters and a typed response — invoices, payments, ad manager, social planner, voice AI, SaaS, custom objects, workflows, all of it. Five busy modules also get hand-written helpers (envelope unwrapping, paginated Streams) on the same services.
use ghl_sdk::services::invoices::ListInvoicesParams;
let params = ListInvoicesParams::new(&location_id, "location", "20", "0").status("draft");
let page = ghl.invoices().list_invoices(¶ms).await?; // API v2
let dup = ghl.v3().contacts().get_duplicate_contact(&p).await?; // API v3
Documentation
| Doc | What's in it |
|---|---|
| Usage guide | Auth decision tree, per-module cookbook, pagination, errors, rate limits, agency/multi-location, v2-vs-v3, troubleshooting |
| API reference | All 45 modules: every endpoint (params, body fields, scopes, Version), every struct, every enum value |
| docs.rs/ghl-sdk | Client API docs |
| docs.rs/ghl-models | All 2,417 DTOs, field by field |
| Design proposal | Research and architecture rationale |
| Release & distribution | Tagging, crates.io, Homebrew, npm, Docker, MCP registries |
| Changelog | What changed in every release, including the breaking ones |
Why this exists
GoHighLevel powers 60k+ agencies and ~2M businesses, but its developer stack has gaps:
- No official Rust SDK (official support: TypeScript, plus low-adoption Python/PHP).
- The official MCP server is locked to a single sub-account — no agency-wide access, ~36 tools, $297+/mo plans only.
- No developer support policy: HighLevel support explicitly does not help with API integration code.
ghl-rs fills those gaps:
| Official MCP server | Community Node servers | ghl-mcp | |
|---|---|---|---|
| API coverage | ~36 curated tools | varies, often stale | ✅ 1,203 typed Rust methods + all of them via meta-tools |
| API v3 support | ❌ | ❌ | ✅ v2 and v3 side by side |
| Typed data models | — | ❌ | ✅ 2,417 generated DTOs |
| Agency (multi-location) access | ❌ one location per connection | ⚠️ varies | ✅ agency token → per-location routing |
| Self-hostable | ❌ | ✅ | ✅ |
| Runtime | hosted | Node.js | single static binary |
| Typed end-to-end | — | ❌ | ✅ Rust types from official OpenAPI specs |
| Rate-limit awareness | opaque | mostly none | ✅ header-driven backoff, per-location budgets |
| Destructive-action gating | ❌ | mostly none | ✅ off by default, --allow-destructive to enable |
Quickstart — SDK
[dependencies]
ghl-sdk = { version = "0.5", features = ["contacts", "invoices"] }
tokio = { version = "1", features = ["full"] }
use ghl_sdk::{Ghl, contacts::CreateContact};
#[tokio::main]
async fn main() -> Result<(), ghl_sdk::Error> {
// Reads GHL_PIT_TOKEN (or GHL_ACCESS_TOKEN) from the environment…
let ghl = Ghl::from_env()?;
// …or configure explicitly:
// let ghl = Ghl::builder().private_integration_token("pit-…").build()?;
let contact = ghl
.contacts()
.create(CreateContact {
location_id: "LOCATION_ID".into(),
email: Some("[email protected]".into()),
first_name: Some("Ada".into()),
..Default::default()
})
.await?;
println!("created contact {}", contact.id);
Ok(())
}
Need an endpoint without a typed service? Use the generated DTOs plus request_raw:
ghl-sdk = { version = "0.5", features = ["models"] }
ghl-models = { version = "0.5", features = ["invoices"] }
use ghl_models::v2::invoices::CreateInvoiceDto;
let body = serde_json::to_value(CreateInvoiceDto {
alt_id: location_id.clone(),
alt_type: "location".into(),
name: "August retainer".into(),
currency: "USD".into(),
..Default::default()
})?;
let created = ghl.request_raw("POST", "/invoices/", &[], Some(&body), None).await?;
Receiving webhooks? Verify HighLevel's RSA signature before trusting a payload:
ghl-sdk = { version = "0.5", features = ["webhooks"] }
ghl_sdk::webhooks::verify(raw_body, signature_header)?; // raw bytes, not re-serialized
let event: ghl_sdk::webhooks::WebhookEvent = serde_json::from_slice(raw_body)?;
if event.is_stale(std::time::Duration::from_secs(300)) { return; } // replay guard
Pagination is a Stream — the SDK handles GoHighLevel's cursor scheme (startAfterId) for you:
use futures_util::TryStreamExt;
let mut contacts = ghl.contacts().list("LOCATION_ID").limit(100).stream();
while let Some(c) = contacts.try_next().await? {
println!("{} {:?}", c.id, c.email);
}
Quickstart — MCP server
cargo install ghl-mcp # or: npx ghl-mcp · brew install · docker run
Claude Desktop / Claude Code config:
{
"mcpServers": {
"gohighlevel": {
"command": "ghl-mcp",
"env": {
"GHL_PIT_TOKEN": "pit-…",
"GHL_LOCATION_ID": "your-location-id"
}
}
}
}
Then ask your agent things like "find every contact tagged hot-lead added this week and summarize them" — the server handles auth, retries, rate limits, and pagination.
To share one server between several agents, serve Streamable HTTP instead of stdio:
ghl-mcp --http 127.0.0.1:8000 --http-auth-token "$(openssl rand -hex 32)"
Callers then send Authorization: Bearer <token>. Omit the flag and the endpoint is unauthenticated (the server warns at startup) — only do that on localhost.
Install without Rust:
npx ghl-mcp
brew tap shahroz/ghl-rs https://github.com/Shahroz/ghl-rs
brew trust shahroz/ghl-rs # Homebrew requires this for any third-party tap
brew install ghl-mcp
docker run -p 8000:8000 -e GHL_PIT_TOKEN=pit-… ghcr.io/shahroz/ghl-mcp
Configuration
Everything is configurable by environment variable or explicitly as a parameter — env vars are the zero-code path, builder/CLI parameters always win when both are set.
| Env var | CLI flag (ghl-mcp) |
SDK builder | Purpose |
|---|---|---|---|
GHL_PIT_TOKEN |
--pit-token |
.private_integration_token(…) |
Private Integration Token (simplest auth) |
GHL_ACCESS_TOKEN |
--access-token |
.access_token(…) |
OAuth access token (bring your own flow) |
GHL_LOCATION_ID |
--location-id |
— | Default sub-account for MCP tools |
GHL_BASE_URL |
--base-url |
.base_url(…) |
API base (default https://services.leadconnectorhq.com) |
GHL_ALLOW_DESTRUCTIVE |
--allow-destructive |
— | Enable write/delete/send tools (off by default) |
GHL_HTTP_ADDR |
--http |
— | Serve Streamable HTTP instead of stdio |
GHL_HTTP_AUTH_TOKEN |
--http-auth-token |
— | Require a bearer token on the HTTP endpoint |
RUST_LOG |
— | — | Log filter (logs go to stderr, MCP-safe) |
Secrets are held in secrecy types — they never appear in Debug output or logs.
Status & roadmap
The MCP server reaches the entire API today; typed SDK services cover the busiest modules and keep growing. Design rationale lives in docs/PROPOSAL.md.
- Private Integration Token + OAuth token refresh +
/oauth/locationTokenexchange - Contacts (CRUD + cursor-paginated list as
Stream) - Opportunities (pipelines, search, CRUD, stage/status moves)
- Conversations (search threads, read messages, send SMS/email)
- Calendars (list, free slots, book/fetch appointments)
- Locations (get + search, with location-scoped fallback)
- MCP server: 21 tools over stdio, write/destructive gating
- Meta-tools reaching all 1,203 operations / 45 modules, v2 and v3
- 2,417 generated DTOs in
ghl-models, feature-gated per module - 1,203 generated typed service methods — every endpoint in API v2 and v3
- Webhook RSA signature verification + typed events (
webhooksfeature) - Streamable HTTP transport for the MCP server (
--http) -
npx ghl-mcpwrapper, Docker image, prebuilt release binaries - Homebrew formula, MCP registry manifests (
server.json,smithery.yaml) - Bearer-token auth on the HTTP endpoint
- Hosted gateway as a product: token vault, per-tenant rate pooling, audit trail, billing
License
MIT or Apache-2.0, at your option.
Not affiliated with HighLevel Inc. "GoHighLevel" and "HighLevel" are trademarks of their respective owners. This is an independent, unofficial open-source project.
Installing Ghl
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/Shahroz/ghl-rsFAQ
Is Ghl MCP free?
Yes, Ghl MCP is free — one-click install via Unyly at no cost.
Does Ghl need an API key?
No, Ghl runs without API keys or environment variables.
Is Ghl hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Ghl in Claude Desktop, Claude Code or Cursor?
Open Ghl on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectAmap Maps Mcp Server
MCP server for using the AMap Maps API
by duxiaohuiSupabase
Database, auth and storage
by SupabaseEverything
Reference / test server with prompts, resources, and tools.
Git
Tools to read, search, and manipulate Git repositories.
Sequential Thinking
Dynamic and reflective problem-solving through thought sequences.
Time
Time and timezone conversion capabilities.
Compare Ghl with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
