@sellable/mcp 0.1.116 → 0.1.117

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/dist/index-dev.js CHANGED
File without changes
package/dist/index.js CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.116",
3
+ "version": "0.1.117",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -165,47 +165,31 @@ linked skill versions, runbooks, npm/package details, repo-local files, VPS or
165
165
  browser automation limitations, or local skill files in normal customer-facing
166
166
  copy.
167
167
 
168
- ## Watch Link Handoff
169
-
170
- When a campaign tool returns `watchUrl`, treat it as a user-opened watch link.
171
- A valid handoff link must be a safe direct
172
- `/campaign-builder/{campaignId}?mode=claude|codex|watch` URL.
173
- `create_campaign.watchUrl`, `create_campaign({ campaignId }).watchUrl`, and
174
- `get_campaign.watchUrl` are all acceptable only when they return that direct
175
- campaign-builder shape, with `workspaceId` used only as a safe routing hint when
176
- needed.
177
-
178
- Do not claim Sellable can force every host to open links in a specific browser.
179
- The host controls link-click behavior. Do not call Chrome, browser automation,
180
- shell `open`, Computer Use, or in-app browser-control tools just because a
181
- watch link exists.
182
-
183
- - In Codex Desktop, clicking a URL can open the Codex in-app browser, but that
184
- browser is only reliable for unauthenticated/public pages. Sellable campaign
185
- watch pages may need a signed-in session. Tell the user to click the link
186
- first; if it lands on sign-up/auth, they should open the same link in their
187
- regular browser to watch real-time updates.
188
- - In Claude Code, provide the link and direct the user to open it in their
189
- browser. If their Claude Code setup opens links in an in-app/preview browser,
190
- that is fine, but do not attempt to open Chrome for them.
191
-
192
- Make the direct watch link easy to copy/open, then continue with explicit
193
- customer-facing campaign progress and `get_campaign_navigation_state`
194
- orientation checks. Use this fallback shape:
168
+ ## Codex Watch Link Handoff
169
+
170
+ When a campaign tool returns `watchUrl`, treat it as a user-opened app link, not
171
+ as permission to drive the browser. A valid handoff link must be a direct
172
+ `/campaign-builder/{campaignId}?mode=claude|codex` URL with the auth token and
173
+ workspace routing needed for auto-login. `create_campaign.watchUrl`,
174
+ `create_campaign({ campaignId }).watchUrl`, and `get_campaign.watchUrl` are all
175
+ acceptable only when they return that direct campaign-builder shape.
176
+
177
+ Never call browser-opening tools, shell `open`, Computer Use, or in-app browser
178
+ automation just because a watch link exists. Print the link and tell the user to
179
+ Command-Enter/click it when they want to watch in the app. Use this shape:
195
180
 
196
181
  ```text
197
- Watch link: [Open campaign]({watchUrl})
182
+ Watch link: {watchUrl}
198
183
 
199
- Click that link to watch the campaign. If it opens in an in-app browser and asks
200
- you to sign in, open the same link in your regular browser so you can watch
201
- real-time updates from your signed-in session. I’ll keep the brief, lead source,
202
- and message-review steps explicit here as I build.
184
+ Command-Enter or click that link to watch the campaign in Sellable. I’ll keep
185
+ the brief, lead source, and message-review steps explicit here as I build.
203
186
  ```
204
187
 
205
- If the user reports that the watch link lands on auth, 404, permission, blank,
206
- or an error state, recover a fresh watch link once with
207
- `create_campaign({ campaignId })` or `get_campaign`, then print the recovered
208
- link. Do not claim the browser was opened, inspected, or synchronized.
188
+ The watch link should auto-login through the token in the URL. If the user says
189
+ the link lands on auth, 404, permission, blank, or a visible error state, recover
190
+ a fresh watch link once with `create_campaign({ campaignId })` or `get_campaign`
191
+ and print that link. Do not claim the browser was opened, inspected, or
192
+ synchronized.
209
193
 
210
194
  Never print a placeholder watch link such as "Open campaign" or "link will
211
195
  update once the shell is created." If the shell is not created yet, call
@@ -214,7 +198,7 @@ and surface the missing watch-link error before lead sourcing.
214
198
 
215
199
  After every `update_campaign({ campaignId, currentStep })`, use
216
200
  `get_campaign_navigation_state` when available as a compact orientation check:
217
- match the expected watch-link step to the saved campaign state, explain the
201
+ match the saved campaign state to the expected watch-link step, explain the
218
202
  current state in one sentence, and only then continue. Sender selection belongs
219
203
  at Settings after message approval and 10-row validation. After message
220
204
  validation, use Settings to help the user connect or select a LinkedIn sender.
@@ -437,9 +437,10 @@ brief`, `Revise target`, `Revise offer/proof`, and `Other / custom`.
437
437
 
438
438
  - After the brief is approved, show the next progress line:
439
439
  `Cool. Now I'm going to find people who are both a good fit and active enough
440
- to be worth a LinkedIn test. I'll compare source paths by expected volume,
441
- sampled ICP fit, activity/warmth signal, cleanup risk, and tradeoffs. This
442
- will end with a source decision + sample before anything goes live.`
440
+ to be worth a LinkedIn test. I see two promising source paths: {source path 1}
441
+ and {source path 2}. I'll launch background source checks for both so we can
442
+ confirm which one is viable before I show results. No leads import until you
443
+ approve the source.`
443
444
  - In watch mode, do not leave the user sitting on only `pick-provider` while
444
445
  source scouts run. Move the campaign to the likely primary source lane
445
446
  (`signal-discovery`, `sales-nav`, or `prospeo`) before background source
@@ -450,8 +451,9 @@ will end with a source decision + sample before anything goes live.`
450
451
  - After the lead sample/source decision is ready and approved,
451
452
  show the next progress line:
452
453
  `Lead source is set. I'll import the first 15-row review batch into the
453
- campaign table, then use that same batch to tighten the fit filter and draft the
454
- message we should test.`
454
+ campaign table, then add fit filters and draft the first message from that same
455
+ sample. You can inspect filters once they are saved, but enrichment and message
456
+ checks wait until the message draft is ready and approved.`
455
457
  - During long post-intake work, show concise progress checkpoints before the
456
458
  next expensive stage: source being checked, source switch/tradeoff if any,
457
459
  lead sample usable, filter/message drafting, and message-review rule loading.
@@ -1006,6 +1008,25 @@ The first sentence of the visible decision must make the actual choice clear:
1006
1008
  is {source} because {reason}.` Do not make the user infer the decision from
1007
1009
  numbers alone.
1008
1010
 
1011
+ Before asking for lead-source approval, make the watched campaign show the
1012
+ recommended primary source lane. Call
1013
+ `update_campaign({ campaignId, leadSourceType: "new", leadSourceProvider,
1014
+ currentStep, watchNarration })` with `currentStep` set to the provider lane
1015
+ being recommended (`sales-nav`, `signal-discovery`, or `prospeo`). If the last
1016
+ sampled lane was Signals but the recommendation is Sales Nav, switch the
1017
+ watched provider page to Sales Nav before asking the question so the user can
1018
+ see what they are approving and why. No leads import until the user approves.
1019
+
1020
+ After the user approves a lead source, the approved provider must remain the
1021
+ active watched provider before any materialization work starts. Immediately
1022
+ call `update_campaign` again if needed with the approved `leadSourceProvider`
1023
+ and matching `currentStep` before `lookup_sales_nav_filter`,
1024
+ `get_provider_prompt`, `search_sales_nav`, `search_prospeo`, `import_leads`, or
1025
+ `confirm_lead_list`. For example, if the user approves Sales Nav while the
1026
+ browser is still showing Signal Discovery, set `leadSourceProvider: "sales-nav"`
1027
+ and `currentStep: "sales-nav"` first so the browser switches to the Sales Nav
1028
+ lane and the user can watch the approved source progress.
1029
+
1009
1030
  If you ask for lead-source approval, the question and choices must name the
1010
1031
  source decision. Prefer `Approve Sales Nav with founder/CEO filters, or use
1011
1032
  warmer Signals posts instead?` over `Approve this lead source?`. Option labels
@@ -522,7 +522,7 @@
522
522
  "watchNarration.stage": "find-leads"
523
523
  },
524
524
  "when": "before_source_scouts_or_provider_search",
525
- "chatRenderRule": "Move the campaign watch view to Find Leads before the main thread starts comparing source paths. The watchNarration headline/body must name the likely provider or lane being tested and why it fits this campaign. Do not mention MCP or local artifacts."
525
+ "chatRenderRule": "Move the campaign watch view to Find Leads before the main thread starts comparing source paths. In chat, name the two promising source paths the agent thinks may work, say it is launching background source checks/agents to confirm viability before showing results, and state that no leads import until a source is approved. The watchNarration headline/body must name the likely provider or lane being tested and why it fits this campaign. Do not mention MCP or local artifacts."
526
526
  },
527
527
  {
528
528
  "action": "advance_watch_to_initial_source_lane",
@@ -745,7 +745,7 @@
745
745
  "artifactLinkTiming": "before_next_step_or_revision_question",
746
746
  "doNotCompressToSummaryOnly": false,
747
747
  "doNotRenderArtifactLinksOnly": true,
748
- "sourceRecommendationReadyWatchRule": "When the source recommendation decision card is ready in chat with counts and sample quality, update watchNarration to a find-leads chat-handoff frame. Use a headline like `Review the source in Codex`, body copy that says the browser is showing the evaluated source/results, and nextAction like `Approve in Codex`. Do not keep future-tense copy like `I'll show a source recommendation` after the decision is visible. Include a safety note that no leads import until the user approves the source.",
748
+ "sourceRecommendationReadyWatchRule": "When the source recommendation decision card is ready in chat with counts and sample quality, and before asking for source approval, call update_campaign with leadSourceType `new`, leadSourceProvider set to the recommended primary provider, currentStep set to that provider lane (`sales-nav`, `signal-discovery`, or `prospeo`), and find-leads watchNarration. If the recommendation changed from the lane last sampled, switch the watched provider page to the recommended lane first so the user can inspect what they are approving. Use a headline like `Review the source in Codex`, body copy that says the browser is showing the evaluated source/results, and nextAction like `Approve in Codex`. Do not keep future-tense copy like `I'll show a source recommendation` after the decision is visible. Include a safety note that no leads import until the user approves the source.",
749
749
  "chatRenderRule": "Show a slim rendered-Markdown decision summary only, never a fenced code block. The first sentence must make the decision explicit: 'I recommend {primary source} using {exact filter/source recipe}. The runner-up is {source} because {reason}.' Use indexed sections and short bullets: recommendation, Primary source and filters, Runner-up sources, why it won, Quick numbers with one provider/source angle per bullet, raw volume, sampled fit count as n/N only (no percentages), estimated good-fit range after cleanup, activity/warmth basis, confidence note, 3-5 representative sample leads, and one tradeoff. Do not forecast connection acceptance rates, reply rates, meetings, pipeline, revenue, or ROI unless the user supplied verified benchmark data for this exact workspace/sender. If Signals was searched or considered, include two compact inline Markdown tables before the recommendation is treated as final: Signal keyword lanes with keyword lane, timeframe, posts found, and finalist posts reviewed; and LinkedIn posts sampled with post URL/title, author/topic, age, engagers, sampled engagers, good fits as n/N only, estimated usable prospects per post, and use/discard decision. Default to selecting a few promising Signals posts for the first sample instead of trying to prove full Signals scale up front; if the sample is good but volume is low, say how many more posts to add/scrape next. Do not skip or discard Signals based only on raw post count or vibes; show the post-level math first, or explicitly say no engagers could be fetched and lower confidence. Keep discarded paths, full sample rows, and lead-sample.json details in lead-review.md. Do not show plain filesystem paths unless links cannot be created."
750
750
  },
751
751
  {
@@ -796,6 +796,7 @@
796
796
  "watchNarration: find-leads source recommendation ready, or review-batch import starting when source approval already happened",
797
797
  "selectedLeadListId as source list id only for existing-list or supplied-list preview"
798
798
  ],
799
+ "sourceApprovalWatchRule": "Immediately after the user approves a source, and before lookup_sales_nav_filter, get_provider_prompt, search_sales_nav, search_prospeo, import_leads, or confirm_lead_list, persist the approved source as the active provider on the CampaignOffer. For Sales Nav approval, call update_campaign with leadSourceType `new`, leadSourceProvider `sales-nav`, currentStep `sales-nav`, and current-tense watchNarration so the browser switches off the previous Signal Discovery lane and the user can continue watching the approved provider setup. Apply the same rule for signal-discovery and prospeo approvals.",
799
800
  "fallback": "Stop if campaignId is missing; the source must be attached to the existing CampaignOffer before import.",
800
801
  "readsCampaignStateFirst": true
801
802
  }
@@ -875,7 +876,7 @@
875
876
  },
876
877
  {
877
878
  "action": "watch_mode_orient",
878
- "watchNarrationRule": "Before import_leads or confirm_lead_list starts, align the guide with chat by setting review-batch watchNarration to current-tense import copy. Use a headline like `Importing the review batch`; explain that the browser may still show the approved source leads while Codex imports only the bounded 15-row review batch; include a no-launch safety note."
879
+ "watchNarrationRule": "Before import_leads or confirm_lead_list starts, align the guide with chat by setting review-batch watchNarration to current-tense import copy. Also persist the approved source provider/currentStep first: Sales Nav approval must set leadSourceProvider `sales-nav` and currentStep `sales-nav`, Signals approval must set `signal-discovery`, and Prospeo approval must set `prospeo`. Use a headline like `Importing the review batch`; explain that the browser is on the approved source lane while Codex imports only the bounded 15-row review batch; include a no-launch safety note."
879
880
  },
880
881
  {
881
882
  "tool": "import_leads",
@@ -943,8 +944,10 @@
943
944
  ],
944
945
  "requiredValues": {
945
946
  "currentStep": "filter-choice",
946
- "watchNarration.stage": "fit-message"
947
- }
947
+ "watchNarration.stage": "fit-message",
948
+ "watchNarration.headline": "Added to Campaign"
949
+ },
950
+ "watchNarrationRule": "After the bounded review batch is present, update the watched guide to `Added to Campaign`. Say Codex is adding fit filters so every send stays qualified while drafting the first message in the background. This persists add-filters intent by currentStep/watchNarration only; do not set enableICPFilters=true until save_rubrics succeeds with active criteria. Nothing enriches, validates, or sends until the first message is ready and approved."
948
951
  }
949
952
  ],
950
953
  "allowedTools": [
@@ -134,6 +134,27 @@ current-tense import copy. Do not leave the guide in source-approved or
134
134
  future-tense copy such as `I'll show the review-batch outcome`; that makes the
135
135
  browser guide describe a different moment than chat.
136
136
 
137
+ After review batch import:
138
+
139
+ ```json
140
+ {
141
+ "stage": "fit-message",
142
+ "headline": "Added to Campaign",
143
+ "visibleState": "The first review batch is in the campaign.",
144
+ "agentIntent": "Codex is adding fit filters to keep every send qualified while drafting the first message in the background.",
145
+ "nextAction": "Review fit rules and message",
146
+ "safety": "Nothing enriches, validates, or sends until the message is ready and approved.",
147
+ "workerStatuses": {
148
+ "leadFitBuilder": "running",
149
+ "messageDraftBuilder": "running"
150
+ }
151
+ }
152
+ ```
153
+
154
+ Use this after the selected review rows are present and before filters are
155
+ saved. This is add-filters intent, not active filtering. `enableICPFilters`
156
+ only becomes true after active filter criteria are saved.
157
+
137
158
  Fit + message:
138
159
 
139
160
  ```json
@@ -0,0 +1,9 @@
1
+ {
2
+ "parallelMode": "wide",
3
+ "agentCount": 6,
4
+ "maxToolCallsPerAgent": 2,
5
+ "senderMaxAgents": 2,
6
+ "senderMaxToolCallsPerAgent": 3,
7
+ "progressMode": true,
8
+ "debugMode": true
9
+ }