@sellable/mcp 0.1.146 → 0.1.147

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.
@@ -57,7 +57,8 @@ currentStep: "signal-discovery" })` before sampling so the watched Signal
57
57
  leads per 100 engagers before and after a conservative dedupe/cleanup
58
58
  factor, required engagers to scrape (`source target / fit rate`), average
59
59
  reachable engagers per right-content post, expected usable leads per
60
- right-content post after dedupe/cleanup, and posts needed to hit the target.
60
+ right-content post after dedupe/cleanup, posts needed to hit the target, and
61
+ whether sampled/projected fit clears the 10% planning floor.
61
62
  8. Select/promote enough right-content posts to plausibly hit the target. If the
62
63
  warm Signals pool is useful but too small, return the expected warm range and
63
64
  recommend Sales Nav/Prospeo for scale instead of padding with noisy posts.
@@ -74,8 +75,9 @@ Return a concise structured result with:
74
75
  engagers, ICP-fit rate as `n/N` plus percentage/range, good-fit prospects per
75
76
  100 engagers, required engagers to scrape, average reachable engagers per
76
77
  post, expected usable prospects per post after cleanup, posts needed for
77
- target, selected post count, review-batch import limit, expected usable lead
78
- range, and scale fallback
78
+ target, whether the 10% planning floor clears after cleanup, selected post
79
+ count, review-batch import limit, expected usable lead range, and scale
80
+ fallback
79
81
  - `estimated_good_fit_range`
80
82
  - `message_context_strength`, directional and source-specific
81
83
  - `false_positive_patterns`
@@ -99,3 +101,5 @@ Evidence standards:
99
101
  bounded review batch.
100
102
  - If `fetch_post_engagers` is unavailable or fails, report that explicitly and mark the estimate lower-confidence.
101
103
  - Keep LinkedIn Engagement viable when selected posts can produce roughly 150+ ICP-fit warm prospects before final filtering, even if Sales Nav is more scalable.
104
+ - If sampled/projected fit after cleanup is below 10%, reject the Signals scrape
105
+ path and recommend Sales Nav recent activity as the next source.
@@ -27,7 +27,7 @@ Process:
27
27
  1. Read the campaign brief, source intake, kickoff doc, or lane prompt supplied by the parent.
28
28
  2. Identify whether this is domain/account targeting or broad persona expansion.
29
29
  3. For domain targeting, use or create the standalone `domainFilterId` before searching; never pass raw domains directly into `search_prospeo`.
30
- 4. Run the narrowest useful Prospeo people preview and 1-2 refinements if quality or scale is unclear. Check scale against a default 300+ good-fit target, capped at 2,500 source candidates unless the parent supplies a different target.
30
+ 4. Run the narrowest useful Prospeo people preview and 1-2 refinements if quality or scale is unclear. Check scale against a default 300+ good-fit target, capped at 2,500 source candidates unless the parent supplies a different target, and require at least 10% projected good-fit after cleanup.
31
31
  5. Call out that Prospeo gives contact/account coverage but usually weaker LinkedIn intent than LinkedIn Engagement or Sales Nav activity slices.
32
32
 
33
33
  Return a concise structured result with:
@@ -50,4 +50,7 @@ Evidence standards:
50
50
 
51
51
  - Never pass raw domains, company website arrays, or company-name arrays into `search_prospeo`.
52
52
  - If the user supplied company names rather than domains, report that domain resolution is required before this lane can run safely.
53
+ - Prospeo is the terminal fallback. If projected good-fit after cleanup remains
54
+ below 10% after reasonable refinement, recommend tightening the ICP/source
55
+ direction rather than switching providers again.
53
56
  - Treat Prospeo as an account/contact coverage lane, not as proof of fresh LinkedIn intent.
@@ -35,6 +35,9 @@ Process:
35
35
  Loosen nonessential filters in order: remove recent-activity first, widen
36
36
  adjacent title variants, widen geography/company-size constraints, and only
37
37
  keep hard ICP requirements from the brief.
38
+ Also check the 10% planning floor after cleanup. If the best reasonable
39
+ Sales Nav lane remains below 10% projected good-fit, move to Prospeo instead
40
+ of recommending Sales Nav.
38
41
  6. Run the baseline plus 1-2 refinements or loosening passes if the first pass
39
42
  is noisy or under-scaled. Label the final pool as constrained if it still
40
43
  cannot plausibly reach the target after loosening.
@@ -69,5 +72,7 @@ Evidence standards:
69
72
  larger than the warm-post path. If Sales Nav is offered for scale, it should
70
73
  either project to the target good-fit count or clearly say it is too tight and
71
74
  name the next broadening/Prospeo option.
75
+ - If projected good-fit after cleanup is below 10%, do not recommend Sales Nav
76
+ as the winning source; recommend Prospeo as the next provider.
72
77
  - Do not hand-wave missing filter IDs.
73
78
  - If Sales Nav returns a giant unfiltered pool, discard that result and retry with valid filters before recommending it.
package/dist/index-dev.js CHANGED
File without changes
package/dist/index.js CHANGED
File without changes
@@ -31,6 +31,9 @@ const defaultCampaignSourceDefaults = {
31
31
  defaultSize: 25,
32
32
  minProjectedPass: 5,
33
33
  },
34
+ planning: {
35
+ minFitRate: 0.1,
36
+ },
34
37
  providers: {
35
38
  "signal-discovery": {
36
39
  targetGoodFitLeads: 150,
@@ -280,6 +283,10 @@ function loadCampaignSourceDefaults() {
280
283
  ...defaultCampaignSourceDefaults.reviewBatch,
281
284
  ...(parsed.reviewBatch ?? {}),
282
285
  },
286
+ planning: {
287
+ ...defaultCampaignSourceDefaults.planning,
288
+ ...(parsed.planning ?? {}),
289
+ },
283
290
  providers: {
284
291
  ...defaultCampaignSourceDefaults.providers,
285
292
  ...(parsed.providers ?? {}),
@@ -297,6 +304,7 @@ function getSignalDiscoverySourcePlanDefaults() {
297
304
  return {
298
305
  targetGoodFitLeads: signalDefaults.targetGoodFitLeads,
299
306
  defaultFitRate: signalDefaults.defaultFitRate,
307
+ minPlanningFitRate: defaults.planning.minFitRate,
300
308
  sourceCandidateTarget,
301
309
  reviewBatchSize: defaults.reviewBatch.defaultSize,
302
310
  };
@@ -602,7 +610,7 @@ function formatApproxInteger(value) {
602
610
  return `~${rounded.toLocaleString("en-US")}`;
603
611
  }
604
612
  function buildSignalDiscoverySourceRecommendation({ selectedPosts, }) {
605
- const { targetGoodFitLeads, defaultFitRate, sourceCandidateTarget, reviewBatchSize, } = getSignalDiscoverySourcePlanDefaults();
613
+ const { targetGoodFitLeads, defaultFitRate, minPlanningFitRate, sourceCandidateTarget, reviewBatchSize, } = getSignalDiscoverySourcePlanDefaults();
606
614
  const selectedCount = selectedPosts.length;
607
615
  const totalEngagement = selectedPosts.reduce((sum, post) => sum + (post.likes ?? 0) + (post.comments ?? 0), 0);
608
616
  const tableRows = selectedPosts
@@ -618,6 +626,7 @@ Use Signal Discovery first.
618
626
 
619
627
  **Good-fit target:** ~${targetGoodFitLeads.toLocaleString("en-US")} prospects after cleanup, enrichment, and filters<br>
620
628
  **Source-candidate plan:** scrape ~${sourceCandidateTarget.toLocaleString("en-US")} raw engagers using a conservative ${Math.round(defaultFitRate * 100)}% fit-rate assumption<br>
629
+ **Planning floor:** continue with Signal Discovery only when sampled/projected fit is at least ${Math.round(minPlanningFitRate * 100)}% after cleanup; below that, switch to Sales Nav recent activity<br>
621
630
  **Review checkpoint:** import the first ${reviewBatchSize.toLocaleString("en-US")} leads into the campaign for fit and message review before scaling
622
631
 
623
632
  ### Selected posts
@@ -637,7 +646,7 @@ This gives enough volume to work toward ~${targetGoodFitLeads.toLocaleString("en
637
646
 
638
647
  **First pass:** build the source list, then import only the ${reviewBatchSize.toLocaleString("en-US")}-lead review batch so we can inspect fit and messages before scaling.
639
648
 
640
- **Fallback:** if the review batch is too vendor-heavy, agency-heavy, or off-ICP, switch to Sales Nav recent activity.
649
+ **Fallback:** if the sampled/projected fit rate is below ${Math.round(minPlanningFitRate * 100)}%, or if the review batch is too vendor-heavy, agency-heavy, or off-ICP, switch to Sales Nav recent activity.
641
650
 
642
651
  Approval card should say:
643
652
 
@@ -1223,7 +1232,7 @@ export const leadToolDefinitions = [
1223
1232
  },
1224
1233
  targetEngagerCount: {
1225
1234
  type: "number",
1226
- description: "Signal Discovery: target number of post engagers/source candidates to scrape. Compute from source target good-fit leads / sampled fit rate; e.g. 150 good fits at 15% fit requires about 1000 engagers. Limits selected posts before starting scrape.",
1235
+ description: "Signal Discovery: target number of post engagers/source candidates to scrape. Compute from source target good-fit leads / sampled fit rate; e.g. 150 good fits at 15% fit requires about 1000 engagers. If the sampled/projected fit rate is below the 10% planning floor after cleanup, switch to the next provider instead of scaling noisy engagers. Limits selected posts before starting scrape.",
1227
1236
  },
1228
1237
  maxPostsToScrape: {
1229
1238
  type: "number",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.146",
3
+ "version": "0.1.147",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -155,14 +155,17 @@ should be a compact `## Source Recommendation` block with:
155
155
  - good-fit target: about 150 prospects after cleanup, enrichment, and filters
156
156
  - source-candidate plan: about 1,000 raw engagers using a conservative 15%
157
157
  fit-rate assumption unless sampled data supports a different number
158
+ - planning floor: continue with Signal Discovery only when sampled/projected
159
+ fit is at least 10% after cleanup; below that, move to Sales Nav recent
160
+ activity instead of scraping noisy engagers
158
161
  - review checkpoint: import the first 25 leads for fit and message review
159
162
  - a selected-post table with post author/topic, why it fits, and visible
160
163
  engagement
161
164
  - total visible pool and estimated good-fit pool
162
165
  - first pass: build the source list, then import only the review
163
166
  batch
164
- - fallback: switch to Sales Nav recent activity if the review batch is
165
- vendor-heavy, agency-heavy, or off-ICP
167
+ - fallback: switch to Sales Nav recent activity if sampled/projected fit falls
168
+ below 10%, or if the review batch is vendor-heavy, agency-heavy, or off-ICP
166
169
 
167
170
  When the user has not supplied a source and multiple source angles are viable,
168
171
  scout those angles as independent branches when the host can actually do it:
@@ -149,6 +149,11 @@ sequential by default. Run `source-scout-linkedin-engagement`,
149
149
  `source-scout-sales-nav`, and `source-scout-prospeo-contact` in parallel only
150
150
  when the user explicitly requested source comparison, a prior lane failed, or
151
151
  the first viable lane is borderline and a cheap fallback check is needed.
152
+ Use a 10% planning floor after conservative cleanup. If Signal Discovery falls
153
+ below that floor, move to Sales Nav. If Sales Nav falls below that floor after
154
+ reasonable refinement, move to Prospeo. Prospeo is the terminal fallback; if it
155
+ also falls below 10%, tighten the ICP/source direction instead of inventing
156
+ another provider.
152
157
 
153
158
  After scouting, show a second approval gate for the concrete source action. For
154
159
  Signal Discovery, this gate must say how many selected posts will be scraped,
@@ -175,6 +180,7 @@ Use Signal Discovery first.
175
180
 
176
181
  **Good-fit target:** ~150 prospects after cleanup, enrichment, and filters<br>
177
182
  **Source-candidate plan:** scrape ~1,000 raw engagers using a conservative 15% fit-rate assumption<br>
183
+ **Planning floor:** continue only when sampled/projected fit is at least 10% after cleanup; below that, switch to Sales Nav recent activity<br>
178
184
  **Review checkpoint:** import the first 25 leads into the campaign for fit and message review before scaling<br>
179
185
 
180
186
  ### Selected posts
@@ -199,8 +205,9 @@ AI-native sales workflows.
199
205
  **First pass:** build the source list, then import only the 25-lead review
200
206
  batch so we can inspect fit and messages before scaling.
201
207
 
202
- **Fallback:** if the review batch is too vendor-heavy, agency-heavy, or
203
- off-ICP, switch to Sales Nav recent activity.
208
+ **Fallback:** if sampled/projected fit falls below 10%, or if the review batch
209
+ is too vendor-heavy, agency-heavy, or off-ICP, switch to Sales Nav recent
210
+ activity.
204
211
  ```
205
212
 
206
213
  A source recommendation must show concrete evidence: source lane, filters or
@@ -239,9 +239,9 @@ for source approval before import.
239
239
  For Signal Discovery, the second gate is not "approve source" in the abstract.
240
240
  It is a concrete scrape approval: show a compact `## Source Recommendation`
241
241
  with the ~150 good-fit prospect goal, 15% raw-engager assumption, selected-post
242
- table, total visible pool, estimated good-fit pool, first-pass review
243
- batch, and fallback. The approval question should be "Approve scraping N Signal
244
- Discovery posts?"
242
+ table, total visible pool, estimated good-fit pool, 10% planning floor,
243
+ first-pass review batch, and fallback. The approval question should be "Approve
244
+ scraping N Signal Discovery posts?"
245
245
 
246
246
  That scrape approval is single-use. Once the user approves it, do not replay
247
247
  the source card or ask for the same approval again. Acknowledge the approval in
@@ -257,6 +257,11 @@ borderline and needs a second source to avoid a bad recommendation. The fallback
257
257
  order must stay plain: use Sales Nav to find ICP people who are actively posting
258
258
  on LinkedIn; if that is not enough, search Sales Nav by titles; if that is still
259
259
  not enough, use Prospeo for a broader account/contact path.
260
+ Use a 10% planning floor after conservative cleanup. If Signal Discovery falls
261
+ below that floor, move to Sales Nav. If Sales Nav falls below that floor after
262
+ reasonable refinement, move to Prospeo. Prospeo is the terminal fallback; if it
263
+ also falls below 10%, tighten the ICP/source direction instead of inventing
264
+ another provider.
260
265
 
261
266
  Source-angle comparison should be real, not implied. Call
262
267
  `get_source_scout_registry` before dispatching source scouts and use the
@@ -125,7 +125,9 @@ fallback fit rate is 15%, so the default source-candidate plan is about 1,000
125
125
  raw engagers. If the sampled fit rate is stronger or weaker, use the sampled
126
126
  rate with a conservative cleanup factor, cap the source candidates at the
127
127
  approved provider limit, and select only enough posts to reach that engager
128
- count. The subsequent
128
+ count. The planning floor is 10% projected fit after cleanup; if Signal
129
+ Discovery falls below that floor, do not import the source list. Route back to
130
+ find-leads and move to Sales Nav recent activity instead. The subsequent
129
131
  `confirm_lead_list` call still uses `targetLeadCount: <importLimit>` so only the
130
132
  bounded review batch enters the campaign table.
131
133
 
@@ -321,6 +321,9 @@ Use first when the value is in conversation opportunity, competitor engagers, co
321
321
  - Sample a representative first page only, scoring the first 25-40 engagers across the chosen posts against a rough yes/no headline rubric or `headlineICPCriteria`.
322
322
  - Use headline and display-name cues only for the spot-check sample; do not enrich people during this phase.
323
323
  - Base `estimatedReachableLeads` on the sampled engager pass rate, not only on a guessed discount from post themes.
324
+ - Use a 10% planning floor after conservative cleanup. If the sampled/projected
325
+ fit rate is below 10%, do not scale Signals; move to Sales Nav recent activity
326
+ instead.
324
327
  - A Signals lane with ~150+ estimated ICP-fit reachable engagers from selected
325
328
  posts is viable for a focused warm campaign, even if Sales Nav is more
326
329
  scalable. Do not discard that lane solely for being smaller. If post-level
@@ -384,6 +387,9 @@ Use first when LinkedIn activity plus tighter role / company filters matter.
384
387
  mark Sales Nav as a provider/tool issue and do not include it as a winning
385
388
  source.
386
389
  - If quality is good but scale is too small, widen the lane by adding/removing roles, expanding industries, widening headcount bands, or relaxing activity constraints.
390
+ - Use the same 10% planning floor after cleanup. If the final Sales Nav lane is
391
+ projected below 10% good-fit after reasonable refinement, move to Prospeo
392
+ rather than importing a noisy Sales Nav list.
387
393
  - Use as many smart refinement steps as needed within the remaining probe budget instead of returning the first under-scaled recipe.
388
394
  - If the lane is meant to support scalable outbound, do not stop at a merely borderline workable result when obvious expansion steps remain.
389
395
  - If you can name a specific next Sales Nav refinement that is still allowed by the probe budget, execute it before returning instead of listing it only as a recommendation.
@@ -404,6 +410,9 @@ Use first for broad persona expansion, ABM/domain targeting, hiring-led targetin
404
410
  - If you widen with seniority labels such as `Head` or `Director`, keep a matching department/function constraint and inspect the sample for off-function leakage such as `Head of Social Media`, `Head of IT`, or `Director of Finance`.
405
411
  - If quality is poor, tighten titles, company shape, seniority, geography, or hiring filters.
406
412
  - If quality is good but scale is too small, widen titles, industries, company-size bands, or account scope.
413
+ - Prospeo is the terminal fallback for this chain. If projected fit is still
414
+ below the 10% planning floor after reasonable Prospeo refinement, stop and ask
415
+ for a tighter ICP/source direction instead of inventing another provider.
407
416
  - When ABM/domain targeting exists, prefer refining around the account set before broadening away from it.
408
417
  - Use as many smart refinement steps as needed within the remaining probe budget instead of returning the first under-scaled recipe.
409
418
  - If the lane is meant to support scalable outbound, do not stop at a merely borderline workable result when obvious expansion steps remain.
@@ -63,6 +63,10 @@ search_prospeo({
63
63
  - Use `import_leads` with `provider: \"prospeo\"` and the `searchId` to create a lead list and start import.
64
64
  - **IMPORTANT:** If `import_leads` returns `needsModeSelection: true`, use `AskUserQuestion` to ask "add to existing leads or replace?" Do NOT assume.
65
65
  - Default source target is 300+ good-fit leads, capped at 2,500 source candidates for now.
66
+ - Apply the campaign source planning floor: the sampled/projected good-fit rate
67
+ after cleanup should be at least 10%. Prospeo is the terminal fallback; if the
68
+ best reasonable Prospeo lane is still below 10%, tighten the ICP/source
69
+ direction instead of switching to another provider.
66
70
  - After the list finishes and the user confirms it looks good, call `confirm_lead_list` with the `jobId` and the review-batch `targetLeadCount` from the active campaign defaults to import only the review batch into the campaign table.
67
71
  - `import_leads` owns the watched move to `confirm-lead-list` after a lead list/job exists.
68
72
  - `confirm_lead_list` owns the watched move to `filter-choice` after the bounded review batch exists.
@@ -96,6 +96,11 @@ Example search name: "Active CXOs at 201-500 companies"
96
96
  - < 1,000 = remove a filter or widen criteria
97
97
  - > 10,000 = add more filters
98
98
 
99
+ Also apply the campaign source planning floor: the sampled/projected good-fit
100
+ rate after cleanup should be at least 10%. If the best reasonable Sales Nav
101
+ lane remains below 10%, do not present it as the winning source; move to
102
+ Prospeo for broader account/contact coverage.
103
+
99
104
  4. FINAL SEARCH + CONFIRM - Execute winning strategy, ask before saving
100
105
 
101
106
  - Run the final search with the best filter combination
@@ -24,7 +24,7 @@ When the user asks to find posts or start searching, **IMMEDIATELY begin Round 1
24
24
 
25
25
  <lead_target>
26
26
 
27
- - **Default: provider max import count** (use this unless user specifies otherwise; see `lead-import-limits.json`, currently 250)
27
+ - **Default: provider max import count** (use this unless user specifies otherwise; see `lead-import-limits.json`, currently 2,500)
28
28
  - **Maximum: provider max import count**
29
29
  - Quality > Quantity: a few hundred active users > 1000 potentially inactive profiles
30
30
  - Focus on ACTIVE platform users who will actually see and respond to outreach
@@ -104,6 +104,9 @@ You must estimate:
104
104
  - `ceil(targetGoodFitLeads / sampledFitRate)`; for example 15 good-fit
105
105
  prospects per 100 engagers means a 150-good-fit source target needs about
106
106
  1,000 engagers scraped
107
+ - `planningFloor`
108
+ - minimum acceptable sampled/projected fit rate after conservative cleanup;
109
+ default 10%. Below this, do not scale Signal Discovery.
107
110
  - `projectedRange`
108
111
  - the conservative range implied by the observed sample
109
112
 
@@ -130,7 +133,10 @@ Use conservative logic:
130
133
  - preferred: "`sampledCount`: 40, `passCount`: 9, `passRate`: ~22%, `goodFitPer100Engagers`: ~22 before cleanup / ~13-16 after cleanup, `requiredEngagersToScrape`: ~940-1,150 for a 150-good-fit target after cleanup, `avgReachableEngagersPerPost`: 240, `goodFitProspectsPerPost`: ~31-38, `postsNeededForTarget`: ~4-5, `recentStrongPostCount`: 15-25, `freshEnoughPostCount`: 8-12, `projectedRange`: 150-190 from selected posts"
131
134
  - fallback: "I could not fetch engagers, so this is inferred from post and author quality only"
132
135
  5. If the evidence is too weak, say so and return a low-confidence estimate instead of pretending precision.
133
- 6. Do not manually enumerate dozens of engagers in the final answer. Summarize the sample by `sampledCount`, `passCount`, `passRate`, `projectedRange`, and 3-6 representative examples.
136
+ 6. If sampled/projected fit after cleanup is below the 10% planning floor,
137
+ reject the Signal Discovery scrape path and recommend Sales Nav recent
138
+ activity as the next source.
139
+ 7. Do not manually enumerate dozens of engagers in the final answer. Summarize the sample by `sampledCount`, `passCount`, `passRate`, `projectedRange`, and 3-6 representative examples.
134
140
 
135
141
  </yield_estimation>
136
142
 
@@ -389,12 +395,15 @@ recommendation, estimate source capacity from real sample math:
389
395
  - average reachable engagers per right-content post
390
396
  - expected good-fit leads per selected post after dedupe/cleanup
391
397
  - posts needed to reach the target
398
+ - whether sampled/projected fit clears the 10% planning floor
392
399
 
393
400
  Then select the smallest right-content post set that plausibly hits the source
394
401
  target. Do not scrape every promoted sample post by default; promoted sampling
395
402
  state and final scrape plan are separate. If the math says the warm post lane
396
403
  only supports a smaller first batch, say that and name the Sales Nav or Prospeo
397
- scale fallback rather than padding the selection with noisy posts.
404
+ scale fallback rather than padding the selection with noisy posts. If the
405
+ sampled/projected fit rate is below 10% after cleanup, do not call
406
+ `import_leads`; move to Sales Nav recent activity.
398
407
 
399
408
  ```json
400
409
  select_promising_posts({
@@ -1,9 +0,0 @@
1
- {
2
- "parallelMode": "wide",
3
- "agentCount": 6,
4
- "maxToolCallsPerAgent": 2,
5
- "senderMaxAgents": 2,
6
- "senderMaxToolCallsPerAgent": 3,
7
- "progressMode": true,
8
- "debugMode": true
9
- }