@aiwerk/mcp-server-resend 0.1.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/CHANGELOG.md +11 -0
  2. package/LICENSE +21 -0
  3. package/README.md +154 -0
  4. package/dist/src/errors.d.ts +16 -0
  5. package/dist/src/errors.d.ts.map +1 -0
  6. package/dist/src/errors.js +21 -0
  7. package/dist/src/lib/destructive-gate.d.ts +27 -0
  8. package/dist/src/lib/destructive-gate.d.ts.map +1 -0
  9. package/dist/src/lib/destructive-gate.js +72 -0
  10. package/dist/src/lib/idempotency.d.ts +2 -0
  11. package/dist/src/lib/idempotency.d.ts.map +1 -0
  12. package/dist/src/lib/idempotency.js +12 -0
  13. package/dist/src/lib/resend-client.d.ts +13 -0
  14. package/dist/src/lib/resend-client.d.ts.map +1 -0
  15. package/dist/src/lib/resend-client.js +128 -0
  16. package/dist/src/server.d.ts +12 -0
  17. package/dist/src/server.d.ts.map +1 -0
  18. package/dist/src/server.js +400 -0
  19. package/dist/src/tools/apikeys.d.ts +37 -0
  20. package/dist/src/tools/apikeys.d.ts.map +1 -0
  21. package/dist/src/tools/apikeys.js +72 -0
  22. package/dist/src/tools/broadcasts.d.ts +85 -0
  23. package/dist/src/tools/broadcasts.d.ts.map +1 -0
  24. package/dist/src/tools/broadcasts.js +118 -0
  25. package/dist/src/tools/contact-properties.d.ts +47 -0
  26. package/dist/src/tools/contact-properties.d.ts.map +1 -0
  27. package/dist/src/tools/contact-properties.js +80 -0
  28. package/dist/src/tools/contacts.d.ts +137 -0
  29. package/dist/src/tools/contacts.d.ts.map +1 -0
  30. package/dist/src/tools/contacts.js +139 -0
  31. package/dist/src/tools/domains.d.ts +95 -0
  32. package/dist/src/tools/domains.d.ts.map +1 -0
  33. package/dist/src/tools/domains.js +118 -0
  34. package/dist/src/tools/emails.d.ts +214 -0
  35. package/dist/src/tools/emails.d.ts.map +1 -0
  36. package/dist/src/tools/emails.js +142 -0
  37. package/dist/src/tools/logs.d.ts +18 -0
  38. package/dist/src/tools/logs.d.ts.map +1 -0
  39. package/dist/src/tools/logs.js +18 -0
  40. package/dist/src/tools/segments.d.ts +49 -0
  41. package/dist/src/tools/segments.d.ts.map +1 -0
  42. package/dist/src/tools/segments.js +79 -0
  43. package/dist/src/tools/templates.d.ts +113 -0
  44. package/dist/src/tools/templates.d.ts.map +1 -0
  45. package/dist/src/tools/templates.js +113 -0
  46. package/dist/src/tools/topics.d.ts +53 -0
  47. package/dist/src/tools/topics.d.ts.map +1 -0
  48. package/dist/src/tools/topics.js +81 -0
  49. package/dist/src/tools/webhooks.d.ts +49 -0
  50. package/dist/src/tools/webhooks.d.ts.map +1 -0
  51. package/dist/src/tools/webhooks.js +87 -0
  52. package/dist/src/version.d.ts +2 -0
  53. package/dist/src/version.d.ts.map +1 -0
  54. package/dist/src/version.js +2 -0
  55. package/package.json +42 -0
@@ -0,0 +1,118 @@
1
+ import { z } from 'zod';
2
+ import { resendPost, resendGet, resendPatch, resendDelete } from '../lib/resend-client.js';
3
+ import { requireConfirmation, validateAndConsume } from '../lib/destructive-gate.js';
4
+ import { deriveIdempotencyKey } from '../lib/idempotency.js';
5
+ const paginationSchema = {
6
+ limit: z.number().int().min(1).max(100).optional().describe('Max items to return (max 100).'),
7
+ after: z.string().optional().describe('Cursor — return items after this value.'),
8
+ before: z.string().optional().describe('Cursor — return items before this value.'),
9
+ };
10
+ // --- resend_broadcast_create ---
11
+ // Decision #7: send:false HARD-FORCED — we always set send:false regardless of user input.
12
+ export const broadcastCreateInputSchema = {
13
+ from: z.string().describe('Sender address (must be from a verified domain).'),
14
+ subject: z.string().describe('Email subject line.'),
15
+ segment_id: z.string().describe('Segment ID — the broadcast sends to all contacts in this segment.'),
16
+ name: z.string().optional().describe('Internal name for this broadcast.'),
17
+ reply_to: z.array(z.string()).optional().describe('Reply-to address(es).'),
18
+ preview_text: z.string().optional().describe('Preview text shown in email clients before opening.'),
19
+ html: z.string().optional().describe('HTML body.'),
20
+ text: z.string().optional().describe('Plain text body.'),
21
+ topic_id: z.string().optional().describe('Topic to scope the broadcast. Contacts opted out of the topic won\'t receive it.'),
22
+ };
23
+ export async function broadcastCreate(args) {
24
+ // Hard-force send:false — sending is only possible via resend_broadcast_send (α-gated).
25
+ return resendPost('/broadcasts', { ...args, send: false });
26
+ }
27
+ // --- resend_broadcast_list ---
28
+ export const broadcastListInputSchema = paginationSchema;
29
+ export async function broadcastList(args) {
30
+ return resendGet('/broadcasts', args);
31
+ }
32
+ // --- resend_broadcast_get ---
33
+ export const broadcastGetInputSchema = {
34
+ id: z.string().describe('Broadcast ID.'),
35
+ };
36
+ export async function broadcastGet(args) {
37
+ return resendGet(`/broadcasts/${args.id}`);
38
+ }
39
+ // --- resend_broadcast_update ---
40
+ export const broadcastUpdateInputSchema = {
41
+ id: z.string().describe('Broadcast ID to update. Only draft broadcasts can be updated.'),
42
+ name: z.string().optional().describe('New internal name.'),
43
+ segment_id: z.string().optional().describe('New segment ID.'),
44
+ from: z.string().optional().describe('New sender address.'),
45
+ subject: z.string().optional().describe('New subject line.'),
46
+ reply_to: z.array(z.string()).optional().describe('New reply-to address(es).'),
47
+ preview_text: z.string().optional().describe('New preview text.'),
48
+ html: z.string().optional().describe('New HTML body.'),
49
+ text: z.string().optional().describe('New plain text body.'),
50
+ topic_id: z.string().optional().describe('New topic ID.'),
51
+ };
52
+ export async function broadcastUpdate(args) {
53
+ const { id, ...body } = args;
54
+ return resendPatch(`/broadcasts/${id}`, body);
55
+ }
56
+ // --- resend_broadcast_delete (α-gated) ---
57
+ export const broadcastDeleteInputSchema = {
58
+ id: z.string().optional().describe('Broadcast ID to delete (must be in draft status). Provide id or ids.'),
59
+ ids: z.array(z.string()).optional().describe('Multiple broadcast IDs to delete.'),
60
+ confirm_token: z.string().optional().describe('Confirmation token from a previous call.'),
61
+ };
62
+ export async function broadcastDelete(args) {
63
+ const { confirm_token, ...rest } = args;
64
+ const tool = 'resend_broadcast_delete';
65
+ if (!rest.id && (!rest.ids || rest.ids.length === 0)) {
66
+ throw new Error('Provide id (single) or ids (bulk).');
67
+ }
68
+ const isBulk = !!rest.ids;
69
+ const ids = isBulk ? rest.ids : undefined;
70
+ const id = !isBulk ? rest.id : undefined;
71
+ if (!confirm_token) {
72
+ const count = isBulk ? ids.length : 1;
73
+ const preview = isBulk ? ids.slice(0, 3).join(', ') : rest.id;
74
+ return requireConfirmation({
75
+ tool, id, ids, payload: rest,
76
+ summary: `Delete ${count} broadcast draft(s): ${preview}. Irreversible.`,
77
+ });
78
+ }
79
+ const result = validateAndConsume({ confirm_token, tool, id, ids, payload: rest });
80
+ if (!result.valid)
81
+ throw new Error(result.reason);
82
+ if (isBulk) {
83
+ const results = await Promise.allSettled(ids.map(bid => resendDelete(`/broadcasts/${bid}`)));
84
+ const succeeded = [];
85
+ const failed = [];
86
+ results.forEach((r, idx) => {
87
+ if (r.status === 'fulfilled')
88
+ succeeded.push(ids[idx]);
89
+ else
90
+ failed.push({ id: ids[idx], error: String(r.reason) });
91
+ });
92
+ return { succeeded, failed, summary: `${succeeded.length}/${ids.length} succeeded` };
93
+ }
94
+ return resendDelete(`/broadcasts/${rest.id}`);
95
+ }
96
+ // --- resend_broadcast_send (α-gated, idempotency) ---
97
+ export const broadcastSendInputSchema = {
98
+ id: z.string().describe('Broadcast ID to send. Must be in draft status.'),
99
+ scheduled_at: z.string().optional().describe('Schedule for later delivery (ISO 8601). Omit to send immediately.'),
100
+ confirm_token: z.string().optional().describe('Confirmation token from a previous call. Required to execute send.'),
101
+ };
102
+ export async function broadcastSend(args) {
103
+ const { confirm_token, id, ...payload } = args;
104
+ const tool = 'resend_broadcast_send';
105
+ if (!confirm_token) {
106
+ return requireConfirmation({
107
+ tool,
108
+ id,
109
+ payload,
110
+ summary: `Send broadcast ${id}${args.scheduled_at ? ` (scheduled: ${args.scheduled_at})` : ' (immediately)'}. Sends to all contacts in the segment — largest blast radius, irreversible.`,
111
+ });
112
+ }
113
+ const result = validateAndConsume({ confirm_token, tool, id, payload });
114
+ if (!result.valid)
115
+ throw new Error(result.reason);
116
+ const idempotencyKey = deriveIdempotencyKey(tool, { id, ...payload });
117
+ return resendPost(`/broadcasts/${id}/send`, payload, { idempotencyKey });
118
+ }
@@ -0,0 +1,47 @@
1
+ import { z } from 'zod';
2
+ import { type ConfirmationRequired } from '../lib/destructive-gate.js';
3
+ export declare const contactPropertyCreateInputSchema: {
4
+ key: z.ZodString;
5
+ type: z.ZodEnum<["string", "number"]>;
6
+ fallback_value: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
7
+ };
8
+ export declare function contactPropertyCreate(args: {
9
+ key: string;
10
+ type: 'string' | 'number';
11
+ fallback_value?: string | number;
12
+ }): Promise<unknown>;
13
+ export declare const contactPropertyListInputSchema: {
14
+ limit: z.ZodOptional<z.ZodNumber>;
15
+ after: z.ZodOptional<z.ZodString>;
16
+ before: z.ZodOptional<z.ZodString>;
17
+ };
18
+ export declare function contactPropertyList(args: {
19
+ limit?: number;
20
+ after?: string;
21
+ before?: string;
22
+ }): Promise<unknown>;
23
+ export declare const contactPropertyGetInputSchema: {
24
+ id: z.ZodString;
25
+ };
26
+ export declare function contactPropertyGet(args: {
27
+ id: string;
28
+ }): Promise<unknown>;
29
+ export declare const contactPropertyUpdateInputSchema: {
30
+ id: z.ZodString;
31
+ fallback_value: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
32
+ };
33
+ export declare function contactPropertyUpdate(args: {
34
+ id: string;
35
+ fallback_value?: string | number;
36
+ }): Promise<unknown>;
37
+ export declare const contactPropertyDeleteInputSchema: {
38
+ id: z.ZodOptional<z.ZodString>;
39
+ ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
40
+ confirm_token: z.ZodOptional<z.ZodString>;
41
+ };
42
+ export declare function contactPropertyDelete(args: {
43
+ id?: string;
44
+ ids?: string[];
45
+ confirm_token?: string;
46
+ }): Promise<unknown | ConfirmationRequired>;
47
+ //# sourceMappingURL=contact-properties.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contact-properties.d.ts","sourceRoot":"","sources":["../../../src/tools/contact-properties.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAA2C,KAAK,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAUhH,eAAO,MAAM,gCAAgC;;;;CAK5C,CAAC;AAEF,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1E,oBAEA;AAID,eAAO,MAAM,8BAA8B;;;;CAAmB,CAAC;AAE/D,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,oBAElG;AAID,eAAO,MAAM,6BAA6B;;CAEzC,CAAC;AAEF,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,oBAE5D;AAID,eAAO,MAAM,gCAAgC;;;CAI5C,CAAC;AAEF,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,oBAGjG;AAID,eAAO,MAAM,gCAAgC;;;;CAI5C,CAAC;AAEF,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACrD,GAAG,OAAO,CAAC,OAAO,GAAG,oBAAoB,CAAC,CAoC1C"}
@@ -0,0 +1,80 @@
1
+ import { z } from 'zod';
2
+ import { resendPost, resendGet, resendPatch, resendDelete } from '../lib/resend-client.js';
3
+ import { requireConfirmation, validateAndConsume } from '../lib/destructive-gate.js';
4
+ const paginationSchema = {
5
+ limit: z.number().int().min(1).max(100).optional().describe('Max items to return (max 100).'),
6
+ after: z.string().optional().describe('Cursor — return items after this value.'),
7
+ before: z.string().optional().describe('Cursor — return items before this value.'),
8
+ };
9
+ // --- resend_contactproperty_create ---
10
+ export const contactPropertyCreateInputSchema = {
11
+ key: z.string().describe('Property key (max 50 chars, alphanumeric + underscores, e.g. "plan_tier").'),
12
+ type: z.enum(['string', 'number']).describe('Property data type: "string" or "number".'),
13
+ fallback_value: z.union([z.string(), z.number()]).optional()
14
+ .describe('Default value when the contact has no value for this property. Must match the type.'),
15
+ };
16
+ export async function contactPropertyCreate(args) {
17
+ return resendPost('/contact-properties', args);
18
+ }
19
+ // --- resend_contactproperty_list ---
20
+ export const contactPropertyListInputSchema = paginationSchema;
21
+ export async function contactPropertyList(args) {
22
+ return resendGet('/contact-properties', args);
23
+ }
24
+ // --- resend_contactproperty_get ---
25
+ export const contactPropertyGetInputSchema = {
26
+ id: z.string().describe('Contact property ID.'),
27
+ };
28
+ export async function contactPropertyGet(args) {
29
+ return resendGet(`/contact-properties/${args.id}`);
30
+ }
31
+ // --- resend_contactproperty_update ---
32
+ export const contactPropertyUpdateInputSchema = {
33
+ id: z.string().describe('Contact property ID to update.'),
34
+ fallback_value: z.union([z.string(), z.number()]).optional()
35
+ .describe('New default fallback value. Must match the property type (string or number).'),
36
+ };
37
+ export async function contactPropertyUpdate(args) {
38
+ const { id, ...body } = args;
39
+ return resendPatch(`/contact-properties/${id}`, body);
40
+ }
41
+ // --- resend_contactproperty_delete (α-gated, bulk) ---
42
+ export const contactPropertyDeleteInputSchema = {
43
+ id: z.string().optional().describe('Contact property ID to delete. Provide id or ids.'),
44
+ ids: z.array(z.string()).optional().describe('Multiple contact property IDs to delete.'),
45
+ confirm_token: z.string().optional().describe('Confirmation token from a previous call.'),
46
+ };
47
+ export async function contactPropertyDelete(args) {
48
+ const { confirm_token, ...rest } = args;
49
+ const tool = 'resend_contactproperty_delete';
50
+ if (!rest.id && (!rest.ids || rest.ids.length === 0)) {
51
+ throw new Error('Provide id (single) or ids (bulk).');
52
+ }
53
+ const isBulk = !!rest.ids;
54
+ const ids = isBulk ? rest.ids : undefined;
55
+ const id = !isBulk ? rest.id : undefined;
56
+ if (!confirm_token) {
57
+ const count = isBulk ? ids.length : 1;
58
+ const preview = isBulk ? ids.slice(0, 3).join(', ') : rest.id;
59
+ return requireConfirmation({
60
+ tool, id, ids, payload: rest,
61
+ summary: `Delete ${count} contact property(ies): ${preview}. Removes custom field definition — irreversible.`,
62
+ });
63
+ }
64
+ const result = validateAndConsume({ confirm_token, tool, id, ids, payload: rest });
65
+ if (!result.valid)
66
+ throw new Error(result.reason);
67
+ if (isBulk) {
68
+ const results = await Promise.allSettled(ids.map(pid => resendDelete(`/contact-properties/${pid}`)));
69
+ const succeeded = [];
70
+ const failed = [];
71
+ results.forEach((r, idx) => {
72
+ if (r.status === 'fulfilled')
73
+ succeeded.push(ids[idx]);
74
+ else
75
+ failed.push({ id: ids[idx], error: String(r.reason) });
76
+ });
77
+ return { succeeded, failed, summary: `${succeeded.length}/${ids.length} succeeded` };
78
+ }
79
+ return resendDelete(`/contact-properties/${rest.id}`);
80
+ }
@@ -0,0 +1,137 @@
1
+ import { z } from 'zod';
2
+ import { type ConfirmationRequired } from '../lib/destructive-gate.js';
3
+ export declare const contactCreateInputSchema: {
4
+ email: z.ZodString;
5
+ first_name: z.ZodOptional<z.ZodString>;
6
+ last_name: z.ZodOptional<z.ZodString>;
7
+ unsubscribed: z.ZodOptional<z.ZodBoolean>;
8
+ properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
9
+ segments: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
10
+ topics: z.ZodOptional<z.ZodArray<z.ZodObject<{
11
+ id: z.ZodString;
12
+ subscription: z.ZodEnum<["opt_in", "opt_out"]>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ id: string;
15
+ subscription: "opt_in" | "opt_out";
16
+ }, {
17
+ id: string;
18
+ subscription: "opt_in" | "opt_out";
19
+ }>, "many">>;
20
+ };
21
+ export declare function contactCreate(args: {
22
+ email: string;
23
+ first_name?: string;
24
+ last_name?: string;
25
+ unsubscribed?: boolean;
26
+ properties?: Record<string, unknown>;
27
+ segments?: string[];
28
+ topics?: Array<{
29
+ id: string;
30
+ subscription: 'opt_in' | 'opt_out';
31
+ }>;
32
+ }): Promise<unknown>;
33
+ export declare const contactListInputSchema: {
34
+ segment_id: z.ZodOptional<z.ZodString>;
35
+ limit: z.ZodOptional<z.ZodNumber>;
36
+ after: z.ZodOptional<z.ZodString>;
37
+ before: z.ZodOptional<z.ZodString>;
38
+ };
39
+ export declare function contactList(args: {
40
+ limit?: number;
41
+ after?: string;
42
+ before?: string;
43
+ segment_id?: string;
44
+ }): Promise<unknown>;
45
+ export declare const contactGetInputSchema: {
46
+ id: z.ZodString;
47
+ };
48
+ export declare function contactGet(args: {
49
+ id: string;
50
+ }): Promise<unknown>;
51
+ export declare const contactUpdateInputSchema: {
52
+ id: z.ZodString;
53
+ email: z.ZodOptional<z.ZodString>;
54
+ first_name: z.ZodOptional<z.ZodString>;
55
+ last_name: z.ZodOptional<z.ZodString>;
56
+ unsubscribed: z.ZodOptional<z.ZodBoolean>;
57
+ properties: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
58
+ };
59
+ export declare function contactUpdate(args: {
60
+ id: string;
61
+ email?: string;
62
+ first_name?: string;
63
+ last_name?: string;
64
+ unsubscribed?: boolean;
65
+ properties?: Record<string, unknown>;
66
+ }): Promise<unknown>;
67
+ export declare const contactDeleteInputSchema: {
68
+ id: z.ZodOptional<z.ZodString>;
69
+ ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
70
+ confirm_token: z.ZodOptional<z.ZodString>;
71
+ };
72
+ export declare function contactDelete(args: {
73
+ id?: string;
74
+ ids?: string[];
75
+ confirm_token?: string;
76
+ }): Promise<unknown | ConfirmationRequired>;
77
+ export declare const contactListSegmentsInputSchema: {
78
+ limit: z.ZodOptional<z.ZodNumber>;
79
+ after: z.ZodOptional<z.ZodString>;
80
+ before: z.ZodOptional<z.ZodString>;
81
+ contact_id: z.ZodString;
82
+ };
83
+ export declare function contactListSegments(args: {
84
+ contact_id: string;
85
+ limit?: number;
86
+ after?: string;
87
+ before?: string;
88
+ }): Promise<unknown>;
89
+ export declare const contactAddSegmentInputSchema: {
90
+ contact_id: z.ZodString;
91
+ segment_id: z.ZodString;
92
+ };
93
+ export declare function contactAddSegment(args: {
94
+ contact_id: string;
95
+ segment_id: string;
96
+ }): Promise<unknown>;
97
+ export declare const contactRemoveSegmentInputSchema: {
98
+ contact_id: z.ZodString;
99
+ segment_id: z.ZodString;
100
+ };
101
+ export declare function contactRemoveSegment(args: {
102
+ contact_id: string;
103
+ segment_id: string;
104
+ }): Promise<unknown>;
105
+ export declare const contactGetTopicsInputSchema: {
106
+ limit: z.ZodOptional<z.ZodNumber>;
107
+ after: z.ZodOptional<z.ZodString>;
108
+ before: z.ZodOptional<z.ZodString>;
109
+ contact_id: z.ZodString;
110
+ };
111
+ export declare function contactGetTopics(args: {
112
+ contact_id: string;
113
+ limit?: number;
114
+ after?: string;
115
+ before?: string;
116
+ }): Promise<unknown>;
117
+ export declare const contactUpdateTopicsInputSchema: {
118
+ contact_id: z.ZodString;
119
+ topics: z.ZodArray<z.ZodObject<{
120
+ id: z.ZodString;
121
+ subscription: z.ZodEnum<["opt_in", "opt_out"]>;
122
+ }, "strip", z.ZodTypeAny, {
123
+ id: string;
124
+ subscription: "opt_in" | "opt_out";
125
+ }, {
126
+ id: string;
127
+ subscription: "opt_in" | "opt_out";
128
+ }>, "many">;
129
+ };
130
+ export declare function contactUpdateTopics(args: {
131
+ contact_id: string;
132
+ topics: Array<{
133
+ id: string;
134
+ subscription: 'opt_in' | 'opt_out';
135
+ }>;
136
+ }): Promise<unknown>;
137
+ //# sourceMappingURL=contacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contacts.d.ts","sourceRoot":"","sources":["../../../src/tools/contacts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ import { z } from 'zod';
2
+ import { resendPost, resendGet, resendPatch, resendDelete } from '../lib/resend-client.js';
3
+ import { requireConfirmation, validateAndConsume } from '../lib/destructive-gate.js';
4
+ const paginationSchema = {
5
+ limit: z.number().int().min(1).max(100).optional().describe('Max items to return (max 100).'),
6
+ after: z.string().optional().describe('Cursor — return items after this value.'),
7
+ before: z.string().optional().describe('Cursor — return items before this value.'),
8
+ };
9
+ // --- resend_contact_create ---
10
+ export const contactCreateInputSchema = {
11
+ email: z.string().describe('Contact email address (required).'),
12
+ first_name: z.string().optional().describe('Contact first name.'),
13
+ last_name: z.string().optional().describe('Contact last name.'),
14
+ unsubscribed: z.boolean().optional().describe('Set to true if the contact is unsubscribed from all emails.'),
15
+ properties: z.record(z.unknown()).optional().describe('Custom contact properties as key-value pairs.'),
16
+ segments: z.array(z.string()).optional().describe('Array of segment IDs to add the contact to.'),
17
+ topics: z.array(z.object({
18
+ id: z.string().describe('Topic ID.'),
19
+ subscription: z.enum(['opt_in', 'opt_out']).describe('Subscription status.'),
20
+ })).optional().describe('Topics to subscribe or unsubscribe the contact to.'),
21
+ };
22
+ export async function contactCreate(args) {
23
+ return resendPost('/contacts', args);
24
+ }
25
+ // --- resend_contact_list ---
26
+ export const contactListInputSchema = {
27
+ ...paginationSchema,
28
+ segment_id: z.string().optional().describe('Filter contacts by segment ID.'),
29
+ };
30
+ export async function contactList(args) {
31
+ return resendGet('/contacts', { limit: args.limit, after: args.after, before: args.before, segment_id: args.segment_id });
32
+ }
33
+ // --- resend_contact_get ---
34
+ export const contactGetInputSchema = {
35
+ id: z.string().describe('Contact ID or email address.'),
36
+ };
37
+ export async function contactGet(args) {
38
+ return resendGet(`/contacts/${encodeURIComponent(args.id)}`);
39
+ }
40
+ // --- resend_contact_update ---
41
+ export const contactUpdateInputSchema = {
42
+ id: z.string().describe('Contact ID or email address.'),
43
+ email: z.string().optional().describe('New email address.'),
44
+ first_name: z.string().optional().describe('First name.'),
45
+ last_name: z.string().optional().describe('Last name.'),
46
+ unsubscribed: z.boolean().optional().describe('Unsubscribe status.'),
47
+ properties: z.record(z.unknown()).optional().describe('Custom properties.'),
48
+ };
49
+ export async function contactUpdate(args) {
50
+ const { id, ...body } = args;
51
+ return resendPatch(`/contacts/${encodeURIComponent(id)}`, body);
52
+ }
53
+ // --- resend_contact_delete (α-gated, bulk) ---
54
+ export const contactDeleteInputSchema = {
55
+ id: z.string().optional().describe('Contact ID or email to delete. Provide id or ids.'),
56
+ ids: z.array(z.string()).optional().describe('Multiple contact IDs/emails to delete. Provide id or ids.'),
57
+ confirm_token: z.string().optional().describe('Confirmation token from a previous call.'),
58
+ };
59
+ export async function contactDelete(args) {
60
+ const { confirm_token, ...rest } = args;
61
+ const tool = 'resend_contact_delete';
62
+ if (!rest.id && (!rest.ids || rest.ids.length === 0)) {
63
+ throw new Error('Provide id (single) or ids (bulk).');
64
+ }
65
+ const isBulk = !!rest.ids;
66
+ const ids = isBulk ? rest.ids : undefined;
67
+ const id = !isBulk ? rest.id : undefined;
68
+ if (!confirm_token) {
69
+ const count = isBulk ? ids.length : 1;
70
+ const preview = isBulk ? ids.slice(0, 3).join(', ') : rest.id;
71
+ return requireConfirmation({
72
+ tool, id, ids, payload: rest,
73
+ summary: `Delete ${count} contact(s): ${preview}. Removes subscriber data — irreversible.`,
74
+ });
75
+ }
76
+ const result = validateAndConsume({ confirm_token, tool, id, ids, payload: rest });
77
+ if (!result.valid)
78
+ throw new Error(result.reason);
79
+ if (isBulk) {
80
+ const results = await Promise.allSettled(ids.map(cid => resendDelete(`/contacts/${encodeURIComponent(cid)}`)));
81
+ const succeeded = [];
82
+ const failed = [];
83
+ results.forEach((r, idx) => {
84
+ if (r.status === 'fulfilled')
85
+ succeeded.push(ids[idx]);
86
+ else
87
+ failed.push({ id: ids[idx], error: String(r.reason) });
88
+ });
89
+ return { succeeded, failed, summary: `${succeeded.length}/${ids.length} succeeded` };
90
+ }
91
+ return resendDelete(`/contacts/${encodeURIComponent(rest.id)}`);
92
+ }
93
+ // --- resend_contact_list_segments ---
94
+ export const contactListSegmentsInputSchema = {
95
+ contact_id: z.string().describe('Contact ID.'),
96
+ ...paginationSchema,
97
+ };
98
+ export async function contactListSegments(args) {
99
+ const { contact_id, ...query } = args;
100
+ return resendGet(`/contacts/${encodeURIComponent(contact_id)}/segments`, query);
101
+ }
102
+ // --- resend_contact_add_segment ---
103
+ export const contactAddSegmentInputSchema = {
104
+ contact_id: z.string().describe('Contact ID.'),
105
+ segment_id: z.string().describe('Segment ID to add the contact to.'),
106
+ };
107
+ export async function contactAddSegment(args) {
108
+ return resendPost(`/contacts/${encodeURIComponent(args.contact_id)}/segments/${encodeURIComponent(args.segment_id)}`);
109
+ }
110
+ // --- resend_contact_remove_segment ---
111
+ // NOT α-gated: removing from a segment is recoverable (can re-add)
112
+ export const contactRemoveSegmentInputSchema = {
113
+ contact_id: z.string().describe('Contact ID.'),
114
+ segment_id: z.string().describe('Segment ID to remove the contact from.'),
115
+ };
116
+ export async function contactRemoveSegment(args) {
117
+ return resendDelete(`/contacts/${encodeURIComponent(args.contact_id)}/segments/${encodeURIComponent(args.segment_id)}`);
118
+ }
119
+ // --- resend_contact_get_topics ---
120
+ export const contactGetTopicsInputSchema = {
121
+ contact_id: z.string().describe('Contact ID.'),
122
+ ...paginationSchema,
123
+ };
124
+ export async function contactGetTopics(args) {
125
+ const { contact_id, ...query } = args;
126
+ return resendGet(`/contacts/${encodeURIComponent(contact_id)}/topics`, query);
127
+ }
128
+ // --- resend_contact_update_topics ---
129
+ export const contactUpdateTopicsInputSchema = {
130
+ contact_id: z.string().describe('Contact ID.'),
131
+ topics: z.array(z.object({
132
+ id: z.string().describe('Topic ID.'),
133
+ subscription: z.enum(['opt_in', 'opt_out']).describe('opt_in to subscribe, opt_out to unsubscribe.'),
134
+ })).describe('Array of topic subscriptions to apply.'),
135
+ };
136
+ export async function contactUpdateTopics(args) {
137
+ const { contact_id, topics } = args;
138
+ return resendPatch(`/contacts/${encodeURIComponent(contact_id)}/topics`, { topics });
139
+ }
@@ -0,0 +1,95 @@
1
+ import { z } from 'zod';
2
+ import { type ConfirmationRequired } from '../lib/destructive-gate.js';
3
+ export declare const domainCreateInputSchema: {
4
+ name: z.ZodString;
5
+ region: z.ZodOptional<z.ZodEnum<["us-east-1", "eu-west-1", "sa-east-1", "ap-northeast-1"]>>;
6
+ custom_return_path: z.ZodOptional<z.ZodString>;
7
+ open_tracking: z.ZodOptional<z.ZodBoolean>;
8
+ click_tracking: z.ZodOptional<z.ZodBoolean>;
9
+ tls: z.ZodOptional<z.ZodEnum<["opportunistic", "enforced"]>>;
10
+ capabilities: z.ZodOptional<z.ZodObject<{
11
+ sending: z.ZodOptional<z.ZodEnum<["enabled", "disabled"]>>;
12
+ receiving: z.ZodOptional<z.ZodEnum<["enabled", "disabled"]>>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ sending?: "enabled" | "disabled" | undefined;
15
+ receiving?: "enabled" | "disabled" | undefined;
16
+ }, {
17
+ sending?: "enabled" | "disabled" | undefined;
18
+ receiving?: "enabled" | "disabled" | undefined;
19
+ }>>;
20
+ tracking_subdomain: z.ZodOptional<z.ZodString>;
21
+ };
22
+ export declare function domainCreate(args: {
23
+ name: string;
24
+ region?: 'us-east-1' | 'eu-west-1' | 'sa-east-1' | 'ap-northeast-1';
25
+ custom_return_path?: string;
26
+ open_tracking?: boolean;
27
+ click_tracking?: boolean;
28
+ tls?: 'opportunistic' | 'enforced';
29
+ capabilities?: {
30
+ sending?: 'enabled' | 'disabled';
31
+ receiving?: 'enabled' | 'disabled';
32
+ };
33
+ tracking_subdomain?: string;
34
+ }): Promise<unknown>;
35
+ export declare const domainListInputSchema: {
36
+ limit: z.ZodOptional<z.ZodNumber>;
37
+ after: z.ZodOptional<z.ZodString>;
38
+ before: z.ZodOptional<z.ZodString>;
39
+ };
40
+ export declare function domainList(args: {
41
+ limit?: number;
42
+ after?: string;
43
+ before?: string;
44
+ }): Promise<unknown>;
45
+ export declare const domainGetInputSchema: {
46
+ domain_id: z.ZodString;
47
+ };
48
+ export declare function domainGet(args: {
49
+ domain_id: string;
50
+ }): Promise<unknown>;
51
+ export declare const domainUpdateInputSchema: {
52
+ domain_id: z.ZodString;
53
+ open_tracking: z.ZodOptional<z.ZodBoolean>;
54
+ click_tracking: z.ZodOptional<z.ZodBoolean>;
55
+ tls: z.ZodOptional<z.ZodEnum<["opportunistic", "enforced"]>>;
56
+ capabilities: z.ZodOptional<z.ZodObject<{
57
+ sending: z.ZodOptional<z.ZodEnum<["enabled", "disabled"]>>;
58
+ receiving: z.ZodOptional<z.ZodEnum<["enabled", "disabled"]>>;
59
+ }, "strip", z.ZodTypeAny, {
60
+ sending?: "enabled" | "disabled" | undefined;
61
+ receiving?: "enabled" | "disabled" | undefined;
62
+ }, {
63
+ sending?: "enabled" | "disabled" | undefined;
64
+ receiving?: "enabled" | "disabled" | undefined;
65
+ }>>;
66
+ tracking_subdomain: z.ZodOptional<z.ZodString>;
67
+ };
68
+ export declare function domainUpdate(args: {
69
+ domain_id: string;
70
+ open_tracking?: boolean;
71
+ click_tracking?: boolean;
72
+ tls?: 'opportunistic' | 'enforced';
73
+ capabilities?: {
74
+ sending?: 'enabled' | 'disabled';
75
+ receiving?: 'enabled' | 'disabled';
76
+ };
77
+ tracking_subdomain?: string;
78
+ }): Promise<unknown>;
79
+ export declare const domainVerifyInputSchema: {
80
+ domain_id: z.ZodString;
81
+ };
82
+ export declare function domainVerify(args: {
83
+ domain_id: string;
84
+ }): Promise<unknown>;
85
+ export declare const domainDeleteInputSchema: {
86
+ domain_id: z.ZodOptional<z.ZodString>;
87
+ domain_ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
88
+ confirm_token: z.ZodOptional<z.ZodString>;
89
+ };
90
+ export declare function domainDelete(args: {
91
+ domain_id?: string;
92
+ domain_ids?: string[];
93
+ confirm_token?: string;
94
+ }): Promise<unknown | ConfirmationRequired>;
95
+ //# sourceMappingURL=domains.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domains.d.ts","sourceRoot":"","sources":["../../../src/tools/domains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAA2C,KAAK,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAWhH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;CAgBnC,CAAC;AAEF,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,gBAAgB,CAAC;IACpE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,GAAG,CAAC,EAAE,eAAe,GAAG,UAAU,CAAC;IACnC,YAAY,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;QAAC,SAAS,CAAC,EAAE,SAAS,GAAG,UAAU,CAAA;KAAE,CAAC;IACxF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,oBAEA;AAID,eAAO,MAAM,qBAAqB;;;;CAOjC,CAAC;AAEF,wBAAsB,UAAU,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,oBAEzF;AAID,eAAO,MAAM,oBAAoB;;CAEhC,CAAC;AAEF,wBAAsB,SAAS,CAAC,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,oBAE1D;AAID,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;CAUnC,CAAC;AAEF,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,GAAG,CAAC,EAAE,eAAe,GAAG,UAAU,CAAC;IACnC,YAAY,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;QAAC,SAAS,CAAC,EAAE,SAAS,GAAG,UAAU,CAAA;KAAE,CAAC;IACxF,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,oBAGA;AAID,eAAO,MAAM,uBAAuB;;CAEnC,CAAC;AAEF,wBAAsB,YAAY,CAAC,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,oBAE7D;AAID,eAAO,MAAM,uBAAuB;;;;CAOnC,CAAC;AAEF,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,OAAO,CAAC,OAAO,GAAG,oBAAoB,CAAC,CAuC1C"}