@sendinel/mcp-server 1.0.165 → 1.0.167

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.
@@ -388,7 +388,7 @@ export function registerNewsletterTools(server) {
388
388
  },
389
389
  description: 'Schedule a newsletter issue through the campaign send pipeline.',
390
390
  inputSchema: {
391
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
391
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
392
392
  newsletter_id: z.string().uuid(),
393
393
  issue_id: z.string().uuid(),
394
394
  scheduled_at: z.string(),
@@ -425,9 +425,9 @@ export function registerNewsletterTools(server) {
425
425
  idempotentHint: false,
426
426
  openWorldHint: true,
427
427
  },
428
- description: 'Send a newsletter issue now through the campaign send pipeline and create archive metadata. Requires human approval: the first call returns an approve_url and does nothing; call again with the same arguments plus approval_id once approved.',
428
+ description: 'Send a newsletter issue now through the campaign send pipeline and create archive metadata. Requires human approval: the first call returns an approve_url and does nothing; call again with only approval_id once approved.',
429
429
  inputSchema: {
430
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
430
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
431
431
  newsletter_id: z.string().uuid(),
432
432
  issue_id: z.string().uuid(),
433
433
  },
@@ -179,7 +179,7 @@ export function registerOrgTools(server) {
179
179
  },
180
180
  description: 'Invite a team member by email to the current project organization using the system invitation template. Reuses a matching pending invitation. Always requires human approval; request once, then repeat identical email, role and project_ids with approval_id. Owner invitations are unsupported by the API.',
181
181
  inputSchema: {
182
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
182
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
183
183
  email: z.string().email(),
184
184
  role: z.enum(['owner', 'admin', 'member', 'tester']).default('member'),
185
185
  project_ids: z.array(z.string().uuid()).optional().describe('Same-org project IDs. Omit for org-wide access; [] grants no projects. Must match an existing pending invitation.'),
@@ -350,7 +350,7 @@ export function registerOrgTools(server) {
350
350
  },
351
351
  description: "Replace a team member's per-project access within the org (full replace, not a merge). Org owners have implicit access to all projects and cannot be scoped this way.",
352
352
  inputSchema: {
353
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
353
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
354
354
  user_id: z.string().uuid(),
355
355
  projects: z.array(memberProjectAssignmentSchema),
356
356
  org_id: z.string().uuid().optional(),
@@ -498,7 +498,7 @@ export function registerOrgTools(server) {
498
498
  },
499
499
  description: 'Revoke a pending org invitation before it is accepted.',
500
500
  inputSchema: {
501
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
501
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
502
502
  invitation_id: z.string().uuid(),
503
503
  org_id: z.string().uuid().optional(),
504
504
  },
@@ -940,7 +940,7 @@ export function registerOrgTools(server) {
940
940
  },
941
941
  description: 'Start moving a sending domain between supported providers using the existing provider-switch flow.',
942
942
  inputSchema: {
943
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
943
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
944
944
  site_id: z.string().uuid(),
945
945
  to_provider: z.enum(PROVIDER_SWITCH_V1_PROVIDERS),
946
946
  },
@@ -207,7 +207,7 @@ export function registerSegmentTools(server) {
207
207
  },
208
208
  description: 'Delete a saved segment. Campaigns using this segment will lose targeting.',
209
209
  inputSchema: {
210
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
210
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
211
211
  segment_id: z.string().uuid(),
212
212
  },
213
213
  }, withApproval('delete_segment', async ({ segment_id }) => {
@@ -139,7 +139,7 @@ export function registerSignatureTools(server) {
139
139
  title: 'Delete Signature',
140
140
  annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },
141
141
  description: 'Permanently delete a project-scoped sending signature block.',
142
- inputSchema: { approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'), id: z.string().uuid() },
142
+ inputSchema: { approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'), id: z.string().uuid() },
143
143
  }, withApproval('delete_signature', async ({ id }) => {
144
144
  const projectId = getProjectId();
145
145
  const { data: existing, error: existingError } = await db()
@@ -312,7 +312,7 @@ export function registerSmsTools(server) {
312
312
  },
313
313
  description: 'Manually record an opt-in or opt-out for a contact (e.g., from a paper form or phone conversation).',
314
314
  inputSchema: {
315
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
315
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
316
316
  contact_id: z.string().uuid(),
317
317
  status: z.enum(['opt_in', 'opt_out']),
318
318
  source: z.string().optional(),
@@ -408,7 +408,7 @@ export function registerSmsTools(server) {
408
408
  },
409
409
  description: "Launch an SMS campaign or broadcast to a segment. Same shape as email campaigns but with channel='sms'.",
410
410
  inputSchema: {
411
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
411
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
412
412
  site_id: z.string().uuid(),
413
413
  name: z.string().min(1).max(200),
414
414
  body: z.string().min(1),
@@ -467,9 +467,9 @@ export function registerSmsTools(server) {
467
467
  idempotentHint: false,
468
468
  openWorldHint: true,
469
469
  },
470
- description: 'Send a single SMS through the active SMS provider to a contact or raw phone number. Validates consent and quiet hours before sending. Requires human approval: the first call returns an approve_url and does nothing; call again with the same arguments plus approval_id once approved.',
470
+ description: 'Send a single SMS through the active SMS provider to a contact or raw phone number. Validates consent and quiet hours before sending. Requires human approval: the first call returns an approve_url and does nothing; call again with only approval_id once approved.',
471
471
  inputSchema: {
472
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
472
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
473
473
  body: z.string().min(1),
474
474
  to_number: z.string().optional(),
475
475
  contact_id: z.string().uuid().optional(),
@@ -632,7 +632,7 @@ export function registerSocialPostTools(server) {
632
632
  openWorldHint: true,
633
633
  },
634
634
  description: 'Archive a social post so it disappears from active planner and list views.',
635
- inputSchema: { approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'), post_id: z.string().uuid() },
635
+ inputSchema: { approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'), post_id: z.string().uuid() },
636
636
  }, withApproval('delete_social_post', async ({ post_id }) => {
637
637
  const { data, error } = await db()
638
638
  .from('social_posts')
@@ -696,7 +696,7 @@ export function registerSocialPostTools(server) {
696
696
  },
697
697
  description: 'Schedule a social campaign post via a connected BYO publisher (UploadPost, Buffer). Returns publisherPostId on success.',
698
698
  inputSchema: {
699
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
699
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
700
700
  campaign_id: z.string().uuid().describe('UUID of the social campaign in Sendinel'),
701
701
  content: z.string().min(1).describe('Post body text'),
702
702
  publisher: z.enum(socialPublishers).describe('Which BYO publisher to route through'),
@@ -146,9 +146,9 @@ export function registerSocialReplyTools(server) {
146
146
  inputSchema: { post_url_or_urn: z.string().min(1), text: replyText, target_member_id: z.string().uuid().optional() },
147
147
  }, async ({ post_url_or_urn, text, target_member_id }) => proposePersonal('post_comment', post_url_or_urn, text, target_member_id));
148
148
  server.registerTool('reply_to_comment', {
149
- title: 'Propose LinkedIn Comment Reply', description: 'Create a review card for a personal LinkedIn reply. Never posts. Requires human approval: the first call returns an approve_url and does nothing; call again with the same arguments plus approval_id once approved.',
149
+ title: 'Propose LinkedIn Comment Reply', description: 'Create a review card for a personal LinkedIn reply. Never posts. Requires human approval: the first call returns an approve_url and does nothing; call again with only approval_id once approved.',
150
150
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
151
- inputSchema: { comment_url_or_urn: z.string().min(1), text: replyText, target_member_id: z.string().uuid().optional(), approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.') },
151
+ inputSchema: { comment_url_or_urn: z.string().min(1), text: replyText, target_member_id: z.string().uuid().optional(), approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.') },
152
152
  }, withApproval('reply_to_comment', async ({ comment_url_or_urn, text, target_member_id }) => proposePersonal('comment_reply', comment_url_or_urn, text, target_member_id)));
153
153
  server.registerTool('request_social_reply', {
154
154
  title: 'Request LinkedIn Reply Proposal',
@@ -379,7 +379,7 @@ export function registerTemplateTools(server) {
379
379
  openWorldHint: false,
380
380
  },
381
381
  description: 'Archive an email template. System templates cannot be deleted.',
382
- inputSchema: { approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'), id: z.string().uuid() },
382
+ inputSchema: { approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'), id: z.string().uuid() },
383
383
  }, withApproval('delete_template', async ({ id }) => {
384
384
  const projectId = getProjectId();
385
385
  const { data: existing, error: existingErr } = await db().from('campaign_templates')
@@ -50,7 +50,7 @@ export function registerWebhookTools(server) {
50
50
  },
51
51
  description: `Register a webhook URL to receive push notifications when events occur. Sendinel signs each payload with HMAC-SHA256 so you can verify authenticity. Valid events: ${VALID_EVENTS.join(', ')}`,
52
52
  inputSchema: {
53
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
53
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
54
54
  url: z.string().url().describe('HTTPS endpoint that will receive POST requests'),
55
55
  events: z.array(z.enum(VALID_EVENTS)).min(1).describe('Events to subscribe to'),
56
56
  description: z.string().optional().describe('Human-readable label, e.g. "Production orchestrator"'),
@@ -116,7 +116,7 @@ export function registerWebhookTools(server) {
116
116
  },
117
117
  description: 'Update a webhook subscription — change URL, events, or active status.',
118
118
  inputSchema: {
119
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
119
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
120
120
  subscription_id: z.string().uuid(),
121
121
  url: z.string().url().optional(),
122
122
  events: z.array(z.enum(VALID_EVENTS)).min(1).optional(),
@@ -159,7 +159,7 @@ export function registerWebhookTools(server) {
159
159
  },
160
160
  description: 'Permanently delete a webhook subscription. This also deletes all delivery history for this subscription.',
161
161
  inputSchema: {
162
- approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with the same arguments plus this approval_id to run the action.'),
162
+ approval_id: z.string().uuid().optional().describe('Get this by calling once without it, then have a human approve the returned approve_url. Re-call with only approval_id to run the action.'),
163
163
  subscription_id: z.string().uuid(),
164
164
  },
165
165
  }, withApproval('delete_webhook_subscription', async ({ subscription_id }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sendinel/mcp-server",
3
- "version": "1.0.165",
3
+ "version": "1.0.167",
4
4
  "description": "AI-controlled email operations control plane for campaigns, contacts, segments, analytics, and multi-provider sending via MCP.",
5
5
  "mcpName": "ai.sendinel/mcp-server",
6
6
  "type": "module",