@elitedcs/ghl-mcp 3.65.1 → 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 +38 -0
- package/dist/index.js +65 -16
- package/guide/guide.html +612 -171
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
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
|
+
|
|
3
41
|
## 3.65.1 — the guide caught up with the product
|
|
4
42
|
|
|
5
43
|
No code changes. The built-in user guide ships inside the install, so it goes
|
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
|
);
|