conduyt-mcp 4.24.0 → 4.26.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/index.js +2 -0
- package/dist/tools/messaging.js +2 -0
- package/dist/tools/smart-views.d.ts +3 -0
- package/dist/tools/smart-views.js +69 -0
- package/package.json +1 -1
- package/scripts/coverage-matrix.json +34 -12
package/dist/index.js
CHANGED
|
@@ -35,6 +35,7 @@ import { registerDashboardTools } from "./tools/dashboard.js";
|
|
|
35
35
|
import { registerAiExtendedTools } from "./tools/ai-extended.js";
|
|
36
36
|
import { registerWorkflowSandboxTools } from "./tools/workflow-sandbox.js";
|
|
37
37
|
import { registerPrivacyTools } from "./tools/privacy.js";
|
|
38
|
+
import { registerSmartViewTools } from "./tools/smart-views.js";
|
|
38
39
|
import { registerAccountExportTools } from "./tools/account-exports.js";
|
|
39
40
|
import { registerLifecycleTools } from "./tools/lifecycle.js";
|
|
40
41
|
import { registerReplyCaptureTools } from "./tools/reply-capture.js";
|
|
@@ -97,6 +98,7 @@ registerDashboardTools(server, client);
|
|
|
97
98
|
registerAiExtendedTools(server, client);
|
|
98
99
|
registerWorkflowSandboxTools(server, client);
|
|
99
100
|
registerPrivacyTools(server, client);
|
|
101
|
+
registerSmartViewTools(server, client);
|
|
100
102
|
registerAccountExportTools(server, client);
|
|
101
103
|
registerLifecycleTools(server, client);
|
|
102
104
|
registerReplyCaptureTools(server, client);
|
package/dist/tools/messaging.js
CHANGED
|
@@ -5,6 +5,8 @@ export function registerMessagingTools(server, client) {
|
|
|
5
5
|
contactId: z.string().describe("Contact UUID — must have a phone number on file"),
|
|
6
6
|
body: z.string().describe("SMS message body (max 1600 characters)"),
|
|
7
7
|
fromNumber: z.string().optional().describe("Sender phone number (defaults to account's primary number)"),
|
|
8
|
+
transport: z.enum(["twilio", "project_blue"]).optional().describe("'project_blue' sends from the acting user's own Project Blue iPhone line (iMessage when the lead is on Apple, SMS otherwise; the user must have a line assigned in Settings → Project Blue). Default: Twilio."),
|
|
9
|
+
idempotencyKey: z.string().min(8).max(200).optional().describe("Operation key for at-most-once sends: reuse the SAME key when retrying a send whose outcome you did not see; a settled key answers with the original message and never sends twice."),
|
|
8
10
|
}, async (params) => {
|
|
9
11
|
const result = await client.post("/api/v1/messages/sms/send", params);
|
|
10
12
|
return formatResult(result);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatResult } from "../client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Smart Views + Smart Dialing (#53). Smart Views are the admin-curated
|
|
5
|
+
* contact buckets in the sidebar; the dial-enabled ones are the Smart
|
|
6
|
+
* Dialing PRIORITIES: when an agent starts Smart Dialing the CRM feeds one
|
|
7
|
+
* lead at a time from priority 1 down (sidebar order = dial order), skipping
|
|
8
|
+
* leads in cooldown, over a cap, already connected, or on DNC. One call at a
|
|
9
|
+
* time with the agent on the line — never predictive. Dialing settings are
|
|
10
|
+
* admin-only in the API (owner/admin API keys); reads work for any key with
|
|
11
|
+
* the 'contacts' scope.
|
|
12
|
+
*/
|
|
13
|
+
const scheduleStepSchema = z.object({
|
|
14
|
+
attemptNumber: z.number().int().min(1).max(20).describe("1 = the first call, 2 = the first retry, …"),
|
|
15
|
+
delayMinutes: z.number().int().min(0).describe("Minutes to wait after the previous attempt before this one (0 = immediately)"),
|
|
16
|
+
});
|
|
17
|
+
export function registerSmartViewTools(server, client) {
|
|
18
|
+
server.tool("conduyt_list_smart_views", "List the account's Smart Views in sidebar order with their lead counts and Smart Dialing settings (dialEnabled = it is a dialing priority; sortPosition = its rank; maxDialAttempts, maxDialAttemptsPerDay, dialCooldownMinutes, dialSchedule). Use it to answer \"what does the team dial first?\" or before changing a priority.", {}, async () => {
|
|
19
|
+
const result = await client.get("/api/v1/smart-views");
|
|
20
|
+
return formatResult(result);
|
|
21
|
+
});
|
|
22
|
+
server.tool("conduyt_update_smart_view_dialing", "Change one Smart View's Smart Dialing settings (admin key): make it a priority or not, the lifetime attempt cap, the per-day cap (null = no daily cap, counted in the account timezone), the cooldown between calls to the same lead, and the retry schedule. Only the fields you pass change. Use conduyt_reorder_smart_views to change WHICH priority it is.", {
|
|
23
|
+
id: z.string().uuid().describe("Smart View UUID (from conduyt_list_smart_views)"),
|
|
24
|
+
dialEnabled: z.boolean().optional().describe("true = this view is a Smart Dialing priority; false = agents no longer dial it"),
|
|
25
|
+
maxDialAttempts: z.number().int().min(1).max(20).optional().describe("Stop after N calls to a lead, ever (1–20)"),
|
|
26
|
+
maxDialAttemptsPerDay: z
|
|
27
|
+
.number()
|
|
28
|
+
.int()
|
|
29
|
+
.min(1)
|
|
30
|
+
.max(20)
|
|
31
|
+
.nullable()
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("Most calls to one lead in a single account-local day (1–20); null removes the daily cap"),
|
|
34
|
+
dialCooldownMinutes: z.number().int().min(0).max(10080).optional().describe("Minutes to wait between calls to the same lead"),
|
|
35
|
+
dialSchedule: z
|
|
36
|
+
.array(scheduleStepSchema)
|
|
37
|
+
.min(1)
|
|
38
|
+
.max(20)
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('Retry schedule, e.g. [{"attemptNumber":1,"delayMinutes":0},{"attemptNumber":2,"delayMinutes":60},{"attemptNumber":3,"delayMinutes":1440}]'),
|
|
41
|
+
}, async ({ id, dialEnabled, maxDialAttempts, maxDialAttemptsPerDay, dialCooldownMinutes, dialSchedule }) => {
|
|
42
|
+
// Inline body (undefined fields drop out in JSON) — keeps the shape
|
|
43
|
+
// readable by the contract verifier's static parser.
|
|
44
|
+
const result = await client.patch(`/api/v1/smart-views/${encodeURIComponent(id)}`, {
|
|
45
|
+
dialEnabled,
|
|
46
|
+
maxDialAttempts,
|
|
47
|
+
maxDialAttemptsPerDay,
|
|
48
|
+
dialCooldownMinutes,
|
|
49
|
+
dialSchedule,
|
|
50
|
+
});
|
|
51
|
+
return formatResult(result);
|
|
52
|
+
});
|
|
53
|
+
server.tool("conduyt_get_smart_dialing_order", "The Smart Dialing PRIORITIES, uncapped: every dial-enabled, account-wide contact Smart View in dial order (exactly the set the queue walks; personal views and deal views are never priorities) plus the candidates that could become one. Prefer this over conduyt_list_smart_views (capped at 100) before changing the priority order.", {}, async () => {
|
|
54
|
+
const result = await client.get("/api/v1/smart-views/dial-order");
|
|
55
|
+
return formatResult(result);
|
|
56
|
+
});
|
|
57
|
+
server.tool("conduyt_set_smart_dialing_order", "Set the Smart Dialing PRIORITY order (admin key): pass the dial-enabled Smart View ids in the wanted order — every dial-enabled view exactly once, nothing else. The server rebuilds the account-wide view order so views that are not priorities keep their slots. Prefer this over conduyt_reorder_smart_views for dialing.", {
|
|
58
|
+
order: z.array(z.string().uuid()).max(2000).describe("Every dial-enabled Smart View UUID (from conduyt_get_smart_dialing_order), first = dialed first"),
|
|
59
|
+
}, async ({ order }) => {
|
|
60
|
+
const result = await client.patch("/api/v1/smart-views/dial-order", { order });
|
|
61
|
+
return formatResult(result);
|
|
62
|
+
});
|
|
63
|
+
server.tool("conduyt_reorder_smart_views", "Set the SIDEBAR order of Smart Views (admin key). Pass EVERY view id from conduyt_list_smart_views in the wanted order (max 200, no duplicates) — views you leave out keep a stale position, so always send the full list. For the dialing priority use conduyt_set_smart_dialing_order, which only needs the dial-enabled ids.", {
|
|
64
|
+
order: z.array(z.string().uuid()).min(1).max(200).describe("Every Smart View UUID, first = highest priority"),
|
|
65
|
+
}, async ({ order }) => {
|
|
66
|
+
const result = await client.patch("/api/v1/smart-views/reorder", { order });
|
|
67
|
+
return formatResult(result);
|
|
68
|
+
});
|
|
69
|
+
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-09-
|
|
3
|
-
"toolCount":
|
|
4
|
-
"totalEndpoints":
|
|
2
|
+
"generatedAt": "2026-09-06T00:25:42.269Z",
|
|
3
|
+
"toolCount": 209,
|
|
4
|
+
"totalEndpoints": 911,
|
|
5
5
|
"counts": {
|
|
6
|
-
"covered":
|
|
7
|
-
"excluded":
|
|
8
|
-
"planned":
|
|
6
|
+
"covered": 194,
|
|
7
|
+
"excluded": 274,
|
|
8
|
+
"planned": 443,
|
|
9
9
|
"uncategorized": 0
|
|
10
10
|
},
|
|
11
11
|
"matrix": {
|
|
@@ -1649,6 +1649,10 @@
|
|
|
1649
1649
|
"status": "excluded",
|
|
1650
1650
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1651
1651
|
},
|
|
1652
|
+
"GET /api/v1/cron/project-blue-inbound-reconcile": {
|
|
1653
|
+
"status": "excluded",
|
|
1654
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1655
|
+
},
|
|
1652
1656
|
"GET /api/v1/cron/prune-screen-share-sessions": {
|
|
1653
1657
|
"status": "excluded",
|
|
1654
1658
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
@@ -3520,24 +3524,42 @@
|
|
|
3520
3524
|
"reason": "smart list management"
|
|
3521
3525
|
},
|
|
3522
3526
|
"GET /api/v1/smart-views": {
|
|
3523
|
-
"status": "
|
|
3524
|
-
"
|
|
3527
|
+
"status": "covered",
|
|
3528
|
+
"tools": [
|
|
3529
|
+
"conduyt_list_smart_views"
|
|
3530
|
+
]
|
|
3525
3531
|
},
|
|
3526
3532
|
"POST /api/v1/smart-views": {
|
|
3527
3533
|
"status": "planned",
|
|
3528
3534
|
"reason": "smart view management beyond summaries"
|
|
3529
3535
|
},
|
|
3530
3536
|
"PATCH /api/v1/smart-views/:id": {
|
|
3531
|
-
"status": "
|
|
3532
|
-
"
|
|
3537
|
+
"status": "covered",
|
|
3538
|
+
"tools": [
|
|
3539
|
+
"conduyt_update_smart_view_dialing"
|
|
3540
|
+
]
|
|
3533
3541
|
},
|
|
3534
3542
|
"DELETE /api/v1/smart-views/:id": {
|
|
3535
3543
|
"status": "planned",
|
|
3536
3544
|
"reason": "smart view management beyond summaries"
|
|
3537
3545
|
},
|
|
3546
|
+
"GET /api/v1/smart-views/dial-order": {
|
|
3547
|
+
"status": "covered",
|
|
3548
|
+
"tools": [
|
|
3549
|
+
"conduyt_get_smart_dialing_order"
|
|
3550
|
+
]
|
|
3551
|
+
},
|
|
3552
|
+
"PATCH /api/v1/smart-views/dial-order": {
|
|
3553
|
+
"status": "covered",
|
|
3554
|
+
"tools": [
|
|
3555
|
+
"conduyt_set_smart_dialing_order"
|
|
3556
|
+
]
|
|
3557
|
+
},
|
|
3538
3558
|
"PATCH /api/v1/smart-views/reorder": {
|
|
3539
|
-
"status": "
|
|
3540
|
-
"
|
|
3559
|
+
"status": "covered",
|
|
3560
|
+
"tools": [
|
|
3561
|
+
"conduyt_reorder_smart_views"
|
|
3562
|
+
]
|
|
3541
3563
|
},
|
|
3542
3564
|
"GET /api/v1/sms-providers": {
|
|
3543
3565
|
"status": "planned",
|