@agifyai/leadify-mcp 9.1.1 → 9.3.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 +48 -0
- package/dist/client.js +11 -1
- package/dist/server.js +4 -0
- package/dist/tools/context_entities.d.ts +66 -66
- package/dist/tools/organizations.d.ts +2 -1
- package/dist/tools/organizations.js +15 -3
- package/dist/tools/outreach_exclusion.d.ts +3 -0
- package/dist/tools/outreach_exclusion.js +89 -0
- package/dist/tools/qualification_runs.d.ts +3 -0
- package/dist/tools/qualification_runs.js +33 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -234,6 +234,9 @@ Leadify et ne doit jamais être envoyée par un agent MCP.
|
|
|
234
234
|
| `add_leads` | Import plat générique vers un groupe : ne crée aucune relation d’emploi, aucun rattachement parent ni identité canonique. Ne jamais l’utiliser pour rattacher une Personne à une Company (voir `upsert_person_leads_with_employment`). |
|
|
235
235
|
| `upsert_person_leads_with_employment` | Créer ou réconcilier atomiquement des Person Leads, PERSON, EMPLOYED_BY, projections et historique, sans effet commercial. |
|
|
236
236
|
| `create_person_employment_evidence` / `get_person_employment_evidence` | Créer puis relire une preuve d’emploi individuelle tenant-scopée ; transmettre l’`evidence.id` retourné tel quel à l’upsert Person. |
|
|
237
|
+
| `exclude_account` | Exclure une entreprise (établissement) et toutes ses personnes liées : cause protégée `ACCOUNT_EXCLUDED`, motif et URL source obligatoires, `level: "establishment"`. |
|
|
238
|
+
| `exclude_lead` / `reintegrate_lead` | Exclure ou réintégrer une personne avec les mêmes commandes que l'interface ; raison obligatoire, aucun motif protégé levé. |
|
|
239
|
+
| `get_outreach_state` | Lire causes actives, version et date de 1 à 100 fiches. |
|
|
237
240
|
| `get_leads` | Rechercher et lister des leads avec filtres, recherche et pagination, dont le critère composé `event_filter`. |
|
|
238
241
|
| `get_lead` | Récupérer les détails complets d'un lead par son ID. |
|
|
239
242
|
| `update_lead` | Mettre à jour un ou plusieurs champs d'un lead existant. |
|
|
@@ -374,3 +377,48 @@ Aucune mutation de sourcing ne qualifie le lead, n’enrichit les contacts
|
|
|
374
377
|
(email/téléphone), ne génère de message, n’inscrit en campagne et n’active
|
|
375
378
|
aucun canal externe : le readback porte `noSend: true` et
|
|
376
379
|
`externalActivation: 0`.
|
|
380
|
+
|
|
381
|
+
### Exclusions de prospection (PRD-2404)
|
|
382
|
+
|
|
383
|
+
Une exclusion ne s'écrit jamais en texte (Context Workspace, notes, persona) ni dans les
|
|
384
|
+
champs `excluded`, `hide_from_campaign` ou `outreach_status` : le serveur refuse
|
|
385
|
+
ces champs (409 `PROTECTED_OUTREACH_FIELD`). Utiliser `exclude_account` pour un
|
|
386
|
+
client existant ou un compte à ne pas contacter : motif et `source_url` publique
|
|
387
|
+
obligatoires, les personnes liées sont exclues tant que le lien existe et leurs
|
|
388
|
+
campagnes s'arrêtent. Leadify ne distingue pas les services : la réponse dit
|
|
389
|
+
toujours `level: "establishment"`. `exclude_lead` et `reintegrate_lead` agissent
|
|
390
|
+
sur une personne ; la réintégration ne lève jamais une opposition, une protection
|
|
391
|
+
de délivrabilité ni l'exclusion d'une entreprise. Chaque écriture accepte
|
|
392
|
+
`idempotency_key` et `expected_version`, et rend l'état relu ;
|
|
393
|
+
`get_outreach_state` relit 1 à 100 fiches. Routes serveur : `/api/outreach/*`
|
|
394
|
+
(PRD-2337), auteur tracé dans Leadify : propriétaire de la clé, source Agent.
|
|
395
|
+
|
|
396
|
+
### Création d’organisation et qualification (PRD-2398)
|
|
397
|
+
|
|
398
|
+
Dans Leadify, **Réglages → Clés API → Modifier** permet de changer les actions
|
|
399
|
+
et les organisations accessibles sans remplacer la clé. Le choix explicite
|
|
400
|
+
« Toutes les organisations actuelles et futures » inclut les futures créations.
|
|
401
|
+
Le droit `create_organization`, accordé par un administrateur global, complète
|
|
402
|
+
le droit d’écriture. `create_organization` normalise le domaine et renvoie la
|
|
403
|
+
même organisation lors d’une répétition ; le compte appelant en devient
|
|
404
|
+
administrateur. `list_organizations({ domain })` fait une recherche sans création.
|
|
405
|
+
|
|
406
|
+
`start_qualification_run` exige une organisation, un groupe, une liste explicite
|
|
407
|
+
de 1 à 20 entreprises et un `request_id` UUID. Commencer avec `dry_run: true`
|
|
408
|
+
(valeur par défaut), puis transmettre le `expectedSchemaHash` retourné dans
|
|
409
|
+
`expected_schema_hash` avec `dry_run: false`. La clé doit avoir les droits
|
|
410
|
+
`write` et `start_qualification`, et son propriétaire doit administrer
|
|
411
|
+
l’organisation. Chaque entreprise doit avoir un employé vérifié et relié.
|
|
412
|
+
Avant l’accord du pilote dans les réglages du groupe, deux entreprises distinctes
|
|
413
|
+
au plus sont admises, même avec plusieurs appels. Une répétition conserve le
|
|
414
|
+
même `request_id` et la même sélection. Aucun groupe entier n’est déduit.
|
|
415
|
+
|
|
416
|
+
`get_qualification_run` reçoit le `run_id` retourné et l’organisation explicite.
|
|
417
|
+
Il conserve les statuts et refus, et relit les documents enregistrés aux révisions
|
|
418
|
+
exactes du run : température, faits datés, preuves et personnes qualifiées.
|
|
419
|
+
Une réception de lancement ne prouve pas la fin du traitement. Ces outils ne
|
|
420
|
+
préparent ni n’envoient de message commercial.
|
|
421
|
+
|
|
422
|
+
Pour les essais locaux, `LEADIFY_LOCAL_API_URL=http://localhost:<port>` dirige
|
|
423
|
+
le MCP vers une origine HTTP locale. Les adresses distantes sont refusées par ce
|
|
424
|
+
réglage ; sans ce réglage, l’adresse habituelle de Leadify est utilisée.
|
package/dist/client.js
CHANGED
|
@@ -3,7 +3,17 @@ export class LeadifyClient {
|
|
|
3
3
|
baseUrl;
|
|
4
4
|
apiKey;
|
|
5
5
|
constructor() {
|
|
6
|
-
|
|
6
|
+
const localUrl = process.env.LEADIFY_LOCAL_API_URL;
|
|
7
|
+
if (localUrl) {
|
|
8
|
+
const parsed = new URL(localUrl);
|
|
9
|
+
if (parsed.protocol !== "http:" || !["localhost", "127.0.0.1", "[::1]"].includes(parsed.hostname)
|
|
10
|
+
|| parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
|
|
11
|
+
throw new Error("LEADIFY_LOCAL_API_URL must be a loopback HTTP origin.");
|
|
12
|
+
}
|
|
13
|
+
this.baseUrl = parsed.origin;
|
|
14
|
+
}
|
|
15
|
+
else
|
|
16
|
+
this.baseUrl = "https://api-leadify.agify.fr";
|
|
7
17
|
const key = process.env.LEADIFY_API_KEY;
|
|
8
18
|
if (!key) {
|
|
9
19
|
throw new Error("LEADIFY_API_KEY environment variable is required. " +
|
package/dist/server.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { registerQualificationRunTools } from "./tools/qualification_runs.js";
|
|
2
|
+
import { registerOutreachExclusionTools } from "./tools/outreach_exclusion.js";
|
|
1
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
4
|
import { registerAuthTools } from "./tools/auth.js";
|
|
3
5
|
import { registerLeadTools } from "./tools/leads.js";
|
|
@@ -51,5 +53,7 @@ export function createServer() {
|
|
|
51
53
|
registerDataSourceTools(server);
|
|
52
54
|
registerPersonaTools(server);
|
|
53
55
|
registerPipelineTools(server);
|
|
56
|
+
registerQualificationRunTools(server);
|
|
57
|
+
registerOutreachExclusionTools(server);
|
|
54
58
|
return server;
|
|
55
59
|
}
|
|
@@ -30,13 +30,13 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
30
30
|
value: z.ZodString;
|
|
31
31
|
explanation: z.ZodOptional<z.ZodString>;
|
|
32
32
|
}, "strict", z.ZodTypeAny, {
|
|
33
|
-
id: string;
|
|
34
33
|
value: string;
|
|
34
|
+
id: string;
|
|
35
35
|
label: string;
|
|
36
36
|
explanation?: string | undefined;
|
|
37
37
|
}, {
|
|
38
|
-
id: string;
|
|
39
38
|
value: string;
|
|
39
|
+
id: string;
|
|
40
40
|
label: string;
|
|
41
41
|
explanation?: string | undefined;
|
|
42
42
|
}>, "many">>;
|
|
@@ -47,13 +47,13 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
47
47
|
description: z.ZodOptional<z.ZodString>;
|
|
48
48
|
customerCaseIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
49
49
|
}, "strict", z.ZodTypeAny, {
|
|
50
|
-
id: string;
|
|
51
50
|
title: string;
|
|
51
|
+
id: string;
|
|
52
52
|
description?: string | undefined;
|
|
53
53
|
customerCaseIds?: string[] | undefined;
|
|
54
54
|
}, {
|
|
55
|
-
id: string;
|
|
56
55
|
title: string;
|
|
56
|
+
id: string;
|
|
57
57
|
description?: string | undefined;
|
|
58
58
|
customerCaseIds?: string[] | undefined;
|
|
59
59
|
}>, "many">>;
|
|
@@ -64,14 +64,14 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
64
64
|
useCaseIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
65
65
|
customerCaseIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
66
66
|
}, "strict", z.ZodTypeAny, {
|
|
67
|
-
id: string;
|
|
68
67
|
title: string;
|
|
68
|
+
id: string;
|
|
69
69
|
description?: string | undefined;
|
|
70
70
|
customerCaseIds?: string[] | undefined;
|
|
71
71
|
useCaseIds?: string[] | undefined;
|
|
72
72
|
}, {
|
|
73
|
-
id: string;
|
|
74
73
|
title: string;
|
|
74
|
+
id: string;
|
|
75
75
|
description?: string | undefined;
|
|
76
76
|
customerCaseIds?: string[] | undefined;
|
|
77
77
|
useCaseIds?: string[] | undefined;
|
|
@@ -82,13 +82,13 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
82
82
|
example: z.ZodOptional<z.ZodString>;
|
|
83
83
|
meaning: z.ZodOptional<z.ZodString>;
|
|
84
84
|
}, "strict", z.ZodTypeAny, {
|
|
85
|
-
id: string;
|
|
86
85
|
title: string;
|
|
86
|
+
id: string;
|
|
87
87
|
example?: string | undefined;
|
|
88
88
|
meaning?: string | undefined;
|
|
89
89
|
}, {
|
|
90
|
-
id: string;
|
|
91
90
|
title: string;
|
|
91
|
+
id: string;
|
|
92
92
|
example?: string | undefined;
|
|
93
93
|
meaning?: string | undefined;
|
|
94
94
|
}>, "many">>;
|
|
@@ -97,12 +97,12 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
97
97
|
title: z.ZodString;
|
|
98
98
|
description: z.ZodOptional<z.ZodString>;
|
|
99
99
|
}, "strict", z.ZodTypeAny, {
|
|
100
|
-
id: string;
|
|
101
100
|
title: string;
|
|
101
|
+
id: string;
|
|
102
102
|
description?: string | undefined;
|
|
103
103
|
}, {
|
|
104
|
-
id: string;
|
|
105
104
|
title: string;
|
|
105
|
+
id: string;
|
|
106
106
|
description?: string | undefined;
|
|
107
107
|
}>, "many">>;
|
|
108
108
|
competitors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -110,12 +110,12 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
110
110
|
title: z.ZodString;
|
|
111
111
|
description: z.ZodOptional<z.ZodString>;
|
|
112
112
|
}, "strict", z.ZodTypeAny, {
|
|
113
|
-
id: string;
|
|
114
113
|
title: string;
|
|
114
|
+
id: string;
|
|
115
115
|
description?: string | undefined;
|
|
116
116
|
}, {
|
|
117
|
-
id: string;
|
|
118
117
|
title: string;
|
|
118
|
+
id: string;
|
|
119
119
|
description?: string | undefined;
|
|
120
120
|
}>, "many">>;
|
|
121
121
|
objections: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -138,12 +138,12 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
138
138
|
title: z.ZodString;
|
|
139
139
|
description: z.ZodOptional<z.ZodString>;
|
|
140
140
|
}, "strict", z.ZodTypeAny, {
|
|
141
|
-
id: string;
|
|
142
141
|
title: string;
|
|
142
|
+
id: string;
|
|
143
143
|
description?: string | undefined;
|
|
144
144
|
}, {
|
|
145
|
-
id: string;
|
|
146
145
|
title: string;
|
|
146
|
+
id: string;
|
|
147
147
|
description?: string | undefined;
|
|
148
148
|
}>, "many">>;
|
|
149
149
|
regulatoryInformation: z.ZodOptional<z.ZodString>;
|
|
@@ -162,8 +162,8 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
162
162
|
}>, "many">>;
|
|
163
163
|
}, "strict", z.ZodTypeAny, {
|
|
164
164
|
painPoints?: {
|
|
165
|
-
id: string;
|
|
166
165
|
title: string;
|
|
166
|
+
id: string;
|
|
167
167
|
description?: string | undefined;
|
|
168
168
|
customerCaseIds?: string[] | undefined;
|
|
169
169
|
useCaseIds?: string[] | undefined;
|
|
@@ -171,8 +171,8 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
171
171
|
allowedVocabulary?: string[] | undefined;
|
|
172
172
|
prohibitedVocabulary?: string[] | undefined;
|
|
173
173
|
legalConstraints?: {
|
|
174
|
-
id: string;
|
|
175
174
|
title: string;
|
|
175
|
+
id: string;
|
|
176
176
|
description?: string | undefined;
|
|
177
177
|
}[] | undefined;
|
|
178
178
|
customerCaseIds?: string[] | undefined;
|
|
@@ -187,31 +187,31 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
187
187
|
characteristics?: string[] | undefined;
|
|
188
188
|
} | undefined;
|
|
189
189
|
marketMetrics?: {
|
|
190
|
-
id: string;
|
|
191
190
|
value: string;
|
|
191
|
+
id: string;
|
|
192
192
|
label: string;
|
|
193
193
|
explanation?: string | undefined;
|
|
194
194
|
}[] | undefined;
|
|
195
195
|
useCases?: {
|
|
196
|
-
id: string;
|
|
197
196
|
title: string;
|
|
197
|
+
id: string;
|
|
198
198
|
description?: string | undefined;
|
|
199
199
|
customerCaseIds?: string[] | undefined;
|
|
200
200
|
}[] | undefined;
|
|
201
201
|
qualificationSignals?: {
|
|
202
|
-
id: string;
|
|
203
202
|
title: string;
|
|
203
|
+
id: string;
|
|
204
204
|
example?: string | undefined;
|
|
205
205
|
meaning?: string | undefined;
|
|
206
206
|
}[] | undefined;
|
|
207
207
|
competitiveAdvantages?: {
|
|
208
|
-
id: string;
|
|
209
208
|
title: string;
|
|
209
|
+
id: string;
|
|
210
210
|
description?: string | undefined;
|
|
211
211
|
}[] | undefined;
|
|
212
212
|
competitors?: {
|
|
213
|
-
id: string;
|
|
214
213
|
title: string;
|
|
214
|
+
id: string;
|
|
215
215
|
description?: string | undefined;
|
|
216
216
|
}[] | undefined;
|
|
217
217
|
objections?: {
|
|
@@ -227,8 +227,8 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
227
227
|
}[] | undefined;
|
|
228
228
|
}, {
|
|
229
229
|
painPoints?: {
|
|
230
|
-
id: string;
|
|
231
230
|
title: string;
|
|
231
|
+
id: string;
|
|
232
232
|
description?: string | undefined;
|
|
233
233
|
customerCaseIds?: string[] | undefined;
|
|
234
234
|
useCaseIds?: string[] | undefined;
|
|
@@ -236,8 +236,8 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
236
236
|
allowedVocabulary?: string[] | undefined;
|
|
237
237
|
prohibitedVocabulary?: string[] | undefined;
|
|
238
238
|
legalConstraints?: {
|
|
239
|
-
id: string;
|
|
240
239
|
title: string;
|
|
240
|
+
id: string;
|
|
241
241
|
description?: string | undefined;
|
|
242
242
|
}[] | undefined;
|
|
243
243
|
customerCaseIds?: string[] | undefined;
|
|
@@ -252,31 +252,31 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
252
252
|
characteristics?: string[] | undefined;
|
|
253
253
|
} | undefined;
|
|
254
254
|
marketMetrics?: {
|
|
255
|
-
id: string;
|
|
256
255
|
value: string;
|
|
256
|
+
id: string;
|
|
257
257
|
label: string;
|
|
258
258
|
explanation?: string | undefined;
|
|
259
259
|
}[] | undefined;
|
|
260
260
|
useCases?: {
|
|
261
|
-
id: string;
|
|
262
261
|
title: string;
|
|
262
|
+
id: string;
|
|
263
263
|
description?: string | undefined;
|
|
264
264
|
customerCaseIds?: string[] | undefined;
|
|
265
265
|
}[] | undefined;
|
|
266
266
|
qualificationSignals?: {
|
|
267
|
-
id: string;
|
|
268
267
|
title: string;
|
|
268
|
+
id: string;
|
|
269
269
|
example?: string | undefined;
|
|
270
270
|
meaning?: string | undefined;
|
|
271
271
|
}[] | undefined;
|
|
272
272
|
competitiveAdvantages?: {
|
|
273
|
-
id: string;
|
|
274
273
|
title: string;
|
|
274
|
+
id: string;
|
|
275
275
|
description?: string | undefined;
|
|
276
276
|
}[] | undefined;
|
|
277
277
|
competitors?: {
|
|
278
|
-
id: string;
|
|
279
278
|
title: string;
|
|
279
|
+
id: string;
|
|
280
280
|
description?: string | undefined;
|
|
281
281
|
}[] | undefined;
|
|
282
282
|
objections?: {
|
|
@@ -292,8 +292,8 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
292
292
|
}[] | undefined;
|
|
293
293
|
}>, {
|
|
294
294
|
painPoints?: {
|
|
295
|
-
id: string;
|
|
296
295
|
title: string;
|
|
296
|
+
id: string;
|
|
297
297
|
description?: string | undefined;
|
|
298
298
|
customerCaseIds?: string[] | undefined;
|
|
299
299
|
useCaseIds?: string[] | undefined;
|
|
@@ -301,8 +301,8 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
301
301
|
allowedVocabulary?: string[] | undefined;
|
|
302
302
|
prohibitedVocabulary?: string[] | undefined;
|
|
303
303
|
legalConstraints?: {
|
|
304
|
-
id: string;
|
|
305
304
|
title: string;
|
|
305
|
+
id: string;
|
|
306
306
|
description?: string | undefined;
|
|
307
307
|
}[] | undefined;
|
|
308
308
|
customerCaseIds?: string[] | undefined;
|
|
@@ -317,31 +317,31 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
317
317
|
characteristics?: string[] | undefined;
|
|
318
318
|
} | undefined;
|
|
319
319
|
marketMetrics?: {
|
|
320
|
-
id: string;
|
|
321
320
|
value: string;
|
|
321
|
+
id: string;
|
|
322
322
|
label: string;
|
|
323
323
|
explanation?: string | undefined;
|
|
324
324
|
}[] | undefined;
|
|
325
325
|
useCases?: {
|
|
326
|
-
id: string;
|
|
327
326
|
title: string;
|
|
327
|
+
id: string;
|
|
328
328
|
description?: string | undefined;
|
|
329
329
|
customerCaseIds?: string[] | undefined;
|
|
330
330
|
}[] | undefined;
|
|
331
331
|
qualificationSignals?: {
|
|
332
|
-
id: string;
|
|
333
332
|
title: string;
|
|
333
|
+
id: string;
|
|
334
334
|
example?: string | undefined;
|
|
335
335
|
meaning?: string | undefined;
|
|
336
336
|
}[] | undefined;
|
|
337
337
|
competitiveAdvantages?: {
|
|
338
|
-
id: string;
|
|
339
338
|
title: string;
|
|
339
|
+
id: string;
|
|
340
340
|
description?: string | undefined;
|
|
341
341
|
}[] | undefined;
|
|
342
342
|
competitors?: {
|
|
343
|
-
id: string;
|
|
344
343
|
title: string;
|
|
344
|
+
id: string;
|
|
345
345
|
description?: string | undefined;
|
|
346
346
|
}[] | undefined;
|
|
347
347
|
objections?: {
|
|
@@ -357,8 +357,8 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
357
357
|
}[] | undefined;
|
|
358
358
|
}, {
|
|
359
359
|
painPoints?: {
|
|
360
|
-
id: string;
|
|
361
360
|
title: string;
|
|
361
|
+
id: string;
|
|
362
362
|
description?: string | undefined;
|
|
363
363
|
customerCaseIds?: string[] | undefined;
|
|
364
364
|
useCaseIds?: string[] | undefined;
|
|
@@ -366,8 +366,8 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
366
366
|
allowedVocabulary?: string[] | undefined;
|
|
367
367
|
prohibitedVocabulary?: string[] | undefined;
|
|
368
368
|
legalConstraints?: {
|
|
369
|
-
id: string;
|
|
370
369
|
title: string;
|
|
370
|
+
id: string;
|
|
371
371
|
description?: string | undefined;
|
|
372
372
|
}[] | undefined;
|
|
373
373
|
customerCaseIds?: string[] | undefined;
|
|
@@ -382,31 +382,31 @@ export declare const verticalContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
382
382
|
characteristics?: string[] | undefined;
|
|
383
383
|
} | undefined;
|
|
384
384
|
marketMetrics?: {
|
|
385
|
-
id: string;
|
|
386
385
|
value: string;
|
|
386
|
+
id: string;
|
|
387
387
|
label: string;
|
|
388
388
|
explanation?: string | undefined;
|
|
389
389
|
}[] | undefined;
|
|
390
390
|
useCases?: {
|
|
391
|
-
id: string;
|
|
392
391
|
title: string;
|
|
392
|
+
id: string;
|
|
393
393
|
description?: string | undefined;
|
|
394
394
|
customerCaseIds?: string[] | undefined;
|
|
395
395
|
}[] | undefined;
|
|
396
396
|
qualificationSignals?: {
|
|
397
|
-
id: string;
|
|
398
397
|
title: string;
|
|
398
|
+
id: string;
|
|
399
399
|
example?: string | undefined;
|
|
400
400
|
meaning?: string | undefined;
|
|
401
401
|
}[] | undefined;
|
|
402
402
|
competitiveAdvantages?: {
|
|
403
|
-
id: string;
|
|
404
403
|
title: string;
|
|
404
|
+
id: string;
|
|
405
405
|
description?: string | undefined;
|
|
406
406
|
}[] | undefined;
|
|
407
407
|
competitors?: {
|
|
408
|
-
id: string;
|
|
409
408
|
title: string;
|
|
409
|
+
id: string;
|
|
410
410
|
description?: string | undefined;
|
|
411
411
|
}[] | undefined;
|
|
412
412
|
objections?: {
|
|
@@ -429,12 +429,12 @@ export declare const offerContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
429
429
|
title: z.ZodString;
|
|
430
430
|
description: z.ZodOptional<z.ZodString>;
|
|
431
431
|
}, "strict", z.ZodTypeAny, {
|
|
432
|
-
id: string;
|
|
433
432
|
title: string;
|
|
433
|
+
id: string;
|
|
434
434
|
description?: string | undefined;
|
|
435
435
|
}, {
|
|
436
|
-
id: string;
|
|
437
436
|
title: string;
|
|
437
|
+
id: string;
|
|
438
438
|
description?: string | undefined;
|
|
439
439
|
}>, "many">>;
|
|
440
440
|
activationConditions: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -442,12 +442,12 @@ export declare const offerContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
442
442
|
title: z.ZodString;
|
|
443
443
|
description: z.ZodOptional<z.ZodString>;
|
|
444
444
|
}, "strict", z.ZodTypeAny, {
|
|
445
|
-
id: string;
|
|
446
445
|
title: string;
|
|
446
|
+
id: string;
|
|
447
447
|
description?: string | undefined;
|
|
448
448
|
}, {
|
|
449
|
-
id: string;
|
|
450
449
|
title: string;
|
|
450
|
+
id: string;
|
|
451
451
|
description?: string | undefined;
|
|
452
452
|
}>, "many">>;
|
|
453
453
|
claims: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -469,13 +469,13 @@ export declare const offerContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
469
469
|
value: z.ZodString;
|
|
470
470
|
details: z.ZodOptional<z.ZodString>;
|
|
471
471
|
}, "strict", z.ZodTypeAny, {
|
|
472
|
-
id: string;
|
|
473
472
|
value: string;
|
|
473
|
+
id: string;
|
|
474
474
|
label: string;
|
|
475
475
|
details?: string | undefined;
|
|
476
476
|
}, {
|
|
477
|
-
id: string;
|
|
478
477
|
value: string;
|
|
478
|
+
id: string;
|
|
479
479
|
label: string;
|
|
480
480
|
details?: string | undefined;
|
|
481
481
|
}>, "many">>;
|
|
@@ -506,25 +506,25 @@ export declare const offerContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
506
506
|
title: z.ZodString;
|
|
507
507
|
description: z.ZodOptional<z.ZodString>;
|
|
508
508
|
}, "strict", z.ZodTypeAny, {
|
|
509
|
-
id: string;
|
|
510
509
|
title: string;
|
|
510
|
+
id: string;
|
|
511
511
|
description?: string | undefined;
|
|
512
512
|
}, {
|
|
513
|
-
id: string;
|
|
514
513
|
title: string;
|
|
514
|
+
id: string;
|
|
515
515
|
description?: string | undefined;
|
|
516
516
|
}>, "many">>;
|
|
517
517
|
}, "strict", z.ZodTypeAny, {
|
|
518
518
|
description?: string | undefined;
|
|
519
519
|
promise?: string | undefined;
|
|
520
520
|
capabilities?: {
|
|
521
|
-
id: string;
|
|
522
521
|
title: string;
|
|
522
|
+
id: string;
|
|
523
523
|
description?: string | undefined;
|
|
524
524
|
}[] | undefined;
|
|
525
525
|
activationConditions?: {
|
|
526
|
-
id: string;
|
|
527
526
|
title: string;
|
|
527
|
+
id: string;
|
|
528
528
|
description?: string | undefined;
|
|
529
529
|
}[] | undefined;
|
|
530
530
|
claims?: {
|
|
@@ -533,8 +533,8 @@ export declare const offerContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
533
533
|
details?: string | undefined;
|
|
534
534
|
}[] | undefined;
|
|
535
535
|
demonstratedResults?: {
|
|
536
|
-
id: string;
|
|
537
536
|
value: string;
|
|
537
|
+
id: string;
|
|
538
538
|
label: string;
|
|
539
539
|
details?: string | undefined;
|
|
540
540
|
}[] | undefined;
|
|
@@ -547,21 +547,21 @@ export declare const offerContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
547
547
|
testimonial?: string | undefined;
|
|
548
548
|
}[] | undefined;
|
|
549
549
|
constraints?: {
|
|
550
|
-
id: string;
|
|
551
550
|
title: string;
|
|
551
|
+
id: string;
|
|
552
552
|
description?: string | undefined;
|
|
553
553
|
}[] | undefined;
|
|
554
554
|
}, {
|
|
555
555
|
description?: string | undefined;
|
|
556
556
|
promise?: string | undefined;
|
|
557
557
|
capabilities?: {
|
|
558
|
-
id: string;
|
|
559
558
|
title: string;
|
|
559
|
+
id: string;
|
|
560
560
|
description?: string | undefined;
|
|
561
561
|
}[] | undefined;
|
|
562
562
|
activationConditions?: {
|
|
563
|
-
id: string;
|
|
564
563
|
title: string;
|
|
564
|
+
id: string;
|
|
565
565
|
description?: string | undefined;
|
|
566
566
|
}[] | undefined;
|
|
567
567
|
claims?: {
|
|
@@ -570,8 +570,8 @@ export declare const offerContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
570
570
|
details?: string | undefined;
|
|
571
571
|
}[] | undefined;
|
|
572
572
|
demonstratedResults?: {
|
|
573
|
-
id: string;
|
|
574
573
|
value: string;
|
|
574
|
+
id: string;
|
|
575
575
|
label: string;
|
|
576
576
|
details?: string | undefined;
|
|
577
577
|
}[] | undefined;
|
|
@@ -584,21 +584,21 @@ export declare const offerContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
584
584
|
testimonial?: string | undefined;
|
|
585
585
|
}[] | undefined;
|
|
586
586
|
constraints?: {
|
|
587
|
-
id: string;
|
|
588
587
|
title: string;
|
|
588
|
+
id: string;
|
|
589
589
|
description?: string | undefined;
|
|
590
590
|
}[] | undefined;
|
|
591
591
|
}>, {
|
|
592
592
|
description?: string | undefined;
|
|
593
593
|
promise?: string | undefined;
|
|
594
594
|
capabilities?: {
|
|
595
|
-
id: string;
|
|
596
595
|
title: string;
|
|
596
|
+
id: string;
|
|
597
597
|
description?: string | undefined;
|
|
598
598
|
}[] | undefined;
|
|
599
599
|
activationConditions?: {
|
|
600
|
-
id: string;
|
|
601
600
|
title: string;
|
|
601
|
+
id: string;
|
|
602
602
|
description?: string | undefined;
|
|
603
603
|
}[] | undefined;
|
|
604
604
|
claims?: {
|
|
@@ -607,8 +607,8 @@ export declare const offerContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
607
607
|
details?: string | undefined;
|
|
608
608
|
}[] | undefined;
|
|
609
609
|
demonstratedResults?: {
|
|
610
|
-
id: string;
|
|
611
610
|
value: string;
|
|
611
|
+
id: string;
|
|
612
612
|
label: string;
|
|
613
613
|
details?: string | undefined;
|
|
614
614
|
}[] | undefined;
|
|
@@ -621,21 +621,21 @@ export declare const offerContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
621
621
|
testimonial?: string | undefined;
|
|
622
622
|
}[] | undefined;
|
|
623
623
|
constraints?: {
|
|
624
|
-
id: string;
|
|
625
624
|
title: string;
|
|
625
|
+
id: string;
|
|
626
626
|
description?: string | undefined;
|
|
627
627
|
}[] | undefined;
|
|
628
628
|
}, {
|
|
629
629
|
description?: string | undefined;
|
|
630
630
|
promise?: string | undefined;
|
|
631
631
|
capabilities?: {
|
|
632
|
-
id: string;
|
|
633
632
|
title: string;
|
|
633
|
+
id: string;
|
|
634
634
|
description?: string | undefined;
|
|
635
635
|
}[] | undefined;
|
|
636
636
|
activationConditions?: {
|
|
637
|
-
id: string;
|
|
638
637
|
title: string;
|
|
638
|
+
id: string;
|
|
639
639
|
description?: string | undefined;
|
|
640
640
|
}[] | undefined;
|
|
641
641
|
claims?: {
|
|
@@ -644,8 +644,8 @@ export declare const offerContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
644
644
|
details?: string | undefined;
|
|
645
645
|
}[] | undefined;
|
|
646
646
|
demonstratedResults?: {
|
|
647
|
-
id: string;
|
|
648
647
|
value: string;
|
|
648
|
+
id: string;
|
|
649
649
|
label: string;
|
|
650
650
|
details?: string | undefined;
|
|
651
651
|
}[] | undefined;
|
|
@@ -658,8 +658,8 @@ export declare const offerContextContentSchema: z.ZodEffects<z.ZodObject<{
|
|
|
658
658
|
testimonial?: string | undefined;
|
|
659
659
|
}[] | undefined;
|
|
660
660
|
constraints?: {
|
|
661
|
-
id: string;
|
|
662
661
|
title: string;
|
|
662
|
+
id: string;
|
|
663
663
|
description?: string | undefined;
|
|
664
664
|
}[] | undefined;
|
|
665
665
|
}>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { type LeadifyClient } from "../client.js";
|
|
2
3
|
export declare function assertLeadGroupsBelongToOrganization(data: unknown, organizationId: string): Array<Record<string, unknown>>;
|
|
3
4
|
/** Keep group reads navigable: never return schema, profiles, or lead data. */
|
|
4
5
|
export declare function compactLeadGroup(group: unknown): Record<string, unknown>;
|
|
5
|
-
export declare function registerOrganizationTools(server: McpServer): void;
|
|
6
|
+
export declare function registerOrganizationTools(server: McpServer, client?: Pick<LeadifyClient, "get" | "post">): void;
|
|
@@ -44,14 +44,26 @@ export function compactLeadGroup(group) {
|
|
|
44
44
|
createdAt: source.createdAt ?? null,
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
|
-
export function registerOrganizationTools(server) {
|
|
47
|
+
export function registerOrganizationTools(server, client = getClient()) {
|
|
48
|
+
server.tool("create_organization", "Create an organization through Leadify using an explicitly authorized API key. The caller becomes its " +
|
|
49
|
+
"administrator. Repeating the same normalized domain returns the existing organization with created=false. " +
|
|
50
|
+
"The server grants this key access to the new organization without removing its existing bindings. " +
|
|
51
|
+
"This does not create a Context Workspace or start qualification. Manage key permissions in Leadify settings.", { name: z.string().trim().min(1).max(200), domain: z.string().trim().min(1),
|
|
52
|
+
external_ref: z.string().trim().min(1).max(200).optional() }, async ({ name, domain, external_ref }) => {
|
|
53
|
+
try {
|
|
54
|
+
return toolResult(await client.post("/api/organizations", { name, domain, externalRef: external_ref }));
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
return handleToolError(error);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
48
60
|
// ── list_organizations ─────────────────────────────────────────────────
|
|
49
61
|
server.tool("list_organizations", "List every organization accessible to the caller, returning each with id, name, and " +
|
|
50
62
|
"optional slug. Use this as the starting point when you need an organization_id — " +
|
|
51
63
|
"e.g. before create_lead_group, clone_lead_group, create_persona_contract (org-scoped), " +
|
|
52
|
-
"or move_persona.", {}, async () => {
|
|
64
|
+
"or move_persona.", { domain: z.string().trim().min(1).optional().describe("Optional exact domain lookup; never creates an organization.") }, async ({ domain }) => {
|
|
53
65
|
try {
|
|
54
|
-
const data = await
|
|
66
|
+
const data = await client.get("/api/organizations", domain ? new URLSearchParams({ domain }) : undefined);
|
|
55
67
|
return toolResult(data);
|
|
56
68
|
}
|
|
57
69
|
catch (error) {
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getClient } from "../client.js";
|
|
3
|
+
import { toolResult, handleToolError } from "../types.js";
|
|
4
|
+
// PRD-2404 — vraies exclusions de prospection, branchées sur /api/outreach
|
|
5
|
+
// (PRD-2337) : mêmes commandes que les boutons de l'interface Leadify.
|
|
6
|
+
const NEVER_IN_TEXT = "Never write an exclusion as text (Context Workspace, company brain, notes, persona) and never write excluded, " +
|
|
7
|
+
"hide_from_campaign or outreach_status on a lead: text excludes nothing and Leadify refuses those fields (409 PROTECTED_OUTREACH_FIELD).";
|
|
8
|
+
const id = z.string().trim().min(1).max(200);
|
|
9
|
+
const writeShape = {
|
|
10
|
+
organization_id: id.describe("Organization that owns the lead. Must be in the API key's scope."),
|
|
11
|
+
idempotency_key: z.string().trim().min(8).max(200).optional().describe("Stable key for this decision. Retrying with the same key replays the first result; reusing it for another lead or reason returns 409 OUTREACH_IDEMPOTENCY_KEY_REUSED."),
|
|
12
|
+
expected_version: z.number().int().min(0).optional().describe("state.version read with get_outreach_state. If the state changed meanwhile, the server refuses with 409 OUTREACH_VERSION_CONFLICT: re-read, then decide again."),
|
|
13
|
+
};
|
|
14
|
+
const reason = z.string().trim().min(3).max(2000);
|
|
15
|
+
export function registerOutreachExclusionTools(server, client = getClient()) {
|
|
16
|
+
server.tool("exclude_account", "Exclude a company (a hospital, clinic or other establishment) from all prospecting: sets the protected cause " +
|
|
17
|
+
"ACCOUNT_EXCLUDED on the company lead, and every person linked to it is excluded too (now and when linked later) and " +
|
|
18
|
+
"their running campaigns stop. Use it for existing customers, competitors or accounts the client must not contact. " +
|
|
19
|
+
"reason and source_url (the public page proving it) are required. Leadify has no department level: the response " +
|
|
20
|
+
"always says level=\"establishment\", with levelNote when service was given. Idempotent. An agent cannot lift this " +
|
|
21
|
+
"exclusion; only a human in Leadify can. " + NEVER_IN_TEXT, {
|
|
22
|
+
...writeShape,
|
|
23
|
+
company_lead_id: id.describe("Lead id of the company (COMPANY group)."),
|
|
24
|
+
reason: reason.describe("Why the account is excluded, e.g. 'Déjà client RDS Diag'."),
|
|
25
|
+
source_url: z.string().trim().url().max(2000).refine(value => /^https?:\/\//i.test(value), "http(s) URL required")
|
|
26
|
+
.describe("Public http(s) page proving the reason."),
|
|
27
|
+
service: z.string().trim().min(1).max(200).optional().describe("Department targeted, if any. Recorded in the note; the exclusion still covers the whole establishment."),
|
|
28
|
+
}, async ({ organization_id, company_lead_id, reason, source_url, service, idempotency_key, expected_version }) => {
|
|
29
|
+
try {
|
|
30
|
+
return toolResult(await client.post("/api/outreach/accounts/exclude", {
|
|
31
|
+
organizationId: organization_id, companyLeadId: company_lead_id, reason, sourceUrl: source_url, service,
|
|
32
|
+
idempotencyKey: idempotency_key, expectedVersion: expected_version, origin: "AGENT",
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
return handleToolError(error);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
server.tool("exclude_lead", "Exclude one person from prospecting: no message is drafted, enrolled or sent, and their running campaigns stop. " +
|
|
40
|
+
"Same command as the Exclude button in Leadify; the history shows the API key owner as author. caused_by is MANUAL " +
|
|
41
|
+
"(default) or TARGET_NOT_FIT (out of target). For a company use exclude_account instead (this tool refuses company leads " +
|
|
42
|
+
"with 409 OUTREACH_COMPANY_USE_ACCOUNT_ROUTE). Returns the re-read state. " + NEVER_IN_TEXT, {
|
|
43
|
+
...writeShape,
|
|
44
|
+
lead_id: id.describe("Lead id of the person."),
|
|
45
|
+
caused_by: z.enum(["MANUAL", "TARGET_NOT_FIT"]).default("MANUAL"),
|
|
46
|
+
reason: reason.describe("Why the person is excluded; shown in the Leadify history."),
|
|
47
|
+
}, async ({ organization_id, lead_id, caused_by, reason, idempotency_key, expected_version }) => {
|
|
48
|
+
try {
|
|
49
|
+
return toolResult(await client.post("/api/outreach/leads/exclude", {
|
|
50
|
+
organizationId: organization_id, leadId: lead_id, causedBy: caused_by, reason,
|
|
51
|
+
idempotencyKey: idempotency_key, expectedVersion: expected_version, origin: "AGENT",
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
return handleToolError(error);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
server.tool("reintegrate_lead", "Allow again a person excluded by hand (MANUAL, out of target, or a migrated historical flag). A justification is " +
|
|
59
|
+
"required. It never lifts an opt-out, a deliverability protection or a company exclusion: if one remains, state.status " +
|
|
60
|
+
"stays \"excluded\" and state.causes says why. No campaign is restarted. Returns the re-read state.", {
|
|
61
|
+
...writeShape,
|
|
62
|
+
lead_id: id.describe("Lead id of the person."),
|
|
63
|
+
reason: reason.describe("Why the person may be contacted again; shown in the Leadify history."),
|
|
64
|
+
}, async ({ organization_id, lead_id, reason, idempotency_key, expected_version }) => {
|
|
65
|
+
try {
|
|
66
|
+
return toolResult(await client.post("/api/outreach/leads/reintegrate", {
|
|
67
|
+
organizationId: organization_id, leadId: lead_id, reason,
|
|
68
|
+
idempotencyKey: idempotency_key, expectedVersion: expected_version, origin: "AGENT",
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
return handleToolError(error);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
server.tool("get_outreach_state", "Read the prospecting state of 1 to 100 leads (people or companies): status allowed or excluded, active causes with " +
|
|
76
|
+
"their origin and note, version (pass it as expected_version to a write), lastTransitionAt and accountSources " +
|
|
77
|
+
"(companies whose exclusion the person inherits). Leads absent from the organization are listed in missingLeadIds. " +
|
|
78
|
+
"Read this before deciding, instead of looking for exclusions in text.", {
|
|
79
|
+
organization_id: id,
|
|
80
|
+
lead_ids: z.array(id).min(1).max(100),
|
|
81
|
+
}, { readOnlyHint: true }, async ({ organization_id, lead_ids }) => {
|
|
82
|
+
try {
|
|
83
|
+
return toolResult(await client.post("/api/outreach/state", { organizationId: organization_id, leadIds: lead_ids }));
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
return handleToolError(error);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getClient } from "../client.js";
|
|
3
|
+
import { toolResult, handleToolError } from "../types.js";
|
|
4
|
+
export function registerQualificationRunTools(server, client = getClient()) {
|
|
5
|
+
server.tool("start_qualification_run", "Validate or start qualification of an explicit list of 1 to 20 companies in one organization and group, " +
|
|
6
|
+
"then their linked people. dry_run defaults to true: read preflight.snapshot.expectedSchemaHash, then " +
|
|
7
|
+
"send it as expected_schema_hash with dry_run=false and the same request_id to launch. " +
|
|
8
|
+
"The server refuses companies without a verified employee and more than two distinct pilot companies " +
|
|
9
|
+
"until a human approves the pilot for this group in Leadify. No outreach or campaign activation. " +
|
|
10
|
+
"Keep request_id unchanged when retrying the same selection. Read the returned runId with get_qualification_run.", { organization_id: z.string().trim().min(1), lead_group_id: z.string().trim().min(1),
|
|
11
|
+
company_lead_ids: z.array(z.string().trim().min(1)).min(1).max(20).refine(ids => new Set(ids).size === ids.length),
|
|
12
|
+
request_id: z.string().uuid(), dry_run: z.boolean().default(true),
|
|
13
|
+
expected_schema_hash: z.string().regex(/^[a-f0-9]{64}$/).optional() }, async ({ organization_id, lead_group_id, company_lead_ids, request_id, dry_run, expected_schema_hash }) => {
|
|
14
|
+
try {
|
|
15
|
+
return toolResult(await client.post("/api/qualification-runs", { organizationId: organization_id,
|
|
16
|
+
leadGroupId: lead_group_id, companyLeadIds: company_lead_ids, requestId: request_id,
|
|
17
|
+
dryRun: dry_run, expectedSchemaHash: expected_schema_hash }));
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return handleToolError(error);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
server.tool("get_qualification_run", "Read a qualification batch returned by start_qualification_run in an explicitly selected organization. " +
|
|
24
|
+
"Returns each company's run status, dated observation, output and qualified people; failures are retained. " +
|
|
25
|
+
"Never infer a completed qualification from a launch acknowledgment.", { organization_id: z.string().trim().min(1), run_id: z.string().trim().min(1) }, async ({ organization_id, run_id }) => {
|
|
26
|
+
try {
|
|
27
|
+
return toolResult(await client.get(`/api/qualification-runs/${encodeURIComponent(run_id)}`, new URLSearchParams({ organizationId: organization_id })));
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
return handleToolError(error);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|