conduyt-mcp 4.1.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/.env.example +2 -0
- package/README.md +286 -0
- package/dist/client.d.ts +17 -0
- package/dist/client.js +43 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +79 -0
- package/dist/tools/activities.d.ts +3 -0
- package/dist/tools/activities.js +35 -0
- package/dist/tools/ai-extended.d.ts +3 -0
- package/dist/tools/ai-extended.js +38 -0
- package/dist/tools/ai.d.ts +3 -0
- package/dist/tools/ai.js +22 -0
- package/dist/tools/automations.d.ts +3 -0
- package/dist/tools/automations.js +66 -0
- package/dist/tools/bulk.d.ts +3 -0
- package/dist/tools/bulk.js +71 -0
- package/dist/tools/calendar.d.ts +3 -0
- package/dist/tools/calendar.js +81 -0
- package/dist/tools/companies.d.ts +3 -0
- package/dist/tools/companies.js +67 -0
- package/dist/tools/contacts.d.ts +3 -0
- package/dist/tools/contacts.js +64 -0
- package/dist/tools/custom-fields.d.ts +3 -0
- package/dist/tools/custom-fields.js +48 -0
- package/dist/tools/dashboard.d.ts +3 -0
- package/dist/tools/dashboard.js +7 -0
- package/dist/tools/deals.d.ts +3 -0
- package/dist/tools/deals.js +59 -0
- package/dist/tools/discovery.d.ts +3 -0
- package/dist/tools/discovery.js +28 -0
- package/dist/tools/drip-campaigns.d.ts +3 -0
- package/dist/tools/drip-campaigns.js +98 -0
- package/dist/tools/forms.d.ts +3 -0
- package/dist/tools/forms.js +54 -0
- package/dist/tools/invoices.d.ts +3 -0
- package/dist/tools/invoices.js +76 -0
- package/dist/tools/messaging.d.ts +3 -0
- package/dist/tools/messaging.js +25 -0
- package/dist/tools/notifications.d.ts +3 -0
- package/dist/tools/notifications.js +28 -0
- package/dist/tools/pipelines.d.ts +3 -0
- package/dist/tools/pipelines.js +7 -0
- package/dist/tools/products.d.ts +3 -0
- package/dist/tools/products.js +55 -0
- package/dist/tools/scoring.d.ts +3 -0
- package/dist/tools/scoring.js +48 -0
- package/dist/tools/sequences.d.ts +3 -0
- package/dist/tools/sequences.js +53 -0
- package/dist/tools/smart-lists.d.ts +3 -0
- package/dist/tools/smart-lists.js +54 -0
- package/dist/tools/tags.d.ts +3 -0
- package/dist/tools/tags.js +44 -0
- package/dist/tools/tasks.d.ts +3 -0
- package/dist/tools/tasks.js +40 -0
- package/dist/tools/templates.d.ts +3 -0
- package/dist/tools/templates.js +55 -0
- package/dist/tools/users.d.ts +3 -0
- package/dist/tools/users.js +65 -0
- package/dist/tools/webhooks.d.ts +3 -0
- package/dist/tools/webhooks.js +41 -0
- package/dist/tools/workflow-sandbox.d.ts +3 -0
- package/dist/tools/workflow-sandbox.js +90 -0
- package/dist/types.d.ts +20 -0
- package/dist/types.js +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatResult } from "../client.js";
|
|
3
|
+
export function registerWebhookTools(server, client) {
|
|
4
|
+
server.tool("conduyt_list_webhooks", "List all registered webhooks with their events, status, and failure counts.", {
|
|
5
|
+
page: z.number().optional().describe("Page number (default 1)"),
|
|
6
|
+
per_page: z.number().optional().describe("Results per page"),
|
|
7
|
+
}, async ({ page, per_page }) => {
|
|
8
|
+
const params = new URLSearchParams();
|
|
9
|
+
if (page)
|
|
10
|
+
params.set("page", String(page));
|
|
11
|
+
if (per_page)
|
|
12
|
+
params.set("per_page", String(per_page));
|
|
13
|
+
const result = await client.get(`/api/v1/webhooks/manage?${params}`);
|
|
14
|
+
return formatResult(result);
|
|
15
|
+
});
|
|
16
|
+
server.tool("conduyt_create_webhook", "Register a new webhook endpoint. Returns the signing secret once — store it securely. Events: contact.created/updated/deleted, contact.tag_added/removed, deal.created/updated/stage_changed/won/lost/deleted, company.created/updated/deleted, message.sent/received, appointment.created/updated/cancelled, campaign.completed.", {
|
|
17
|
+
url: z.string().describe("Webhook endpoint URL (HTTPS required in production)"),
|
|
18
|
+
events: z.array(z.string()).describe("Events to subscribe to (e.g. ['contact.created', 'deal.won'])"),
|
|
19
|
+
description: z.string().optional().describe("Human-readable description of this webhook"),
|
|
20
|
+
isActive: z.boolean().optional().describe("Whether webhook is active (default true)"),
|
|
21
|
+
}, async (params) => {
|
|
22
|
+
const result = await client.post("/api/v1/webhooks/manage", params);
|
|
23
|
+
return formatResult(result);
|
|
24
|
+
});
|
|
25
|
+
server.tool("conduyt_update_webhook", "Update a webhook — change URL, events, or enable/disable. Reactivating resets the failure count.", {
|
|
26
|
+
id: z.string().describe("Webhook UUID"),
|
|
27
|
+
url: z.string().optional().describe("Updated endpoint URL"),
|
|
28
|
+
events: z.array(z.string()).optional().describe("Updated event subscriptions"),
|
|
29
|
+
isActive: z.boolean().optional().describe("Enable or disable the webhook"),
|
|
30
|
+
description: z.string().optional().describe("Updated description"),
|
|
31
|
+
}, async ({ id, ...updates }) => {
|
|
32
|
+
const result = await client.patch(`/api/v1/webhooks/manage/${id}`, updates);
|
|
33
|
+
return formatResult(result);
|
|
34
|
+
});
|
|
35
|
+
server.tool("conduyt_delete_webhook", "Delete a webhook endpoint.", {
|
|
36
|
+
id: z.string().describe("Webhook UUID"),
|
|
37
|
+
}, async ({ id }) => {
|
|
38
|
+
const result = await client.del(`/api/v1/webhooks/manage/${id}`);
|
|
39
|
+
return formatResult(result);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatResult } from "../client.js";
|
|
3
|
+
function unwrap(response) {
|
|
4
|
+
if (response && typeof response === "object" && "data" in response) {
|
|
5
|
+
return response.data;
|
|
6
|
+
}
|
|
7
|
+
return response;
|
|
8
|
+
}
|
|
9
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
10
|
+
export function registerWorkflowSandboxTools(server, client) {
|
|
11
|
+
server.tool("conduyt_workflow_validate", "Validate a workflow graph WITHOUT saving it. Returns errors and warnings so you can fix issues before creating or publishing. Always call this before conduyt_workflow_promote.", {
|
|
12
|
+
triggerEvent: z.string().describe("Trigger event (e.g. 'contact.created', 'deal.stage_changed', 'tag.added', 'scheduled')"),
|
|
13
|
+
graph: z.object({
|
|
14
|
+
nodes: z.array(z.object({
|
|
15
|
+
id: z.string(),
|
|
16
|
+
type: z.string(),
|
|
17
|
+
}).passthrough()).describe("Array of graph nodes"),
|
|
18
|
+
startNodeId: z.string().describe("ID of the trigger/start node"),
|
|
19
|
+
}).describe("The workflow graph to validate"),
|
|
20
|
+
}, async ({ triggerEvent, graph }) => {
|
|
21
|
+
const result = await client.post("/api/v1/automations/validate", {
|
|
22
|
+
triggerEvent,
|
|
23
|
+
graph,
|
|
24
|
+
});
|
|
25
|
+
return formatResult(result);
|
|
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.", {
|
|
28
|
+
automationId: z.string().describe("Automation UUID to simulate"),
|
|
29
|
+
contactId: z.string().optional().describe("Contact UUID to simulate against. If omitted, uses a stub contact with empty fields."),
|
|
30
|
+
}, async ({ automationId, contactId }) => {
|
|
31
|
+
if (!UUID_RE.test(automationId)) {
|
|
32
|
+
return formatResult({ error: "automationId must be a valid UUID" });
|
|
33
|
+
}
|
|
34
|
+
if (contactId && !UUID_RE.test(contactId)) {
|
|
35
|
+
return formatResult({ error: "contactId must be a valid UUID" });
|
|
36
|
+
}
|
|
37
|
+
const body = {};
|
|
38
|
+
if (contactId)
|
|
39
|
+
body.contactId = contactId;
|
|
40
|
+
const result = await client.post(`/api/v1/automations/${automationId}/dry-run`, body);
|
|
41
|
+
return formatResult(result);
|
|
42
|
+
});
|
|
43
|
+
server.tool("conduyt_workflow_promote", "Safely publish a workflow. First validates the current graph — if there are errors, returns them and refuses to publish. If validation passes, publishes the draft to live. This is the recommended way to go live — it prevents broken workflows from reaching contacts.", {
|
|
44
|
+
automationId: z.string().describe("Automation UUID to promote to live"),
|
|
45
|
+
allowWarnings: z.boolean().optional().describe("Publish even if there are warnings (default true). Set false to block on warnings too."),
|
|
46
|
+
}, async ({ automationId, allowWarnings }) => {
|
|
47
|
+
if (!UUID_RE.test(automationId)) {
|
|
48
|
+
return formatResult({ promoted: false, error: "automationId must be a valid UUID" });
|
|
49
|
+
}
|
|
50
|
+
const rawAutomation = await client.get(`/api/v1/automations/${automationId}`);
|
|
51
|
+
const automation = unwrap(rawAutomation);
|
|
52
|
+
const graph = automation.actions;
|
|
53
|
+
const triggerEvent = automation.triggerEvent;
|
|
54
|
+
if (!graph || !triggerEvent) {
|
|
55
|
+
return formatResult({
|
|
56
|
+
promoted: false,
|
|
57
|
+
error: "Automation has no graph or trigger event defined. Save a draft first.",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const rawValidation = await client.post("/api/v1/automations/validate", {
|
|
61
|
+
triggerEvent,
|
|
62
|
+
graph,
|
|
63
|
+
});
|
|
64
|
+
const validation = unwrap(rawValidation);
|
|
65
|
+
if (!validation.valid) {
|
|
66
|
+
return formatResult({
|
|
67
|
+
promoted: false,
|
|
68
|
+
validation,
|
|
69
|
+
message: "Workflow has validation errors. Fix them before publishing.",
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const hasWarnings = Array.isArray(validation.warnings) && validation.warnings.length > 0;
|
|
73
|
+
if (hasWarnings && allowWarnings === false) {
|
|
74
|
+
return formatResult({
|
|
75
|
+
promoted: false,
|
|
76
|
+
validation,
|
|
77
|
+
message: "Workflow has warnings and allowWarnings is false. Fix warnings or set allowWarnings to true.",
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
const published = await client.post(`/api/v1/automations/${automationId}/publish`, {});
|
|
81
|
+
return formatResult({
|
|
82
|
+
promoted: true,
|
|
83
|
+
warnings: hasWarnings ? validation.warnings : [],
|
|
84
|
+
message: hasWarnings
|
|
85
|
+
? "Published with warnings — review them."
|
|
86
|
+
: "Workflow validated and published successfully.",
|
|
87
|
+
result: unwrap(published),
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface ConduytConfig {
|
|
2
|
+
apiUrl: string;
|
|
3
|
+
apiKey: string;
|
|
4
|
+
}
|
|
5
|
+
export interface ApiResponse<T = unknown> {
|
|
6
|
+
data?: T;
|
|
7
|
+
meta?: {
|
|
8
|
+
page: number;
|
|
9
|
+
per_page: number;
|
|
10
|
+
total: number;
|
|
11
|
+
};
|
|
12
|
+
error?: string;
|
|
13
|
+
}
|
|
14
|
+
export type ToolContent = {
|
|
15
|
+
type: "text";
|
|
16
|
+
text: string;
|
|
17
|
+
};
|
|
18
|
+
export type ToolResult = {
|
|
19
|
+
content: ToolContent[];
|
|
20
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "conduyt-mcp",
|
|
3
|
+
"version": "4.1.0",
|
|
4
|
+
"description": "MCP server for Conduyt CRM — expose CRM operations as AI-accessible tools",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"conduyt-mcp": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md",
|
|
14
|
+
".env.example"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"start": "tsx src/index.ts",
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"typecheck": "tsc --noEmit",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"mcp",
|
|
27
|
+
"model-context-protocol",
|
|
28
|
+
"conduyt",
|
|
29
|
+
"crm",
|
|
30
|
+
"ai",
|
|
31
|
+
"claude",
|
|
32
|
+
"llm-tools"
|
|
33
|
+
],
|
|
34
|
+
"homepage": "https://conduyt.app",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/ptaramona/conduyt-mcp.git"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/ptaramona/conduyt-mcp/issues"
|
|
41
|
+
},
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"author": "Conduyt",
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
46
|
+
"zod": "^3.23.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"typescript": "^5.5.0",
|
|
50
|
+
"tsx": "^4.19.0",
|
|
51
|
+
"@types/node": "^22.0.0"
|
|
52
|
+
}
|
|
53
|
+
}
|