@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.
- package/CHANGELOG.md +11 -0
- package/LICENSE +21 -0
- package/README.md +154 -0
- package/dist/src/errors.d.ts +16 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +21 -0
- package/dist/src/lib/destructive-gate.d.ts +27 -0
- package/dist/src/lib/destructive-gate.d.ts.map +1 -0
- package/dist/src/lib/destructive-gate.js +72 -0
- package/dist/src/lib/idempotency.d.ts +2 -0
- package/dist/src/lib/idempotency.d.ts.map +1 -0
- package/dist/src/lib/idempotency.js +12 -0
- package/dist/src/lib/resend-client.d.ts +13 -0
- package/dist/src/lib/resend-client.d.ts.map +1 -0
- package/dist/src/lib/resend-client.js +128 -0
- package/dist/src/server.d.ts +12 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +400 -0
- package/dist/src/tools/apikeys.d.ts +37 -0
- package/dist/src/tools/apikeys.d.ts.map +1 -0
- package/dist/src/tools/apikeys.js +72 -0
- package/dist/src/tools/broadcasts.d.ts +85 -0
- package/dist/src/tools/broadcasts.d.ts.map +1 -0
- package/dist/src/tools/broadcasts.js +118 -0
- package/dist/src/tools/contact-properties.d.ts +47 -0
- package/dist/src/tools/contact-properties.d.ts.map +1 -0
- package/dist/src/tools/contact-properties.js +80 -0
- package/dist/src/tools/contacts.d.ts +137 -0
- package/dist/src/tools/contacts.d.ts.map +1 -0
- package/dist/src/tools/contacts.js +139 -0
- package/dist/src/tools/domains.d.ts +95 -0
- package/dist/src/tools/domains.d.ts.map +1 -0
- package/dist/src/tools/domains.js +118 -0
- package/dist/src/tools/emails.d.ts +214 -0
- package/dist/src/tools/emails.d.ts.map +1 -0
- package/dist/src/tools/emails.js +142 -0
- package/dist/src/tools/logs.d.ts +18 -0
- package/dist/src/tools/logs.d.ts.map +1 -0
- package/dist/src/tools/logs.js +18 -0
- package/dist/src/tools/segments.d.ts +49 -0
- package/dist/src/tools/segments.d.ts.map +1 -0
- package/dist/src/tools/segments.js +79 -0
- package/dist/src/tools/templates.d.ts +113 -0
- package/dist/src/tools/templates.d.ts.map +1 -0
- package/dist/src/tools/templates.js +113 -0
- package/dist/src/tools/topics.d.ts +53 -0
- package/dist/src/tools/topics.d.ts.map +1 -0
- package/dist/src/tools/topics.js +81 -0
- package/dist/src/tools/webhooks.d.ts +49 -0
- package/dist/src/tools/webhooks.d.ts.map +1 -0
- package/dist/src/tools/webhooks.js +87 -0
- package/dist/src/version.d.ts +2 -0
- package/dist/src/version.d.ts.map +1 -0
- package/dist/src/version.js +2 -0
- 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
|
+
const domainCapabilitiesSchema = z.object({
|
|
5
|
+
sending: z.enum(['enabled', 'disabled']).optional()
|
|
6
|
+
.describe('Enable or disable sending emails from this domain.'),
|
|
7
|
+
receiving: z.enum(['enabled', 'disabled']).optional()
|
|
8
|
+
.describe('Enable or disable receiving emails to this domain.'),
|
|
9
|
+
});
|
|
10
|
+
// --- resend_domain_create ---
|
|
11
|
+
export const domainCreateInputSchema = {
|
|
12
|
+
name: z.string().describe('Domain name to add (e.g. "mail.example.com").'),
|
|
13
|
+
region: z.enum(['us-east-1', 'eu-west-1', 'sa-east-1', 'ap-northeast-1']).optional()
|
|
14
|
+
.describe('AWS region where emails are sent from (default: us-east-1).'),
|
|
15
|
+
custom_return_path: z.string().optional()
|
|
16
|
+
.describe('Subdomain for Return-Path address (default: "send", giving send.yourdomain.tld).'),
|
|
17
|
+
open_tracking: z.boolean().optional()
|
|
18
|
+
.describe('Track email open rate.'),
|
|
19
|
+
click_tracking: z.boolean().optional()
|
|
20
|
+
.describe('Track clicks within HTML emails.'),
|
|
21
|
+
tls: z.enum(['opportunistic', 'enforced']).optional()
|
|
22
|
+
.describe('TLS mode: opportunistic (tries TLS, falls back) or enforced (requires TLS or email won\'t send).'),
|
|
23
|
+
capabilities: domainCapabilitiesSchema.optional()
|
|
24
|
+
.describe('Enable/disable sending and receiving for this domain. At least one must be enabled.'),
|
|
25
|
+
tracking_subdomain: z.string().optional()
|
|
26
|
+
.describe('Custom subdomain for click and open tracking.'),
|
|
27
|
+
};
|
|
28
|
+
export async function domainCreate(args) {
|
|
29
|
+
return resendPost('/domains', args);
|
|
30
|
+
}
|
|
31
|
+
// --- resend_domain_list ---
|
|
32
|
+
export const domainListInputSchema = {
|
|
33
|
+
limit: z.number().int().min(1).max(100).optional()
|
|
34
|
+
.describe('Max number of domains to return (max 100).'),
|
|
35
|
+
after: z.string().optional()
|
|
36
|
+
.describe('Cursor — return items after this value.'),
|
|
37
|
+
before: z.string().optional()
|
|
38
|
+
.describe('Cursor — return items before this value.'),
|
|
39
|
+
};
|
|
40
|
+
export async function domainList(args) {
|
|
41
|
+
return resendGet('/domains', { limit: args.limit, after: args.after, before: args.before });
|
|
42
|
+
}
|
|
43
|
+
// --- resend_domain_get ---
|
|
44
|
+
export const domainGetInputSchema = {
|
|
45
|
+
domain_id: z.string().describe('Domain ID to retrieve.'),
|
|
46
|
+
};
|
|
47
|
+
export async function domainGet(args) {
|
|
48
|
+
return resendGet(`/domains/${args.domain_id}`);
|
|
49
|
+
}
|
|
50
|
+
// --- resend_domain_update ---
|
|
51
|
+
export const domainUpdateInputSchema = {
|
|
52
|
+
domain_id: z.string().describe('Domain ID to update.'),
|
|
53
|
+
open_tracking: z.boolean().optional().describe('Enable or disable open tracking.'),
|
|
54
|
+
click_tracking: z.boolean().optional().describe('Enable or disable click tracking.'),
|
|
55
|
+
tls: z.enum(['opportunistic', 'enforced']).optional()
|
|
56
|
+
.describe('TLS mode: opportunistic or enforced.'),
|
|
57
|
+
capabilities: domainCapabilitiesSchema.optional()
|
|
58
|
+
.describe('Enable/disable sending and receiving for this domain.'),
|
|
59
|
+
tracking_subdomain: z.string().optional()
|
|
60
|
+
.describe('Custom subdomain for tracking.'),
|
|
61
|
+
};
|
|
62
|
+
export async function domainUpdate(args) {
|
|
63
|
+
const { domain_id, ...body } = args;
|
|
64
|
+
return resendPatch(`/domains/${domain_id}`, body);
|
|
65
|
+
}
|
|
66
|
+
// --- resend_domain_verify ---
|
|
67
|
+
export const domainVerifyInputSchema = {
|
|
68
|
+
domain_id: z.string().describe('Domain ID to trigger DNS verification for.'),
|
|
69
|
+
};
|
|
70
|
+
export async function domainVerify(args) {
|
|
71
|
+
return resendPost(`/domains/${args.domain_id}/verify`);
|
|
72
|
+
}
|
|
73
|
+
// --- resend_domain_delete (α-gated, bulk-capable) ---
|
|
74
|
+
export const domainDeleteInputSchema = {
|
|
75
|
+
domain_id: z.string().optional()
|
|
76
|
+
.describe('Single domain ID to delete. Provide either domain_id or domain_ids.'),
|
|
77
|
+
domain_ids: z.array(z.string()).optional()
|
|
78
|
+
.describe('Multiple domain IDs to delete in one confirmed operation. Provide either domain_id or domain_ids.'),
|
|
79
|
+
confirm_token: z.string().optional()
|
|
80
|
+
.describe('Confirmation token from a previous call. Required to execute deletion.'),
|
|
81
|
+
};
|
|
82
|
+
export async function domainDelete(args) {
|
|
83
|
+
const { confirm_token, ...rest } = args;
|
|
84
|
+
const tool = 'resend_domain_delete';
|
|
85
|
+
if (!rest.domain_id && (!rest.domain_ids || rest.domain_ids.length === 0)) {
|
|
86
|
+
throw new Error('Provide domain_id (single) or domain_ids (bulk).');
|
|
87
|
+
}
|
|
88
|
+
const isBulk = !!rest.domain_ids;
|
|
89
|
+
const ids = isBulk ? rest.domain_ids : undefined;
|
|
90
|
+
const id = !isBulk ? rest.domain_id : undefined;
|
|
91
|
+
if (!confirm_token) {
|
|
92
|
+
const count = isBulk ? ids.length : 1;
|
|
93
|
+
const preview = isBulk ? ids.slice(0, 3).join(', ') : rest.domain_id;
|
|
94
|
+
return requireConfirmation({
|
|
95
|
+
tool,
|
|
96
|
+
id,
|
|
97
|
+
ids,
|
|
98
|
+
payload: rest,
|
|
99
|
+
summary: `Delete ${count} domain(s): ${preview}. Destroys DNS records and sending config — irreversible.`,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
const result = validateAndConsume({ confirm_token, tool, id, ids, payload: rest });
|
|
103
|
+
if (!result.valid)
|
|
104
|
+
throw new Error(result.reason);
|
|
105
|
+
if (isBulk) {
|
|
106
|
+
const results = await Promise.allSettled(ids.map(did => resendDelete(`/domains/${did}`)));
|
|
107
|
+
const succeeded = [];
|
|
108
|
+
const failed = [];
|
|
109
|
+
results.forEach((r, idx) => {
|
|
110
|
+
if (r.status === 'fulfilled')
|
|
111
|
+
succeeded.push(ids[idx]);
|
|
112
|
+
else
|
|
113
|
+
failed.push({ id: ids[idx], error: String(r.reason) });
|
|
114
|
+
});
|
|
115
|
+
return { succeeded, failed, summary: `${succeeded.length}/${ids.length} succeeded` };
|
|
116
|
+
}
|
|
117
|
+
return resendDelete(`/domains/${rest.domain_id}`);
|
|
118
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type ConfirmationRequired } from '../lib/destructive-gate.js';
|
|
3
|
+
export declare const emailSendInputSchema: {
|
|
4
|
+
from: z.ZodString;
|
|
5
|
+
to: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
|
|
6
|
+
subject: z.ZodString;
|
|
7
|
+
html: z.ZodOptional<z.ZodString>;
|
|
8
|
+
text: z.ZodOptional<z.ZodString>;
|
|
9
|
+
cc: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
10
|
+
bcc: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
11
|
+
reply_to: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
12
|
+
scheduled_at: z.ZodOptional<z.ZodString>;
|
|
13
|
+
topic_id: z.ZodOptional<z.ZodString>;
|
|
14
|
+
attachments: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
15
|
+
filename: z.ZodString;
|
|
16
|
+
content: z.ZodOptional<z.ZodString>;
|
|
17
|
+
path: z.ZodOptional<z.ZodString>;
|
|
18
|
+
content_type: z.ZodOptional<z.ZodString>;
|
|
19
|
+
}, "strip", z.ZodTypeAny, {
|
|
20
|
+
filename: string;
|
|
21
|
+
content?: string | undefined;
|
|
22
|
+
path?: string | undefined;
|
|
23
|
+
content_type?: string | undefined;
|
|
24
|
+
}, {
|
|
25
|
+
filename: string;
|
|
26
|
+
content?: string | undefined;
|
|
27
|
+
path?: string | undefined;
|
|
28
|
+
content_type?: string | undefined;
|
|
29
|
+
}>, "many">>;
|
|
30
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
31
|
+
name: z.ZodString;
|
|
32
|
+
value: z.ZodString;
|
|
33
|
+
}, "strip", z.ZodTypeAny, {
|
|
34
|
+
name: string;
|
|
35
|
+
value: string;
|
|
36
|
+
}, {
|
|
37
|
+
name: string;
|
|
38
|
+
value: string;
|
|
39
|
+
}>, "many">>;
|
|
40
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
41
|
+
template: z.ZodOptional<z.ZodObject<{
|
|
42
|
+
id: z.ZodString;
|
|
43
|
+
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber]>>>;
|
|
44
|
+
}, "strip", z.ZodTypeAny, {
|
|
45
|
+
id: string;
|
|
46
|
+
variables?: Record<string, string | number> | undefined;
|
|
47
|
+
}, {
|
|
48
|
+
id: string;
|
|
49
|
+
variables?: Record<string, string | number> | undefined;
|
|
50
|
+
}>>;
|
|
51
|
+
confirm_token: z.ZodOptional<z.ZodString>;
|
|
52
|
+
};
|
|
53
|
+
interface SendEmailResponse {
|
|
54
|
+
id: string;
|
|
55
|
+
}
|
|
56
|
+
export declare function emailSend(args: {
|
|
57
|
+
from: string;
|
|
58
|
+
to: string | string[];
|
|
59
|
+
subject: string;
|
|
60
|
+
html?: string;
|
|
61
|
+
text?: string;
|
|
62
|
+
cc?: string | string[];
|
|
63
|
+
bcc?: string | string[];
|
|
64
|
+
reply_to?: string | string[];
|
|
65
|
+
scheduled_at?: string;
|
|
66
|
+
topic_id?: string;
|
|
67
|
+
attachments?: Array<{
|
|
68
|
+
filename: string;
|
|
69
|
+
content?: string;
|
|
70
|
+
path?: string;
|
|
71
|
+
content_type?: string;
|
|
72
|
+
}>;
|
|
73
|
+
tags?: Array<{
|
|
74
|
+
name: string;
|
|
75
|
+
value: string;
|
|
76
|
+
}>;
|
|
77
|
+
headers?: Record<string, string>;
|
|
78
|
+
template?: {
|
|
79
|
+
id: string;
|
|
80
|
+
variables?: Record<string, string | number>;
|
|
81
|
+
};
|
|
82
|
+
confirm_token?: string;
|
|
83
|
+
}): Promise<SendEmailResponse | ConfirmationRequired>;
|
|
84
|
+
export declare const emailSendBatchInputSchema: {
|
|
85
|
+
emails: z.ZodArray<z.ZodObject<{
|
|
86
|
+
from: z.ZodString;
|
|
87
|
+
to: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
|
|
88
|
+
subject: z.ZodString;
|
|
89
|
+
html: z.ZodOptional<z.ZodString>;
|
|
90
|
+
text: z.ZodOptional<z.ZodString>;
|
|
91
|
+
cc: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
92
|
+
bcc: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
93
|
+
reply_to: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>>;
|
|
94
|
+
scheduled_at: z.ZodOptional<z.ZodString>;
|
|
95
|
+
topic_id: z.ZodOptional<z.ZodString>;
|
|
96
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
97
|
+
name: z.ZodString;
|
|
98
|
+
value: z.ZodString;
|
|
99
|
+
}, "strip", z.ZodTypeAny, {
|
|
100
|
+
name: string;
|
|
101
|
+
value: string;
|
|
102
|
+
}, {
|
|
103
|
+
name: string;
|
|
104
|
+
value: string;
|
|
105
|
+
}>, "many">>;
|
|
106
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
107
|
+
}, "strip", z.ZodTypeAny, {
|
|
108
|
+
from: string;
|
|
109
|
+
to: string | string[];
|
|
110
|
+
subject: string;
|
|
111
|
+
html?: string | undefined;
|
|
112
|
+
text?: string | undefined;
|
|
113
|
+
cc?: string | string[] | undefined;
|
|
114
|
+
bcc?: string | string[] | undefined;
|
|
115
|
+
reply_to?: string | string[] | undefined;
|
|
116
|
+
scheduled_at?: string | undefined;
|
|
117
|
+
topic_id?: string | undefined;
|
|
118
|
+
tags?: {
|
|
119
|
+
name: string;
|
|
120
|
+
value: string;
|
|
121
|
+
}[] | undefined;
|
|
122
|
+
headers?: Record<string, string> | undefined;
|
|
123
|
+
}, {
|
|
124
|
+
from: string;
|
|
125
|
+
to: string | string[];
|
|
126
|
+
subject: string;
|
|
127
|
+
html?: string | undefined;
|
|
128
|
+
text?: string | undefined;
|
|
129
|
+
cc?: string | string[] | undefined;
|
|
130
|
+
bcc?: string | string[] | undefined;
|
|
131
|
+
reply_to?: string | string[] | undefined;
|
|
132
|
+
scheduled_at?: string | undefined;
|
|
133
|
+
topic_id?: string | undefined;
|
|
134
|
+
tags?: {
|
|
135
|
+
name: string;
|
|
136
|
+
value: string;
|
|
137
|
+
}[] | undefined;
|
|
138
|
+
headers?: Record<string, string> | undefined;
|
|
139
|
+
}>, "many">;
|
|
140
|
+
confirm_token: z.ZodOptional<z.ZodString>;
|
|
141
|
+
};
|
|
142
|
+
interface BatchEmailResponse {
|
|
143
|
+
data: Array<{
|
|
144
|
+
id: string;
|
|
145
|
+
}>;
|
|
146
|
+
}
|
|
147
|
+
export declare function emailSendBatch(args: {
|
|
148
|
+
emails: Array<{
|
|
149
|
+
from: string;
|
|
150
|
+
to: string | string[];
|
|
151
|
+
subject: string;
|
|
152
|
+
html?: string;
|
|
153
|
+
text?: string;
|
|
154
|
+
cc?: string | string[];
|
|
155
|
+
bcc?: string | string[];
|
|
156
|
+
reply_to?: string | string[];
|
|
157
|
+
scheduled_at?: string;
|
|
158
|
+
topic_id?: string;
|
|
159
|
+
tags?: Array<{
|
|
160
|
+
name: string;
|
|
161
|
+
value: string;
|
|
162
|
+
}>;
|
|
163
|
+
headers?: Record<string, string>;
|
|
164
|
+
}>;
|
|
165
|
+
confirm_token?: string;
|
|
166
|
+
}): Promise<BatchEmailResponse | ConfirmationRequired>;
|
|
167
|
+
export declare const emailGetInputSchema: {
|
|
168
|
+
id: z.ZodString;
|
|
169
|
+
};
|
|
170
|
+
export declare function emailGet(args: {
|
|
171
|
+
id: string;
|
|
172
|
+
}): Promise<unknown>;
|
|
173
|
+
export declare const emailListInputSchema: {
|
|
174
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
175
|
+
after: z.ZodOptional<z.ZodString>;
|
|
176
|
+
before: z.ZodOptional<z.ZodString>;
|
|
177
|
+
};
|
|
178
|
+
export declare function emailList(args: {
|
|
179
|
+
limit?: number;
|
|
180
|
+
after?: string;
|
|
181
|
+
before?: string;
|
|
182
|
+
}): Promise<unknown>;
|
|
183
|
+
export declare const emailUpdateInputSchema: {
|
|
184
|
+
id: z.ZodString;
|
|
185
|
+
scheduled_at: z.ZodOptional<z.ZodString>;
|
|
186
|
+
};
|
|
187
|
+
export declare function emailUpdate(args: {
|
|
188
|
+
id: string;
|
|
189
|
+
scheduled_at?: string;
|
|
190
|
+
}): Promise<unknown>;
|
|
191
|
+
export declare const emailCancelInputSchema: {
|
|
192
|
+
id: z.ZodString;
|
|
193
|
+
};
|
|
194
|
+
export declare function emailCancel(args: {
|
|
195
|
+
id: string;
|
|
196
|
+
}): Promise<unknown>;
|
|
197
|
+
export declare const emailListReceivedInputSchema: {
|
|
198
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
199
|
+
after: z.ZodOptional<z.ZodString>;
|
|
200
|
+
before: z.ZodOptional<z.ZodString>;
|
|
201
|
+
};
|
|
202
|
+
export declare function emailListReceived(args: {
|
|
203
|
+
limit?: number;
|
|
204
|
+
after?: string;
|
|
205
|
+
before?: string;
|
|
206
|
+
}): Promise<unknown>;
|
|
207
|
+
export declare const emailGetReceivedInputSchema: {
|
|
208
|
+
id: z.ZodString;
|
|
209
|
+
};
|
|
210
|
+
export declare function emailGetReceived(args: {
|
|
211
|
+
id: string;
|
|
212
|
+
}): Promise<unknown>;
|
|
213
|
+
export {};
|
|
214
|
+
//# sourceMappingURL=emails.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emails.d.ts","sourceRoot":"","sources":["../../../src/tools/emails.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAA2C,KAAK,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAwBhH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoBhC,CAAC;AAEF,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClG,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,QAAQ,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAA;KAAE,CAAC;IACvE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,OAAO,CAAC,iBAAiB,GAAG,oBAAoB,CAAC,CAiBpD;AAmBD,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAIrC,CAAC;AAEF,UAAU,kBAAkB;IAC1B,IAAI,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7B;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QACrD,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACrD,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QACtD,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QACzC,IAAI,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACjF,CAAC,CAAC;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,OAAO,CAAC,kBAAkB,GAAG,oBAAoB,CAAC,CAiBrD;AAID,eAAO,MAAM,mBAAmB;;CAE/B,CAAC;AAEF,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,oBAElD;AAID,eAAO,MAAM,oBAAoB;;;;CAIhC,CAAC;AAEF,wBAAsB,SAAS,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,oBAExF;AAID,eAAO,MAAM,sBAAsB;;;CAGlC,CAAC;AAEF,wBAAsB,WAAW,CAAC,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,oBAG5E;AAKD,eAAO,MAAM,sBAAsB;;CAElC,CAAC;AAEF,wBAAsB,WAAW,CAAC,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,oBAErD;AAID,eAAO,MAAM,4BAA4B;;;;CAIxC,CAAC;AAEF,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,oBAEhG;AAID,eAAO,MAAM,2BAA2B;;CAEvC,CAAC;AAEF,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,oBAE1D"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { resendPost, resendGet, resendPatch } from '../lib/resend-client.js';
|
|
3
|
+
import { requireConfirmation, validateAndConsume } from '../lib/destructive-gate.js';
|
|
4
|
+
import { deriveIdempotencyKey } from '../lib/idempotency.js';
|
|
5
|
+
// --- Shared sub-schemas ---
|
|
6
|
+
const attachmentSchema = z.object({
|
|
7
|
+
filename: z.string().describe('Filename for the attachment.'),
|
|
8
|
+
content: z.string().optional().describe('Base64-encoded content of the attachment.'),
|
|
9
|
+
path: z.string().optional().describe('URL path to the attachment file.'),
|
|
10
|
+
content_type: z.string().optional().describe('MIME type of the attachment.'),
|
|
11
|
+
});
|
|
12
|
+
const tagSchema = z.object({
|
|
13
|
+
name: z.string().describe('Tag name.'),
|
|
14
|
+
value: z.string().describe('Tag value.'),
|
|
15
|
+
});
|
|
16
|
+
const toField = z.union([
|
|
17
|
+
z.string(),
|
|
18
|
+
z.array(z.string()).min(1).max(50),
|
|
19
|
+
]).describe('Recipient email address(es). String or array of strings. Max 50.');
|
|
20
|
+
// --- resend_email_send ---
|
|
21
|
+
export const emailSendInputSchema = {
|
|
22
|
+
from: z.string().describe('Sender email address. Use "Name <email@domain.com>" for a friendly name. For testing without a verified domain, use onboarding@resend.dev.'),
|
|
23
|
+
to: toField,
|
|
24
|
+
subject: z.string().describe('Email subject line.'),
|
|
25
|
+
html: z.string().optional().describe('HTML body of the email. Provide html or text (or both).'),
|
|
26
|
+
text: z.string().optional().describe('Plain text body of the email.'),
|
|
27
|
+
cc: z.union([z.string(), z.array(z.string())]).optional().describe('CC recipient(s). String or array.'),
|
|
28
|
+
bcc: z.union([z.string(), z.array(z.string())]).optional().describe('BCC recipient(s). String or array.'),
|
|
29
|
+
reply_to: z.union([z.string(), z.array(z.string())]).optional().describe('Reply-to address(es).'),
|
|
30
|
+
scheduled_at: z.string().optional().describe('Schedule the email for later delivery. ISO 8601 format (e.g. "2025-01-01T12:00:00Z" or "in 1 min").'),
|
|
31
|
+
topic_id: z.string().optional().describe('Topic ID to scope the send. If the recipient has opted out of this topic, the email is suppressed.'),
|
|
32
|
+
attachments: z.array(attachmentSchema).optional().describe('File attachments.'),
|
|
33
|
+
tags: z.array(tagSchema).optional().describe('Custom tags for tracking.'),
|
|
34
|
+
headers: z.record(z.string()).optional().describe('Custom email headers as key-value pairs.'),
|
|
35
|
+
template: z.object({
|
|
36
|
+
id: z.string().describe('Template ID or alias to use as the email body.'),
|
|
37
|
+
variables: z.record(z.union([z.string(), z.number()])).optional()
|
|
38
|
+
.describe('Variable values to inject into the template.'),
|
|
39
|
+
}).optional().describe('Use a saved template instead of (or alongside) html/text fields.'),
|
|
40
|
+
confirm_token: z.string().optional().describe('Confirmation token from a previous call. Required to actually send. Omit on first call to get the token.'),
|
|
41
|
+
};
|
|
42
|
+
export async function emailSend(args) {
|
|
43
|
+
const { confirm_token, ...payload } = args;
|
|
44
|
+
const tool = 'resend_email_send';
|
|
45
|
+
if (!confirm_token) {
|
|
46
|
+
return requireConfirmation({
|
|
47
|
+
tool,
|
|
48
|
+
payload,
|
|
49
|
+
summary: `Send email from ${args.from} to ${Array.isArray(args.to) ? args.to.join(', ') : args.to} — subject: "${args.subject}". This is irreversible.`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
const result = validateAndConsume({ confirm_token, tool, payload });
|
|
53
|
+
if (!result.valid)
|
|
54
|
+
throw new Error(result.reason);
|
|
55
|
+
const idempotencyKey = deriveIdempotencyKey(tool, payload);
|
|
56
|
+
return resendPost('/emails', payload, { idempotencyKey });
|
|
57
|
+
}
|
|
58
|
+
// --- resend_email_send_batch ---
|
|
59
|
+
const batchEmailSchema = z.object({
|
|
60
|
+
from: z.string().describe('Sender email address.'),
|
|
61
|
+
to: toField,
|
|
62
|
+
subject: z.string().describe('Email subject.'),
|
|
63
|
+
html: z.string().optional().describe('HTML body.'),
|
|
64
|
+
text: z.string().optional().describe('Plain text body.'),
|
|
65
|
+
cc: z.union([z.string(), z.array(z.string())]).optional().describe('CC recipient(s).'),
|
|
66
|
+
bcc: z.union([z.string(), z.array(z.string())]).optional().describe('BCC recipient(s).'),
|
|
67
|
+
reply_to: z.union([z.string(), z.array(z.string())]).optional().describe('Reply-to address(es).'),
|
|
68
|
+
scheduled_at: z.string().optional().describe('Schedule for later delivery (ISO 8601).'),
|
|
69
|
+
topic_id: z.string().optional().describe('Topic ID to scope the send.'),
|
|
70
|
+
tags: z.array(tagSchema).optional().describe('Custom tags.'),
|
|
71
|
+
headers: z.record(z.string()).optional().describe('Custom headers.'),
|
|
72
|
+
});
|
|
73
|
+
export const emailSendBatchInputSchema = {
|
|
74
|
+
emails: z.array(batchEmailSchema).min(1).max(100)
|
|
75
|
+
.describe('Array of up to 100 email objects to send in a single batch call.'),
|
|
76
|
+
confirm_token: z.string().optional().describe('Confirmation token from a previous call. Required to actually send.'),
|
|
77
|
+
};
|
|
78
|
+
export async function emailSendBatch(args) {
|
|
79
|
+
const { confirm_token, ...payload } = args;
|
|
80
|
+
const tool = 'resend_email_send_batch';
|
|
81
|
+
if (!confirm_token) {
|
|
82
|
+
return requireConfirmation({
|
|
83
|
+
tool,
|
|
84
|
+
payload,
|
|
85
|
+
summary: `Send batch of ${args.emails.length} email(s). Irreversible once sent.`,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const result = validateAndConsume({ confirm_token, tool, payload });
|
|
89
|
+
if (!result.valid)
|
|
90
|
+
throw new Error(result.reason);
|
|
91
|
+
const idempotencyKey = deriveIdempotencyKey(tool, payload);
|
|
92
|
+
return resendPost('/emails/batch', args.emails, { idempotencyKey });
|
|
93
|
+
}
|
|
94
|
+
// --- resend_email_get ---
|
|
95
|
+
export const emailGetInputSchema = {
|
|
96
|
+
id: z.string().describe('Email ID returned by resend_email_send.'),
|
|
97
|
+
};
|
|
98
|
+
export async function emailGet(args) {
|
|
99
|
+
return resendGet(`/emails/${args.id}`);
|
|
100
|
+
}
|
|
101
|
+
// --- resend_email_list ---
|
|
102
|
+
export const emailListInputSchema = {
|
|
103
|
+
limit: z.number().int().min(1).max(100).optional().describe('Max number of emails to return (max 100).'),
|
|
104
|
+
after: z.string().optional().describe('Cursor from a previous response — return items after this cursor.'),
|
|
105
|
+
before: z.string().optional().describe('Cursor from a previous response — return items before this cursor.'),
|
|
106
|
+
};
|
|
107
|
+
export async function emailList(args) {
|
|
108
|
+
return resendGet('/emails', { limit: args.limit, after: args.after, before: args.before });
|
|
109
|
+
}
|
|
110
|
+
// --- resend_email_update ---
|
|
111
|
+
export const emailUpdateInputSchema = {
|
|
112
|
+
id: z.string().describe('Email ID to update. Only works on scheduled emails that have not yet been sent.'),
|
|
113
|
+
scheduled_at: z.string().optional().describe('New scheduled time (ISO 8601). Updates when the email will be sent.'),
|
|
114
|
+
};
|
|
115
|
+
export async function emailUpdate(args) {
|
|
116
|
+
const { id, ...body } = args;
|
|
117
|
+
return resendPatch(`/emails/${id}`, body);
|
|
118
|
+
}
|
|
119
|
+
// --- resend_email_cancel ---
|
|
120
|
+
// NOT α-gated: cancelling a scheduled send is a safety action.
|
|
121
|
+
export const emailCancelInputSchema = {
|
|
122
|
+
id: z.string().describe('Email ID to cancel. Only works on scheduled emails that have not been sent yet.'),
|
|
123
|
+
};
|
|
124
|
+
export async function emailCancel(args) {
|
|
125
|
+
return resendPost(`/emails/${args.id}/cancel`);
|
|
126
|
+
}
|
|
127
|
+
// --- resend_email_list_received ---
|
|
128
|
+
export const emailListReceivedInputSchema = {
|
|
129
|
+
limit: z.number().int().min(1).max(100).optional().describe('Max results to return (max 100).'),
|
|
130
|
+
after: z.string().optional().describe('Cursor — return items after this value.'),
|
|
131
|
+
before: z.string().optional().describe('Cursor — return items before this value.'),
|
|
132
|
+
};
|
|
133
|
+
export async function emailListReceived(args) {
|
|
134
|
+
return resendGet('/emails/receiving', { limit: args.limit, after: args.after, before: args.before });
|
|
135
|
+
}
|
|
136
|
+
// --- resend_email_get_received ---
|
|
137
|
+
export const emailGetReceivedInputSchema = {
|
|
138
|
+
id: z.string().describe('Received email ID.'),
|
|
139
|
+
};
|
|
140
|
+
export async function emailGetReceived(args) {
|
|
141
|
+
return resendGet(`/emails/receiving/${args.id}`);
|
|
142
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const logListInputSchema: {
|
|
3
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
4
|
+
after: z.ZodOptional<z.ZodString>;
|
|
5
|
+
before: z.ZodOptional<z.ZodString>;
|
|
6
|
+
};
|
|
7
|
+
export declare function logList(args: {
|
|
8
|
+
limit?: number;
|
|
9
|
+
after?: string;
|
|
10
|
+
before?: string;
|
|
11
|
+
}): Promise<unknown>;
|
|
12
|
+
export declare const logGetInputSchema: {
|
|
13
|
+
log_id: z.ZodString;
|
|
14
|
+
};
|
|
15
|
+
export declare function logGet(args: {
|
|
16
|
+
log_id: string;
|
|
17
|
+
}): Promise<unknown>;
|
|
18
|
+
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/tools/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,kBAAkB;;;;CAI9B,CAAC;AAEF,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,oBAEtF;AAID,eAAO,MAAM,iBAAiB;;CAE7B,CAAC;AAEF,wBAAsB,MAAM,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,oBAEpD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { resendGet } from '../lib/resend-client.js';
|
|
3
|
+
// --- resend_log_list ---
|
|
4
|
+
export const logListInputSchema = {
|
|
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
|
+
export async function logList(args) {
|
|
10
|
+
return resendGet('/logs', args);
|
|
11
|
+
}
|
|
12
|
+
// --- resend_log_get ---
|
|
13
|
+
export const logGetInputSchema = {
|
|
14
|
+
log_id: z.string().describe('Log entry ID.'),
|
|
15
|
+
};
|
|
16
|
+
export async function logGet(args) {
|
|
17
|
+
return resendGet(`/logs/${args.log_id}`);
|
|
18
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type ConfirmationRequired } from '../lib/destructive-gate.js';
|
|
3
|
+
export declare const segmentCreateInputSchema: {
|
|
4
|
+
name: z.ZodString;
|
|
5
|
+
filter: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
6
|
+
};
|
|
7
|
+
export declare function segmentCreate(args: {
|
|
8
|
+
name: string;
|
|
9
|
+
filter?: Record<string, unknown>;
|
|
10
|
+
}): Promise<unknown>;
|
|
11
|
+
export declare const segmentListInputSchema: {
|
|
12
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
13
|
+
after: z.ZodOptional<z.ZodString>;
|
|
14
|
+
before: z.ZodOptional<z.ZodString>;
|
|
15
|
+
};
|
|
16
|
+
export declare function segmentList(args: {
|
|
17
|
+
limit?: number;
|
|
18
|
+
after?: string;
|
|
19
|
+
before?: string;
|
|
20
|
+
}): Promise<unknown>;
|
|
21
|
+
export declare const segmentGetInputSchema: {
|
|
22
|
+
id: z.ZodString;
|
|
23
|
+
};
|
|
24
|
+
export declare function segmentGet(args: {
|
|
25
|
+
id: string;
|
|
26
|
+
}): Promise<unknown>;
|
|
27
|
+
export declare const segmentListContactsInputSchema: {
|
|
28
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
29
|
+
after: z.ZodOptional<z.ZodString>;
|
|
30
|
+
before: z.ZodOptional<z.ZodString>;
|
|
31
|
+
id: z.ZodString;
|
|
32
|
+
};
|
|
33
|
+
export declare function segmentListContacts(args: {
|
|
34
|
+
id: string;
|
|
35
|
+
limit?: number;
|
|
36
|
+
after?: string;
|
|
37
|
+
before?: string;
|
|
38
|
+
}): Promise<unknown>;
|
|
39
|
+
export declare const segmentDeleteInputSchema: {
|
|
40
|
+
id: z.ZodOptional<z.ZodString>;
|
|
41
|
+
ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
42
|
+
confirm_token: z.ZodOptional<z.ZodString>;
|
|
43
|
+
};
|
|
44
|
+
export declare function segmentDelete(args: {
|
|
45
|
+
id?: string;
|
|
46
|
+
ids?: string[];
|
|
47
|
+
confirm_token?: string;
|
|
48
|
+
}): Promise<unknown | ConfirmationRequired>;
|
|
49
|
+
//# sourceMappingURL=segments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../../../src/tools/segments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAA2C,KAAK,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAUhH,eAAO,MAAM,wBAAwB;;;CAGpC,CAAC;AAEF,wBAAsB,aAAa,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,oBAE3F;AAID,eAAO,MAAM,sBAAsB;;;;CAAmB,CAAC;AAEvD,wBAAsB,WAAW,CAAC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,oBAE1F;AAID,eAAO,MAAM,qBAAqB;;CAEjC,CAAC;AAEF,wBAAsB,UAAU,CAAC,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,oBAEpD;AAMD,eAAO,MAAM,8BAA8B;;;;;CAG1C,CAAC;AAEF,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,oBAG9G;AAID,eAAO,MAAM,wBAAwB;;;;CAIpC,CAAC;AAEF,wBAAsB,aAAa,CAAC,IAAI,EAAE;IACxC,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,79 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { resendPost, resendGet, 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_segment_create ---
|
|
10
|
+
export const segmentCreateInputSchema = {
|
|
11
|
+
name: z.string().describe('Segment name.'),
|
|
12
|
+
filter: z.record(z.unknown()).optional().describe('Filter conditions to automatically include contacts in this segment.'),
|
|
13
|
+
};
|
|
14
|
+
export async function segmentCreate(args) {
|
|
15
|
+
return resendPost('/segments', args);
|
|
16
|
+
}
|
|
17
|
+
// --- resend_segment_list ---
|
|
18
|
+
export const segmentListInputSchema = paginationSchema;
|
|
19
|
+
export async function segmentList(args) {
|
|
20
|
+
return resendGet('/segments', args);
|
|
21
|
+
}
|
|
22
|
+
// --- resend_segment_get ---
|
|
23
|
+
export const segmentGetInputSchema = {
|
|
24
|
+
id: z.string().describe('Segment ID.'),
|
|
25
|
+
};
|
|
26
|
+
export async function segmentGet(args) {
|
|
27
|
+
return resendGet(`/segments/${args.id}`);
|
|
28
|
+
}
|
|
29
|
+
// --- resend_segment_list_contacts ---
|
|
30
|
+
// No GET /segments/{id}/contacts in the OpenAPI spec.
|
|
31
|
+
// Contacts in a segment are retrieved via GET /contacts?segment_id={id}.
|
|
32
|
+
export const segmentListContactsInputSchema = {
|
|
33
|
+
id: z.string().describe('Segment ID.'),
|
|
34
|
+
...paginationSchema,
|
|
35
|
+
};
|
|
36
|
+
export async function segmentListContacts(args) {
|
|
37
|
+
const { id, ...query } = args;
|
|
38
|
+
return resendGet('/contacts', { segment_id: id, ...query });
|
|
39
|
+
}
|
|
40
|
+
// --- resend_segment_delete (α-gated, bulk) ---
|
|
41
|
+
export const segmentDeleteInputSchema = {
|
|
42
|
+
id: z.string().optional().describe('Segment ID to delete. Provide id or ids.'),
|
|
43
|
+
ids: z.array(z.string()).optional().describe('Multiple segment IDs to delete.'),
|
|
44
|
+
confirm_token: z.string().optional().describe('Confirmation token from a previous call.'),
|
|
45
|
+
};
|
|
46
|
+
export async function segmentDelete(args) {
|
|
47
|
+
const { confirm_token, ...rest } = args;
|
|
48
|
+
const tool = 'resend_segment_delete';
|
|
49
|
+
if (!rest.id && (!rest.ids || rest.ids.length === 0)) {
|
|
50
|
+
throw new Error('Provide id (single) or ids (bulk).');
|
|
51
|
+
}
|
|
52
|
+
const isBulk = !!rest.ids;
|
|
53
|
+
const ids = isBulk ? rest.ids : undefined;
|
|
54
|
+
const id = !isBulk ? rest.id : undefined;
|
|
55
|
+
if (!confirm_token) {
|
|
56
|
+
const count = isBulk ? ids.length : 1;
|
|
57
|
+
const preview = isBulk ? ids.slice(0, 3).join(', ') : rest.id;
|
|
58
|
+
return requireConfirmation({
|
|
59
|
+
tool, id, ids, payload: rest,
|
|
60
|
+
summary: `Delete ${count} segment(s): ${preview}. Destroys the segment definition — irreversible.`,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
const result = validateAndConsume({ confirm_token, tool, id, ids, payload: rest });
|
|
64
|
+
if (!result.valid)
|
|
65
|
+
throw new Error(result.reason);
|
|
66
|
+
if (isBulk) {
|
|
67
|
+
const results = await Promise.allSettled(ids.map(sid => resendDelete(`/segments/${sid}`)));
|
|
68
|
+
const succeeded = [];
|
|
69
|
+
const failed = [];
|
|
70
|
+
results.forEach((r, idx) => {
|
|
71
|
+
if (r.status === 'fulfilled')
|
|
72
|
+
succeeded.push(ids[idx]);
|
|
73
|
+
else
|
|
74
|
+
failed.push({ id: ids[idx], error: String(r.reason) });
|
|
75
|
+
});
|
|
76
|
+
return { succeeded, failed, summary: `${succeeded.length}/${ids.length} succeeded` };
|
|
77
|
+
}
|
|
78
|
+
return resendDelete(`/segments/${rest.id}`);
|
|
79
|
+
}
|