Marketplace Developer MCP Server
The HighLevel Marketplace CLI includes a local MCP server, HighLevelMarketplaceDev, that connects AI coding assistants to your Marketplace developer account. Once it is set up, you can ask your assistant to answer HighLevel API questions from the official docs, create or pull an app, edit its configuration, add and test workflow actions and triggers, upload media, manage client keys, and release new versions.
The server runs on your machine through the ghl command and uses the same login and developer account as the CLI.
Requirements
- Node.js 20.12 or later
- HighLevel Marketplace CLI 1.1.0 or later
- A HighLevel developer account
- One of the supported AI clients: Claude Code, Codex CLI, Cursor, Gemini CLI, VS Code, or Windsurf
Check your CLI version and update it if needed:
ghl --version
ghl update
New to the CLI? Install it first with npm install -g @gohighlevel/marketplace-cli. See Install the CLI.
Set up the server
-
Log in to your developer account (you can also do this later from your AI client):
ghl login -
Register the server with your AI clients:
ghl mcp setupThe command lists the supported clients and marks the ones it cannot find on your machine as not detected. Nothing is selected to start with: use the arrow keys and Space to tick each client you want, then press Enter. Only the clients you tick are configured.
-
Restart any AI client that was already open so it loads the server.
-
Confirm that the server is connected:
Client How to check Claude Code Run /mcpand look forHighLevelMarketplaceDev, or runclaude mcp get HighLevelMarketplaceDevin a terminal.Codex CLI Run codex mcp list.Cursor Open Settings > Tools & MCP. Gemini CLI Run /mcp.VS Code Run MCP: List Servers from the Command Palette. Windsurf Open the MCP servers list in Windsurf settings.
To configure specific clients without the interactive prompt (for example, in a setup script), pass --client once per client:
ghl mcp setup --client claude --client cursor
Setup options
| Flag | Description |
|---|---|
--client <id> | Client to configure: claude, codex, cursor, gemini, vscode, or windsurf. Repeat it for several clients. Required when running non-interactively. |
--standalone, --no-standalone | Launch the server through npx instead of your installed CLI. On by default only when the CLI itself is running through a package runner such as npx. |
--cli-version <version> | Standalone mode only. The CLI version npx runs: an exact version such as 1.1.0, or latest. Defaults to the version running setup. |
--registry <url> | Standalone mode only. The npm registry npx installs from. Defaults to https://registry.npmjs.org/; set it to use a private mirror. |
--json | Print the result as JSON. |
Each client is configured independently, so one failure does not stop the others. Running ghl mcp setup again replaces the existing HighLevelMarketplaceDev entry. Other servers and settings in the client's configuration are kept.
Where each client is configured
| Client | Registered with |
|---|---|
| Claude Code | claude mcp add --scope user (available in every project) |
| Codex CLI | codex mcp add |
| Cursor | ~/.cursor/mcp.json |
| Gemini CLI | ~/.gemini/settings.json |
| VS Code | Your user mcp.json: ~/Library/Application Support/Code/User/mcp.json on macOS, ~/.config/Code/User/mcp.json on Linux, %APPDATA%\Code\User\mcp.json on Windows |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
Installed and standalone modes
By default, setup registers absolute paths to your Node.js binary and your installed CLI. Editors opened from the Dock or a launcher do not load your shell's PATH, so this keeps the server working with Node managers such as nvm, volta, or asdf. If you switch Node.js versions or reinstall the CLI in a different location, run ghl mcp setup again.
In standalone mode, clients start the server with npx, pinned to a CLI version and registry:
npx -y --registry=https://registry.npmjs.org/ --package @gohighlevel/[email protected] ghl mcp start
Use standalone mode on machines where global npm installs are not allowed, or to pin every client to one CLI version:
ghl mcp setup --client codex --standalone --cli-version 1.1.0
Clients run ghl mcp start to launch the server over stdio. You do not need to run it yourself.
How the server keeps you in control
- Your CLI session and account. Tools act as the developer logged in with
ghl login, in the account selected withghl account switch. The app selected withghl app useis the default app for app tools. - Clear read and write tools. Every tool tells your client whether it only reads or makes changes, so clients that ask before running a tool can ask before changes.
- Pushes run only the plan you reviewed.
check-workspacereturns a plan ID for the exact changes it found.push-workspaceruns only that plan and stops if the files or the portal changed since. When your client supports it, the server also asks you directly, showing every changed field with its old and new value. - Secrets stay out of the conversation. New client secrets and sandbox passwords are saved in the CLI's local secrets store and never appear in tool output. Header secrets are hidden in workflow action test output, and sending a stored secret to a new destination needs your direct approval.
- Releases only when you ask. The server instructs the AI to publish, withdraw, or deprecate only on your explicit request.
- Docs are reference material. Documentation text is never treated as instructions, so a page cannot make the AI run commands or change files.
Tools at a glance
| # | Tool | What it does | Changes |
|---|---|---|---|
| 1 | login | Logs in to the developer portal through your browser. | Local session |
| 2 | get-account | Shows who is logged in, the available accounts, and the apps in the active account. | Read-only |
| 3 | switch-account | Makes another developer account active. | Local session |
| 4 | search-docs | Searches the developer docs, API reference, and CLI workspace guides. | Read-only |
| 5 | fetch-doc | Reads up to 5 doc pages or API endpoint references in one call. | Read-only |
| 6 | create-app | Creates a new app and its local workspace. | Portal and local files |
| 7 | pull-app | Writes an app version into a local workspace, or refreshes one. | Local files |
| 8 | get-app | Shows an app version, its settings, and its publish readiness. | Read-only |
| 9 | list-scopes | Lists OAuth scopes, their token types, and the webhook events they unlock. | Read-only |
| 10 | scaffold-workflow-module | Adds draft workflow actions or triggers to a workspace. | Local files |
| 11 | check-workspace | Validates a workspace, compares it with the portal, and returns a push plan. | Read-only |
| 12 | test-workflow-action | Runs a workflow action through the portal's test runner. | Calls your action's endpoints |
| 13 | push-workspace | Pushes the reviewed plan to the portal. | Portal and local files |
| 14 | update-media | Sets the logo and adds or removes screenshots. | Portal |
| 15 | manage-client-keys | Creates, deletes, or sets the default OAuth client key. | Portal |
| 16 | manage-sandbox | Lists, creates, or deletes sandbox agencies. | Portal |
| 17 | release-workflow-module | Publishes an action or trigger version, or starts a new version. | Portal and local files |
| 18 | release-app | Publishes, withdraws, drafts, deprecates, or requests a security review. | Portal |
Sign in and choose an account
1. login
Opens the developer portal login page in your browser and waits for you to approve it. If you have not approved it within about 45 seconds, the tool returns the login URL and the login keeps waiting in the background for up to 5 minutes. Portal tools work as soon as it completes. If a session already works, the tool reports it instead of logging in again.
Your assistant calls this tool when another tool returns AUTH_REQUIRED.
| Parameter | Required | Description |
|---|---|---|
force | No | Log in again even though a session works, for example as another developer. Default false. |
Example prompt: "Log me in to the HighLevel developer portal."
2. get-account
Shows the logged-in developer, the active developer account, the other accounts you can switch to, and the apps in the active account with their app IDs, version, status, and which app is selected. Lists up to 50 apps; use search to narrow the list.
| Parameter | Required | Description |
|---|---|---|
search | No | Show only apps whose name contains this text. |
Example prompt: "Which apps do I have in my developer account?"
3. switch-account
Makes another developer account (team) active for the CLI and these tools, then lists the first apps in it. The app selected in the previous account is cleared. Use it only when you want to work in a different account.
| Parameter | Required | Description |
|---|---|---|
accountId | Yes | The account ID from get-account. |
Example prompt: "Switch to my agency team account."
Look up how things work
4. search-docs
Searches the HighLevel developer documentation and returns ranked excerpts with links to the matching sections. It covers:
- Marketplace guides: OAuth, scopes, webhooks, billing, external authentication, workflow actions and triggers, and publishing
- Every HighLevel API endpoint
- The CLI's app workspace guides and JSON Schemas
The docs index is cached on your machine, so searches are fast and keep working offline after the first use.
| Parameter | Required | Description |
|---|---|---|
query | Yes | Focused keywords, 2 to 300 characters. Keep exact names such as X-GHL-Signature, contacts.write, or ContactCreate. An endpoint such as POST /contacts/ also works. |
limit | No | Maximum results, 1 to 10. Default 5. |
kind | No | all (default), guide for Marketplace guides, api for API endpoints, or cli for app workspace files and their JSON Schemas. |
Example prompt: "How do I verify the webhook signature HighLevel sends?"
5. fetch-doc
Reads up to 5 documentation pages in one call, as Markdown. It accepts:
- Documentation URLs from
search-docs, including#sectionanchors - API endpoints such as
POST /contacts/orGET /contacts/{contactId}, which return a compact reference: token type, scopes,Versionheader, parameters, and request and response schemas - CLI workspace guides:
ghl-cli:app,ghl-cli:workflow-actions,ghl-cli:workflow-triggers,ghl-cli:billing, andghl-cli:commands - JSON Schemas for workspace files:
ghl-cli:schema/app,ghl-cli:schema/webhooks,ghl-cli:schema/workflow-action,ghl-cli:schema/workflow-trigger,ghl-cli:schema/subscription, andghl-cli:schema/usage-based
For a long guide, it returns the requested section and lists the page's other sections. If an endpoint is not found, it suggests the closest matches.
| Parameter | Required | Description |
|---|---|---|
pages | Yes | 1 to 5 documentation URLs, endpoints, or ghl-cli: references. |
startIndex | No | Continue a truncated page from this character offset. Default 0. |
maxLength | No | Characters returned across all pages, 2,000 to 100,000. Default 30,000. |
Example prompt: "What scope, token type, and Version header does GET /contacts/{contactId} need?"
Start an app
6. create-app
Creates a new app in the developer portal, writes its local workspace, and selects it. Ask for it only when you want a new app; your assistant confirms the name, type, target, installer, and listing with you first. The workspace folder must be outside any existing app workspace.
| Parameter | Required | Description |
|---|---|---|
name | Yes | App name, up to 50 characters. |
type | Yes | public (listed in the Marketplace) or private (installed by link). |
target | Yes | Who uses the app: sub-account or agency. |
installer | For sub-account apps | Who may install it: everyone (agencies and sub-accounts) or agency-only. |
listing | Yes | standard, or white-label to let agencies rebrand the app. |
directory | Yes | Absolute path of an existing folder to create the workspace folder in. |
folder | No | Workspace folder name. Defaults to the app name. |
Example prompt: "Create a private sub-account app called Contact Sync that everyone can install, in ~/code/apps."
7. pull-app
Writes an app version from the developer portal into a local workspace: ghl-app.json, webhooks, workflow actions and triggers with their code files, and billing plans and meters. It creates a new workspace folder, or refreshes an existing workspace, and selects the pulled version for the CLI. By default it pulls the latest version, which is the draft when one exists.
It refuses to overwrite local changes you have not pushed (LOCAL_CHANGES) unless you pass force.
| Parameter | Required | Description |
|---|---|---|
appId | No | The app to pull, from get-account. Omit it to refresh the workspace at directory. |
directory | Yes | Absolute path of a workspace to refresh, or of the folder to create a new workspace in. |
folder | No | New workspace folder name. Defaults to the app name. |
version | No | Version ID or version number to pull. Defaults to the latest version. |
force | No | Discard unpushed local changes when refreshing. Default false. |
withTypes | No | Also write TypeScript declarations and tsconfig files for TypeScript workflow actions. Default false. |
Example prompt: "Pull my Contact Sync app into ~/code/apps with TypeScript types."
Review the app
8. get-app
Shows one app version as the portal has it, in a single call:
- Status and all versions
- Basic info, OAuth scopes, redirect URIs, and client key names (never secrets)
- Media file names, webhooks, billing, and support details
- Workflow actions and triggers with their versions
For a draft, it also shows publish readiness: every missing required field with how to fill it using these tools, what publishing will do (a private app goes live, a public app goes to Marketplace review), and the next version number. For a live or in-review version, it says how the version can change.
| Parameter | Required | Description |
|---|---|---|
appId | No | App ID from get-account. Defaults to the app of directory, then the selected app. |
directory | No | Absolute path inside an app workspace, used when appId is omitted. |
Example prompt: "Is my app ready to publish? What is missing?"
9. list-scopes
Lists the exact OAuth scope names the developer portal accepts, the token types each scope allows (sub-account or agency), and the webhook events each scope unlocks. Use it to choose scopes for oauth.allowedScopes in ghl-app.json and events for the webhooks file.
| Parameter | Required | Description |
|---|---|---|
query | No | Words to match in a scope, its label, or a webhook event, such as contacts or ContactCreate. Omit it to list every scope. |
target | No | Only scopes an app with this target can request: sub-account or agency. |
Example prompt: "Which scope do I need to receive OpportunityCreate webhooks?"
Build and validate
10. scaffold-workflow-module
Adds up to 10 draft workflow actions or triggers to a workspace in one call: a JSON file for each, plus a JavaScript or TypeScript handler file for each action. Nothing reaches the portal until you push. The result lists the files to fill in, the guides that describe them, and any prerequisites, such as the workflows.readonly scope.
| Parameter | Required | Description |
|---|---|---|
directory | Yes | Absolute path of the app workspace or any folder inside it. |
modules | Yes | 1 to 10 modules, each with kind (action or trigger), a display name, and a stable key in snake_case that starts with a letter, such as send_sms. |
typescript | No | Give new actions a typed TypeScript handler instead of JavaScript. Default false. |
Example prompt: "Add a workflow action called Send SMS and a trigger called Deal Won to my app."
11. check-workspace
Validates every file in an app workspace (app settings, webhooks, workflow actions and triggers, billing) and compares the workspace with the developer portal. For each part it reports errors, your local changes, changes made in the portal since the last pull, and conflicts.
When the changes are valid, it lists exactly what a push would do and returns a plan ID for push-workspace. If you are not logged in, it checks the local files only. Pointed at a folder that is not a workspace, it lists the workspaces inside that folder.
| Parameter | Required | Description |
|---|---|---|
directory | Yes | Absolute path of the app workspace or any folder inside it. |
remote | No | Also compare with the developer portal. Default true; false checks local files only. |
Example prompt: "Check my app workspace and tell me what would be pushed."
12. test-workflow-action
Runs the local, unpushed configuration of a workflow action through the portal's test runner with the input you give it, and returns the action's output and up to 30 lines of console logs. Use it to test changes before you push them. The action may call its real endpoints.
Credential headers are hidden in the output. If the test would send a stored header secret to a URL the portal does not use for that action yet, the server asks for your direct approval first.
| Parameter | Required | Description |
|---|---|---|
directory | Yes | Absolute path of the app workspace or any folder inside it. |
key | Yes | The workflow action key. |
input | No | Input values keyed by field, as a workflow would send them. Up to 64 KB of JSON. |
version | No | The action version to test. Defaults to the draft, otherwise the newest version. |
locationId | No | A sub-account with the app installed, for actions that use location data or external authentication. |
Example prompt: "Test the send_sms action with phone +15555550123 and message Hello."
13. push-workspace
Pushes the plan returned by check-workspace to the developer portal: workflow actions first, then triggers, billing, and app settings, in the order the portal requires. It verifies the result and updates the workspace's baseline.
- It refuses with
PLAN_CHANGEDif the files or the portal changed after the plan was made. Runcheck-workspaceagain and review the new plan. - When your client supports it, the server asks you directly to approve the push and shows every changed field with its old and new value.
- Editing a live version creates a new draft version; the workspace follows it automatically.
- A version in review cannot be edited. Withdraw it with
release-appfirst. - If one part fails, the push stops and reports what was already applied.
| Parameter | Required | Description |
|---|---|---|
directory | Yes | Absolute path of the app workspace or any folder inside it. |
planId | Yes | The plan ID that check-workspace returned for the changes you approved. |
Example prompt: "Push those changes."
Add media and credentials
14. update-media
Sets the app logo, adds screenshots to the agency or sub-account profile, and removes attached media, in one call. Every upload is checked before anything is deleted. The result names each file added or removed and the media now on the app.
These changes go to the portal directly, so an open workspace falls behind; refresh it with pull-app. Enabling the sub-account profile needs at least 3 screenshots and a valid agency description.
| Parameter | Required | Description |
|---|---|---|
appId | No | Defaults to the app of directory, then the selected app. |
directory | No | App workspace whose app is used when appId is omitted. |
logo | No | Image file to set as the logo. |
screenshots | No | 1 to 9 image files to add as screenshots. |
profile | No | Profile the screenshots belong to: agency (default) or sub-account. |
remove | No | 1 to 20 attached media to delete, as file names from get-app or URLs. |
Pass at least one of logo, screenshots, or remove.
Example prompt: "Upload ./screens/dashboard.png as an agency screenshot and remove the oldest one."
15. manage-client-keys
Creates an OAuth client key, deletes one, or makes one the default for the app. A new key's secret is saved in the CLI's local secrets store and never appears in the conversation; view it once with ghl secrets reveal. Deleting a key breaks any integration that uses it.
| Parameter | Required | Description |
|---|---|---|
appId | No | Defaults to the app of directory, then the selected app. |
directory | No | App workspace whose app is used when appId is omitted. |
action | Yes | create, delete, or default. |
name | For create | A name for the new key. |
keyId | For delete and default | The client key ID from get-app. |
Example prompt: "Create a client key named Staging for my app."
Install and try the app
16. manage-sandbox
Lists the sandbox agencies you use to install and test apps, creates one, or deletes one with all its data. A new sandbox's password is saved in the CLI's local secrets store; log in with your developer email and view the password once with ghl secrets reveal. The portal allows one active sandbox per developer account.
| Parameter | Required | Description |
|---|---|---|
action | Yes | list, create, or delete. |
name | For create | The sandbox agency name. |
sandboxId | For delete | The company ID from list. |
Example prompt: "Do I have a sandbox account? If not, create one called QA Sandbox."
Release
17. release-workflow-module
Publishes the pushed draft version of a workflow action or trigger, or starts a new draft version of a published one. Either way, the workspace files are refreshed. Publishing checks the module's release requirements first, such as a trigger's subscription URL, and names the file to fix if one is missing.
| Parameter | Required | Description |
|---|---|---|
directory | Yes | Absolute path of the app workspace or any folder inside it. |
action | Yes | publish a draft version, or new-version to start a new draft of a published module. |
kind | Yes | action or trigger. |
key | Yes | The module key. |
version | No | For publish: the draft version to publish. Defaults to the current draft. |
notes | For publish | The release change log, up to 2,000 characters. |
Example prompt: "Publish the send_sms action with the change log 'Adds delivery status'."
18. release-app
Moves an app version through its release lifecycle. Run it only when you are ready; check readiness with get-app first.
| Action | What it does |
|---|---|
publish | Publishes the draft. A private app goes live for new installs; a public app is submitted for Marketplace review. The first release is always 1.0.0. Later releases default to the suggested version and need release notes. Readiness is checked first, and only one version can be pending at a time. |
withdraw | Withdraws the version in review. It becomes a draft again so you can edit it. |
create-draft | Creates a new draft from the latest live version. An app can have one draft at a time. |
deprecate | Schedules deprecation of an older live version, with a date at least 3 days ahead and notes for its users. The latest live version cannot be deprecated. Uses your local time zone. |
security-review | Requests a security review of a private app's live version. Available after 4 qualifying agency installs. |
| Parameter | Required | Description |
|---|---|---|
action | Yes | publish, withdraw, create-draft, deprecate, or security-review. |
appId | No | Defaults to the app of directory, then the selected app. |
directory | No | App workspace to keep in sync with the version's new status. |
version | For deprecate | For publish: the new version number (defaults to the suggested one). For deprecate: the live version to retire. |
notes | For publish after 1.0.0, and deprecate | For publish: release notes for agencies. For deprecate: notes for users of the version. Up to 2,000 characters. |
subAccountNotes | No | For publish: release notes for sub-accounts. |
date | For deprecate | Deprecation date as YYYY-MM-DD, at least 3 days ahead. |
If a value is not allowed, the error lists what is, for example the allowed version numbers.
Example prompts:
- "Publish my app as 1.1.0 with the release notes 'Adds opportunity sync'."
- "Withdraw my app from review."
- "Deprecate version 1.0.0 on 2026-12-31 and tell users to upgrade."