@elitedcs/ghl-mcp 3.63.0 → 3.64.0
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 +29 -0
- package/dist/index.js +103 -70
- package/guide/guide.html +212 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.64.0 — four silent failures fixed, four more guides open
|
|
4
|
+
|
|
5
|
+
Every fix here is the same shape: a call that succeeded, returned
|
|
6
|
+
plausible-looking data, and was wrong. None of them raised an error, so none of
|
|
7
|
+
them were visible until a guide was written against them and run for real.
|
|
8
|
+
|
|
9
|
+
- **Fix: comparing two sub-accounts reported the other one as empty.** A
|
|
10
|
+
Private Integration key only works on the sub-account it was created in, so
|
|
11
|
+
reading a second account returned 403 — which `compare_locations` caught,
|
|
12
|
+
stored as null, and counted as zero. Comparing a client account against your
|
|
13
|
+
template answered "nothing is missing". It now uses each account's own saved
|
|
14
|
+
key (the same registry `switch_location` uses), reports a section it genuinely
|
|
15
|
+
cannot read as "unavailable" rather than as zero, and returns the NAMES
|
|
16
|
+
present in one account and missing from the other — which it always claimed to
|
|
17
|
+
do but never did. Live-proven: a template that read as "0 pipelines,
|
|
18
|
+
0 workflows, 0 tags" actually holds 8, 12 and 11.
|
|
19
|
+
- **Fix: filtering reviews by star rating did nothing.** The filter used a field
|
|
20
|
+
name GoHighLevel does not have, and an unknown filter field is dropped
|
|
21
|
+
silently, so asking for five-star reviews returned two-star ones. Correct
|
|
22
|
+
field and range form captured from GoHighLevel's own reputation filter.
|
|
23
|
+
Adds `minRating`/`maxRating`, so "every review under four stars" now works.
|
|
24
|
+
- **Fix: `get_users` advertised `limit` and `skip`.** GoHighLevel rejects both
|
|
25
|
+
outright. Anyone who used them got an error instead of users. Removed; the
|
|
26
|
+
endpoint returns every user in one response.
|
|
27
|
+
- Four more guides open in the library, each proven against a real account
|
|
28
|
+
before shipping: see and manage appointments, create forms and read
|
|
29
|
+
submissions, watch your reviews, account admin basics. 24 open, 6 still
|
|
30
|
+
being written.
|
|
31
|
+
|
|
3
32
|
## 3.63.0 — the guide library grows from 3 guides to 20
|
|
4
33
|
|
|
5
34
|
- **`get_user_guide` now opens a 20-guide library.** Seventeen guides were
|
package/dist/index.js
CHANGED
|
@@ -2854,7 +2854,7 @@ var require_package = __commonJS({
|
|
|
2854
2854
|
"package.json"(exports2, module2) {
|
|
2855
2855
|
module2.exports = {
|
|
2856
2856
|
name: "@elitedcs/ghl-mcp",
|
|
2857
|
-
version: "3.
|
|
2857
|
+
version: "3.64.0",
|
|
2858
2858
|
mcpName: "io.github.drjerryrelth/ghl-command",
|
|
2859
2859
|
description: "GoHighLevel MCP Server for Claude. 235 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",
|
|
@@ -8832,18 +8832,17 @@ function registerUserTools(server2, client) {
|
|
|
8832
8832
|
safeTool(
|
|
8833
8833
|
server2,
|
|
8834
8834
|
"get_users",
|
|
8835
|
-
"List
|
|
8835
|
+
"List every user on a location, with their role and permissions. Returns them all in one response \u2014 GHL's users endpoint takes no paging parameters.",
|
|
8836
8836
|
{
|
|
8837
|
-
locationId: import_zod22.z.string().optional().describe("GHL Location ID (optional if GHL_LOCATION_ID is set)")
|
|
8838
|
-
limit: import_zod22.z.number().optional().describe("Max number of users to return"),
|
|
8839
|
-
skip: import_zod22.z.number().optional().describe("Number of users to skip")
|
|
8837
|
+
locationId: import_zod22.z.string().optional().describe("GHL Location ID (optional if GHL_LOCATION_ID is set)")
|
|
8840
8838
|
},
|
|
8841
|
-
|
|
8839
|
+
// No limit/skip: GHL rejects them outright with 422 "property limit should
|
|
8840
|
+
// not exist". They were advertised on this tool for months, so anyone who
|
|
8841
|
+
// took the schema at its word got an error instead of a page of users
|
|
8842
|
+
// (live-verified 2026-08-08).
|
|
8843
|
+
async ({ locationId: locationId2 }) => {
|
|
8842
8844
|
const resolvedLocationId = client.resolveLocationId(locationId2);
|
|
8843
|
-
|
|
8844
|
-
if (limit !== void 0) params.limit = limit;
|
|
8845
|
-
if (skip !== void 0) params.skip = skip;
|
|
8846
|
-
return client.get("/users/", { params });
|
|
8845
|
+
return client.get("/users/", { params: { locationId: resolvedLocationId } });
|
|
8847
8846
|
}
|
|
8848
8847
|
);
|
|
8849
8848
|
safeTool(
|
|
@@ -13338,7 +13337,7 @@ var import_zod46 = require("zod");
|
|
|
13338
13337
|
function delay2(ms) {
|
|
13339
13338
|
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
13340
13339
|
}
|
|
13341
|
-
function registerAccountExportTools(server2, client) {
|
|
13340
|
+
function registerAccountExportTools(server2, client, registry2) {
|
|
13342
13341
|
const builderClient = WorkflowBuilderClient.fromEnv();
|
|
13343
13342
|
server2.tool(
|
|
13344
13343
|
"export_account",
|
|
@@ -13471,7 +13470,7 @@ function registerAccountExportTools(server2, client) {
|
|
|
13471
13470
|
);
|
|
13472
13471
|
server2.tool(
|
|
13473
13472
|
"compare_locations",
|
|
13474
|
-
"Compare two GHL sub-accounts side by side
|
|
13473
|
+
"Compare two GHL sub-accounts side by side. For pipelines, workflows, custom fields, tags and forms it returns the count on each side plus the NAMES present in one account and missing from the other, so a setup gap reads directly. If a section cannot be read (commonly the API key has no access to the second location), that section is reported as unavailable with the reason \u2014 never as a count of zero.",
|
|
13475
13474
|
{
|
|
13476
13475
|
locationA: import_zod46.z.string().describe("First Location ID."),
|
|
13477
13476
|
locationB: import_zod46.z.string().describe("Second Location ID.")
|
|
@@ -13483,66 +13482,57 @@ function registerAccountExportTools(server2, client) {
|
|
|
13483
13482
|
locationA,
|
|
13484
13483
|
locationB
|
|
13485
13484
|
};
|
|
13486
|
-
const
|
|
13487
|
-
|
|
13485
|
+
const SECTIONS = ["pipelines", "workflows", "customFields", "tags", "forms"];
|
|
13486
|
+
const namesFrom = (payload) => {
|
|
13487
|
+
const list = Array.isArray(payload) ? payload : payload && typeof payload === "object" ? Object.values(payload).find(Array.isArray) : void 0;
|
|
13488
|
+
if (!Array.isArray(list)) return [];
|
|
13489
|
+
return list.map(
|
|
13490
|
+
(item) => item && typeof item === "object" ? String(item.name ?? item.id ?? "") : String(item)
|
|
13491
|
+
).filter(Boolean);
|
|
13492
|
+
};
|
|
13493
|
+
const read = async (fn) => {
|
|
13488
13494
|
try {
|
|
13489
|
-
|
|
13490
|
-
} catch {
|
|
13491
|
-
|
|
13495
|
+
return { names: namesFrom(await fn()) };
|
|
13496
|
+
} catch (err) {
|
|
13497
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
13492
13498
|
}
|
|
13499
|
+
};
|
|
13500
|
+
const fetchData = async (locId) => {
|
|
13501
|
+
const data = {};
|
|
13502
|
+
data.pipelines = await read(() => client.get("/opportunities/pipelines", { params: { locationId: locId } }));
|
|
13493
13503
|
await delay2(100);
|
|
13494
|
-
|
|
13495
|
-
data.pipelines = await client.get("/opportunities/pipelines", { params: { locationId: locId } });
|
|
13496
|
-
} catch {
|
|
13497
|
-
data.pipelines = null;
|
|
13498
|
-
}
|
|
13504
|
+
data.workflows = await read(() => client.get("/workflows/", { params: { locationId: locId } }));
|
|
13499
13505
|
await delay2(100);
|
|
13500
|
-
|
|
13501
|
-
data.workflows = await client.get("/workflows/", { params: { locationId: locId } });
|
|
13502
|
-
} catch {
|
|
13503
|
-
data.workflows = null;
|
|
13504
|
-
}
|
|
13506
|
+
data.customFields = await read(() => client.get(`/locations/${locId}/customFields`));
|
|
13505
13507
|
await delay2(100);
|
|
13506
|
-
|
|
13507
|
-
data.customFields = await client.get("/locations/" + locId + "/customFields");
|
|
13508
|
-
} catch {
|
|
13509
|
-
data.customFields = null;
|
|
13510
|
-
}
|
|
13508
|
+
data.tags = await read(() => client.get(`/locations/${locId}/tags`));
|
|
13511
13509
|
await delay2(100);
|
|
13512
|
-
|
|
13513
|
-
data.tags = await client.get("/locations/" + locId + "/tags");
|
|
13514
|
-
} catch {
|
|
13515
|
-
data.tags = null;
|
|
13516
|
-
}
|
|
13517
|
-
await delay2(100);
|
|
13518
|
-
try {
|
|
13519
|
-
data.forms = await client.get("/forms/", { params: { locationId: locId } });
|
|
13520
|
-
} catch {
|
|
13521
|
-
data.forms = null;
|
|
13522
|
-
}
|
|
13510
|
+
data.forms = await read(() => client.get("/forms/", { params: { locationId: locId } }));
|
|
13523
13511
|
return data;
|
|
13524
13512
|
};
|
|
13525
|
-
const
|
|
13526
|
-
const
|
|
13527
|
-
|
|
13528
|
-
const
|
|
13529
|
-
if (
|
|
13530
|
-
|
|
13531
|
-
|
|
13532
|
-
|
|
13533
|
-
|
|
13513
|
+
const originalKey = client.getApiKey();
|
|
13514
|
+
const usedRegisteredKey = [];
|
|
13515
|
+
const fetchWithOwnKey = async (locId) => {
|
|
13516
|
+
const token = registry2?.getToken(locId);
|
|
13517
|
+
if (token?.apiKey && token.apiKey !== originalKey) {
|
|
13518
|
+
client.setApiKey(token.apiKey);
|
|
13519
|
+
usedRegisteredKey.push(locId);
|
|
13520
|
+
}
|
|
13521
|
+
try {
|
|
13522
|
+
return await fetchData(locId);
|
|
13523
|
+
} finally {
|
|
13524
|
+
client.setApiKey(originalKey);
|
|
13534
13525
|
}
|
|
13535
|
-
return "?";
|
|
13536
|
-
};
|
|
13537
|
-
diff.comparison = {
|
|
13538
|
-
pipelines: { A: count(dataA, "pipelines"), B: count(dataB, "pipelines") },
|
|
13539
|
-
workflows: { A: count(dataA, "workflows"), B: count(dataB, "workflows") },
|
|
13540
|
-
customFields: { A: count(dataA, "customFields"), B: count(dataB, "customFields") },
|
|
13541
|
-
tags: { A: count(dataA, "tags"), B: count(dataB, "tags") },
|
|
13542
|
-
forms: { A: count(dataA, "forms"), B: count(dataB, "forms") }
|
|
13543
13526
|
};
|
|
13544
|
-
|
|
13545
|
-
|
|
13527
|
+
const dataA = await fetchWithOwnKey(locationA);
|
|
13528
|
+
const dataB = await fetchWithOwnKey(locationB);
|
|
13529
|
+
const { comparison, unavailable } = buildLocationComparison(dataA, dataB, SECTIONS);
|
|
13530
|
+
diff.comparison = comparison;
|
|
13531
|
+
if (usedRegisteredKey.length) diff.usedRegisteredKeyFor = usedRegisteredKey;
|
|
13532
|
+
if (unavailable.length) {
|
|
13533
|
+
diff.unavailable = unavailable;
|
|
13534
|
+
diff.warning = "Some sections could not be read. Those sections are marked unavailable \u2014 do NOT read them as empty. A Private Integration key only works on the sub-account it was created in, so register each account's own key (register_location) before comparing them.";
|
|
13535
|
+
}
|
|
13546
13536
|
return jsonResponse(diff);
|
|
13547
13537
|
} catch (error) {
|
|
13548
13538
|
return errorResponse(error);
|
|
@@ -13550,6 +13540,35 @@ function registerAccountExportTools(server2, client) {
|
|
|
13550
13540
|
}
|
|
13551
13541
|
);
|
|
13552
13542
|
}
|
|
13543
|
+
function buildLocationComparison(dataA, dataB, sections) {
|
|
13544
|
+
const unavailable = [];
|
|
13545
|
+
const comparison = {};
|
|
13546
|
+
for (const key of sections) {
|
|
13547
|
+
const a = dataA[key] ?? { error: "not read" };
|
|
13548
|
+
const b = dataB[key] ?? { error: "not read" };
|
|
13549
|
+
if ("error" in a) unavailable.push(`locationA.${key}: ${a.error}`);
|
|
13550
|
+
if ("error" in b) unavailable.push(`locationB.${key}: ${b.error}`);
|
|
13551
|
+
if ("error" in a || "error" in b) {
|
|
13552
|
+
comparison[key] = {
|
|
13553
|
+
A: "error" in a ? "unavailable" : a.names.length,
|
|
13554
|
+
B: "error" in b ? "unavailable" : b.names.length,
|
|
13555
|
+
comparable: false,
|
|
13556
|
+
note: "One side could not be read, so no gap can be reported for this section."
|
|
13557
|
+
};
|
|
13558
|
+
continue;
|
|
13559
|
+
}
|
|
13560
|
+
const setA = new Set(a.names);
|
|
13561
|
+
const setB = new Set(b.names);
|
|
13562
|
+
comparison[key] = {
|
|
13563
|
+
A: a.names.length,
|
|
13564
|
+
B: b.names.length,
|
|
13565
|
+
comparable: true,
|
|
13566
|
+
onlyInA: a.names.filter((n) => !setB.has(n)),
|
|
13567
|
+
onlyInB: b.names.filter((n) => !setA.has(n))
|
|
13568
|
+
};
|
|
13569
|
+
}
|
|
13570
|
+
return { comparison, unavailable };
|
|
13571
|
+
}
|
|
13553
13572
|
|
|
13554
13573
|
// src/tools/workflow-cloner.ts
|
|
13555
13574
|
var import_zod47 = require("zod");
|
|
@@ -13826,17 +13845,22 @@ ${text2}`);
|
|
|
13826
13845
|
safeTool(
|
|
13827
13846
|
server2,
|
|
13828
13847
|
"list_reviews",
|
|
13829
|
-
"List the reviews a location has received (Google, Facebook, etc.) with rating, author, text, reply status, and source.
|
|
13848
|
+
"List the reviews a location has received (Google, Facebook, etc.) with rating, author, text, reply status, sentiment score, and source. Filter by an exact star rating or a range \u2014 'everything under 4 stars' is minRating 1 + maxRating 3. NOTE: location is resolved through nested filter params internally \u2014 a flat locationId is what caused the long-standing 'No Location Found' error, now fixed. Responding to a review is not yet available via API. Requires Firebase auth.",
|
|
13830
13849
|
{
|
|
13831
13850
|
locationId: import_zod49.z.string().optional().describe("Location ID. Falls back to the active builder client's location."),
|
|
13832
13851
|
pageNumber: import_zod49.z.number().optional().describe("1-based page number. Defaults to 1."),
|
|
13833
13852
|
pageSize: import_zod49.z.number().optional().describe("Results per page. Defaults to 10."),
|
|
13834
|
-
rating: import_zod49.z.number().optional().describe("
|
|
13853
|
+
rating: import_zod49.z.number().min(1).max(5).optional().describe("Exact star rating (1-5). Takes precedence over minRating/maxRating."),
|
|
13854
|
+
minRating: import_zod49.z.number().min(1).max(5).optional().describe("Lowest star rating to include (1-5), inclusive."),
|
|
13855
|
+
maxRating: import_zod49.z.number().min(1).max(5).optional().describe("Highest star rating to include (1-5), inclusive. For 'under 4 stars', pass 3."),
|
|
13835
13856
|
includeDeleted: import_zod49.z.boolean().optional().describe("Include deleted reviews. Defaults to false.")
|
|
13836
13857
|
},
|
|
13837
|
-
async ({ locationId: locationId2, pageNumber, pageSize, rating, includeDeleted }) => {
|
|
13858
|
+
async ({ locationId: locationId2, pageNumber, pageSize, rating, minRating, maxRating, includeDeleted }) => {
|
|
13838
13859
|
const loc = locationId2 ?? client.locationId;
|
|
13839
|
-
return reputationRequest(
|
|
13860
|
+
return reputationRequest(
|
|
13861
|
+
"GET",
|
|
13862
|
+
buildReviewsQuery(loc, { pageNumber, pageSize, rating, minRating, maxRating, includeDeleted })
|
|
13863
|
+
);
|
|
13840
13864
|
}
|
|
13841
13865
|
);
|
|
13842
13866
|
}
|
|
@@ -13847,10 +13871,17 @@ function buildReviewsQuery(locationId2, opts = {}) {
|
|
|
13847
13871
|
`filterParams[deleted][0][value]=${opts.includeDeleted ? "true" : "false"}`,
|
|
13848
13872
|
`filterParams[deleted][0][condition]=eq`
|
|
13849
13873
|
];
|
|
13874
|
+
const bounds = [];
|
|
13850
13875
|
if (opts.rating !== void 0) {
|
|
13851
|
-
|
|
13852
|
-
|
|
13876
|
+
bounds.push([opts.rating, "gte"], [opts.rating, "lte"]);
|
|
13877
|
+
} else {
|
|
13878
|
+
if (opts.minRating !== void 0) bounds.push([opts.minRating, "gte"]);
|
|
13879
|
+
if (opts.maxRating !== void 0) bounds.push([opts.maxRating, "lte"]);
|
|
13853
13880
|
}
|
|
13881
|
+
bounds.forEach(([value, condition], i) => {
|
|
13882
|
+
q2.push(`filterParams[starRating][${i}][value]=${value}`);
|
|
13883
|
+
q2.push(`filterParams[starRating][${i}][condition]=${condition}`);
|
|
13884
|
+
});
|
|
13854
13885
|
q2.push(`sortParams[dateAdded]=-1`);
|
|
13855
13886
|
q2.push(`pageNumber=${opts.pageNumber ?? 1}`);
|
|
13856
13887
|
q2.push(`pageSize=${opts.pageSize ?? 10}`);
|
|
@@ -18732,7 +18763,6 @@ var publicApiTools = [
|
|
|
18732
18763
|
[registerWebhookTools, "webhooks"],
|
|
18733
18764
|
[registerDocumentTools, "documents"],
|
|
18734
18765
|
[registerBulkOperationTools, "bulk-operations"],
|
|
18735
|
-
[registerAccountExportTools, "account-export"],
|
|
18736
18766
|
[registerTemplateDeployerTools, "template-deployer"],
|
|
18737
18767
|
[registerPhoneTools, "phone"],
|
|
18738
18768
|
[registerAccountHealthTools, "account-health"]
|
|
@@ -18753,6 +18783,7 @@ var VALIDATORS_MODULE = "validators";
|
|
|
18753
18783
|
var DIAGNOSTICS_MODULE = "diagnostics";
|
|
18754
18784
|
var LOCATION_SWITCHER_MODULE = "location-switcher";
|
|
18755
18785
|
var SNAPSHOTS_MODULE = "snapshots";
|
|
18786
|
+
var ACCOUNT_EXPORT_MODULE = "account-export";
|
|
18756
18787
|
var FORM_BUILDER_MODULE = "form-builder";
|
|
18757
18788
|
var INTAKE_TO_BUILD_MODULE = "intake-to-build";
|
|
18758
18789
|
var FUNNEL_QA_MODULE = "funnel-qa";
|
|
@@ -18767,7 +18798,8 @@ var KNOWN_MODULES = /* @__PURE__ */ new Set([
|
|
|
18767
18798
|
VALIDATORS_MODULE,
|
|
18768
18799
|
DIAGNOSTICS_MODULE,
|
|
18769
18800
|
LOCATION_SWITCHER_MODULE,
|
|
18770
|
-
SNAPSHOTS_MODULE
|
|
18801
|
+
SNAPSHOTS_MODULE,
|
|
18802
|
+
ACCOUNT_EXPORT_MODULE
|
|
18771
18803
|
]);
|
|
18772
18804
|
function registerAllTools(server2, client, registry2, mcpVersion, env = process.env, tier = "full", outOfBand) {
|
|
18773
18805
|
const config3 = parseAllowlist(env);
|
|
@@ -18796,6 +18828,7 @@ function registerAllTools(server2, client, registry2, mcpVersion, env = process.
|
|
|
18796
18828
|
() => buildGatingReport(config3, KNOWN_MODULES, attemptedTools, registeredTools, outOfBand)
|
|
18797
18829
|
);
|
|
18798
18830
|
registerSnapshotTools(wrap(SNAPSHOTS_MODULE), client, registry2);
|
|
18831
|
+
registerAccountExportTools(wrap(ACCOUNT_EXPORT_MODULE), client, registry2);
|
|
18799
18832
|
registerLocationSwitcherTools(
|
|
18800
18833
|
wrap(LOCATION_SWITCHER_MODULE),
|
|
18801
18834
|
client,
|
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:
|
|
7
|
+
<!-- guides-hash: 6ffc57aa1224244f -->
|
|
8
8
|
<style>
|
|
9
9
|
:root{
|
|
10
10
|
--bg:#F2F4F6; --surface:#FFFFFF; --ink:#1C2833; --muted:#5B6B78; --line:#DDE3E8;
|
|
@@ -188,21 +188,73 @@ main{max-width:1180px}
|
|
|
188
188
|
<div class="catsec"><h2>Client builds and pages</h2><div class="cards"><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>
|
|
189
189
|
<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>
|
|
190
190
|
<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>
|
|
191
|
-
<div class="catsec"><h2>Booking and calendars</h2><div class="cards"><a class="card pub" href="#g-
|
|
192
|
-
<
|
|
191
|
+
<div class="catsec"><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">Read below ↓</span></div></a>
|
|
192
|
+
<a class="card pub" href="#g-set-up-a-booking-calendar" data-k="calendar create booking consult slots availability buffer appointment types schedule"><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">Read below ↓</span></div></a></div></div>
|
|
193
193
|
<div class="catsec"><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">Read below ↓</span></div></a>
|
|
194
194
|
<a class="card pub" href="#g-review-your-conversations" data-k="conversations inbox read unread replies check messages who replied catch up missed"><h3>Review your conversations</h3><p>Catch up on replies and unread threads across every channel.</p><div class="meta"><span class="pill free">Free plan</span><span class="time">~1 minute</span><span class="open">Read below ↓</span></div></a>
|
|
195
195
|
<a class="card pub" href="#g-send-texts-and-emails" data-k="send message text sms email contact reply conversation follow up one off"><h3>Send texts and emails</h3><p>Message any contact from Claude, in your voice, on the right channel.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~30 seconds</span><span class="open">Read below ↓</span></div></a></div></div>
|
|
196
196
|
<div class="catsec"><h2>Content and social</h2><div class="cards"><a class="card pub" href="#g-social-posting" data-k="social posts schedule planner facebook instagram linkedin queue draft content calendar"><h3>Plan social posts</h3><p>Queue posts as drafts across your connected social accounts, ready for you to publish.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~5 minutes</span><span class="open">Read below ↓</span></div></a>
|
|
197
197
|
<button class="card locked" type="button" data-k="blog posts publish draft seo articles slug" data-toast="This guide arrives in a product update — your install picks it up automatically." title="Coming in a product update." aria-label="Plan and check blog posts. Coming in a product update."><h3>Plan and check blog posts</h3><p>See what is published, check a web address is free, and get the next post written ready to paste.</p><div class="meta"><span class="pill full">Full license</span><span class="time">~10 min</span><span class="applabel">Coming in an update</span></div></button>
|
|
198
198
|
<button class="card locked" type="button" data-k="courses memberships lessons offers community" data-toast="This guide arrives in a product update — your install picks it up automatically." title="Coming in a product update." aria-label="Courses and memberships. Coming in a product update."><h3>Courses and memberships</h3><p>Course outlines, lessons, and offers built in your membership area.</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>
|
|
199
|
-
<div class="catsec"><h2>Forms and reviews</h2><div class="cards"><a class="card pub" href="#g-
|
|
200
|
-
<
|
|
201
|
-
<
|
|
202
|
-
<div class="catsec"><h2>Account admin</h2><div class="cards"><a class="card pub" href="#g-
|
|
203
|
-
<
|
|
199
|
+
<div class="catsec"><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">Read below ↓</span></div></a>
|
|
200
|
+
<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">Read below ↓</span></div></a>
|
|
201
|
+
<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">Read below ↓</span></div></a></div></div>
|
|
202
|
+
<div class="catsec"><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">Read below ↓</span></div></a>
|
|
203
|
+
<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">Read below ↓</span></div></a></div></div>
|
|
204
204
|
<div class="noresults" id="noresults"><p><b>No guides match that yet.</b> Try a different word, like "contacts" or "workflow".</p></div>
|
|
205
205
|
|
|
206
|
+
<section class="gview" id="g-account-admin-basics">
|
|
207
|
+
<h1 class="gtitle serif">Account admin basics</h1>
|
|
208
|
+
<p class="gpromise">Users, phone numbers, media, and account exports without hunting through menus.</p>
|
|
209
|
+
<div class="gmeta"><span class="pill full">Full license</span><span class="time">~1 minute</span><span class="time">Works in Claude Desktop and Claude Code</span></div>
|
|
210
|
+
<div class="gsec"><h2>What you'll get</h2>
|
|
211
|
+
<ul>
|
|
212
|
+
<li>Who has access to an account, with their role, in one ask.</li>
|
|
213
|
+
<li>The account's phone numbers, media library, and connected pieces, read without clicking through five settings screens.</li>
|
|
214
|
+
<li>A full written export of what an account contains, and a straight comparison between two accounts.</li>
|
|
215
|
+
</ul>
|
|
216
|
+
</div>
|
|
217
|
+
<div class="gsec"><h2>Say this</h2>
|
|
218
|
+
<div class="prompt"><q>Who has access to this account?</q><button class="copy" type="button">Copy</button></div>
|
|
219
|
+
<div class="prompt"><q>What phone numbers does this account have?</q><button class="copy" type="button">Copy</button></div>
|
|
220
|
+
<div class="prompt"><q>Export everything in this account so I can see what is in it.</q><button class="copy" type="button">Copy</button></div>
|
|
221
|
+
<div class="prompt"><q>Compare this account to my template account and tell me what is missing.</q><button class="copy" type="button">Copy</button></div>
|
|
222
|
+
</div>
|
|
223
|
+
<div class="gsec"><h2>The pro prompt</h2>
|
|
224
|
+
<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">Give me an inventory of my [MCP Testing] account.
|
|
225
|
+
I want: every user with their role, every phone number, how many files are in the media library, and which pipelines, calendars, forms, and workflows exist by name.
|
|
226
|
+
Then compare it to my [template] account and tell me what the first account is missing that the second one has.
|
|
227
|
+
Do not change anything. This is a read.</p></div>
|
|
228
|
+
<p class="gpara">Everything in [brackets] is yours to change. Run this the day you take over a client account. It is the fastest honest picture of what you have inherited.</p>
|
|
229
|
+
</div>
|
|
230
|
+
<div class="gsec"><h2>What happens when you ask</h2>
|
|
231
|
+
<ol class="steps">
|
|
232
|
+
<li>Claude reads the account across users, phone numbers, media, and the objects that matter.</li>
|
|
233
|
+
<li>It lists what exists by name rather than by ID, so you can read it.</li>
|
|
234
|
+
<li>Compared against another account, it names the gaps in both directions.</li>
|
|
235
|
+
</ol>
|
|
236
|
+
</div>
|
|
237
|
+
<div class="gsec"><h2>Good to know</h2>
|
|
238
|
+
<ul>
|
|
239
|
+
<li>The comparison is the useful one. Line a new client's account up against your template account and the setup list writes itself.</li>
|
|
240
|
+
<li>User roles matter for workflow notifications. A notification pointed at somebody who has left the business fails silently, and this is where you spot them.</li>
|
|
241
|
+
<li>Snapshots are how you carry a whole account setup to a new client. Claude can list what you have and create a share link for one.</li>
|
|
242
|
+
<li>Creating and deleting sub-accounts is switched off by default, on purpose. It stays off unless you deliberately turn it on.</li>
|
|
243
|
+
<li>Needs the full license. Reading users and numbers is free.</li>
|
|
244
|
+
</ul>
|
|
245
|
+
</div>
|
|
246
|
+
<div class="gsec"><h2>Where people go wrong</h2>
|
|
247
|
+
<div style="overflow-x:auto"><table class="wrongtbl"><tr><th>What happened</th><th>The fix</th></tr><tr><td>"Workflow notifications go to nobody."</td><td>They point at a user who has gone. List the users, then ask Claude to repoint the notification.</td></tr><tr><td>"Texts fail on a new client account."</td><td>The account has no number, or is not registered for texting yet. The number list shows you in seconds.</td></tr><tr><td>"The export is huge."</td><td>Ask for the part you care about: "just the workflows and pipelines by name".</td></tr><tr><td>"The comparison says the other account is empty."</td><td>Each account's key only works on that account, so the other one could not be read at all. Save its key once and compare again. Claude now says "unavailable" rather than showing zeros, so you can tell the two apart.</td></tr></table></div>
|
|
248
|
+
</div>
|
|
249
|
+
<div class="gsec"><h2>Related guides</h2>
|
|
250
|
+
<ul>
|
|
251
|
+
<li>switch-between-client-accounts</li>
|
|
252
|
+
<li>audit-your-workflows</li>
|
|
253
|
+
</ul>
|
|
254
|
+
</div>
|
|
255
|
+
<p class="gfoot"><a class="back" href="#top">↑ All guides</a> · Stuck? Email support@ghlcommand.com and a human answers.</p>
|
|
256
|
+
</section>
|
|
257
|
+
|
|
206
258
|
<section class="gview" id="g-add-an-exit-workflow">
|
|
207
259
|
<h1 class="gtitle serif">Add an exit workflow</h1>
|
|
208
260
|
<p class="gpromise">Cleanly pull people out of a sequence when they reply, tag them, and get you notified.</p>
|
|
@@ -597,6 +649,55 @@ Do not delete anything, do not send anything, and do not change any other field.
|
|
|
597
649
|
<p class="gfoot"><a class="back" href="#top">↑ All guides</a> · Stuck? Email support@ghlcommand.com and a human answers.</p>
|
|
598
650
|
</section>
|
|
599
651
|
|
|
652
|
+
<section class="gview" id="g-create-forms-and-read-submissions">
|
|
653
|
+
<h1 class="gtitle serif">Create forms and read submissions</h1>
|
|
654
|
+
<p class="gpromise">Intake forms built to spec, and submissions pulled into a clean summary.</p>
|
|
655
|
+
<div class="gmeta"><span class="pill full">Full license</span><span class="time">~10 minutes</span><span class="time">Works in Claude Desktop and Claude Code</span></div>
|
|
656
|
+
<div class="gsec"><h2>What you'll get</h2>
|
|
657
|
+
<ul>
|
|
658
|
+
<li>An intake form built with the exact questions you want, saved in the account and ready to attach to a page.</li>
|
|
659
|
+
<li>Answers that land on the contact record instead of in a text box nobody can filter, because the questions are wired to real fields.</li>
|
|
660
|
+
<li>The submissions read back to you as a summary rather than a list you have to click through.</li>
|
|
661
|
+
</ul>
|
|
662
|
+
</div>
|
|
663
|
+
<div class="gsec"><h2>Say this</h2>
|
|
664
|
+
<div class="prompt"><q>Build a consult intake form: name, email, phone, treatment interest, and best time to call.</q><button class="copy" type="button">Copy</button></div>
|
|
665
|
+
<div class="prompt"><q>Show me this week's submissions for the consult form.</q><button class="copy" type="button">Copy</button></div>
|
|
666
|
+
<div class="prompt"><q>Add a question to the intake form about how they heard about us.</q><button class="copy" type="button">Copy</button></div>
|
|
667
|
+
</div>
|
|
668
|
+
<div class="gsec"><h2>The pro prompt</h2>
|
|
669
|
+
<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">In my [MCP Testing] account, create a form called "[Consult Intake]" with these questions in order: [first name, last name, email, phone, which treatment are you interested in (choose one: body contouring, injectables, skin, not sure), what is your goal in your own words, best time to reach you (morning, afternoon, evening)].
|
|
670
|
+
Wire [treatment interest] and [best time to reach you] to real custom fields on the contact record so I can filter on them later. Create those fields if they do not exist yet.
|
|
671
|
+
When it saves, read the form back to me question by question, and tell me exactly where in GHL I will find it.</p></div>
|
|
672
|
+
<p class="gpara">Everything in [brackets] is yours to change. The wiring line is the one that matters. Answers that only live inside a submission are almost useless later; answers on the contact record drive your automations.</p>
|
|
673
|
+
</div>
|
|
674
|
+
<div class="gsec"><h2>What happens when you ask</h2>
|
|
675
|
+
<ol class="steps">
|
|
676
|
+
<li>Claude checks which custom fields exist and creates the missing ones.</li>
|
|
677
|
+
<li>It builds the form with your questions in order and the right answer types.</li>
|
|
678
|
+
<li>It reads the form back question by question so you can check it before you put it in front of anybody.</li>
|
|
679
|
+
</ol>
|
|
680
|
+
</div>
|
|
681
|
+
<div class="gsec"><h2>Good to know</h2>
|
|
682
|
+
<ul>
|
|
683
|
+
<li>Fewer questions convert better. Name, contact detail, and one qualifying question will out-perform your ten-question dream form every time.</li>
|
|
684
|
+
<li>Wire the answers to contact fields. That is what lets you tag, segment, and branch on them later.</li>
|
|
685
|
+
<li>Attach the form to a page in a funnel, or send the form link directly. Both work.</li>
|
|
686
|
+
<li>Submissions can be read on the Free plan. Building and changing forms needs the full license.</li>
|
|
687
|
+
</ul>
|
|
688
|
+
</div>
|
|
689
|
+
<div class="gsec"><h2>Where people go wrong</h2>
|
|
690
|
+
<div style="overflow-x:auto"><table class="wrongtbl"><tr><th>What happened</th><th>The fix</th></tr><tr><td>"The answers are not on the contact record."</td><td>The questions were not wired to fields. Ask Claude to wire them, and it will create the fields it needs.</td></tr><tr><td>"The form saved but looks wrong on the page."</td><td>The page has its own copy of the form settings. Rebuild the page section with the form after you finish the form, not before.</td></tr><tr><td>"Nobody finished the form."</td><td>Too many questions. Cut it to four and put the rest in the follow-up conversation.</td></tr><tr><td>"It says my test phone number is invalid."</td><td>Numbers starting 555 are reserved for fiction and GHL rejects them. Test with a real-format number instead.</td></tr><tr><td>"I submitted a test and the contact does not come up in search."</td><td>Search runs off an index that lags a few moments behind. The contact record itself is already correct, so open it directly or just ask again shortly.</td></tr></table></div>
|
|
691
|
+
</div>
|
|
692
|
+
<div class="gsec"><h2>Related guides</h2>
|
|
693
|
+
<ul>
|
|
694
|
+
<li>page-studio-pages-and-sites</li>
|
|
695
|
+
<li>custom-fields-and-objects</li>
|
|
696
|
+
</ul>
|
|
697
|
+
</div>
|
|
698
|
+
<p class="gfoot"><a class="back" href="#top">↑ All guides</a> · Stuck? Email support@ghlcommand.com and a human answers.</p>
|
|
699
|
+
</section>
|
|
700
|
+
|
|
600
701
|
<section class="gview" id="g-custom-fields-and-objects">
|
|
601
702
|
<h1 class="gtitle serif">Custom fields and objects</h1>
|
|
602
703
|
<p class="gpromise">The fields and records your niche needs, created correctly the first time.</p>
|
|
@@ -832,6 +933,56 @@ Do not reply to anyone. This is a read.</p></div>
|
|
|
832
933
|
<p class="gfoot"><a class="back" href="#top">↑ All guides</a> · Stuck? Email support@ghlcommand.com and a human answers.</p>
|
|
833
934
|
</section>
|
|
834
935
|
|
|
936
|
+
<section class="gview" id="g-see-and-manage-appointments">
|
|
937
|
+
<h1 class="gtitle serif">See and manage appointments</h1>
|
|
938
|
+
<p class="gpromise">Who is booked today, this week, or for a specific client, in one ask.</p>
|
|
939
|
+
<div class="gmeta"><span class="pill free">Free plan</span><span class="time">~10 seconds</span><span class="time">Works in Claude Desktop and Claude Code</span></div>
|
|
940
|
+
<div class="gsec"><h2>What you'll get</h2>
|
|
941
|
+
<ul>
|
|
942
|
+
<li>Today's bookings, this week's bookings, or one person's history, read out in plain English.</li>
|
|
943
|
+
<li>The gaps: which slots are still open, so you know what to fill.</li>
|
|
944
|
+
<li>Appointment status where it matters: confirmed, cancelled, no show.</li>
|
|
945
|
+
</ul>
|
|
946
|
+
</div>
|
|
947
|
+
<div class="gsec"><h2>Say this</h2>
|
|
948
|
+
<div class="prompt"><q>Who is booked today?</q><button class="copy" type="button">Copy</button></div>
|
|
949
|
+
<div class="prompt"><q>What does next week look like on the consult calendar?</q><button class="copy" type="button">Copy</button></div>
|
|
950
|
+
<div class="prompt"><q>When is Dana Miller's next appointment?</q><button class="copy" type="button">Copy</button></div>
|
|
951
|
+
<div class="prompt"><q>What slots are still free on Thursday?</q><button class="copy" type="button">Copy</button></div>
|
|
952
|
+
</div>
|
|
953
|
+
<div class="gsec"><h2>What it looks like</h2>
|
|
954
|
+
<div class="chat"><span class="chat-cap">Your Claude conversation</span>
|
|
955
|
+
<div class="msg user">Who is booked today?</div>
|
|
956
|
+
<div class="msg claude"><b>Three on the books today</b>, Arizona time: 9:00 Dana Miller (confirmed), 11:00 Priya Shah (confirmed), 2:00 Marc Ellis (cancelled, so that slot is actually free). Two real appointments, one hole at 2:00. Want me to check tomorrow too?</div>
|
|
957
|
+
</div>
|
|
958
|
+
</div>
|
|
959
|
+
<div class="gsec"><h2>What happens when you ask</h2>
|
|
960
|
+
<ol class="steps">
|
|
961
|
+
<li>Claude finds the calendars in the account and reads the bookings in your window.</li>
|
|
962
|
+
<li>It reports them in the account's timezone and says which timezone that is.</li>
|
|
963
|
+
<li>For one person, it looks up the contact first and then their appointments, past and upcoming.</li>
|
|
964
|
+
</ol>
|
|
965
|
+
</div>
|
|
966
|
+
<div class="gsec"><h2>Good to know</h2>
|
|
967
|
+
<ul>
|
|
968
|
+
<li>Say the window plainly: today, this week, next Thursday, the rest of the month. Claude echoes the dates back so you can check.</li>
|
|
969
|
+
<li>Timezone comes from the sub-account. On a new client account, confirm it once, because everything downstream inherits it.</li>
|
|
970
|
+
<li>Booking, moving, and cancelling appointments need the full license. Reading them is free.</li>
|
|
971
|
+
<li>Appointment totals are deliberately left out of the weekly account report. Ask for them here instead, where the window is explicit.</li>
|
|
972
|
+
</ul>
|
|
973
|
+
</div>
|
|
974
|
+
<div class="gsec"><h2>Where people go wrong</h2>
|
|
975
|
+
<div style="overflow-x:auto"><table class="wrongtbl"><tr><th>What happened</th><th>The fix</th></tr><tr><td>"The times look an hour off."</td><td>The sub-account timezone is set to the wrong city. Fix it in GHL once and every reading is right afterwards.</td></tr><tr><td>"It missed an appointment I know about."</td><td>It is on a calendar you did not name. Ask "list every calendar in this account" and then ask across all of them.</td></tr><tr><td>"I asked for today and got this week."</td><td>Say the word today on its own. Claude prints the window it used, so you can spot it immediately.</td></tr></table></div>
|
|
976
|
+
</div>
|
|
977
|
+
<div class="gsec"><h2>Related guides</h2>
|
|
978
|
+
<ul>
|
|
979
|
+
<li>set-up-a-booking-calendar</li>
|
|
980
|
+
<li>weekly-account-report</li>
|
|
981
|
+
</ul>
|
|
982
|
+
</div>
|
|
983
|
+
<p class="gfoot"><a class="back" href="#top">↑ All guides</a> · Stuck? Email support@ghlcommand.com and a human answers.</p>
|
|
984
|
+
</section>
|
|
985
|
+
|
|
835
986
|
<section class="gview" id="g-send-texts-and-emails">
|
|
836
987
|
<h1 class="gtitle serif">Send texts and emails</h1>
|
|
837
988
|
<p class="gpromise">Message any contact from Claude, in your voice, on the right channel.</p>
|
|
@@ -1068,13 +1219,16 @@ Do not add any contacts or deals to it yet.</p></div>
|
|
|
1068
1219
|
<div class="gsec"><h2>Good to know</h2>
|
|
1069
1220
|
<ul>
|
|
1070
1221
|
<li>Every sub-account needs its own key saved once. The installer does this for the first account. To add another, say "add my Radiance Med Spa account" and Claude walks you through it.</li>
|
|
1222
|
+
<li><b>You do not need to keep your own list of keys.</b> Saved keys live in a private file on your machine that only your install reads, and it is deliberately excluded from anything that gets committed or shared. Keeping a second copy in Notes or a doc is the risky part, not the useful part.</li>
|
|
1223
|
+
<li>Because each key is saved once, you never have to paste one into the chat again. If you do paste one, it lives in that conversation's history afterwards, so treat it as spent and create a fresh one in GHL.</li>
|
|
1224
|
+
<li>Ask "which accounts do you have keys saved for?" any time. That is the list Claude can actually reach, which is not always the same as the list in GHL.</li>
|
|
1071
1225
|
<li>Your license covers unlimited sub-accounts. Adding another client costs nothing extra.</li>
|
|
1072
1226
|
<li>Get in the habit of asking "which account am I in" before any build. It takes two seconds and it is the cheapest insurance there is.</li>
|
|
1073
1227
|
<li>This works fully on the Free plan.</li>
|
|
1074
1228
|
</ul>
|
|
1075
1229
|
</div>
|
|
1076
1230
|
<div class="gsec"><h2>Where people go wrong</h2>
|
|
1077
|
-
<div style="overflow-x:auto"><table class="wrongtbl"><tr><th>What happened</th><th>The fix</th></tr><tr><td>"It built something in the wrong client's account."</td><td>Always confirm the account first. Ask "which account am I in", then build.</td></tr><tr><td>"I switched accounts an hour ago, and now it is back on my default."</td><td>When the product updates itself in the background, the active account can fall back to your default. Ask "which account am I in" again before you build.</td></tr><tr><td>"It says it cannot find that account."</td><td>Use the name exactly as it appears in GHL, or say "list my sub-accounts" and pick from the list.</td></tr></table></div>
|
|
1231
|
+
<div style="overflow-x:auto"><table class="wrongtbl"><tr><th>What happened</th><th>The fix</th></tr><tr><td>"It built something in the wrong client's account."</td><td>Always confirm the account first. Ask "which account am I in", then build.</td></tr><tr><td>"I switched accounts an hour ago, and now it is back on my default."</td><td>When the product updates itself in the background, the active account can fall back to your default. Ask "which account am I in" again before you build.</td></tr><tr><td>"It says it cannot find that account."</td><td>Use the name exactly as it appears in GHL, or say "list my sub-accounts" and pick from the list.</td></tr><tr><td>"I set up new clients in GHL last week and Claude does not see them."</td><td>Creating a sub-account in GHL does not save its key here. Ask "which accounts do you have keys saved for?", compare that against GHL, and add the missing ones. Worth doing whenever you have taken on new clients.</td></tr><tr><td>"Comparing two accounts says the second one is empty."</td><td>A key only works on the account it was created in. Save the second account's own key first, then compare. Without it, the second account cannot be read at all.</td></tr></table></div>
|
|
1078
1232
|
</div>
|
|
1079
1233
|
<div class="gsec"><h2>Related guides</h2>
|
|
1080
1234
|
<ul>
|
|
@@ -1187,6 +1341,55 @@ Tell me plainly what happens on my side when somebody clicks it, and what I woul
|
|
|
1187
1341
|
<p class="gfoot"><a class="back" href="#top">↑ All guides</a> · Stuck? Email support@ghlcommand.com and a human answers.</p>
|
|
1188
1342
|
</section>
|
|
1189
1343
|
|
|
1344
|
+
<section class="gview" id="g-watch-your-reviews">
|
|
1345
|
+
<h1 class="gtitle serif">Watch your reviews</h1>
|
|
1346
|
+
<p class="gpromise">See new reviews across clients without logging into each account.</p>
|
|
1347
|
+
<div class="gmeta"><span class="pill free">Free plan</span><span class="time">~30 seconds</span><span class="time">Works in Claude Desktop and Claude Code</span></div>
|
|
1348
|
+
<div class="gsec"><h2>What you'll get</h2>
|
|
1349
|
+
<ul>
|
|
1350
|
+
<li>New reviews for an account, read out with the star rating and what the person actually wrote.</li>
|
|
1351
|
+
<li>The bad ones surfaced first, because those are the ones with a clock on them.</li>
|
|
1352
|
+
<li>The account's review request link, so you can send it to a happy patient while they are still happy.</li>
|
|
1353
|
+
</ul>
|
|
1354
|
+
</div>
|
|
1355
|
+
<div class="gsec"><h2>Say this</h2>
|
|
1356
|
+
<div class="prompt"><q>Any new reviews this week?</q><button class="copy" type="button">Copy</button></div>
|
|
1357
|
+
<div class="prompt"><q>Show me every review under four stars.</q><button class="copy" type="button">Copy</button></div>
|
|
1358
|
+
<div class="prompt"><q>What is our review link for this account?</q><button class="copy" type="button">Copy</button></div>
|
|
1359
|
+
</div>
|
|
1360
|
+
<div class="gsec"><h2>What it looks like</h2>
|
|
1361
|
+
<div class="chat"><span class="chat-cap">Your Claude conversation</span>
|
|
1362
|
+
<div class="msg user">Any new reviews this week?</div>
|
|
1363
|
+
<div class="msg claude"><b>Three new reviews.</b> Two five-star, both mentioning Sarah by name. One two-star from Aug 4: "Waited 40 minutes past my appointment time and nobody said anything." That one is unanswered and four days old. Want the wording for a reply you can post?</div>
|
|
1364
|
+
</div>
|
|
1365
|
+
</div>
|
|
1366
|
+
<div class="gsec"><h2>What happens when you ask</h2>
|
|
1367
|
+
<ol class="steps">
|
|
1368
|
+
<li>Claude reads the reviews attached to the account.</li>
|
|
1369
|
+
<li>It sorts them so anything low-rated and recent comes first.</li>
|
|
1370
|
+
<li>It can draft your reply for you to post. Posting the reply itself is done in GHL.</li>
|
|
1371
|
+
</ol>
|
|
1372
|
+
</div>
|
|
1373
|
+
<div class="gsec"><h2>Good to know</h2>
|
|
1374
|
+
<ul>
|
|
1375
|
+
<li>Replying is done by you inside GHL. Claude reads the reviews and writes the reply; a public response going out without a human reading it first is not a risk worth automating.</li>
|
|
1376
|
+
<li>Run it across several client accounts in one sitting. Say the client's name and Claude switches, reads, and moves on.</li>
|
|
1377
|
+
<li>A two-star review answered within a day reads completely differently to one answered in a fortnight. Speed is most of the job.</li>
|
|
1378
|
+
<li>Reading reviews works fully on the Free plan.</li>
|
|
1379
|
+
</ul>
|
|
1380
|
+
</div>
|
|
1381
|
+
<div class="gsec"><h2>Where people go wrong</h2>
|
|
1382
|
+
<div style="overflow-x:auto"><table class="wrongtbl"><tr><th>What happened</th><th>The fix</th></tr><tr><td>"No reviews came back and I know we have some."</td><td>Reviews live per sub-account. Confirm which account you are in, then ask again. Reviews also only appear here once the platform they came from is connected under Reputation.</td></tr><tr><td>"It says no reviews, but there are some on our Facebook page."</td><td>Having a review link for a platform is not the same as having that platform connected. Until it is connected, the reviews stay on Facebook and never reach the account.</td></tr><tr><td>"I want alerts, not to keep asking."</td><td>Ask for a workflow instead: a review request after every completed appointment, and a notification to you on anything low.</td></tr><tr><td>"The reply Claude wrote sounds defensive."</td><td>Tell it the tone: short, human, take responsibility, offer to fix it privately. It will rewrite.</td></tr></table></div>
|
|
1383
|
+
</div>
|
|
1384
|
+
<div class="gsec"><h2>Related guides</h2>
|
|
1385
|
+
<ul>
|
|
1386
|
+
<li>weekly-account-report</li>
|
|
1387
|
+
<li>trigger-links</li>
|
|
1388
|
+
</ul>
|
|
1389
|
+
</div>
|
|
1390
|
+
<p class="gfoot"><a class="back" href="#top">↑ All guides</a> · Stuck? Email support@ghlcommand.com and a human answers.</p>
|
|
1391
|
+
</section>
|
|
1392
|
+
|
|
1190
1393
|
<section class="gview" id="g-weekly-account-report">
|
|
1191
1394
|
<h1 class="gtitle serif">Weekly account report</h1>
|
|
1192
1395
|
<p class="gpromise">One ask, a full snapshot of the account's week: leads, pipeline, and conversations.</p>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elitedcs/ghl-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.64.0",
|
|
4
4
|
"mcpName": "io.github.drjerryrelth/ghl-command",
|
|
5
5
|
"description": "GoHighLevel MCP Server for Claude. 235 tools — 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",
|