@elitedcs/ghl-mcp 3.2.0 → 3.3.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 CHANGED
@@ -1,5 +1,40 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.3.0 — 100% native trigger coverage
4
+
5
+ **173 tools across 36 modules. Bundle: 255.4 KB.**
6
+
7
+ All **57 of 57** native GHL workflow trigger types now have their own typed Zod variant in `WorkflowTriggerSchema`. Claude can discriminate every trigger type by name and read documented field paths where the catalogue captured them.
8
+
9
+ Field-documentation completeness (per trigger, marked in the schema's `.describe()` so the LLM knows):
10
+
11
+ - **42 fully documented** — every filter field path captured (e.g., `contact_changed` with 12 fields, `opportunity_decay` with 9, `survey_submission`, `birthday_reminder`, etc.)
12
+ - **4 partial** — some fields captured, others not: `custom_date_reminder`, `inbound_trigger`, `facebook_comment_on_post`, `ig_comment_on_post`. Reads still pass; LLM is told docs are partial.
13
+ - **2 fieldless by design** — `inbound_webhook`, `payment_received` (fire on any event)
14
+ - **9 uncaptured** — typed-but-no-docs: `affiliate_created`, `scheduler_trigger`, `user_log_in`, `order_submission`, `conv_ai_trigger`, `conv_ai_autonomous_trigger`, `custom_object_created`, `custom_object_changed`, `facebook_lead_gen`. Most rarely used. Type discrimination still works; field paths to be backfilled when buyers need them.
15
+
16
+ ### Backfills
17
+ - The 4 originally-typed triggers (contact_tag, appointment, customer_reply, pipeline_stage_updated) had incomplete field lists in v3.2.0. Now enriched with all captured fields. `customer_reply` went from "no fields documented" to `workflow.id, message.type, message.body, contact.tags`.
18
+
19
+ ### Coverage delta
20
+ | State | Typed | Reachable-but-untyped | Total |
21
+ |---|---:|---:|---:|
22
+ | Before v3.1.0 | 4 | 0 (reads crashed) | 57 |
23
+ | v3.1.0 | 4 | 53 | 57 |
24
+ | v3.2.0 | 13 | 44 | 57 |
25
+ | **v3.3.0** | **57** | **0** | **57** |
26
+
27
+ ### Future-proof
28
+ Even though every native trigger has a typed variant now, `UnknownTriggerSchema` is still in the union as the last fallback — if GHL ships a new trigger type, reads will pass through cleanly instead of throwing.
29
+
30
+ ### Verified
31
+ - 57 / 57 typed variants matched their own type literal via runtime z.union parse test
32
+ - A synthetic "future_trigger_ghl_invents" type still passes through via the fallback
33
+ - Build: 255.4 KB (up from 248.4 KB; +7 KB for the 44 new variants)
34
+
35
+ ### Files changed
36
+ - `src/trigger-schemas.ts` — all 57 typed variants + 4 doc-completeness statuses (`documented`, `partial`, `fieldless`, `uncaptured`) so the LLM's expectations match each trigger's reality.
37
+
3
38
  ## 3.2.0 — Deep trigger typing
4
39
 
5
40
  **173 tools across 36 modules. Bundle: 248.4 KB.**
package/README.md CHANGED
@@ -350,7 +350,7 @@ Re-run setup_ghl_mcp with workflow builder:
350
350
 
351
351
  **Supported action types:** `sms`, `email`, `add_contact_tag`, `remove_contact_tag`, `update_contact_field`, `wait`, `if_else`, `webhook`, `create_opportunity`, `custom_code`, `add_notes`, `internal_notification`, `task-notification`, `remove_from_workflow`, and more.
352
352
 
353
- **Supported trigger types:** All 57 native GHL trigger types read cleanly. **13 are deeply typed** with documented field paths (contact_tag, customer_reply, appointment, pipeline_stage_updated, form_submission, opportunity_created, opportunity_changed, opportunity_status_changed, payment_received, inbound_webhook, mailgun_email_event, note_add, task_added). The other 44 pass through a permissive schema so workflows never fail to read regardless of trigger type. Plus 434 marketplace trigger entries across 85 third-party apps — query them via `get_trigger_registry`.
353
+ **Supported trigger types:** **All 57 native GHL trigger types are deeply typed** with their own Zod variant. 42 have full field-path documentation (`opportunity_*`, `form_submission`, `contact_changed`, `survey_submission`, `birthday_reminder`, `mailgun_email_event`, and 36 others). 4 have partial docs, 2 are fieldless by design, 9 have type-only discrimination pending field-path capture. A permissive fallback handles any future trigger types GHL ships, so reads never crash. Plus 434 marketplace trigger entries across 85 third-party apps — query them via `get_trigger_registry`.
354
354
 
355
355
  ### Pipeline Builder (5 tools) — Internal API
356
356
 
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.2.0",
34
+ version: "3.3.0",
35
35
  description: "GoHighLevel MCP Server for Claude. 173 tools \u2014 full CRM, automation, marketing control, and the only programmatic GHL workflow builder.",
36
36
  main: "dist/index.js",
37
37
  bin: {
@@ -405,12 +405,24 @@ var TriggerCommonSchema = import_zod2.z.object({
405
405
  schedule_config: import_zod2.z.record(import_zod2.z.unknown()).optional(),
406
406
  date_updated: import_zod2.z.string().optional()
407
407
  }).passthrough();
408
- function typedTrigger(typeLiteral, knownFields) {
409
- const fieldDesc = knownFields.length === 0 ? "No filter fields \u2014 trigger matches any event of this type." : `Known field paths: ${knownFields.join(", ")}.`;
408
+ function describe(status, knownFields) {
409
+ switch (status) {
410
+ case "fieldless":
411
+ return "No filter fields \u2014 trigger fires on any event of this type.";
412
+ case "documented":
413
+ return `Known field paths: ${knownFields.join(", ")}.`;
414
+ case "partial":
415
+ return knownFields.length > 0 ? `Known field paths: ${knownFields.join(", ")}. Note: GHL exposes additional filter fields that aren't yet captured; pass them through if known.` : "GHL exposes one or more filter fields for this trigger; the exact field paths are not yet captured. Pass through whatever you know from the GHL UI.";
416
+ case "uncaptured":
417
+ return "Filter field paths not yet captured. Pass through whatever fields you know from the GHL UI; reads will accept any.";
418
+ }
419
+ }
420
+ function typedTrigger(typeLiteral, knownFields, status = "documented") {
421
+ const fieldDesc = describe(status, knownFields);
410
422
  return TriggerCommonSchema.extend({
411
423
  type: import_zod2.z.literal(typeLiteral),
412
424
  conditions: import_zod2.z.array(import_zod2.z.object({
413
- operator: import_zod2.z.string().describe("Comparison operator (equals, greater_than, less_than, contains, index-of-true, etc.)."),
425
+ operator: import_zod2.z.string().describe("Comparison operator (equals, greater_than, less_than, contains, index-of-true, is-any-of, etc.)."),
414
426
  field: import_zod2.z.string().describe(fieldDesc),
415
427
  value: import_zod2.z.unknown().optional(),
416
428
  title: import_zod2.z.string().optional(),
@@ -430,9 +442,6 @@ var ContactTagTriggerSchema = TriggerCommonSchema.extend({
430
442
  id: import_zod2.z.string().optional()
431
443
  }).passthrough())
432
444
  });
433
- var CustomerReplyTriggerSchema = typedTrigger("customer_reply", [
434
- // No fields in the catalogue — Customer Reply matches any inbound message.
435
- ]);
436
445
  var AppointmentTriggerSchema = typedTrigger("appointment", [
437
446
  "calendar.id",
438
447
  "appointment.status",
@@ -441,15 +450,105 @@ var AppointmentTriggerSchema = typedTrigger("appointment", [
441
450
  "appointment.eventType",
442
451
  "appointment.modifiedBy"
443
452
  ]);
444
- var PipelineStageUpdatedTriggerSchema = typedTrigger("pipeline_stage_updated", [
445
- "opportunity.pipelineId",
446
- "opportunity.pipelineStageId",
453
+ var BirthdayReminderTriggerSchema = typedTrigger("birthday_reminder", [
454
+ "contact.birthMonth",
455
+ "contact.birthDay",
456
+ "contact.dateOfBirth"
457
+ ]);
458
+ var CallStatusTriggerSchema = typedTrigger("call_status", [
459
+ "call_status",
460
+ "custom_disposition",
461
+ "message.direction",
462
+ "workflow.id"
463
+ ]);
464
+ var CategoryCompletedTriggerSchema = typedTrigger("category_completed", [
465
+ "membership.product.id"
466
+ ]);
467
+ var CategoryStartedTriggerSchema = typedTrigger("category_started", [
468
+ "membership.product.id"
469
+ ]);
470
+ var ContactChangedTriggerSchema = typedTrigger("contact_changed", [
471
+ "contact.tags",
472
+ "contact.dnd",
473
+ "contact.assignedTo",
474
+ "contact.phone",
475
+ "contact.email",
476
+ "contact.type",
477
+ "contact.address1",
478
+ "contact.city",
479
+ "contact.state",
480
+ "contact.country",
481
+ "contact.postalCode",
482
+ "contact.website"
483
+ ]);
484
+ var ContactCreatedTriggerSchema = typedTrigger("contact_created", [
485
+ "tagsAdded",
486
+ "contact.phone",
487
+ "contact.email",
488
+ "contact.type"
489
+ ]);
490
+ var CustomerAppointmentTriggerSchema = typedTrigger("customer_appointment", [
491
+ "calendar.id",
492
+ "contact.tags"
493
+ ]);
494
+ var CustomerReplyTriggerSchema = typedTrigger("customer_reply", [
495
+ "workflow.id",
496
+ "message.type",
497
+ "message.body",
498
+ "contact.tags"
499
+ ]);
500
+ var DndContactTriggerSchema = typedTrigger("dnd_contact", [
501
+ "contact.dnd_direction",
502
+ "contact.dnd",
447
503
  "contact.tags"
448
504
  ]);
449
505
  var FormSubmissionTriggerSchema = typedTrigger("form_submission", [
450
506
  "form.id",
451
507
  "formData.termsAndConditions"
452
508
  ]);
509
+ var InvoiceTriggerSchema = typedTrigger("invoice", [
510
+ "invoice.status",
511
+ "contact.tags"
512
+ ]);
513
+ var IvrIncomingCallTriggerSchema = typedTrigger("ivr_incoming_call", [
514
+ "inbound_number"
515
+ ]);
516
+ var LessonCompletedTriggerSchema = typedTrigger("lesson_completed", [
517
+ "membership.product.id"
518
+ ]);
519
+ var LessonStartedTriggerSchema = typedTrigger("lesson_started", [
520
+ "membership.product.id"
521
+ ]);
522
+ var MailgunEmailEventTriggerSchema = typedTrigger("mailgun_email_event", [
523
+ "workflow.id",
524
+ "mailgun.event"
525
+ // opened | clicked | bounced | delivered | etc.
526
+ ]);
527
+ var MembershipContactCreatedTriggerSchema = typedTrigger("membership_contact_created", [
528
+ "offer.id"
529
+ ]);
530
+ var NoteAddTriggerSchema = typedTrigger("note_add", [
531
+ "contact.tags"
532
+ ]);
533
+ var NoteChangedTriggerSchema = typedTrigger("note_changed", [
534
+ "contact.tags"
535
+ ]);
536
+ var OfferAccessGrantedTriggerSchema = typedTrigger("offer_access_granted", [
537
+ "offer.id"
538
+ ]);
539
+ var OfferAccessRemovedTriggerSchema = typedTrigger("offer_access_removed", [
540
+ "offer.id"
541
+ ]);
542
+ var OpportunityChangedTriggerSchema = typedTrigger("opportunity_changed", [
543
+ "opportunity.pipelineId",
544
+ "contact.tags",
545
+ "opportunity.assignedTo",
546
+ "opportunity.monetaryValue",
547
+ "opportunity.forecastExpectedCloseDate",
548
+ "opportunity.forecastProbability",
549
+ "opportunity.status",
550
+ "opportunity.lostReasonId"
551
+ ]);
453
552
  var OpportunityCreatedTriggerSchema = typedTrigger("opportunity_created", [
454
553
  "opportunity.pipelineId",
455
554
  "contact.tags",
@@ -460,8 +559,9 @@ var OpportunityCreatedTriggerSchema = typedTrigger("opportunity_created", [
460
559
  "opportunity.status",
461
560
  "opportunity.lostReasonId"
462
561
  ]);
463
- var OpportunityChangedTriggerSchema = typedTrigger("opportunity_changed", [
562
+ var OpportunityDecayTriggerSchema = typedTrigger("opportunity_decay", [
464
563
  "opportunity.pipelineId",
564
+ "opportunity.lastActionDate",
465
565
  "contact.tags",
466
566
  "opportunity.assignedTo",
467
567
  "opportunity.monetaryValue",
@@ -481,44 +581,146 @@ var OpportunityStatusChangedTriggerSchema = typedTrigger("opportunity_status_cha
481
581
  "opportunity.forecastProbability",
482
582
  "opportunity.lostReasonId"
483
583
  ]);
484
- var PaymentReceivedTriggerSchema = typedTrigger("payment_received", [
485
- // No filter fields — fires on any payment received.
584
+ var PipelineStageUpdatedTriggerSchema = typedTrigger("pipeline_stage_updated", [
585
+ "opportunity.pipelineId",
586
+ "opportunity.pipelineStageId",
587
+ // not in catalogue but central to this trigger by name
588
+ "contact.tags",
589
+ "opportunity.assignedTo",
590
+ "opportunity.monetaryValue",
591
+ "opportunity.forecastExpectedCloseDate",
592
+ "opportunity.forecastProbability",
593
+ "opportunity.status",
594
+ "opportunity.lostReasonId"
486
595
  ]);
487
- var InboundWebhookTriggerSchema = typedTrigger("inbound_webhook", [
488
- // No filter fields — fires on any inbound webhook hit.
596
+ var ProductAccessGrantedTriggerSchema = typedTrigger("product_access_granted", [
597
+ "product.id"
489
598
  ]);
490
- var MailgunEmailEventTriggerSchema = typedTrigger("mailgun_email_event", [
491
- "workflow.id",
492
- "mailgun.event"
493
- // opened | clicked | bounced | delivered | etc.
599
+ var ProductAccessRemovedTriggerSchema = typedTrigger("product_access_removed", [
600
+ "product.id"
494
601
  ]);
495
- var NoteAddTriggerSchema = typedTrigger("note_add", [
496
- "contact.tags"
602
+ var ProductCompletedTriggerSchema = typedTrigger("product_completed", [
603
+ "membership.product.id"
604
+ ]);
605
+ var ProductStartedTriggerSchema = typedTrigger("product_started", [
606
+ "membership.product.id"
607
+ ]);
608
+ var ShopifyAbandonedCartTriggerSchema = typedTrigger("shopify_abandoned_cart", [
609
+ "duration",
610
+ "cart_value"
611
+ ]);
612
+ var ShopifyOrderFulfilledTriggerSchema = typedTrigger("shopify_order_fulfilled", [
613
+ "cart_value"
614
+ ]);
615
+ var ShopifyOrderPlacedTriggerSchema = typedTrigger("shopify_order_placed", [
616
+ "cart_value"
617
+ ]);
618
+ var SurveySubmissionTriggerSchema = typedTrigger("survey_submission", [
619
+ "survey.id",
620
+ "surveySubmission.disqualified",
621
+ "surveyData.termsAndConditions"
497
622
  ]);
498
623
  var TaskAddedTriggerSchema = typedTrigger("task_added", [
499
624
  "task.assignedTo"
500
625
  ]);
626
+ var TaskDueDateReminderTriggerSchema = typedTrigger("task_due_date_reminder", [
627
+ "task.dueDate"
628
+ ]);
629
+ var TikTokFormSubmittedTriggerSchema = typedTrigger("tik_tok_form_submitted", [
630
+ "tikTok.formId"
631
+ ]);
632
+ var TriggerLinkTriggerSchema = typedTrigger("trigger_link", [
633
+ "link.id"
634
+ ]);
635
+ var TwoStepFormSubmissionTriggerSchema = typedTrigger("two_step_form_submission", [
636
+ "twoStepOrderForm.funnelId",
637
+ "twoStepOrderForm.submissionType"
638
+ ]);
639
+ var ValidationErrorTriggerSchema = typedTrigger("validation_error", [
640
+ "contact.phoneInfo"
641
+ ]);
642
+ var VideoEventTriggerSchema = typedTrigger("video_event", [
643
+ "video.funnelId",
644
+ "video.videoId",
645
+ "video.duration"
646
+ ]);
647
+ var CustomDateReminderTriggerSchema = typedTrigger("custom_date_reminder", [], "partial");
648
+ var InboundTriggerTriggerSchema = typedTrigger("inbound_trigger", ["contact.tags"], "partial");
649
+ var FacebookCommentOnPostTriggerSchema = typedTrigger("facebook_comment_on_post", [], "partial");
650
+ var IgCommentOnPostTriggerSchema = typedTrigger("ig_comment_on_post", [], "partial");
651
+ var InboundWebhookTriggerSchema = typedTrigger("inbound_webhook", [], "fieldless");
652
+ var PaymentReceivedTriggerSchema = typedTrigger("payment_received", [], "fieldless");
653
+ var AffiliateCreatedTriggerSchema = typedTrigger("affiliate_created", [], "uncaptured");
654
+ var SchedulerTriggerTriggerSchema = typedTrigger("scheduler_trigger", [], "uncaptured");
655
+ var UserLogInTriggerSchema = typedTrigger("user_log_in", [], "uncaptured");
656
+ var OrderSubmissionTriggerSchema = typedTrigger("order_submission", [], "uncaptured");
657
+ var ConvAiTriggerTriggerSchema = typedTrigger("conv_ai_trigger", [], "uncaptured");
658
+ var ConvAiAutonomousTriggerTriggerSchema = typedTrigger("conv_ai_autonomous_trigger", [], "uncaptured");
659
+ var CustomObjectCreatedTriggerSchema = typedTrigger("custom_object_created", [], "uncaptured");
660
+ var CustomObjectChangedTriggerSchema = typedTrigger("custom_object_changed", [], "uncaptured");
661
+ var FacebookLeadGenTriggerSchema = typedTrigger("facebook_lead_gen", [], "uncaptured");
501
662
  var UnknownTriggerSchema = TriggerCommonSchema.extend({
502
663
  type: import_zod2.z.string(),
503
664
  conditions: import_zod2.z.array(import_zod2.z.record(import_zod2.z.unknown())).optional()
504
665
  });
505
666
  var WorkflowTriggerSchema = import_zod2.z.union([
506
- // Originally typed (v3.0.x)
507
667
  ContactTagTriggerSchema,
508
- CustomerReplyTriggerSchema,
509
668
  AppointmentTriggerSchema,
510
- PipelineStageUpdatedTriggerSchema,
511
- // Added in v3.2.0
669
+ BirthdayReminderTriggerSchema,
670
+ CallStatusTriggerSchema,
671
+ CategoryCompletedTriggerSchema,
672
+ CategoryStartedTriggerSchema,
673
+ ContactChangedTriggerSchema,
674
+ ContactCreatedTriggerSchema,
675
+ CustomerAppointmentTriggerSchema,
676
+ CustomerReplyTriggerSchema,
677
+ DndContactTriggerSchema,
512
678
  FormSubmissionTriggerSchema,
513
- OpportunityCreatedTriggerSchema,
514
- OpportunityChangedTriggerSchema,
515
- OpportunityStatusChangedTriggerSchema,
516
- PaymentReceivedTriggerSchema,
517
- InboundWebhookTriggerSchema,
679
+ InvoiceTriggerSchema,
680
+ IvrIncomingCallTriggerSchema,
681
+ LessonCompletedTriggerSchema,
682
+ LessonStartedTriggerSchema,
518
683
  MailgunEmailEventTriggerSchema,
684
+ MembershipContactCreatedTriggerSchema,
519
685
  NoteAddTriggerSchema,
686
+ NoteChangedTriggerSchema,
687
+ OfferAccessGrantedTriggerSchema,
688
+ OfferAccessRemovedTriggerSchema,
689
+ OpportunityChangedTriggerSchema,
690
+ OpportunityCreatedTriggerSchema,
691
+ OpportunityDecayTriggerSchema,
692
+ OpportunityStatusChangedTriggerSchema,
693
+ PipelineStageUpdatedTriggerSchema,
694
+ ProductAccessGrantedTriggerSchema,
695
+ ProductAccessRemovedTriggerSchema,
696
+ ProductCompletedTriggerSchema,
697
+ ProductStartedTriggerSchema,
698
+ ShopifyAbandonedCartTriggerSchema,
699
+ ShopifyOrderFulfilledTriggerSchema,
700
+ ShopifyOrderPlacedTriggerSchema,
701
+ SurveySubmissionTriggerSchema,
520
702
  TaskAddedTriggerSchema,
521
- // Fallback for the remaining 44 native trigger types + any future ones
703
+ TaskDueDateReminderTriggerSchema,
704
+ TikTokFormSubmittedTriggerSchema,
705
+ TriggerLinkTriggerSchema,
706
+ TwoStepFormSubmissionTriggerSchema,
707
+ ValidationErrorTriggerSchema,
708
+ VideoEventTriggerSchema,
709
+ CustomDateReminderTriggerSchema,
710
+ InboundTriggerTriggerSchema,
711
+ FacebookCommentOnPostTriggerSchema,
712
+ IgCommentOnPostTriggerSchema,
713
+ InboundWebhookTriggerSchema,
714
+ PaymentReceivedTriggerSchema,
715
+ AffiliateCreatedTriggerSchema,
716
+ SchedulerTriggerTriggerSchema,
717
+ UserLogInTriggerSchema,
718
+ OrderSubmissionTriggerSchema,
719
+ ConvAiTriggerTriggerSchema,
720
+ ConvAiAutonomousTriggerTriggerSchema,
721
+ CustomObjectCreatedTriggerSchema,
722
+ CustomObjectChangedTriggerSchema,
723
+ FacebookLeadGenTriggerSchema,
522
724
  UnknownTriggerSchema
523
725
  ]);
524
726
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elitedcs/ghl-mcp",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "GoHighLevel MCP Server for Claude. 173 tools — full CRM, automation, marketing control, and the only programmatic GHL workflow builder.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {