Skip to main content
Glama

GoHighLevel MCP Starter

Talk to your GoHighLevel sub-account from Claude, in plain English.

A small, readable Model Context Protocol server for GoHighLevel API v2. Six tools, roughly 300 lines, MIT licensed. Built to be read in one sitting and forked into whatever you actually need.

You:    Who booked with us last week, and is Tuesday at 2 open?
Claude: [search_contacts] [list_calendars] [get_free_slots]
        Three new contacts. Tuesday 2:00 is not offered, the calendar runs
        at quarter past. 2:15 and 3:15 are open.

Why another GHL MCP server

Most of them are a thin wrapper around the API surface. This one is opinionated about the three things that actually bite you in production:

1. It never hides an error. GHL explains its failures in the response body, but almost every wrapper throws away the body and surfaces a bare 400. That single decision turns a ten second fix into an hour of guessing. This client always reads the body and puts the real message in the error.

2. Writes are opt-in. Every mutating tool is a dry run by default. It returns the exact payload it would send so you can look at it first. Add confirm: true to actually write. Letting a model create records in a live CRM on the first try is how you end up with 40 test contacts named "John Doe" in a client account.

3. It looks before it leaps. book_appointment pulls live availability and checks your requested time against it before writing, then tells you the real open slots if you missed. GHL would just return a bare 400.

Plus GOTCHAS.md, which is the list of GHL API quirks that cost real debugging time. That file may be more valuable than the code.

Related MCP server: ghl-mcp

Tools

Tool

What it does

search_contacts

Find contacts by name, email, or phone

get_contact

Fetch one contact by id

create_contact

Create a contact (dry run by default)

list_calendars

All calendars with ids and slot durations

get_free_slots

Real bookable times, epoch conversion handled

book_appointment

Verify the slot, then book (dry run by default)

Setup

1. Install

git clone https://github.com/rockurbusinesscs-ship-it/gohighlevel-mcp-starter.git
cd gohighlevel-mcp-starter
npm install

2. Get a Private Integration Token

In GoHighLevel, go to your sub-account (not the agency):

Settings > Private Integrations > Create new integration

Grant the scopes you need. For these six tools: contacts read/write, calendars read, calendars/events write. Copy the token, it is shown once.

Use a test sub-account while you are learning. See Safety below.

3. Configure

cp .env.example .env

Fill in GHL_TOKEN and GHL_LOCATION_ID. The server loads .env automatically, and env vars set by your MCP client take precedence, so either approach works.

4. Connect to Claude

Claude Code:

claude mcp add ghl -- node /absolute/path/to/gohighlevel-mcp-starter/src/index.js

Claude Desktop, in claude_desktop_config.json:

{
  "mcpServers": {
    "ghl": {
      "command": "node",
      "args": ["/absolute/path/to/gohighlevel-mcp-starter/src/index.js"],
      "env": {
        "GHL_TOKEN": "your_token",
        "GHL_LOCATION_ID": "your_location_id"
      }
    }
  }
}

Restart, then ask it to search your contacts.

Use cases

Pipeline triage without the UI. "Show me everyone tagged hot who has not been contacted in 14 days." Reading a CRM conversationally is faster than clicking through filters, and it is where most of the daily value is.

Booking without the back and forth. "Is Wednesday afternoon open, and book Sarah into the first slot." The slot verification means it fails loudly with real options instead of a mystery error.

Data hygiene. Point it at your contacts and ask what is malformed: missing emails, phone numbers that are not E.164, duplicates. It is very good at spotting the mess.

Onboarding automation. Chain contact creation and booking into a single request when a new client signs, with the dry run keeping you in the loop before anything writes.

Learning the API. Honestly, this is the big one. Fork it, add a seventh tool against an endpoint you care about, and you will understand GHL's API better in an afternoon than a week of reading docs.

Safety

  • Never commit .env. It is gitignored. Check before you push anyway.

  • Use a test sub-account first. A Private Integration Token can write to a real client's CRM. Learn on data you can afford to break.

  • Keep the dry run. If you remove the confirm gate, you have handed write access to a language model that occasionally misreads intent.

  • One token, one location. Do not reach for an agency token to avoid setting locationId.

Contributing

Found a gotcha not in GOTCHAS.md? That is the most valuable PR you can send. Bug reports and new tools welcome too.

License

MIT. Use it commercially, fork it, ship it in your product, no obligations.


Not affiliated with or endorsed by GoHighLevel / HighLevel Inc.

Available Tools

6 tools
book_appointmentA

Book an appointment. Verifies the requested time is a real free slot first, then writes. DRY RUN BY DEFAULT: pass confirm:true to actually book.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNo
confirmNoMust be exactly boolean true to actually book. Anything else is a dry run.
endTimeYesISO 8601 with offset
timezoneNoIANA tz used for the availability check, default America/New_York
contactIdYes
startTimeYesISO 8601 with offset, e.g. 2026-08-05T13:15:00-04:00
calendarIdYes

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description discloses critical behavioral traits: it verifies the slot first (read-before-write) and is dry-run by default, requiring confirm:true for the actual booking. This is excellent transparency for a mutating tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose, and every word adds value. It avoids fluff and is easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the most important behavioral context (dry-run, verification) but does not mention return values or error handling, and there is no output schema. It also does not relate to sibling tools, leaving the agent to infer the workflow. Still, it is fairly complete for a booking operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers 57% of parameters with descriptions. The description emphasizes the confirm parameter's dry-run behavior, but this is largely already in the schema. It does not explain the undocumented parameters (title, contactId, calendarId), so it adds limited value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool books an appointment, using a specific verb and resource. It also distinguishes from siblings like get_free_slots by noting it verifies the time is a real free slot before writing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides the key usage instruction to pass confirm:true to actually book, and explains the dry-run default. However, it does not explicitly mention when to use this tool versus alternatives like get_free_slots, nor does it state any exclusion criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_contactA

Create a contact. DRY RUN BY DEFAULT: returns the exact payload without sending. Pass confirm:true to actually write.

ParametersJSON Schema
NameRequiredDescriptionDefault
tagsNo
emailNo
phoneNoE.164 format, e.g. +15551234567
confirmNoMust be exactly boolean true to actually create. Anything else is a dry run.
lastNameNo
firstNameNo

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly reveals the critical dry-run-by-default mechanism and the need for confirm:true to actually write, which is valuable context. It does not describe post-confirmation effects or return format, preventing a higher score.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences, front-loaded with the core purpose followed by the key dry-run behavior. Every word earns its place with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations, no output schema, and 6 parameters, the description is incomplete. It omits what happens after confirmation, whether fields are validated, and any guidance on returning a created object. This is insufficient for a potentially mutating tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, and the description fails to compensate. It only references confirm:true and 'payload' without explaining tags, email, phone, or name fields, leaving most parameters semantically undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The phrase 'Create a contact' uses a specific verb and resource, clearly identifying the tool's action. It distinguishes from sibling tools which handle searches, slots, and appointments, making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for creating contacts and emphasizes the dry-run-then-confirm pattern. However, it does not explicitly contrast with sibling tools or state when not to use this tool, so guidance is only implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_contactA

Fetch one contact by its GoHighLevel contact id.

ParametersJSON Schema
NameRequiredDescriptionDefault
contactIdYes

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavioral traits. The description only says 'Fetch', which implies a read operation but gives no details about error handling, return format, authentication requirements, or behavior when the contact is not found. This is a significant gap for a tool with zero annotation support.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. Every word contributes to understanding the tool's purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple: one parameter, no output schema, no annotations. The description covers the core purpose and the parameter's type, but omits any detail about the return value or failure behavior. For such a simple tool, this might be acceptable, but it still leaves basic expectations (e.g., what happens if the contact doesn't exist) unstated, making it minimally complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has no description for contactId (0% coverage), so the description must compensate. The description explains that the ID is a 'GoHighLevel contact id', which adds meaning beyond just 'contactId'. However, it doesn't specify format or any other nuances, so it is minimally sufficient for a single parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Fetch') and resource ('one contact') and clearly identifies the lookup by 'GoHighLevel contact id'. This distinguishes it from sibling tools like search_contacts (which searches) and create_contact (which creates). Purpose is immediately clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states this tool is for fetching a single contact by its ID, implying it should be used when the ID is known. It does not explicitly mention alternatives (e.g., 'use search_contacts if you don't have the ID'), but the context of having a specific ID is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_free_slotsA

Get real bookable slots for a calendar in a date range. Handles the epoch-milliseconds requirement for you.

ParametersJSON Schema
NameRequiredDescriptionDefault
endDateYesISO 8601
timezoneNoIANA tz, default America/New_York
startDateYesISO 8601, e.g. 2026-08-05T00:00:00-04:00
calendarIdYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description must disclose behavior. It adds a useful detail: 'Handles the epoch-milliseconds requirement for you,' but it does not mention whether the operation is read-only, what side effects exist, error behavior, or return format. Some context is provided, but significant gaps remain.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose, and contains no redundant or extraneous information. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description must explain what the returned slots look like—especially since book_appointment likely needs a slot identifier. It does not describe the return structure, nor does it address how timezone affects slot availability. This makes it insufficient for an agent to fully chain with the sibling tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75% (three of four parameters have descriptions). The description adds value by revealing that date parameters are automatically converted from ISO 8601 to epoch milliseconds, which is not stated in the schema. It does not clarify calendarId or timezone semantics further, but the added detail improves parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool gets 'real bookable slots' for a specified calendar and date range, using a specific verb and resource. This distinguishes it from siblings like book_appointment and list_calendars.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for finding available slots before booking, but it does not explicitly say when to use this versus alternatives, nor does it mention any exclusions or prerequisites. The guidance is only implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_calendarsA

List all calendars in the connected location, with their ids and slot durations.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It reveals the output contents (ids and slot durations) and implies a read-only operation, but does not mention any limitations, authentication requirements, or side effects. Adequate for a simple listing, but lacks depth.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One concise sentence that is front-loaded with the action and resource. Every word contributes meaning without redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero parameters and no output schema, the description adequately supports invocation by stating what the tool returns. It could mention ordering or filtering, but for a simple 'list all' operation, the provided information is sufficient for an agent to select and call it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters, so the description need not explain parameter syntax. Baseline of 4 for tools with no parameters is appropriate; the description adds no parameter information but none is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the tool lists all calendars in the connected location, specifying the output includes ids and slot durations. The verb 'list' is specific and the resource is well-defined, distinguishing it from sibling tools like get_free_slots which focuses on availability slots.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use this tool versus alternatives. There is no mention of exclusions, complementary tools, or scenarios where another tool would be more appropriate. The usage context is only implied by the tool's name and description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_contactsA

Search contacts in the connected GoHighLevel location by name, email, or phone.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax results (default 20)
queryYesName, email, or phone to search for

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavioral traits. It only states the action without mentioning whether it is read-only, what it returns, pagination behavior, or any side effects. This leaves the agent without important context for a search operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, clear, and front-loaded sentence with no filler. Every word adds meaning, and it avoids restating information already present in the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple, but with no output schema and no mention of return format or pagination behavior, the description is only minimally complete. It provides enough to understand the search action but leaves gaps about what the agent will receive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds no new meaning beyond repeating the schema's parameter descriptions (query as name/email/phone, limit default). It does not clarify format or edge cases, so no extra credit is warranted.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Search') and resource ('contacts in the connected GoHighLevel location'), with searchable fields (name, email, phone). This clearly distinguishes it from siblings like get_contact (single contact retrieval) and create_contact (creation).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when searching for contacts by name, email, or phone, but provides no explicit guidance on when to use this tool versus alternatives such as get_contact. Sibling tools exist but are not referenced, and there are no exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updatesv1.0.0
    • First observedbook_appointment
    • First observedcreate_contact
    • First observedget_contact
    • First observedget_free_slots
    • First observedlist_calendars
    • First observedsearch_contacts

TDQS

A3.9/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a distinct resource and action: calendar slot retrieval, contact search/by-id/creation, calendar listing, and appointment booking. There is no ambiguity between tools; even related tools like list_calendars and get_free_slots serve clearly different purposes.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern: get_free_slots, search_contacts, get_contact, create_contact, list_calendars, book_appointment. This makes the toolset predictable and easy to navigate.

Tool Count5/5

With 6 tools, the server is well-scoped for a GoHighLevel starter integration, covering contact management and calendar/appointment workflows without unnecessary bloat. Each tool serves a clear purpose within this domain.

Completeness3/5

The toolset covers contact creation, retrieval, search, and appointment booking, but lacks contact update/delete operations and appointment cancellation/listing. These are notable gaps, especially for a CRM-related server, though the core workflow of finding/creating contacts and booking appointments is intact.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    A comprehensive MCP server that connects AI assistants to GoHighLevel CRM, enabling management of contacts, conversations, calendars, pipelines, payments, and more through 60+ tools.
    64
    39 npm
    1
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    MCP 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.
    50
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server for GoHighLevel with 82 live-tested tools, enabling CRM operations like contact management, appointments, invoices, and workflows via natural language.
    20 npm
    MIT