@elitedcs/ghl-mcp 3.17.0 → 3.18.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 +20 -0
- package/dist/index.js +75 -44
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.18.0 — Social Planner: location-scoped endpoints, scheduled posts, typed media
|
|
4
|
+
|
|
5
|
+
**No new tools (still 212 across 43 modules) — fixes plus a capability add to the existing Social Planner tools.**
|
|
6
|
+
|
|
7
|
+
- Every Social Planner call (`get_social_posts`, `get_social_post`, `delete_social_post`, `get_social_media_accounts`, `create_social_post`) now hits the correct location-scoped v2 path (`/social-media-posting/{locationId}/...`). The bare paths were returning errors.
|
|
8
|
+
- `create_social_post` now supports **scheduled posts**: pass `scheduledAt` (sent as `scheduleDate`) with `status: "scheduled"`. `status` is a typed enum: `in_review`, `scheduled`, `draft`, `published`.
|
|
9
|
+
- Media items are typed — each URL is sent as `{ url, type }` with the MIME type inferred. Scheduled posts reject untyped media (and Instagram requires at least one media item).
|
|
10
|
+
|
|
11
|
+
## 3.17.1 — Onboarding messaging fixes + public feedback tracker
|
|
12
|
+
|
|
13
|
+
**No tool changes — still 212 across 43 modules.** Bug-driven fixes from a buyer support ticket (Ryan Thomas, 2026-05-25), plus a public place to file feedback.
|
|
14
|
+
|
|
15
|
+
### Firebase / Workflow Builder onboarding was steering buyers wrong
|
|
16
|
+
|
|
17
|
+
`workflow_builder_status` told users to "set env vars in start-mcp.sh or .env" to enable the 49 Firebase-gated tools. On the npm / Claude Desktop install path there is no `start-mcp.sh` or `.env`, so buyers added the Firebase values to the `claude_desktop_config.json` env block — which Claude Desktop passes unreliably — and got `health_check` → "Firebase: SKIP" after a restart. Now both `workflow_builder_status` and the `health_check` Firebase-SKIP detail steer to `enable_workflow_builder` (the supported path: it validates the values and writes them to `credentials.json`), explicitly warn off the config env-var path, and demote the raw env vars to an advanced/self-hosted note.
|
|
18
|
+
|
|
19
|
+
### Dead npm "Repository" link → public feedback repo
|
|
20
|
+
|
|
21
|
+
`package.json` `repository`/`bugs` pointed at the **private** source repo, which npm renders as a clickable link that 404s for buyers. Now both point to the new public feedback tracker — **https://github.com/drjerryrelth/ghl-command-feedback** — where users can file bug reports and feature requests via issue templates.
|
|
22
|
+
|
|
3
23
|
## 3.17.0 — Multi-tenant bootstrap, internal hardening, test coverage
|
|
4
24
|
|
|
5
25
|
**No new tools — still 212 across 43 modules. Internal hardening + a multi-tenant fix.**
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ var require_package = __commonJS({
|
|
|
31
31
|
"package.json"(exports2, module2) {
|
|
32
32
|
module2.exports = {
|
|
33
33
|
name: "@elitedcs/ghl-mcp",
|
|
34
|
-
version: "3.
|
|
34
|
+
version: "3.18.0",
|
|
35
35
|
description: "GoHighLevel MCP Server for Claude. 212 tools \u2014 full CRM, automation, marketing control, and the only programmatic GHL workflow builder, now multi-tenant across client accounts.",
|
|
36
36
|
main: "dist/index.js",
|
|
37
37
|
bin: {
|
|
@@ -68,10 +68,11 @@ var require_package = __commonJS({
|
|
|
68
68
|
homepage: "https://elitedcs.com/ghl-mcp-server",
|
|
69
69
|
repository: {
|
|
70
70
|
type: "git",
|
|
71
|
-
url: "git+https://github.com/drjerryrelth/
|
|
71
|
+
url: "git+https://github.com/drjerryrelth/ghl-command-feedback.git"
|
|
72
72
|
},
|
|
73
73
|
bugs: {
|
|
74
|
-
url: "https://github.com/drjerryrelth/
|
|
74
|
+
url: "https://github.com/drjerryrelth/ghl-command-feedback/issues",
|
|
75
|
+
email: "support@cliniclaunchlab.com"
|
|
75
76
|
},
|
|
76
77
|
publishConfig: {
|
|
77
78
|
access: "public"
|
|
@@ -3605,18 +3606,22 @@ function registerSocialPlannerTools(server2, client) {
|
|
|
3605
3606
|
fromDate: import_zod21.z.string().optional().describe("Start date filter (ISO string)"),
|
|
3606
3607
|
toDate: import_zod21.z.string().optional().describe("End date filter (ISO string)"),
|
|
3607
3608
|
includeUsers: import_zod21.z.boolean().optional().describe("Whether to include user details"),
|
|
3608
|
-
status: import_zod21.z.enum(["in_review", "scheduled", "published", "failed", "in_progress"]).optional().describe("Post status filter")
|
|
3609
|
+
status: import_zod21.z.enum(["in_review", "scheduled", "published", "failed", "in_progress"]).optional().describe("Post status filter"),
|
|
3610
|
+
skip: import_zod21.z.number().optional().describe("Pagination offset"),
|
|
3611
|
+
limit: import_zod21.z.number().optional().describe("Page size")
|
|
3609
3612
|
},
|
|
3610
|
-
async ({ locationId: locationId2, type, accounts, fromDate, toDate, includeUsers, status }) => {
|
|
3613
|
+
async ({ locationId: locationId2, type, accounts, fromDate, toDate, includeUsers, status, skip, limit }) => {
|
|
3611
3614
|
const resolvedLocationId = client.resolveLocationId(locationId2);
|
|
3612
|
-
const
|
|
3613
|
-
if (type !== void 0)
|
|
3614
|
-
if (accounts !== void 0)
|
|
3615
|
-
if (fromDate !== void 0)
|
|
3616
|
-
if (toDate !== void 0)
|
|
3617
|
-
if (includeUsers !== void 0)
|
|
3618
|
-
if (status !== void 0)
|
|
3619
|
-
|
|
3615
|
+
const body = {};
|
|
3616
|
+
if (type !== void 0) body.type = type;
|
|
3617
|
+
if (accounts !== void 0) body.accounts = accounts;
|
|
3618
|
+
if (fromDate !== void 0) body.fromDate = fromDate;
|
|
3619
|
+
if (toDate !== void 0) body.toDate = toDate;
|
|
3620
|
+
if (includeUsers !== void 0) body.includeUsers = includeUsers;
|
|
3621
|
+
if (status !== void 0) body.status = status;
|
|
3622
|
+
body.skip = skip ?? 0;
|
|
3623
|
+
body.limit = limit ?? 20;
|
|
3624
|
+
return client.post(`/social-media-posting/${resolvedLocationId}/posts/list`, { body });
|
|
3620
3625
|
}
|
|
3621
3626
|
);
|
|
3622
3627
|
safeTool(
|
|
@@ -3624,10 +3629,12 @@ function registerSocialPlannerTools(server2, client) {
|
|
|
3624
3629
|
"get_social_post",
|
|
3625
3630
|
"Get a single social media post by ID",
|
|
3626
3631
|
{
|
|
3627
|
-
postId: import_zod21.z.string().describe("The social media post ID")
|
|
3632
|
+
postId: import_zod21.z.string().describe("The social media post ID"),
|
|
3633
|
+
locationId: import_zod21.z.string().optional().describe("GHL Location ID (optional if GHL_LOCATION_ID is set)")
|
|
3628
3634
|
},
|
|
3629
|
-
async ({ postId }) => {
|
|
3630
|
-
|
|
3635
|
+
async ({ postId, locationId: locationId2 }) => {
|
|
3636
|
+
const resolvedLocationId = client.resolveLocationId(locationId2);
|
|
3637
|
+
return client.get(`/social-media-posting/${resolvedLocationId}/posts/${postId}`);
|
|
3631
3638
|
}
|
|
3632
3639
|
);
|
|
3633
3640
|
safeTool(
|
|
@@ -3635,13 +3642,16 @@ function registerSocialPlannerTools(server2, client) {
|
|
|
3635
3642
|
"delete_social_post",
|
|
3636
3643
|
"Delete a social media post",
|
|
3637
3644
|
{
|
|
3638
|
-
postId: import_zod21.z.string().describe("The social media post ID to delete")
|
|
3645
|
+
postId: import_zod21.z.string().describe("The social media post ID to delete"),
|
|
3646
|
+
locationId: import_zod21.z.string().optional().describe("GHL Location ID (optional if GHL_LOCATION_ID is set)")
|
|
3639
3647
|
},
|
|
3640
|
-
async ({ postId }) => {
|
|
3641
|
-
|
|
3648
|
+
async ({ postId, locationId: locationId2 }) => {
|
|
3649
|
+
const resolvedLocationId = client.resolveLocationId(locationId2);
|
|
3650
|
+
return client.delete(`/social-media-posting/${resolvedLocationId}/posts/${postId}`);
|
|
3642
3651
|
}
|
|
3643
3652
|
);
|
|
3644
|
-
|
|
3653
|
+
safeTool(
|
|
3654
|
+
server2,
|
|
3645
3655
|
"get_social_media_accounts",
|
|
3646
3656
|
"Get connected social media accounts for a location",
|
|
3647
3657
|
{
|
|
@@ -3649,21 +3659,7 @@ function registerSocialPlannerTools(server2, client) {
|
|
|
3649
3659
|
},
|
|
3650
3660
|
async ({ locationId: locationId2 }) => {
|
|
3651
3661
|
const resolvedLocationId = client.resolveLocationId(locationId2);
|
|
3652
|
-
|
|
3653
|
-
const result = await client.get(
|
|
3654
|
-
`/social-media-posting/oauth/${resolvedLocationId}/accounts`
|
|
3655
|
-
);
|
|
3656
|
-
return jsonResponse(result);
|
|
3657
|
-
} catch {
|
|
3658
|
-
try {
|
|
3659
|
-
const result = await client.get(
|
|
3660
|
-
`/social-media-posting/oauth/facebook/accounts/${resolvedLocationId}`
|
|
3661
|
-
);
|
|
3662
|
-
return jsonResponse(result);
|
|
3663
|
-
} catch (fallbackError) {
|
|
3664
|
-
return errorResponse(fallbackError);
|
|
3665
|
-
}
|
|
3666
|
-
}
|
|
3662
|
+
return client.get(`/social-media-posting/${resolvedLocationId}/accounts`);
|
|
3667
3663
|
}
|
|
3668
3664
|
);
|
|
3669
3665
|
safeTool(
|
|
@@ -3673,9 +3669,11 @@ function registerSocialPlannerTools(server2, client) {
|
|
|
3673
3669
|
{
|
|
3674
3670
|
locationId: import_zod21.z.string().optional().describe("GHL Location ID (optional if GHL_LOCATION_ID is set)"),
|
|
3675
3671
|
accountIds: import_zod21.z.array(import_zod21.z.string()).describe("Array of social account IDs to post to"),
|
|
3672
|
+
userId: import_zod21.z.string().optional().describe("GHL user ID that authors the post (required by the API; falls back to GHL_USER_ID env)"),
|
|
3676
3673
|
summary: import_zod21.z.string().optional().describe("The post text/caption"),
|
|
3677
3674
|
media: import_zod21.z.array(import_zod21.z.string()).optional().describe("Array of media URLs to attach"),
|
|
3678
|
-
|
|
3675
|
+
type: import_zod21.z.enum(["post", "story", "reel"]).optional().describe("Post type (default post)"),
|
|
3676
|
+
status: import_zod21.z.enum(["in_review", "scheduled", "draft", "published"]).optional().describe("Post status"),
|
|
3679
3677
|
scheduledAt: import_zod21.z.string().optional().describe("Scheduled publish time (ISO string)"),
|
|
3680
3678
|
tags: import_zod21.z.array(import_zod21.z.string()).optional().describe("Tags for the post"),
|
|
3681
3679
|
ogData: import_zod21.z.object({
|
|
@@ -3684,16 +3682,41 @@ function registerSocialPlannerTools(server2, client) {
|
|
|
3684
3682
|
image: import_zod21.z.string().optional()
|
|
3685
3683
|
}).optional().describe("Open Graph data for link previews")
|
|
3686
3684
|
},
|
|
3687
|
-
async ({ locationId: locationId2, accountIds, summary, media, status, scheduledAt, tags, ogData }) => {
|
|
3685
|
+
async ({ locationId: locationId2, accountIds, userId, summary, media, type, status, scheduledAt, tags, ogData }) => {
|
|
3688
3686
|
const resolvedLocationId = client.resolveLocationId(locationId2);
|
|
3689
|
-
const
|
|
3687
|
+
const resolvedUserId = userId ?? process.env.GHL_USER_ID;
|
|
3688
|
+
if (!resolvedUserId) {
|
|
3689
|
+
throw new Error(
|
|
3690
|
+
"create_social_post requires a userId (the post author). Pass userId or set GHL_USER_ID."
|
|
3691
|
+
);
|
|
3692
|
+
}
|
|
3693
|
+
const body = {
|
|
3694
|
+
accountIds,
|
|
3695
|
+
userId: resolvedUserId,
|
|
3696
|
+
type: type ?? "post"
|
|
3697
|
+
};
|
|
3690
3698
|
if (summary !== void 0) body.summary = summary;
|
|
3691
|
-
if (media !== void 0)
|
|
3699
|
+
if (media !== void 0) {
|
|
3700
|
+
const mimeFor = (url) => {
|
|
3701
|
+
const ext = url.split("?")[0].split(".").pop()?.toLowerCase() ?? "";
|
|
3702
|
+
const map = {
|
|
3703
|
+
png: "image/png",
|
|
3704
|
+
jpg: "image/jpeg",
|
|
3705
|
+
jpeg: "image/jpeg",
|
|
3706
|
+
gif: "image/gif",
|
|
3707
|
+
webp: "image/webp",
|
|
3708
|
+
mp4: "video/mp4",
|
|
3709
|
+
mov: "video/quicktime"
|
|
3710
|
+
};
|
|
3711
|
+
return map[ext] ?? "image/png";
|
|
3712
|
+
};
|
|
3713
|
+
body.media = media.map((url) => ({ url, type: mimeFor(url) }));
|
|
3714
|
+
}
|
|
3692
3715
|
if (status !== void 0) body.status = status;
|
|
3693
|
-
if (scheduledAt !== void 0) body.
|
|
3716
|
+
if (scheduledAt !== void 0) body.scheduleDate = scheduledAt;
|
|
3694
3717
|
if (tags !== void 0) body.tags = tags;
|
|
3695
3718
|
if (ogData !== void 0) body.ogData = ogData;
|
|
3696
|
-
return client.post(
|
|
3719
|
+
return client.post(`/social-media-posting/${resolvedLocationId}/posts`, { body });
|
|
3697
3720
|
}
|
|
3698
3721
|
);
|
|
3699
3722
|
}
|
|
@@ -4791,13 +4814,21 @@ function registerWorkflowBuilderTools(server2, client) {
|
|
|
4791
4814
|
if (!client) {
|
|
4792
4815
|
server2.tool(
|
|
4793
4816
|
"workflow_builder_status",
|
|
4794
|
-
"Check if the workflow builder (internal API) is configured.
|
|
4817
|
+
"Check if the workflow builder (internal API) is configured. Needs Firebase credentials, added via enable_workflow_builder.",
|
|
4795
4818
|
{},
|
|
4796
4819
|
async () => ({
|
|
4797
4820
|
content: [
|
|
4798
4821
|
{
|
|
4799
4822
|
type: "text",
|
|
4800
|
-
text:
|
|
4823
|
+
text: [
|
|
4824
|
+
"Workflow builder is NOT configured (Firebase credentials missing).",
|
|
4825
|
+
"",
|
|
4826
|
+
"To enable the 49 Firebase-gated tools, run enable_workflow_builder with your three Firebase values (ghl_user_id, ghl_firebase_api_key, ghl_firebase_refresh_token) captured from a logged-in GHL browser tab. Step-by-step DevTools guide: https://elitedcs.com/ghl-mcp-firebase",
|
|
4827
|
+
"",
|
|
4828
|
+
"Do NOT add these as env vars in your Claude Desktop config \u2014 that path is unreliable and is the usual reason this still shows missing after a restart. enable_workflow_builder validates the values and saves them for you; then fully quit and reopen Claude.",
|
|
4829
|
+
"",
|
|
4830
|
+
"(Advanced / self-hosted wrapper only: GHL_FIREBASE_API_KEY, GHL_FIREBASE_REFRESH_TOKEN, GHL_USER_ID via start-mcp.sh or .env.)"
|
|
4831
|
+
].join("\n")
|
|
4801
4832
|
}
|
|
4802
4833
|
],
|
|
4803
4834
|
isError: true
|
|
@@ -8041,7 +8072,7 @@ function registerDiagnosticTools(server2, installedVersion, client, builderClien
|
|
|
8041
8072
|
})();
|
|
8042
8073
|
const firebasePromise = (async () => {
|
|
8043
8074
|
if (!builderClient) {
|
|
8044
|
-
return { name: "Firebase auth (workflow builder)", status: "skip", detail: "Not configured. The 49 Firebase-gated tools need Firebase credentials. The other 163 tools work fine without. To add it: run enable_workflow_builder with the three Firebase values from your GHL browser session (see elitedcs.com/ghl-mcp-firebase for DevTools steps)." };
|
|
8075
|
+
return { name: "Firebase auth (workflow builder)", status: "skip", detail: "Not configured. The 49 Firebase-gated tools need Firebase credentials. The other 163 tools work fine without. To add it: run enable_workflow_builder with the three Firebase values from your GHL browser session (see elitedcs.com/ghl-mcp-firebase for DevTools steps). Do NOT put Firebase values as env vars in your Claude Desktop config \u2014 that path is unreliable and is the usual reason this still shows skip after a restart. enable_workflow_builder saves and verifies them for you." };
|
|
8045
8076
|
}
|
|
8046
8077
|
const result = await builderClient.checkAuth();
|
|
8047
8078
|
const activeCompany = builderClient.getCurrentCompanyId();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elitedcs/ghl-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.18.0",
|
|
4
4
|
"description": "GoHighLevel MCP Server for Claude. 212 tools — full CRM, automation, marketing control, and the only programmatic GHL workflow builder, now multi-tenant across client accounts.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -37,10 +37,11 @@
|
|
|
37
37
|
"homepage": "https://elitedcs.com/ghl-mcp-server",
|
|
38
38
|
"repository": {
|
|
39
39
|
"type": "git",
|
|
40
|
-
"url": "git+https://github.com/drjerryrelth/
|
|
40
|
+
"url": "git+https://github.com/drjerryrelth/ghl-command-feedback.git"
|
|
41
41
|
},
|
|
42
42
|
"bugs": {
|
|
43
|
-
"url": "https://github.com/drjerryrelth/
|
|
43
|
+
"url": "https://github.com/drjerryrelth/ghl-command-feedback/issues",
|
|
44
|
+
"email": "support@cliniclaunchlab.com"
|
|
44
45
|
},
|
|
45
46
|
"publishConfig": {
|
|
46
47
|
"access": "public"
|