@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 +66 -0
- package/dist/index.js +65 -16
- package/guide/guide.html +643 -176
- package/package.json +2 -2
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.
|
|
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("
|
|
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
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8734
|
-
|
|
8735
|
-
|
|
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
|
-
|
|
8738
|
-
|
|
8739
|
-
|
|
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
|
);
|