@sendinel/mcp-server 1.0.19 → 1.0.20

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.
@@ -2241,16 +2241,30 @@ Requirements: urgency without desperation, acknowledge the gap, one clear CTA, v
2241
2241
  });
2242
2242
  if (error) {
2243
2243
  // Fallback: inline query if RPC not yet available
2244
- const { data: rows, error: qErr } = await db()
2245
- .from('subscribers')
2246
- .select('custom_properties')
2247
- .eq('project_id', projectId)
2248
- .eq('source_site', site_id)
2249
- .not('custom_properties', 'is', null)
2250
- .order('created_at', { ascending: false })
2251
- .limit(500);
2252
- if (qErr)
2253
- return txt(`Error: ${qErr.message}`);
2244
+ const SCHEMA_SAMPLE_LIMIT = 500;
2245
+ async function sampleSubscriberProperties(scopeToSite) {
2246
+ let query = db()
2247
+ .from('subscribers')
2248
+ .select('custom_properties')
2249
+ .eq('project_id', projectId)
2250
+ .not('custom_properties', 'is', null)
2251
+ .order('created_at', { ascending: false });
2252
+ if (scopeToSite)
2253
+ query = query.eq('source_site', site_id);
2254
+ return query.limit(SCHEMA_SAMPLE_LIMIT);
2255
+ }
2256
+ const siteSample = await sampleSubscriberProperties(true);
2257
+ if (siteSample.error)
2258
+ return txt(`Error: ${siteSample.error.message}`);
2259
+ let rows = siteSample.data ?? [];
2260
+ let scope = 'site';
2261
+ if (rows.length === 0) {
2262
+ const projectSample = await sampleSubscriberProperties(false);
2263
+ if (projectSample.error)
2264
+ return txt(`Error: ${projectSample.error.message}`);
2265
+ rows = projectSample.data ?? [];
2266
+ scope = 'project';
2267
+ }
2254
2268
  const keyMap = new Map();
2255
2269
  for (const row of rows ?? []) {
2256
2270
  const props = row.custom_properties;
@@ -2277,9 +2291,12 @@ Requirements: urgency without desperation, acknowledge the gap, one clear CTA, v
2277
2291
  }));
2278
2292
  return j({
2279
2293
  site_id,
2294
+ scope,
2280
2295
  total_keys: schema.length,
2281
2296
  schema,
2282
- note: 'Use merge_tag syntax in email body/subject. For sensitive data, add a fallback: {{custom.plan|subscriber}}. ⚠️ custom_properties data passes through the Anthropic API — avoid storing sensitive PII (SSNs, passwords, financial account numbers).',
2297
+ note: scope === 'project'
2298
+ ? `No contacts are tagged to site ${site_id} via source_site — sampled custom_properties across the whole project instead. Use merge_tag syntax in email body/subject. For sensitive data, add a fallback: {{custom.plan|subscriber}}. ⚠️ custom_properties data passes through the Anthropic API — avoid storing sensitive PII (SSNs, passwords, financial account numbers).`
2299
+ : 'Use merge_tag syntax in email body/subject. For sensitive data, add a fallback: {{custom.plan|subscriber}}. ⚠️ custom_properties data passes through the Anthropic API — avoid storing sensitive PII (SSNs, passwords, financial account numbers).',
2283
2300
  });
2284
2301
  }
2285
2302
  return j({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sendinel/mcp-server",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
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",