GHL MCP Server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@GHL MCP ServerCreate a contact for Jane Smith with email jane@example.com"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
GHL MCP Server
A production-grade Model Context Protocol (MCP) server that wraps the GoHighLevel (GHL) API v2, enabling Claude and other MCP clients to interact with GHL CRM as structured tools — creating contacts, sending messages, managing pipelines, booking appointments, and more.
Overview
This server exposes 113 tools as MCP tools — 111 GHL API tools across 17 modules, plus 2 AI agent tools that chain multiple GHL operations autonomously.
Module | Tools | Description |
Contacts | 14 | CRUD, search, tags, notes, tasks, upsert |
Conversations | 7 | List threads, send SMS/email, get messages, mark read, reports |
Opportunities | 9 | Pipeline management, stage moves, CRUD |
Calendars | 15 | Calendars, calendar groups, slots, book/update/cancel appointments |
Payments | 11 | Products, invoices, transactions, subscriptions |
Workflows | 3 | List, enroll/remove contacts from automations |
Forms & Surveys | 4 | List forms/surveys, get submissions |
Users | 5 | CRUD team members |
Locations | 16 | Sub-account management, custom values, custom fields, tags |
Media | 3 | Upload, list, delete media library files |
Links | 5 | Custom tracking link management |
Blogs | 5 | Blog post management |
Funnels | 5 | Funnel and funnel-page management |
Snapshots | 2 | View cloneable account snapshots |
Documents | 4 | List, send docs/templates |
SaaS | 3 | Plans, subscriptions, enable SaaS mode |
AI Agents | 2 | Multi-step sales automation with LLM reasoning and HITL approval |
Webhooks | inbound | Signature-validated event router |
Related MCP server: ghl-mcp
Prerequisites
Python 3.11+
A GoHighLevel account with API access
(For OAuth) A GHL Marketplace app with OAuth credentials
Installation
# 1. Clone the repository
git clone https://github.com/RohitashAery/ghl-mcp-server.git
cd ghl-mcp-server
# 2. Copy and configure environment
cp .env.example .env
# Edit .env with your credentials (see configuration section below)
# 3. Install dependencies
pip install -e .
# 4. Create data directory for OAuth token storage
mkdir -p data
# 5. Start the server
python main.pyThe server starts at http://localhost:8000. Visit http://localhost:8000/docs for the Swagger UI.
Configuration
All configuration is via environment variables (or .env file):
Variable | Default | Description |
|
| Auth mode: |
| — | Private integration token (private mode) |
| — | Default sub-account location ID |
| — | OAuth app client ID |
| — | OAuth app client secret |
|
| OAuth callback URL |
|
| Transport: |
|
| HTTP server bind host |
|
| HTTP server port |
| — | HMAC secret for webhook validation |
|
|
|
|
|
|
|
| SQLite path for OAuth tokens |
|
| Comma-separated module names to expose, or |
| (empty) | Comma-separated API keys required on |
|
| LLM backend for AI agents: |
| — | Anthropic API key (required if |
| — | OpenAI API key (required if |
|
| Model name passed to the LLM provider |
|
| SQLite path for LangGraph HITL checkpoint state |
|
| ChromaDB persistence directory for semantic vector search (Phase 2) |
SaaS Hosting (Multi-client)
This server supports running as a managed hosted service with multiple clients on shared infrastructure. Each client gets an isolated container with their own credentials and plan-gated tool set.
Plan gating
Set ALLOWED_MODULES to a comma-separated list of module names:
# Tier 1 — 48 tools
ALLOWED_MODULES=contacts,conversations,opportunities,pipelines,calendars,forms
# Tier 2 — 88 tools
ALLOWED_MODULES=contacts,conversations,opportunities,pipelines,calendars,payments,invoices,transactions,subscriptions,workflows,forms,surveys,users,media,links,blogs,funnels,documents
# Tier 3 — 113 tools (default: all GHL tools + AI agents)
ALLOWED_MODULES=allClaude only sees the tools in the allowed modules — blocked modules are invisible.
Claude seat enforcement
Set ALLOWED_API_KEYS to a comma-separated list of bearer tokens:
ALLOWED_API_KEYS=key-abc123,key-xyz789Clients include their key in Claude Desktop config:
{
"mcpServers": {
"ghl": {
"type": "sse",
"url": "https://client.yourdomain.com/mcp/sse",
"headers": { "Authorization": "Bearer key-abc123" }
}
}
}See docs/saas-deployment.md for the full per-tier setup guide and docs/aws-deployment.md for the AWS ECS infrastructure guide.
Private Token Setup
Log into GoHighLevel
Go to Settings → Integrations → Private Integrations
Click Create New Integration
Give it a name and select all required scopes
Copy the generated token
Set
GHL_PRIVATE_TOKEN=<token>in your.envSet
GHL_AUTH_MODE=private
OAuth Setup
Step 1: Create a GHL Marketplace App
Go to GHL Marketplace
Click + Create App
Set the Redirect URI to your server's callback URL (e.g.
https://your-server.com/oauth/callback)Under Scopes, select all scopes listed in
.env.exampleSave — copy your Client ID and Client Secret
Step 2: Configure your server
GHL_AUTH_MODE=oauth
GHL_CLIENT_ID=your_client_id
GHL_CLIENT_SECRET=your_client_secret
GHL_REDIRECT_URI=http://localhost:8000/oauth/callbackStep 3: Authorize
Start the server:
python main.pyOpen
http://localhost:8000/oauth/authorizein your browserSelect the GHL location to authorize
After approval, you're redirected to
/oauth/callbackToken is stored in SQLite — the server auto-refreshes before expiry
Claude Desktop Setup (stdio mode)
Set MCP_TRANSPORT=stdio in your .env, then add to your Claude Desktop config:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"ghl": {
"command": "python",
"args": ["/absolute/path/to/ghl-mcp-server/main.py"],
"env": {
"MCP_TRANSPORT": "stdio",
"GHL_AUTH_MODE": "private",
"GHL_PRIVATE_TOKEN": "your_token_here",
"GHL_LOCATION_ID": "your_location_id",
"LOG_FORMAT": "console"
}
}
}
}Restart Claude Desktop. The GHL tools will appear in the tools panel.
Claude.ai / N8N Setup (HTTP/SSE mode)
Set MCP_TRANSPORT=http and start the server. The SSE endpoint is:
http://your-server:8000/mcp/sseClaude.ai connector: Add the SSE URL in Claude's connector settings.
N8N: Use the MCP Client node with the SSE endpoint URL.
Swagger UI: http://your-server:8000/docs
All Tools Reference
Contacts
Tool | Description | Required Params |
| Create a new contact | — (at least one of: email, phone) |
| Get contact by ID |
|
| Search contacts | — |
| Update contact fields |
|
| Delete a contact |
|
| Add tags to contact |
|
| Remove tags from contact |
|
| Add a note |
|
| List contact notes |
|
| Create a task |
|
| List contact tasks |
|
| Create or update by email/phone |
|
Conversations
Tool | Description | Required Params |
| List conversation threads | — |
| Get a conversation |
|
| Send SMS to contact |
|
| Send email to contact |
|
| Get messages in thread |
|
| Mark conversation read |
|
Opportunities
Tool | Description | Required Params |
| List opportunities | — |
| Get opportunity |
|
| Create opportunity |
|
| Update opportunity |
|
| Move to stage |
|
| Delete opportunity |
|
| List all pipelines | — |
Calendars & Appointments
Tool | Description | Required Params |
| List calendars | — |
| Get available slots |
|
| List appointments | — |
| Book appointment |
|
| Update appointment |
|
| Cancel appointment |
|
Payments
Tool | Description | Required Params |
| List products | — |
| Create invoice |
|
| List invoices | — |
| List transactions | — |
| List subscriptions | — |
| Get subscription |
|
Workflows
Tool | Description | Required Params |
| List workflows | — |
| Enroll contact in workflow |
|
| Remove from workflow |
|
Forms
Tool | Description | Required Params |
| List forms | — |
| Get form submissions |
|
Users
Tool | Description | Required Params |
| List team members | — |
| Get user by ID |
|
| Create user |
|
| Update user |
|
| Delete user |
|
Locations
Tool | Description | Required Params |
| List sub-accounts |
|
| Get location |
|
| Create location |
|
| Update location |
|
Documents
Tool | Description | Required Params |
| List documents | — |
| Send document |
|
| List templates | — |
| Send template |
|
SaaS
Tool | Description | Required Params |
| List SaaS plans |
|
| Get subscription status | — |
| Enable SaaS for location |
|
AI Agents
Multi-step autonomous agents powered by LangGraph. Each agent fetches data from multiple GHL domains, uses an LLM to reason about the best action, and executes it. High-stakes write actions (send SMS/email, move pipeline stage, enroll workflow) pause for human approval before executing.
Tool | Description | Required Params |
| Run a full sales automation sequence for a contact: fetch contact + opportunities + conversations → LLM analysis → execute action (or pause for approval) |
|
| Approve or reject a high-stakes action proposed by a suspended agent run |
|
How the HITL (Human-in-the-Loop) flow works:
Call
ghl_agent_sales_automation(contact_id="abc123")— agent fetches data and reasons over itIf the LLM proposes a high-stakes action (send SMS, move pipeline, etc.), it returns:
{ "status": "awaiting_approval", "thread_id": "uuid", "proposed_action": {...}, "reasoning": "..." }Review the proposed action, then call
ghl_agent_approve_action(thread_id="uuid", approved=true)to execute it orapproved=falseto cancelFor low-stakes actions (add note, add tag), the agent executes immediately and returns
"status": "completed"
To resume a previously suspended run without re-running data fetching, pass thread_id to ghl_agent_sales_automation.
LLM setup: Set LLM_PROVIDER, ANTHROPIC_API_KEY (or OPENAI_API_KEY), and LLM_MODEL in your .env. The agent layer is model-agnostic — swap providers without changing any agent code.
Webhook Setup
In GHL: go to Settings → Webhooks → Add Webhook
Set the URL to
https://your-server.com/webhooks/ghlCopy the Signing Secret from GHL and set
GHL_WEBHOOK_SECRET=<secret>in.envSelect the event types you want to receive
Supported Events
Event Type | Triggered When |
| New contact created |
| Contact fields changed |
| Contact deleted |
| New opportunity created |
| Opportunity updated |
| Opportunity won/lost/etc. |
| Contact sent a message |
| Message sent to contact |
| Appointment booked |
| Appointment changed |
| Note added to contact |
| Task added to contact |
| Form submitted |
| Payment completed |
Custom Event Handlers
In mcp/webhooks.py, add your own logic:
from mcp.webhooks import webhook_handler
@webhook_handler("ContactCreate")
async def my_handler(event: dict) -> None:
contact_id = event.get("id")
# your custom logic hereDocker
# Build and start
docker-compose up -d
# View logs
docker-compose logs -f ghl-mcp-server
# Stop
docker-compose downThe data/ directory is mounted as a volume to persist OAuth tokens across restarts.
Running Tests
# Install dev dependencies
pip install -e ".[dev]"
# Run all tests with coverage
pytest
# Run specific module
pytest tests/test_contacts.py -v
# Run with HTML coverage report
pytest --cov-report=html
# Open htmlcov/index.html in browserHow to Add a New Tool
Add the API method in
api/<module>.py:async def my_new_action(self, location_id: str, param: str) -> dict[str, Any]: return await self._client.post("/endpoint", location_id=location_id, json={"param": param})Add the Pydantic model in
models/<module>.py(if new response shape):class MyNewModel(BaseModel): id: str field: strAdd the Tool definition in
mcp/tools/<module>.py— append to the_<module>_tools()list:Tool( name="ghl_module_my_new_action", description="Clear description of what this does and when to use it.", inputSchema={ "type": "object", "properties": { "locationId": {"type": "string"}, "param": {"type": "string", "description": "What this param does"}, }, "required": ["param"], }, ),Add the dispatch case in
_dispatch()in the same file:elif name == "ghl_module_my_new_action": result = await api.my_new_action(location_id, arguments["param"])Write a test in
tests/test_<module>.py:@pytest.mark.asyncio async def test_my_new_action(module_api, mock_ghl): mock_ghl.post("/endpoint").mock(return_value=httpx.Response(200, json={"ok": True})) result = await module_api.my_new_action("loc_id", "value") assert result["ok"] is TrueRegister the tool — it's already wired up via
mcp/server.pydispatch based on prefix.
Rate Limits
GHL enforces:
Burst limit: 100 requests per 10 seconds per location
Daily limit: ~200,000 requests per day
This server handles both automatically:
Token bucket per location: waits for refill if empty (never drops requests)
Daily warning: logs a warning at 80% of daily limit
Retry on 429: exponential backoff with jitter (up to 3 retries)
When the rate limit is hit, the tool call will wait (up to ~7 seconds across retries) rather than fail immediately.
Troubleshooting
Error | Cause | Fix |
|
| Regenerate token in GHL Settings |
| No locationId passed or | Set |
| Resource ID doesn't exist in this location | Verify the ID belongs to the correct location |
| Required GHL fields missing or wrong format | Check GHL API docs for required fields |
| GHL API is down | Server retries up to 3 times with backoff |
OAuth: | OAuth flow not completed | Visit |
OAuth: | Refresh token expired (>60 days unused) | Re-authorize via |
Webhook: |
| Copy exact secret from GHL webhook settings |
| MCP SDK not installed | Run |
Agent: | AI agent tools called without LLM config | Set |
Agent: |
| Restart with a new |
Agent: | Called | Pass a valid GHL |
Architecture
main.py ← Entrypoint; starts stdio or HTTP transport
config.py ← pydantic-settings; all env config
auth/
private_token.py ← Bearer token injection
oauth.py ← Auth code grant, token refresh, SQLite storage
api/
client.py ← httpx AsyncClient; retry, rate-limit, error mapping
contacts.py ← Raw GHL API calls (no business logic)
...
ghl_mcp/
server.py ← MCP Server; registers all 113 tools
tools/
contacts.py ← Tool definitions + dispatch for contacts
... (17 domain tool files, all untouched by agent layer)
agents/ ← LangGraph agent layer (NEW)
base.py ← GHLAgentContext, get_llm(), truncate_text()
sales_automation.py ← LangGraph StateGraph: 7 nodes + HITL interrupt
registry.py ← MCP tool definitions + agent dispatch router
checkpointer.py ← MemorySaver singleton for HITL state persistence
tools.py ← LangChain StructuredTool wrappers (for future ReAct agents)
webhooks.py ← FastAPI router; signature validation + event routing
models/ ← Pydantic v2 models for GHL response shapes
tests/ ← pytest with respx mock for every moduleRequest flow — GHL tool (HTTP mode):
Claude → SSE /mcp/sse → MCP Server → tool dispatch → API module → GHLClient → GHL API v2Request flow — AI agent tool:
Claude → SSE /mcp/sse → MCP Server → _agent_dispatch → LangGraph StateGraph
→ [fetch_contact] → [fetch_opportunities] → [fetch_conversations]
→ [analyze_and_plan (LLM)] → [request_approval (interrupt)] or [execute_action]
→ API module → GHLClient → GHL API v2Agent HITL (Human-in-the-Loop) checkpoint flow:
ghl_agent_sales_automation → interrupt() → MemorySaver saves state
→ returns "awaiting_approval"
ghl_agent_approve_action → Command(resume=approved) → graph resumes
→ execute_action → completedThis server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseBqualityDmaintenanceA comprehensive MCP server that connects AI assistants to GoHighLevel CRM, enabling management of contacts, conversations, calendars, pipelines, payments, and more through 60+ tools.6427MIT
- AlicenseBqualityDmaintenanceMCP server for GoHighLevel API v2 that provides 50+ tools for CRM, billing, marketing, and operations workflows, enabling natural language interaction with contacts, opportunities, conversations, and more.501MIT
- Alicense-qualityCmaintenanceAn MCP server for GoHighLevel with 82 live-tested tools, enabling CRM operations like contact management, appointments, invoices, and workflows via natural language.52MIT
- AlicenseBqualityDmaintenanceA Model Context Protocol (MCP) server that provides tools for managing GoHighLevel (GHL) conversations, tasks, and calendar appointments through AI assistants like Claude.2152MIT
Related MCP Connectors
LeadConnector / GoHighLevel MCP Pack — wraps the GoHighLevel CRM for AI agents.
Hosted Amazon Seller Central and Amazon Ads MCP server for Claude, ChatGPT, Cursor, and agents.
Hosted Amazon Seller and Vendor MCP server for Claude, ChatGPT, Cursor, Codex, Gemini, Copilot.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/RohitashAery/ghl-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server