@agifyai/leadify-mcp 8.6.6 → 8.6.8
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
|
@@ -289,6 +289,9 @@ Leadify et ne doit jamais être envoyée par un agent MCP.
|
|
|
289
289
|
| `preview_canonical_relationship_migration` | Prévisualiser une migration de champs historiques, divergences et quarantaines comprises, sans mutation. |
|
|
290
290
|
| `apply_canonical_relationship_migration` | Appliquer exactement un plan prévisualisé et borné grâce à son digest. |
|
|
291
291
|
| `rollback_canonical_relationship_migration` | Tombstoner les liens créés par un plan de migration précis. |
|
|
292
|
+
| `configure_lead_group_relations` | Configurer, dans un tenant explicitement vérifié, la projection legacy relue par une migration canonique. |
|
|
293
|
+
| `preview_canonical_identity_backfill` | Prévisualiser le backfill d'identité tenant-scoped d'un groupe et de ses parents Company configurés. |
|
|
294
|
+
| `apply_canonical_identity_backfill` | Appliquer exactement un backfill d'identité relu par digest, sans outreach ni activation. |
|
|
292
295
|
| `update_company_brain_sections` | Modifier uniquement les sections globales encore actives (`identity`, `positioning`, `allowedVocabulary`, `prohibitedVocabulary`, `legalConstraints`). Les anciennes sections Offre/Verticale sont filtrées et refusées. |
|
|
293
296
|
| `publish_context_workspace` | Publier une révision prête du Company Brain après confirmation explicite (`confirm_publish: true`). Admin de l'organisation requis ; les raisons de non-readiness sont renvoyées par le serveur. |
|
|
294
297
|
| `list_persona_contracts` / `get_persona_contract` | Lister ou lire les contrats Persona canoniques d’une organisation explicitement sélectionnée. |
|
package/dist/server.js
CHANGED
|
@@ -15,6 +15,7 @@ import { registerFineTuningTools } from "./tools/fine_tuning.js";
|
|
|
15
15
|
import { registerContextWorkspaceTools } from "./tools/context_workspace.js";
|
|
16
16
|
import { registerLeadViewTools } from "./tools/views.js";
|
|
17
17
|
import { registerRelationshipTools } from "./tools/relationships.js";
|
|
18
|
+
import { registerCanonicalBackfillTools } from "./tools/canonical_backfill.js";
|
|
18
19
|
import { registerCommercialTruthTools } from "./tools/commercial_truth.js";
|
|
19
20
|
import { registerEventTools } from "./tools/events.js";
|
|
20
21
|
import { registerContextEntityTools } from "./tools/context_entities.js";
|
|
@@ -30,6 +31,7 @@ export function createServer() {
|
|
|
30
31
|
registerLeadViewTools(server);
|
|
31
32
|
registerLeadTools(server);
|
|
32
33
|
registerRelationshipTools(server);
|
|
34
|
+
registerCanonicalBackfillTools(server);
|
|
33
35
|
registerEventTools(server);
|
|
34
36
|
registerCommercialTruthTools(server);
|
|
35
37
|
registerSchemaTools(server);
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getClient } from "../client.js";
|
|
3
|
+
import { handleToolError, toolResult } from "../types.js";
|
|
4
|
+
const relationshipType = z.enum(["EMPLOYED_BY", "AFFILIATED_WITH", "PART_OF", "COLLEAGUE_OF"]);
|
|
5
|
+
const relation = z.object({
|
|
6
|
+
field: z.string().trim().min(1),
|
|
7
|
+
lead_group_id: z.string().trim().min(1),
|
|
8
|
+
target_field: z.string().trim().min(1).optional(),
|
|
9
|
+
display_field: z.string().trim().min(1).optional(),
|
|
10
|
+
inverse_field: z.string().trim().min(1).optional(),
|
|
11
|
+
canonical_type: relationshipType.optional(),
|
|
12
|
+
canonical_endpoint_role: z.enum(["SOURCE", "TARGET"]).optional(),
|
|
13
|
+
canonical_label: z.string().trim().min(1).max(120).optional(),
|
|
14
|
+
}).strict().superRefine((value, context) => {
|
|
15
|
+
if (Boolean(value.canonical_type) === Boolean(value.canonical_endpoint_role))
|
|
16
|
+
return;
|
|
17
|
+
context.addIssue({ code: z.ZodIssueCode.custom, path: ["canonical_type"], message: "canonical_type and canonical_endpoint_role must be provided together" });
|
|
18
|
+
});
|
|
19
|
+
function apiRelation(value) {
|
|
20
|
+
return {
|
|
21
|
+
field: value.field,
|
|
22
|
+
leadGroupId: value.lead_group_id,
|
|
23
|
+
targetField: value.target_field,
|
|
24
|
+
displayField: value.display_field,
|
|
25
|
+
inverseField: value.inverse_field,
|
|
26
|
+
canonicalType: value.canonical_type,
|
|
27
|
+
canonicalEndpointRole: value.canonical_endpoint_role,
|
|
28
|
+
canonicalLabel: value.canonical_label,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const backfillScope = {
|
|
32
|
+
organization_id: z.string().trim().min(1),
|
|
33
|
+
lead_group_id: z.string().trim().min(1),
|
|
34
|
+
lead_ids: z.array(z.string().trim().min(1)).min(1).max(100),
|
|
35
|
+
};
|
|
36
|
+
export function registerCanonicalBackfillTools(server, client = getClient()) {
|
|
37
|
+
server.tool("configure_lead_group_relations", "Configure the legacy projection that a canonical migration reads. The organization is mandatory and verified against both groups; canonical_type and canonical_endpoint_role must be specified together. This changes no lead, identity, canonical relationship, campaign, or outreach.", { organization_id: z.string().trim().min(1), lead_group_id: z.string().trim().min(1), relations: z.array(relation).max(100) }, async ({ organization_id, lead_group_id, relations }) => {
|
|
38
|
+
try {
|
|
39
|
+
return toolResult(await client.put(`/api/lead-group/${encodeURIComponent(lead_group_id)}/relations`, {
|
|
40
|
+
organizationId: organization_id,
|
|
41
|
+
relations: relations.map(apiRelation),
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
return handleToolError(error);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
server.tool("preview_canonical_identity_backfill", "Preview the tenant-scoped canonical identity backfill for one LeadGroup. It reads only the listed leads and their configured Company parent, returns an exact plan digest, and creates no identity, relationship, outreach, or activation.", backfillScope, async ({ organization_id, lead_group_id, lead_ids }) => {
|
|
49
|
+
try {
|
|
50
|
+
return toolResult(await client.post("/api/canonical-identity/backfill", {
|
|
51
|
+
organizationId: organization_id, leadGroupId: lead_group_id, leadIds: lead_ids,
|
|
52
|
+
projectionTarget: "lead", dryRun: true,
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
return handleToolError(error);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
server.tool("apply_canonical_identity_backfill", "Apply exactly a reviewed canonical identity backfill plan. The organization and LeadGroup stay explicit, and the backend rejects a changed digest, cross-tenant lead, missing parent, or missing canonical Company account. It never sends outreach or activates campaigns.", { ...backfillScope, expected_plan_digest: z.string().regex(/^[a-f0-9]{64}$/) }, async ({ organization_id, lead_group_id, lead_ids, expected_plan_digest }) => {
|
|
60
|
+
try {
|
|
61
|
+
return toolResult(await client.post("/api/canonical-identity/backfill", {
|
|
62
|
+
organizationId: organization_id, leadGroupId: lead_group_id, leadIds: lead_ids,
|
|
63
|
+
projectionTarget: "lead", dryRun: false, expectedPlanDigest: expected_plan_digest,
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
return handleToolError(error);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
package/dist/tools/schema.js
CHANGED
|
@@ -85,7 +85,7 @@ export function registerSchemaTools(server, client) {
|
|
|
85
85
|
lead_group_id: z.string().describe("ID of the lead group to inspect."),
|
|
86
86
|
}, async ({ lead_group_id }) => {
|
|
87
87
|
try {
|
|
88
|
-
const data = await (client ?? getClient()).
|
|
88
|
+
const data = await (client ?? getClient()).post(`/api/lead-group/${encodeURIComponent(lead_group_id)}/schema-migration/preview`, {});
|
|
89
89
|
return toolResult(data);
|
|
90
90
|
}
|
|
91
91
|
catch (error) {
|
|
@@ -102,8 +102,7 @@ export function registerSchemaTools(server, client) {
|
|
|
102
102
|
confirmation: z.literal("apply_destructive_schema_migration").describe("Exact acknowledgement required by the server."),
|
|
103
103
|
}, async ({ lead_group_id, expected_schema_hash, expected_plan_hash, confirmation }) => {
|
|
104
104
|
try {
|
|
105
|
-
const data = await (client ?? getClient()).
|
|
106
|
-
leadGroupId: lead_group_id,
|
|
105
|
+
const data = await (client ?? getClient()).post(`/api/lead-group/${encodeURIComponent(lead_group_id)}/schema-migration/apply`, {
|
|
107
106
|
expectedSchemaHash: expected_schema_hash,
|
|
108
107
|
expectedPlanHash: expected_plan_hash,
|
|
109
108
|
confirmation,
|