conduyt-mcp 4.3.1 → 4.3.3
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 +1 -1
- package/dist/tools/custom-fields.js +4 -4
- package/dist/tools/deals.js +45 -8
- package/dist/tools/discovery.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -45,7 +45,7 @@ if (!apiKey.startsWith("cdy_")) {
|
|
|
45
45
|
const client = new ConduytClient({ apiUrl, apiKey });
|
|
46
46
|
const server = new McpServer({
|
|
47
47
|
name: "conduyt",
|
|
48
|
-
version: "4.3.
|
|
48
|
+
version: "4.3.3",
|
|
49
49
|
});
|
|
50
50
|
registerDiscoveryTools(server, client);
|
|
51
51
|
registerContactTools(server, client);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { formatResult } from "../client.js";
|
|
3
3
|
export function registerCustomFieldTools(server, client) {
|
|
4
|
-
server.tool("conduyt_list_custom_fields", "List custom field definitions. Filter by entity type (contact or
|
|
5
|
-
entityType: z.enum(["contact", "deal"]).optional().describe("Filter by entity type"),
|
|
4
|
+
server.tool("conduyt_list_custom_fields", "List custom field definitions. Filter by entity type (contact, deal, or company) to see available fields.", {
|
|
5
|
+
entityType: z.enum(["contact", "deal", "company"]).optional().describe("Filter by entity type"),
|
|
6
6
|
page: z.number().optional().describe("Page number (default 1)"),
|
|
7
7
|
per_page: z.number().optional().describe("Results per page"),
|
|
8
8
|
}, async ({ entityType, page, per_page }) => {
|
|
@@ -16,8 +16,8 @@ export function registerCustomFieldTools(server, client) {
|
|
|
16
16
|
const result = await client.get(`/api/v1/custom-fields?${params}`);
|
|
17
17
|
return formatResult(result);
|
|
18
18
|
});
|
|
19
|
-
server.tool("conduyt_create_custom_field", "Create a new custom field definition for contacts or
|
|
20
|
-
entityType: z.enum(["contact", "deal"]).describe("Entity type this field applies to"),
|
|
19
|
+
server.tool("conduyt_create_custom_field", "Create a new custom field definition for contacts, deals, or companies. Field types: text, number, date, select, multiselect, boolean.", {
|
|
20
|
+
entityType: z.enum(["contact", "deal", "company"]).describe("Entity type this field applies to"),
|
|
21
21
|
fieldKey: z.string().describe("Unique field key (alphanumeric + underscores, e.g. 'lead_score')"),
|
|
22
22
|
label: z.string().describe("Human-readable label (e.g. 'Lead Score')"),
|
|
23
23
|
fieldType: z.enum(["text", "number", "date", "select", "multiselect", "boolean"]).describe("Field data type"),
|
package/dist/tools/deals.js
CHANGED
|
@@ -1,20 +1,57 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { formatResult } from "../client.js";
|
|
3
3
|
export function registerDealTools(server, client) {
|
|
4
|
-
server.tool("conduyt_list_deals", "List deals with filtering by pipeline, stage, assignee, or status. Returns deal title, value, stage, contact, and dates.", {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
server.tool("conduyt_list_deals", "List deals with filtering by pipeline, stage, assignee, or status. Returns deal title, value, stage, contact, and dates. Filter by pipeline/stage NAME (the same names you import with) or by UUID — both camelCase (pipelineName) and snake_case (pipeline_name) argument names are accepted. An unknown name returns a clear error, never the whole account.", {
|
|
5
|
+
pipeline: z.string().optional().describe("Filter by pipeline UUID (canonical). Aliases: pipelineId, pipeline_id."),
|
|
6
|
+
pipelineId: z.string().optional().describe("Filter by pipeline UUID (alias of pipeline)."),
|
|
7
|
+
pipeline_id: z.string().optional().describe("snake_case alias of pipelineId."),
|
|
8
|
+
pipelineName: z.string().optional().describe("Filter by pipeline NAME (the same name used in conduyt_import_deals/create) — resolved to its UUID; errors if not found. Alias: pipeline_name."),
|
|
9
|
+
pipeline_name: z.string().optional().describe("snake_case alias of pipelineName."),
|
|
10
|
+
stage: z.string().optional().describe("Filter by stage UUID (canonical). Aliases: stageId, stage_id."),
|
|
11
|
+
stageId: z.string().optional().describe("Filter by stage UUID (alias of stage)."),
|
|
12
|
+
stage_id: z.string().optional().describe("snake_case alias of stageId."),
|
|
13
|
+
stageName: z.string().optional().describe("Filter by stage NAME within the pipeline — resolved to its UUID; errors if not found. Alias: stage_name."),
|
|
14
|
+
stage_name: z.string().optional().describe("snake_case alias of stageName."),
|
|
7
15
|
assignedTo: z.string().optional().describe("Filter by assigned user UUID"),
|
|
8
16
|
status: z.enum(["open", "won", "lost"]).optional().describe("Filter by deal status"),
|
|
9
17
|
search: z.string().optional().describe("Search deal titles"),
|
|
10
18
|
page: z.number().optional().describe("Page number (default 1)"),
|
|
11
19
|
per_page: z.number().optional().describe("Results per page (default 25, max 100)"),
|
|
12
|
-
}, async (
|
|
20
|
+
}, async (a) => {
|
|
13
21
|
const params = new URLSearchParams();
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
22
|
+
// Accept every reasonable casing of each filter (canonical bare name +
|
|
23
|
+
// camelCase + snake_case) so an agent's provided filter is NEVER silently
|
|
24
|
+
// stripped by the schema. Coalesce each alias GROUP to a single value
|
|
25
|
+
// locally — conflicting non-blank values in a group are a contradictory
|
|
26
|
+
// request and raise a clear tool error (don't emit ambiguous duplicate
|
|
27
|
+
// query params and hope the parser picks the right one) — then send ONE
|
|
28
|
+
// canonical wire param (pipeline / stage / pipeline_name / stage_name, the
|
|
29
|
+
// params the live contract advertises). A blank value is forwarded so the
|
|
30
|
+
// server rejects it; an id/name cross-conflict is caught by the server.
|
|
31
|
+
const coalesce = (label, ...vals) => {
|
|
32
|
+
const present = vals.filter((v) => v !== undefined);
|
|
33
|
+
if (present.length === 0)
|
|
34
|
+
return undefined;
|
|
35
|
+
const distinct = [...new Set(present.map((v) => v.trim().toLowerCase()).filter((v) => v !== ""))];
|
|
36
|
+
if (distinct.length > 1) {
|
|
37
|
+
throw new Error(`Conflicting ${label} values — pass only one.`);
|
|
38
|
+
}
|
|
39
|
+
// prefer a non-blank original; else keep a blank so the server can reject it
|
|
40
|
+
return present.find((v) => v.trim() !== "") ?? present[0];
|
|
41
|
+
};
|
|
42
|
+
const { assignedTo, status, search, page, per_page } = a;
|
|
43
|
+
const pipelineV = coalesce("pipeline id", a.pipeline, a.pipelineId, a.pipeline_id);
|
|
44
|
+
const pipelineNameV = coalesce("pipeline name", a.pipelineName, a.pipeline_name);
|
|
45
|
+
const stageV = coalesce("stage id", a.stage, a.stageId, a.stage_id);
|
|
46
|
+
const stageNameV = coalesce("stage name", a.stageName, a.stage_name);
|
|
47
|
+
if (pipelineV !== undefined)
|
|
48
|
+
params.set("pipeline", pipelineV);
|
|
49
|
+
if (pipelineNameV !== undefined)
|
|
50
|
+
params.set("pipeline_name", pipelineNameV);
|
|
51
|
+
if (stageV !== undefined)
|
|
52
|
+
params.set("stage", stageV);
|
|
53
|
+
if (stageNameV !== undefined)
|
|
54
|
+
params.set("stage_name", stageNameV);
|
|
18
55
|
if (assignedTo)
|
|
19
56
|
params.set("assigned_to", assignedTo);
|
|
20
57
|
if (status)
|
package/dist/tools/discovery.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { formatResult } from "../client.js";
|
|
3
3
|
export function registerDiscoveryTools(server, client) {
|
|
4
|
-
server.tool("conduyt_api_catalog", "Discover all Conduyt CRM API endpoints
|
|
4
|
+
server.tool("conduyt_api_catalog", "Discover all Conduyt CRM API endpoints across 90+ domains, with full request and response schemas. Call this first to learn what the CRM can do — the response carries the exact, current endpoint counts.", {}, async () => {
|
|
5
5
|
const result = await client.get("/api/v1/schema/api-catalog");
|
|
6
6
|
return formatResult(result);
|
|
7
7
|
});
|