@elitedcs/ghl-mcp 3.66.0 → 3.66.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,68 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.66.2 — an export could describe the wrong client
4
+
5
+ If you asked for one client's account and the server had been started pointing at
6
+ another, part of the report came from the other account. Not an error, not a
7
+ warning: the workflows and funnels of a different business, sitting under the
8
+ name of the one you asked about.
9
+
10
+ It happened because the export asked two different places for "which account",
11
+ and only one of them listened to the account you named. That is now a single
12
+ answer. If the two ever disagree, the export refuses those sections and tells you
13
+ which account it is actually holding and how to switch, rather than answering for
14
+ the wrong one. Everything else in the report was always correct.
15
+
16
+ Every section also explains itself when it fails now. They used to all say
17
+ "Error fetching", which told you nothing and hid a real permissions error behind
18
+ what looked like a hiccup.
19
+
20
+ **New guide: Clone and rebrand a site.** Point Claude at a page you have the
21
+ rights to, and get it rebuilt for your client with their name, colours and
22
+ contact details, plus a review list of everything still belonging to whoever
23
+ owned the original: where the leads and payments still go, other people's
24
+ testimonials, claims that came along with the copy. Proven against a real site
25
+ before it was written.
26
+
27
+ That guide is deliberately separate from building a page inside GHL. Cloning an
28
+ existing page and composing a new one are different jobs that fail in different
29
+ ways, and one guide covering both served neither.
30
+
31
+ **Blog guide parked.** Reading a list of blog posts does not work — the address
32
+ it calls does not exist, on any account. Rather than ship a guide that depends on
33
+ it, the blog tools are marked as not guide material until that is fixed.
34
+
35
+ ## 3.66.1 — the tool count was wrong, and so was the thing that checked it
36
+
37
+ GHL Command has served 239 tools since v3.60.0. Every place we stated the number
38
+ said 238, and had done for twelve releases.
39
+
40
+ The cause is worth writing down, because the number was the smaller half of it.
41
+ The count was derived from a total that a person kept up to date by hand, and the
42
+ test that checked our claims derived its answer from that same total. So the
43
+ claim and the check always agreed, and both were wrong together. Nothing in the
44
+ suite could see the gap, because everything in the suite was looking at the same
45
+ number.
46
+
47
+ Three figures were each one low and are now correct: **239 tools**, **184 without
48
+ the optional builder step**, **111 on the free tier**. The upgrade still unlocks
49
+ 55 tools; that figure was always right, because the error cancelled out of a
50
+ subtraction.
51
+
52
+ The mechanism is fixed too, which matters more than the digits. The tools counted
53
+ here are now read from the list the server registers them from, so a tool added
54
+ tomorrow changes the number the day it lands rather than the day someone
55
+ remembers. There is also a new release check that starts a real server, asks it
56
+ what tools it has, and compares that to what we advertise. That is the only check
57
+ that could have caught this, because it is the only one that does not get its
58
+ answer from the code it is checking.
59
+
60
+ Earlier entries in this file state counts that were one low at the time. They are
61
+ left as they were written rather than quietly corrected.
62
+
63
+ Also: `update_webhook` now carries the same warning as the other webhook tools
64
+ about `tags` arriving as comma separated text rather than a list.
65
+
3
66
  ## 3.66.0 — webhooks work now
4
67
 
5
68
  The five webhook tools have never worked for anyone. They called an address
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # GHL Command — GoHighLevel MCP Server
2
2
 
3
- **Full GoHighLevel API access for Claude.** 238 tools across 50 modules — manage contacts, conversations, pipelines, calendars, funnels, workflows, invoices, custom objects, webhooks, and more. **Includes full workflow builder, funnel/page editor, form builder, pipeline builder, bulk operations, account export, and workflow cloning** — capabilities no other GHL tool offers. **Multi-tenant:** one install can run the workflow builder across multiple clients' GHL accounts.
3
+ **Full GoHighLevel API access for Claude.** 239 tools across 50 modules — manage contacts, conversations, pipelines, calendars, funnels, workflows, invoices, custom objects, webhooks, and more. **Includes full workflow builder, funnel/page editor, form builder, pipeline builder, bulk operations, account export, and workflow cloning** — capabilities no other GHL tool offers. **Multi-tenant:** one install can run the workflow builder across multiple clients' GHL accounts.
4
4
 
5
5
  **Distributed via npm as [`@elitedcs/ghl-mcp`](https://www.npmjs.com/package/@elitedcs/ghl-mcp).** Buyers install with one config block — no git, no Node.js setup, no terminal commands. Updates flow automatically (`npx @latest` re-resolves on every Claude restart).
6
6
 
@@ -8,7 +8,7 @@ Works with **both the Claude Desktop App and Claude Code terminal** — your cho
8
8
 
9
9
  **License required.** Get it at [ghlcommand.com](https://ghlcommand.com?utm_source=npm&utm_medium=readme) — $97/mo, covering UNLIMITED GoHighLevel sub-accounts on up to 3 machines (never billed per account). **30-day time-back guarantee**: save 5+ hours on one client build or your first month back.
10
10
 
11
- **Try it FREE (read-only tier).** Grab an instant free key at [ghlcommand.com/free](https://ghlcommand.com/free?utm_source=npm&utm_medium=readme) — 110 read-only tools on your own GHL account once the two-step install is finished (the same install as the paid tier — upgrading later is just a license swap): the account-wide workflow audit (`audit_workflows` finds the silently broken references GHL never warns you about), account health, and every read across contacts, pipelines, funnels, and workflows. Write tools stay visible and answer with upgrade info. Buying later with the same email upgrades your key in place — 1 machine on free, 3 when you upgrade.
11
+ **Try it FREE (read-only tier).** Grab an instant free key at [ghlcommand.com/free](https://ghlcommand.com/free?utm_source=npm&utm_medium=readme) — 111 read-only tools on your own GHL account once the two-step install is finished (the same install as the paid tier — upgrading later is just a license swap): the account-wide workflow audit (`audit_workflows` finds the silently broken references GHL never warns you about), account health, and every read across contacts, pipelines, funnels, and workflows. Write tools stay visible and answer with upgrade info. Buying later with the same email upgrades your key in place — 1 machine on free, 3 when you upgrade.
12
12
 
13
13
  **How this differs from HighLevel's official MCP.** HighLevel ships an official Anthropic MCP that reads and writes your CRM (contacts, conversations, calendars, opportunities, payments, social) over the public API — it's free and it's good; use it for that. What it *cannot* do, because the public API doesn't expose it: **build or edit workflows, build funnels/landing pages, or build forms.** That's exactly what GHL Command does — the programmatic Workflow Builder, funnel/page builder, form builder, deep workflow cloning, the silent-failure `audit_workflows`, and Blueprint (build a whole client account from one intake — ships as a guided skill that **installs itself automatically** with this package; nothing to download), all on GHL's internal APIs. **Official MCP = read/write your CRM. GHL Command = build and fix it.** They stack fine together.
14
14
 
@@ -135,7 +135,7 @@ Run setup_ghl_mcp to activate GHL Command:
135
135
  ghl_location_id: YOUR_LOCATION_ID
136
136
  ```
137
137
 
138
- Approve the tool call. Server validates your license, verifies your GHL credentials, writes them to a per-user config file. **Quit Claude one more time and reopen** — the full core toolset is now unlocked (238 tools total with the optional Workflow Builder Firebase add-on).
138
+ Approve the tool call. Server validates your license, verifies your GHL credentials, writes them to a per-user config file. **Quit Claude one more time and reopen** — the full core toolset is now unlocked (239 tools total with the optional Workflow Builder Firebase add-on).
139
139
 
140
140
  ### 4. Try it
141
141
 
@@ -175,7 +175,7 @@ https://app.gohighlevel.com/v2/location/YOUR_LOCATION_ID/dashboard
175
175
 
176
176
  ## Enable the Workflow Builder
177
177
 
178
- The builder + cloner + validator tools (workflow builder, funnel builder, form builder, pipeline builder, workflow cloner, validate_workflow) use GHL's internal API and require Firebase credentials. Without them, the other 183 tools work fine — you just won't have workflow/funnel/form/pipeline editing. This is the flagship feature: do this step.
178
+ The builder + cloner + validator tools (workflow builder, funnel builder, form builder, pipeline builder, workflow cloner, validate_workflow) use GHL's internal API and require Firebase credentials. Without them, the other 184 tools work fine — you just won't have workflow/funnel/form/pipeline editing. This is the flagship feature: do this step.
179
179
 
180
180
  **One-click capture (v3.49.0+, the supported path):**
181
181
 
@@ -798,7 +798,7 @@ Source repo is private. Contributors need an invitation from `drjerryrelth`. The
798
798
 
799
799
  ### Reducing context / token usage
800
800
 
801
- Every registered MCP tool's schema is shipped to the model on every message. With 238 tools that's a meaningful per-message context cost even in chats that never touch GHL. If you only use a slice of GHL Command, restrict the tool surface with `GHL_ENABLED_MODULES` and/or `GHL_ENABLED_TOOLS`:
801
+ Every registered MCP tool's schema is shipped to the model on every message. With 239 tools that's a meaningful per-message context cost even in chats that never touch GHL. If you only use a slice of GHL Command, restrict the tool surface with `GHL_ENABLED_MODULES` and/or `GHL_ENABLED_TOOLS`:
802
802
 
803
803
  ```jsonc
804
804
  // Claude Desktop config — enable whole modules
package/dist/index.js CHANGED
@@ -1648,7 +1648,7 @@ Note: Firebase credentials rejected (${fb.error}).`;
1648
1648
  const telemetryLine = telemetryDisabled(process.env) ? "" : `
1649
1649
 
1650
1650
  ${TELEMETRY_DISCLOSURE}`;
1651
- const finishedCount = isFree ? "110" : "238";
1651
+ const finishedCount = isFree ? "111" : "239";
1652
1652
  const freeTip = isFree ? `
1653
1653
 
1654
1654
  Free tier: read-only. Write tools stay visible but answer with upgrade info instead of acting. Full version ($97/mo founding rate) upgrades in place \u2014 same install, you only swap the license key: https://ghlcommand.com` : "";
@@ -1693,7 +1693,7 @@ Free tier: read-only. Write tools stay visible but answer with upgrade info inst
1693
1693
  function registerEnableWorkflowBuilderTool(server2) {
1694
1694
  server2.tool(
1695
1695
  "enable_workflow_builder",
1696
- "Add Firebase credentials to an existing GHL Command install to unlock 55 additional tools across the internal-API modules: workflow builder (create/edit/clone/delete/publish/validate workflows, build_if_else_branch, build_goal_event, get_trigger_registry), funnel + page builder, form builder, pipeline builder, workflow cloner, smart lists, reputation, email campaigns, email templates, and memberships, plus the pre-deploy validator. On the FREE tier this same login unlocks the read-only auditor suite (audit_workflows, validate_workflow, full-detail workflow/funnel/pipeline reads). Requires you've already run setup_ghl_mcp. EASIEST PATH: run `capture_firebase_interactive` instead \u2014 a Chrome window opens, you log into GHL, zero pasting. Use THIS tool when you have JSON from `auto_capture_firebase_script` (console-paste path) to put in `firebase_paste`, or the three manual DevTools fields. Tool count goes from 183 to 238 after the next Claude restart.",
1696
+ "Add Firebase credentials to an existing GHL Command install to unlock 55 additional tools across the internal-API modules: workflow builder (create/edit/clone/delete/publish/validate workflows, build_if_else_branch, build_goal_event, get_trigger_registry), funnel + page builder, form builder, pipeline builder, workflow cloner, smart lists, reputation, email campaigns, email templates, and memberships, plus the pre-deploy validator. On the FREE tier this same login unlocks the read-only auditor suite (audit_workflows, validate_workflow, full-detail workflow/funnel/pipeline reads). Requires you've already run setup_ghl_mcp. EASIEST PATH: run `capture_firebase_interactive` instead \u2014 a Chrome window opens, you log into GHL, zero pasting. Use THIS tool when you have JSON from `auto_capture_firebase_script` (console-paste path) to put in `firebase_paste`, or the three manual DevTools fields. Tool count goes from 184 to 239 after the next Claude restart.",
1697
1697
  {
1698
1698
  // v3.25.0: one-paste path. Tool runs `auto_capture_firebase_script` to
1699
1699
  // get the console script; the script returns a JSON object that pastes
@@ -1774,7 +1774,7 @@ DevTools steps: https://elitedcs.com/ghl-mcp-firebase`
1774
1774
  "",
1775
1775
  "**You MUST restart Claude before using any workflow-builder tool.** Quit Claude completely (Cmd+Q on Mac, full exit on Windows) and reopen. Without a restart, the workflow builder tools will keep using the OLD Firebase auth from before this call and fail with 401 errors \u2014 even though this tool reported success.",
1776
1776
  "",
1777
- 'After restart, all 238 tools load. Try: "List my workflows in full detail" or "Validate workflow <id>".',
1777
+ 'After restart, all 239 tools load. Try: "List my workflows in full detail" or "Validate workflow <id>".',
1778
1778
  "",
1779
1779
  "Note: Firebase refresh tokens rotate every few weeks. If workflow tools stop working in a few weeks (run `health_check` to confirm Firebase auth: FAIL), run `auto_capture_firebase_script` for fresh values and re-run this tool with the new firebase_paste."
1780
1780
  ].join("\n")
@@ -1870,7 +1870,7 @@ The login in the capture window may belong to the wrong GHL account, or the sess
1870
1870
  "",
1871
1871
  "**You MUST restart Claude before using any workflow-builder tool.** Quit Claude completely (Cmd+Q on Mac, full exit on Windows) and reopen.",
1872
1872
  "",
1873
- 'After restart, all 238 tools load. Try: "List my workflows in full detail".',
1873
+ 'After restart, all 239 tools load. Try: "List my workflows in full detail".',
1874
1874
  "",
1875
1875
  "Future token rotations re-capture silently \u2014 if workflow tools ever 401, just run capture_firebase_interactive again; no window should appear."
1876
1876
  ].join("\n")
@@ -2854,9 +2854,9 @@ var require_package = __commonJS({
2854
2854
  "package.json"(exports2, module2) {
2855
2855
  module2.exports = {
2856
2856
  name: "@elitedcs/ghl-mcp",
2857
- version: "3.66.0",
2857
+ version: "3.66.2",
2858
2858
  mcpName: "io.github.drjerryrelth/ghl-command",
2859
- description: "GoHighLevel MCP Server for Claude. 238 tools \u2014 full CRM, automation, marketing control, account-wide workflow audit, live funnel-capture verification, and the only programmatic GHL workflow builder, now multi-tenant across client accounts.",
2859
+ description: "GoHighLevel MCP Server for Claude. 239 tools \u2014 full CRM, automation, marketing control, account-wide workflow audit, live funnel-capture verification, and the only programmatic GHL workflow builder, now multi-tenant across client accounts.",
2860
2860
  main: "dist/index.js",
2861
2861
  bin: {
2862
2862
  "ghl-mcp": "dist/index.js"
@@ -10292,7 +10292,7 @@ function registerWebhookTools(server2, builderClient) {
10292
10292
  );
10293
10293
  server2.tool(
10294
10294
  "update_webhook",
10295
- "Change a webhook's URL, method, custom data, headers, name, events, or published status. Edits the existing action in place rather than replacing it, so the workflow's history and any other steps around it survive. Only the fields you pass change; everything else is left alone.",
10295
+ "Change a webhook's URL, method, custom data, headers, name, events, or published status. Edits the existing action in place rather than replacing it, so the workflow's history and any other steps around it survive. Only the fields you pass change; everything else is left alone. " + WEBHOOK_PAYLOAD_NOTE,
10296
10296
  {
10297
10297
  webhookId: import_zod34.z.string().describe("The webhook ID (its workflow ID)."),
10298
10298
  url: import_zod34.z.string().optional().describe("New destination URL."),
@@ -13691,8 +13691,22 @@ var import_zod46 = require("zod");
13691
13691
  function delay2(ms) {
13692
13692
  return new Promise((resolve8) => setTimeout(resolve8, ms));
13693
13693
  }
13694
- function registerAccountExportTools(server2, client, registry2) {
13695
- const builderClient = WorkflowBuilderClient.fromEnv();
13694
+ function builderSectionAvailability(builderLocationId, requestedLocationId) {
13695
+ if (!builderLocationId) {
13696
+ return {
13697
+ usable: false,
13698
+ reason: "Not read: the workflow builder is not connected. Run enable_workflow_builder to add Firebase credentials, then export again."
13699
+ };
13700
+ }
13701
+ if (builderLocationId !== requestedLocationId) {
13702
+ return {
13703
+ usable: false,
13704
+ reason: `Not read: the workflow builder is connected to a DIFFERENT sub-account (${builderLocationId}), not the one being exported (${requestedLocationId}). Reading it would describe the wrong account. Run switch_location to ${requestedLocationId} and export again.`
13705
+ };
13706
+ }
13707
+ return { usable: true };
13708
+ }
13709
+ function registerAccountExportTools(server2, client, registry2, builderClient) {
13696
13710
  server2.tool(
13697
13711
  "export_account",
13698
13712
  "Export a complete inventory of the GHL sub-account: location info, contacts (count + sample), pipelines with stages, workflows (with full actions if builder auth is configured), funnels with pages, forms, custom fields, custom values, tags, calendars, and users. Returns a comprehensive JSON report for auditing or backup.",
@@ -13709,8 +13723,8 @@ function registerAccountExportTools(server2, client, registry2) {
13709
13723
  };
13710
13724
  try {
13711
13725
  report.location = await client.get(`/locations/${locId}`);
13712
- } catch {
13713
- report.location = "Error fetching";
13726
+ } catch (e) {
13727
+ report.location = `Error fetching: ${errorMessage(e)}`;
13714
13728
  }
13715
13729
  await delay2(100);
13716
13730
  try {
@@ -13724,36 +13738,38 @@ function registerAccountExportTools(server2, client, registry2) {
13724
13738
  total: typeof meta.total === "number" ? meta.total : contactList.length,
13725
13739
  sample: includeContacts ? contactList : contactList.slice(0, 1)
13726
13740
  };
13727
- } catch {
13728
- report.contacts = "Error fetching";
13741
+ } catch (e) {
13742
+ report.contacts = `Error fetching: ${errorMessage(e)}`;
13729
13743
  }
13730
13744
  await delay2(100);
13731
13745
  try {
13732
13746
  report.pipelines = await client.get("/opportunities/pipelines", {
13733
13747
  params: { locationId: locId }
13734
13748
  });
13735
- } catch {
13736
- report.pipelines = "Error fetching";
13749
+ } catch (e) {
13750
+ report.pipelines = `Error fetching: ${errorMessage(e)}`;
13737
13751
  }
13738
13752
  await delay2(100);
13739
13753
  try {
13740
13754
  report.workflows = await client.get("/workflows/", {
13741
13755
  params: { locationId: locId }
13742
13756
  });
13743
- } catch {
13744
- report.workflows = "Error fetching";
13757
+ } catch (e) {
13758
+ report.workflows = `Error fetching: ${errorMessage(e)}`;
13745
13759
  }
13746
13760
  await delay2(100);
13747
- if (builderClient) {
13761
+ const builderUse = builderSectionAvailability(builderClient?.locationId, locId);
13762
+ if (builderUse.usable && builderClient) {
13748
13763
  try {
13749
- const fullWorkflows = await builderClient.listWorkflows(50, 0);
13750
- report.workflowsFull = fullWorkflows;
13751
- } catch {
13752
- report.workflowsFull = "Error fetching (builder auth may have expired)";
13764
+ report.workflowsFull = await builderClient.listWorkflows(50, 0);
13765
+ } catch (e) {
13766
+ report.workflowsFull = `Error fetching: ${errorMessage(e)}`;
13753
13767
  }
13754
13768
  await delay2(100);
13769
+ } else {
13770
+ report.workflowsFull = builderUse.reason;
13755
13771
  }
13756
- if (builderClient) {
13772
+ if (builderUse.usable && builderClient) {
13757
13773
  try {
13758
13774
  const headers = await builderClient.buildHeaders();
13759
13775
  const res = await fetch(
@@ -13761,9 +13777,9 @@ function registerAccountExportTools(server2, client, registry2) {
13761
13777
  { headers }
13762
13778
  );
13763
13779
  if (res.ok) report.funnels = await res.json();
13764
- else report.funnels = "Error fetching";
13765
- } catch {
13766
- report.funnels = "Error fetching";
13780
+ else report.funnels = `Error fetching: builder returned HTTP ${res.status}`;
13781
+ } catch (e) {
13782
+ report.funnels = `Error fetching: ${errorMessage(e)}`;
13767
13783
  }
13768
13784
  await delay2(100);
13769
13785
  } else {
@@ -13771,50 +13787,50 @@ function registerAccountExportTools(server2, client, registry2) {
13771
13787
  report.funnels = await client.get("/funnels/", {
13772
13788
  params: { locationId: locId }
13773
13789
  });
13774
- } catch {
13775
- report.funnels = "Error fetching";
13790
+ } catch (e) {
13791
+ report.funnels = `Error fetching: ${errorMessage(e)}`;
13776
13792
  }
13777
13793
  }
13778
13794
  try {
13779
13795
  report.forms = await client.get("/forms/", {
13780
13796
  params: { locationId: locId }
13781
13797
  });
13782
- } catch {
13783
- report.forms = "Error fetching";
13798
+ } catch (e) {
13799
+ report.forms = `Error fetching: ${errorMessage(e)}`;
13784
13800
  }
13785
13801
  await delay2(100);
13786
13802
  try {
13787
13803
  report.customFields = await client.get("/locations/" + locId + "/customFields");
13788
- } catch {
13789
- report.customFields = "Error fetching";
13804
+ } catch (e) {
13805
+ report.customFields = `Error fetching: ${errorMessage(e)}`;
13790
13806
  }
13791
13807
  await delay2(100);
13792
13808
  try {
13793
13809
  report.customValues = await client.get("/locations/" + locId + "/customValues");
13794
- } catch {
13795
- report.customValues = "Error fetching";
13810
+ } catch (e) {
13811
+ report.customValues = `Error fetching: ${errorMessage(e)}`;
13796
13812
  }
13797
13813
  await delay2(100);
13798
13814
  try {
13799
13815
  report.tags = await client.get("/locations/" + locId + "/tags");
13800
- } catch {
13801
- report.tags = "Error fetching";
13816
+ } catch (e) {
13817
+ report.tags = `Error fetching: ${errorMessage(e)}`;
13802
13818
  }
13803
13819
  await delay2(100);
13804
13820
  try {
13805
13821
  report.calendars = await client.get("/calendars/", {
13806
13822
  params: { locationId: locId }
13807
13823
  });
13808
- } catch {
13809
- report.calendars = "Error fetching";
13824
+ } catch (e) {
13825
+ report.calendars = `Error fetching: ${errorMessage(e)}`;
13810
13826
  }
13811
13827
  await delay2(100);
13812
13828
  try {
13813
13829
  report.users = await client.get("/users/", {
13814
13830
  params: { locationId: locId }
13815
13831
  });
13816
- } catch {
13817
- report.users = "Error fetching";
13832
+ } catch (e) {
13833
+ report.users = `Error fetching: ${errorMessage(e)}`;
13818
13834
  }
13819
13835
  return jsonResponse(report);
13820
13836
  } catch (error) {
@@ -19411,7 +19427,7 @@ function registerAllTools(server2, client, registry2, mcpVersion, env = process.
19411
19427
  () => buildGatingReport(config3, KNOWN_MODULES, attemptedTools, registeredTools, outOfBand)
19412
19428
  );
19413
19429
  registerSnapshotTools(wrap(SNAPSHOTS_MODULE), client, registry2);
19414
- registerAccountExportTools(wrap(ACCOUNT_EXPORT_MODULE), client, registry2);
19430
+ registerAccountExportTools(wrap(ACCOUNT_EXPORT_MODULE), client, registry2, builderClient);
19415
19431
  registerLocationSwitcherTools(
19416
19432
  wrap(LOCATION_SWITCHER_MODULE),
19417
19433
  client,
@@ -19439,6 +19455,13 @@ init_telemetry_transport();
19439
19455
  function makeOutOfBandTracker() {
19440
19456
  return { registered: /* @__PURE__ */ new Set(), denied: /* @__PURE__ */ new Set() };
19441
19457
  }
19458
+ var NORMAL_MODE_OUT_OF_BAND_TOOLS = [
19459
+ "setup_ghl_mcp",
19460
+ "enable_workflow_builder",
19461
+ "auto_capture_firebase_script",
19462
+ "capture_firebase_interactive",
19463
+ "install_skills"
19464
+ ];
19442
19465
  function registerOutOfBand(entries, config3, tracker, log = (m) => process.stderr.write(m)) {
19443
19466
  for (const entry of entries) {
19444
19467
  if (isToolDenied(entry.name, "", config3)) {
@@ -20190,48 +20213,51 @@ async function resolveAccessAndRegister() {
20190
20213
  } else {
20191
20214
  const client = new GHLClient({ apiKey, locationId });
20192
20215
  registerAllTools(server, client, registry, pkg.version, process.env, sessionTier, outOfBandTracker);
20193
- registerOutOfBand(
20194
- [
20195
- // Available in normal mode so buyers can add Firebase later without
20196
- // re-running setup_ghl_mcp with all 7 fields, and so they can re-grab
20197
- // a fresh refresh token when it rotates. Registered on the FREE tier too:
20198
- // the Firebase login powers the read-only auditor tools (audit_workflows,
20199
- // validate_workflow, *_full reads) — only the write tools stay gated.
20200
- // v3.60.0: setup_ghl_mcp registers in NORMAL mode too — it is the
20201
- // ONE-LINE UPGRADE path ("email + new license key, nothing else").
20202
- // Before this it existed only in bootstrap, so an installed free user
20203
- // pasting the upgrade line got "Tool setup_ghl_mcp not found" — the
20204
- // exact audience the upgrade exists for. Caught by the live wire
20205
- // proof, not by unit tests (the handler worked; registration didn't).
20206
- { name: "setup_ghl_mcp", register: () => registerSetupTool(server, pkg.version) },
20207
- { name: "enable_workflow_builder", register: () => registerEnableWorkflowBuilderTool(server) },
20208
- { name: "auto_capture_firebase_script", register: () => registerFirebaseCaptureScriptTool(server) },
20209
- // One-click Builder unlock buyer just logs into a Chrome window the
20210
- // helper opens; also the silent re-capture path for token rotations.
20211
- { name: "capture_firebase_interactive", register: () => registerInteractiveCaptureTool(server) },
20212
- // Skills rail (2026-07-28): bundled skills (Blueprint) install themselves
20213
- // into ~/.claude/skills subscribers never download anything separately.
20214
- // Auto-runs on every start (idempotent, never clobbers user edits);
20215
- // the tool exists for verification/repair. Every tier: local file copy
20216
- // only. Denying install_skills also skips the auto-install a buyer who
20217
- // gated it clearly doesn't want this server writing files into ~/.claude.
20218
- {
20219
- name: "install_skills",
20220
- register: () => registerSkillsTool(server, pkg.version, __dirname),
20221
- deniedNote: "bundled-skills auto-install skipped too",
20222
- sideEffect: () => {
20223
- try {
20224
- const skillsResult = installBundledSkills({ packageVersion: pkg.version, baseDir: __dirname });
20225
- const line = summarizeInstall(skillsResult);
20226
- if (line) process.stderr.write(`[ghl-mcp] ${line}
20216
+ const normalModeOutOfBand = {
20217
+ // Available in normal mode so buyers can add Firebase later without
20218
+ // re-running setup_ghl_mcp with all 7 fields, and so they can re-grab
20219
+ // a fresh refresh token when it rotates. Registered on the FREE tier too:
20220
+ // the Firebase login powers the read-only auditor tools (audit_workflows,
20221
+ // validate_workflow, *_full reads) only the write tools stay gated.
20222
+ //
20223
+ // v3.60.0: setup_ghl_mcp registers in NORMAL mode too — it is the
20224
+ // ONE-LINE UPGRADE path ("email + new license key, nothing else").
20225
+ // Before this it existed only in bootstrap, so an installed free user
20226
+ // pasting the upgrade line got "Tool setup_ghl_mcp not found" — the
20227
+ // exact audience the upgrade exists for. Caught by the live wire
20228
+ // proof, not by unit tests (the handler worked; registration didn't).
20229
+ // The SAME change also went uncounted for twelve releases, which is why
20230
+ // this block is now driven by a list the count guard can read.
20231
+ setup_ghl_mcp: { register: () => registerSetupTool(server, pkg.version) },
20232
+ enable_workflow_builder: { register: () => registerEnableWorkflowBuilderTool(server) },
20233
+ auto_capture_firebase_script: { register: () => registerFirebaseCaptureScriptTool(server) },
20234
+ // One-click Builder unlock buyer just logs into a Chrome window the
20235
+ // helper opens; also the silent re-capture path for token rotations.
20236
+ capture_firebase_interactive: { register: () => registerInteractiveCaptureTool(server) },
20237
+ // Skills rail (2026-07-28): bundled skills (Blueprint) install themselves
20238
+ // into ~/.claude/skills subscribers never download anything separately.
20239
+ // Auto-runs on every start (idempotent, never clobbers user edits);
20240
+ // the tool exists for verification/repair. Every tier: local file copy
20241
+ // only. Denying install_skills also skips the auto-install — a buyer who
20242
+ // gated it clearly doesn't want this server writing files into ~/.claude.
20243
+ install_skills: {
20244
+ register: () => registerSkillsTool(server, pkg.version, __dirname),
20245
+ deniedNote: "bundled-skills auto-install skipped too",
20246
+ sideEffect: () => {
20247
+ try {
20248
+ const skillsResult = installBundledSkills({ packageVersion: pkg.version, baseDir: __dirname });
20249
+ const line = summarizeInstall(skillsResult);
20250
+ if (line) process.stderr.write(`[ghl-mcp] ${line}
20227
20251
  `);
20228
- } catch (e) {
20229
- process.stderr.write(`[ghl-mcp] Skills install skipped: ${String(e).slice(0, 120)}
20252
+ } catch (e) {
20253
+ process.stderr.write(`[ghl-mcp] Skills install skipped: ${String(e).slice(0, 120)}
20230
20254
  `);
20231
- }
20232
20255
  }
20233
20256
  }
20234
- ],
20257
+ }
20258
+ };
20259
+ registerOutOfBand(
20260
+ NORMAL_MODE_OUT_OF_BAND_TOOLS.map((name) => ({ name, ...normalModeOutOfBand[name] })),
20235
20261
  gatingConfig,
20236
20262
  outOfBandTracker
20237
20263
  );
package/guide/guide.html CHANGED
@@ -4,7 +4,7 @@
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1">
6
6
  <title>GHL Command — User Guide</title>
7
- <!-- guides-hash: a156991f1141b0d5 -->
7
+ <!-- guides-hash: eb1eef4169720b47 -->
8
8
  <style>
9
9
  /* Deliberately light in every environment, including a dark-mode OS. This is a
10
10
  reference document people read at length, print, and save to PDF, and a page
@@ -226,7 +226,7 @@ body.app.reading #indexview{display:none}
226
226
  <p class="eyebrow">GHL Command</p>
227
227
  <h1>What do you want to get done?</h1>
228
228
  <p class="sub">Every guide is a job, in plain English: open one, copy a prompt, paste it to Claude. A job is not a button, so one guide usually puts a dozen of GHL Command's tools to work at once. Every prompt marked "Proven live" was run against a real GoHighLevel account before it shipped.</p>
229
- <div class="badges"><span class="badge on">28 guides</span><span class="badge">10 categories</span><span class="badge">Updates with the product</span></div>
229
+ <div class="badges"><span class="badge on">29 guides</span><span class="badge">10 categories</span><span class="badge">Updates with the product</span></div>
230
230
  </div></section>
231
231
  <div class="shell">
232
232
  <main>
@@ -247,10 +247,10 @@ body.app.reading #indexview{display:none}
247
247
  <a class="card pub" href="#g-invoices-and-payments" data-k="invoice bill billing payment paid product price coupon promo code discount transactions orders revenue estimate"><h3>Bill a client and see what you were paid</h3><p>Products, invoices, coupons, and the money reads, without opening the billing screen.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~5 minutes</span><span class="open">Open guide &#8594;</span></div></a>
248
248
  <a class="card pub" href="#g-stand-up-a-pipeline" data-k="pipeline stages create new client setup opportunity sales process deal stages"><h3>Stand up a pipeline</h3><p>Stages, fields, and tags for a new client in one conversation.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~10 minutes</span><span class="open">Open guide &#8594;</span></div></a>
249
249
  <a class="card pub" href="#g-track-and-move-opportunities" data-k="opportunities deals move stage track stuck value won lost pipeline board"><h3>Track and move opportunities</h3><p>Move deals between stages, update values, and see what is stuck.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~1 minute</span><span class="open">Open guide &#8594;</span></div></a></div></div>
250
- <div class="catsec" id="cat-client-builds-and-pages"><h2>Client builds and pages</h2><div class="cards"><a class="card pub" href="#g-snapshots-and-reusing-a-build" data-k="snapshot template reuse clone account new client share link import rollout onboarding"><h3>Reuse a build across client accounts</h3><p>Find your snapshots, share one, and know exactly what does not travel with it.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~5 minutes</span><span class="open">Open guide &#8594;</span></div></a>
250
+ <div class="catsec" id="cat-client-builds-and-pages"><h2>Client builds and pages</h2><div class="cards"><a class="card pub" href="#g-clone-and-rebrand-a-site" data-k="clone site copy rebrand landing page existing url duplicate make one like this mirror"><h3>Clone and rebrand a site</h3><p>Rebuild an existing page for a new client, with a rights check and a review report.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~30 minutes</span><span class="open">Open guide &#8594;</span></div></a>
251
+ <a class="card pub" href="#g-snapshots-and-reusing-a-build" data-k="snapshot template reuse clone account new client share link import rollout onboarding"><h3>Reuse a build across client accounts</h3><p>Find your snapshots, share one, and know exactly what does not travel with it.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~5 minutes</span><span class="open">Open guide &#8594;</span></div></a>
251
252
  <button class="card locked" type="button" data-k="blueprint client account build intake onboarding new complete template" data-toast="This guide arrives in a product update — your install picks it up automatically." title="Coming in a product update." aria-label="The Blueprint: build a client account. Coming in a product update."><h3>The Blueprint: build a client account</h3><p>From intake form to a complete, reviewed account build you approve before it runs.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~1 hour</span><span class="applabel">Coming in an update</span></div></button>
252
- <button class="card locked" type="button" data-k="page studio compose website landing pages funnel" data-toast="This guide arrives in a product update — your install picks it up automatically." title="Coming in a product update." aria-label="Page Studio: pages and sites. Coming in a product update."><h3>Page Studio: pages and sites</h3><p>Compose landing pages and full sites that render correctly in GHL.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~20 min</span><span class="applabel">Coming in an update</span></div></button>
253
- <button class="card locked" type="button" data-k="clone site copy rebrand landing page existing url" data-toast="This guide arrives in a product update — your install picks it up automatically." title="Coming in a product update." aria-label="Clone and rebrand a site. Coming in a product update."><h3>Clone and rebrand a site</h3><p>Rebuild an existing page for a new client, with a rights check and a review report.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~30 min</span><span class="applabel">Coming in an update</span></div></button></div></div>
253
+ <button class="card locked" type="button" data-k="page studio compose website landing pages funnel" data-toast="This guide arrives in a product update — your install picks it up automatically." title="Coming in a product update." aria-label="Page Studio: pages and sites. Coming in a product update."><h3>Page Studio: pages and sites</h3><p>Compose landing pages and full sites that render correctly in GHL.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~20 min</span><span class="applabel">Coming in an update</span></div></button></div></div>
254
254
  <div class="catsec" id="cat-booking-and-calendars"><h2>Booking and calendars</h2><div class="cards"><a class="card pub" href="#g-see-and-manage-appointments" data-k="appointments today schedule upcoming who is booked list no show cancel reschedule diary"><h3>See and manage appointments</h3><p>Who is booked today, this week, or for a specific client, in one ask.</p><div class="meta"><span class="pill free">Free plan</span><span class="time">~10 seconds</span><span class="open">Open guide &#8594;</span></div></a>
255
255
  <a class="card pub" href="#g-set-up-a-booking-calendar" data-k="calendar create booking consult slots availability buffer appointment types schedule daily limit notice same day"><h3>Set up a booking calendar</h3><p>A consult calendar with the right slots, buffers, and the right person attached.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~10 minutes</span><span class="open">Open guide &#8594;</span></div></a></div></div>
256
256
  <div class="catsec" id="cat-email-and-sms"><h2>Email and SMS</h2><div class="cards"><a class="card pub" href="#g-build-email-templates" data-k="email template design create campaign builder reusable branded rename archive"><h3>Build email templates</h3><p>Reusable, branded templates created and edited without the GHL editor.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~10 minutes</span><span class="open">Open guide &#8594;</span></div></a>
@@ -262,7 +262,7 @@ body.app.reading #indexview{display:none}
262
262
  <div class="catsec" id="cat-forms-and-reviews"><h2>Forms and reviews</h2><div class="cards"><a class="card pub" href="#g-create-forms-and-read-submissions" data-k="form create intake survey fields submissions responses questions who filled in"><h3>Create forms and read submissions</h3><p>Intake forms built to spec, and submissions pulled into a clean summary.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~10 minutes</span><span class="open">Open guide &#8594;</span></div></a>
263
263
  <a class="card pub" href="#g-trigger-links" data-k="trigger links tracking click automations tracked link who clicked interest"><h3>Trigger links</h3><p>Create tracked links that fire automations when clicked.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~2 minutes</span><span class="open">Open guide &#8594;</span></div></a>
264
264
  <a class="card pub" href="#g-watch-your-reviews" data-k="reviews reputation ratings google stars new review negative feedback review link"><h3>Watch your reviews</h3><p>See new reviews across clients without logging into each account.</p><div class="meta"><span class="pill free">Free plan</span><span class="time">~30 seconds</span><span class="open">Open guide &#8594;</span></div></a></div></div>
265
- <div class="catsec" id="cat-account-admin"><h2>Account admin</h2><div class="cards"><a class="card pub" href="#g-account-admin-basics" data-k="users phone numbers media export snapshot webhooks admin settings who has access compare"><h3>Account admin basics</h3><p>Users, phone numbers, media, and account exports without hunting through menus.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~1 minute</span><span class="open">Open guide &#8594;</span></div></a>
265
+ <div class="catsec" id="cat-account-admin"><h2>Account admin</h2><div class="cards"><a class="card pub" href="#g-account-admin-basics" data-k="users phone numbers media export snapshot admin settings who has access compare"><h3>Account admin basics</h3><p>Users, phone numbers, media, and account exports without hunting through menus.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~1 minute</span><span class="open">Open guide &#8594;</span></div></a>
266
266
  <a class="card pub" href="#g-custom-fields-and-objects" data-k="custom fields objects records associations create field dropdown date field niche"><h3>Custom fields and objects</h3><p>The fields and records your niche needs, created correctly the first time.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~5 minutes</span><span class="open">Open guide &#8594;</span></div></a></div></div>
267
267
  <div class="noresults" id="noresults"><p><b>No guides match that yet.</b> Try a different word, like "contacts" or "workflow".</p></div>
268
268
  </main>
@@ -817,6 +817,67 @@ Do not change any contact, and do not delete any list that is already there.</p>
817
817
  </main></div>
818
818
  </section>
819
819
 
820
+ <section class="gpage" id="g-clone-and-rebrand-a-site">
821
+ <div class="hero"><div class="hero-in">
822
+ <p class="eyebrow">GHL Command User Guide</p>
823
+ <h1>Clone and rebrand a site</h1>
824
+ <p class="sub">Rebuild an existing page for a new client, with a rights check and a review report.</p>
825
+ <div class="badges"><span class="badge on">Full license</span><span class="badge">~30 minutes</span><span class="badge">Client builds and pages</span></div>
826
+ </div></div>
827
+ <div class="shell"><main class="gview">
828
+ <a class="back" href="#top">&#8592; All guides</a>
829
+ <div class="gsec"><h2>What you'll get</h2>
830
+ <ul>
831
+ <li>A page rebuilt for your client from a page you point at, with their name, colours, contact details, and copy.</li>
832
+ <li>A rights question at the start that decides how the rebuild is done, and an honest answer either way.</li>
833
+ <li>A review report at the end listing everything that still belongs to whoever owned the original.</li>
834
+ </ul>
835
+ </div>
836
+ <div class="gsec"><h2>Say this</h2>
837
+ <div class="prompt"><q>Clone this page for my client: [paste the URL].</q><button class="copy" type="button">Copy</button></div>
838
+ <div class="prompt"><q>Rebuild this landing page for Radiance Med Spa.</q><button class="copy" type="button">Copy</button></div>
839
+ <div class="prompt"><q>What is left over from the original on this clone?</q><button class="copy" type="button">Copy</button></div>
840
+ </div>
841
+ <div class="gsec"><h2>The pro prompt</h2>
842
+ <div class="pro"><div class="pro-head"><b>The exact ask we run on real client accounts</b><span class="pill full">Proven live</span><button class="copy" type="button">Copy</button></div><p class="pro-body">Clone [https://example.com/their-landing-page] for my client [Radiance Med Spa].
843
+ My rights to that page: [I built it for a previous client of mine and reuse the layout].
844
+ Rebrand it: company name [Radiance Med Spa], phone [512-555-0100], email [hello@radiance.example], colours [deep green and cream].
845
+ Leave the page's words alone for now. I will ask for a rewrite separately.
846
+ Point the form and any booking button at my [MCP Testing] account, not at whatever it points at now.
847
+ When you are done, give me the review list of everything still belonging to the original owner: names, testimonials, photos of their people, any claim I cannot back up, and anywhere a lead or a payment would still go to them.</p></div>
848
+ <p class="gpara">Everything in [brackets] is yours to change. Answer the rights question honestly. It changes what gets built, and getting it wrong is your problem, not the tool's.</p>
849
+ </div>
850
+ <div class="gsec"><h2>What happens when you ask</h2>
851
+ <ol class="steps">
852
+ <li>Claude asks what rights you have to the page, and records your answer.</li>
853
+ <li>With rights, it makes a faithful rebuild. Without them, it takes the design system, meaning the layout logic, spacing, and type scale, and builds a fresh page on it instead of copying the original.</li>
854
+ <li>It swaps in your client's brand: name, contact details, colours. It does NOT rewrite the page's words.</li>
855
+ <li>It hands you a review list: everything it found that still belongs to the original owner and everything it could not be sure about.</li>
856
+ </ol>
857
+ </div>
858
+ <div class="gsec"><h2>Good to know</h2>
859
+ <ul>
860
+ <li><b>Changing the colours is riskier than it sounds.</b> A palette is a set of relationships, not a list of hex codes. Swap a dark background for a light one and text that was white for the dark background is now white on light, and invisible. Nothing checks this for you. After any colour change, look at the page before you show anyone.</li>
861
+ <li><b>A clone copies. It does not rewrite.</b> When it finishes, the layout and brand are your client's and every word is still the original's, so the page still reads as the other business. Rewriting is a second ask, on purpose: a clone that paraphrases as it copies is the one that comes back &quot;not even close&quot;.</li>
862
+ <li>Read the review list. It exists because some things cannot be caught by find and replace: a brand name split across styled text, a logo inside an image, branding baked into a booking widget, another business's testimonials.</li>
863
+ <li>Lead and payment destinations are the dangerous ones. A cloned page that still posts leads to the original owner is worse than no page.</li>
864
+ <li>Regulated claims travel with the copy. If the original made a medical or income claim, it is now on your client's page and it is now your client's liability.</li>
865
+ <li>Needs the full license.</li>
866
+ </ul>
867
+ </div>
868
+ <div class="gsec"><h2>Where people go wrong</h2>
869
+ <div style="overflow-x:auto"><table class="wrongtbl"><tr><th>What happened</th><th>The fix</th></tr><tr><td>&quot;The clone still has the other company's name in one spot.&quot;</td><td>That is what the review list catches, usually a name split across styled text. Fix the items it names before you show the client.</td></tr><tr><td>&quot;A booking button still goes to the original business.&quot;</td><td>Say which account and which calendar the buttons should point at, in the ask. Then check every button on the live page.</td></tr><tr><td>&quot;The new colours made half the page unreadable.&quot;</td><td>Text colours were not swapped alongside the backgrounds they sit on. Caught live: a navy-to-cream background left white headings invisible. Change colours only if you will check the result by eye, or leave them alone and clone exactly.</td></tr><tr><td>&quot;The header still showed the old brand after a clean replace.&quot;</td><td>A two-tone brand mark is split across markup, so no find-and-replace can reach it. It is caught and listed for a hand edit. The proving run had exactly two.</td></tr><tr><td>&quot;The logo still says the other company.&quot;</td><td>The brand is inside the image file. Pixels cannot be substituted; the review list names the files so you can swap the artwork.</td></tr><tr><td>&quot;It refused to make an exact copy.&quot;</td><td>You said you have no rights to the page. That answer routes you to a rebuild on the design system instead, which is the version you can actually ship.</td></tr></table></div>
870
+ </div>
871
+ <div class="gsec"><h2>Related guides</h2>
872
+ <ul>
873
+ <li>page-studio-pages-and-sites</li>
874
+ <li>create-forms-and-read-submissions</li>
875
+ </ul>
876
+ </div>
877
+ <p class="gfoot">Works in Claude Desktop and Claude Code. Stuck? Email support@ghlcommand.com and a human answers.</p>
878
+ </main></div>
879
+ </section>
880
+
820
881
  <section class="gpage" id="g-count-and-report-contacts">
821
882
  <div class="hero"><div class="hero-in">
822
883
  <p class="eyebrow">GHL Command User Guide</p>
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@elitedcs/ghl-mcp",
3
- "version": "3.66.0",
3
+ "version": "3.66.2",
4
4
  "mcpName": "io.github.drjerryrelth/ghl-command",
5
- "description": "GoHighLevel MCP Server for Claude. 238 tools \u2014 full CRM, automation, marketing control, account-wide workflow audit, live funnel-capture verification, and the only programmatic GHL workflow builder, now multi-tenant across client accounts.",
5
+ "description": "GoHighLevel MCP Server for Claude. 239 tools \u2014 full CRM, automation, marketing control, account-wide workflow audit, live funnel-capture verification, and the only programmatic GHL workflow builder, now multi-tenant across client accounts.",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
8
  "ghl-mcp": "dist/index.js"