@agifyai/leadify-mcp 7.1.0 → 7.1.1
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/tools/dataroom.js +28 -18
- package/dist/tools/leads.js +39 -18
- package/dist/tools/logs.js +12 -1
- package/package.json +1 -1
package/dist/tools/dataroom.js
CHANGED
|
@@ -249,27 +249,37 @@ async function mergeAndPut(organizationId, dry_run, patcher, validationHint) {
|
|
|
249
249
|
// organization_id. The backend resolves the org server-side.
|
|
250
250
|
export function registerDataRoomTools(server) {
|
|
251
251
|
// ── get_data_room ──────────────────────────────────────────────────────
|
|
252
|
-
server.tool("get_data_room", "Retrieve
|
|
253
|
-
"
|
|
254
|
-
"before writing campaigns or messages. " +
|
|
255
|
-
"By default, `personas[]` is NO LONGER included in the response (slimed down to " +
|
|
256
|
-
"keep the LLM context small — the data room itself was 158k chars). " +
|
|
257
|
-
"Pass `include_personas=true` to restore the legacy full payload (escape hatch). " +
|
|
258
|
-
"For per-persona queries, prefer the `list_personas` tool.", {
|
|
252
|
+
server.tool("get_data_room", "Retrieve compact data-room metadata by default. Documents are paginated and their content " +
|
|
253
|
+
"is omitted unless explicitly requested for named document IDs.", {
|
|
259
254
|
organization_id: z.string().describe(ORG_ID_DESC),
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
}, async ({ organization_id, include_personas }) => {
|
|
255
|
+
page: z.number().int().positive().optional().default(1).describe("Document page, starting at 1."),
|
|
256
|
+
limit: z.number().int().positive().max(50).optional().default(20).describe("Documents per page, max 50."),
|
|
257
|
+
category: z.string().optional().describe("Filter documents by category."),
|
|
258
|
+
search: z.string().optional().describe("Search document title and metadata."),
|
|
259
|
+
include_document_content_for_ids: z.array(z.string()).max(10).optional().describe("Explicit document IDs whose content is required."),
|
|
260
|
+
include_personas: z.boolean().optional().default(false).describe("Include personas only when explicitly required."),
|
|
261
|
+
}, async ({ organization_id, page, limit, category, search, include_document_content_for_ids, include_personas }) => {
|
|
268
262
|
try {
|
|
269
|
-
const
|
|
270
|
-
|
|
263
|
+
const state = await fetchDataRoom(organization_id, { includePersonas: include_personas === true });
|
|
264
|
+
const room = state.dataRoom && typeof state.dataRoom === "object" ? state.dataRoom : state;
|
|
265
|
+
const documents = Array.isArray(room.documents) ? room.documents : [];
|
|
266
|
+
const term = search?.toLowerCase();
|
|
267
|
+
const filtered = documents.filter((document) => {
|
|
268
|
+
const value = document && typeof document === "object" ? document : {};
|
|
269
|
+
if (category && value.category !== category)
|
|
270
|
+
return false;
|
|
271
|
+
return !term || JSON.stringify({ title: value.title, name: value.name, category: value.category }).toLowerCase().includes(term);
|
|
271
272
|
});
|
|
272
|
-
|
|
273
|
+
const start = (page - 1) * limit;
|
|
274
|
+
const requested = new Set(include_document_content_for_ids ?? []);
|
|
275
|
+
const items = filtered.slice(start, start + limit).map((document) => {
|
|
276
|
+
const value = document && typeof document === "object" ? document : {};
|
|
277
|
+
const compact = { id: value.id, title: value.title ?? value.name, category: value.category, createdAt: value.createdAt, updatedAt: value.updatedAt };
|
|
278
|
+
if (requested.has(String(value.id)))
|
|
279
|
+
compact.content = value.content;
|
|
280
|
+
return compact;
|
|
281
|
+
});
|
|
282
|
+
return toolResult({ company_info: room.companyInfo, documents: items, pagination: { page, limit, total: filtered.length, totalPages: Math.ceil(filtered.length / limit) } });
|
|
273
283
|
}
|
|
274
284
|
catch (error) {
|
|
275
285
|
return handleToolError(error);
|
package/dist/tools/leads.js
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { getClient } from "../client.js";
|
|
3
3
|
import { toolResult, handleToolError } from "../types.js";
|
|
4
|
+
const DEFAULT_LEAD_FIELDS = ["firstName", "lastName", "email", "company", "jobTitle", "linkedin"];
|
|
5
|
+
function projectLead(lead, fields) {
|
|
6
|
+
const source = lead && typeof lead === "object" ? lead : {};
|
|
7
|
+
const data = source.data && typeof source.data === "object" ? source.data : {};
|
|
8
|
+
const projected = { id: source.id };
|
|
9
|
+
for (const field of fields)
|
|
10
|
+
if (data[field] !== undefined)
|
|
11
|
+
projected[field] = data[field];
|
|
12
|
+
return projected;
|
|
13
|
+
}
|
|
14
|
+
function compactLeadsResponse(data, fields, includeSchema) {
|
|
15
|
+
const source = data && typeof data === "object" ? data : {};
|
|
16
|
+
const leads = Array.isArray(source.leads) ? source.leads : [];
|
|
17
|
+
const result = { leads: leads.map((lead) => projectLead(lead, fields)), pagination: source.pagination };
|
|
18
|
+
if (includeSchema)
|
|
19
|
+
result.schema = source.schema;
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
4
22
|
export function registerLeadTools(server) {
|
|
5
23
|
// ── add_leads ──────────────────────────────────────────────────────────
|
|
6
24
|
server.tool("add_leads", "Add one or more leads to a specific lead group in Leadify. Provide the group ID " +
|
|
@@ -42,11 +60,9 @@ export function registerLeadTools(server) {
|
|
|
42
60
|
});
|
|
43
61
|
// ── get_leads ──────────────────────────────────────────────────────────
|
|
44
62
|
server.tool("get_leads", "Search and list leads from a Leadify lead group with optional filtering, search, " +
|
|
45
|
-
"and
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"the group schema. Use this to browse, search, or filter leads. For retrieving " +
|
|
49
|
-
"a single lead by its ID, use get_lead instead.", {
|
|
63
|
+
"full-text search, saved views, and compact field projections. Returns lead ID plus " +
|
|
64
|
+
"common identity fields by default. Pass `fields` for a workflow-specific projection " +
|
|
65
|
+
"and `include_schema=true` only when the schema is explicitly needed.", {
|
|
50
66
|
group_id: z.string().describe("ID of the lead group to query."),
|
|
51
67
|
view_id: z
|
|
52
68
|
.string()
|
|
@@ -69,6 +85,8 @@ export function registerLeadTools(server) {
|
|
|
69
85
|
.string()
|
|
70
86
|
.optional()
|
|
71
87
|
.describe("Full-text search term applied across all fields."),
|
|
88
|
+
fields: z.array(z.string()).min(1).max(30).optional().describe("Lead data fields to return. Defaults to a compact identity projection."),
|
|
89
|
+
include_schema: z.boolean().optional().default(false).describe("Include the complete group schema only when explicitly needed."),
|
|
72
90
|
filters: z
|
|
73
91
|
.record(z.record(z.string()))
|
|
74
92
|
.optional()
|
|
@@ -76,7 +94,7 @@ export function registerLeadTools(server) {
|
|
|
76
94
|
"operator to value. Operators: equals, not_equals, contains, not_contains, " +
|
|
77
95
|
"gte, lte, is_true, is_false, is_null, is_not_null. " +
|
|
78
96
|
'Example: {"industry": {"contains": "tech"}, "company": {"is_not_null": "true"}}'),
|
|
79
|
-
}, async ({ group_id, view_id, page, limit, search, filters }) => {
|
|
97
|
+
}, async ({ group_id, view_id, page, limit, search, fields, include_schema, filters }) => {
|
|
80
98
|
try {
|
|
81
99
|
const params = new URLSearchParams();
|
|
82
100
|
params.set("groupId", group_id);
|
|
@@ -96,29 +114,32 @@ export function registerLeadTools(server) {
|
|
|
96
114
|
}
|
|
97
115
|
}
|
|
98
116
|
const data = await getClient().get("/get-leads", params);
|
|
99
|
-
return toolResult(data);
|
|
117
|
+
return toolResult(compactLeadsResponse(data, fields ?? DEFAULT_LEAD_FIELDS, include_schema));
|
|
100
118
|
}
|
|
101
119
|
catch (error) {
|
|
102
120
|
return handleToolError(error);
|
|
103
121
|
}
|
|
104
122
|
});
|
|
105
123
|
// ── get_lead ───────────────────────────────────────────────────────────
|
|
106
|
-
server.tool("get_lead", "Retrieve
|
|
107
|
-
"
|
|
108
|
-
"configured), and the group schema. Use this when you already have a lead ID " +
|
|
109
|
-
"and need its complete information. For searching or browsing multiple leads, " +
|
|
110
|
-
"use get_leads instead. " +
|
|
111
|
-
"Note: the group schema lives at `lead.group.schema` (no top-level `schema` " +
|
|
112
|
-
"field). System-level `select` field options (qualification_level, " +
|
|
113
|
-
"qualification_status, seniority, institution_type) are reconciled against the " +
|
|
114
|
-
"canonical registry, so all legitimate values are listed.", {
|
|
124
|
+
server.tool("get_lead", "Retrieve a compact projection for a single lead. Defaults to identity fields only; " +
|
|
125
|
+
"request fields for workflow-specific data and include_schema only when needed.", {
|
|
115
126
|
id: z.string().describe("The unique ID of the lead to retrieve."),
|
|
116
|
-
|
|
127
|
+
fields: z.array(z.string()).min(1).max(30).optional().describe("Lead data fields to return."),
|
|
128
|
+
include_schema: z.boolean().optional().default(false).describe("Include the group schema only when explicitly needed."),
|
|
129
|
+
}, async ({ id, fields, include_schema }) => {
|
|
117
130
|
try {
|
|
118
131
|
const params = new URLSearchParams();
|
|
119
132
|
params.set("id", id);
|
|
120
133
|
const data = await getClient().get("/get-lead", params);
|
|
121
|
-
|
|
134
|
+
const source = data && typeof data === "object" ? data : {};
|
|
135
|
+
const lead = source.lead;
|
|
136
|
+
const result = { lead: projectLead(lead, fields ?? DEFAULT_LEAD_FIELDS) };
|
|
137
|
+
if (include_schema && lead && typeof lead === "object") {
|
|
138
|
+
const group = lead.group;
|
|
139
|
+
if (group && typeof group === "object")
|
|
140
|
+
result.schema = group.schema;
|
|
141
|
+
}
|
|
142
|
+
return toolResult(result);
|
|
122
143
|
}
|
|
123
144
|
catch (error) {
|
|
124
145
|
return handleToolError(error);
|
package/dist/tools/logs.js
CHANGED
|
@@ -124,6 +124,7 @@ export function registerLogTools(server) {
|
|
|
124
124
|
.max(100)
|
|
125
125
|
.optional()
|
|
126
126
|
.describe("Results per page. Defaults to 50, max 100."),
|
|
127
|
+
include_message_for_log_ids: z.array(z.string()).max(10).optional().describe("Explicit log IDs whose complete message is required."),
|
|
127
128
|
sort_by: z
|
|
128
129
|
.enum(["createdAt", "level", "action", "campaignSlug"])
|
|
129
130
|
.optional()
|
|
@@ -158,7 +159,17 @@ export function registerLogTools(server) {
|
|
|
158
159
|
if (params.sort_order)
|
|
159
160
|
qp.set("sort_order", params.sort_order);
|
|
160
161
|
const data = await getClient().get("/get-lead-logs", qp);
|
|
161
|
-
|
|
162
|
+
const source = data && typeof data === "object" ? data : {};
|
|
163
|
+
const requested = new Set(params.include_message_for_log_ids ?? []);
|
|
164
|
+
const logs = Array.isArray(source.data) ? source.data : [];
|
|
165
|
+
const compact = logs.map((log) => {
|
|
166
|
+
const value = log && typeof log === "object" ? log : {};
|
|
167
|
+
const item = { id: value.id, leadId: value.leadId, campaignSlug: value.campaignSlug, campaignName: value.campaignName, action: value.action, level: value.level, createdAt: value.createdAt, errorCode: value.errorCode, retryCount: value.retryCount };
|
|
168
|
+
if (requested.has(String(value.id)))
|
|
169
|
+
item.message = value.message;
|
|
170
|
+
return item;
|
|
171
|
+
});
|
|
172
|
+
return toolResult({ logs: compact, pagination: source.pagination });
|
|
162
173
|
}
|
|
163
174
|
catch (error) {
|
|
164
175
|
return handleToolError(error);
|