conduyt-mcp 4.13.0 → 4.15.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 +13 -1
- package/dist/index.js +4 -0
- package/dist/tools/account-exports.d.ts +14 -0
- package/dist/tools/account-exports.js +35 -0
- package/dist/tools/calls.js +4 -0
- package/dist/tools/contacts.js +4 -1
- package/dist/tools/deals.js +2 -0
- package/dist/tools/lifecycle.d.ts +3 -0
- package/dist/tools/lifecycle.js +64 -0
- package/package.json +3 -3
- package/scripts/coverage-manifest.json +5 -0
- package/scripts/coverage-matrix.json +90 -9
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
MCP server for [Conduyt CRM](https://conduyt.app) — expose your CRM as AI-accessible tools. Covers the core CRM surface (contacts, deals, pipelines, custom fields, automations, messaging, and more); use `conduyt_api_catalog` to discover the full set of 500+ REST endpoints.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 169 Tools
|
|
6
6
|
|
|
7
7
|
### Discovery
|
|
8
8
|
| Tool | Description |
|
|
@@ -258,6 +258,18 @@ MCP server for [Conduyt CRM](https://conduyt.app) — expose your CRM as AI-acce
|
|
|
258
258
|
| `conduyt_export_contact_data` | GDPR data-portability export — full portable JSON of everything held about a contact (owner/admin) |
|
|
259
259
|
| `conduyt_forget_contact` | IRREVERSIBLE GDPR right-to-be-forgotten erasure — requires `confirm='FORGET'` (owner only) |
|
|
260
260
|
|
|
261
|
+
### Dialer
|
|
262
|
+
| Tool | Description |
|
|
263
|
+
|------|-------------|
|
|
264
|
+
| `conduyt_sync_local_presence` | Reconcile the Local Presence pool from Twilio (LP-named, voice, US +1, max 50) |
|
|
265
|
+
|
|
266
|
+
### Lifecycle (master lead status + intake deals)
|
|
267
|
+
| Tool | Description |
|
|
268
|
+
|------|-------------|
|
|
269
|
+
| `conduyt_get_lifecycle_settings` | Effective master statuses (defaults + customs) and intake-deals config |
|
|
270
|
+
| `conduyt_update_intake_deals` | Configure automatic deal creation on live intake (webhooks, forms, bookings) |
|
|
271
|
+
| `conduyt_update_master_statuses` | Set the account's custom lead lifecycle statuses |
|
|
272
|
+
|
|
261
273
|
## Setup
|
|
262
274
|
|
|
263
275
|
```bash
|
package/dist/index.js
CHANGED
|
@@ -35,6 +35,8 @@ 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 { registerAccountExportTools } from "./tools/account-exports.js";
|
|
39
|
+
import { registerLifecycleTools } from "./tools/lifecycle.js";
|
|
38
40
|
const apiUrl = process.env.CONDUYT_API_URL;
|
|
39
41
|
const apiKey = process.env.CONDUYT_API_KEY;
|
|
40
42
|
if (!apiUrl || !apiKey) {
|
|
@@ -92,5 +94,7 @@ registerDashboardTools(server, client);
|
|
|
92
94
|
registerAiExtendedTools(server, client);
|
|
93
95
|
registerWorkflowSandboxTools(server, client);
|
|
94
96
|
registerPrivacyTools(server, client);
|
|
97
|
+
registerAccountExportTools(server, client);
|
|
98
|
+
registerLifecycleTools(server, client);
|
|
95
99
|
const transport = new StdioServerTransport();
|
|
96
100
|
await server.connect(transport);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { ConduytClient } from "../client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Scheduled account exports (Enterprise): settings + run history.
|
|
5
|
+
*
|
|
6
|
+
* Listing/downloading full-account export files is account-wide PII egress,
|
|
7
|
+
* so the /account-exports endpoints require the EXPLICIT 'account-exports'
|
|
8
|
+
* API-key scope (same posture as 'dnc' — an admin must grant it per key; an
|
|
9
|
+
* unrestricted key does NOT imply it). The settings endpoints ride the
|
|
10
|
+
* normal 'settings' scope. File BYTES are not fetched through MCP (a 50k-row
|
|
11
|
+
* CSV does not belong in a tool result) — tools return metadata plus the
|
|
12
|
+
* authed downloadPath for the API/CLI to retrieve.
|
|
13
|
+
*/
|
|
14
|
+
export declare function registerAccountExportTools(server: McpServer, client: ConduytClient): void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatResult } from "../client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Scheduled account exports (Enterprise): settings + run history.
|
|
5
|
+
*
|
|
6
|
+
* Listing/downloading full-account export files is account-wide PII egress,
|
|
7
|
+
* so the /account-exports endpoints require the EXPLICIT 'account-exports'
|
|
8
|
+
* API-key scope (same posture as 'dnc' — an admin must grant it per key; an
|
|
9
|
+
* unrestricted key does NOT imply it). The settings endpoints ride the
|
|
10
|
+
* normal 'settings' scope. File BYTES are not fetched through MCP (a 50k-row
|
|
11
|
+
* CSV does not belong in a tool result) — tools return metadata plus the
|
|
12
|
+
* authed downloadPath for the API/CLI to retrieve.
|
|
13
|
+
*/
|
|
14
|
+
export function registerAccountExportTools(server, client) {
|
|
15
|
+
server.tool("conduyt_scheduled_export_get_settings", "Get the account's scheduled-export configuration (enabled, frequency, entities) and whether the Enterprise feature is available on the current plan.", {}, async () => {
|
|
16
|
+
const result = await client.get("/api/v1/settings/scheduled-export");
|
|
17
|
+
return formatResult(result);
|
|
18
|
+
});
|
|
19
|
+
server.tool("conduyt_scheduled_export_update_settings", "Update scheduled-export settings. Enabling requires an Enterprise plan (403 upsell otherwise). Omitted fields keep their current values. Weekly exports run on Mondays; all exports run in the morning of the account timezone and files are kept 14 days.", {
|
|
20
|
+
enabled: z.boolean().optional().describe("Turn scheduled exports on/off"),
|
|
21
|
+
frequency: z.enum(["daily", "weekly"]).optional().describe("How often to export (weekly = Mondays)"),
|
|
22
|
+
entities: z
|
|
23
|
+
.array(z.enum(["contacts", "deals", "companies"]))
|
|
24
|
+
.min(1)
|
|
25
|
+
.optional()
|
|
26
|
+
.describe("Which entities to include"),
|
|
27
|
+
}, async (params) => {
|
|
28
|
+
const result = await client.patch("/api/v1/settings/scheduled-export", params);
|
|
29
|
+
return formatResult(result);
|
|
30
|
+
});
|
|
31
|
+
server.tool("conduyt_account_exports_list", "List recent scheduled account-export runs with per-file metadata (rows, truncation, size, expiry) and authed downloadPath for each completed file. Requires the explicit 'account-exports' API-key scope. Download the CSV bytes via the API or CLI using downloadPath — not through MCP.", {}, async () => {
|
|
32
|
+
const result = await client.get("/api/v1/account-exports");
|
|
33
|
+
return formatResult(result);
|
|
34
|
+
});
|
|
35
|
+
}
|
package/dist/tools/calls.js
CHANGED
|
@@ -46,4 +46,8 @@ export function registerCallTools(server, client) {
|
|
|
46
46
|
const result = await client.get(`/api/v1/calls/${encodeURIComponent(id)}`);
|
|
47
47
|
return formatResult(result);
|
|
48
48
|
});
|
|
49
|
+
server.tool("conduyt_sync_local_presence", "Sync the dialer's Local Presence number pool from the account's Twilio subaccount. IMPORTANT — sync only adopts numbers that meet ALL of: (1) the Twilio FriendlyName contains a standalone 'LP' (or 'LocalPres'), e.g. 'LP Miami 305'; (2) the number is voice-capable; (3) it is a US +1 E.164 number. The first 50 matches in sorted order become the pool; anything already in the pool that no longer matches is REMOVED. So buying a number is not enough — name it with the LP convention in Twilio first, then run this. Returns pool/added/removed/matched. Requires settings:edit.", {}, async () => {
|
|
50
|
+
const result = await client.post("/api/v1/dialer/local-presence/sync", {});
|
|
51
|
+
return formatResult(result);
|
|
52
|
+
});
|
|
49
53
|
}
|
package/dist/tools/contacts.js
CHANGED
|
@@ -52,7 +52,8 @@ export function registerContactTools(server, client) {
|
|
|
52
52
|
lastName: z.string().optional().describe("Last name"),
|
|
53
53
|
phone: z.string().optional().describe("Phone number"),
|
|
54
54
|
company: z.string().optional().describe("Company name"),
|
|
55
|
-
source: z.string().optional().describe("Lead source (e.g. 'website', 'referral', 'import')"),
|
|
55
|
+
source: z.string().trim().min(1).max(100).optional().describe("Lead source (e.g. 'website', 'referral', 'import') — FIRST-WRITE-WINS acquisition truth for the lead; later inbound events do not overwrite it. 1-100 chars."),
|
|
56
|
+
masterStatus: z.string().trim().min(1).max(40).optional().describe("Lifecycle status of the LEAD (master record), distinct from any deal's status: 'open' (default), 'won', 'lost', 'abandoned', 'disqualified', or an account-defined custom status. A terminal status (won/lost/abandoned/disqualified) SILENCES all outbound automations for this contact — drips, sequences, and scheduled sends stop. Use conduyt_get_lifecycle_settings to see the account's configured statuses."),
|
|
56
57
|
tags: z.array(z.string()).optional().describe("Tag UUIDs to apply (tags must already exist — create them with conduyt_create_tag first)"),
|
|
57
58
|
customFields: z.record(z.any()).optional().describe("Structured custom-field values keyed by field key, e.g. { lead_temperature: 'hot', budget: 50000 }. Define fields first with conduyt_create_custom_field (entity 'contact')."),
|
|
58
59
|
custom_fields: z.record(z.any()).optional().describe("Alias for customFields (snake_case). Provide only one of customFields / custom_fields."),
|
|
@@ -69,6 +70,8 @@ export function registerContactTools(server, client) {
|
|
|
69
70
|
lastName: z.string().optional().describe("Updated last name"),
|
|
70
71
|
phone: z.string().optional().describe("Updated phone"),
|
|
71
72
|
company: z.string().optional().describe("Updated company name"),
|
|
73
|
+
source: z.string().trim().min(1).max(100).nullable().optional().describe("Correct the lead's first-touch source (normally first-write-wins and set at creation — update only to FIX bad attribution). Pass null to clear."),
|
|
74
|
+
masterStatus: z.string().trim().min(1).max(40).optional().describe("Lifecycle status of the LEAD (master record), distinct from any deal's status: 'open' (default), 'won', 'lost', 'abandoned', 'disqualified', or an account-defined custom status. A terminal status (won/lost/abandoned/disqualified) SILENCES all outbound automations for this contact — drips, sequences, and scheduled sends stop. Use conduyt_get_lifecycle_settings to see the account's configured statuses."),
|
|
72
75
|
customFields: z.record(z.any()).optional().describe("Structured custom-field values to merge, keyed by field key. Omit a key to leave it unchanged."),
|
|
73
76
|
custom_fields: z.record(z.any()).optional().describe("Alias for customFields (snake_case). Provide only one of customFields / custom_fields."),
|
|
74
77
|
}, async ({ id, customFields, custom_fields, ...updates }) => {
|
package/dist/tools/deals.js
CHANGED
|
@@ -84,6 +84,7 @@ export function registerDealTools(server, client) {
|
|
|
84
84
|
probability: z.number().min(0).max(1).optional().describe("Win probability as a 0–1 fraction (e.g. 0.75 = 75%)"),
|
|
85
85
|
expectedCloseDate: z.string().optional().describe("Expected close date (ISO 8601, e.g. '2026-09-30')"),
|
|
86
86
|
assignedTo: z.string().optional().describe("Assigned user (owner) UUID"),
|
|
87
|
+
source: z.string().trim().min(1).max(500).optional().describe("Attribution source for THIS deal — the trigger that produced it (e.g. 'sms-reply', 'booking:demo', 'partner-referral'). Each deal carries its own source; the contact's source stays the first-touch acquisition truth. 1-500 chars."),
|
|
87
88
|
customFields: z.record(z.any()).optional().describe("Structured custom-field values keyed by field key, e.g. { limit_of_indemnity: 5000000, commission_pct: 12.5 }. Define fields first with conduyt_create_custom_field."),
|
|
88
89
|
}, async (params) => {
|
|
89
90
|
const result = await client.post("/api/v1/deals", params);
|
|
@@ -102,6 +103,7 @@ export function registerDealTools(server, client) {
|
|
|
102
103
|
probability: z.number().min(0).max(1).optional().describe("Win probability as a 0–1 fraction (e.g. 0.75 = 75%)"),
|
|
103
104
|
expectedCloseDate: z.string().optional().describe("Expected close date (ISO 8601)"),
|
|
104
105
|
assignedTo: z.string().optional().describe("Reassign to user (owner) UUID"),
|
|
106
|
+
source: z.string().trim().min(1).max(500).nullable().optional().describe("Attribution source for THIS deal (the trigger that produced it) — distinct from the contact's first-touch source. Pass null to clear it; a blank string is rejected. 1-500 chars."),
|
|
105
107
|
customFields: z.record(z.any()).optional().describe("Structured custom-field values to merge, keyed by field key"),
|
|
106
108
|
}, async ({ id, ...updates }) => {
|
|
107
109
|
const result = await client.patch(`/api/v1/deals/${id}`, updates);
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatResult } from "../client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Lifecycle v2 settings (master lead status + intake deals). The master lead
|
|
5
|
+
* is the acquisition truth (first-write-wins source, one lifecycle status);
|
|
6
|
+
* deals are per-trigger children with their own source and owner. A terminal
|
|
7
|
+
* master status silences every outbound automation for that contact.
|
|
8
|
+
*/
|
|
9
|
+
const DEFAULT_MASTER_STATUSES = ["open", "won", "lost", "abandoned", "disqualified"];
|
|
10
|
+
// Mirror of the API's masterStatuses validator (20 names max, 1-40 chars,
|
|
11
|
+
// letters/numbers/spaces/-/_ only) so agent-generated input fails fast here
|
|
12
|
+
// instead of late at the API.
|
|
13
|
+
const masterStatusName = z
|
|
14
|
+
.string()
|
|
15
|
+
.trim()
|
|
16
|
+
.min(1)
|
|
17
|
+
.max(40)
|
|
18
|
+
.regex(/^[a-z0-9][a-z0-9 _-]*$/i, "letters, numbers, spaces, - and _ only");
|
|
19
|
+
export function registerLifecycleTools(server, client) {
|
|
20
|
+
server.tool("conduyt_get_lifecycle_settings", "Read the account's Lifecycle v2 configuration, shaped for read-before-write: 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 () => {
|
|
21
|
+
const result = await client.get("/api/v1/settings");
|
|
22
|
+
const raw = result?.data ?? {};
|
|
23
|
+
const customs = Array.isArray(raw.masterStatuses)
|
|
24
|
+
? raw.masterStatuses.filter((s) => typeof s === "string")
|
|
25
|
+
: [];
|
|
26
|
+
// intakeDeals is admin-visible only: member-shaped responses omit it,
|
|
27
|
+
// and an unconfigured account also lacks it. The two are not
|
|
28
|
+
// distinguishable from here, so null is reported with a note saying so.
|
|
29
|
+
const intakeDeals = raw.intakeDeals && typeof raw.intakeDeals === "object" ? raw.intakeDeals : null;
|
|
30
|
+
const shaped = {
|
|
31
|
+
masterStatuses: {
|
|
32
|
+
defaults: DEFAULT_MASTER_STATUSES,
|
|
33
|
+
customs,
|
|
34
|
+
effective: [...DEFAULT_MASTER_STATUSES, ...customs.filter((c) => !DEFAULT_MASTER_STATUSES.includes(c.toLowerCase()))],
|
|
35
|
+
},
|
|
36
|
+
intakeDeals: intakeDeals ?? null,
|
|
37
|
+
intakeDealsNote: intakeDeals === null
|
|
38
|
+
? "null = not configured, OR your key's role cannot read this admin-visible setting; configure/verify with an admin-tier key"
|
|
39
|
+
: undefined,
|
|
40
|
+
};
|
|
41
|
+
return formatResult({ data: shaped });
|
|
42
|
+
});
|
|
43
|
+
server.tool("conduyt_update_intake_deals", "Configure automatic deal creation on LIVE intake (inbound webhook contact upserts, public form submissions, public bookings). When enabled, each ELIGIBLE intake event mints a deal in the chosen pipeline/stage stamped with the trigger's own source. Exclusions that apply even under reInbound 'always': bulk imports never mint, staff/calendar/dialer-created appointments never mint, an exact replay of the same occurrence never mints twice, a same-source event for the same contact+pipeline within 10 minutes is treated as a delivery retry and skipped, and a contact whose masterStatus is terminal (won/lost/abandoned/disqualified) gets no new intake deals. reInbound governs contacts that already exist: 'if_no_open' (default, recommended) also skips when the contact already has an open deal in that pipeline; 'never' mints only for brand-new contacts. Requires settings:edit.", {
|
|
44
|
+
enabled: z.boolean().describe("Turn automatic intake-deal creation on or off"),
|
|
45
|
+
pipelineId: z.string().uuid().describe("Pipeline UUID the intake deals land in (conduyt_list_pipelines)"),
|
|
46
|
+
stageId: z.string().uuid().describe("Starting stage UUID within that pipeline"),
|
|
47
|
+
reInbound: z
|
|
48
|
+
.enum(["always", "if_no_open", "never"])
|
|
49
|
+
.optional()
|
|
50
|
+
.describe("Policy for contacts that already exist (default 'if_no_open')"),
|
|
51
|
+
}, async (params) => {
|
|
52
|
+
const result = await client.patch("/api/v1/settings", { intakeDeals: params });
|
|
53
|
+
return formatResult(result);
|
|
54
|
+
});
|
|
55
|
+
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.", {
|
|
56
|
+
statuses: z
|
|
57
|
+
.array(masterStatusName)
|
|
58
|
+
.max(20)
|
|
59
|
+
.describe("Custom status names to make available alongside the defaults, e.g. ['nurturing', 'in underwriting']"),
|
|
60
|
+
}, async ({ statuses }) => {
|
|
61
|
+
const result = await client.patch("/api/v1/settings", { masterStatuses: statuses });
|
|
62
|
+
return formatResult(result);
|
|
63
|
+
});
|
|
64
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conduyt-mcp",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "MCP server for Conduyt CRM
|
|
3
|
+
"version": "4.15.0",
|
|
4
|
+
"description": "MCP server for Conduyt CRM \u2014 expose CRM operations as AI-accessible tools",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -57,4 +57,4 @@
|
|
|
57
57
|
"tsx": "^4.19.0",
|
|
58
58
|
"@types/node": "^22.0.0"
|
|
59
59
|
}
|
|
60
|
-
}
|
|
60
|
+
}
|
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
"status": "excluded",
|
|
16
16
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
17
17
|
},
|
|
18
|
+
{
|
|
19
|
+
"match": "GET /api/v1/account-exports/:id/files/:entity/download",
|
|
20
|
+
"status": "excluded",
|
|
21
|
+
"reason": "raw CSV bytes (up to 50k rows) do not belong in a tool result; conduyt_account_exports_list returns the authed downloadPath for API/CLI retrieval"
|
|
22
|
+
},
|
|
18
23
|
{
|
|
19
24
|
"match": "/api/v1/auth/",
|
|
20
25
|
"status": "excluded",
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-07-
|
|
3
|
-
"toolCount":
|
|
4
|
-
"totalEndpoints":
|
|
2
|
+
"generatedAt": "2026-07-29T16:12:55.014Z",
|
|
3
|
+
"toolCount": 169,
|
|
4
|
+
"totalEndpoints": 831,
|
|
5
5
|
"counts": {
|
|
6
|
-
"covered":
|
|
7
|
-
"excluded":
|
|
6
|
+
"covered": 157,
|
|
7
|
+
"excluded": 243,
|
|
8
8
|
"planned": 431,
|
|
9
9
|
"uncategorized": 0
|
|
10
10
|
},
|
|
@@ -211,6 +211,16 @@
|
|
|
211
211
|
"status": "excluded",
|
|
212
212
|
"reason": "email open/click tracking pixels and redirects — recipient-facing"
|
|
213
213
|
},
|
|
214
|
+
"GET /api/v1/account-exports": {
|
|
215
|
+
"status": "covered",
|
|
216
|
+
"tools": [
|
|
217
|
+
"conduyt_account_exports_list"
|
|
218
|
+
]
|
|
219
|
+
},
|
|
220
|
+
"GET /api/v1/account-exports/:id/files/:entity/download": {
|
|
221
|
+
"status": "excluded",
|
|
222
|
+
"reason": "raw CSV bytes (up to 50k rows) do not belong in a tool result; conduyt_account_exports_list returns the authed downloadPath for API/CLI retrieval"
|
|
223
|
+
},
|
|
214
224
|
"GET /api/v1/account/readiness": {
|
|
215
225
|
"status": "planned",
|
|
216
226
|
"reason": "account readiness/onboarding surfaces"
|
|
@@ -1177,6 +1187,10 @@
|
|
|
1177
1187
|
"conduyt_export_contact_data"
|
|
1178
1188
|
]
|
|
1179
1189
|
},
|
|
1190
|
+
"GET /api/v1/contacts/:id/gdpr-export/files/:fileId/download": {
|
|
1191
|
+
"status": "planned",
|
|
1192
|
+
"reason": "contact subroutes beyond the core CRUD/search tools"
|
|
1193
|
+
},
|
|
1180
1194
|
"POST /api/v1/contacts/:id/gdpr-forget": {
|
|
1181
1195
|
"status": "covered",
|
|
1182
1196
|
"tools": [
|
|
@@ -1399,6 +1413,10 @@
|
|
|
1399
1413
|
"status": "excluded",
|
|
1400
1414
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1401
1415
|
},
|
|
1416
|
+
"GET /api/v1/cron/process-external-deletions": {
|
|
1417
|
+
"status": "excluded",
|
|
1418
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1419
|
+
},
|
|
1402
1420
|
"GET /api/v1/cron/process-import-side-effects": {
|
|
1403
1421
|
"status": "excluded",
|
|
1404
1422
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
@@ -1407,6 +1425,10 @@
|
|
|
1407
1425
|
"status": "excluded",
|
|
1408
1426
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1409
1427
|
},
|
|
1428
|
+
"GET /api/v1/cron/process-outbox": {
|
|
1429
|
+
"status": "excluded",
|
|
1430
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1431
|
+
},
|
|
1410
1432
|
"GET /api/v1/cron/process-playbook-steps": {
|
|
1411
1433
|
"status": "excluded",
|
|
1412
1434
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
@@ -1443,6 +1465,18 @@
|
|
|
1443
1465
|
"status": "excluded",
|
|
1444
1466
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1445
1467
|
},
|
|
1468
|
+
"GET /api/v1/cron/reap-qa-tenants": {
|
|
1469
|
+
"status": "excluded",
|
|
1470
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1471
|
+
},
|
|
1472
|
+
"GET /api/v1/cron/reconcile-document-sends": {
|
|
1473
|
+
"status": "excluded",
|
|
1474
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1475
|
+
},
|
|
1476
|
+
"POST /api/v1/cron/reconcile-document-sends": {
|
|
1477
|
+
"status": "excluded",
|
|
1478
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1479
|
+
},
|
|
1446
1480
|
"GET /api/v1/cron/recurring-tasks": {
|
|
1447
1481
|
"status": "excluded",
|
|
1448
1482
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
@@ -1479,6 +1513,18 @@
|
|
|
1479
1513
|
"status": "excluded",
|
|
1480
1514
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1481
1515
|
},
|
|
1516
|
+
"GET /api/v1/cron/scheduled-account-exports": {
|
|
1517
|
+
"status": "excluded",
|
|
1518
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1519
|
+
},
|
|
1520
|
+
"POST /api/v1/cron/scheduled-account-exports": {
|
|
1521
|
+
"status": "excluded",
|
|
1522
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1523
|
+
},
|
|
1524
|
+
"GET /api/v1/cron/seat-threshold-alerts": {
|
|
1525
|
+
"status": "excluded",
|
|
1526
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1527
|
+
},
|
|
1482
1528
|
"GET /api/v1/cron/send-scheduled-emails": {
|
|
1483
1529
|
"status": "excluded",
|
|
1484
1530
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
@@ -1491,6 +1537,14 @@
|
|
|
1491
1537
|
"status": "excluded",
|
|
1492
1538
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1493
1539
|
},
|
|
1540
|
+
"GET /api/v1/cron/sync-local-presence": {
|
|
1541
|
+
"status": "excluded",
|
|
1542
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1543
|
+
},
|
|
1544
|
+
"POST /api/v1/cron/sync-local-presence": {
|
|
1545
|
+
"status": "excluded",
|
|
1546
|
+
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
1547
|
+
},
|
|
1494
1548
|
"GET /api/v1/cron/task-reminders": {
|
|
1495
1549
|
"status": "excluded",
|
|
1496
1550
|
"reason": "CRON_SECRET-gated infrastructure jobs; never key-callable"
|
|
@@ -1785,6 +1839,12 @@
|
|
|
1785
1839
|
"status": "excluded",
|
|
1786
1840
|
"reason": "realtime browser dialer (WebRTC tokens, live call control) — needs a live audio session"
|
|
1787
1841
|
},
|
|
1842
|
+
"POST /api/v1/dialer/local-presence/sync": {
|
|
1843
|
+
"status": "covered",
|
|
1844
|
+
"tools": [
|
|
1845
|
+
"conduyt_sync_local_presence"
|
|
1846
|
+
]
|
|
1847
|
+
},
|
|
1788
1848
|
"POST /api/v1/dialer/mirror-token": {
|
|
1789
1849
|
"status": "excluded",
|
|
1790
1850
|
"reason": "realtime browser dialer (WebRTC tokens, live call control) — needs a live audio session"
|
|
@@ -2249,6 +2309,10 @@
|
|
|
2249
2309
|
"status": "planned",
|
|
2250
2310
|
"reason": "import job monitoring/resubmission (ai-import tool covers creation)"
|
|
2251
2311
|
},
|
|
2312
|
+
"POST /api/v1/imports/upload-url": {
|
|
2313
|
+
"status": "planned",
|
|
2314
|
+
"reason": "import job monitoring/resubmission (ai-import tool covers creation)"
|
|
2315
|
+
},
|
|
2252
2316
|
"GET /api/v1/imports/users": {
|
|
2253
2317
|
"status": "planned",
|
|
2254
2318
|
"reason": "import job monitoring/resubmission (ai-import tool covers creation)"
|
|
@@ -2938,12 +3002,17 @@
|
|
|
2938
3002
|
]
|
|
2939
3003
|
},
|
|
2940
3004
|
"GET /api/v1/settings": {
|
|
2941
|
-
"status": "
|
|
2942
|
-
"
|
|
3005
|
+
"status": "covered",
|
|
3006
|
+
"tools": [
|
|
3007
|
+
"conduyt_get_lifecycle_settings"
|
|
3008
|
+
]
|
|
2943
3009
|
},
|
|
2944
3010
|
"PATCH /api/v1/settings": {
|
|
2945
|
-
"status": "
|
|
2946
|
-
"
|
|
3011
|
+
"status": "covered",
|
|
3012
|
+
"tools": [
|
|
3013
|
+
"conduyt_update_intake_deals",
|
|
3014
|
+
"conduyt_update_master_statuses"
|
|
3015
|
+
]
|
|
2947
3016
|
},
|
|
2948
3017
|
"GET /api/v1/settings/ai": {
|
|
2949
3018
|
"status": "planned",
|
|
@@ -2997,6 +3066,18 @@
|
|
|
2997
3066
|
"status": "planned",
|
|
2998
3067
|
"reason": "account settings read/update surfaces"
|
|
2999
3068
|
},
|
|
3069
|
+
"GET /api/v1/settings/scheduled-export": {
|
|
3070
|
+
"status": "covered",
|
|
3071
|
+
"tools": [
|
|
3072
|
+
"conduyt_scheduled_export_get_settings"
|
|
3073
|
+
]
|
|
3074
|
+
},
|
|
3075
|
+
"PATCH /api/v1/settings/scheduled-export": {
|
|
3076
|
+
"status": "covered",
|
|
3077
|
+
"tools": [
|
|
3078
|
+
"conduyt_scheduled_export_update_settings"
|
|
3079
|
+
]
|
|
3080
|
+
},
|
|
3000
3081
|
"GET /api/v1/settings/sms": {
|
|
3001
3082
|
"status": "planned",
|
|
3002
3083
|
"reason": "account settings read/update surfaces"
|