# Marketplace Developer MCP Server

Source: https://marketplace.gohighlevel.com/docs/2021-07-28/sdk/marketplace-cli/mcp

The [HighLevel Marketplace CLI](../marketplace-cli.md) 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](https://marketplace.gohighlevel.com)
- 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:

```bash
ghl --version
ghl update
```

New to the CLI? Install it first with `npm install -g @gohighlevel/marketplace-cli`. See [Install the CLI](../marketplace-cli.md#install-the-cli).

## Set up the server

1. Log in to your developer account (you can also do this later from your AI client):

   ```bash
   ghl login
   ```

2. Register the server with your AI clients:

   ```bash
   ghl mcp setup
   ```

   The 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.

3. Restart any AI client that was already open so it loads the server.

4. Confirm that the server is connected:

   | Client | How to check |
   | --- | --- |
   | Claude Code | Run `/mcp` and look for `HighLevelMarketplaceDev`, or run `claude mcp get HighLevelMarketplaceDev` in 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:

```bash
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:

```bash
npx -y --registry=https://registry.npmjs.org/ --package @gohighlevel/marketplace-cli@1.1.0 ghl mcp start
```

Use standalone mode on machines where global npm installs are not allowed, or to pin every client to one CLI version:

```bash
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 with `ghl account switch`. The app selected with `ghl app use` is 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-workspace` returns a plan ID for the exact changes it found. `push-workspace` runs 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 `#section` anchors
- API endpoints such as `POST /contacts/` or `GET /contacts/{contactId}`, which return a compact reference: token type, scopes, `Version` header, parameters, and request and response schemas
- CLI workspace guides: `ghl-cli:app`, `ghl-cli:workflow-actions`, `ghl-cli:workflow-triggers`, `ghl-cli:billing`, and `ghl-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`, and `ghl-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_CHANGED` if the files or the portal changed after the plan was made. Run `check-workspace` again 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-app` first.
- 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."
