Highlevel MCP

GHL MCP API — Critical Gaps Preventing Full AI Automation
I've been building AI-powered client systems on GoHighLevel for two years and I'm a strong advocate for the platform. I recently integrated Claude AI via your MCP server and the potential is genuinely game-changing — but the current MCP implementation has critical gaps that are preventing true AI-powered automation of GHL. Here's what's missing that would unlock full AI-driven system building: Pipeline creation and stage management via API Workflow/automation builder access — create triggers, actions, and full workflows Funnel and page builder write access Custom field and folder creation with full picklist support Tag creation and management Email template creation and sequence building Snapshot creation and deployment Sub-account creation and configuration Form and survey builder access Right now I can read CRM data via MCP but I have to manually build pipelines, automations, funnels, and templates by hand or resort to raw Terminal API scripts. The vision of an AI agent that can build an entire client system end-to-end — pipelines, workflows, funnels, automations, all of it — is completely achievable on your platform, but only if these write endpoints are exposed in the MCP. Your roadmap mentions expanding to 250+ tools. I'd strongly urge you to prioritize the workflow builder and pipeline creation endpoints first — those two alone would transform how agencies deliver client work on GHL. The agencies that figure this out first will have an insurmountable competitive advantage. GHL has the opportunity to be the platform that makes that possible. I'd love to connect and share more about what we're building at LeadVortex AI.
3
GHL MCP — Cannot update picklist options on contact-model custom fields
Issue: No available operation can update the picklistOptions array on a contact-model custom field with dataType: SINGLE_OPTIONS (or likely MULTIPLE_OPTIONS/RADIO/CHECKBOX). What was tried: custom-fields.update-custom-field (PUT /custom-fields/{id}) This is the only operation whose documented schema includes an options field for picklist values. Fails immediately with 400: "Fields with model contact is not supported on this route" whenever the target field's model is contact. locations.update-custom-field (PUT /locations/{locationId}/customFields/{id}) Does support contact-model fields. Its only options-array field is textBoxListOptions — intended for TEXTBOX_LIST type fields. Sending textBoxListOptions against a SINGLE_OPTIONS field returns 200 success, but the change is silently discarded — re-fetching the field via get-custom-fields confirms picklistOptions is unchanged. Sending picklistOptions directly (matching the GET response's field name) is rejected: 422: "property picklistOptions should not exist". Net effect: There's no working write path for editing picklist values on a contact custom field. The only workaround is manual editing in the GHL UI. Suggested fix direction: Either (a) allow custom-fields.update-custom-field to accept model: contact, or (b) make locations.update-custom-field accept picklistOptions (or apply textBoxListOptions to SINGLE_OPTIONS/MULTIPLE_OPTIONS types instead of only TEXTBOX_LIST), and ideally return a validation error rather than a false 200 when the options change isn't actually applied.
0
Add MCP read tools for configuration objects (workflows, calendars, forms, products, settings)
The MCP server exposes RECORDS well and CONFIGURATION poorly. Contacts, opportunities, conversations and transactions are all readable. The objects that define how a sub-account actually behaves mostly are not. There is no way to list a workflow, a form, a calendar, a product, a tag, or a user. That blocks anything needing to know how an account is set up rather than what is in it: auditing, documentation, migration, agency-side QA, or handing a sub-account to a new operator. Below is the full set of reads that are missing, grouped by area. Some may already exist in the public REST API; where they do, exposing them through MCP should be a wrapper change rather than new engineering. AUTOMATION AND MESSAGING Nothing in this area is reachable today. This is the largest gap. workflows_get-workflows — list: id, name, status, folder, created, updated workflows_get-workflow — full definition, see the note below triggers_get-triggers — legacy Triggers, the pre-Workflows system campaigns_get-campaigns — legacy Campaigns, with status emails_get-templates — template list; emails_fetch-template already exists but requires an id nothing returns sms_get-templates — template list with message body trigger-links_get-trigger-links — name, destination URL, id ai_get-agents — Conversation AI and Voice AI agents: instruction set, channels, escalation rules, status reputation_get-review-requests — review request automations: trigger, template, platform pushed to Note on workflows_get-workflow: please return action parameters, not just action types. A response listing only "SendEmail, AddTag, UpdateField" is not enough to understand a workflow. To be useful it needs, per action, the thing that action is configured to act on: the tag it adds or removes, the email or SMS template it sends, the custom field or custom value it writes and the value written, the pipeline and stage it moves an opportunity to, the webhook URL it calls, the other workflow it starts or stops, and the media asset it attaches. Branch conditions need their operands for the same reason. Which tag or field a branch tests on is how you learn what a workflow READS, as opposed to what it writes. With that included, "which workflows use this tag, field or template?" becomes answerable client-side. Without it, that stays unanswerable even with everything else on this list implemented. Legacy Triggers and Campaigns matter more than they may appear. Both are enabled by default on every sub-account we looked at, and either can hold live automation that is completely invisible from the Workflows list. FORMS, SURVEYS AND CALENDARS forms_get-forms — list: id, name, folder forms_get-form — field schema, field types, custom-field mapping, conditional logic, submission behavior surveys_get-surveys — as above, for surveys surveys_get-survey calendars_get-calendars — list: id, name, type, group, assigned users, status calendars_get-calendar — duration, buffers, availability rules, attached form, confirmation behavior, booking URL, notification settings calendars_get-calendar-groups — group id and name calendars_get-calendar-events already exists, but it requires a calendarId, userId or groupId, and nothing in the MCP surface returns any of those. It cannot be called without obtaining an id from outside MCP first. The event payload also never contains the calendar's name, so even working backwards from events does not identify which calendar you are looking at. COMMERCE products_get-products — name, type, price, billing interval, trial, connected processor, where sold from, status products_get-prices — price points per product coupons_get-coupons — code, discount, validity window, applicable products, status memberships_get-offerings — courses, memberships and communities: structure, modules, lesson titles, drip schedule memberships_get-access-rules — what grants access and what revokes it invoices_get-templates — invoice templates and tax collection settings affiliates_get-campaigns — Affiliate Manager: campaigns, commission structure, payout settings documents_get-documents — document and contract templates, signature settings payments_list-transactions exists, so a partial catalog can be reconstructed from what has sold. That cannot show a product configured but never sold, cannot show list price where a discount was applied, and cannot show a coupon at all. SUB-ACCOUNT SETTINGS locations_get-custom-values — custom values (global variables): name, value, id locations_get-tags — tag list WITH contact counts; today the only way to enumerate tags is sampling contact records, which cannot find a tag applied to zero contacts, exactly the tag worth finding locations_get-smart-lists — saved segments with their filter logic locations_get-custom-field-folders — folder id and name; locations_get-custom-fields returns parentId but nothing resolves it to a name locations_get-plan — plan tier and business hours, both absent from locations_get-location users_get-users — name, email, role, permissions, which locations each can reach, status reports_get-dashboards — custom dashboards and reports INTEGRATIONS integrations_get-connections — connected services per location: payment processor, email provider, phone provider, per-user calendar syncs, marketplace apps integrations_get-private-tokens — private integration tokens with scopes and creation date webhooks_get-webhooks — outbound webhook destinations and triggers phone_get-numbers — numbers attached, provider, A2P registration status phone_get-call-routing — IVR menu options, routing targets, business-hours and after-hours behavior, voicemail email_get-sending-config — sending domain, provider, authentication status The token inventory matters more than its position suggests. An unattributed live API token is a security finding, and there is currently no programmatic way for an account owner to enumerate their own tokens. PUBLIC SURFACES funnels_get-funnels — funnel and website list: name, type, serving domain, status funnels_get-pages — page list with URLs, and the forms and calendars embedded on each funnels_get-tracking-code — injected scripts, with site-level versus page-level scope portal_get-config — client portal: enabled, domain, what it exposes, authentication, how access is granted or revoked media_get-files — media library listing CUSTOM OBJECTS custom-objects_get-objects — the object itself: name, description, what it links to Today only a custom object's FIELDS are readable, via locations_get-custom-fields, with no way to learn what the object is or what it relates to. GAPS INSIDE EXISTING TOOLS These are missing data rather than missing tools. locations_get-custom-fields returns picklistOptions for contact and opportunity fields, but omits the property entirely for custom_objects.* fields, including single-select fields that clearly have options in the UI. Those option lists are unreachable. locations_get-location returns no plan tier and no business hours. emails_fetch-template requires an id, and no tool returns one. calendars_get-calendar-events requires an id, and no tool returns one. ADD A fields PARAMETER Every read returns the whole object; there is no projection. Reading TAG NAMES means pulling full contact records. Reading WHICH PAYMENT PROCESSOR IS CONNECTED means pulling full transaction records, which also return contact name, email address, IP address, card brand, last four digits and billing postal code. A fields= parameter on list endpoints, taking a comma-separated projection, would cut response sizes by an order of magnitude and stop configuration queries returning cardholder data as a side effect. That second point makes the MCP server considerably easier to adopt in any regulated context.
0
Load More