@migma/mcp 1.9.0 → 1.9.1-automations.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 (76) hide show
  1. package/README.md +22 -18
  2. package/build/index.d.ts.map +1 -1
  3. package/build/index.js +11 -3
  4. package/build/index.js.map +1 -1
  5. package/build/prompts/index.d.ts +1 -0
  6. package/build/prompts/index.d.ts.map +1 -1
  7. package/build/prompts/index.js +20 -5
  8. package/build/prompts/index.js.map +1 -1
  9. package/build/tools/__tests__/automations.test.d.ts +2 -0
  10. package/build/tools/__tests__/automations.test.d.ts.map +1 -0
  11. package/build/tools/__tests__/automations.test.js +259 -0
  12. package/build/tools/__tests__/automations.test.js.map +1 -0
  13. package/build/tools/__tests__/brand.test.js +0 -25
  14. package/build/tools/__tests__/brand.test.js.map +1 -1
  15. package/build/tools/__tests__/campaign-recipients.test.js +2 -5
  16. package/build/tools/__tests__/campaign-recipients.test.js.map +1 -1
  17. package/build/tools/__tests__/catalog.test.js +20 -26
  18. package/build/tools/__tests__/catalog.test.js.map +1 -1
  19. package/build/tools/__tests__/forms.test.d.ts +2 -0
  20. package/build/tools/__tests__/forms.test.d.ts.map +1 -0
  21. package/build/tools/__tests__/forms.test.js +127 -0
  22. package/build/tools/__tests__/forms.test.js.map +1 -0
  23. package/build/tools/__tests__/provider-imports.test.js +0 -23
  24. package/build/tools/__tests__/provider-imports.test.js.map +1 -1
  25. package/build/tools/__tests__/review-annotations.test.js +10 -4
  26. package/build/tools/__tests__/review-annotations.test.js.map +1 -1
  27. package/build/tools/__tests__/websites.test.d.ts +2 -0
  28. package/build/tools/__tests__/websites.test.d.ts.map +1 -0
  29. package/build/tools/__tests__/websites.test.js +138 -0
  30. package/build/tools/__tests__/websites.test.js.map +1 -0
  31. package/build/tools/automations.d.ts +22 -0
  32. package/build/tools/automations.d.ts.map +1 -0
  33. package/build/tools/automations.js +134 -0
  34. package/build/tools/automations.js.map +1 -0
  35. package/build/tools/brand.d.ts.map +1 -1
  36. package/build/tools/brand.js +7 -10
  37. package/build/tools/brand.js.map +1 -1
  38. package/build/tools/campaigns.d.ts +0 -2
  39. package/build/tools/campaigns.d.ts.map +1 -1
  40. package/build/tools/campaigns.js +13 -144
  41. package/build/tools/campaigns.js.map +1 -1
  42. package/build/tools/capabilities.d.ts +3 -1
  43. package/build/tools/capabilities.d.ts.map +1 -1
  44. package/build/tools/capabilities.js +54 -6
  45. package/build/tools/capabilities.js.map +1 -1
  46. package/build/tools/contacts.d.ts.map +1 -1
  47. package/build/tools/contacts.js +15 -30
  48. package/build/tools/contacts.js.map +1 -1
  49. package/build/tools/context.js +1 -1
  50. package/build/tools/context.js.map +1 -1
  51. package/build/tools/forms.d.ts +6 -0
  52. package/build/tools/forms.d.ts.map +1 -0
  53. package/build/tools/forms.js +97 -0
  54. package/build/tools/forms.js.map +1 -0
  55. package/build/tools/generate.js +2 -2
  56. package/build/tools/generate.js.map +1 -1
  57. package/build/tools/send.d.ts.map +1 -1
  58. package/build/tools/send.js +8 -92
  59. package/build/tools/send.js.map +1 -1
  60. package/build/tools/websites.d.ts +4 -0
  61. package/build/tools/websites.d.ts.map +1 -0
  62. package/build/tools/websites.js +114 -0
  63. package/build/tools/websites.js.map +1 -0
  64. package/package.json +3 -3
  65. package/build/tools/__tests__/campaign-schedule.test.d.ts +0 -2
  66. package/build/tools/__tests__/campaign-schedule.test.d.ts.map +0 -1
  67. package/build/tools/__tests__/campaign-schedule.test.js +0 -43
  68. package/build/tools/__tests__/campaign-schedule.test.js.map +0 -1
  69. package/build/tools/__tests__/send-confirmation.test.d.ts +0 -2
  70. package/build/tools/__tests__/send-confirmation.test.d.ts.map +0 -1
  71. package/build/tools/__tests__/send-confirmation.test.js +0 -170
  72. package/build/tools/__tests__/send-confirmation.test.js.map +0 -1
  73. package/build/tools/send-confirmation.d.ts +0 -64
  74. package/build/tools/send-confirmation.d.ts.map +0 -1
  75. package/build/tools/send-confirmation.js +0 -150
  76. package/build/tools/send-confirmation.js.map +0 -1
@@ -1,150 +0,0 @@
1
- import { createHash, createHmac, timingSafeEqual } from "node:crypto";
2
- /**
3
- * Sending is a two-call handshake the server enforces: a call without
4
- * confirmationToken only returns a summary built from live data (audience,
5
- * recipient count, sender, subject, timing) and a short-lived token; mail goes
6
- * out only when the same call is repeated with that token. Each MCP request
7
- * may run on a fresh server instance, so the token is self-validating: an HMAC,
8
- * keyed by the caller's API key, over its expiry and a hash of everything that
9
- * decides who gets what, from whom, and when. Any change in between voids it.
10
- */
11
- export const CONFIRMATION_TTL_MS = 10 * 60_000;
12
- export const CONFIRMATION_TOKEN_DESCRIPTION = "Leave empty first: the call then sends nothing and returns a summary plus confirmationToken. Show the summary to the user; after they approve it in this chat, repeat the same call with the token. The token expires in 10 minutes and stops working if any detail changes.";
13
- function signingKey(apiKey) {
14
- if (!apiKey)
15
- throw new Error("Sending needs a Migma API key.");
16
- return createHash("sha256").update(`migma-mcp-send-confirmation:${apiKey}`).digest();
17
- }
18
- /** JSON with object keys sorted at every level, so a reordered argument hashes the same. */
19
- function canonical(value) {
20
- if (Array.isArray(value))
21
- return `[${value.map(canonical).join(",")}]`;
22
- if (value && typeof value === "object") {
23
- const record = value;
24
- return `{${Object.keys(record).sort().filter((k) => record[k] !== undefined)
25
- .map((k) => `${JSON.stringify(k)}:${canonical(record[k])}`).join(",")}}`;
26
- }
27
- return JSON.stringify(value ?? null);
28
- }
29
- function sign(apiKey, action, expiresAt, facts) {
30
- const hash = createHash("sha256").update(canonical(facts)).digest("hex");
31
- return createHmac("sha256", signingKey(apiKey))
32
- .update(`${action}.${expiresAt}.${hash}`)
33
- .digest("base64url");
34
- }
35
- export function issueConfirmationToken(apiKey, action, facts, now = Date.now()) {
36
- const expiresAt = now + CONFIRMATION_TTL_MS;
37
- return {
38
- token: `${expiresAt}.${sign(apiKey, action, expiresAt, facts)}`,
39
- expiresAt: new Date(expiresAt).toISOString(),
40
- };
41
- }
42
- /** Null when the token was issued for exactly these facts and is still valid, else why not. */
43
- export function checkConfirmationToken(apiKey, token, action, facts, now = Date.now()) {
44
- const [rawExpiry, signature = ""] = token.split(".");
45
- const expiresAt = Number(rawExpiry);
46
- if (!Number.isSafeInteger(expiresAt) || !signature) {
47
- return "confirmationToken is not valid. Call again without it to get a new summary.";
48
- }
49
- if (expiresAt <= now) {
50
- return "confirmationToken expired. Call again without it to get a new summary for the user.";
51
- }
52
- const expected = Buffer.from(sign(apiKey, action, expiresAt, facts));
53
- const given = Buffer.from(signature);
54
- if (expected.length !== given.length || !timingSafeEqual(expected, given)) {
55
- return "Nothing was sent: the details differ from the approved summary, or the token belongs to another send. Call again without confirmationToken to get a new summary.";
56
- }
57
- return null;
58
- }
59
- /** A repeated confirmed call replays the first result instead of sending again. */
60
- export function confirmedIdempotencyKey(token, idempotencyKey) {
61
- return idempotencyKey || `confirm-${createHash("sha256").update(token).digest("hex").slice(0, 48)}`;
62
- }
63
- export function previewResult(apiKey, tool, action, facts, summary) {
64
- const { token, expiresAt } = issueConfirmationToken(apiKey, action, facts);
65
- return {
66
- content: [
67
- {
68
- type: "text",
69
- text: JSON.stringify({
70
- sent: false,
71
- confirmationRequired: true,
72
- summary,
73
- confirmationToken: token,
74
- expiresAt,
75
- next: `Nothing was sent. After the user approves this summary, call ${tool} again with the same arguments and confirmationToken.`,
76
- }, null, 2),
77
- },
78
- ],
79
- };
80
- }
81
- const rootOf = (d) => (d.rootDomain || d.domain).toLowerCase();
82
- const isApex = (d) => !!d.rootDomain && d.rootDomain.toLowerCase() === d.domain.toLowerCase();
83
- /**
84
- * Mirrors the backend's send-time sender resolution (SesTenantService
85
- * resolveSendableFrom, and the transactional identity check in v1 sending):
86
- * a From on a sendable domain or its root sends as is; otherwise Migma sends
87
- * from the account's verified managed domain; with neither, nothing can send.
88
- * Transactional mail needs a verified transactional identity for the From's
89
- * root domain, so unsubscribed contacts are only ever reached through one.
90
- */
91
- export async function checkSender(client, from, options = {}) {
92
- const { data, error } = await client.domains.list();
93
- if (error?.statusCode === 403 && !options.transactional) {
94
- // A send-only connection cannot read domains; the send path still checks the sender.
95
- return { ok: true, from, warnings: ["The sender domain was not checked: this connection cannot read sending domains. Migma checks it when sending."] };
96
- }
97
- if (error)
98
- return { ok: false, error: `Could not check the sender: ${error.message}` };
99
- const domains = (data ?? []);
100
- const fromDomain = (from.split("@")[1] || "").toLowerCase();
101
- const sendable = domains.filter((d) => d.isVerified === true);
102
- const warnings = [];
103
- let effectiveFrom = from;
104
- const matches = (d) => d.domain.toLowerCase() === fromDomain || rootOf(d) === fromDomain;
105
- if (!sendable.some(matches)) {
106
- const managed = domains.find((d) => d.isManagedDomain && d.status === "verified");
107
- if (!managed) {
108
- return {
109
- ok: false,
110
- error: `${fromDomain || from} is not a verified sending domain in this account. Use a From address on a verified domain from migma_list_domains, or set one up first.`,
111
- };
112
- }
113
- effectiveFrom = `${from.includes("@") ? from.split("@")[0] : "noreply"}@${managed.domain}`;
114
- warnings.push(`${fromDomain} is not verified yet, so this sends from ${effectiveFrom}.`);
115
- }
116
- if (options.transactional) {
117
- const effectiveDomain = effectiveFrom.split("@")[1].toLowerCase();
118
- const identity = domains.find((d) => d.domain.toLowerCase() === effectiveDomain);
119
- const root = identity ? rootOf(identity) : effectiveDomain;
120
- const hasTransactionalIdentity = sendable.some((d) => rootOf(d) === root && (isApex(d) || (d.stream === "transactional")));
121
- if (!hasTransactionalIdentity) {
122
- return {
123
- ok: false,
124
- error: `transactional: true needs a verified transactional sending identity for ${root} (notify.${root}). Set it up with migma_provision_stream, or send without transactional so unsubscribes are respected.`,
125
- };
126
- }
127
- }
128
- return { ok: true, from: effectiveFrom, warnings };
129
- }
130
- export function formatWhen(scheduledAt, timezone) {
131
- if (!scheduledAt)
132
- return "Now";
133
- const zone = timezone || "UTC";
134
- try {
135
- const local = new Intl.DateTimeFormat("en-CA", {
136
- timeZone: zone,
137
- year: "numeric",
138
- month: "2-digit",
139
- day: "2-digit",
140
- hour: "2-digit",
141
- minute: "2-digit",
142
- hour12: false,
143
- }).format(new Date(scheduledAt));
144
- return `${local.replace(",", "")} (${zone})`;
145
- }
146
- catch {
147
- return `${scheduledAt} (${zone})`;
148
- }
149
- }
150
- //# sourceMappingURL=send-confirmation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"send-confirmation.js","sourceRoot":"","sources":["../../src/tools/send-confirmation.ts"],"names":[],"mappings":"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"}