@elitedcs/ghl-mcp 3.64.0 → 3.64.1

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,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.64.1 — three more calls that failed quietly
4
+
5
+ - **Fix: client pricing was mangled on the way into a build plan.** The Blueprint
6
+ intake parsed price answers by splitting on line breaks only, and read the
7
+ hyphen in a price range as the separator between a product and its price. An
8
+ answer typed as a sentence — "Contouring packages 1200-3500. Injectables
9
+ 400-900." — became a single entry named "Contouring packages 1200" priced at
10
+ "3500", with the second offering discarded entirely, and the brief still
11
+ reported as valid. Prices now survive as ranges, sentences and semicolons
12
+ separate entries, and nothing is silently dropped.
13
+ - **Fix: listing invoices always failed.** GoHighLevel requires both a limit and
14
+ an offset on that endpoint and rejects the call without them, so the ordinary
15
+ "show me my invoices" request never worked. Both are now always sent.
16
+ - **Fix: blog authors and categories always failed**, for the same reason and
17
+ with the same fix. The paths were never wrong — only the request was.
18
+
3
19
  ## 3.64.0 — four silent failures fixed, four more guides open
4
20
 
5
21
  Every fix here is the same shape: a call that succeeded, returned
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.64.0",
2857
+ version: "3.64.1",
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",
@@ -8606,11 +8606,11 @@ function registerInvoiceTools(server2, client) {
8606
8606
  safeTool(
8607
8607
  server2,
8608
8608
  "list_invoices",
8609
- "List invoices for a location. Offset-based pagination via limit/offset.",
8609
+ "List invoices for a location. Offset-based pagination via limit/offset; both are always sent because GHL requires them.",
8610
8610
  {
8611
8611
  locationId: import_zod20.z.string().optional().describe("GHL Location ID (optional if GHL_LOCATION_ID is set)"),
8612
- limit: import_zod20.z.number().optional().describe("Max number of invoices to return"),
8613
- offset: import_zod20.z.number().optional().describe("Offset for pagination"),
8612
+ limit: import_zod20.z.number().min(1).optional().describe("Max number of invoices to return (must be at least 1). Defaults to 10."),
8613
+ offset: import_zod20.z.number().min(0).optional().describe("Offset for pagination. Defaults to 0."),
8614
8614
  status: import_zod20.z.enum(["draft", "sent", "paid", "void", "partially_paid"]).optional().describe("Filter by invoice status"),
8615
8615
  contactId: import_zod20.z.string().optional().describe("Filter by contact ID"),
8616
8616
  startAt: import_zod20.z.string().optional().describe("Start date filter (ISO 8601)"),
@@ -8624,8 +8624,8 @@ function registerInvoiceTools(server2, client) {
8624
8624
  altId: resolvedLocationId,
8625
8625
  altType: "location"
8626
8626
  };
8627
- if (limit !== void 0) params.limit = limit;
8628
- if (offset !== void 0) params.offset = offset;
8627
+ params.limit = limit ?? 10;
8628
+ params.offset = offset ?? 0;
8629
8629
  if (status !== void 0) params.status = status;
8630
8630
  if (contactId !== void 0) params.contactId = contactId;
8631
8631
  if (startAt !== void 0) params.startAt = startAt;
@@ -9214,28 +9214,36 @@ function registerBlogTools(server2, client) {
9214
9214
  safeTool(
9215
9215
  server2,
9216
9216
  "get_blog_authors",
9217
- "List blog authors for a location",
9217
+ "List blog authors for a location.",
9218
9218
  {
9219
- locationId: import_zod27.z.string().optional().describe("GHL Location ID (optional if GHL_LOCATION_ID is set)")
9219
+ locationId: import_zod27.z.string().optional().describe("GHL Location ID (optional if GHL_LOCATION_ID is set)"),
9220
+ limit: import_zod27.z.number().min(1).max(50).optional().describe("How many authors to return (1-50). Defaults to 50."),
9221
+ offset: import_zod27.z.number().min(0).optional().describe("How many to skip. Defaults to 0.")
9220
9222
  },
9221
- async ({ locationId: locationId2 }) => {
9223
+ // limit and offset are REQUIRED by GHL even though they read as optional
9224
+ // paging: omitting them returns 422 "limit should not be empty", which
9225
+ // surfaced as "blog authors are broken" (live-verified 2026-08-08).
9226
+ async ({ locationId: locationId2, limit, offset }) => {
9222
9227
  const resolvedLocationId = client.resolveLocationId(locationId2);
9223
9228
  return client.get("/blogs/authors", {
9224
- params: { locationId: resolvedLocationId }
9229
+ params: { locationId: resolvedLocationId, limit: limit ?? 50, offset: offset ?? 0 }
9225
9230
  });
9226
9231
  }
9227
9232
  );
9228
9233
  safeTool(
9229
9234
  server2,
9230
9235
  "get_blog_categories",
9231
- "List blog categories for a location",
9236
+ "List blog categories for a location.",
9232
9237
  {
9233
- locationId: import_zod27.z.string().optional().describe("GHL Location ID (optional if GHL_LOCATION_ID is set)")
9238
+ locationId: import_zod27.z.string().optional().describe("GHL Location ID (optional if GHL_LOCATION_ID is set)"),
9239
+ limit: import_zod27.z.number().min(1).max(50).optional().describe("How many categories to return (1-50). Defaults to 50."),
9240
+ offset: import_zod27.z.number().min(0).optional().describe("How many to skip. Defaults to 0.")
9234
9241
  },
9235
- async ({ locationId: locationId2 }) => {
9242
+ // Same required-paging contract as /blogs/authors — see the note there.
9243
+ async ({ locationId: locationId2, limit, offset }) => {
9236
9244
  const resolvedLocationId = client.resolveLocationId(locationId2);
9237
9245
  return client.get("/blogs/categories", {
9238
- params: { locationId: resolvedLocationId }
9246
+ params: { locationId: resolvedLocationId, limit: limit ?? 50, offset: offset ?? 0 }
9239
9247
  });
9240
9248
  }
9241
9249
  );
@@ -15956,18 +15964,20 @@ function splitList(text) {
15956
15964
  }
15957
15965
  function parsePricePoints(text) {
15958
15966
  const out = [];
15959
- for (const line of text.split(/\r?\n/)) {
15960
- const t = line.trim();
15967
+ const segments = text.split(/\r?\n|;|\.\s+/);
15968
+ const ENTRY = /^(.*?)\s*[-–—:|]?\s*\$?\s*([\d,]+(?:\.\d+)?)\s*(?:[-–—]\s*\$?\s*([\d,]+(?:\.\d+)?))?\s*$/;
15969
+ const clean = (s) => s.replace(/[\s.,:;|–—-]+$/, "").trim();
15970
+ const num = (s) => s.replace(/,/g, "");
15971
+ for (const segment of segments) {
15972
+ const t = segment.trim().replace(/\.$/, "");
15961
15973
  if (!t) continue;
15962
- const m = t.match(/^(.*?)[\s]*[-—:|]\s*\$?\s*([\d,]+(?:\.\d+)?)/);
15963
- if (m) {
15964
- out.push({ name: m[1].trim(), price: m[2].replace(/,/g, "") });
15974
+ const m = t.match(ENTRY);
15975
+ if (m && m[2]) {
15976
+ const name = clean(m[1]);
15977
+ const price = m[3] ? `${num(m[2])}-${num(m[3])}` : num(m[2]);
15978
+ out.push({ name: name || t, price });
15965
15979
  } else {
15966
- const priceOnly = t.match(/\$?\s*([\d,]+(?:\.\d+)?)\s*$/);
15967
- out.push({
15968
- name: priceOnly ? t.slice(0, priceOnly.index).trim() || t : t,
15969
- price: priceOnly ? priceOnly[1].replace(/,/g, "") : ""
15970
- });
15980
+ out.push({ name: t, price: "" });
15971
15981
  }
15972
15982
  }
15973
15983
  return out;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elitedcs/ghl-mcp",
3
- "version": "3.64.0",
3
+ "version": "3.64.1",
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",