conduyt-mcp 4.32.0 → 4.34.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/dist/tools/contacts.js
CHANGED
|
@@ -21,9 +21,11 @@ export function registerContactTools(server, client) {
|
|
|
21
21
|
tag: z.string().optional().describe("Filter by tag name"),
|
|
22
22
|
source: z.string().optional().describe("Filter by source (e.g. 'signup', 'import', 'manual')"),
|
|
23
23
|
assignedTo: z.string().optional().describe("Filter by assigned user ID"),
|
|
24
|
+
masterStatus: z.array(z.string().trim().min(1).max(40)).max(20).optional().describe("Only contacts whose LEAD (master) status is one of these: 'open', 'won', 'lost', 'abandoned', 'disqualified' or an account custom status. Unknown values are a 400."),
|
|
25
|
+
excludeMasterStatus: z.array(z.string().trim().min(1).max(40)).max(20).optional().describe("Hide contacts whose lead status is one of these — e.g. ['won','lost','abandoned','disqualified'] is the 'Active' view. Naming a status in both lists is a 400."),
|
|
24
26
|
page: z.number().optional().describe("Page number (default 1)"),
|
|
25
27
|
per_page: z.number().optional().describe("Results per page (default 25, max 100)"),
|
|
26
|
-
}, async ({ search, tag, source, assignedTo, page, per_page }) => {
|
|
28
|
+
}, async ({ search, tag, source, assignedTo, masterStatus, excludeMasterStatus, page, per_page }) => {
|
|
27
29
|
const params = new URLSearchParams();
|
|
28
30
|
if (search)
|
|
29
31
|
params.set("search", search);
|
|
@@ -33,6 +35,10 @@ export function registerContactTools(server, client) {
|
|
|
33
35
|
params.set("source", source);
|
|
34
36
|
if (assignedTo)
|
|
35
37
|
params.set("assigned_to", assignedTo);
|
|
38
|
+
if (masterStatus?.length)
|
|
39
|
+
params.set("master_status", masterStatus.join(","));
|
|
40
|
+
if (excludeMasterStatus?.length)
|
|
41
|
+
params.set("exclude_master_status", excludeMasterStatus.join(","));
|
|
36
42
|
if (page)
|
|
37
43
|
params.set("page", String(page));
|
|
38
44
|
if (per_page)
|
package/dist/tools/lifecycle.js
CHANGED
|
@@ -36,7 +36,7 @@ const masterStatusName = z
|
|
|
36
36
|
.max(40)
|
|
37
37
|
.regex(/^[a-z0-9][a-z0-9 _-]*$/i, "letters, numbers, spaces, - and _ only");
|
|
38
38
|
export function registerLifecycleTools(server, client) {
|
|
39
|
-
server.tool("conduyt_get_lifecycle_settings", "Read the account's Lifecycle v2
|
|
39
|
+
server.tool("conduyt_get_lifecycle_settings", "Read the account's Lifecycle configuration (v2 + v3), shaped for read-before-write: dealWorkingMode and lostPropagation say how the tenant works leads and whether lost propagation is live; masterStatuses.effective is the full list a contact's masterStatus may take (the five built-in defaults plus the account's customs — the raw settings key stores only the customs); intakeDeals is the automatic deal-on-intake config, or null with an intakeDealsNote explaining that null can mean either not-configured or not-visible-to-your-key (the setting is admin-visible; member-tier responses omit it).", {}, async () => {
|
|
40
40
|
const result = await client.get("/api/v1/settings");
|
|
41
41
|
const raw = result?.data ?? {};
|
|
42
42
|
const customs = Array.isArray(raw.masterStatuses)
|
|
@@ -46,7 +46,22 @@ export function registerLifecycleTools(server, client) {
|
|
|
46
46
|
// and an unconfigured account also lacks it. The two are not
|
|
47
47
|
// distinguishable from here, so null is reported with a note saying so.
|
|
48
48
|
const intakeDeals = raw.intakeDeals && typeof raw.intakeDeals === "object" ? raw.intakeDeals : null;
|
|
49
|
+
// Lifecycle v3 (2026-09-08): how the tenant works leads, and whether LOST
|
|
50
|
+
// propagation is live for it (P2: contact flips to lost when its LAST
|
|
51
|
+
// open card closes lost; a new open card reopens it; forward-only from
|
|
52
|
+
// enabledAt; off = the nightly shadow report only).
|
|
53
|
+
const dealWorkingMode = raw.dealWorkingMode === "pipeline" || raw.dealWorkingMode === "status" ? raw.dealWorkingMode : null;
|
|
54
|
+
const lostRaw = raw.lostPropagation && typeof raw.lostPropagation === "object" ? raw.lostPropagation : null;
|
|
55
|
+
const lostPropagation = {
|
|
56
|
+
enabled: lostRaw?.enabled === true,
|
|
57
|
+
enabledAt: typeof lostRaw?.enabledAt === "string" ? lostRaw.enabledAt : null,
|
|
58
|
+
};
|
|
49
59
|
const shaped = {
|
|
60
|
+
dealWorkingMode,
|
|
61
|
+
dealWorkingModeNote: dealWorkingMode === null
|
|
62
|
+
? "null = not chosen yet (legacy account) — 'pipeline': every inbound contact gets a deal card (intakeDeals required); 'status': the contact is the opportunity"
|
|
63
|
+
: undefined,
|
|
64
|
+
lostPropagation,
|
|
50
65
|
masterStatuses: {
|
|
51
66
|
defaults: DEFAULT_MASTER_STATUSES,
|
|
52
67
|
customs,
|
|
@@ -68,6 +83,12 @@ export function registerLifecycleTools(server, client) {
|
|
|
68
83
|
.optional()
|
|
69
84
|
.describe("Policy for contacts that already exist (default 'if_no_open')"),
|
|
70
85
|
}, async (params) => patchGeneralSettings(client, { intakeDeals: params }));
|
|
86
|
+
server.tool("conduyt_update_deal_working_mode", "Set how this tenant works leads (Lifecycle v3). 'pipeline': every inbound contact gets a deal card in the intake pipeline — requires intakeDeals enabled with a pipelineId and stageId (conduyt_update_intake_deals first), and a new form/webhook/line cannot go live without a pipeline. 'status': the contact is the opportunity, no automatic cards (small shops). Switchable later; new tenants default to 'pipeline'.", {
|
|
87
|
+
mode: z.enum(["pipeline", "status"]).describe("'pipeline' (cards on every inbound) or 'status' (the contact is the opportunity)"),
|
|
88
|
+
}, async ({ mode }) => patchGeneralSettings(client, { dealWorkingMode: mode }));
|
|
89
|
+
server.tool("conduyt_update_lost_propagation", "Turn LOST propagation on or off for this tenant (Lifecycle v3 P2). When on: a contact's masterStatus flips to 'lost' within a minute of its LAST open deal card closing lost (a per-minute resolver applies the rule on the committed state) (carrying that card's lostReason into masterStatusReason), a new open card on a lost/abandoned/disqualified contact reopens it, and a won contact never flips. Forward-only from the first enable (enabledAt is stamped server-side): existing history never flips by itself. A terminal masterStatus silences every drip, sequence and playbook for that contact, so read the nightly shadow report first (job run 'lost-propagation-shadow': contacts that would flip, their reasons, and the automations that would go quiet) before enabling.", {
|
|
90
|
+
enabled: z.boolean().describe("true = flips happen live from now on; false = shadow report only"),
|
|
91
|
+
}, async ({ enabled }) => patchGeneralSettings(client, { lostPropagation: { enabled } }));
|
|
71
92
|
server.tool("conduyt_update_master_statuses", "Set the account's custom lead lifecycle statuses. The five defaults (open, won, lost, abandoned, disqualified) always exist and cannot be removed; this REPLACES the custom list on top of them (max 20 names, 1-40 chars each, letters/numbers/spaces/-/_ only). Terminal statuses stop all outbound automation for a contact. Requires settings:edit.", {
|
|
72
93
|
statuses: z
|
|
73
94
|
.array(masterStatusName)
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-09-
|
|
3
|
-
"toolCount":
|
|
4
|
-
"totalEndpoints":
|
|
2
|
+
"generatedAt": "2026-09-09T18:54:08.958Z",
|
|
3
|
+
"toolCount": 219,
|
|
4
|
+
"totalEndpoints": 930,
|
|
5
5
|
"counts": {
|
|
6
6
|
"covered": 202,
|
|
7
|
-
"excluded":
|
|
7
|
+
"excluded": 283,
|
|
8
8
|
"planned": 445,
|
|
9
9
|
"uncategorized": 0
|
|
10
10
|
},
|
|
@@ -1553,6 +1553,10 @@
|
|
|
1553
1553
|
"status": "excluded",
|
|
1554
1554
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1555
1555
|
},
|
|
1556
|
+
"GET /api/v1/cron/lost-propagation-shadow": {
|
|
1557
|
+
"status": "excluded",
|
|
1558
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1559
|
+
},
|
|
1556
1560
|
"GET /api/v1/cron/mailbox-delta-recovery": {
|
|
1557
1561
|
"status": "excluded",
|
|
1558
1562
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
@@ -1569,6 +1573,10 @@
|
|
|
1569
1573
|
"status": "excluded",
|
|
1570
1574
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1571
1575
|
},
|
|
1576
|
+
"GET /api/v1/cron/process-auto-dispositions": {
|
|
1577
|
+
"status": "excluded",
|
|
1578
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1579
|
+
},
|
|
1572
1580
|
"GET /api/v1/cron/process-automation-redispatch": {
|
|
1573
1581
|
"status": "excluded",
|
|
1574
1582
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
@@ -1757,6 +1765,10 @@
|
|
|
1757
1765
|
"status": "excluded",
|
|
1758
1766
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1759
1767
|
},
|
|
1768
|
+
"GET /api/v1/cron/resolve-master-status": {
|
|
1769
|
+
"status": "excluded",
|
|
1770
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1771
|
+
},
|
|
1760
1772
|
"GET /api/v1/cron/resume-imports": {
|
|
1761
1773
|
"status": "excluded",
|
|
1762
1774
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
@@ -4076,6 +4088,14 @@
|
|
|
4076
4088
|
"status": "excluded",
|
|
4077
4089
|
"reason": "inbound provider callback receivers (Twilio/Resend/etc.), not client-callable"
|
|
4078
4090
|
},
|
|
4091
|
+
"POST /api/v1/webhooks/voice/vendor-recording": {
|
|
4092
|
+
"status": "excluded",
|
|
4093
|
+
"reason": "inbound provider callback receivers (Twilio/Resend/etc.), not client-callable"
|
|
4094
|
+
},
|
|
4095
|
+
"POST /api/v1/webhooks/voice/vendor-status": {
|
|
4096
|
+
"status": "excluded",
|
|
4097
|
+
"reason": "inbound provider callback receivers (Twilio/Resend/etc.), not client-callable"
|
|
4098
|
+
},
|
|
4079
4099
|
"POST /api/v1/webhooks/voice/voicemail": {
|
|
4080
4100
|
"status": "excluded",
|
|
4081
4101
|
"reason": "inbound provider callback receivers (Twilio/Resend/etc.), not client-callable"
|