@migma/mcp 1.7.4 → 1.8.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.
- package/README.md +32 -4
- package/build/index.d.ts.map +1 -1
- package/build/index.js +14 -10
- package/build/index.js.map +1 -1
- package/build/profiles.d.ts.map +1 -1
- package/build/profiles.js +6 -2
- package/build/profiles.js.map +1 -1
- package/build/prompts/index.d.ts +1 -0
- package/build/prompts/index.d.ts.map +1 -1
- package/build/prompts/index.js +38 -13
- package/build/prompts/index.js.map +1 -1
- package/build/tools/__tests__/catalog.test.js +18 -7
- package/build/tools/__tests__/catalog.test.js.map +1 -1
- package/build/tools/__tests__/connected-tools.test.d.ts +2 -0
- package/build/tools/__tests__/connected-tools.test.d.ts.map +1 -0
- package/build/tools/__tests__/connected-tools.test.js +66 -0
- package/build/tools/__tests__/connected-tools.test.js.map +1 -0
- package/build/tools/__tests__/contact-exports.test.d.ts +2 -0
- package/build/tools/__tests__/contact-exports.test.d.ts.map +1 -0
- package/build/tools/__tests__/contact-exports.test.js +70 -0
- package/build/tools/__tests__/contact-exports.test.js.map +1 -0
- package/build/tools/__tests__/openai-profile.test.js +2 -2
- package/build/tools/__tests__/openai-profile.test.js.map +1 -1
- package/build/tools/__tests__/provider-imports.test.d.ts +2 -0
- package/build/tools/__tests__/provider-imports.test.d.ts.map +1 -0
- package/build/tools/__tests__/provider-imports.test.js +93 -0
- package/build/tools/__tests__/provider-imports.test.js.map +1 -0
- package/build/tools/__tests__/review-annotations.test.d.ts +2 -0
- package/build/tools/__tests__/review-annotations.test.d.ts.map +1 -0
- package/build/tools/__tests__/review-annotations.test.js +140 -0
- package/build/tools/__tests__/review-annotations.test.js.map +1 -0
- package/build/tools/annotations.d.ts +7 -0
- package/build/tools/annotations.d.ts.map +1 -1
- package/build/tools/annotations.js +1 -0
- package/build/tools/annotations.js.map +1 -1
- package/build/tools/billing.js +5 -5
- package/build/tools/billing.js.map +1 -1
- package/build/tools/brand.js +3 -3
- package/build/tools/brand.js.map +1 -1
- package/build/tools/campaigns.js +9 -9
- package/build/tools/campaigns.js.map +1 -1
- package/build/tools/capabilities.d.ts +3 -1
- package/build/tools/capabilities.d.ts.map +1 -1
- package/build/tools/capabilities.js +71 -26
- package/build/tools/capabilities.js.map +1 -1
- package/build/tools/connected-tools.d.ts +5 -0
- package/build/tools/connected-tools.d.ts.map +1 -0
- package/build/tools/connected-tools.js +56 -0
- package/build/tools/connected-tools.js.map +1 -0
- package/build/tools/contact-exports.d.ts +4 -0
- package/build/tools/contact-exports.d.ts.map +1 -0
- package/build/tools/contact-exports.js +67 -0
- package/build/tools/contact-exports.js.map +1 -0
- package/build/tools/contacts.d.ts.map +1 -1
- package/build/tools/contacts.js +140 -14
- package/build/tools/contacts.js.map +1 -1
- package/build/tools/context.js +11 -11
- package/build/tools/context.js.map +1 -1
- package/build/tools/domains.js +5 -5
- package/build/tools/domains.js.map +1 -1
- package/build/tools/export.js +5 -5
- package/build/tools/export.js.map +1 -1
- package/build/tools/generate.d.ts.map +1 -1
- package/build/tools/generate.js +5 -5
- package/build/tools/generate.js.map +1 -1
- package/build/tools/import-html.js +3 -3
- package/build/tools/import-html.js.map +1 -1
- package/build/tools/projects.js +3 -3
- package/build/tools/projects.js.map +1 -1
- package/build/tools/segments.d.ts +135 -0
- package/build/tools/segments.d.ts.map +1 -1
- package/build/tools/segments.js +1 -1
- package/build/tools/segments.js.map +1 -1
- package/build/tools/send.js +3 -3
- package/build/tools/send.js.map +1 -1
- package/build/tools/validate.js +3 -3
- package/build/tools/validate.js.map +1 -1
- package/build/tools/webhooks.d.ts.map +1 -1
- package/build/tools/webhooks.js +3 -3
- package/build/tools/webhooks.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { test } from 'node:test';
|
|
3
|
+
import { createMigmaMcpServer } from '../../index.js';
|
|
4
|
+
const projectId = 'a'.repeat(24), jobId = 'b'.repeat(24);
|
|
5
|
+
function tools(permissions = ['audience:read']) {
|
|
6
|
+
const server = createMigmaMcpServer({ permissions, config: { apiKey: 'test', baseUrl: 'https://api.test/v1', projectId } });
|
|
7
|
+
return server._registeredTools;
|
|
8
|
+
}
|
|
9
|
+
test('exports need audience read, not audience write; missing read hides both tools', () => {
|
|
10
|
+
assert.ok(tools().migma_create_contact_export);
|
|
11
|
+
assert.ok(tools().migma_get_contact_export);
|
|
12
|
+
assert.equal(tools(['audience:write']).migma_create_contact_export, undefined);
|
|
13
|
+
assert.equal(tools(['email:read']).migma_get_contact_export, undefined);
|
|
14
|
+
});
|
|
15
|
+
test('export preserves complex filters, search and stable replay key and returns queued truthfully', async () => {
|
|
16
|
+
const original = globalThis.fetch;
|
|
17
|
+
const calls = [];
|
|
18
|
+
globalThis.fetch = (async (url, init) => {
|
|
19
|
+
calls.push([String(url), init]);
|
|
20
|
+
return new Response(JSON.stringify({ success: true, data: { jobId, projectId, status: 'pending', contactCount: 4321 } }), { status: 202 });
|
|
21
|
+
});
|
|
22
|
+
try {
|
|
23
|
+
const tool = tools().migma_create_contact_export;
|
|
24
|
+
const filters = { status: 'unsubscribed', groups: [{ fields: [{ key: 'tier', mode: 'is', values: ['paid'] }] }] };
|
|
25
|
+
const args = tool.inputSchema.parse({ filters, search: '@example.com', idempotency_key: 'export-1' });
|
|
26
|
+
const result = await tool.handler(args, {});
|
|
27
|
+
assert.equal(calls[0][0], 'https://api.test/v1/contacts/exports');
|
|
28
|
+
assert.equal(calls[0][1].headers['Idempotency-Key'], 'export-1');
|
|
29
|
+
assert.deepEqual(JSON.parse(calls[0][1].body), { projectId, filters: { ...filters, search: '@example.com' } });
|
|
30
|
+
assert.equal(JSON.parse(result.content[0].text).status, 'pending');
|
|
31
|
+
assert.equal(tool.inputSchema.safeParse({ filters }).success, false);
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
globalThis.fetch = original;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
test('poll targets exact job and surfaces server failure rather than zero contacts', async () => {
|
|
38
|
+
const original = globalThis.fetch;
|
|
39
|
+
const calls = [];
|
|
40
|
+
globalThis.fetch = (async (url) => {
|
|
41
|
+
calls.push(String(url));
|
|
42
|
+
return new Response(JSON.stringify({ success: false, error: 'Export not found or expired.' }), { status: 404 });
|
|
43
|
+
});
|
|
44
|
+
try {
|
|
45
|
+
const tool = tools().migma_get_contact_export;
|
|
46
|
+
const result = await tool.handler(tool.inputSchema.parse({ jobId }), {});
|
|
47
|
+
assert.equal(calls[0], `https://api.test/v1/contacts/exports/${jobId}?projectId=${projectId}`);
|
|
48
|
+
assert.equal(result.isError, true);
|
|
49
|
+
assert.match(result.content[0].text, /expired/);
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
globalThis.fetch = original;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
test('ambiguous submission is never automatically repeated', async () => {
|
|
56
|
+
const original = globalThis.fetch;
|
|
57
|
+
let calls = 0;
|
|
58
|
+
globalThis.fetch = (async () => { calls++; throw new Error('lost acknowledgment'); });
|
|
59
|
+
try {
|
|
60
|
+
const tool = tools().migma_create_contact_export;
|
|
61
|
+
const result = await tool.handler(tool.inputSchema.parse({ idempotency_key: 'same-export' }), {});
|
|
62
|
+
assert.equal(calls, 1);
|
|
63
|
+
assert.equal(result.isError, true);
|
|
64
|
+
assert.match(result.content[0].text, /same idempotency_key/);
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
globalThis.fetch = original;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=contact-exports.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contact-exports.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/contact-exports.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
|
4
4
|
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
5
5
|
import { createMigmaMcpServer, createOpenAIMcpServer } from "../../index.js";
|
|
6
6
|
import { buildCapabilitiesPayload, TOOL_CATALOG } from "../capabilities.js";
|
|
7
|
-
const excluded = ["migma_search_buyable_domains", "migma_buy_domain", "migma_get_upgrade_link"];
|
|
7
|
+
const excluded = ["migma_search_buyable_domains", "migma_buy_domain", "migma_get_upgrade_link", "migma_list_connected_tools", "migma_get_connected_tool", "migma_call_connected_tool"];
|
|
8
8
|
test("OpenAI wire surface excludes commerce and rejects direct calls without accessing SDK", async () => {
|
|
9
9
|
const server = createOpenAIMcpServer({
|
|
10
10
|
getClient: () => { throw new Error("Must not call SDK"); },
|
|
@@ -26,7 +26,7 @@ test("OpenAI wire surface excludes commerce and rejects direct calls without acc
|
|
|
26
26
|
assert.doesNotMatch(JSON.stringify(tools), /migma_buy_domain|migma_search_buyable_domains|migma_get_upgrade_link/);
|
|
27
27
|
const capabilities = await client.callTool({ name: "migma_get_capabilities", arguments: {} });
|
|
28
28
|
assert.doesNotMatch(JSON.stringify(capabilities), /migma_buy_domain|migma_search_buyable_domains|migma_get_upgrade_link/);
|
|
29
|
-
assert.
|
|
29
|
+
assert.doesNotMatch(client.getInstructions() ?? "", /checkout|billing portal|chosen plan|offer.*billing/i);
|
|
30
30
|
}
|
|
31
31
|
finally {
|
|
32
32
|
await client.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-profile.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/openai-profile.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE5E,MAAM,QAAQ,GAAG,CAAC,8BAA8B,EAAE,kBAAkB,EAAE,wBAAwB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"openai-profile.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/openai-profile.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-imports.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/provider-imports.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { test } from "node:test";
|
|
3
|
+
import { createMigmaMcpServer } from "../../index.js";
|
|
4
|
+
const projectId = "a".repeat(24);
|
|
5
|
+
const importId = "b".repeat(24);
|
|
6
|
+
function tools(permissions = ["audience:read", "audience:write"]) {
|
|
7
|
+
const server = createMigmaMcpServer({
|
|
8
|
+
permissions,
|
|
9
|
+
config: { apiKey: "test", baseUrl: "https://api.test/v1", projectId },
|
|
10
|
+
});
|
|
11
|
+
return server._registeredTools;
|
|
12
|
+
}
|
|
13
|
+
test("provider list requires audience:read; import requires audience:write", () => {
|
|
14
|
+
assert.ok(tools(["audience:read"]).migma_list_provider_import_sources);
|
|
15
|
+
assert.equal(tools(["audience:read"]).migma_import_contacts_from_provider, undefined);
|
|
16
|
+
assert.ok(tools(["audience:write"]).migma_import_contacts_from_provider);
|
|
17
|
+
assert.equal(tools(["audience:write"]).migma_list_provider_import_sources, undefined);
|
|
18
|
+
});
|
|
19
|
+
test("list provider sources calls GET with projectId and optional connectionId", async () => {
|
|
20
|
+
const original = globalThis.fetch;
|
|
21
|
+
const calls = [];
|
|
22
|
+
globalThis.fetch = (async (url, init) => {
|
|
23
|
+
calls.push([String(url), init]);
|
|
24
|
+
return new Response(JSON.stringify({
|
|
25
|
+
success: true,
|
|
26
|
+
data: { sources: [{ id: "seg-1", type: "segment", name: "VIP" }] },
|
|
27
|
+
}), { status: 200 });
|
|
28
|
+
});
|
|
29
|
+
try {
|
|
30
|
+
const tool = tools(["audience:read"]).migma_list_provider_import_sources;
|
|
31
|
+
const result = await tool.handler(tool.inputSchema.parse({ provider: "klaviyo", connectionId: "c".repeat(24) }));
|
|
32
|
+
assert.equal(calls[0][0], `https://api.test/v1/contacts/imports/providers/klaviyo/sources?projectId=${projectId}&connectionId=${"c".repeat(24)}`);
|
|
33
|
+
assert.equal(calls[0][1].method, "GET");
|
|
34
|
+
assert.match(JSON.parse(result.content[0].text).sources[0].name, /VIP/);
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
globalThis.fetch = original;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
test("provider import posts JSON with idempotency header and can skip wait", async () => {
|
|
41
|
+
const original = globalThis.fetch;
|
|
42
|
+
const calls = [];
|
|
43
|
+
globalThis.fetch = (async (url, init) => {
|
|
44
|
+
calls.push([String(url), init]);
|
|
45
|
+
const path = String(url);
|
|
46
|
+
if (path.endsWith("/contacts/imports/provider")) {
|
|
47
|
+
return new Response(JSON.stringify({
|
|
48
|
+
success: true,
|
|
49
|
+
data: {
|
|
50
|
+
object: "contact_import",
|
|
51
|
+
id: importId,
|
|
52
|
+
status: "pending",
|
|
53
|
+
tag: { id: "t1", name: "VIP" },
|
|
54
|
+
segment: { id: "s1", name: "VIP" },
|
|
55
|
+
},
|
|
56
|
+
}), { status: 201 });
|
|
57
|
+
}
|
|
58
|
+
return new Response(JSON.stringify({ success: true, data: { id: importId, status: "pending" } }), {
|
|
59
|
+
status: 200,
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
try {
|
|
63
|
+
const tool = tools(["audience:write"]).migma_import_contacts_from_provider;
|
|
64
|
+
const sources = [{ id: "seg-1", type: "segment", name: "VIP" }];
|
|
65
|
+
const args = tool.inputSchema.parse({
|
|
66
|
+
provider: "mailchimp",
|
|
67
|
+
sources,
|
|
68
|
+
consentMode: "include-all",
|
|
69
|
+
idempotency_key: "import-1",
|
|
70
|
+
wait: false,
|
|
71
|
+
});
|
|
72
|
+
const result = await tool.handler(args);
|
|
73
|
+
assert.equal(calls[0][0], "https://api.test/v1/contacts/imports/provider");
|
|
74
|
+
assert.equal(calls[0][1].method, "POST");
|
|
75
|
+
const headers = calls[0][1].headers;
|
|
76
|
+
assert.equal(headers["Idempotency-Key"], "import-1");
|
|
77
|
+
assert.equal(headers["Content-Type"], "application/json");
|
|
78
|
+
assert.deepEqual(JSON.parse(String(calls[0][1].body)), {
|
|
79
|
+
projectId,
|
|
80
|
+
provider: "mailchimp",
|
|
81
|
+
sources,
|
|
82
|
+
consentMode: "include-all",
|
|
83
|
+
});
|
|
84
|
+
assert.equal(calls.length, 1);
|
|
85
|
+
const payload = JSON.parse(result.content[0].text);
|
|
86
|
+
assert.equal(payload.status, "pending");
|
|
87
|
+
assert.match(payload.hint, /migma_get_contact_import/);
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
globalThis.fetch = original;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
//# sourceMappingURL=provider-imports.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-imports.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/provider-imports.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-annotations.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/review-annotations.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
4
|
+
import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
|
|
5
|
+
import { createMigmaMcpServer, createOpenAIMcpServer } from "../../index.js";
|
|
6
|
+
import { getToolReviewAnnotations } from "../capabilities.js";
|
|
7
|
+
const config = { apiKey: "test", projectId: "0123456789abcdef01234567", baseUrl: "https://api.example.test/v1" };
|
|
8
|
+
function registry(client = {}) {
|
|
9
|
+
return createMigmaMcpServer({ client: client, config })._registeredTools;
|
|
10
|
+
}
|
|
11
|
+
// Independent expectations from backend behavior, in order:
|
|
12
|
+
// read-only, destructive, idempotent, open-world. Include indirect effects.
|
|
13
|
+
const expected = {
|
|
14
|
+
migma_update_brand_guidelines: [false, true, false, false], // Replaces standing rules; undo does not make it additive.
|
|
15
|
+
migma_add_contact: [false, true, false, true], // Email upsert + webhook notification on each unkeyed call.
|
|
16
|
+
migma_bulk_import_contacts: [false, true, false, true], // Upserts + new bulk job/notification on repetition.
|
|
17
|
+
migma_create_contact_import: [false, true, false, true], // Default CSV upsert + completion webhook.
|
|
18
|
+
migma_list_provider_import_sources: [true, false, true, true], // Reads connected Klaviyo/Mailchimp/HubSpot APIs without changing contacts.
|
|
19
|
+
migma_import_contacts_from_provider: [false, true, false, true], // External provider reads + upserts + new job + completion webhook.
|
|
20
|
+
migma_remove_contact: [false, true, false, true], // Delete + subscriber webhook.
|
|
21
|
+
migma_archive_campaign: [false, true, false, false], // Cancels active/scheduled delivery before hiding.
|
|
22
|
+
migma_unarchive_campaign: [false, false, false, false], // Visibility only; does not restart delivery.
|
|
23
|
+
migma_validate_email: [true, false, true, true], // Default link check requests public href/src URLs.
|
|
24
|
+
migma_validate_compatibility: [true, false, true, false], // No link-check branch.
|
|
25
|
+
migma_validate_deliverability: [true, false, true, false], // Text heuristic; no link-check branch.
|
|
26
|
+
migma_send_email: [false, true, false, true], // Optional key; new send identity without it.
|
|
27
|
+
migma_create_campaign: [false, false, false, false], // Optional key; creates another draft without it.
|
|
28
|
+
migma_send_campaign: [false, true, true, true], // Atomic campaign claim guards repeated sends independently of key.
|
|
29
|
+
migma_schedule_campaign: [false, true, false, true], // scheduled -> scheduled is allowed; replaces queue job.
|
|
30
|
+
migma_import_brand: [false, true, false, true], // Public website + irreversible configured webhook notification.
|
|
31
|
+
migma_generate_email: [false, true, false, true], // Public research/assets + configured webhook notifications.
|
|
32
|
+
migma_import_html: [false, true, false, true], // Renderer assets + configured webhooks + optional key.
|
|
33
|
+
migma_edit_email: [false, true, false, true], // Rewrites content; public renderer assets; fresh key if omitted.
|
|
34
|
+
migma_export_pdf: [false, false, false, true], // Persists export, rendering requests public assets.
|
|
35
|
+
migma_export_png: [false, false, false, true], // Persists export, rendering requests public assets.
|
|
36
|
+
migma_export_html: [false, false, false, false], // Persists export without browser resource fetching.
|
|
37
|
+
migma_export_klaviyo: [false, false, false, false], // All modes transform markup, not browser rendering or ESP sends.
|
|
38
|
+
migma_create_webhook: [false, true, false, true], // Enables automatic outbound event delivery; no immediate test.
|
|
39
|
+
migma_provision_stream: [false, true, false, true], // Existing SES identity can have DKIM restarted.
|
|
40
|
+
migma_setup_domain: [false, true, false, true], // Same existing-provider DKIM path as provision_stream.
|
|
41
|
+
migma_create_contact_export: [false, false, true, false], // Required nonempty replay key; bounded private CSV job.
|
|
42
|
+
};
|
|
43
|
+
test("OpenAI tools/list serializes behavior-based annotations, including indirect effects", async () => {
|
|
44
|
+
const server = createOpenAIMcpServer({ config });
|
|
45
|
+
const client = new Client({ name: "annotation-review", version: "1" });
|
|
46
|
+
const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
47
|
+
try {
|
|
48
|
+
await server.connect(serverTransport);
|
|
49
|
+
await client.connect(clientTransport);
|
|
50
|
+
const { tools } = await client.listTools();
|
|
51
|
+
const wire = new Map(tools.map(tool => [tool.name, tool]));
|
|
52
|
+
assert.equal(tools.length, 73);
|
|
53
|
+
for (const tool of tools) {
|
|
54
|
+
assert.deepEqual(tool.annotations, getToolReviewAnnotations(tool.name), tool.name);
|
|
55
|
+
for (const key of ["readOnlyHint", "destructiveHint", "idempotentHint", "openWorldHint"]) {
|
|
56
|
+
assert.equal(typeof tool.annotations?.[key], "boolean", `${tool.name}.${key}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
for (const [name, [readOnlyHint, destructiveHint, idempotentHint, openWorldHint]] of Object.entries(expected)) {
|
|
60
|
+
assert.deepEqual(wire.get(name)?.annotations, { readOnlyHint, destructiveHint, idempotentHint, openWorldHint }, name);
|
|
61
|
+
}
|
|
62
|
+
assert.match(wire.get("migma_add_contact")?.description ?? "", /[Cc]reate or update.*overwrite/);
|
|
63
|
+
assert.match(wire.get("migma_bulk_import_contacts")?.description ?? "", /overwritten/);
|
|
64
|
+
assert.match(wire.get("migma_archive_campaign")?.description ?? "", /[Cc]ancels active or scheduled delivery/);
|
|
65
|
+
assert.match(wire.get("migma_unarchive_campaign")?.description ?? "", /[Dd]oes not resume/);
|
|
66
|
+
assert.match(wire.get("migma_validate_email")?.description ?? "", /request URLs/);
|
|
67
|
+
assert.match(wire.get("migma_create_webhook")?.description ?? "", /creation sends no test/);
|
|
68
|
+
assert.match(wire.get("migma_setup_domain")?.description ?? "", /send\.<rootDomain> \(marketing\)/);
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
await client.close();
|
|
72
|
+
await server.close();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
test("optional replay keys remain optional, while unkeyed writes do not claim idempotence", async () => {
|
|
76
|
+
const calls = {};
|
|
77
|
+
const record = (name) => async (...args) => {
|
|
78
|
+
(calls[name] ??= []).push(args);
|
|
79
|
+
return { data: { id: "result", conversationId: "conversation", status: "pending" } };
|
|
80
|
+
};
|
|
81
|
+
const tools = registry({
|
|
82
|
+
sending: { send: record("send") },
|
|
83
|
+
campaigns: { create: record("campaign"), schedule: record("schedule") },
|
|
84
|
+
emails: { importHtml: record("import"), startEdit: record("edit") },
|
|
85
|
+
contacts: { create: record("contact"), bulkImport: record("bulk") },
|
|
86
|
+
});
|
|
87
|
+
const cases = [
|
|
88
|
+
{ tool: "migma_send_email", call: "send", args: { recipientType: "email", recipientEmail: "test@example.com", from: "hello@example.com", fromName: "Example", subject: "Hello", emailId: "email-1" } },
|
|
89
|
+
{ tool: "migma_create_campaign", call: "campaign", args: { name: "Hello", conversationId: "conversation", from: "hello@example.com", fromName: "Example", recipientType: "tag", recipientId: "tag-1" } },
|
|
90
|
+
{ tool: "migma_schedule_campaign", call: "schedule", args: { campaignId: "campaign-1", scheduledAt: "2030-01-01T12:00:00Z" } },
|
|
91
|
+
{ tool: "migma_import_html", call: "import", args: { html: "<p>Hello</p>" } },
|
|
92
|
+
{ tool: "migma_edit_email", call: "edit", args: { emailId: "email-1", prompt: "Change title" } },
|
|
93
|
+
{ tool: "migma_add_contact", call: "contact", args: { email: "test@example.com", firstName: "New" } },
|
|
94
|
+
{ tool: "migma_bulk_import_contacts", call: "bulk", args: { subscribers: [{ email: "test@example.com", firstName: "New" }] } },
|
|
95
|
+
];
|
|
96
|
+
for (const { tool, call, args } of cases) {
|
|
97
|
+
assert.equal(tools[tool].inputSchema.safeParse(args).success, true, tool);
|
|
98
|
+
assert.equal(tools[tool].annotations.idempotentHint, false, tool);
|
|
99
|
+
await tools[tool].handler(args);
|
|
100
|
+
await tools[tool].handler(args);
|
|
101
|
+
assert.equal(calls[call].length, 2, tool);
|
|
102
|
+
const options = calls[call].map(row => row.at(-1));
|
|
103
|
+
if (call === "edit") {
|
|
104
|
+
const keys = options;
|
|
105
|
+
assert.ok(keys[0].idempotencyKey);
|
|
106
|
+
assert.notEqual(keys[0].idempotencyKey, keys[1].idempotencyKey, "unkeyed edits allocate new replay identities");
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
assert.deepEqual(options, [undefined, undefined], `${tool} has no replay identity without a key`);
|
|
110
|
+
}
|
|
111
|
+
await tools[tool].handler({ ...args, idempotency_key: "stable-key" });
|
|
112
|
+
assert.deepEqual(calls[call][2].at(-1), { idempotencyKey: "stable-key" }, `${tool} preserves supported keyed retries`);
|
|
113
|
+
}
|
|
114
|
+
assert.equal(tools.migma_create_contact_export.inputSchema.safeParse({}).success, false);
|
|
115
|
+
assert.equal(tools.migma_create_contact_export.inputSchema.safeParse({ idempotency_key: "" }).success, false);
|
|
116
|
+
assert.equal(tools.migma_create_contact_export.inputSchema.safeParse({ idempotency_key: "stable-key" }).success, true);
|
|
117
|
+
assert.equal(tools.migma_create_contact_export.annotations.idempotentHint, true);
|
|
118
|
+
});
|
|
119
|
+
test("provider import preserves optional replay headers without promising unkeyed repetition safety", async () => {
|
|
120
|
+
const originalFetch = globalThis.fetch;
|
|
121
|
+
const headers = [];
|
|
122
|
+
globalThis.fetch = async (_url, init) => {
|
|
123
|
+
headers.push(new Headers(init?.headers));
|
|
124
|
+
return new Response(JSON.stringify({ success: true, data: { id: `import-${headers.length}`, status: "pending" } }));
|
|
125
|
+
};
|
|
126
|
+
try {
|
|
127
|
+
const tool = registry().migma_import_contacts_from_provider;
|
|
128
|
+
const args = { provider: "klaviyo", sources: [{ id: "list-1", type: "list", name: "Customers" }], wait: false };
|
|
129
|
+
assert.equal(tool.inputSchema.safeParse(args).success, true);
|
|
130
|
+
assert.equal(tool.annotations.idempotentHint, false);
|
|
131
|
+
await tool.handler(args);
|
|
132
|
+
await tool.handler(args);
|
|
133
|
+
await tool.handler({ ...args, idempotency_key: "same-import" });
|
|
134
|
+
assert.deepEqual(headers.map(value => value.get("Idempotency-Key")), [null, null, "same-import"]);
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
globalThis.fetch = originalFetch;
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
//# sourceMappingURL=review-annotations.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-annotations.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/review-annotations.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -47,6 +47,13 @@ export declare const DESTRUCTIVE_TOOL: {
|
|
|
47
47
|
idempotentHint?: boolean | undefined;
|
|
48
48
|
openWorldHint?: boolean | undefined;
|
|
49
49
|
};
|
|
50
|
+
export declare const IDEMPOTENT_DESTRUCTIVE_TOOL: {
|
|
51
|
+
title?: string | undefined;
|
|
52
|
+
readOnlyHint?: boolean | undefined;
|
|
53
|
+
destructiveHint?: boolean | undefined;
|
|
54
|
+
idempotentHint?: boolean | undefined;
|
|
55
|
+
openWorldHint?: boolean | undefined;
|
|
56
|
+
};
|
|
50
57
|
export declare const OPEN_WORLD_DESTRUCTIVE_TOOL: {
|
|
51
58
|
title?: string | undefined;
|
|
52
59
|
readOnlyHint?: boolean | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotations.d.ts","sourceRoot":"","sources":["../../src/tools/annotations.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,cAAc;;;;;;CAAwC,CAAC;AACpE,eAAO,MAAM,yBAAyB;;;;;;CAAuC,CAAC;AAC9E,eAAO,MAAM,aAAa;;;;;;CAA0C,CAAC;AACrE,eAAO,MAAM,wBAAwB;;;;;;CAAyC,CAAC;AAC/E,eAAO,MAAM,wBAAwB;;;;;;CAAyC,CAAC;AAC/E,eAAO,MAAM,mCAAmC;;;;;;CAK/C,CAAC;AACF,eAAO,MAAM,gBAAgB;;;;;;CAAyC,CAAC;AACvE,eAAO,MAAM,2BAA2B;;;;;;CAAwC,CAAC;AACjF,eAAO,MAAM,sCAAsC;;;;;;CAKlD,CAAC"}
|
|
1
|
+
{"version":3,"file":"annotations.d.ts","sourceRoot":"","sources":["../../src/tools/annotations.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,cAAc;;;;;;CAAwC,CAAC;AACpE,eAAO,MAAM,yBAAyB;;;;;;CAAuC,CAAC;AAC9E,eAAO,MAAM,aAAa;;;;;;CAA0C,CAAC;AACrE,eAAO,MAAM,wBAAwB;;;;;;CAAyC,CAAC;AAC/E,eAAO,MAAM,wBAAwB;;;;;;CAAyC,CAAC;AAC/E,eAAO,MAAM,mCAAmC;;;;;;CAK/C,CAAC;AACF,eAAO,MAAM,gBAAgB;;;;;;CAAyC,CAAC;AACvE,eAAO,MAAM,2BAA2B;;;;;;CAAwC,CAAC;AACjF,eAAO,MAAM,2BAA2B;;;;;;CAAwC,CAAC;AACjF,eAAO,MAAM,sCAAsC;;;;;;CAKlD,CAAC"}
|
|
@@ -14,6 +14,7 @@ export const IDEMPOTENT_MUTATING_TOOL = annotations(false, false, true, false);
|
|
|
14
14
|
export const OPEN_WORLD_MUTATING_TOOL = annotations(false, false, false, true);
|
|
15
15
|
export const IDEMPOTENT_OPEN_WORLD_MUTATING_TOOL = annotations(false, false, true, true);
|
|
16
16
|
export const DESTRUCTIVE_TOOL = annotations(false, true, false, false);
|
|
17
|
+
export const IDEMPOTENT_DESTRUCTIVE_TOOL = annotations(false, true, true, false);
|
|
17
18
|
export const OPEN_WORLD_DESTRUCTIVE_TOOL = annotations(false, true, false, true);
|
|
18
19
|
export const IDEMPOTENT_OPEN_WORLD_DESTRUCTIVE_TOOL = annotations(false, true, true, true);
|
|
19
20
|
//# sourceMappingURL=annotations.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../src/tools/annotations.ts"],"names":[],"mappings":"AAEA,SAAS,WAAW,CAClB,YAAqB,EACrB,eAAwB,EACxB,cAAuB,EACvB,aAAsB;IAEtB,OAAO;QACL,YAAY;QACZ,eAAe;QACf,cAAc;QACd,aAAa;KACd,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AACpE,MAAM,CAAC,MAAM,yBAAyB,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,wBAAwB,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AAC/E,MAAM,CAAC,MAAM,wBAAwB,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;AAC/E,MAAM,CAAC,MAAM,mCAAmC,GAAG,WAAW,CAC5D,KAAK,EACL,KAAK,EACL,IAAI,EACJ,IAAI,CACL,CAAC;AACF,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AACvE,MAAM,CAAC,MAAM,2BAA2B,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;AACjF,MAAM,CAAC,MAAM,sCAAsC,GAAG,WAAW,CAC/D,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,IAAI,CACL,CAAC"}
|
|
1
|
+
{"version":3,"file":"annotations.js","sourceRoot":"","sources":["../../src/tools/annotations.ts"],"names":[],"mappings":"AAEA,SAAS,WAAW,CAClB,YAAqB,EACrB,eAAwB,EACxB,cAAuB,EACvB,aAAsB;IAEtB,OAAO;QACL,YAAY;QACZ,eAAe;QACf,cAAc;QACd,aAAa;KACd,CAAC;AACJ,CAAC;AAED,iFAAiF;AACjF,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AACpE,MAAM,CAAC,MAAM,yBAAyB,GAAG,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,wBAAwB,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AAC/E,MAAM,CAAC,MAAM,wBAAwB,GAAG,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;AAC/E,MAAM,CAAC,MAAM,mCAAmC,GAAG,WAAW,CAC5D,KAAK,EACL,KAAK,EACL,IAAI,EACJ,IAAI,CACL,CAAC;AACF,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AACvE,MAAM,CAAC,MAAM,2BAA2B,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AACjF,MAAM,CAAC,MAAM,2BAA2B,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;AACjF,MAAM,CAAC,MAAM,sCAAsC,GAAG,WAAW,CAC/D,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,IAAI,CACL,CAAC"}
|
package/build/tools/billing.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { canUse } from "../permissions.js";
|
|
3
3
|
import { isToolInProfile } from "../profiles.js";
|
|
4
|
-
import {
|
|
4
|
+
import { OPEN_WORLD_DESTRUCTIVE_TOOL, READ_ONLY_TOOL } from "./annotations.js";
|
|
5
5
|
const UPGRADE_PLANS = [
|
|
6
6
|
"basic",
|
|
7
7
|
"premium",
|
|
@@ -25,14 +25,14 @@ export function registerBillingTools(server, client, grantedPermissions, profile
|
|
|
25
25
|
}
|
|
26
26
|
if (isToolInProfile("migma_get_upgrade_link", profile) && canUse(grantedPermissions, ["billing:write"])) {
|
|
27
27
|
server.registerTool("migma_get_upgrade_link", {
|
|
28
|
-
title: "Get
|
|
29
|
-
annotations:
|
|
30
|
-
description: "
|
|
28
|
+
title: "Get Billing Link",
|
|
29
|
+
annotations: OPEN_WORLD_DESTRUCTIVE_TOOL,
|
|
30
|
+
description: "Get a Migma checkout or billing-portal URL after the user asks to subscribe or manage billing, including accepting a relevant offer when credits block their task. For existing subscribers, omit plan so they review changes in the billing portal. For new subscribers, pass only the plan the user chose. Passing plan for an existing subscription can change it and charge a prorated payment immediately; require explicit approval for that charge before doing so. Show the returned link once. Never invent prices, automatically retry an unknown billing write, or claim payment completed from a link; recheck credits before resuming blocked work.",
|
|
31
31
|
inputSchema: z.object({
|
|
32
32
|
plan: z
|
|
33
33
|
.enum(UPGRADE_PLANS)
|
|
34
34
|
.optional()
|
|
35
|
-
.describe("
|
|
35
|
+
.describe("User-chosen plan for new subscription checkout. Omit for an existing subscriber's billing portal. Passing a plan for an existing subscription can change it and charge immediately; needs explicit charge approval. Never choose a plan for the user."),
|
|
36
36
|
}),
|
|
37
37
|
}, async (args) => {
|
|
38
38
|
const { data, error } = await client.billing.upgradeLink({ plan: args.plan });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billing.js","sourceRoot":"","sources":["../../src/tools/billing.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAwB,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"billing.js","sourceRoot":"","sources":["../../src/tools/billing.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAwB,MAAM,gBAAgB,CAAC;AACvE,OAAO,EAAE,2BAA2B,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/E,MAAM,aAAa,GAAG;IACpB,OAAO;IACP,SAAS;IACT,UAAU;IACV,cAAc;IACd,gBAAgB;IAChB,iBAAiB;CACT,CAAC;AAEX,MAAM,UAAU,oBAAoB,CAClC,MAAiB,EACjB,MAAa,EACb,kBAA6B,EAC7B,UAA2B,SAAS;IAEpC,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;QACjD,MAAM,CAAC,YAAY,CACjB,mBAAmB,EACnB;YACE,KAAK,EAAE,oBAAoB;YAC3B,WAAW,EAAE,cAAc;YAC3B,WAAW,EACT,4LAA4L;SAC/L,EACD,KAAK,IAAI,EAAE;YACT,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YACvD,IAAI,KAAK;gBAAE,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC3C,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC,CACF,CAAC;IACJ,CAAC;IAED,IAAI,eAAe,CAAC,wBAAwB,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC;QACxG,MAAM,CAAC,YAAY,CACjB,wBAAwB,EACxB;YACE,KAAK,EAAE,kBAAkB;YACzB,WAAW,EAAE,2BAA2B;YACxC,WAAW,EACT,koBAAkoB;YACpoB,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;gBACpB,IAAI,EAAE,CAAC;qBACJ,IAAI,CAAC,aAAa,CAAC;qBACnB,QAAQ,EAAE;qBACV,QAAQ,CACP,uPAAuP,CACxP;aACJ,CAAC;SACH,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;YACb,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAC9E,IAAI,KAAK;gBAAE,OAAO,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC3C,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC,CACF,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAa;IAC/B,OAAO;QACL,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;SAC/D;KACF,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,OAAe;IAChC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QACnD,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
|
package/build/tools/brand.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { canUse } from "../permissions.js";
|
|
3
|
-
import { MUTATING_TOOL } from "./annotations.js";
|
|
3
|
+
import { DESTRUCTIVE_TOOL, MUTATING_TOOL } from "./annotations.js";
|
|
4
4
|
const CONTENT_MAX = 15_000;
|
|
5
5
|
const INSTRUCTIONS_MAX = 20_000;
|
|
6
6
|
const NOTES_MAX = 500;
|
|
@@ -31,8 +31,8 @@ export function registerBrandTools(server, client, config, grantedPermissions) {
|
|
|
31
31
|
const brandClient = client;
|
|
32
32
|
server.registerTool("migma_update_brand_guidelines", {
|
|
33
33
|
title: "Update Brand Guidelines",
|
|
34
|
-
annotations:
|
|
35
|
-
description: "
|
|
34
|
+
annotations: DESTRUCTIVE_TOOL,
|
|
35
|
+
description: "Replace lasting brand rules or image style notes. For lasting changes only, not one email. Read migma_get_project first; pass the complete instructions, keeping unchanged rules. Empty instructions clear all rules only if requested. Migma snapshots the previous version for undo.",
|
|
36
36
|
inputSchema: z
|
|
37
37
|
.object({
|
|
38
38
|
projectId: z
|
package/build/tools/brand.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brand.js","sourceRoot":"","sources":["../../src/tools/brand.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"brand.js","sourceRoot":"","sources":["../../src/tools/brand.ts"],"names":[],"mappings":"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"}
|
package/build/tools/campaigns.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { canUse } from "../permissions.js";
|
|
3
|
-
import { DESTRUCTIVE_TOOL,
|
|
3
|
+
import { DESTRUCTIVE_TOOL, IDEMPOTENT_OPEN_WORLD_DESTRUCTIVE_TOOL, MUTATING_TOOL, OPEN_WORLD_DESTRUCTIVE_TOOL, READ_ONLY_TOOL } from "./annotations.js";
|
|
4
4
|
export function registerCampaignTools(server, client, config, grantedPermissions) {
|
|
5
5
|
if (canUse(grantedPermissions, ["campaign:read"])) {
|
|
6
6
|
server.registerTool("migma_list_campaigns", {
|
|
@@ -41,8 +41,8 @@ export function registerCampaignTools(server, client, config, grantedPermissions
|
|
|
41
41
|
if (canUse(grantedPermissions, ["campaign:write"])) {
|
|
42
42
|
server.registerTool("migma_create_campaign", {
|
|
43
43
|
title: "Create Campaign",
|
|
44
|
-
annotations:
|
|
45
|
-
description: "
|
|
44
|
+
annotations: MUTATING_TOOL,
|
|
45
|
+
description: "Save a campaign draft from an existing emailId. Sends nothing; deliver with migma_send_campaign or migma_schedule_campaign. Use migma_generate_email for new designs. Reuse idempotency_key after uncertainty; retries without it can create duplicate drafts.",
|
|
46
46
|
inputSchema: z.object({
|
|
47
47
|
projectId: z
|
|
48
48
|
.string()
|
|
@@ -123,7 +123,7 @@ export function registerCampaignTools(server, client, config, grantedPermissions
|
|
|
123
123
|
server.registerTool("migma_send_campaign", {
|
|
124
124
|
title: "Send Campaign",
|
|
125
125
|
annotations: IDEMPOTENT_OPEN_WORLD_DESTRUCTIVE_TOOL,
|
|
126
|
-
description: "Send a draft or scheduled campaign immediately. The campaign must be in 'draft' or 'scheduled' status.",
|
|
126
|
+
description: "Send a draft or scheduled campaign immediately. The campaign must be in 'draft' or 'scheduled' status. Require explicit approval of audience, count, sender, subject, timing, and final preview. For future delivery use migma_schedule_campaign instead. Report the returned state; accepted or queued is not proof of delivered email.",
|
|
127
127
|
inputSchema: z.object({
|
|
128
128
|
campaignId: z.string().describe("Campaign ID to send"),
|
|
129
129
|
idempotency_key: z
|
|
@@ -142,8 +142,8 @@ export function registerCampaignTools(server, client, config, grantedPermissions
|
|
|
142
142
|
if (canUse(grantedPermissions, ["campaign:write"])) {
|
|
143
143
|
server.registerTool("migma_schedule_campaign", {
|
|
144
144
|
title: "Schedule Campaign",
|
|
145
|
-
annotations:
|
|
146
|
-
description: "Schedule
|
|
145
|
+
annotations: OPEN_WORLD_DESTRUCTIVE_TOOL,
|
|
146
|
+
description: "Schedule future delivery or replace an existing schedule. Get explicit approval of final preview, audience, count, sender, subject, date, time, and timezone. Resolve ambiguous dates first. Reuse idempotency_key after uncertainty; unkeyed retries replace the queued job. Say 'Scheduled' only after the saved schedule is confirmed; scheduling is not delivery.",
|
|
147
147
|
inputSchema: z.object({
|
|
148
148
|
campaignId: z.string().describe("Campaign ID to schedule"),
|
|
149
149
|
scheduledAt: z
|
|
@@ -236,8 +236,8 @@ export function registerCampaignTools(server, client, config, grantedPermissions
|
|
|
236
236
|
if (canUse(grantedPermissions, ["campaign:write"])) {
|
|
237
237
|
server.registerTool("migma_archive_campaign", {
|
|
238
238
|
title: "Archive Campaign",
|
|
239
|
-
annotations:
|
|
240
|
-
description: "
|
|
239
|
+
annotations: DESTRUCTIVE_TOOL,
|
|
240
|
+
description: "Hide a campaign from the default list. Cancels active or scheduled delivery first. Unarchiving does not resume cancelled delivery.",
|
|
241
241
|
inputSchema: z.object({
|
|
242
242
|
campaignId: z.string().describe("Campaign ID to archive"),
|
|
243
243
|
}),
|
|
@@ -253,7 +253,7 @@ export function registerCampaignTools(server, client, config, grantedPermissions
|
|
|
253
253
|
server.registerTool("migma_unarchive_campaign", {
|
|
254
254
|
title: "Unarchive Campaign",
|
|
255
255
|
annotations: MUTATING_TOOL,
|
|
256
|
-
description: "
|
|
256
|
+
description: "Restore an archived campaign to the default list. Does not resume cancelled delivery.",
|
|
257
257
|
inputSchema: z.object({
|
|
258
258
|
campaignId: z.string().describe("Campaign ID to unarchive"),
|
|
259
259
|
}),
|