@elitedcs/ghl-mcp 3.65.0 → 3.65.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,71 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.65.2 — invoicing never worked, and the guide stopped being one long page
4
+
5
+ - **Fix: creating an invoice failed every single time.** The call sent five
6
+ fields; GoHighLevel needs eleven, and it names line-item amounts differently
7
+ than we did. Given a payload it could not read, their server crashed rather
8
+ than telling us what was missing, so this looked like an outage on their side
9
+ rather than a bug on ours. It has never worked for anyone. Invoices now carry
10
+ the currency, the dates, your business name and the client's own details, and
11
+ are created as real payable drafts unless you ask for a test one.
12
+
13
+ **The user guide is a library again, not a scroll.**
14
+
15
+ - **Cards open their own page.** The guide had drifted into a single document
16
+ that printed the index and then every guide beneath it, growing by one whole
17
+ guide each release. Opening a card now shows that guide on its own, from the
18
+ top, and the back button works.
19
+ - **The category menu is back**, above the cards.
20
+ - **It stays light.** The guide used to follow your computer into dark mode,
21
+ which is wrong for something people read at length, print, and save as a PDF.
22
+ - **It prints properly now.** One guide per job, no navigation, no buttons, no
23
+ index bleeding into the page.
24
+ - Fixed a layout bug that had been chopping numbered steps into narrow columns
25
+ whenever a step contained a command. The install guide's first step was the
26
+ worst hit, which is the first thing a new customer reads.
27
+
28
+ **Three new guides, each proven live before shipping:**
29
+
30
+ - **What your AI bot knows, and where to put it.** Custom values resolve in a
31
+ bot's prompt and are silently ignored in its knowledge base. Asked a question
32
+ whose answer sat behind an unresolved token, a test bot named a nearby
33
+ sentence as the person responsible. Worse, if the same fact also sits in the
34
+ prompt the bot quietly repairs the answer, so the bug passes exactly the test
35
+ you would run.
36
+ - **Bill a client and see what you were paid.** Invoices, products, coupons, and
37
+ the difference between money invoiced and money received.
38
+ - **Reuse a build across client accounts.** Snapshots, and the honest list of
39
+ what does not travel with one.
40
+
41
+ ## 3.65.1 — the guide caught up with the product
42
+
43
+ No code changes. The built-in user guide ships inside the install, so it goes
44
+ out as its own release.
45
+
46
+ - **Fix: the booking-calendar guide was telling you to do something by hand that
47
+ the product now does.** It said minimum booking notice lived on GHL's calendar
48
+ screen "and not here", and sent you there to set it. 3.65.0 made it settable
49
+ directly. Anyone following that page yesterday was sent clicking through GHL
50
+ for no reason.
51
+ - **Booking calendars**: daily caps and minimum notice are now in the guide, in
52
+ the same ask that sets your hours and slot length. Plus what to do if an older
53
+ version reset your slot lengths or opening hours when you changed something
54
+ else.
55
+ - **Nurture sequences**: quiet hours. What they are, why every workflow that
56
+ texts needs its own, and the one thing to go check: if you set quiet hours
57
+ before 3.65.0, they were dropped the next time that workflow was saved. Open
58
+ anything that texts and set them once more.
59
+ - **Contact lists**: how to save a group as a list you can reopen, rather than
60
+ rebuilding the same filter every Monday. These tools never worked before
61
+ 3.65.0, so if you tried this and found nothing in GHL, that is why.
62
+ - **Blueprint**: how appointment, reply, missed-call and number-check triggers
63
+ get scoped to the thing you actually meant, and why a stage move needs to find
64
+ its deal first.
65
+
66
+ Every prompt in the guide is bound to a run that actually happened in a real
67
+ sub-account. The three new ones were proven live before this shipped.
68
+
3
69
  ## 3.65.0 — nine calls that reported success and did the wrong thing
4
70
 
5
71
  Found while building a 139-requirement home-care front office end to end. Every
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.65.0",
2857
+ version: "3.65.2",
2858
2858
  mcpName: "io.github.drjerryrelth/ghl-command",
2859
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.",
2860
2860
  main: "dist/index.js",
@@ -8648,6 +8648,38 @@ function registerProductTools(server2, client) {
8648
8648
 
8649
8649
  // src/tools/invoices.ts
8650
8650
  var import_zod20 = require("zod");
8651
+ function buildCreateInvoiceBody(args, resolvedLocationId, contact, businessName, today) {
8652
+ const currency = args.currency ?? args.items[0]?.currency ?? "USD";
8653
+ return {
8654
+ altId: resolvedLocationId,
8655
+ altType: "location",
8656
+ name: args.name,
8657
+ title: args.title ?? args.name,
8658
+ currency,
8659
+ // GHL's line items are `amount` and `qty`. Sending price/quantity leaves
8660
+ // both undefined on their side, which is the crash.
8661
+ items: args.items.map((i) => ({
8662
+ name: i.name,
8663
+ description: i.description ?? "",
8664
+ currency: i.currency ?? currency,
8665
+ amount: i.price,
8666
+ qty: i.quantity
8667
+ })),
8668
+ discount: args.discount ?? { type: "percentage", value: 0 },
8669
+ termsNotes: args.termsNotes ?? "",
8670
+ businessDetails: { name: businessName },
8671
+ contactDetails: {
8672
+ id: contact.id,
8673
+ name: contact.name ?? "",
8674
+ email: contact.email ?? "",
8675
+ phoneNo: contact.phone ?? ""
8676
+ },
8677
+ issueDate: args.issueDate ?? today,
8678
+ dueDate: args.dueDate ?? args.issueDate ?? today,
8679
+ // Real, payable invoice unless the caller explicitly asks for a test one.
8680
+ liveMode: args.liveMode ?? true
8681
+ };
8682
+ }
8651
8683
  function registerInvoiceTools(server2, client) {
8652
8684
  safeTool(
8653
8685
  server2,
@@ -8713,30 +8745,47 @@ function registerInvoiceTools(server2, client) {
8713
8745
  contactId: import_zod20.z.string().describe("Contact ID for the invoice"),
8714
8746
  items: import_zod20.z.array(import_zod20.z.object({
8715
8747
  name: import_zod20.z.string().describe("Item name"),
8716
- description: import_zod20.z.string().describe("Item description"),
8748
+ description: import_zod20.z.string().optional().describe("Item description"),
8717
8749
  quantity: import_zod20.z.number().describe("Item quantity"),
8718
- price: import_zod20.z.number().describe("Item price"),
8719
- currency: import_zod20.z.string().describe("Currency code (e.g. USD)")
8720
- })).describe("Invoice line items"),
8750
+ price: import_zod20.z.number().describe("Unit price, in the invoice currency."),
8751
+ currency: import_zod20.z.string().optional().describe("Currency code (e.g. USD). Defaults to the invoice currency.")
8752
+ })).min(1).describe("Invoice line items"),
8753
+ currency: import_zod20.z.string().optional().describe("Invoice currency code, e.g. 'USD'. Defaults to the first item's currency, then USD."),
8721
8754
  discount: import_zod20.z.object({
8722
8755
  type: import_zod20.z.string().optional().describe("Discount type: 'percentage' or 'fixed'."),
8723
8756
  value: import_zod20.z.number().optional().describe("Discount amount: percent (0-100) when type=percentage, currency amount when type=fixed.")
8724
8757
  }).optional().describe("Discount to apply"),
8725
8758
  termsNotes: import_zod20.z.string().optional().describe("Terms and notes for the invoice"),
8726
- title: import_zod20.z.string().optional().describe("Invoice title")
8759
+ title: import_zod20.z.string().optional().describe("Invoice title. Defaults to the invoice name."),
8760
+ issueDate: import_zod20.z.string().optional().describe("Issue date, YYYY-MM-DD. Defaults to today."),
8761
+ dueDate: import_zod20.z.string().optional().describe("Due date, YYYY-MM-DD. Defaults to the issue date."),
8762
+ liveMode: import_zod20.z.boolean().optional().describe("true (default) creates a real, payable invoice. false creates a test-mode invoice that cannot be paid.")
8727
8763
  },
8728
- async ({ locationId: locationId2, name, contactId, items, discount, termsNotes, title }) => {
8764
+ async ({ locationId: locationId2, name, contactId, items, currency, discount, termsNotes, title, issueDate, dueDate, liveMode }) => {
8729
8765
  const resolvedLocationId = client.resolveLocationId(locationId2);
8730
- const body = {
8731
- altId: resolvedLocationId,
8732
- altType: "location",
8733
- name,
8734
- contactId,
8735
- items
8766
+ const contactRes = await client.get(`/contacts/${contactId}`);
8767
+ const c = contactRes?.contact ?? contactRes ?? {};
8768
+ const contact = {
8769
+ id: contactId,
8770
+ name: [c.firstName, c.lastName].filter(Boolean).join(" ") || c.name || "",
8771
+ email: c.email ?? "",
8772
+ phone: c.phone ?? ""
8736
8773
  };
8737
- if (discount !== void 0) body.discount = discount;
8738
- if (termsNotes !== void 0) body.termsNotes = termsNotes;
8739
- if (title !== void 0) body.title = title;
8774
+ let businessName = "";
8775
+ try {
8776
+ const loc = await client.get(`/locations/${resolvedLocationId}`);
8777
+ const l = loc?.location ?? loc ?? {};
8778
+ businessName = l.name ?? "";
8779
+ } catch {
8780
+ }
8781
+ const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
8782
+ const body = buildCreateInvoiceBody(
8783
+ { name, contactId, items, currency, discount, termsNotes, title, issueDate, dueDate, liveMode },
8784
+ resolvedLocationId,
8785
+ contact,
8786
+ businessName,
8787
+ today
8788
+ );
8740
8789
  return client.post("/invoices/", { body });
8741
8790
  }
8742
8791
  );