@sendinel/mcp-server 1.0.151 → 1.0.152

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.
@@ -13,6 +13,7 @@ type CampaignSetRow = {
13
13
  recipient_count?: number | null;
14
14
  audience?: Record<string, unknown> | null;
15
15
  audience_error?: string;
16
+ code?: string;
16
17
  };
17
18
  type StepRow = {
18
19
  campaign_id: string;
@@ -41,6 +42,7 @@ export declare function previewOf(campaigns: CampaignSetRow[], steps: StepRow[])
41
42
  recipient_count?: number | null | undefined;
42
43
  audience?: Record<string, unknown> | null | undefined;
43
44
  audience_error?: string | undefined;
45
+ code?: string | undefined;
44
46
  activation?: string | undefined;
45
47
  emails: {
46
48
  step_order: number;
@@ -77,7 +77,7 @@ export function previewOf(campaigns, steps) {
77
77
  ...(c.type === 'broadcast' ? {
78
78
  recipient_count: c.recipient_count ?? null,
79
79
  audience: c.audience ?? null,
80
- ...(c.audience_error ? { audience_error: c.audience_error } : {}),
80
+ ...(c.audience_error ? { audience_error: c.audience_error, code: c.code } : {}),
81
81
  activation: BROADCAST_ACTIVATION,
82
82
  } : {}),
83
83
  emails: steps
@@ -114,8 +114,10 @@ export async function loadSet(projectId, campaignIds) {
114
114
  Object.assign(campaign, { recipient_count, audience });
115
115
  }
116
116
  catch (error) {
117
+ console.error("[campaign-sets] Audience lookup failed:", error);
118
+ const safe = dbToolError(error, "Unable to load campaign audience");
117
119
  Object.assign(campaign, { recipient_count: null, audience: null,
118
- audience_error: error instanceof Error ? error.message : String(error) });
120
+ audience_error: safe.error, code: safe.code });
119
121
  }
120
122
  }
121
123
  return { campaigns: loaded, steps: (steps ?? []) };
@@ -2842,11 +2842,12 @@ Do not include body_html in your response; Sendinel renders body_html from block
2842
2842
  }
2843
2843
  catch (err) {
2844
2844
  await db().from('email_log').update({ status: 'failed' }).eq('id', logRow.id);
2845
+ console.error("[campaigns] Reply action mint failed:", err);
2845
2846
  const errMsg = err instanceof Error ? err.message : String(err);
2846
2847
  if (errMsg.includes('23505') || errMsg.includes('uidx_reply_actions_pending_correlation') || errMsg.includes('already pending')) {
2847
2848
  return txt('An awaiting-reply send for this correlation_id is already pending.');
2848
2849
  }
2849
- return txt(`Error: Failed to mint reply action — ${errMsg}`);
2850
+ return toolError(dbToolError(err, "Failed to mint reply action"));
2850
2851
  }
2851
2852
  const payload = {
2852
2853
  from: `${site.from_name} <${site.from_email}>`,
@@ -6,7 +6,7 @@ import { getProjectId } from '../project.js';
6
6
  import { buildVoicePrompt, deriveTemplateVariables } from '../lib/voice.js';
7
7
  import { parseModelJson, getAnthropicFastModelId } from '../anthropic-model.js';
8
8
  import { BLOCK_GENERATION_SCHEMA, blocksToHtml, blocksToText, normalizeComposerBlocks } from '../lib/composer-blocks.js';
9
- import { dbToolError } from '../lib/db-error.js';
9
+ import { dbToolError, toolError } from '../lib/db-error.js';
10
10
  // Haiku 5.5 (fast role) thinks before answering; thinking counts toward max_tokens (#4193).
11
11
  const FAST_MIN_MAX_TOKENS = 8000;
12
12
  const j = (data) => ({ content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] });
@@ -221,7 +221,8 @@ Respond with JSON: { "subject": "...", "blocks": [...], "body_text": "..." }`,
221
221
  };
222
222
  }
223
223
  catch (error) {
224
- return j({ error: `Generation failed: ${error instanceof Error ? error.message : String(error)}` });
224
+ console.error("[compound] Generation failed:", error);
225
+ return toolError(dbToolError(error, "Generation failed: unable to generate template"));
225
226
  }
226
227
  const { data: template, error } = await db().from('campaign_templates')
227
228
  .insert({
@@ -182,7 +182,8 @@ async function writeBackMcpContact(projectId, contact, patch) {
182
182
  await customer.schema('email').from('subscribers').update(update).eq('id', target.rowId);
183
183
  }
184
184
  catch (error) {
185
- logAudit({ action: 'byod_writeback_failed', resourceType: 'contact', resourceId: contact?.id, details: { email: contact?.email, error: error instanceof Error ? error.message : String(error) } });
185
+ console.error('[contacts] BYOD writeback failed:', error);
186
+ logAudit({ action: 'byod_writeback_failed', resourceType: 'contact', resourceId: contact?.id, details: { email: contact?.email, ...dbToolError(error, 'Contact writeback failed') } });
186
187
  }
187
188
  }
188
189
  function daysAgo(days) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sendinel/mcp-server",
3
- "version": "1.0.151",
3
+ "version": "1.0.152",
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",