conduyt-mcp 4.28.0 → 4.30.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.
|
@@ -155,6 +155,23 @@ export function registerAiExtendedTools(server, client) {
|
|
|
155
155
|
const result = await client.post("/api/v1/ai/actions/execute", { actions, confirmationToken, ...(selectedIds ? { selectedIds } : {}), ...(resumeIds ? { resumeIds } : {}) });
|
|
156
156
|
return formatResult(result);
|
|
157
157
|
});
|
|
158
|
+
server.tool("conduyt_reply_suggestion", "Copilot Tier 2 — the suggested reply for a contact's LATEST inbound text or email (what they said, what they are asking, sentiment, and a draft reply shaped for the channel). Advice only: nothing is sent by this tool. state: ready | pending (the copilot has not read it yet) | none | decided | skipped (opt-out, do-not-contact, feature off).", {
|
|
159
|
+
contactId: z.string().describe("Contact UUID (must be visible to the caller)"),
|
|
160
|
+
}, async ({ contactId }) => {
|
|
161
|
+
const result = await client.get(`/api/v1/conversations/${encodeURIComponent(contactId)}/suggestion`);
|
|
162
|
+
return formatResult(result);
|
|
163
|
+
});
|
|
164
|
+
server.tool("conduyt_reply_suggestion_decide", "Copilot Tier 2 — record what was done with a suggested reply: accepted (the draft was taken into a composer), sent (with the outbound message id, after sending it through conduyt_send_message / the messages API), or dismissed. A suggestion moves once (accepted → sent is allowed).", {
|
|
165
|
+
contactId: z.string().describe("Contact UUID"),
|
|
166
|
+
messageId: z.string().describe("The inbound message the suggestion answers (suggestion.messageId)"),
|
|
167
|
+
decision: z.enum(["accepted", "sent", "dismissed"]),
|
|
168
|
+
sentMessageId: z.string().optional().describe("REQUIRED with decision=sent: the OUTBOUND message id that was sent — it must belong to this contact and be provider-confirmed (status sent/delivered, or queued with a provider id); a pending, draft or failed message is refused"),
|
|
169
|
+
}, async ({ contactId, messageId, decision, sentMessageId }) => {
|
|
170
|
+
if (decision === "sent" && !sentMessageId)
|
|
171
|
+
throw new Error("decision=sent requires sentMessageId (the confirmed outbound message that was sent)");
|
|
172
|
+
const result = await client.post(`/api/v1/conversations/${encodeURIComponent(contactId)}/suggestion`, { messageId, decision, ...(sentMessageId ? { sentMessageId } : {}) });
|
|
173
|
+
return formatResult(result);
|
|
174
|
+
});
|
|
158
175
|
server.tool("conduyt_ai_daily_brief", "AI-generated daily brief for the current user. Summarizes today's priorities — deals needing attention, overdue tasks, hot leads, and recommended focus.", {}, async () => {
|
|
159
176
|
const result = await client.get("/api/v1/ai/daily-brief");
|
|
160
177
|
return formatResult(result);
|
|
@@ -22,7 +22,7 @@ export function registerAutomationTools(server, client) {
|
|
|
22
22
|
server.tool("conduyt_create_automation", "Create a new automation. Requires a name and trigger event. Use conduyt_resolve_names to convert human-readable names to UUIDs before building actions.", {
|
|
23
23
|
name: z.string().describe("Automation name"),
|
|
24
24
|
description: z.string().optional().describe("Description of what this automation does"),
|
|
25
|
-
triggerEvent: z.string().describe("Trigger event (e.g. 'contact.created', 'deal.stage_changed', 'tag.added', 'scheduled')"),
|
|
25
|
+
triggerEvent: z.string().describe("Trigger event (e.g. 'contact.created', 'deal.stage_changed', 'tag.added', 'scheduled', or 'message.understood' — fires when the copilot has read an inbound text/email and understood its intent; list them all with conduyt_list_automation_events)"),
|
|
26
26
|
kind: z.enum(["native", "n8n"]).optional().describe("Automation type — 'native' for the built-in graph engine (use `actions`), 'n8n' for an external n8n webhook (requires n8nWorkflowId + n8nWebhookUrl). For agent-built automations use 'native'."),
|
|
27
27
|
n8nWorkflowId: z.string().optional().describe("n8n workflow ID (required when kind='n8n')"),
|
|
28
28
|
n8nWebhookUrl: z.string().optional().describe("n8n webhook URL (required when kind='n8n')"),
|
|
@@ -33,7 +33,7 @@ export function registerAutomationTools(server, client) {
|
|
|
33
33
|
triggerConditions: z
|
|
34
34
|
.any()
|
|
35
35
|
.optional()
|
|
36
|
-
.describe("Conditions that must match for the trigger to fire. Scalar filters like tagId/pipelineId/bookingPageIds, plus per-event config: for 'contact.untouched' pass { untouchedDays: N } (integer 1-365) to fire once per quiet episode when a contact has had no outreach for N+ days — without it the trigger is the minutes-scale speed-to-lead alert. Unknown keys on native events are rejected at create/publish (422)."),
|
|
36
|
+
.describe("Conditions that must match for the trigger to fire. Scalar filters like tagId/pipelineId/bookingPageIds, plus per-event config: for 'message.understood' filter on the reading with { filters: [{ field: 'trigger.intent', operator: 'equals', value: 'document_sent' }] } (intents: interested, question, callback_requested, appointment_confirm, appointment_cancel, document_sent, objection, not_interested, opt_out, wrong_number, unclear; also trigger.channel sms|email and trigger.sentiment positive|neutral|negative; {{trigger.summary}} / {{trigger.ask}} are merge fields downstream); for 'contact.untouched' pass { untouchedDays: N } (integer 1-365) to fire once per quiet episode when a contact has had no outreach for N+ days — without it the trigger is the minutes-scale speed-to-lead alert. Unknown keys on native events are rejected at create/publish (422)."),
|
|
37
37
|
}, async (params) => {
|
|
38
38
|
const result = await client.post("/api/v1/automations", params);
|
|
39
39
|
return formatResult(result);
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-09-
|
|
3
|
-
"toolCount":
|
|
4
|
-
"totalEndpoints":
|
|
2
|
+
"generatedAt": "2026-09-06T17:51:09.874Z",
|
|
3
|
+
"toolCount": 214,
|
|
4
|
+
"totalEndpoints": 919,
|
|
5
5
|
"counts": {
|
|
6
|
-
"covered":
|
|
7
|
-
"excluded":
|
|
6
|
+
"covered": 198,
|
|
7
|
+
"excluded": 276,
|
|
8
8
|
"planned": 445,
|
|
9
9
|
"uncategorized": 0
|
|
10
10
|
},
|
|
@@ -1473,6 +1473,18 @@
|
|
|
1473
1473
|
"status": "planned",
|
|
1474
1474
|
"reason": "conversation thread surfaces"
|
|
1475
1475
|
},
|
|
1476
|
+
"GET /api/v1/conversations/:contactId/suggestion": {
|
|
1477
|
+
"status": "covered",
|
|
1478
|
+
"tools": [
|
|
1479
|
+
"conduyt_reply_suggestion"
|
|
1480
|
+
]
|
|
1481
|
+
},
|
|
1482
|
+
"POST /api/v1/conversations/:contactId/suggestion": {
|
|
1483
|
+
"status": "covered",
|
|
1484
|
+
"tools": [
|
|
1485
|
+
"conduyt_reply_suggestion_decide"
|
|
1486
|
+
]
|
|
1487
|
+
},
|
|
1476
1488
|
"GET /api/v1/conversations/export": {
|
|
1477
1489
|
"status": "planned",
|
|
1478
1490
|
"reason": "conversation thread surfaces"
|
|
@@ -1637,6 +1649,10 @@
|
|
|
1637
1649
|
"status": "excluded",
|
|
1638
1650
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1639
1651
|
},
|
|
1652
|
+
"GET /api/v1/cron/process-message-insights": {
|
|
1653
|
+
"status": "excluded",
|
|
1654
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1655
|
+
},
|
|
1640
1656
|
"GET /api/v1/cron/process-outbox": {
|
|
1641
1657
|
"status": "excluded",
|
|
1642
1658
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
@@ -1999,6 +2015,10 @@
|
|
|
1999
2015
|
"conduyt_ai_call_disposition"
|
|
2000
2016
|
]
|
|
2001
2017
|
},
|
|
2018
|
+
"POST /api/v1/dialer/call/:id/facetime-status": {
|
|
2019
|
+
"status": "excluded",
|
|
2020
|
+
"reason": "realtime browser dialer (WebRTC tokens, live call control) — needs a live audio session"
|
|
2021
|
+
},
|
|
2002
2022
|
"POST /api/v1/dialer/call/:id/hangup": {
|
|
2003
2023
|
"status": "excluded",
|
|
2004
2024
|
"reason": "realtime browser dialer (WebRTC tokens, live call control) — needs a live audio session"
|