@elitedcs/ghl-mcp 3.62.1 → 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 +48 -0
- package/dist/index.js +130 -82
- package/guide/guide.html +1130 -45
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
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
|
+
|
|
32
|
+
## 3.63.0 — the guide library grows from 3 guides to 20
|
|
33
|
+
|
|
34
|
+
- **`get_user_guide` now opens a 20-guide library.** Seventeen guides were
|
|
35
|
+
written and proven live but had never shipped, so anyone running
|
|
36
|
+
`get user guide` was still getting the three-guide edition. The bundled
|
|
37
|
+
offline guide goes from 43KB to 111KB: 20 open guides, 10 still marked
|
|
38
|
+
"Available in the app" until their prompts are proven. Every prompt marked
|
|
39
|
+
"Proven live" was run against a real GoHighLevel account before it shipped.
|
|
40
|
+
- Same library renders to ghlcommand.com/skills, so the in-product guide and
|
|
41
|
+
the website always match.
|
|
42
|
+
- **Fix: reading appointments returned nothing.** `get_calendar_events` sent
|
|
43
|
+
ISO timestamps, but GHL's `/calendars/events` needs epoch milliseconds and
|
|
44
|
+
answers a wrong-format request with `200` and an empty array instead of an
|
|
45
|
+
error — so a calendar holding real confirmed bookings read back as "nothing
|
|
46
|
+
booked". Now converts via the timezone-aware helper free-slots already used,
|
|
47
|
+
plus an optional `timezone` parameter so a bare `YYYY-MM-DD` window resolves
|
|
48
|
+
in the sub-account's timezone (end date inclusive). Live-proven both
|
|
49
|
+
directions.
|
|
50
|
+
|
|
3
51
|
## 3.62.1 — update_pipeline works again (Bug 8)
|
|
4
52
|
|
|
5
53
|
- **Fix: `update_pipeline` no longer 422s.** GHL's pipeline PUT rejects unknown
|
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",
|
|
@@ -7643,7 +7643,7 @@ function toEpochMillis(value, opts = {}) {
|
|
|
7643
7643
|
const trimmed = value.trim();
|
|
7644
7644
|
if (/^\d+$/.test(trimmed)) {
|
|
7645
7645
|
if (trimmed.length === 13) return trimmed;
|
|
7646
|
-
throw new Error(`Ambiguous numeric date "${value}"
|
|
7646
|
+
throw new Error(`Ambiguous numeric date "${value}" \u2014 pass epoch MILLISECONDS (13 digits), a YYYY-MM-DD date, or a full ISO datetime.`);
|
|
7647
7647
|
}
|
|
7648
7648
|
const dateOnly = /^(\d{4})-(\d{2})-(\d{2})$/.exec(trimmed);
|
|
7649
7649
|
if (dateOnly) {
|
|
@@ -7658,7 +7658,7 @@ function toEpochMillis(value, opts = {}) {
|
|
|
7658
7658
|
}
|
|
7659
7659
|
const parsed = Date.parse(trimmed);
|
|
7660
7660
|
if (!Number.isNaN(parsed)) return String(parsed);
|
|
7661
|
-
throw new Error(`Invalid date "${value}"
|
|
7661
|
+
throw new Error(`Invalid date "${value}" \u2014 use YYYY-MM-DD, a full ISO datetime, or epoch milliseconds.`);
|
|
7662
7662
|
}
|
|
7663
7663
|
function buildFreeSlotsParams(args) {
|
|
7664
7664
|
const params = {
|
|
@@ -7669,6 +7669,16 @@ function buildFreeSlotsParams(args) {
|
|
|
7669
7669
|
if (args.userId !== void 0) params.userId = args.userId;
|
|
7670
7670
|
return params;
|
|
7671
7671
|
}
|
|
7672
|
+
function buildCalendarEventsParams(args) {
|
|
7673
|
+
const params = {
|
|
7674
|
+
locationId: args.locationId,
|
|
7675
|
+
startTime: toEpochMillis(args.startTime, { timeZone: args.timezone }),
|
|
7676
|
+
endTime: toEpochMillis(args.endTime, { endOfDay: true, timeZone: args.timezone })
|
|
7677
|
+
};
|
|
7678
|
+
if (args.calendarId !== void 0) params.calendarId = args.calendarId;
|
|
7679
|
+
if (args.userId !== void 0) params.userId = args.userId;
|
|
7680
|
+
return params;
|
|
7681
|
+
}
|
|
7672
7682
|
function registerCalendarTools(server2, client) {
|
|
7673
7683
|
safeTool(
|
|
7674
7684
|
server2,
|
|
@@ -7789,20 +7799,25 @@ function registerCalendarTools(server2, client) {
|
|
|
7789
7799
|
"List calendar events for a location within a time range",
|
|
7790
7800
|
{
|
|
7791
7801
|
locationId: import_zod12.z.string().optional().describe("Location ID (falls back to GHL_LOCATION_ID env var)"),
|
|
7792
|
-
startTime: import_zod12.z.string().describe(
|
|
7793
|
-
|
|
7802
|
+
startTime: import_zod12.z.string().describe(
|
|
7803
|
+
"Start of the window. Accepts a date (YYYY-MM-DD), a full ISO datetime, or epoch milliseconds. A bare date is taken as start-of-day in `timezone` (UTC if unset). GHL needs epoch ms here; the tool converts for you."
|
|
7804
|
+
),
|
|
7805
|
+
endTime: import_zod12.z.string().describe(
|
|
7806
|
+
"End of the window. Accepts a date (YYYY-MM-DD), a full ISO datetime, or epoch milliseconds. A bare date is taken as END of that day, inclusive, in `timezone`."
|
|
7807
|
+
),
|
|
7808
|
+
timezone: import_zod12.z.string().optional().describe("IANA timezone (e.g. America/Phoenix) used to resolve bare YYYY-MM-DD dates. Defaults to UTC."),
|
|
7794
7809
|
calendarId: import_zod12.z.string().optional().describe("Filter by calendar ID"),
|
|
7795
7810
|
userId: import_zod12.z.string().optional().describe("Filter by user ID")
|
|
7796
7811
|
},
|
|
7797
|
-
async ({ locationId: locationId2, startTime, endTime, calendarId, userId }) => {
|
|
7798
|
-
const
|
|
7799
|
-
|
|
7800
|
-
locationId: resolvedLocationId,
|
|
7812
|
+
async ({ locationId: locationId2, startTime, endTime, timezone, calendarId, userId }) => {
|
|
7813
|
+
const params = buildCalendarEventsParams({
|
|
7814
|
+
locationId: client.resolveLocationId(locationId2),
|
|
7801
7815
|
startTime,
|
|
7802
|
-
endTime
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
7816
|
+
endTime,
|
|
7817
|
+
timezone,
|
|
7818
|
+
calendarId,
|
|
7819
|
+
userId
|
|
7820
|
+
});
|
|
7806
7821
|
return await client.get("/calendars/events", { params });
|
|
7807
7822
|
}
|
|
7808
7823
|
);
|
|
@@ -8817,18 +8832,17 @@ function registerUserTools(server2, client) {
|
|
|
8817
8832
|
safeTool(
|
|
8818
8833
|
server2,
|
|
8819
8834
|
"get_users",
|
|
8820
|
-
"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.",
|
|
8821
8836
|
{
|
|
8822
|
-
locationId: import_zod22.z.string().optional().describe("GHL Location ID (optional if GHL_LOCATION_ID is set)")
|
|
8823
|
-
limit: import_zod22.z.number().optional().describe("Max number of users to return"),
|
|
8824
|
-
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)")
|
|
8825
8838
|
},
|
|
8826
|
-
|
|
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 }) => {
|
|
8827
8844
|
const resolvedLocationId = client.resolveLocationId(locationId2);
|
|
8828
|
-
|
|
8829
|
-
if (limit !== void 0) params.limit = limit;
|
|
8830
|
-
if (skip !== void 0) params.skip = skip;
|
|
8831
|
-
return client.get("/users/", { params });
|
|
8845
|
+
return client.get("/users/", { params: { locationId: resolvedLocationId } });
|
|
8832
8846
|
}
|
|
8833
8847
|
);
|
|
8834
8848
|
safeTool(
|
|
@@ -13323,7 +13337,7 @@ var import_zod46 = require("zod");
|
|
|
13323
13337
|
function delay2(ms) {
|
|
13324
13338
|
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
13325
13339
|
}
|
|
13326
|
-
function registerAccountExportTools(server2, client) {
|
|
13340
|
+
function registerAccountExportTools(server2, client, registry2) {
|
|
13327
13341
|
const builderClient = WorkflowBuilderClient.fromEnv();
|
|
13328
13342
|
server2.tool(
|
|
13329
13343
|
"export_account",
|
|
@@ -13456,7 +13470,7 @@ function registerAccountExportTools(server2, client) {
|
|
|
13456
13470
|
);
|
|
13457
13471
|
server2.tool(
|
|
13458
13472
|
"compare_locations",
|
|
13459
|
-
"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.",
|
|
13460
13474
|
{
|
|
13461
13475
|
locationA: import_zod46.z.string().describe("First Location ID."),
|
|
13462
13476
|
locationB: import_zod46.z.string().describe("Second Location ID.")
|
|
@@ -13468,66 +13482,57 @@ function registerAccountExportTools(server2, client) {
|
|
|
13468
13482
|
locationA,
|
|
13469
13483
|
locationB
|
|
13470
13484
|
};
|
|
13471
|
-
const
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
|
|
13478
|
-
|
|
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) => {
|
|
13479
13494
|
try {
|
|
13480
|
-
|
|
13481
|
-
} catch {
|
|
13482
|
-
|
|
13495
|
+
return { names: namesFrom(await fn()) };
|
|
13496
|
+
} catch (err) {
|
|
13497
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
13483
13498
|
}
|
|
13499
|
+
};
|
|
13500
|
+
const fetchData = async (locId) => {
|
|
13501
|
+
const data = {};
|
|
13502
|
+
data.pipelines = await read(() => client.get("/opportunities/pipelines", { params: { locationId: locId } }));
|
|
13484
13503
|
await delay2(100);
|
|
13485
|
-
|
|
13486
|
-
data.workflows = await client.get("/workflows/", { params: { locationId: locId } });
|
|
13487
|
-
} catch {
|
|
13488
|
-
data.workflows = null;
|
|
13489
|
-
}
|
|
13504
|
+
data.workflows = await read(() => client.get("/workflows/", { params: { locationId: locId } }));
|
|
13490
13505
|
await delay2(100);
|
|
13491
|
-
|
|
13492
|
-
data.customFields = await client.get("/locations/" + locId + "/customFields");
|
|
13493
|
-
} catch {
|
|
13494
|
-
data.customFields = null;
|
|
13495
|
-
}
|
|
13506
|
+
data.customFields = await read(() => client.get(`/locations/${locId}/customFields`));
|
|
13496
13507
|
await delay2(100);
|
|
13497
|
-
|
|
13498
|
-
data.tags = await client.get("/locations/" + locId + "/tags");
|
|
13499
|
-
} catch {
|
|
13500
|
-
data.tags = null;
|
|
13501
|
-
}
|
|
13508
|
+
data.tags = await read(() => client.get(`/locations/${locId}/tags`));
|
|
13502
13509
|
await delay2(100);
|
|
13503
|
-
|
|
13504
|
-
data.forms = await client.get("/forms/", { params: { locationId: locId } });
|
|
13505
|
-
} catch {
|
|
13506
|
-
data.forms = null;
|
|
13507
|
-
}
|
|
13510
|
+
data.forms = await read(() => client.get("/forms/", { params: { locationId: locId } }));
|
|
13508
13511
|
return data;
|
|
13509
13512
|
};
|
|
13510
|
-
const
|
|
13511
|
-
const
|
|
13512
|
-
|
|
13513
|
-
const
|
|
13514
|
-
if (
|
|
13515
|
-
|
|
13516
|
-
|
|
13517
|
-
|
|
13518
|
-
|
|
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);
|
|
13519
13525
|
}
|
|
13520
|
-
return "?";
|
|
13521
|
-
};
|
|
13522
|
-
diff.comparison = {
|
|
13523
|
-
pipelines: { A: count(dataA, "pipelines"), B: count(dataB, "pipelines") },
|
|
13524
|
-
workflows: { A: count(dataA, "workflows"), B: count(dataB, "workflows") },
|
|
13525
|
-
customFields: { A: count(dataA, "customFields"), B: count(dataB, "customFields") },
|
|
13526
|
-
tags: { A: count(dataA, "tags"), B: count(dataB, "tags") },
|
|
13527
|
-
forms: { A: count(dataA, "forms"), B: count(dataB, "forms") }
|
|
13528
13526
|
};
|
|
13529
|
-
|
|
13530
|
-
|
|
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
|
+
}
|
|
13531
13536
|
return jsonResponse(diff);
|
|
13532
13537
|
} catch (error) {
|
|
13533
13538
|
return errorResponse(error);
|
|
@@ -13535,6 +13540,35 @@ function registerAccountExportTools(server2, client) {
|
|
|
13535
13540
|
}
|
|
13536
13541
|
);
|
|
13537
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
|
+
}
|
|
13538
13572
|
|
|
13539
13573
|
// src/tools/workflow-cloner.ts
|
|
13540
13574
|
var import_zod47 = require("zod");
|
|
@@ -13811,17 +13845,22 @@ ${text2}`);
|
|
|
13811
13845
|
safeTool(
|
|
13812
13846
|
server2,
|
|
13813
13847
|
"list_reviews",
|
|
13814
|
-
"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.",
|
|
13815
13849
|
{
|
|
13816
13850
|
locationId: import_zod49.z.string().optional().describe("Location ID. Falls back to the active builder client's location."),
|
|
13817
13851
|
pageNumber: import_zod49.z.number().optional().describe("1-based page number. Defaults to 1."),
|
|
13818
13852
|
pageSize: import_zod49.z.number().optional().describe("Results per page. Defaults to 10."),
|
|
13819
|
-
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."),
|
|
13820
13856
|
includeDeleted: import_zod49.z.boolean().optional().describe("Include deleted reviews. Defaults to false.")
|
|
13821
13857
|
},
|
|
13822
|
-
async ({ locationId: locationId2, pageNumber, pageSize, rating, includeDeleted }) => {
|
|
13858
|
+
async ({ locationId: locationId2, pageNumber, pageSize, rating, minRating, maxRating, includeDeleted }) => {
|
|
13823
13859
|
const loc = locationId2 ?? client.locationId;
|
|
13824
|
-
return reputationRequest(
|
|
13860
|
+
return reputationRequest(
|
|
13861
|
+
"GET",
|
|
13862
|
+
buildReviewsQuery(loc, { pageNumber, pageSize, rating, minRating, maxRating, includeDeleted })
|
|
13863
|
+
);
|
|
13825
13864
|
}
|
|
13826
13865
|
);
|
|
13827
13866
|
}
|
|
@@ -13832,10 +13871,17 @@ function buildReviewsQuery(locationId2, opts = {}) {
|
|
|
13832
13871
|
`filterParams[deleted][0][value]=${opts.includeDeleted ? "true" : "false"}`,
|
|
13833
13872
|
`filterParams[deleted][0][condition]=eq`
|
|
13834
13873
|
];
|
|
13874
|
+
const bounds = [];
|
|
13835
13875
|
if (opts.rating !== void 0) {
|
|
13836
|
-
|
|
13837
|
-
|
|
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"]);
|
|
13838
13880
|
}
|
|
13881
|
+
bounds.forEach(([value, condition], i) => {
|
|
13882
|
+
q2.push(`filterParams[starRating][${i}][value]=${value}`);
|
|
13883
|
+
q2.push(`filterParams[starRating][${i}][condition]=${condition}`);
|
|
13884
|
+
});
|
|
13839
13885
|
q2.push(`sortParams[dateAdded]=-1`);
|
|
13840
13886
|
q2.push(`pageNumber=${opts.pageNumber ?? 1}`);
|
|
13841
13887
|
q2.push(`pageSize=${opts.pageSize ?? 10}`);
|
|
@@ -18717,7 +18763,6 @@ var publicApiTools = [
|
|
|
18717
18763
|
[registerWebhookTools, "webhooks"],
|
|
18718
18764
|
[registerDocumentTools, "documents"],
|
|
18719
18765
|
[registerBulkOperationTools, "bulk-operations"],
|
|
18720
|
-
[registerAccountExportTools, "account-export"],
|
|
18721
18766
|
[registerTemplateDeployerTools, "template-deployer"],
|
|
18722
18767
|
[registerPhoneTools, "phone"],
|
|
18723
18768
|
[registerAccountHealthTools, "account-health"]
|
|
@@ -18738,6 +18783,7 @@ var VALIDATORS_MODULE = "validators";
|
|
|
18738
18783
|
var DIAGNOSTICS_MODULE = "diagnostics";
|
|
18739
18784
|
var LOCATION_SWITCHER_MODULE = "location-switcher";
|
|
18740
18785
|
var SNAPSHOTS_MODULE = "snapshots";
|
|
18786
|
+
var ACCOUNT_EXPORT_MODULE = "account-export";
|
|
18741
18787
|
var FORM_BUILDER_MODULE = "form-builder";
|
|
18742
18788
|
var INTAKE_TO_BUILD_MODULE = "intake-to-build";
|
|
18743
18789
|
var FUNNEL_QA_MODULE = "funnel-qa";
|
|
@@ -18752,7 +18798,8 @@ var KNOWN_MODULES = /* @__PURE__ */ new Set([
|
|
|
18752
18798
|
VALIDATORS_MODULE,
|
|
18753
18799
|
DIAGNOSTICS_MODULE,
|
|
18754
18800
|
LOCATION_SWITCHER_MODULE,
|
|
18755
|
-
SNAPSHOTS_MODULE
|
|
18801
|
+
SNAPSHOTS_MODULE,
|
|
18802
|
+
ACCOUNT_EXPORT_MODULE
|
|
18756
18803
|
]);
|
|
18757
18804
|
function registerAllTools(server2, client, registry2, mcpVersion, env = process.env, tier = "full", outOfBand) {
|
|
18758
18805
|
const config3 = parseAllowlist(env);
|
|
@@ -18781,6 +18828,7 @@ function registerAllTools(server2, client, registry2, mcpVersion, env = process.
|
|
|
18781
18828
|
() => buildGatingReport(config3, KNOWN_MODULES, attemptedTools, registeredTools, outOfBand)
|
|
18782
18829
|
);
|
|
18783
18830
|
registerSnapshotTools(wrap(SNAPSHOTS_MODULE), client, registry2);
|
|
18831
|
+
registerAccountExportTools(wrap(ACCOUNT_EXPORT_MODULE), client, registry2);
|
|
18784
18832
|
registerLocationSwitcherTools(
|
|
18785
18833
|
wrap(LOCATION_SWITCHER_MODULE),
|
|
18786
18834
|
client,
|