@sellable/mcp 0.1.151 → 0.1.153
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.
- package/README.md +4 -3
- package/agents/post-find-leads-filter-scout.md +5 -4
- package/agents/post-find-leads-message-scout.md +15 -14
- package/agents/source-scout-linkedin-engagement.md +6 -5
- package/agents/source-scout-prospeo-contact.md +4 -4
- package/agents/source-scout-sales-nav.md +4 -4
- package/dist/index-dev.js +0 -0
- package/dist/index.js +0 -0
- package/dist/tools/cells.js +1 -1
- package/dist/tools/leads.d.ts +37 -3
- package/dist/tools/leads.js +85 -77
- package/dist/tools/prompts.js +9 -9
- package/dist/tools/readiness.d.ts +7 -1
- package/dist/tools/readiness.js +10 -17
- package/dist/tools/registry.d.ts +17 -0
- package/dist/tools/rubrics.js +23 -20
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +59 -56
- package/skills/create-campaign-v2/SKILL.md +44 -42
- package/skills/create-campaign-v2/SOUL.md +16 -13
- package/skills/create-campaign-v2/core/auto-execute.README.md +16 -17
- package/skills/create-campaign-v2/core/auto-execute.yaml +8 -7
- package/skills/create-campaign-v2/core/flow.v2.json +81 -149
- package/skills/create-campaign-v2/core/policy.md +13 -12
- package/skills/create-campaign-v2/references/approval-gate-framing.md +4 -3
- package/skills/create-campaign-v2/references/filter-leads.md +5 -4
- package/skills/create-campaign-v2/references/lead-validation-preview.md +2 -2
- package/skills/create-campaign-v2/references/sample-validation-loop.md +32 -27
- package/skills/create-campaign-v2/references/step-13-import-leads.md +44 -33
- package/skills/create-campaign-v2/references/watch-guide-narration.md +27 -28
- package/skills/create-campaign-v2-tail/SKILL.md +44 -44
- package/skills/create-rubric/SKILL.md +5 -5
- package/skills/find-leads/SKILL.md +2 -2
- package/skills/generate-messages/SKILL.md +2 -1
- package/skills/providers/prospeo.md +3 -3
- package/skills/providers/sales-nav.md +7 -7
- package/skills/providers/signal-discovery.md +47 -23
|
@@ -51,8 +51,8 @@ Create and save a comprehensive lead scoring rubric that:
|
|
|
51
51
|
|
|
52
52
|
## Rubric Validation + Results
|
|
53
53
|
|
|
54
|
-
- `mcp__sellable__get_rows_minimal` - Read
|
|
55
|
-
- `mcp__sellable__queue_cells` - Queue only bounded `enrichCellId` values
|
|
54
|
+
- `mcp__sellable__get_rows_minimal` - Read first review/process sample cell IDs
|
|
55
|
+
- `mcp__sellable__queue_cells` - Queue only bounded sample `enrichCellId` values
|
|
56
56
|
- `mcp__sellable__wait_for_rubric_results` - Poll pass-rate results
|
|
57
57
|
|
|
58
58
|
`check_rubric` is legacy/recovery only. Do not use it in normal
|
|
@@ -207,8 +207,8 @@ update_campaign({
|
|
|
207
207
|
|
|
208
208
|
This triggers the campaign sync and moves the user to the filter-leads step where they can see the campaign table with scoring columns.
|
|
209
209
|
|
|
210
|
-
For normal create-campaign-v2 runs, the caller should
|
|
211
|
-
|
|
210
|
+
For normal create-campaign-v2 runs, the caller should queue only the first
|
|
211
|
+
review/process sample enrichment cells after message approval. For standalone
|
|
212
212
|
rubric editing, ask the user if we should kick off enrichment for a sample:
|
|
213
213
|
|
|
214
214
|
"ICP filtering enabled — you should see the leads table with scoring columns now. Want me to run enrichment on the first 5 leads to check pass rates?"
|
|
@@ -219,7 +219,7 @@ rubric editing, ask the user if we should kick off enrichment for a sample:
|
|
|
219
219
|
## Phase 5: Enrich + Score a Sample
|
|
220
220
|
|
|
221
221
|
1. Call `get_rows_minimal({ tableId, limit: 5 })` or use the caller-provided
|
|
222
|
-
|
|
222
|
+
review/process sample rows.
|
|
223
223
|
2. Call `queue_cells({ tableId, cellIds })` with only pending/error
|
|
224
224
|
`enrichCellId` values. Do not pass `icpCellId` values or full-table cells;
|
|
225
225
|
the workflow cascade handles downstream ICP scoring after enrichment.
|
|
@@ -162,9 +162,9 @@ Execution flow:
|
|
|
162
162
|
- `campaignOfferId`
|
|
163
163
|
- `sourceLeadListId` (or omit to use `selectedLeadListId`)
|
|
164
164
|
- `jobId` (from `import_leads` when available; omit for direct CSV lead lists)
|
|
165
|
-
- `
|
|
165
|
+
- `reviewBatchLimit: 15` for the first review/process sample
|
|
166
166
|
9. For campaign-builder flows, `confirm_lead_list` owns the watched move to
|
|
167
|
-
`filter-choice` after the
|
|
167
|
+
`filter-choice` after the first review/process sample exists. Then run:
|
|
168
168
|
- `wait_for_campaign_table_ready({ campaignId })`
|
|
169
169
|
- `get_campaign_context({ campaignId, refresh: true })`
|
|
170
170
|
- `get_rows_minimal({ tableId: workflowTableId, limit: 10, page: 1 })`
|
|
@@ -28,7 +28,8 @@ You craft messages in one of two modes:
|
|
|
28
28
|
### Mode 0: Message Draft Builder Branch
|
|
29
29
|
|
|
30
30
|
Use this mode when create-campaign-v2 starts the background Message Draft
|
|
31
|
-
Builder after `confirm_lead_list`
|
|
31
|
+
Builder after `confirm_lead_list` copies source rows and the first
|
|
32
|
+
review/process sample exists.
|
|
32
33
|
This is not the row-cell generation path.
|
|
33
34
|
|
|
34
35
|
Inputs must come from the parent thread or scoped MCP/product tools for the
|
|
@@ -62,14 +62,14 @@ search_prospeo({
|
|
|
62
62
|
- Pass `searchId` on subsequent pages to paginate.
|
|
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
|
-
- Default source target is about
|
|
65
|
+
- Default source import target is about 1,000 source contacts. Use the provider cap internally when the raw pool is larger; do not present that cap as the customer-facing plan unless it is reached.
|
|
66
66
|
- Apply the campaign source planning floor: the sampled/projected good-fit rate
|
|
67
67
|
after cleanup should be at least 10%. Prospeo is the terminal fallback; if the
|
|
68
68
|
best reasonable Prospeo lane is still below 10%, tighten the ICP/source
|
|
69
69
|
direction instead of switching to another provider.
|
|
70
|
-
- After the list finishes and the user confirms it looks good, call `confirm_lead_list` with the `jobId` and
|
|
70
|
+
- After the list finishes and the user confirms it looks good, call `confirm_lead_list` with the `jobId` and `reviewBatchLimit: 15` to copy confirmed rows into the campaign table and use the first 15 as the review/process sample.
|
|
71
71
|
- `import_leads` owns the watched move to `confirm-lead-list` after a lead list/job exists.
|
|
72
|
-
- `confirm_lead_list` owns the watched move to `filter-choice` after
|
|
72
|
+
- `confirm_lead_list` owns the watched move to `filter-choice` after confirmed campaign rows exist.
|
|
73
73
|
- Post-confirm readback order is required:
|
|
74
74
|
1. `wait_for_campaign_table_ready({ campaignId })`
|
|
75
75
|
2. `get_campaign_context({ campaignId, refresh: true })` then `get_rows_minimal(...)` for recommendation
|
|
@@ -354,9 +354,9 @@ Step 4 - Final Search + Confirm:
|
|
|
354
354
|
What would you like?"
|
|
355
355
|
|
|
356
356
|
User: "Save it"
|
|
357
|
-
→ import_leads({campaignOfferId: "cmp_xxx", searchId: "search_xxx", targetLeadCount:
|
|
357
|
+
→ import_leads({campaignOfferId: "cmp_xxx", searchId: "search_xxx", targetLeadCount: 1000})
|
|
358
358
|
→ (wait for lead list to finish, ask user to confirm)
|
|
359
|
-
→ confirm_lead_list({campaignOfferId: "cmp_xxx", jobId: "<jobId from import_leads>",
|
|
359
|
+
→ confirm_lead_list({campaignOfferId: "cmp_xxx", jobId: "<jobId from import_leads>", reviewBatchLimit: 15})
|
|
360
360
|
→ wait_for_campaign_table_ready({campaignId: "cmp_xxx"})
|
|
361
361
|
→ get_campaign_context({campaignId: "cmp_xxx", refresh: true}) + get_rows_minimal(...)
|
|
362
362
|
</iteration_example>
|
|
@@ -378,17 +378,17 @@ User: "Save it"
|
|
|
378
378
|
Call after user selects a search to save
|
|
379
379
|
**IMPORTANT:** If response returns `needsModeSelection: true`, use `AskUserQuestion` to ask "add to existing leads or replace?" Do NOT assume.
|
|
380
380
|
|
|
381
|
-
- `confirm_lead_list` -
|
|
382
|
-
Parameters: campaignOfferId, sourceLeadListId (optional), currentStep (optional)
|
|
381
|
+
- `confirm_lead_list` - Copy confirmed lead list into campaign table
|
|
382
|
+
Parameters: campaignOfferId, sourceLeadListId (optional), reviewBatchLimit (optional, default 15), currentStep (optional)
|
|
383
383
|
Only call after user confirms the list looks good
|
|
384
|
-
Owns the filter-choice beat after
|
|
384
|
+
Owns the filter-choice beat after campaign rows exist; process only the first 15 review rows until later approvals
|
|
385
385
|
</mcp_tools>
|
|
386
386
|
|
|
387
387
|
<limits>
|
|
388
388
|
- 25 results per page
|
|
389
389
|
- Maximum 100 pages (2,500 leads)
|
|
390
|
-
- Default source target: about
|
|
391
|
-
|
|
390
|
+
- Default source import target: about 1,000 source contacts. The provider cap is
|
|
391
|
+
internal; do not present it as the customer-facing plan unless it is reached.
|
|
392
392
|
- Maximum 5 search calls per session
|
|
393
393
|
- If user needs more than 2,500: explain limit, suggest splitting by region
|
|
394
394
|
</limits>
|
|
@@ -24,12 +24,34 @@ When the user asks to find posts or start searching, **IMMEDIATELY begin Round 1
|
|
|
24
24
|
|
|
25
25
|
<lead_target>
|
|
26
26
|
|
|
27
|
-
- **Default
|
|
28
|
-
|
|
27
|
+
- **Default create-campaign target: ~300 good-fit prospects after cleanup,
|
|
28
|
+
enrichment, and fit filtering.**
|
|
29
|
+
- **Working assumption when no stronger sample exists: ~20% of raw post
|
|
30
|
+
engagers become good-fit prospects, so plan around ~1,500 raw engagers.**
|
|
31
|
+
- Provider/import caps are internal execution limits, not customer-facing
|
|
32
|
+
promises. Do not tell the user the internal provider cap.
|
|
29
33
|
- Quality > Quantity: a few hundred active users > 1000 potentially inactive profiles
|
|
30
34
|
- Focus on ACTIVE platform users who will actually see and respond to outreach
|
|
31
35
|
</lead_target>
|
|
32
36
|
|
|
37
|
+
<harvest_scrape_contract>
|
|
38
|
+
|
|
39
|
+
Production Signal Discovery uses Harvest for post comments and reactions.
|
|
40
|
+
Harvest returns about 100 comments or reactions per page. The source scrape
|
|
41
|
+
pages through Harvest up to the configured per-post caps, currently 1,500
|
|
42
|
+
reactions and 300 comments per selected post.
|
|
43
|
+
|
|
44
|
+
Important interpretation rule: a source list row count is the number of
|
|
45
|
+
headline-passing candidates inserted after scraping and filtering, not the raw
|
|
46
|
+
number of engagers fetched. If a selected post has 1,200 visible engagers and
|
|
47
|
+
the source list lands at 71 rows, read that as 71 headline-passing inserted
|
|
48
|
+
rows, not as "only 71 engagers were scraped." Do not reject a completed
|
|
49
|
+
non-empty source list solely because inserted rows are below the raw engager
|
|
50
|
+
target; confirm/copy it for the 15-row review sample, then decide whether to add
|
|
51
|
+
more posts or switch lanes based on sample quality and scale.
|
|
52
|
+
|
|
53
|
+
</harvest_scrape_contract>
|
|
54
|
+
|
|
33
55
|
<multi_round_search>
|
|
34
56
|
|
|
35
57
|
## Multi-Round Search Strategy
|
|
@@ -98,12 +120,12 @@ You must estimate:
|
|
|
98
120
|
- expected good-fit prospects per right-content post after dedupe/cleanup
|
|
99
121
|
- `postsNeededForTarget`
|
|
100
122
|
- number of right-content posts needed to reach the target good-fit lead
|
|
101
|
-
count, defaulting to
|
|
123
|
+
count, defaulting to 300 for Signal Discovery unless the campaign says
|
|
102
124
|
otherwise
|
|
103
125
|
- `requiredEngagersToScrape`
|
|
104
|
-
- `ceil(targetGoodFitLeads / sampledFitRate)`; for example
|
|
105
|
-
prospects per 100 engagers means a
|
|
106
|
-
1,
|
|
126
|
+
- `ceil(targetGoodFitLeads / sampledFitRate)`; for example the default
|
|
127
|
+
planning assumption of 20 good-fit prospects per 100 engagers means a
|
|
128
|
+
300-good-fit source target needs about 1,500 raw engagers scraped
|
|
107
129
|
- `planningFloor`
|
|
108
130
|
- minimum acceptable sampled/projected fit rate after conservative cleanup;
|
|
109
131
|
default 10%. Below this, do not scale Signal Discovery.
|
|
@@ -119,8 +141,8 @@ Use conservative logic:
|
|
|
119
141
|
those posts in the watched Signal Discovery UI before sampling engagers
|
|
120
142
|
- call `fetch_post_engagers`
|
|
121
143
|
- fetch only a representative first sample, not a full scrape
|
|
122
|
-
- default to
|
|
123
|
-
|
|
144
|
+
- default to a fast first sample of roughly 15 people for one post; when
|
|
145
|
+
comparing multiple posts, inspect roughly 15-40 people total
|
|
124
146
|
- score them against `headlineICPCriteria` or a rough yes/no headline rubric
|
|
125
147
|
- use headline and display-name cues only for this spot check; do not enrich people during viability estimation
|
|
126
148
|
- use that sampled pass rate to extrapolate conservatively
|
|
@@ -130,7 +152,7 @@ Use conservative logic:
|
|
|
130
152
|
- stale posts
|
|
131
153
|
- adjacent communities that are not actual buyers
|
|
132
154
|
4. Explain the pass-through briefly and explicitly:
|
|
133
|
-
- preferred: "`sampledCount`: 40, `passCount`: 9, `passRate`: ~22%, `goodFitPer100Engagers`: ~22 before cleanup / ~13-16 after cleanup, `requiredEngagersToScrape`: ~
|
|
155
|
+
- preferred: "`sampledCount`: 40, `passCount`: 9, `passRate`: ~22%, `goodFitPer100Engagers`: ~22 before cleanup / ~13-16 after cleanup, `requiredEngagersToScrape`: ~1,875-2,300 for a 300-good-fit target after cleanup, `avgReachableEngagersPerPost`: 240, `goodFitProspectsPerPost`: ~31-38, `postsNeededForTarget`: ~8-10, `recentStrongPostCount`: 15-25, `freshEnoughPostCount`: 8-12, `projectedRange`: 300-380 from selected posts"
|
|
134
156
|
- fallback: "I could not fetch engagers, so this is inferred from post and author quality only"
|
|
135
157
|
5. If the evidence is too weak, say so and return a low-confidence estimate instead of pretending precision.
|
|
136
158
|
6. If sampled/projected fit after cleanup is below the 10% planning floor,
|
|
@@ -385,7 +407,7 @@ For `create-campaign-v2` source approval, do not treat the default
|
|
|
385
407
|
`selectionTarget` of 3 posts as enough by itself. Before the final source
|
|
386
408
|
recommendation, estimate source capacity from real sample math:
|
|
387
409
|
|
|
388
|
-
- source target good-fit leads (default
|
|
410
|
+
- source target good-fit leads (default 300 for Signal Discovery unless the
|
|
389
411
|
campaign says otherwise)
|
|
390
412
|
- eligible right-content posts by lane/content type
|
|
391
413
|
- reachable engagers from those posts
|
|
@@ -450,18 +472,21 @@ to say **yes**.
|
|
|
450
472
|
|
|
451
473
|
For `create-campaign-v2` after the user has already approved the lead-source
|
|
452
474
|
decision, that approval is the explicit confirmation to materialize the approved
|
|
453
|
-
source list and then
|
|
475
|
+
source list and then copy the confirmed source rows into the campaign. In that
|
|
454
476
|
tail flow, follow `create-campaign-v2-tail`: call
|
|
455
477
|
`select_promising_posts({ campaignOfferId, selectionMode: "replace",
|
|
456
478
|
selections, headlineICPCriteria })`, then call
|
|
457
479
|
`import_leads({ campaignOfferId, provider: "signal-discovery",
|
|
458
|
-
|
|
480
|
+
targetEngagerCount, maxPostsToScrape })` for the approved
|
|
459
481
|
source-capacity plan without asking for another yes/no gate. Then
|
|
460
|
-
`confirm_lead_list
|
|
461
|
-
table
|
|
482
|
+
`confirm_lead_list({ reviewBatchLimit: 15 })` copies confirmed source rows into
|
|
483
|
+
the campaign table and returns the first 15 review/process rows. Do not confuse
|
|
484
|
+
the source-candidate target with the review sample size.
|
|
462
485
|
If the completed source scrape comes back below the approved source-candidate
|
|
463
|
-
target,
|
|
464
|
-
|
|
486
|
+
target but has usable rows, still call `confirm_lead_list` so the completed
|
|
487
|
+
source list is copied into the campaign and the first 15 rows can be reviewed.
|
|
488
|
+
Treat the shortfall as a scale warning: add more approved posts or move to Sales
|
|
489
|
+
Nav only after the first sample proves the lane is too thin or off-ICP.
|
|
465
490
|
|
|
466
491
|
The promotion/select step is required campaign state. Use post IDs from the
|
|
467
492
|
current campaign-scoped search result, not stale IDs copied from a source review
|
|
@@ -474,9 +499,8 @@ the source-list materialization.
|
|
|
474
499
|
```json
|
|
475
500
|
import_leads({
|
|
476
501
|
"campaignOfferId": "cmp_xxx",
|
|
477
|
-
"
|
|
478
|
-
"
|
|
479
|
-
"maxPostsToScrape": 5
|
|
502
|
+
"targetEngagerCount": 1500,
|
|
503
|
+
"maxPostsToScrape": 3
|
|
480
504
|
})
|
|
481
505
|
```
|
|
482
506
|
|
|
@@ -488,13 +512,13 @@ After the lead list finishes and the user confirms it looks good, call:
|
|
|
488
512
|
confirm_lead_list({
|
|
489
513
|
"campaignOfferId": "cmp_xxx",
|
|
490
514
|
"jobId": "<jobId from import_leads>",
|
|
491
|
-
"
|
|
515
|
+
"reviewBatchLimit": 15
|
|
492
516
|
})
|
|
493
517
|
```
|
|
494
518
|
|
|
495
519
|
Then run post-confirm routing in this order:
|
|
496
520
|
|
|
497
|
-
1. `confirm_lead_list` owns the watched move to `filter-choice` after
|
|
521
|
+
1. `confirm_lead_list` owns the watched move to `filter-choice` after confirmed campaign rows exist; do not call `update_campaign` to fix that step.
|
|
498
522
|
2. `wait_for_campaign_table_ready({ campaignId: "cmp_xxx" })`
|
|
499
523
|
3. `get_campaign_context({ campaignId: "cmp_xxx", refresh: true })` then `get_rows_minimal(...)`
|
|
500
524
|
|
|
@@ -516,8 +540,8 @@ Then run post-confirm routing in this order:
|
|
|
516
540
|
5. Standalone Signal Discovery flow: ask for explicit confirmation to import
|
|
517
541
|
leads (e.g., "Does this look right? Should I import leads now?").
|
|
518
542
|
`create-campaign-v2` tail flow: if the user already approved the source
|
|
519
|
-
decision, that approval is the import confirmation for the
|
|
520
|
-
|
|
543
|
+
decision, that approval is the import confirmation for the source list and
|
|
544
|
+
first review sample; do not ask again.
|
|
521
545
|
6. If confirmation exists, call `import_leads`. If not, refine
|
|
522
546
|
selections/criteria and ask again.
|
|
523
547
|
7. When the lead list finishes and the user confirms it looks good, call
|