@migma/mcp 1.9.1-automations.1 → 1.10.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.
Files changed (86) hide show
  1. package/README.md +25 -26
  2. package/build/index.d.ts.map +1 -1
  3. package/build/index.js +5 -11
  4. package/build/index.js.map +1 -1
  5. package/build/prompts/index.d.ts +0 -1
  6. package/build/prompts/index.d.ts.map +1 -1
  7. package/build/prompts/index.js +5 -20
  8. package/build/prompts/index.js.map +1 -1
  9. package/build/tools/__tests__/brand.test.js +25 -0
  10. package/build/tools/__tests__/brand.test.js.map +1 -1
  11. package/build/tools/__tests__/campaign-recipients.test.js +5 -2
  12. package/build/tools/__tests__/campaign-recipients.test.js.map +1 -1
  13. package/build/tools/__tests__/campaign-schedule.test.d.ts +2 -0
  14. package/build/tools/__tests__/campaign-schedule.test.d.ts.map +1 -0
  15. package/build/tools/__tests__/campaign-schedule.test.js +32 -0
  16. package/build/tools/__tests__/campaign-schedule.test.js.map +1 -0
  17. package/build/tools/__tests__/catalog.test.js +27 -21
  18. package/build/tools/__tests__/catalog.test.js.map +1 -1
  19. package/build/tools/__tests__/provider-imports.test.js +23 -0
  20. package/build/tools/__tests__/provider-imports.test.js.map +1 -1
  21. package/build/tools/__tests__/review-annotations.test.js +7 -13
  22. package/build/tools/__tests__/review-annotations.test.js.map +1 -1
  23. package/build/tools/__tests__/send-approval.test.d.ts +2 -0
  24. package/build/tools/__tests__/send-approval.test.d.ts.map +1 -0
  25. package/build/tools/__tests__/send-approval.test.js +71 -0
  26. package/build/tools/__tests__/send-approval.test.js.map +1 -0
  27. package/build/tools/api-request.d.ts +11 -0
  28. package/build/tools/api-request.d.ts.map +1 -0
  29. package/build/tools/api-request.js +35 -0
  30. package/build/tools/api-request.js.map +1 -0
  31. package/build/tools/brand.d.ts.map +1 -1
  32. package/build/tools/brand.js +10 -7
  33. package/build/tools/brand.js.map +1 -1
  34. package/build/tools/campaigns.d.ts +2 -0
  35. package/build/tools/campaigns.d.ts.map +1 -1
  36. package/build/tools/campaigns.js +49 -33
  37. package/build/tools/campaigns.js.map +1 -1
  38. package/build/tools/capabilities.d.ts +1 -3
  39. package/build/tools/capabilities.d.ts.map +1 -1
  40. package/build/tools/capabilities.js +11 -55
  41. package/build/tools/capabilities.js.map +1 -1
  42. package/build/tools/contacts.d.ts.map +1 -1
  43. package/build/tools/contacts.js +31 -48
  44. package/build/tools/contacts.js.map +1 -1
  45. package/build/tools/context.js +1 -1
  46. package/build/tools/context.js.map +1 -1
  47. package/build/tools/generate.js +4 -4
  48. package/build/tools/generate.js.map +1 -1
  49. package/build/tools/segments.d.ts +16 -16
  50. package/build/tools/send-approval.d.ts +29 -0
  51. package/build/tools/send-approval.d.ts.map +1 -0
  52. package/build/tools/send-approval.js +51 -0
  53. package/build/tools/send-approval.js.map +1 -0
  54. package/build/tools/send.d.ts +1 -1
  55. package/build/tools/send.d.ts.map +1 -1
  56. package/build/tools/send.js +24 -35
  57. package/build/tools/send.js.map +1 -1
  58. package/build/tools/sender-check.d.ts +16 -0
  59. package/build/tools/sender-check.d.ts.map +1 -0
  60. package/build/tools/sender-check.js +28 -0
  61. package/build/tools/sender-check.js.map +1 -0
  62. package/package.json +3 -3
  63. package/build/tools/__tests__/automations.test.d.ts +0 -2
  64. package/build/tools/__tests__/automations.test.d.ts.map +0 -1
  65. package/build/tools/__tests__/automations.test.js +0 -259
  66. package/build/tools/__tests__/automations.test.js.map +0 -1
  67. package/build/tools/__tests__/forms.test.d.ts +0 -2
  68. package/build/tools/__tests__/forms.test.d.ts.map +0 -1
  69. package/build/tools/__tests__/forms.test.js +0 -127
  70. package/build/tools/__tests__/forms.test.js.map +0 -1
  71. package/build/tools/__tests__/websites.test.d.ts +0 -2
  72. package/build/tools/__tests__/websites.test.d.ts.map +0 -1
  73. package/build/tools/__tests__/websites.test.js +0 -138
  74. package/build/tools/__tests__/websites.test.js.map +0 -1
  75. package/build/tools/automations.d.ts +0 -22
  76. package/build/tools/automations.d.ts.map +0 -1
  77. package/build/tools/automations.js +0 -134
  78. package/build/tools/automations.js.map +0 -1
  79. package/build/tools/forms.d.ts +0 -6
  80. package/build/tools/forms.d.ts.map +0 -1
  81. package/build/tools/forms.js +0 -97
  82. package/build/tools/forms.js.map +0 -1
  83. package/build/tools/websites.d.ts +0 -4
  84. package/build/tools/websites.d.ts.map +0 -1
  85. package/build/tools/websites.js +0 -114
  86. package/build/tools/websites.js.map +0 -1
@@ -1,259 +0,0 @@
1
- import assert from 'node:assert/strict';
2
- import test from 'node:test';
3
- import { createMigmaMcpServer } from '../../index.js';
4
- import { getToolRequiredScopes, TOOL_CATALOG } from '../capabilities.js';
5
- function tools(permissions) {
6
- return createMigmaMcpServer({ config: { apiKey: 'test-key', baseUrl: 'https://api.example.test/v1', projectId: 'brand' }, permissions })._registeredTools;
7
- }
8
- test('automation discovery honors read/write scopes and marks activation as external', () => {
9
- const read = tools(['campaign:read']);
10
- assert.ok(read.migma_get_automation_capabilities);
11
- assert.ok(read.migma_list_automation_runs);
12
- assert.ok(read.migma_get_automation_metrics);
13
- assert.equal(read.migma_generate_automation, undefined);
14
- assert.equal(read.migma_activate_automation, undefined);
15
- const all = tools();
16
- assert.deepEqual(getToolRequiredScopes('migma_generate_automation'), ['campaign:write', 'email:write']);
17
- assert.equal(all.migma_generate_automation.annotations.idempotentHint, false);
18
- assert.match(TOOL_CATALOG.find(tool => tool.name === 'migma_generate_automation')?.summary ?? '', /Reuse idempotency_key/);
19
- assert.equal(all.migma_activate_automation.annotations.openWorldHint, true);
20
- assert.equal(all.migma_activate_automation.inputSchema.safeParse({ automationId: 'flow', confirmed: false }).success, false);
21
- assert.equal(all.migma_activate_automation.inputSchema.safeParse({ automationId: 'flow', confirmed: true }).success, false);
22
- assert.equal(all.migma_activate_automation.inputSchema.safeParse({ automationId: 'flow', confirmed: true, expectedDefinitionHash: 'not-a-hash' }).success, false);
23
- assert.equal(all.migma_activate_automation.inputSchema.safeParse({ automationId: 'flow', confirmed: true, expectedDefinitionHash: 'a'.repeat(64) }).success, true);
24
- });
25
- test('activation preserves public API error code and checklist data in structured MCP content', async (t) => {
26
- const data = {
27
- checklist: [{ key: 'sender', status: 'missing', message: 'Choose a verified sender' }],
28
- failing: [{ key: 'sender', status: 'missing', message: 'Choose a verified sender' }],
29
- fixes: [{ key: 'sender', fix: 'Verify a sender', message: 'Choose a verified sender' }],
30
- };
31
- t.mock.method(globalThis, 'fetch', async () => new Response(JSON.stringify({
32
- success: false,
33
- error: 'Fix the automation checks before activation',
34
- code: 'AUTOMATION_VALIDATION_FAILED',
35
- data,
36
- }), { status: 400 }));
37
- const result = await tools().migma_activate_automation.handler({ automationId: 'flow', confirmed: true, expectedDefinitionHash: 'a'.repeat(64) }, {});
38
- assert.equal(result.isError, true);
39
- assert.equal(result.content[0].text, 'Fix the automation checks before activation');
40
- assert.deepEqual(result.structuredContent, {
41
- error: {
42
- message: 'Fix the automation checks before activation',
43
- statusCode: 400,
44
- code: 'AUTOMATION_VALIDATION_FAILED',
45
- data,
46
- },
47
- });
48
- });
49
- test('automation mutations carry the exact reviewed definition hash', async (t) => {
50
- const requests = [];
51
- t.mock.method(globalThis, 'fetch', async (url, init) => {
52
- requests.push({ url, body: JSON.parse(init.body) });
53
- return new Response(JSON.stringify({ success: true, data: { id: 'flow', status: 'draft' } }), { status: 200 });
54
- });
55
- const all = tools();
56
- const trigger = { type: 'event', event: { name: 'contact.subscribed' } };
57
- await all.migma_activate_automation.handler({ automationId: 'flow', confirmed: true, expectedDefinitionHash: 'a'.repeat(64) }, {});
58
- await all.migma_update_automation_trigger.handler({ automationId: 'flow', trigger, expectedDefinitionHash: 'b'.repeat(64) }, {});
59
- await all.migma_update_automation_wait.handler({ automationId: 'flow', stepId: 'wait-1', duration: 'P2D', expectedDefinitionHash: 'c'.repeat(64) }, {});
60
- assert.deepEqual(requests.map(request => request.body), [
61
- { confirmed: true, expectedDefinitionHash: 'a'.repeat(64) },
62
- { trigger, expectedDefinitionHash: 'b'.repeat(64) },
63
- { duration: 'P2D', expectedDefinitionHash: 'c'.repeat(64) },
64
- ]);
65
- });
66
- test('unkeyed automation generation uses distinct replay identities and stays non-idempotent', async (t) => {
67
- const keys = [];
68
- t.mock.method(globalThis, 'fetch', async (_url, init) => {
69
- keys.push(init.headers['Idempotency-Key']);
70
- return new Response(JSON.stringify({ success: true, data: { jobId: `job-${keys.length}`, status: 'queued' } }), { status: 202 });
71
- });
72
- const tool = tools().migma_generate_automation;
73
- await tool.handler({ brief: 'Welcome subscribers' }, {});
74
- await tool.handler({ brief: 'Welcome subscribers' }, {});
75
- assert.equal(tool.annotations.idempotentHint, false);
76
- assert.equal(keys.length, 2);
77
- assert.ok(keys[0]);
78
- assert.ok(keys[1]);
79
- assert.notEqual(keys[0], keys[1]);
80
- });
81
- test('automation reporting preserves unavailable values rather than filling zeros', async (t) => {
82
- const report = { nodes: [{ nodeId: 'node', campaignId: 'campaign', reporting: { status: 'unavailable', source: 'unavailable' } }], edges: [], reporting: { status: 'unavailable', source: 'campaigns', warnings: ['Tracking is unavailable'] } };
83
- t.mock.method(globalThis, 'fetch', async (url) => {
84
- assert.equal(url, 'https://api.example.test/v1/automations/flow/metrics');
85
- return new Response(JSON.stringify({ success: true, data: report }), { status: 200 });
86
- });
87
- const result = await tools().migma_get_automation_metrics.handler({ automationId: 'flow' }, {});
88
- assert.deepEqual(JSON.parse(result.content[0].text), { ...report, period: 'lifetime' });
89
- });
90
- test('workflow image generation sends one off-draft request with the supplied retry key', async (t) => {
91
- const calls = [];
92
- t.mock.method(globalThis, 'fetch', async (url, init) => {
93
- calls.push({ url, init });
94
- return new Response(JSON.stringify({ success: true, data: { jobId: 'job', status: 'queued' } }), { status: 202 });
95
- });
96
- const result = await tools().migma_generate_automation.handler({ brief: 'Recreate the branches', imageUrls: ['https://example.test/flow.png'], idempotency_key: 'retry-001' }, {});
97
- assert.equal(result.isError, undefined);
98
- assert.equal(calls.length, 1);
99
- assert.equal(calls[0].url, 'https://api.example.test/v1/automations/generate');
100
- assert.equal(calls[0].init.headers['Idempotency-Key'], 'retry-001');
101
- assert.deepEqual(JSON.parse(calls[0].init.body), { projectId: 'brand', brief: 'Recreate the branches', imageUrls: ['https://example.test/flow.png'] });
102
- assert.equal(JSON.parse(result.content[0].text).status, 'queued');
103
- });
104
- test('automation tools use the account\'s only brand when projectId is omitted', async (t) => {
105
- const brandId = '665f1e928c2a9e4d8f123123';
106
- const client = {
107
- projects: {
108
- list: async () => ({
109
- data: {
110
- projects: [{ _id: brandId, name: 'Only brand', domain: 'example.test' }],
111
- pagination: { total: 1, limit: 10, offset: 0, hasMore: false },
112
- },
113
- }),
114
- },
115
- };
116
- t.mock.method(globalThis, 'fetch', async (url) => {
117
- const request = new URL(url);
118
- assert.equal(request.pathname, '/v1/automations');
119
- assert.equal(request.searchParams.get('projectId'), brandId);
120
- return new Response(JSON.stringify({ success: true, data: [] }), { status: 200 });
121
- });
122
- const registered = createMigmaMcpServer({
123
- client,
124
- config: { apiKey: 'automation-single-brand', baseUrl: 'https://api.example.test/v1' },
125
- permissions: ['campaign:read'],
126
- })._registeredTools;
127
- const result = await registered.migma_list_automations.handler({}, {});
128
- assert.equal(result.isError, undefined);
129
- assert.deepEqual(JSON.parse(result.content[0].text), []);
130
- });
131
- test('automation lists forward bounded pagination and archived visibility', async (t) => {
132
- const tool = tools(['campaign:read']).migma_list_automations;
133
- assert.equal(tool.inputSchema.safeParse({ cursor: 'next', limit: 1, includeArchived: true }).success, true);
134
- assert.equal(tool.inputSchema.safeParse({ limit: 0 }).success, false);
135
- assert.equal(tool.inputSchema.safeParse({ limit: 201 }).success, false);
136
- assert.equal(tool.inputSchema.safeParse({ cursor: 'x'.repeat(201) }).success, false);
137
- assert.equal(tool.inputSchema.safeParse({ includeArchived: 'true' }).success, false);
138
- assert.equal(tool.inputSchema.safeParse({ status: 'archived' }).success, false);
139
- t.mock.method(globalThis, 'fetch', async (url) => {
140
- assert.equal(url, 'https://api.example.test/v1/automations?projectId=brand&cursor=next&limit=25&includeArchived=true');
141
- return new Response(JSON.stringify({ success: true, data: { automations: [], count: 0, nextCursor: null } }), { status: 200 });
142
- });
143
- const result = await tool.handler({ cursor: 'next', limit: 25, includeArchived: true }, {});
144
- assert.deepEqual(JSON.parse(result.content[0].text), { automations: [], count: 0, nextCursor: null });
145
- });
146
- test('validation surfaces exact blockers without making an activation call', async (t) => {
147
- let calls = 0;
148
- const checks = { ready: false, checklist: [{ key: 'sender', status: 'missing', message: 'Choose a verified sender' }] };
149
- t.mock.method(globalThis, 'fetch', async (url) => {
150
- calls++;
151
- assert.equal(url, 'https://api.example.test/v1/automations/flow/validate');
152
- return new Response(JSON.stringify({ success: true, data: checks }), { status: 200 });
153
- });
154
- const result = await tools().migma_validate_automation.handler({ automationId: 'flow' }, {});
155
- assert.deepEqual(JSON.parse(result.content[0].text), checks);
156
- assert.equal(calls, 1);
157
- });
158
- test('selected reporting window uses report and preserves period, coverage, and unavailable totals', async (t) => {
159
- const window = { startDate: '2026-03-28', endDate: '2026-03-30', timezone: 'Europe/Madrid' };
160
- const report = { version: 1, cohort: 'send-date', scope: 'all-versions', window,
161
- nodes: [], totals: null, coverage: { since: '2026-03-29T00:00:00Z', complete: false },
162
- revenue: { status: 'unavailable' }, reporting: { status: 'partial', warnings: ['Incomplete history'] } };
163
- t.mock.method(globalThis, 'fetch', async (url) => {
164
- const request = new URL(url);
165
- assert.equal(request.pathname, '/v1/automations/flow/report');
166
- assert.deepEqual(Object.fromEntries(request.searchParams), window);
167
- return new Response(JSON.stringify({ success: true, data: report }), { status: 200 });
168
- });
169
- const tool = tools(['campaign:read']).migma_get_automation_metrics;
170
- assert.equal(tool.inputSchema.safeParse({ automationId: 'flow', ...window }).success, true);
171
- const result = await tool.handler({ automationId: 'flow', ...window }, {});
172
- assert.deepEqual(JSON.parse(result.content[0].text), report);
173
- });
174
- test('invalid and partial reporting windows fail before transport instead of falling back to lifetime', async (t) => {
175
- t.mock.method(globalThis, 'fetch', async () => { throw new Error('Transport must not be called'); });
176
- const tool = tools().migma_get_automation_metrics;
177
- const window = { automationId: 'flow', startDate: '2026-01-01', endDate: '2026-12-31', timezone: 'UTC' };
178
- assert.equal(tool.inputSchema.safeParse(window).success, true);
179
- assert.equal(tool.inputSchema.safeParse({ automationId: 'flow' }).success, true);
180
- for (const args of [
181
- { automationId: 'flow', startDate: '2026-01-01' },
182
- { automationId: 'flow', startDate: '2026-01-01', endDate: '2026-01-02' },
183
- { automationId: 'flow', timezone: 'UTC' },
184
- { ...window, startDate: '2026-02-30' },
185
- { ...window, endDate: '2025-12-31' },
186
- { ...window, endDate: '2027-01-02' },
187
- { ...window, timezone: 'Invalid/Zone' },
188
- ]) {
189
- assert.equal(tool.inputSchema.safeParse(args).success, false, JSON.stringify(args));
190
- const result = await tool.handler(args, {});
191
- assert.equal(result.isError, true);
192
- assert.doesNotMatch(result.content[0].text, /Transport must not be called/);
193
- }
194
- });
195
- test('explicit zero-email generation is accepted and transported without losing zero', async (t) => {
196
- const tool = tools().migma_generate_automation;
197
- for (const emailCount of [-1, 13, 0.5]) {
198
- assert.equal(tool.inputSchema.safeParse({ brief: 'Add a tag', emailCount }).success, false);
199
- }
200
- const args = { brief: 'Add an existing tag after signup, with no emails', emailCount: 0, idempotency_key: 'action-only' };
201
- assert.equal(tool.inputSchema.safeParse(args).success, true);
202
- t.mock.method(globalThis, 'fetch', async (_url, init) => {
203
- assert.equal(JSON.parse(init.body).emailCount, 0);
204
- return new Response(JSON.stringify({ success: true, data: { jobId: 'job', status: 'queued' } }), { status: 202 });
205
- });
206
- const result = await tool.handler(args, {});
207
- assert.equal(result.isError, undefined);
208
- });
209
- test('automation writes send one replay key per call and reuse it on transport retries', async (t) => {
210
- const calls = [];
211
- t.mock.method(globalThis, 'fetch', async (_url, init) => {
212
- calls.push({ method: init.method, key: init.headers['Idempotency-Key'] });
213
- // The first attempt of every call is lost; the transport retries it.
214
- return calls.length % 2
215
- ? new Response(JSON.stringify({ success: false, error: 'Unavailable' }), { status: 503 })
216
- : new Response(JSON.stringify({ success: true, data: { id: 'flow' } }), { status: 200 });
217
- });
218
- t.mock.method(globalThis, 'setTimeout', (callback) => { callback(); return 0; });
219
- const all = tools();
220
- const hash = 'a'.repeat(64);
221
- await all.migma_validate_automation.handler({ automationId: 'flow' }, {});
222
- await all.migma_activate_automation.handler({ automationId: 'flow', confirmed: true, expectedDefinitionHash: hash }, {});
223
- await all.migma_pause_automation.handler({ automationId: 'flow' }, {});
224
- await all.migma_update_automation_trigger.handler({ automationId: 'flow', expectedDefinitionHash: hash, trigger: { type: 'event', event: { name: 'contact.subscribed' } } }, {});
225
- await all.migma_update_automation_wait.handler({ automationId: 'flow', stepId: 'wait', duration: 'P2D', expectedDefinitionHash: hash, idempotency_key: 'wait-edit' }, {});
226
- assert.equal(calls.length, 10);
227
- for (let i = 0; i < calls.length; i += 2) {
228
- assert.ok(calls[i].key);
229
- assert.equal(calls[i + 1].key, calls[i].key, 'a retried attempt replays the same change');
230
- }
231
- assert.equal(new Set(calls.map(call => call.key)).size, 5);
232
- assert.equal(calls[6].method, 'PUT');
233
- assert.equal(calls[8].key, 'wait-edit');
234
- });
235
- test('trigger and wait inputs match the public API limits before transport', () => {
236
- const all = tools();
237
- const base = { automationId: 'flow', expectedDefinitionHash: 'a'.repeat(64) };
238
- const trigger = (propertyFilters) => ({ ...base, trigger: { type: 'event', event: { name: 'form.submitted', propertyFilters } } });
239
- const valid = { path: 'formId', op: 'eq', value: 'form' };
240
- const schema = all.migma_update_automation_trigger.inputSchema;
241
- assert.equal(schema.safeParse(trigger([valid, { path: 'email', op: 'exists' }])).success, true);
242
- assert.equal(schema.safeParse(trigger([{ ...valid, value: null }])).success, false, 'null is not a filter value');
243
- assert.equal(schema.safeParse(trigger([{ path: 'formId', op: 'eq' }])).success, false, 'value operators need a value');
244
- assert.equal(schema.safeParse(trigger([{ ...valid, path: 'a'.repeat(201) }])).success, false);
245
- assert.equal(schema.safeParse(trigger(Array(21).fill(valid))).success, false);
246
- const wait = all.migma_update_automation_wait.inputSchema;
247
- assert.equal(wait.safeParse({ ...base, stepId: 's'.repeat(160), duration: 'P2D' }).success, true);
248
- assert.equal(wait.safeParse({ ...base, stepId: 's'.repeat(161), duration: 'P2D' }).success, false);
249
- assert.equal(wait.safeParse({ ...base, stepId: 'wait', duration: 'P'.padEnd(51, '1') }).success, false);
250
- });
251
- test('run detail forwards the requested history size', async (t) => {
252
- t.mock.method(globalThis, 'fetch', async (url) => {
253
- assert.equal(url, 'https://api.example.test/v1/automations/flow/runs/run?historyLimit=50');
254
- return new Response(JSON.stringify({ success: true, data: { id: 'run', history: [], historyTotal: 0 } }), { status: 200 });
255
- });
256
- const result = await tools().migma_get_automation_run.handler({ automationId: 'flow', runId: 'run', historyLimit: 50 }, {});
257
- assert.equal(result.isError, undefined);
258
- });
259
- //# sourceMappingURL=automations.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"automations.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/automations.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=forms.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"forms.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/forms.test.ts"],"names":[],"mappings":""}
@@ -1,127 +0,0 @@
1
- import assert from 'node:assert/strict';
2
- import test from 'node:test';
3
- import { createMigmaMcpServer } from '../../index.js';
4
- import { getToolRequiredScopes } from '../capabilities.js';
5
- function tools(permissions) {
6
- return createMigmaMcpServer({ config: { apiKey: 'test-key', baseUrl: 'https://api.example.test/v1', projectId: 'brand' }, permissions })._registeredTools;
7
- }
8
- const spec = {
9
- kind: 'subscribe', confirmation: { mode: 'message', value: 'Thanks' }, styleTokens: {},
10
- steps: [{ id: 'signup', headline: 'Join', ctaLabel: 'Join', fields: [{ key: 'email', label: 'Email', type: 'email', required: true }] }],
11
- };
12
- test('form tools follow read, write and contact-data scopes', () => {
13
- const read = tools(['campaign:read']);
14
- assert.ok(read.migma_list_forms);
15
- assert.ok(read.migma_get_form);
16
- assert.equal(read.migma_create_form, undefined);
17
- assert.equal(read.migma_list_form_submissions, undefined, 'Submissions contain contact data');
18
- assert.ok(tools(['campaign:read', 'audience:read']).migma_list_form_submissions);
19
- assert.deepEqual(getToolRequiredScopes('migma_list_form_submissions'), ['campaign:read', 'audience:read']);
20
- assert.deepEqual(getToolRequiredScopes('migma_publish_form'), ['campaign:write']);
21
- assert.equal(tools(['campaign:write']).migma_submit_form, undefined, 'Submitting writes contacts');
22
- assert.ok(tools(['campaign:write', 'audience:write']).migma_submit_form);
23
- assert.deepEqual(getToolRequiredScopes('migma_submit_form'), ['campaign:write', 'audience:write']);
24
- const all = tools();
25
- assert.equal(all.migma_publish_form.annotations.openWorldHint, true, 'Publishing makes the form public');
26
- assert.equal(all.migma_delete_form.annotations.destructiveHint, true);
27
- assert.equal(all.migma_create_form.annotations.idempotentHint, false);
28
- assert.equal(all.migma_list_forms.annotations.readOnlyHint, true);
29
- });
30
- test('form inputs reject unknown fields and invalid specs before transport', () => {
31
- const create = tools().migma_create_form.inputSchema;
32
- assert.equal(create.safeParse({ spec }).success, true);
33
- assert.equal(create.safeParse({ spec: { ...spec, steps: [] } }).success, false);
34
- assert.equal(create.safeParse({ spec: { ...spec, confirmation: { mode: 'popup', value: 'x' } } }).success, false);
35
- assert.equal(create.safeParse({ spec, userId: 'owner' }).success, false);
36
- const field = (key) => ({ ...spec, steps: [{ ...spec.steps[0], fields: [{ key, label: 'Email', type: 'email', required: true }] }] });
37
- assert.equal(create.safeParse({ spec: field('1email') }).success, false);
38
- const update = tools().migma_update_form.inputSchema;
39
- assert.equal(update.safeParse({ formId: 'form', spec: { confirmation: { mode: 'message', value: 'Welcome' } } }).success, true);
40
- assert.equal(create.safeParse({ spec, name: 'Spring waitlist' }).success, true);
41
- assert.equal(create.safeParse({ spec, name: 'x'.repeat(121) }).success, false);
42
- assert.equal(create.safeParse({ spec, name: ' ' }).success, false);
43
- assert.equal(update.safeParse({ formId: 'form', name: 'Summer waitlist' }).success, true);
44
- assert.equal(update.safeParse({ formId: 'form', name: null }).success, true, 'null clears the name');
45
- });
46
- test('form writes send one replay key per call, the brand and only supplied fields', async (t) => {
47
- const calls = [];
48
- t.mock.method(globalThis, 'fetch', async (url, init) => {
49
- calls.push({ url, method: init.method, key: init.headers['Idempotency-Key'], body: init.body });
50
- return new Response(JSON.stringify({ success: true, data: { id: 'form', status: 'draft' } }), { status: 200 });
51
- });
52
- const all = tools();
53
- await all.migma_create_form.handler({ spec, tagIds: ['tag'] }, {});
54
- await all.migma_update_form.handler({ formId: 'form', spec: { confirmation: { mode: 'message', value: 'Welcome' } } }, {});
55
- await all.migma_publish_form.handler({ formId: 'form' }, {});
56
- await all.migma_pause_form.handler({ formId: 'form', idempotency_key: 'pause-1' }, {});
57
- await all.migma_delete_form.handler({ formId: 'form' }, {});
58
- assert.deepEqual(calls.map(call => [call.method, call.url]), [
59
- ['POST', 'https://api.example.test/v1/forms'],
60
- ['PATCH', 'https://api.example.test/v1/forms/form'],
61
- ['POST', 'https://api.example.test/v1/forms/form/publish'],
62
- ['POST', 'https://api.example.test/v1/forms/form/pause'],
63
- ['DELETE', 'https://api.example.test/v1/forms/form'],
64
- ]);
65
- assert.deepEqual(JSON.parse(calls[0].body), { projectId: 'brand', spec, tagIds: ['tag'] });
66
- assert.deepEqual(JSON.parse(calls[1].body), { spec: { confirmation: { mode: 'message', value: 'Welcome' } } });
67
- assert.equal(new Set(calls.map(call => call.key)).size, 5);
68
- assert.ok(calls.every(call => call.key));
69
- assert.equal(calls[3].key, 'pause-1');
70
- await all.migma_create_form.handler({ spec, name: 'Spring waitlist' }, {});
71
- await all.migma_update_form.handler({ formId: 'form', name: 'Summer waitlist' }, {});
72
- assert.equal(JSON.parse(calls[5].body).name, 'Spring waitlist');
73
- assert.deepEqual(JSON.parse(calls[6].body), { name: 'Summer waitlist' }, 'A rename sends only the name');
74
- });
75
- test('submitting a form sends one replay key per call and only the signup', async (t) => {
76
- const calls = [];
77
- t.mock.method(globalThis, 'fetch', async (url, init) => {
78
- calls.push({ url, method: init.method, key: init.headers['Idempotency-Key'], body: init.body });
79
- return new Response(JSON.stringify({ success: true, data: { formId: 'form', submissionId: 'hash', state: 'received', duplicate: false } }), { status: 201 });
80
- });
81
- const submit = tools().migma_submit_form;
82
- const args = {
83
- formId: 'form',
84
- email: 'ada@example.com',
85
- fields: { firstName: 'Ada', consent: true },
86
- attribution: { utmSource: 'launch' },
87
- consent: { ip: '203.0.113.10', userAgent: 'Signup UI/1.0' },
88
- };
89
- assert.equal(submit.inputSchema.safeParse(args).success, true);
90
- assert.equal(submit.inputSchema.safeParse({ ...args, status: 'subscribed' }).success, false, 'Callers cannot set a status');
91
- assert.equal(submit.inputSchema.safeParse({ ...args, attribution: { source: 'x' } }).success, false);
92
- assert.equal(submit.inputSchema.safeParse({ ...args, consent: { ip: 'not-an-ip' } }).success, false);
93
- assert.equal(submit.inputSchema.safeParse({ ...args, consent: { userAgent: 'x'.repeat(1001) } }).success, false);
94
- assert.equal(submit.inputSchema.safeParse({ ...args, consent: { ip: '203.0.113.10', forwardedFor: '198.51.100.2' } }).success, false);
95
- assert.equal(submit.inputSchema.safeParse({ formId: 'form', email: 'not-an-email' }).success, false);
96
- const result = await submit.handler(args, {});
97
- await submit.handler({ ...args, idempotency_key: 'signup-1' }, {});
98
- assert.deepEqual(JSON.parse(result.content[0].text), { formId: 'form', submissionId: 'hash', state: 'received', duplicate: false });
99
- assert.deepEqual(calls.map(call => [call.method, call.url]), Array(2).fill(['POST', 'https://api.example.test/v1/forms/form/submissions']));
100
- assert.deepEqual(JSON.parse(calls[0].body), {
101
- email: 'ada@example.com',
102
- fields: { firstName: 'Ada', consent: true },
103
- attribution: { utmSource: 'launch' },
104
- consent: { ip: '203.0.113.10', userAgent: 'Signup UI/1.0' },
105
- });
106
- assert.ok(calls[0].key);
107
- assert.equal(calls[1].key, 'signup-1');
108
- });
109
- test('a form used by an enabled automation reports the blocking flows', async (t) => {
110
- const data = { automations: [{ id: 'flow', name: 'Welcome', link: 'https://migma.ai/chat?automation=flow' }] };
111
- t.mock.method(globalThis, 'fetch', async () => new Response(JSON.stringify({ success: false, error: 'The automation "Welcome" starts when this form is used. Pause it first.', code: 'FORM_USED_BY_AUTOMATION', data }), { status: 409 }));
112
- const result = await tools().migma_pause_form.handler({ formId: 'form' }, {});
113
- assert.equal(result.isError, true);
114
- assert.deepEqual(result.structuredContent, { error: { message: 'The automation "Welcome" starts when this form is used. Pause it first.', statusCode: 409, code: 'FORM_USED_BY_AUTOMATION', data } });
115
- });
116
- test('submissions and lists pass filters through', async (t) => {
117
- const urls = [];
118
- t.mock.method(globalThis, 'fetch', async (url) => { urls.push(url); return new Response(JSON.stringify({ success: true, data: {} }), { status: 200 }); });
119
- const all = tools();
120
- await all.migma_list_forms.handler({ status: 'live' }, {});
121
- await all.migma_list_form_submissions.handler({ formId: 'form', limit: 10, cursor: 'next' }, {});
122
- assert.deepEqual(urls, [
123
- 'https://api.example.test/v1/forms?projectId=brand&status=live',
124
- 'https://api.example.test/v1/forms/form/submissions?limit=10&cursor=next',
125
- ]);
126
- });
127
- //# sourceMappingURL=forms.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"forms.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/forms.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=websites.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"websites.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/websites.test.ts"],"names":[],"mappings":""}
@@ -1,138 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import { createMigmaMcpServer } from "../../index.js";
4
- const PROJECT_ID = "665f1e928c2a9e4d8f123123";
5
- const WEBSITE_ID = "665f1e928c2a9e4d8f123456";
6
- const site = {
7
- id: WEBSITE_ID,
8
- projectId: PROJECT_ID,
9
- name: "Main storefront",
10
- origins: ["https://shop.example.com"],
11
- environment: "test",
12
- status: "enabled",
13
- collectorUrl: "https://collector.example.com",
14
- createdAt: "2026-10-01T08:00:00.000Z",
15
- updatedAt: "2026-10-01T08:00:00.000Z",
16
- };
17
- function registeredTools(client, permissions) {
18
- return createMigmaMcpServer({
19
- config: { apiKey: "test-key" },
20
- client: client,
21
- permissions,
22
- })._registeredTools;
23
- }
24
- test("website tools follow audience scopes and never expose identity issuance", () => {
25
- const client = { websites: {} };
26
- const read = registeredTools(client, ["audience:read"]);
27
- assert.ok(read.migma_list_websites);
28
- assert.ok(read.migma_get_website_events);
29
- assert.equal(read.migma_create_website, undefined);
30
- assert.equal(read.migma_update_website, undefined);
31
- const write = registeredTools(client, ["audience:write"]);
32
- assert.ok(write.migma_create_website);
33
- assert.ok(write.migma_update_website);
34
- assert.equal(write.migma_list_websites, undefined);
35
- assert.equal(write.migma_issue_website_identity, undefined);
36
- });
37
- test("website schemas enforce exact origins, IDs, bounds, and updates", () => {
38
- const tools = registeredTools({ websites: {} });
39
- const create = tools.migma_create_website.inputSchema;
40
- assert.equal(create.safeParse({
41
- projectId: PROJECT_ID,
42
- name: "Main storefront",
43
- origins: ["https://shop.example.com"],
44
- environment: "test",
45
- }).success, true);
46
- assert.equal(create.safeParse({
47
- projectId: PROJECT_ID,
48
- name: "Main storefront",
49
- origins: ["http://shop.example.com"],
50
- environment: "test",
51
- }).success, false);
52
- assert.equal(create.safeParse({
53
- projectId: PROJECT_ID,
54
- name: "Main storefront",
55
- origins: ["https://shop.example.com/path"],
56
- environment: "test",
57
- }).success, false);
58
- assert.equal(create.safeParse({
59
- projectId: PROJECT_ID,
60
- name: "Main storefront",
61
- origins: ["not a URL"],
62
- environment: "test",
63
- }).success, false);
64
- assert.equal(create.safeParse({ name: "Missing project", origins: ["https://shop.example.com"], environment: "test" }).success, false);
65
- assert.equal(tools.migma_update_website.inputSchema.safeParse({ websiteId: WEBSITE_ID }).success, false);
66
- assert.equal(tools.migma_update_website.inputSchema.safeParse({ websiteId: WEBSITE_ID, status: "disabled" }).success, true);
67
- });
68
- test("website tools call the SDK with one stable creation key", async () => {
69
- const calls = [];
70
- const client = {
71
- websites: {
72
- async list(projectId) {
73
- calls.push(["list", projectId]);
74
- return { data: [site], error: null };
75
- },
76
- async create(input, key) {
77
- calls.push(["create", input, key]);
78
- return { data: site, error: null };
79
- },
80
- async update(id, input) {
81
- calls.push(["update", id, input]);
82
- return { data: { ...site, ...input }, error: null };
83
- },
84
- async events(id) {
85
- calls.push(["events", id]);
86
- return { data: { status: "available", events: [], sampleWindowHours: 24, sampledRows: 1000 }, error: null };
87
- },
88
- },
89
- };
90
- const tools = registeredTools(client);
91
- await tools.migma_list_websites.handler({ projectId: PROJECT_ID }, {});
92
- await tools.migma_create_website.handler({
93
- projectId: PROJECT_ID,
94
- name: site.name,
95
- origins: site.origins,
96
- environment: "test",
97
- idempotency_key: "storefront-setup-1",
98
- }, {});
99
- await tools.migma_update_website.handler({ websiteId: WEBSITE_ID, status: "disabled" }, {});
100
- const history = await tools.migma_get_website_events.handler({ websiteId: WEBSITE_ID }, {});
101
- assert.deepEqual(calls, [
102
- ["list", PROJECT_ID],
103
- ["create", { projectId: PROJECT_ID, name: site.name, origins: site.origins, environment: "test" }, "storefront-setup-1"],
104
- ["update", WEBSITE_ID, { status: "disabled" }],
105
- ["events", WEBSITE_ID],
106
- ]);
107
- assert.deepEqual(JSON.parse(history.content[0].text), {
108
- status: "available",
109
- events: [],
110
- sampleWindowHours: 24,
111
- sampledRows: 1000,
112
- });
113
- });
114
- test("website creation without a caller key uses separate keys and does not advertise safe replay", async () => {
115
- const keys = [];
116
- const tools = registeredTools({
117
- websites: {
118
- async create(_input, key) {
119
- keys.push(key);
120
- return { data: site, error: null };
121
- },
122
- },
123
- }, ["audience:write"]);
124
- const input = {
125
- projectId: PROJECT_ID,
126
- name: site.name,
127
- origins: site.origins,
128
- environment: "test",
129
- };
130
- const result = await tools.migma_create_website.handler(input, {});
131
- await tools.migma_create_website.handler(input, {});
132
- assert.equal(result.isError, undefined);
133
- assert.equal(tools.migma_create_website.annotations?.idempotentHint, false);
134
- assert.equal(keys.length, 2);
135
- assert.notEqual(keys[0], keys[1]);
136
- assert.match(keys[0], /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/);
137
- });
138
- //# sourceMappingURL=websites.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"websites.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/websites.test.ts"],"names":[],"mappings":"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"}