@sellable/mcp 0.1.206 → 0.1.208

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 CHANGED
@@ -264,36 +264,25 @@ Parallel execution contract:
264
264
 
265
265
  - Source scout names come from `agents/registry.json` and are exposed at runtime
266
266
  through `get_source_scout_registry`. Add new scouts there first; installer,
267
- Codex config, Claude agent files, and prompts should consume the registry.
268
- - Post-find-leads scout names also come from `agents/registry.json` and are
269
- exposed through `get_post_find_leads_scout_registry`. After
270
- `confirm_lead_list` imports a non-empty review batch and rows are proven, ask
271
- the filter-choice question immediately. Do not load this registry or deep
272
- filter/message prompts before that question. Once the user answers, launch the
273
- message-generation scout from the same campaign/table basis. If the user
274
- chooses filters, also launch the filter-leads scout, show Filter Rules, save
275
- rubrics, then ask for filter approval. After approval, move to Filter Leads
276
- and show `Filters saved + waiting for message approval` while the message
267
+ Codex config, Claude agent files, and prompts can consume the registry for
268
+ explicit source-comparison/debug runs. Normal create-campaign source work
269
+ stays inline in the parent thread with the active provider MCP tools.
270
+ - `get_post_find_leads_scout_registry` returns only the Message Drafting worker
271
+ for normal create-campaign runs. After `confirm_lead_list` imports a non-empty
272
+ review batch and rows are proven, ask the filter-choice question immediately.
273
+ Do not load this registry or deep filter/message prompts before that question.
274
+ Once the user answers, launch Message Drafting from the same campaign/table
275
+ basis. If the user chooses filters, keep filter/rubric work in the parent
276
+ thread: show Filter Rules, load `references/filter-leads.md`, save rubrics,
277
+ then ask for filter approval. After approval, move to Filter Leads and show
278
+ `Filters saved + waiting for message approval` while the message
277
279
  recommendation is reviewed. If filters are skipped, move to Messages/message
278
280
  review. Enrichment/filtering and Generate Message cells wait for message
279
281
  approval.
280
- - Claude host: use the installed `source-scout-linkedin-engagement`,
281
- `source-scout-sales-nav`, and `source-scout-prospeo-contact` Task/Agent
282
- subagents for parallel lead-source scouting only when the current session
283
- exposes those agent names. Launch all credible lanes in one assistant message
284
- so Claude Code can run them concurrently/background.
285
- - Codex host: use named custom scouts for source-angle work when subagents are
286
- available: `source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
287
- `source-scout-prospeo-contact`. Use `multi_tool_use.parallel` for independent
288
- tool-call batches when subagents are unavailable or the work is only simple
289
- batched lookups.
290
- - For prospect setup, Codex/Claude should launch Prospect Filters
291
- (`post-find-leads-filter-scout`) and Message Drafting
292
- (`post-find-leads-message-scout`) in the same turn/message when those
293
- subagents are available in the current session.
294
- If not, run them sequentially with MCP tools/assets, do not surface install
295
- status to the customer, and do not claim parallel work.
296
- - If neither backend is available, run sequentially with the same output schema.
282
+ - Source scouts and Prospect Filters are not normal create-campaign background
283
+ agents. Only Message Drafting may spawn as a background/custom agent on the
284
+ normal path; if it cannot be launched and the user does not approve inline
285
+ fallback, stop instead of silently drafting in the parent thread.
297
286
 
298
287
  Config path resolution (in order):
299
288
 
@@ -21,12 +21,14 @@ Use the live campaign inputs supplied by the parent thread:
21
21
 
22
22
  - `campaignId`
23
23
  - campaign revision or `campaignUpdatedAt`
24
- - `campaignBrief` / campaign brief content model
24
+ - campaign brief summary from the parent, then the current `campaignBrief` /
25
+ campaign brief content loaded through Sellable tools
25
26
  - selected source decision and provider state
26
27
  - `selectedLeadListId` or selected source list context
27
28
  - `workflowTableId`
28
- - initial campaign-table execution slice rows from that selected list, including row IDs
29
- and a sample row hash when available
29
+ - compact initial campaign-table execution-slice basis: copied source row count,
30
+ review-batch row count, and review-batch basis/hash. Do not require the
31
+ parent to paste a long review-batch row-id list.
30
32
  - filter basis at branch start: `pending`, `use-filters`, or `skip-filters`
31
33
  - any already-saved fit/rubric result summaries supplied by the parent
32
34
 
@@ -38,22 +40,34 @@ read stale local markdown files to reconstruct campaign state.
38
40
  All live reads must come from scoped MCP/product tools by campaign and
39
41
  workspace, such as `get_campaign`, `get_campaign_context`, and
40
42
  `get_rows_minimal({ tableId: workflowTableId })`, or from equivalent parent
41
- thread payloads. Reject the task as `blocked` if the campaign id, workspace,
42
- `selectedLeadListId`, `workflowTableId`, or execution-slice row ids do not match
43
- the branch input.
43
+ thread payloads. Load the current campaign brief and the current review-batch
44
+ rows from those tools before drafting. Reject the task as `blocked` if the
45
+ campaign id, workspace, `selectedLeadListId`, `workflowTableId`, review-batch
46
+ row count, or review-batch basis/hash does not match the branch input.
44
47
 
45
48
  ## Required First Steps
46
49
 
47
- 1. Load the full normal-path message prompt:
50
+ 1. Load the current campaign brief and compact campaign/table state:
51
+ campaign name, `campaignId`, `selectedLeadListId`, `workflowTableId`,
52
+ copied source row count, review-batch row count, review-batch basis/hash,
53
+ selected source summary, filter choice, and parent-supplied brief summary.
54
+ Then read the current campaign/table state through scoped Sellable tools.
55
+ Do not ask the parent to paste row data or a long row-id list.
56
+ 2. Load the full normal-path message prompt:
48
57
 
49
58
  `get_subskill_prompt({ subskillName: "generate-messages" })`
50
59
 
51
- 2. Use that prompt as the drafting contract. Do not use any alternate prompt,
52
- examples-only shortcut, or create-campaign safety/checklist instructions as a
53
- substitute for the full message prompt.
54
- 3. Draft only from the campaign brief, selected source context, and initial
55
- campaign-table execution slice rows supplied by the parent.
56
- 4. Keep the work provisional until the user chooses `Use Template` in Messages.
60
+ 3. Load the reference assets required by that prompt's Reference Asset Loading
61
+ pack, including validation/QA criteria. If a required validation asset cannot
62
+ load, return `blocked` or `retry-needed` instead of drafting from memory.
63
+ 4. Use that prompt as the drafting and QA contract. Do not use any alternate
64
+ prompt, examples-only shortcut, or create-campaign safety/checklist
65
+ instructions as a substitute for the full message prompt.
66
+ 5. Draft only from the current campaign brief, selected source context, and
67
+ review-batch rows loaded through scoped Sellable tools.
68
+ 6. Run the normal message validation/QA rules before final return. The final
69
+ recommendation must include the QA pass/fail receipt, not just draft copy.
70
+ 7. Keep the work provisional until the user chooses `Use Template` in Messages.
57
71
 
58
72
  ## Owned Output
59
73
 
@@ -64,10 +78,12 @@ Return the following to the parent thread:
64
78
  - one rendered good-fill sample for a plausible passing campaign-table row
65
79
  - one omit/fallback sample when the row signal is not safe
66
80
  - pass/fail notes against the generate-messages quality gates
81
+ - `qaReceipt` / validation notes showing token safety, proof safety, fit
82
+ uncertainty, bad-fill avoidance, and "would I take this call?" judgment
67
83
  - message-draft runtime status: `ready`, `blocked`, `retry-needed`, or `stale`
68
84
  - basis token containing campaign revision/updatedAt, brief hash,
69
- `selectedLeadListId`, `workflowTableId`, execution-slice row ids/hash, filter
70
- choice, and rubric/filter basis when present
85
+ `selectedLeadListId`, `workflowTableId`, compact execution-slice row
86
+ count/hash, filter choice, and rubric/filter basis when present
71
87
  - output timestamp/hash and any retry/error detail
72
88
 
73
89
  Do not write local markdown/json artifacts in normal live campaign runs. Return
@@ -98,7 +114,7 @@ row data became available after this branch started.
98
114
 
99
115
  Treat later filter/enrichment data as optional rewrite context. If campaign id,
100
116
  brief hash, selected source, `selectedLeadListId`, `workflowTableId`, and
101
- execution-slice row ids/hash still match, keep the initial recommendation usable
117
+ execution-slice row count/hash still match, keep the initial recommendation usable
102
118
  and report `status: ready` with `basisStatus: "usable_initial"` or
103
119
  `"enriched_rewrite_available"`. The parent thread may offer the user a choice
104
120
  to keep the initial draft or rewrite with enriched/filter data, but the rewrite
@@ -107,9 +123,32 @@ must be explicit user opt-in.
107
123
  Retry or regenerate without asking only when the initial recommendation is
108
124
  missing, failed, structurally invalid, unsafe, or mismatched on campaign id,
109
125
  brief hash, selected source, `selectedLeadListId`, `workflowTableId`, or
110
- execution-slice rows. Filter/rubric/enrichment basis drift alone is not a stale
126
+ execution-slice row count/hash. Filter/rubric/enrichment basis drift alone is not a stale
111
127
  blocker.
112
128
 
129
+ ## User Revision Feedback And QA
130
+
131
+ If the parent sends user feedback, a QA request, or a rewrite request about the
132
+ template before `approve-message`, treat it as Message Drafting work, not a
133
+ campaign write. Use the current `messageDraftRecommendation`, basis token/hash,
134
+ campaign/table basis, and latest user feedback as inputs. Load or reuse the full
135
+ `generate-messages` contract and validation assets, then return a revised or
136
+ QA-only recommendation with:
137
+
138
+ - revised proposed template
139
+ - what changed and why
140
+ - token fill rule/fallback changes, if any
141
+ - one rendered good-fill sample
142
+ - `qaReceipt` with pass/fail notes against the loaded validation assets
143
+ - pass/fail notes against the same quality gates
144
+ - updated output timestamp/hash and basis token
145
+
146
+ Keep the revision grounded in the same source/list/table rows unless the parent
147
+ explicitly supplies a new selected list or review slice. Do not call
148
+ `update_campaign_brief`, do not persist the template, and do not approve your
149
+ own revision. The parent renders the revised template and waits for
150
+ `approve-message`.
151
+
113
152
  ## Hard Rules
114
153
 
115
154
  - Do not call product Generate Message cells. This worker drafts the template
@@ -86,7 +86,7 @@ export interface SourceScoutRegistryResponse {
86
86
  }
87
87
  export interface PostFindLeadsScoutRegistryResponse {
88
88
  version: number;
89
- trigger: "find_leads_source_approved";
89
+ trigger: "message_drafting_after_confirm_lead_list";
90
90
  requiredInputs?: string[];
91
91
  scouts: Array<{
92
92
  id: string;
@@ -147,7 +147,7 @@ export const promptToolDefinitions = [
147
147
  },
148
148
  {
149
149
  name: "get_source_scout_registry",
150
- description: "Return the canonical Sellable source-scout agent names and host filenames. Use this before the source-finding step so Codex and Claude can launch the same named scouts from one registry when the current host exposes them.",
150
+ description: "Return the canonical Sellable source-scout agent names and host filenames for explicit source-comparison/debug runs only. Normal create-campaign source work stays inline in the parent thread.",
151
151
  inputSchema: {
152
152
  type: "object",
153
153
  properties: {},
@@ -157,7 +157,7 @@ export const promptToolDefinitions = [
157
157
  },
158
158
  {
159
159
  name: "get_post_find_leads_scout_registry",
160
- description: "Return canonical Sellable prospect-setup worker names for Prospect Filters and Message Drafting after Start Import copies confirmed source rows.",
160
+ description: "Return the canonical Sellable Message Drafting worker name after Start Import copies confirmed source rows. Prospect filters stay inline in the parent thread in normal create-campaign runs.",
161
161
  inputSchema: {
162
162
  type: "object",
163
163
  properties: {},
@@ -257,25 +257,26 @@ export function getSourceScoutRegistry() {
257
257
  legacy: agent.legacy,
258
258
  })),
259
259
  usage: {
260
- codex: "Source finding is sequential by default. Launch multiple returned `name` values in one assistant turn only when the user asked for comparison, a prior lane failed, or the active flow marks the first lane borderline.",
261
- claude: "Source finding is sequential by default. Invoke multiple Task/Agent subagents with subagent_type equal to returned `name` values only when comparison, fallback, or borderline-source conditions apply.",
262
- parentThreadRule: "Named agents are optional acceleration. If they are absent, do not customer-surface install status; run the same provider probes with MCP tools from the parent thread. Default fallback order: Signal Discovery / LinkedIn engagement, then Sales Nav recent activity, then broader Sales Nav title search, then Prospeo account/contact search. Do not preload every provider prompt before spawning agents; each scout loads only the provider prompt for its lane.",
260
+ codex: "Source finding is parent-thread and sequential by default in create-campaign. Do not launch source scouts in the normal campaign flow. Returned `name` values are for explicit source-comparison/debug runs only.",
261
+ claude: "Source finding is parent-thread and sequential by default in create-campaign. Do not invoke source-scout Task/Agent workers in the normal campaign flow. Returned `name` values are for explicit source-comparison/debug runs only.",
262
+ parentThreadRule: "Normal create-campaign source work stays inline in the parent thread with MCP provider tools. Default fallback order: Signal Discovery / LinkedIn engagement, then Sales Nav recent activity, then broader Sales Nav title search, then Prospeo account/contact search. Do not preload every provider prompt; load only the provider prompt for the active sequential source.",
263
263
  },
264
264
  };
265
265
  }
266
266
  export function getPostFindLeadsScoutRegistry() {
267
267
  const registry = readAgentRegistry();
268
- const scouts = registry.agents.filter((agent) => String(agent.kind || "") === "post-find-leads-scout");
268
+ const scouts = registry.agents.filter((agent) => String(agent.kind || "") === "post-find-leads-scout" &&
269
+ String(agent.target || agent.id || "") === "generate-messages");
269
270
  return {
270
271
  version: registry.version,
271
- trigger: "find_leads_source_approved",
272
+ trigger: "message_drafting_after_confirm_lead_list",
272
273
  requiredInputs: [
273
274
  "campaignId",
274
275
  "campaign revision or campaignUpdatedAt",
275
276
  "campaignBrief",
276
277
  "source decision and selectedLeadList/source state",
277
278
  "workflowTableId",
278
- "initial campaign-table execution slice rows from selectedLeadList with row ids/hash",
279
+ "compact review-batch row count and basis/hash; branch reads rows through scoped tools",
279
280
  "filter choice and filter/rubric basis when present",
280
281
  ],
281
282
  scouts: scouts.map((agent) => ({
@@ -305,10 +306,10 @@ export function getPostFindLeadsScoutRegistry() {
305
306
  })),
306
307
  joinGate: {
307
308
  afterAllComplete: true,
308
- requiredState: ["leadScoringRubrics", "messageDraftRecommendation"],
309
+ requiredState: ["messageDraftRecommendation"],
309
310
  noFilterRequiredState: ["messageDraftRecommendation"],
310
311
  skipFilterRule: "leadScoringRubrics may be absent only when the user explicitly skips filters with enableICPFilters=false; messageDraftRecommendation is still required before template review.",
311
- show: ["readable_filters_with_reasons", "sample_message_for_approval"],
312
+ show: ["sample_message_for_approval", "message_qa_receipt"],
312
313
  nextStage: "message-review",
313
314
  },
314
315
  messageDraftBranchContract: {
@@ -328,15 +329,16 @@ export function getPostFindLeadsScoutRegistry() {
328
329
  "basisToken",
329
330
  "basis.selectedLeadListId",
330
331
  "basis.workflowTableId",
331
- "basis.reviewSampleRowHash or basis.reviewSampleRowIds",
332
+ "basis.reviewSampleRowCount",
333
+ "basis.reviewSampleRowHash",
332
334
  ],
333
- promptRequired: 'get_subskill_prompt({ subskillName: "generate-messages" }); the full generate-messages prompt and its Reference Asset Loading pack are required inside the Message Drafting branch for normal message drafting. If required assets cannot be loaded, return blocked/retry-needed instead of drafting from prompt memory.',
335
+ promptRequired: 'Load current campaign brief/table state through scoped tools, then get_subskill_prompt({ subskillName: "generate-messages" }); the full generate-messages prompt and its Reference Asset Loading pack, including message validation/QA assets requested by that prompt, are required inside the Message Drafting branch for normal drafting, QA, and user-requested rewrites. If required assets cannot be loaded, return blocked/retry-needed instead of drafting from prompt memory.',
334
336
  basisFields: [
335
337
  "campaign revision or updatedAt",
336
338
  "brief hash",
337
339
  "selectedLeadListId",
338
340
  "workflowTableId",
339
- "initial campaign-table execution slice row ids/hash",
341
+ "compact initial campaign-table execution slice row count/hash",
340
342
  "filter choice",
341
343
  "filter/rubric basis when present",
342
344
  ],
@@ -345,19 +347,21 @@ export function getPostFindLeadsScoutRegistry() {
345
347
  "tokenFillRules",
346
348
  "renderedSample",
347
349
  "concerns",
350
+ "revisionNotes when user feedback triggered a revision",
348
351
  "status",
349
352
  "basisStatus",
350
353
  "basisToken",
354
+ "qaReceipt or validationNotes",
351
355
  "outputAt",
352
356
  "outputHash",
353
357
  "error or retry detail",
354
358
  ],
355
- reusePolicy: "The first completed Message Drafting recommendation remains the default review candidate. Later Prospect Filters, Filter Leads, enrichment, or rubric completion may make an enriched rewrite available, but does not automatically retry or replace the initial draft unless campaign/brief/source/list/table/review-sample identity mismatches or the initial output failed.",
359
+ reusePolicy: "The first completed Message Drafting recommendation remains the default review candidate. Later Prospect Filters, Filter Leads, enrichment, or rubric completion may make an enriched rewrite available, but does not automatically retry or replace the initial draft unless campaign/brief/source/list/table/review-sample identity mismatches or the initial output failed. User copy feedback before approve-message is an explicit Message Drafting revision and must be routed back through the message branch with the current recommendation and basis.",
356
360
  },
357
361
  usage: {
358
- codex: "After confirm_lead_list copies source rows and the initial campaign-table execution slice exists, ask the filter-choice question immediately. Do not spawn returned prospect-setup worker names before that question. Once the user answers, spawn Message Drafting from the same campaign/table basis whenever Codex agent-launch policy is satisfied. Treat YOLO/autonomous mode as campaign-scoped permission to use Sellable background agents for pre-launch work. If the user has not enabled YOLO and has not explicitly asked for background agents/subagents/parallel agents/delegation/message bg agent in this campaign, ask once for permission before loading generate-messages in the parent. If permission is granted and the named custom agent is unavailable, spawn a generic gpt-5.5 xhigh background agent with the same campaign/table basis. If the user chooses filters, also spawn Prospect Filters when allowed, move to Filter Rules, save rubrics, ask for filter approval, then keep the browser on Filter Leads and show `Filters saved + waiting for message approval` while the message recommendation is reviewed. If filters are skipped, move to Messages/message review.",
359
- claude: "After confirm_lead_list copies source rows and the initial campaign-table execution slice exists, ask the filter-choice question immediately. Do not invoke returned prospect-setup Task/Agent names before that question. Once the user answers, invoke Message Drafting from the same campaign/table basis. If the user chooses filters, also invoke Prospect Filters, move to Filter Rules, save rubrics, ask for filter approval, then keep the browser on Filter Leads and show `Filters saved + waiting for message approval` while the message recommendation is reviewed. If filters are skipped, move to Messages/message review.",
360
- parentThreadRule: 'Message drafting is agent-first, not optional acceleration. If post-find-leads-message-scout is available, run that compatibility agent as background Message Drafting after the filter-choice answer. In Codex, YOLO/autonomous mode counts as campaign-scoped permission to use Sellable background agents for pre-launch work; if the user has not enabled YOLO and has not explicitly asked for background agents/subagents/parallel agents/delegation/message bg agent in this campaign, ask once for that permission before loading generate-messages in the parent. If permission is granted and the named custom agent is unavailable, spawn a generic gpt-5.5 xhigh background agent with the same campaign/table basis. Do not silently fall back to parent-thread message drafting. The parent may run the message branch inline only if the user explicitly says to continue without a background agent; when doing so, state that message generation is running inline. Local markdown/json files are not normal-path inputs. The filter-choice question is the first post-import user gate; do not load prospect-setup registries or filter references before it. Message drafting starts after the filter-choice answer, must load get_subskill_prompt({ subskillName: "generate-messages" }) and its Reference Asset Loading pack inside the branch or explicitly approved inline fallback, must read live campaign table state through scoped MCP/product tools, and must reject mismatched selectedLeadListId/workflowTableId/campaign/workspace input. Do not use any alternate or examples-only message prompt. On the filter path, keep the browser on Filter Rules after save_rubrics so the user can approve the saved criteria; only then move to Filter Leads, show `Filters saved + waiting for message approval`, and wait there for message approval. Enrichment, filtering, Generate Message cells, sender setup, sequence attach, and launch wait for template approval on the Use Template path. On the skip path, move to Messages/message review and wait for message approval before enrichment or Settings. Do not render message review from checklist or shortcut instructions; message review requires a messageDraftRecommendation whose basis proves the generate-messages prompt ran for the current campaign/table execution slice. Do not automatically rerun Message Drafting after filters/enrichment finish; show the initial draft by default and offer an enriched rewrite only with explicit user opt-in.',
362
+ codex: "After confirm_lead_list copies source rows and the initial campaign-table execution slice exists, ask the filter-choice question immediately. Do not spawn anything before that question. Once the user answers, spawn only Message Drafting from the same campaign/table basis whenever Codex agent-launch policy is satisfied. Treat YOLO/autonomous mode as campaign-scoped permission for this single message background agent. If the user has not enabled YOLO and has not explicitly asked for background agents/subagents/parallel agents/delegation/message bg agent in this campaign, ask once for permission before loading generate-messages in the parent. If permission is granted and the named custom agent is unavailable, spawn a generic gpt-5.5 xhigh Message Drafting background agent with the same campaign/table basis. If filters are chosen, do filter/rubric work inline in the parent thread while Message Drafting runs, then keep the browser on Filter Leads and show `Filters saved + waiting for message approval` while the message recommendation is reviewed. If filters are skipped, move to Messages/message review.",
363
+ claude: "After confirm_lead_list copies source rows and the initial campaign-table execution slice exists, ask the filter-choice question immediately. Do not invoke any Task/Agent before that question. Once the user answers, invoke only Message Drafting from the same campaign/table basis. If filters are chosen, do filter/rubric work inline in the parent thread while Message Drafting runs, then keep the browser on Filter Leads and show `Filters saved + waiting for message approval` while the message recommendation is reviewed. If filters are skipped, move to Messages/message review.",
364
+ parentThreadRule: 'Message Drafting is the only normal create-campaign background agent. If post-find-leads-message-scout is available, run that compatibility agent after the filter-choice answer so it works while the parent thread handles filter/rubric setup inline. In Codex, YOLO/autonomous mode counts as campaign-scoped permission for this single message background agent; if the user has not enabled YOLO and has not explicitly asked for background agents/subagents/parallel agents/delegation/message bg agent in this campaign, ask once for permission before loading generate-messages in the parent. If permission is granted and the named custom agent is unavailable, spawn a generic gpt-5.5 xhigh Message Drafting background agent with the same campaign/table basis. Do not spawn source scouts or Prospect Filters in the normal create-campaign flow. Do not silently fall back to parent-thread message drafting. The Message Drafting handoff must be compact: campaign identity/name, brief summary, source summary, selectedLeadListId, workflowTableId, copied source row count, review-batch row count/hash, and filter choice. Do not paste full reviewBatchRowIds, row data, or local debug artifacts into the spawn prompt; the branch must load the current campaign brief, campaign/table state, review rows, full generate-messages prompt, and validation/QA assets through scoped tools. The parent may run the message branch inline only if the user explicitly says to continue without a background agent; when doing so, state that message generation is running inline. Local markdown/json files are not normal-path inputs. The filter-choice question is the first post-import user gate; do not load this registry or filter references before it. Message drafting starts after the filter-choice answer, must load get_subskill_prompt({ subskillName: "generate-messages" }) and its Reference Asset Loading plus message validation/QA assets inside the branch or explicitly approved inline fallback, must read live campaign table state through scoped MCP/product tools, and must reject mismatched selectedLeadListId/workflowTableId/campaign/workspace input. Do not use any alternate or examples-only message prompt. User copy feedback, message QA, or rewrite requests before approve-message must be routed back to Message Drafting with the current recommendation, basis token, campaign/table basis, and latest user text; the parent must not rewrite or QA the template from memory and must not call update_campaign_brief before approve-message. On the filter path, the parent thread keeps the browser on Filter Rules after save_rubrics so the user can approve the saved criteria; only then move to Filter Leads, show `Filters saved + waiting for message approval`, and wait there for message approval. Enrichment, filtering, Generate Message cells, sender setup, sequence attach, and launch wait for template approval on the Use Template path. On the skip path, move to Messages/message review and wait for message approval before enrichment or Settings. Do not render message review from checklist or shortcut instructions; message review requires a messageDraftRecommendation whose basis proves the generate-messages prompt and QA assets ran for the current campaign/table execution slice. Do not automatically rerun Message Drafting after filters/enrichment finish; show the initial draft by default and offer an enriched rewrite only with explicit user opt-in.',
361
365
  },
362
366
  };
363
367
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.206",
3
+ "version": "0.1.208",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -248,25 +248,12 @@ summary should be a compact `## Source Recommendation` block with:
248
248
  - fallback: switch to active LinkedIn profiles if the first sample is too noisy
249
249
  or has too few prospects
250
250
 
251
- When the user has not supplied a source and multiple source angles are viable,
252
- scout those angles as independent branches when the host can actually do it:
253
- LinkedIn posts / people reacting or commenting (internal `signal-discovery`
254
- provider prompt), Sales Nav / title + company filters, and Prospeo Contact /
255
- domains, hiring filters, or broad verified-contact expansion when relevant. In
256
- Codex, explicitly spawn the named custom scouts
257
- `source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
258
- `source-scout-prospeo-contact` for the credible lanes only when the current host
259
- exposes those names; Codex does not infer subagent fan-out from generic source
260
- comparison wording. In Claude Code, invoke the generated `source-scout-*`
261
- Task/Agent subagents for all credible lanes in one assistant message only when
262
- the current session lists those names. The installer writes them from the same
263
- canonical Sellable agent registry with explicit Sellable MCP tool allowlists.
264
- The create-campaign-v2 subskill calls `get_source_scout_registry` before
265
- dispatch so the current registry, not this copy, is the runtime source of truth.
266
- If the host runs them sequentially or the named agents are unavailable, do not
267
- claim they ran in parallel and do not surface install status to the customer. In
268
- chat, call the downstream copy stage `message generation`; message validation is
269
- only an internal approval proof.
251
+ Source discovery stays inline in the parent thread for normal create-campaign
252
+ runs. Use the approved provider prompt and MCP tools sequentially; do not spawn
253
+ source-scout background agents unless the user explicitly asks for a source
254
+ comparison/debug run. Do not claim a scout ran unless one did, and do not surface
255
+ install status to the customer. In chat, call the downstream copy stage
256
+ `message generation`; message validation/QA is owned by Message Drafting.
270
257
 
271
258
  For campaign-attached Signal Discovery sampling, promote/select the exact posts
272
259
  with `select_promising_posts` before `fetch_post_engagers` so the user can see
@@ -279,20 +266,27 @@ math should import the smallest set that covers a target. The watch guide should
279
266
  say that we are checking people from these posts to confirm the right people are
280
267
  actually engaging and the source is viable.
281
268
 
282
- After confirmed source rows exist in the campaign table, use the same registry pattern for
283
-
284
- prospect setup work, but do not load that registry or any deep filter/message prompt
269
+ After confirmed source rows exist in the campaign table, do not load the
270
+ message registry or any deep filter/message prompt
285
271
  before the filter-choice question. After `confirm_lead_list`, ask add filters
286
- vs skip filters immediately. Once the user answers, launch Message Drafting
287
- from the same campaign/table basis. If the user chooses filters, also launch the
288
- Prospect Filters worker, move to Filter Rules, save rubrics, then ask for filter
289
- approval. After approval, move to Filter Leads and show `Filters saved + waiting
290
- for message approval` while the message recommendation is reviewed. If the user
291
- skips filters, move to Messages/message review. Enrichment/filtering and
292
- Generate Message cells wait for message approval. AI Generated is an explicit
293
- opt-out from the template path. If the
294
- prospect setup agents are absent, the main thread still orchestrates the same
295
- branches from compact MCP context.
272
+ vs skip filters immediately. Once the user answers, launch only Message Drafting
273
+ from the same campaign/table basis. If the user chooses filters, the parent
274
+ thread moves to Filter Rules, loads the filter reference, saves rubrics, then
275
+ asks for filter approval while Message Drafting runs. After approval, move to
276
+ Filter Leads and show `Filters saved + waiting for message approval` while the
277
+ message recommendation is reviewed. If the user skips filters, move to
278
+ Messages/message review. Enrichment/filtering and Generate Message cells wait
279
+ for message approval. AI Generated is an explicit opt-out from the template
280
+ path.
281
+
282
+ The Message Drafting handoff must stay compact. Include campaign identity,
283
+ campaign name, `selectedLeadListId`, `workflowTableId`, copied source row count,
284
+ review-batch row count, review-batch basis/hash, filter choice, source summary,
285
+ and a concise campaign brief summary. Do not paste the full review-batch row ID
286
+ list or row data into the spawn prompt. Message Drafting must load the current
287
+ campaign brief, campaign/table state, and review-batch rows through Sellable
288
+ tools, then load the normal message validation/QA rules and run a QA pass before
289
+ returning its concise review-ready recommendation.
296
290
 
297
291
  Use rendered Markdown for user review surfaces, not fenced code blocks. Keep
298
292
  lines short, use indexed section labels and bullets, and translate internal
@@ -423,26 +417,19 @@ Treat host capabilities as concrete functions, not prose conventions:
423
417
  - `load_subprompt_asset`: call
424
418
  `mcp__sellable__get_subskill_asset({ subskillName, assetPath, offset?, limit? })`
425
419
  and continue chunks until `hasMore` is false.
426
- - `load_source_scout_registry`: call
427
- `mcp__sellable__get_source_scout_registry({})` before any scout dispatch.
420
+ - `load_source_scout_registry`: explicit source-comparison/debug runs only; do
421
+ not call it in the normal create-campaign source path.
428
422
  - `load_post_find_leads_scout_registry`: call
429
423
  `mcp__sellable__get_post_find_leads_scout_registry({})` after source
430
- import and before dispatching Prospect Filters/Message Drafting.
431
- - `launch_source_scout`: Claude Code uses `Task` with `subagent_type` equal to
432
- the registry `name` only when the session lists those agents; Codex uses
433
- named custom agents such as
434
- `source-scout-linkedin-engagement`, `source-scout-sales-nav`, and
435
- `source-scout-prospeo-contact` when subagents are available.
436
- - `launch_post_find_leads_scout`: Claude Code uses `Task` with `subagent_type`
437
- equal to the returned prospect-setup registry `name` only when the session
438
- lists those agents; Codex uses the returned compatibility agents such as
439
- `post-find-leads-filter-scout` and `post-find-leads-message-scout` when
440
- subagents are available.
424
+ import and before dispatching Message Drafting only.
425
+ - `launch_message_drafting`: Claude Code uses `Task` with `subagent_type`
426
+ `post-find-leads-message-scout` when listed; Codex uses the returned
427
+ compatibility agent or a generic `gpt-5.5` / `xhigh` Message Drafting agent.
441
428
 
442
429
  If a required interactive question function or MCP loader is missing, stop and
443
- explain the Sellable install/reload problem. Named scout agents are optional
444
- acceleration: if they are absent, do not surface install status to the customer;
445
- fall back to product-native MCP orchestration instead of local scripts.
430
+ explain the Sellable install/reload problem. Source and filter work use
431
+ product-native MCP orchestration in the parent; the only normal background
432
+ branch is Message Drafting.
446
433
 
447
434
  Never narrate local draft housekeeping to the user. If you create directories,
448
435
  save drafts, write artifacts, or persist intermediate state, translate it into
@@ -764,7 +751,7 @@ updates.
764
751
  and the current host policy allows agent launch. The worker must load
765
752
  `mcp__sellable__get_subskill_prompt({ subskillName: "generate-messages" })`.
766
753
  In Codex, YOLO/autonomous mode counts as campaign-scoped permission to use
767
- Sellable background agents for pre-launch work. If the user has not enabled
754
+ this single Message Drafting background agent. If the user has not enabled
768
755
  YOLO and has not explicitly asked for background agents, subagents, parallel
769
756
  agents, delegation, or a message/bg agent in this campaign, ask once for
770
757
  permission before loading the long message prompt in the parent. If
@@ -774,17 +761,24 @@ updates.
774
761
  silently fall back to parent-thread message drafting; parent fallback is
775
762
  allowed only when the user explicitly says to continue without a background
776
763
  agent.
777
- Do not use any alternate or examples-only message prompt. Message review requires Message Drafting output:
764
+ Do not use any alternate or examples-only message prompt. Message review and
765
+ message QA require Message Drafting output:
778
766
  do not draft from a checklist, local markdown artifact, or parent-thread
779
767
  intuition. Use campaign state, campaign brief content, selected source state, and
780
768
  initial campaign-table execution slice rows as the source of truth; do not read stale local
781
769
  markdown such as `message-validation.md`, inspect the database directly, or
782
- synthesize local validation artifacts from general knowledge.
770
+ synthesize local validation artifacts from general knowledge. The handoff to
771
+ Message Drafting should pass compact basis only, not a long row-id list; the
772
+ branch loads current brief/table rows and validation assets itself.
783
773
  5. Create the campaign shell early with the v1 brief so the user can open the
784
774
  watch link and see useful setup state immediately. Materialize the approved
785
775
  source list, copy confirmed rows into the campaign, and internally process the
786
- first campaign-table execution slice after the source is attached to the campaign; do not
787
- queue workflow cells, attach a sequence, or start until saved filters and the
776
+ first campaign-table execution slice after the source is attached to the
777
+ campaign; do not load prospect-setup registries/prompts before asking add
778
+ filters vs skip filters. Once the user answers, launch only Message Drafting
779
+ from the same campaign/table basis. If filters are approved, do filter/rubric
780
+ work inline in the parent thread. Do not queue workflow cells, attach a
781
+ sequence, or start until saved filters and the
788
782
  message template/token rules are approved. When filters are chosen, immediately
789
783
  call `mcp__sellable__update_campaign({ campaignId, enableICPFilters: true, currentStep: "create-icp-rubric", watchNarration })`
790
784
  so the watched app moves to Filter Rules while rubrics are drafted/saved.