conduyt-mcp 4.93.0 → 4.94.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/README.md CHANGED
@@ -88,7 +88,7 @@ MCP server for [Conduyt CRM](https://conduyt.app) — expose your CRM as AI-acce
88
88
  | Tool | Description |
89
89
  |------|-------------|
90
90
  | `conduyt_workflow_validate` | Validate a workflow graph without saving — returns errors and warnings |
91
- | `conduyt_workflow_simulate` | Dry-run a workflow against a real or stub contact — step-by-step trace with compliance and provider checks |
91
+ | `conduyt_workflow_simulate` | Dry-run a workflow against a real or stub contact — step-by-step trace with compliance and provider checks; optional `dealId` (deal occurrence), `companyId` (company occurrence) and `executionId` (replays a stored run, admin or owner only, supplies the company its payload carried) |
92
92
  | `conduyt_workflow_promote` | Safely publish a workflow — validates first, refuses if errors exist |
93
93
 
94
94
  ### Sequences (Email and SMS)
@@ -24,19 +24,33 @@ export function registerWorkflowSandboxTools(server, client) {
24
24
  });
25
25
  return formatResult(result);
26
26
  });
27
- server.tool("conduyt_workflow_simulate", "Dry-run a saved automation against a real or stub contact. Returns a step-by-step trace of what WOULD happen — no messages sent, no tags applied, no side effects. Checks compliance (DNC, opt-outs), provider readiness (SMS/email configured), and condition evaluation. Use this to verify a workflow does what you expect before publishing.", {
27
+ server.tool("conduyt_workflow_simulate", "Dry-run a saved automation against a real or stub contact. Returns a step-by-step trace of what WOULD happen — no messages sent, no tags applied, no side effects. Checks compliance (DNC, opt-outs), provider readiness (SMS/email configured), and condition evaluation. Use this to verify a workflow does what you expect before publishing. A deal occurrence needs dealId and a company occurrence needs companyId (see those fields). executionId (optional, admin or owner only) replays a stored run of this automation and supplies ONE fact, the company carried by that run's payload; the run must belong to this account and this automation with the same trigger event, contact and deal as the preview, and without executionId on a non-company occurrence the preview is a synthetic sample whose company rules evaluate as unknown/absent, which the response states.", {
28
28
  automationId: z.string().describe("Automation UUID to simulate"),
29
29
  contactId: z.string().optional().describe("Contact UUID to simulate against. If omitted, uses a stub contact with empty fields."),
30
- }, async ({ automationId, contactId }) => {
30
+ dealId: z.string().optional().describe("The event's deal for a DEAL occurrence (deal.created / stage_changed / won / lost / ...): REQUIRED, 400 without it (the contact's newest deal is never a substitute); must be a deal you can see (deals.view and pipeline visibility), 404 otherwise; refused (400) when the selected occurrence is not a deal event (UUID)"),
31
+ companyId: z.string().optional().describe("The event's company for a COMPANY occurrence (company.created / updated / stage_changed / deleted / tagged / tag_removed): REQUIRED, 400 without it; needs companies.view, 404 when not found in this account; executionId does not replace it. On any other occurrence it is accepted only when it equals the company carried by the replayed executionId payload, else refused (400). With executionId on a company occurrence it must equal the replayed payload's company (400 otherwise). Company producers carry no contact, so contact filters on such an occurrence are judged as production judges them, without one (UUID)"),
32
+ executionId: z.string().optional().describe("Optional id of a stored run of THIS automation to replay (admin or owner only). The replay supplies ONE fact: the company carried by that run's stored payload, read the way the live runner reads it; nothing else about the subject comes from the run. The run must belong to this account and this automation, carry the same trigger event as the occurrence being previewed, and the same contact and deal as the preview; otherwise 404 (not found, or a deal run hidden from API keys without the deals scope) or 400 (other event or other subject). Runs that carry a deal are hidden from API keys without the deals scope. On a COMPANY occurrence companyId stays required and executionId does not replace it (it must equal the replayed payload's company). Omitted, on a non-company occurrence: the preview is a synthetic sample, company rules evaluate as unknown/absent, and the response says so (UUID)"),
33
+ }, async ({ automationId, contactId, dealId, companyId, executionId }) => {
31
34
  if (!UUID_RE.test(automationId)) {
32
35
  return formatResult({ error: "automationId must be a valid UUID" });
33
36
  }
34
37
  if (contactId && !UUID_RE.test(contactId)) {
35
38
  return formatResult({ error: "contactId must be a valid UUID" });
36
39
  }
40
+ for (const [name, value] of [["dealId", dealId], ["companyId", companyId], ["executionId", executionId]]) {
41
+ if (value !== undefined && !UUID_RE.test(value)) {
42
+ return formatResult({ error: `${name} must be a valid UUID` });
43
+ }
44
+ }
37
45
  const body = {};
38
46
  if (contactId)
39
47
  body.contactId = contactId;
48
+ if (dealId !== undefined)
49
+ body.dealId = dealId;
50
+ if (companyId !== undefined)
51
+ body.companyId = companyId;
52
+ if (executionId !== undefined)
53
+ body.executionId = executionId;
40
54
  const result = await client.post(`/api/v1/automations/${automationId}/dry-run`, body);
41
55
  return formatResult(result);
42
56
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conduyt-mcp",
3
- "version": "4.93.0",
3
+ "version": "4.94.0",
4
4
  "mcpName": "com.conduyt/mcp",
5
5
  "description": "MCP server for Conduyt CRM — expose CRM operations as AI-accessible tools",
6
6
  "type": "module",
@@ -1,11 +1,11 @@
1
1
  {
2
- "generatedAt": "2026-10-16T13:22:04.002Z",
2
+ "generatedAt": "2026-10-17T19:39:12.198Z",
3
3
  "toolCount": 355,
4
- "totalEndpoints": 1093,
4
+ "totalEndpoints": 1096,
5
5
  "counts": {
6
6
  "covered": 314,
7
- "excluded": 324,
8
- "planned": 455,
7
+ "excluded": 326,
8
+ "planned": 456,
9
9
  "uncategorized": 0
10
10
  },
11
11
  "matrix": {
@@ -1657,10 +1657,18 @@
1657
1657
  "status": "planned",
1658
1658
  "reason": "conversation thread surfaces"
1659
1659
  },
1660
+ "GET /api/v1/cron/analytics-account-sync": {
1661
+ "status": "excluded",
1662
+ "reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
1663
+ },
1660
1664
  "GET /api/v1/cron/apply-contact-stamps": {
1661
1665
  "status": "excluded",
1662
1666
  "reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
1663
1667
  },
1668
+ "GET /api/v1/cron/apply-product-signals": {
1669
+ "status": "excluded",
1670
+ "reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
1671
+ },
1664
1672
  "GET /api/v1/cron/booking-reminders": {
1665
1673
  "status": "excluded",
1666
1674
  "reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
@@ -3157,6 +3165,10 @@
3157
3165
  "conduyt_mailchimp_retry_unsubscribes"
3158
3166
  ]
3159
3167
  },
3168
+ "POST /api/v1/integrations/posthog/intent": {
3169
+ "status": "planned",
3170
+ "reason": "integration management"
3171
+ },
3160
3172
  "GET /api/v1/integrations/slack/channels": {
3161
3173
  "status": "planned",
3162
3174
  "reason": "integration management"