@agifyai/leadify-mcp 9.15.0 → 9.16.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 +3 -2
- package/dist/tools/campaigns.js +20 -2
- package/dist/tools/views.js +15 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -304,7 +304,7 @@ Leadify et ne doit jamais être envoyée par un agent MCP.
|
|
|
304
304
|
| `delete_campaign_log` | Supprimer une entrée de log de campagne. |
|
|
305
305
|
| `update_campaign_stats` | Mettre à jour les statistiques d'email d'une campagne pour un groupe de leads. |
|
|
306
306
|
| `create_campaign` | Créer une campagne DRAFT mono-canal rattachée à un Lead Group qui possède déjà sa paire Persona–Offre. Aucun `persona_id` ou contexte indépendant n’est accepté au niveau Campagne. `channel` (`LINKEDIN` ou `EMAIL`) est obligatoire ; `start_at` inclusif, `end_at` exclusif et `timezone` IANA configurent la fenêtre métier. À `end_at`, Leadify met la campagne en pause réversible (`WINDOW_END`) sans la clôturer. |
|
|
307
|
-
| `update_campaign` / `update_campaign_configuration` | Modifier le nom, la description
|
|
307
|
+
| `update_campaign` / `update_campaign_configuration` | Modifier le nom, la description, la fenêtre, la limite par jour (`daily_limit`) et les jours d'envoi (`send_days`) de toute campagne encore `OPEN`, y compris en pilote ; l'audience (`audience_view_id`) se change jusqu'au lancement. La réponse rend `settings` et `sequenceWindowWarning` si la fin de campagne coupe la séquence; le canal reste modifiable uniquement en DRAFT. Prolonger `end_at` dans le futur ou le supprimer relance automatiquement une pause `WINDOW_END` après validation du fournisseur, mais jamais une pause manuelle. La fenêtre demandée reste enregistrée si cette validation échoue. La Persona est héritée du Lead Group et n’est pas modifiable au niveau Campagne. |
|
|
308
308
|
| `delete_campaign` | Supprimer irréversiblement une campagne `DRAFT` ou `PAUSED` encore `OPEN`, avec la confirmation explicite `delete_campaign`. Une campagne active ou clôturée est refusée, et aucun envoi n’est déclenché. |
|
|
309
309
|
| `list_campaigns` | Lister compactement les campagnes d'une organisation explicitement sélectionnée, avec état effectif, fenêtre, motif de pause et clôture. |
|
|
310
310
|
| `get_campaign` | Récupérer les détails d'une campagne, son état effectif, sa clôture et son éventuel rapport final figé, ainsi que ses KPIs temps réel. |
|
|
@@ -475,7 +475,8 @@ d'écrire à quelqu'un : `get_contact_state`, puis `get_prospect_approach`. Les
|
|
|
475
475
|
échanges captés à la main (emails et messages LinkedIn, avec texte, auteur et
|
|
476
476
|
origine) arrivent dans `organizationContact.exchanges` de
|
|
477
477
|
`get_outreach_contact_history` et de la première page de
|
|
478
|
-
`get_outreach_context_history`.
|
|
478
|
+
`get_outreach_context_history`. Une vue qu'aucune campagne n'utilise se supprime
|
|
479
|
+
avec `delete_lead_view`. Les vues (`preview_lead_view`,
|
|
479
480
|
`create_lead_view`) acceptent les 12 champs `__contact_*` (dont `__contact_due`,
|
|
480
481
|
le filtre « À relancer »), `within_last_days`, `older_than_days` et
|
|
481
482
|
`includeEmpty`. Les listes fermées des entrées sont recopiées octet pour octet du
|
package/dist/tools/campaigns.js
CHANGED
|
@@ -142,7 +142,18 @@ export function registerCampaignTools(server, readClient, writeClient, mutationC
|
|
|
142
142
|
timezone: z.string().min(1).optional().describe("IANA timezone used for the business window, for example Europe/Paris."),
|
|
143
143
|
name: z.string().min(1).optional().describe("New campaign name."),
|
|
144
144
|
description: z.string().nullable().optional().describe("New campaign description, or null to clear it."),
|
|
145
|
-
|
|
145
|
+
daily_limit: z.number().int().min(1).optional().describe("Daily sending limit of the campaign channel, as on the campaign page: at most 500 for EMAIL, at most 30 for LINKEDIN (invitations and messages)."),
|
|
146
|
+
send_days: z.object({
|
|
147
|
+
monday: z.boolean().optional(),
|
|
148
|
+
tuesday: z.boolean().optional(),
|
|
149
|
+
wednesday: z.boolean().optional(),
|
|
150
|
+
thursday: z.boolean().optional(),
|
|
151
|
+
friday: z.boolean().optional(),
|
|
152
|
+
saturday: z.boolean().optional(),
|
|
153
|
+
sunday: z.boolean().optional(),
|
|
154
|
+
}).strict().optional().describe("Sending days to change; omitted days stay as they are. At least one day must stay enabled."),
|
|
155
|
+
audience_view_id: z.string().min(1).nullable().optional().describe("Audience segment: a lead view of the campaign group, or null for the whole group. Refused once the campaign is launched (only DRAFT and PILOT)."),
|
|
156
|
+
}, async ({ id, channel, start_at, end_at, timezone, name, description, daily_limit, send_days, audience_view_id }) => {
|
|
146
157
|
try {
|
|
147
158
|
const body = {};
|
|
148
159
|
if (channel !== undefined)
|
|
@@ -157,6 +168,12 @@ export function registerCampaignTools(server, readClient, writeClient, mutationC
|
|
|
157
168
|
body.name = name;
|
|
158
169
|
if (description !== undefined)
|
|
159
170
|
body.description = description;
|
|
171
|
+
if (daily_limit !== undefined)
|
|
172
|
+
body.dailyLimit = daily_limit;
|
|
173
|
+
if (send_days !== undefined)
|
|
174
|
+
body.sendDays = send_days;
|
|
175
|
+
if (audience_view_id !== undefined)
|
|
176
|
+
body.audienceViewId = audience_view_id;
|
|
160
177
|
return toolResult(await (mutationClient ?? getClient()).put(`/api/campaign/${encodeURIComponent(id)}/configuration`, body));
|
|
161
178
|
}
|
|
162
179
|
catch (error) {
|
|
@@ -164,7 +181,8 @@ export function registerCampaignTools(server, readClient, writeClient, mutationC
|
|
|
164
181
|
}
|
|
165
182
|
});
|
|
166
183
|
};
|
|
167
|
-
const updateCampaignDescription = "Edit the name, description,
|
|
184
|
+
const updateCampaignDescription = "Edit the name, description, lifecycle window, daily limit and sending days of any OPEN campaign, including a campaign in PILOT, as the campaign page does; " +
|
|
185
|
+
"the audience segment changes until launch, and changing channel remains limited to DRAFT. The response returns the saved settings and sequenceWindowWarning when the campaign end cuts the longest sequence. " +
|
|
168
186
|
"Extending endAt into the future or removing it automatically resumes only a campaign paused " +
|
|
169
187
|
"because WINDOW_END, after provider validation and immediate replanning. A MANUAL pause never " +
|
|
170
188
|
"auto-resumes. The requested window remains saved when provider validation fails, and a CLOSED " +
|
package/dist/tools/views.js
CHANGED
|
@@ -65,7 +65,7 @@ export function registerLeadViewTools(server) {
|
|
|
65
65
|
return handleToolError(error);
|
|
66
66
|
}
|
|
67
67
|
});
|
|
68
|
-
server.tool("create_lead_view", "Create an organization-shared saved view after previewing it. Idempotency key is required: retry the same request with the same key; changing the payload with that key conflicts. Update
|
|
68
|
+
server.tool("create_lead_view", "Create an organization-shared saved view after previewing it. Idempotency key is required: retry the same request with the same key; changing the payload with that key conflicts. Update is intentionally unavailable; delete_lead_view removes a view no campaign uses. " +
|
|
69
69
|
"Filters may use the contact fields __contact_*, with within_last_days, older_than_days and includeEmpty (see preview_lead_view).", { ...viewConfigSchema, idempotency_key: z.string().min(8).max(200) }, async ({ organization_id, lead_group_id, name, filters, columns, sort, pagination, idempotency_key }) => {
|
|
70
70
|
try {
|
|
71
71
|
const data = await getClient().post(`/api/lead-group/${encodeURIComponent(lead_group_id)}/views`, { organizationId: organization_id, name, filters, columns, sort, pagination, idempotencyKey: idempotency_key });
|
|
@@ -75,4 +75,18 @@ export function registerLeadViewTools(server) {
|
|
|
75
75
|
return handleToolError(error);
|
|
76
76
|
}
|
|
77
77
|
});
|
|
78
|
+
server.tool("delete_lead_view", "Delete one organization-shared saved view that no campaign uses. No lead is deleted. The default view cannot be deleted, and a view chosen by a campaign is refused with the list of those campaigns. Always confirm with the user first.", {
|
|
79
|
+
organization_id: z.string().min(1),
|
|
80
|
+
lead_group_id: z.string().min(1),
|
|
81
|
+
view_id: z.string().min(1),
|
|
82
|
+
confirmation: z.literal("delete_lead_view").describe("Exact acknowledgement required before deleting the view."),
|
|
83
|
+
}, async ({ organization_id, lead_group_id, view_id }) => {
|
|
84
|
+
try {
|
|
85
|
+
const data = await getClient().delete(`/api/lead-group/${encodeURIComponent(lead_group_id)}/views/${encodeURIComponent(view_id)}?organizationId=${encodeURIComponent(organization_id)}`);
|
|
86
|
+
return toolResult(data);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
return handleToolError(error);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
78
92
|
}
|