@connect-xlab/mcp-server 0.2.0 → 0.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.
Files changed (55) hide show
  1. package/dist/index.js +97 -0
  2. package/dist/tools/approveAssistantAction.js +40 -0
  3. package/dist/tools/correctAssistantAction.js +36 -0
  4. package/dist/tools/createCompany.js +2 -0
  5. package/dist/tools/createDmSequence.js +36 -0
  6. package/dist/tools/createLinkInBioBlock.js +27 -18
  7. package/dist/tools/createQuiz.js +38 -0
  8. package/dist/tools/createQuizAnswer.js +42 -0
  9. package/dist/tools/createQuizItem.js +46 -0
  10. package/dist/tools/createQuizProfile.js +50 -0
  11. package/dist/tools/createShopProduct.js +7 -5
  12. package/dist/tools/deleteQuiz.js +33 -0
  13. package/dist/tools/deleteQuizAnswer.js +37 -0
  14. package/dist/tools/deleteQuizItem.js +35 -0
  15. package/dist/tools/deleteQuizProfile.js +35 -0
  16. package/dist/tools/getAssistantAction.js +33 -0
  17. package/dist/tools/getAssistantProducts.js +31 -0
  18. package/dist/tools/getAssistantSettings.js +31 -0
  19. package/dist/tools/getAssistantSummary.js +36 -0
  20. package/dist/tools/getDmSequence.js +33 -0
  21. package/dist/tools/getDmSequenceSettings.js +31 -0
  22. package/dist/tools/getDmSequenceStats.js +38 -0
  23. package/dist/tools/getLinkInBioCatalog.js +31 -0
  24. package/dist/tools/getQuiz.js +33 -0
  25. package/dist/tools/getQuizLead.js +35 -0
  26. package/dist/tools/getQuizSettings.js +31 -0
  27. package/dist/tools/getQuizStats.js +33 -0
  28. package/dist/tools/listAssistantActions.js +40 -0
  29. package/dist/tools/listDmEnrollments.js +40 -0
  30. package/dist/tools/listDmSequenceTargetPosts.js +31 -0
  31. package/dist/tools/listDmSequences.js +31 -0
  32. package/dist/tools/listQuizLeads.js +48 -0
  33. package/dist/tools/listQuizTemplates.js +31 -0
  34. package/dist/tools/listQuizzes.js +31 -0
  35. package/dist/tools/manageDmEnrollment.js +36 -0
  36. package/dist/tools/previewDmSequence.js +40 -0
  37. package/dist/tools/rejectAssistantAction.js +33 -0
  38. package/dist/tools/reorderQuizItems.js +36 -0
  39. package/dist/tools/requestAssistantPostDraft.js +38 -0
  40. package/dist/tools/setDmSequenceStatus.js +36 -0
  41. package/dist/tools/setQuizPublished.js +35 -0
  42. package/dist/tools/toggleCompanyVisibility.js +35 -0
  43. package/dist/tools/updateAssistantProducts.js +34 -0
  44. package/dist/tools/updateAssistantSettings.js +90 -0
  45. package/dist/tools/updateCompany.js +2 -0
  46. package/dist/tools/updateDmSequence.js +44 -0
  47. package/dist/tools/updateDmSequenceSettings.js +44 -0
  48. package/dist/tools/updateLinkInBioBlock.js +13 -8
  49. package/dist/tools/updateQuiz.js +56 -0
  50. package/dist/tools/updateQuizAnswer.js +44 -0
  51. package/dist/tools/updateQuizItem.js +46 -0
  52. package/dist/tools/updateQuizProfile.js +52 -0
  53. package/dist/tools/updateQuizSettings.js +34 -0
  54. package/dist/tools/updateShopProduct.js +7 -5
  55. package/package.json +1 -1
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Tool `delete_quiz_item` — supprime une question / page.
3
+ * Scope : quiz.write.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const deleteQuizItemTool = {
8
+ name: 'delete_quiz_item',
9
+ description: "Supprime une question (et ses reponses) ou une page intermediaire.",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ quiz_id: { type: 'number', minimum: 1, description: 'id du quiz (list_quizzes)' },
15
+ item_id: { type: 'number', minimum: 1, description: 'id de la question / page (get_quiz)' },
16
+ },
17
+ required: ['lab', 'quiz_id', 'item_id'],
18
+ additionalProperties: false,
19
+ },
20
+ zodSchema: z.object({
21
+ lab: z.string(),
22
+ quiz_id: z.number().int().positive(),
23
+ item_id: z.number().int().positive(),
24
+ }),
25
+ async handler(args) {
26
+ const p = this.zodSchema.parse(args);
27
+ try {
28
+ const { data } = await http.delete(`/mcp/labs/${encodeURIComponent(p.lab)}/quiz/quizzes/${p.quiz_id}/items/${p.item_id}`);
29
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
30
+ }
31
+ catch (err) {
32
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
33
+ }
34
+ },
35
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Tool `delete_quiz_profile` — supprime un profil de resultat.
3
+ * Scope : quiz.write.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const deleteQuizProfileTool = {
8
+ name: 'delete_quiz_profile',
9
+ description: "Supprime un profil de resultat.",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ quiz_id: { type: 'number', minimum: 1, description: 'id du quiz (list_quizzes)' },
15
+ profile_id: { type: 'number', minimum: 1, description: 'id du profil de resultat (get_quiz)' },
16
+ },
17
+ required: ['lab', 'quiz_id', 'profile_id'],
18
+ additionalProperties: false,
19
+ },
20
+ zodSchema: z.object({
21
+ lab: z.string(),
22
+ quiz_id: z.number().int().positive(),
23
+ profile_id: z.number().int().positive(),
24
+ }),
25
+ async handler(args) {
26
+ const p = this.zodSchema.parse(args);
27
+ try {
28
+ const { data } = await http.delete(`/mcp/labs/${encodeURIComponent(p.lab)}/quiz/quizzes/${p.quiz_id}/profiles/${p.profile_id}`);
29
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
30
+ }
31
+ catch (err) {
32
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
33
+ }
34
+ },
35
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Tool `get_assistant_action` — detail d'une proposition de Lou.
3
+ * Scope : assistant.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const getAssistantActionTool = {
8
+ name: 'get_assistant_action',
9
+ description: "Detail d'une proposition de Lou : contenu propose (payload), contexte, membre concerne, statut.",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ uuid: { type: 'string', description: 'uuid de la proposition (list_assistant_actions)' },
15
+ },
16
+ required: ['lab', 'uuid'],
17
+ additionalProperties: false,
18
+ },
19
+ zodSchema: z.object({
20
+ lab: z.string(),
21
+ uuid: z.string(),
22
+ }),
23
+ async handler(args) {
24
+ const p = this.zodSchema.parse(args);
25
+ try {
26
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/assistant/actions/${encodeURIComponent(p.uuid)}`);
27
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
28
+ }
29
+ catch (err) {
30
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
31
+ }
32
+ },
33
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Tool `get_assistant_products` — produits que Lou peut recommander.
3
+ * Scope : assistant.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const getAssistantProductsTool = {
8
+ name: 'get_assistant_products',
9
+ description: "Liste les produits de la boutique que Lou peut recommander aux membres : group_shop_id, title, price, enabled, pitch_notes (arguments), ideal_for (a qui le proposer).",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ },
15
+ required: ['lab'],
16
+ additionalProperties: false,
17
+ },
18
+ zodSchema: z.object({
19
+ lab: z.string(),
20
+ }),
21
+ async handler(args) {
22
+ const p = this.zodSchema.parse(args);
23
+ try {
24
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/assistant/products`);
25
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
26
+ }
27
+ catch (err) {
28
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
29
+ }
30
+ },
31
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Tool `get_assistant_settings` — reglages de Lou.
3
+ * Scope : assistant.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const getAssistantSettingsTool = {
8
+ name: 'get_assistant_settings',
9
+ description: "Reglages de Lou, l'assistant IA du Lab (ton, langue, capacites autorisees et leur mode), entitled (abonnement XLab Agent actif), pending_count (propositions en attente) et categories du Lab (pour les posts).",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ },
15
+ required: ['lab'],
16
+ additionalProperties: false,
17
+ },
18
+ zodSchema: z.object({
19
+ lab: z.string(),
20
+ }),
21
+ async handler(args) {
22
+ const p = this.zodSchema.parse(args);
23
+ try {
24
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/assistant/settings`);
25
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
26
+ }
27
+ catch (err) {
28
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
29
+ }
30
+ },
31
+ };
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Tool `get_assistant_summary` — resume de l'activite de Lou.
3
+ * Scope : assistant.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const getAssistantSummaryTool = {
8
+ name: 'get_assistant_summary',
9
+ description: "Resume de l'activite de Lou sur une periode (from / to, YYYY-MM-DD) : propositions, validations, envois automatiques, ventes generees.",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ from: { type: 'string', description: 'YYYY-MM-DD' },
15
+ to: { type: 'string', description: 'YYYY-MM-DD' },
16
+ },
17
+ required: ['lab'],
18
+ additionalProperties: false,
19
+ },
20
+ zodSchema: z.object({
21
+ lab: z.string(),
22
+ from: z.string().nullable().optional(),
23
+ to: z.string().nullable().optional(),
24
+ }),
25
+ async handler(args) {
26
+ const p = this.zodSchema.parse(args);
27
+ const { from, to } = p;
28
+ try {
29
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/assistant/summary`, { params: { from, to } });
30
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
31
+ }
32
+ catch (err) {
33
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
34
+ }
35
+ },
36
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Tool `get_dm_sequence` — detail d'une sequence DM.
3
+ * Scope : dm_sequences.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const getDmSequenceTool = {
8
+ name: 'get_dm_sequence',
9
+ description: "Detail d'une sequence DM : version en ligne (live_version) et brouillon (draft) avec trigger, goal, config, steps et revision.",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ sequence_id: { type: 'number', minimum: 1, description: 'id de la sequence (list_dm_sequences)' },
15
+ },
16
+ required: ['lab', 'sequence_id'],
17
+ additionalProperties: false,
18
+ },
19
+ zodSchema: z.object({
20
+ lab: z.string(),
21
+ sequence_id: z.number().int().positive(),
22
+ }),
23
+ async handler(args) {
24
+ const p = this.zodSchema.parse(args);
25
+ try {
26
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/dm-sequences/sequences/${p.sequence_id}`);
27
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
28
+ }
29
+ catch (err) {
30
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
31
+ }
32
+ },
33
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Tool `get_dm_sequence_settings` — reglages du plug-in Sequences DM.
3
+ * Scope : dm_sequences.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const getDmSequenceSettingsTool = {
8
+ name: 'get_dm_sequence_settings',
9
+ description: "Reglages du plug-in Sequences DM : enabled, timezone, fenetre d'envoi (window_start / window_end HH:MM), member_daily_cap (DM max par membre et par jour), revision. auto_dm_active indique si l'ancien \"Auto DM\" de bienvenue est actif en parallele.",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ },
15
+ required: ['lab'],
16
+ additionalProperties: false,
17
+ },
18
+ zodSchema: z.object({
19
+ lab: z.string(),
20
+ }),
21
+ async handler(args) {
22
+ const p = this.zodSchema.parse(args);
23
+ try {
24
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/dm-sequences/settings`);
25
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
26
+ }
27
+ catch (err) {
28
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
29
+ }
30
+ },
31
+ };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Tool `get_dm_sequence_stats` — statistiques d'une sequence DM.
3
+ * Scope : dm_sequences.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const getDmSequenceStatsTool = {
8
+ name: 'get_dm_sequence_stats',
9
+ description: "Statistiques d'une sequence DM (inscrits, envois, reponses, objectifs atteints) sur une periode optionnelle from / to (YYYY-MM-DD).",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ sequence_id: { type: 'number', minimum: 1, description: 'id de la sequence (list_dm_sequences)' },
15
+ from: { type: 'string', description: 'YYYY-MM-DD' },
16
+ to: { type: 'string', description: 'YYYY-MM-DD' },
17
+ },
18
+ required: ['lab', 'sequence_id'],
19
+ additionalProperties: false,
20
+ },
21
+ zodSchema: z.object({
22
+ lab: z.string(),
23
+ sequence_id: z.number().int().positive(),
24
+ from: z.string().nullable().optional(),
25
+ to: z.string().nullable().optional(),
26
+ }),
27
+ async handler(args) {
28
+ const p = this.zodSchema.parse(args);
29
+ const { from, to } = p;
30
+ try {
31
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/dm-sequences/sequences/${p.sequence_id}/stats`, { params: { from, to } });
32
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
33
+ }
34
+ catch (err) {
35
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
36
+ }
37
+ },
38
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Tool `get_link_in_bio_catalog` — catalogue des ids utilisables dans les blocs Link in Bio.
3
+ * Scope : link_in_bio.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const getLinkInBioCatalogTool = {
8
+ name: 'get_link_in_bio_catalog',
9
+ description: "Liste les ids utilisables dans les blocs Link in Bio : products (type + id pour kind=product), labs (id pour kind=lab = autres Labs de l'owner), quizzes (id + published pour kind=quiz) et quiz_plugin_enabled. Un bloc quiz n'apparait sur la page publique que si le quiz est publie ET le plug-in Quiz active.",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ },
15
+ required: ['lab'],
16
+ additionalProperties: false,
17
+ },
18
+ zodSchema: z.object({
19
+ lab: z.string(),
20
+ }),
21
+ async handler(args) {
22
+ const p = this.zodSchema.parse(args);
23
+ try {
24
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/link-in-bio/catalog`);
25
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
26
+ }
27
+ catch (err) {
28
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
29
+ }
30
+ },
31
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Tool `get_quiz` — detail complet d'un quiz.
3
+ * Scope : quiz.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const getQuizTool = {
8
+ name: 'get_quiz',
9
+ description: "Detail complet d'un quiz : items (questions / pages intermediaires) avec leurs reponses (points, profile_id), profils de resultat, integrations (secrets masques).",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ quiz_id: { type: 'number', minimum: 1, description: 'id du quiz (list_quizzes)' },
15
+ },
16
+ required: ['lab', 'quiz_id'],
17
+ additionalProperties: false,
18
+ },
19
+ zodSchema: z.object({
20
+ lab: z.string(),
21
+ quiz_id: z.number().int().positive(),
22
+ }),
23
+ async handler(args) {
24
+ const p = this.zodSchema.parse(args);
25
+ try {
26
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/quiz/quizzes/${p.quiz_id}`);
27
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
28
+ }
29
+ catch (err) {
30
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
31
+ }
32
+ },
33
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Tool `get_quiz_lead` — detail d'un prospect.
3
+ * Scope : quiz.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const getQuizLeadTool = {
8
+ name: 'get_quiz_lead',
9
+ description: "Detail d'un prospect capture par un quiz (reponses, score, profil).",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ quiz_id: { type: 'number', minimum: 1, description: 'id du quiz (list_quizzes)' },
15
+ lead_id: { type: 'number', minimum: 1, description: 'id du prospect (list_quiz_leads)' },
16
+ },
17
+ required: ['lab', 'quiz_id', 'lead_id'],
18
+ additionalProperties: false,
19
+ },
20
+ zodSchema: z.object({
21
+ lab: z.string(),
22
+ quiz_id: z.number().int().positive(),
23
+ lead_id: z.number().int().positive(),
24
+ }),
25
+ async handler(args) {
26
+ const p = this.zodSchema.parse(args);
27
+ try {
28
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/quiz/quizzes/${p.quiz_id}/leads/${p.lead_id}`);
29
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
30
+ }
31
+ catch (err) {
32
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
33
+ }
34
+ },
35
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Tool `get_quiz_settings` — etat du plug-in Quiz du Lab.
3
+ * Scope : quiz.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const getQuizSettingsTool = {
8
+ name: 'get_quiz_settings',
9
+ description: "Etat du plug-in Quiz pour le Lab (enabled). Un quiz n'est joignable publiquement que si le plug-in est active ET le quiz publie.",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ },
15
+ required: ['lab'],
16
+ additionalProperties: false,
17
+ },
18
+ zodSchema: z.object({
19
+ lab: z.string(),
20
+ }),
21
+ async handler(args) {
22
+ const p = this.zodSchema.parse(args);
23
+ try {
24
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/quiz/settings`);
25
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
26
+ }
27
+ catch (err) {
28
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
29
+ }
30
+ },
31
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Tool `get_quiz_stats` — statistiques d'un quiz.
3
+ * Scope : quiz.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const getQuizStatsTool = {
8
+ name: 'get_quiz_stats',
9
+ description: "Statistiques d'un quiz : vues, demarrages, completions, prospects captures, abandon par question, repartition par profil.",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ quiz_id: { type: 'number', minimum: 1, description: 'id du quiz (list_quizzes)' },
15
+ },
16
+ required: ['lab', 'quiz_id'],
17
+ additionalProperties: false,
18
+ },
19
+ zodSchema: z.object({
20
+ lab: z.string(),
21
+ quiz_id: z.number().int().positive(),
22
+ }),
23
+ async handler(args) {
24
+ const p = this.zodSchema.parse(args);
25
+ try {
26
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/quiz/quizzes/${p.quiz_id}/stats`);
27
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
28
+ }
29
+ catch (err) {
30
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
31
+ }
32
+ },
33
+ };
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Tool `list_assistant_actions` — propositions de Lou.
3
+ * Scope : assistant.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const listAssistantActionsTool = {
8
+ name: 'list_assistant_actions',
9
+ description: "Liste paginee des propositions de Lou (reponses a des commentaires / DM, brouillons de posts, DM de vente...). Filtre status=proposed pour celles qui attendent une validation.",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ status: { type: 'string', enum: ['proposed', 'executed', 'rejected', 'expired', 'failed', 'scheduled'] },
15
+ type: { type: 'string', enum: ['comment_reply', 'post_draft', 'sales_dm', 'dm_reply', 'course_question', 'sales_question', 'sequence_reply', 'comment_sales_pitch', 'course_sales_pitch', 'milestone_offer', 'product_suggestion'] },
16
+ per_page: { type: 'number', minimum: 1, maximum: 50 },
17
+ page: { type: 'number', minimum: 1, description: 'page (pagination)' },
18
+ },
19
+ required: ['lab'],
20
+ additionalProperties: false,
21
+ },
22
+ zodSchema: z.object({
23
+ lab: z.string(),
24
+ status: z.enum(['proposed', 'executed', 'rejected', 'expired', 'failed', 'scheduled']).optional(),
25
+ type: z.enum(['comment_reply', 'post_draft', 'sales_dm', 'dm_reply', 'course_question', 'sales_question', 'sequence_reply', 'comment_sales_pitch', 'course_sales_pitch', 'milestone_offer', 'product_suggestion']).optional(),
26
+ per_page: z.number().int().min(1).max(50).optional(),
27
+ page: z.number().int().min(1).optional(),
28
+ }),
29
+ async handler(args) {
30
+ const p = this.zodSchema.parse(args);
31
+ const { status, type, per_page, page } = p;
32
+ try {
33
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/assistant/actions`, { params: { status, type, per_page, page } });
34
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
35
+ }
36
+ catch (err) {
37
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
38
+ }
39
+ },
40
+ };
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Tool `list_dm_enrollments` — membres inscrits dans les sequences DM.
3
+ * Scope : dm_sequences.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const listDmEnrollmentsTool = {
8
+ name: 'list_dm_enrollments',
9
+ description: "Liste paginee des membres inscrits dans une sequence (state : scheduled, running, paused_reply, paused_owner, paused_admin, completed_goal, completed_steps, cancelled, expired, failed).",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ sequence_id: { type: 'number', minimum: 1 },
15
+ state: { type: 'string', enum: ['scheduled', 'running', 'paused_reply', 'paused_owner', 'paused_admin', 'completed_goal', 'completed_steps', 'cancelled', 'expired', 'failed'] },
16
+ per_page: { type: 'number', minimum: 1, maximum: 50 },
17
+ page: { type: 'number', minimum: 1, description: 'page (pagination)' },
18
+ },
19
+ required: ['lab'],
20
+ additionalProperties: false,
21
+ },
22
+ zodSchema: z.object({
23
+ lab: z.string(),
24
+ sequence_id: z.number().int().min(1).optional(),
25
+ state: z.enum(['scheduled', 'running', 'paused_reply', 'paused_owner', 'paused_admin', 'completed_goal', 'completed_steps', 'cancelled', 'expired', 'failed']).optional(),
26
+ per_page: z.number().int().min(1).max(50).optional(),
27
+ page: z.number().int().min(1).optional(),
28
+ }),
29
+ async handler(args) {
30
+ const p = this.zodSchema.parse(args);
31
+ const { sequence_id, state, per_page, page } = p;
32
+ try {
33
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/dm-sequences/enrollments`, { params: { sequence_id, state, per_page, page } });
34
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
35
+ }
36
+ catch (err) {
37
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
38
+ }
39
+ },
40
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Tool `list_dm_sequence_target_posts` — publications utilisables comme declencheur.
3
+ * Scope : dm_sequences.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const listDmSequenceTargetPostsTool = {
8
+ name: 'list_dm_sequence_target_posts',
9
+ description: "Liste les 100 dernieres publications du Lab (id numerique, titre) utilisables dans trigger.post_ids d'une sequence de type keyword.",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ },
15
+ required: ['lab'],
16
+ additionalProperties: false,
17
+ },
18
+ zodSchema: z.object({
19
+ lab: z.string(),
20
+ }),
21
+ async handler(args) {
22
+ const p = this.zodSchema.parse(args);
23
+ try {
24
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/dm-sequences/target-posts`);
25
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
26
+ }
27
+ catch (err) {
28
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
29
+ }
30
+ },
31
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Tool `list_dm_sequences` — sequences DM du Lab.
3
+ * Scope : dm_sequences.read.
4
+ */
5
+ import { z } from 'zod';
6
+ import { http, formatApiError } from '../http.js';
7
+ export const listDmSequencesTool = {
8
+ name: 'list_dm_sequences',
9
+ description: "Liste les sequences DM du Lab : id, name, template (welcome / keyword), status (draft / active / paused / archived), version en ligne.",
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ lab: { type: 'string', description: 'group_url ou id du Lab' },
14
+ },
15
+ required: ['lab'],
16
+ additionalProperties: false,
17
+ },
18
+ zodSchema: z.object({
19
+ lab: z.string(),
20
+ }),
21
+ async handler(args) {
22
+ const p = this.zodSchema.parse(args);
23
+ try {
24
+ const { data } = await http.get(`/mcp/labs/${encodeURIComponent(p.lab)}/dm-sequences/sequences`);
25
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
26
+ }
27
+ catch (err) {
28
+ return { isError: true, content: [{ type: 'text', text: formatApiError(err) }] };
29
+ }
30
+ },
31
+ };