@sendinel/mcp-server 1.0.99 → 1.0.100

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.
@@ -1166,21 +1166,27 @@ Requirements: urgency without desperation, acknowledge the gap, one clear CTA, v
1166
1166
  if (!rows.length)
1167
1167
  return j([]);
1168
1168
  const companyIds = rows.map((company) => company.id);
1169
- const { data: subscribers, error: subscriberError } = await db()
1170
- .from('subscribers')
1171
- .select('company_id, engagement_score, total_opens, total_clicks, lifecycle_stage, last_engaged_at')
1172
- .eq('project_id', projectId)
1173
- .in('company_id', companyIds);
1174
- if (subscriberError)
1175
- return txt(`Error: ${subscriberError.message}`);
1176
1169
  const grouped = new Map();
1177
- for (const subscriber of subscribers ?? []) {
1178
- const companyId = typeof subscriber.company_id === 'string' ? subscriber.company_id : null;
1179
- if (!companyId)
1180
- continue;
1181
- const bucket = grouped.get(companyId) ?? [];
1182
- bucket.push(subscriber);
1183
- grouped.set(companyId, bucket);
1170
+ for (let offset = 0;; offset += 1000) {
1171
+ const { data: subscribers, error: subscriberError } = await db()
1172
+ .from('subscribers')
1173
+ .select('company_id, engagement_score, total_opens, total_clicks, lifecycle_stage, last_engaged_at')
1174
+ .eq('project_id', projectId)
1175
+ .in('company_id', companyIds)
1176
+ .order('id')
1177
+ .range(offset, offset + 999);
1178
+ if (subscriberError)
1179
+ return txt(`Error: ${subscriberError.message}`);
1180
+ for (const subscriber of subscribers ?? []) {
1181
+ const companyId = typeof subscriber.company_id === 'string' ? subscriber.company_id : null;
1182
+ if (!companyId)
1183
+ continue;
1184
+ const bucket = grouped.get(companyId) ?? [];
1185
+ bucket.push(subscriber);
1186
+ grouped.set(companyId, bucket);
1187
+ }
1188
+ if ((subscribers ?? []).length < 1000)
1189
+ break;
1184
1190
  }
1185
1191
  return j(rows.map((company) => ({
1186
1192
  ...company,
@@ -2196,11 +2202,21 @@ Requirements: urgency without desperation, acknowledge the gap, one clear CTA, v
2196
2202
  return j({ inactive_count: 0, sample: [], message: 'No subscribed contacts for this site.' });
2197
2203
  q = q.in('id', ids);
2198
2204
  }
2199
- const { data: suppressed } = await db()
2200
- .from('suppressions')
2201
- .select('email')
2202
- .eq('project_id', projectId);
2203
- const suppressedSet = new Set((suppressed ?? []).map((s) => s.email));
2205
+ const suppressedSet = new Set();
2206
+ for (let offset = 0;; offset += 1000) {
2207
+ const { data: suppressed, error: suppressionError } = await db()
2208
+ .from('suppressions')
2209
+ .select('email')
2210
+ .eq('project_id', projectId)
2211
+ .order('email')
2212
+ .range(offset, offset + 999);
2213
+ if (suppressionError)
2214
+ return txt(`Error: ${suppressionError.message}`);
2215
+ for (const suppression of suppressed ?? [])
2216
+ suppressedSet.add(suppression.email);
2217
+ if ((suppressed ?? []).length < 1000)
2218
+ break;
2219
+ }
2204
2220
  const { data: contacts, error } = await q.order('engagement_score', { ascending: true }).limit(sampleLimit);
2205
2221
  if (error)
2206
2222
  return txt(`Error: ${error.message}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sendinel/mcp-server",
3
- "version": "1.0.99",
3
+ "version": "1.0.100",
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",