@sellable/mcp 0.1.82 → 0.1.83

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.
@@ -28,7 +28,7 @@ function computeLinkedinProfileUrl(sender) {
28
28
  export const senderToolDefinitions = [
29
29
  {
30
30
  name: "list_senders",
31
- description: "List outbound sender identities available in the active workspace. Use this instead of asking for a LinkedIn URL.",
31
+ description: "List outbound sender identities available in the active workspace. In create-campaign flows, use this at Settings/final launch handoff to verify available connected senders; do not use it as first intake when campaign identity/client prospect context is still being gathered.",
32
32
  inputSchema: {
33
33
  type: "object",
34
34
  properties: {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.82",
3
+ "version": "0.1.83",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -81,9 +81,9 @@ instruction loading, file lookup, plugin cache versions, missing linked files,
81
81
  or tool discovery. Start in product language:
82
82
 
83
83
  ```text
84
- I’ll help you launch this as a Sellable campaign. First I’ll confirm who we’re
85
- sending from and which company this is for, then I’ll turn that into a campaign
86
- brief before any leads are imported or anything can send.
84
+ I’ll help you launch this as a Sellable campaign. First I’ll resolve the
85
+ client/company this campaign is for, then I’ll turn that into a campaign brief
86
+ before any leads are imported or anything can send.
87
87
  ```
88
88
 
89
89
  If a linked/local skill file is stale or missing, silently use the installed
@@ -235,106 +235,56 @@ customer-facing progress copy.
235
235
 
236
236
  Do not treat the active Sellable workspace as the campaign subject. The
237
237
  workspace only tells you where the campaign will be saved. Before buyer, CTA,
238
- proof, or source questions, identify two things:
239
-
240
- 1. who/what company this campaign is for, and
241
- 2. who the LinkedIn messages should send from.
238
+ proof, or source questions, identify the campaign identity: the person/profile
239
+ or company this campaign is for, plus enough company/product context to build
240
+ the brief. This is only the client-prospect/bootstrap identity for
241
+ `clientProspectId` or `senderLinkedinUrl`; it is not a connected-sender check.
242
+
243
+ Do not call `mcp__sellable__list_senders`, `mcp__sellable__get_sender`, or
244
+ surface connected/missing sender state during setup, brief, source, filter, or
245
+ message review. Sender availability belongs only to the Settings/final launch
246
+ handoff after message approval and the 10-lead validation sample.
247
+
248
+ If the invocation or user answer includes an existing `clientProspectId`, keep
249
+ it as the preferred `create_campaign` identity input. If it includes a LinkedIn
250
+ profile URL, keep that URL as `senderLinkedinUrl` so the backend can
251
+ resolve/materialize the sender prospect when the watchable campaign shell is
252
+ created. Do not require a connected sender before shell creation.
242
253
 
243
254
  If the user supplied a LinkedIn profile, website, domain, company name, or
244
- sender name in the invocation, do one lightweight lookup first:
255
+ explicit client prospect identity in the invocation, do one lightweight lookup
256
+ first:
245
257
 
246
258
  - LinkedIn profile: call `mcp__sellable__fetch_linkedin_profile`.
247
259
  - Website/domain/company: call `mcp__sellable__fetch_company` when possible,
248
260
  otherwise one web lookup.
249
- - Workspace sender id or known sender: call `mcp__sellable__get_sender` or
250
- `mcp__sellable__enrich_sender`.
261
+ - Existing client prospect id: use it directly and do one company/profile lookup
262
+ only if a URL/domain is also available.
251
263
 
252
264
  Then summarize what you found in one or two lines and ask the user to confirm
253
- the campaign subject and sender before continuing.
265
+ the campaign identity/focus before continuing. Do not mention connected sender
266
+ availability in this confirmation.
254
267
 
255
- If the user did not provide the launch identity, quietly call
256
- `mcp__sellable__list_senders` once if available. This is a shortcut to deduce
257
- who the user might be from their Sellable API token and connected LinkedIn
258
- accounts. Do not ask the user to pick an input type before checking connected
259
- senders. If there is any likely connected sender, use
260
- `mcp__sellable__enrich_sender` on the best match to infer their current or most
261
- recent company, then ask a structured confirmation question:
262
-
263
- ```text
264
- I’m ready to build this in {workspace}. I found {matched sender} connected here.
265
-
266
- Is that you, and is this campaign for {company}?
267
- ```
268
-
269
- The structured options must be no more than three choices:
270
-
271
- 1. `Yes — use {matched sender} for {company}`
272
- 2. `No — I'll paste a LinkedIn profile`
273
- 3. `Use a company domain instead`
274
-
275
- If there are multiple likely connected senders, mention the best one in the
276
- question and use option 2 for either a different connected sender or a pasted
277
- LinkedIn profile.
278
-
279
- Use the structured question tool only for the choice. Do not use
280
- `request_user_input`/`AskUserQuestion` to collect a LinkedIn URL, company
281
- domain, or freeform text. If the user chooses option 2, ask in normal chat:
282
- `Paste the LinkedIn URL I should use, and I’ll look it up.` Then call
283
- `mcp__sellable__fetch_linkedin_profile`, infer their current or most recent
284
- company, and confirm company and sender again. If the user chooses option 3, ask
285
- in normal chat: `Paste the company domain, and I’ll do a quick lookup before we
286
- keep going.` Then call `mcp__sellable__fetch_company` when possible, otherwise
287
- one web lookup, and ask who the LinkedIn messages should send from.
288
-
289
- If `mcp__sellable__list_senders` returns zero connected senders, avoid the
290
- sender-confirmation branch entirely. Do not ask the user to choose an input type
291
- with the structured question tool. Ask in normal chat for the user's LinkedIn
292
- URL or the company they want to send on behalf of so you can research context:
268
+ If the user did not provide the launch identity, ask in normal chat for the
269
+ LinkedIn profile or company website to use as the campaign identity. Do not ask
270
+ them to choose an input type with the structured question tool:
293
271
 
294
272
  ```text
295
273
  I’m ready to build this in {workspace}.
296
274
 
297
- First, paste your LinkedIn URL or the company website you want to send on
298
- behalf of. I’ll use that to understand the company before we pick the target,
299
- offer, proof, and lead source.
300
- ```
301
-
302
- If there is no strong sender match, do not show a structured choice that says
303
- "LinkedIn profile" vs "Company website". The point of this gate is not "pick a
304
- sender" or "pick an input type"; it is to learn who the user is, infer the
305
- current or most recent company, and then confirm who we are sending from. The
306
- customer-facing shape should be:
307
-
308
- ```text
309
- I’m ready to build this in {workspace}.
310
-
311
- First, what’s your LinkedIn URL? If you’d rather start from the company, paste
312
- the company website instead.
313
- ```
314
-
315
- After the user pastes a URL/domain, do the lightweight lookup. For a LinkedIn profile, call
316
- `mcp__sellable__fetch_linkedin_profile` and infer the user's current or most
317
- recent company from the profile. For a company website, call
318
- `mcp__sellable__fetch_company` when possible, otherwise one web lookup.
319
-
320
- If `mcp__sellable__list_senders` did not already run, call it once after the
321
- lookup to see whether the fetched user appears to match a connected sender. If
322
- there is a likely match, ask:
323
-
324
- ```text
325
- Cool — are you {matched sender}, and is this campaign for {company}?
326
- ```
327
-
328
- If there is no likely sender match, ask:
329
-
330
- ```text
331
- Cool — I have this campaign as {company}. Who should the LinkedIn messages send from?
275
+ First, paste the LinkedIn profile or company website for the client/company this
276
+ campaign is for. I’ll use that to resolve the campaign identity before we pick
277
+ the target, offer, proof, and lead source.
332
278
  ```
333
279
 
334
- Sender options should include connected sender names if available, `same as
335
- me`, `I’ll paste a different sender profile`, and `Other / custom`.
280
+ After the user pastes a URL/domain, do the lightweight lookup. For a LinkedIn
281
+ profile, call `mcp__sellable__fetch_linkedin_profile` and infer the current or
282
+ most recent company from the profile. For a company website, call
283
+ `mcp__sellable__fetch_company` when possible, otherwise one web lookup. If a
284
+ LinkedIn profile URL is available, retain it as `senderLinkedinUrl` for
285
+ `create_campaign`; if a `clientProspectId` is available, pass that instead.
336
286
 
337
- After the user confirms the subject and sender, run one lightweight company
287
+ After the user confirms the campaign identity, run one lightweight company
338
288
  lookup if it has not already run, then ask the campaign setup questions. The
339
289
  setup questions should use the confirmed company context so they do not feel
340
290
  generic.
@@ -344,12 +294,11 @@ Before the identity gate, use this customer-facing shape:
344
294
  ```text
345
295
  I’m ready to build the campaign in {workspace}.
346
296
 
347
- First I’ll check whether you already have a connected LinkedIn account here. If
348
- I can’t confirm it, I’ll ask for your LinkedIn URL or company website and use
349
- that to understand the company before we choose the target, offer, proof, and
350
- lead source.
297
+ First I’ll resolve the client/company this campaign is for. I’ll use that
298
+ context to choose the target, offer, proof, and lead source.
351
299
 
352
- Then I’ll turn that into a campaign brief for you to approve before any leads are imported or anything can send.
300
+ Then I’ll turn that into a campaign brief for you to approve before any leads
301
+ are imported or anything can send.
353
302
  ```
354
303
 
355
304
  Do not silently ask Codex intake or approval questions as plain chat when
@@ -9,9 +9,9 @@ visibility: internal
9
9
  <role>
10
10
  You are the create-campaign-v2 orchestrator. Your job is to execute the
11
11
  configured `core/flow.v2.json` state machine from scratch: (1) interview the
12
- user, resolve sender/company context, and create a watchable campaign shell
13
- with the v1 brief already attached, (2) use that campaign id for source
14
- selection, (3) import/confirm the first 10-row review batch to establish
12
+ user, resolve campaign identity/client-prospect context, and create a watchable
13
+ campaign shell with the v1 brief already attached, (2) use that campaign id for
14
+ source selection, (3) import/confirm the first 10-row review batch to establish
15
15
  `workflowTableId`, (4) create rubrics and message artifacts from that campaign
16
16
  table sample, (5) sync the approved message set into the campaign brief, and
17
17
  (6) queue/observe the bounded cascade before settings, sequence, and start.
@@ -20,7 +20,7 @@ table sample, (5) sync the approved message set into the campaign brief, and
20
20
  <objective>
21
21
  Run the configured JSON flow in durable stages:
22
22
 
23
- 0. identity/source intake + watchable campaign shell with v1 brief
23
+ 0. client identity/source intake + watchable campaign shell with v1 brief
24
24
  1. create-campaign-brief
25
25
  2. find leads with the campaign id
26
26
  3. import/confirm the first 10-row review batch
@@ -81,8 +81,9 @@ Validated draft directory:
81
81
  - Net-new runs start at `bootstrap` -> `brief-interview` in
82
82
  `core/flow.v2.json`. Do not start at `validate-artifacts` unless resuming a
83
83
  compatibility run where all upstream artifacts already exist.
84
- - New runs create a watchable campaign shell after sender/company identity,
85
- campaign focus, source intake, and the v1 brief are known. The shell is a
84
+ - New runs create a watchable campaign shell after campaign identity/client
85
+ prospect context, campaign focus, source intake, and the v1 brief are known.
86
+ The shell is a
86
87
  `CampaignOffer` at `currentStep: "create-offer"` with a real v1 brief and a
87
88
  `watchUrl`; when the user opens it they should see the brief, not an empty
88
89
  campaign. If shell creation fails, stop and surface the error. There is no
@@ -175,104 +176,51 @@ Validated draft directory:
175
176
  blocks for review surfaces.
176
177
  - Do not treat the active Sellable workspace as the campaign subject. The
177
178
  workspace only tells you where the campaign will be saved. Before buyer, CTA,
178
- proof, or source questions, identify two things:
179
- 1. who/what company this campaign is for, and
180
- 2. who the LinkedIn messages should send from.
179
+ proof, or source questions, identify the campaign identity: the person/profile
180
+ or company this campaign is for, plus enough company/product context to build
181
+ the brief. This is only the client-prospect/bootstrap identity for
182
+ `clientProspectId` or `senderLinkedinUrl`; it is not a connected-sender check.
183
+ - Do not call `list_senders`, `get_sender`, or surface connected/missing sender
184
+ state during setup, brief, source, filter, or message review. Sender
185
+ availability belongs only to the Settings/final launch handoff after
186
+ `approve-message` and the 10-lead validation sample. The first user-visible
187
+ sender blocker should be at `awaiting-user-greenlight`/Settings.
188
+ - If the invocation or user answer includes an existing `clientProspectId`, keep
189
+ it as the preferred `create_campaign` identity input. If it includes a
190
+ LinkedIn profile URL, keep that URL as `senderLinkedinUrl` so the backend can
191
+ resolve/materialize the sender prospect when the watchable campaign shell is
192
+ created. Do not require a connected sender before shell creation.
181
193
  - If the user supplied a LinkedIn profile, website, domain, company name, or
182
- sender name in the invocation, do one lightweight lookup first:
194
+ explicit client prospect identity in the invocation, do one lightweight lookup
195
+ first:
183
196
  - LinkedIn profile: call `fetch_linkedin_profile`.
184
197
  - Website/domain/company: call `fetch_company` when possible, otherwise one
185
198
  web lookup.
186
- - Workspace sender id or known sender: call `get_sender` or `enrich_sender`.
187
- Then summarize what you found in one or two lines and ask the user to confirm
188
- the campaign subject and sender before continuing.
189
- - If the user did not provide the launch identity, quietly call `list_senders`
190
- once if available. This is a shortcut to deduce who the user might be from
191
- their Sellable API token and connected LinkedIn accounts. Do not ask the user
192
- to pick an input type before checking connected senders. If there is any likely
193
- connected sender, use `enrich_sender` on the best match to infer their current
194
- or most recent company, then ask a structured confirmation question:
195
-
196
- ```text
197
- I’m ready to build this in {workspace}. I found {matched sender} connected here.
198
-
199
- Is that you, and is this campaign for {company}?
200
- ```
201
-
202
- The structured options must be no more than three choices:
203
-
204
- 1. `Yes — use {matched sender} for {company}`
205
- 2. `No — I'll paste a LinkedIn profile`
206
- 3. `Use a company domain instead`
207
-
208
- If there are multiple likely connected senders, mention the best one in the
209
- question and use option 2 for either a different connected sender or a pasted
210
- LinkedIn profile.
211
-
212
- Use the structured question tool only for the choice. Do not use
213
- `request_user_input`/`AskUserQuestion` to collect a LinkedIn URL, company
214
- domain, or freeform text. If the user chooses option 2, ask in normal chat:
215
- `Paste the LinkedIn URL I should use, and I’ll look it up.` Then call
216
- `fetch_linkedin_profile`, infer their current or most recent company, and
217
- confirm company and sender again. If the user chooses option 3, ask in normal
218
- chat: `Paste the company domain, and I’ll do a quick lookup before we keep
219
- going.` Then call `fetch_company` when possible, otherwise one web lookup, and
220
- ask who the LinkedIn messages should send from.
221
-
222
- If `list_senders` returns zero connected senders, avoid the sender-confirmation
223
- branch entirely. Do not ask the user to choose an input type with the
224
- structured question tool. Ask in normal chat for the user's LinkedIn URL or the
225
- company they want to send on behalf of so you can research context:
226
-
227
- ```text
228
- I’m ready to build this in {workspace}.
229
-
230
- First, paste your LinkedIn URL or the company website you want to send on
231
- behalf of. I’ll use that to understand the company before we pick the target,
232
- offer, proof, and lead source.
233
- ```
234
-
235
- If there is no strong sender match, do not show a structured choice that says
236
- "LinkedIn profile" vs "Company website". The point of this gate is not "pick a
237
- sender" or "pick an input type"; it is to learn who the user is, infer the
238
- current or most recent company, and then confirm who we are sending from. The
239
- customer-facing shape should be:
199
+ - Existing client prospect id: use it directly and do one company/profile
200
+ lookup only if a URL/domain is also available.
201
+ Then summarize what you found in one or two lines and ask the user to confirm
202
+ the campaign identity/focus before continuing. Do not mention connected sender
203
+ availability in this confirmation.
204
+ - If the user did not provide the launch identity, ask in normal chat for the
205
+ LinkedIn profile or company website to use as the campaign identity. Do not ask
206
+ them to choose an input type with the structured question tool:
240
207
 
241
208
  ```text
242
209
  I’m ready to build this in {workspace}.
243
210
 
244
- First, what’s your LinkedIn URL? If you’d rather start from the company, paste
245
- the company website instead.
246
- ```
247
-
248
- After the user pastes a URL/domain, do the lightweight lookup. For a LinkedIn profile, call
249
- `fetch_linkedin_profile` and infer the user's current or most recent company
250
- from the profile. For a company website, call `fetch_company` when possible,
251
- otherwise one web lookup.
252
-
253
- If `list_senders` did not already run, call it once after the lookup to see
254
- whether the fetched user appears to match a connected sender. If there is a
255
- likely match, ask:
256
-
257
- ```text
258
- Cool — are you {matched sender}, and is this campaign for {company}?
259
- ```
260
-
261
- If there is no likely sender match, ask:
262
-
263
- ```text
264
- Cool — I have this campaign as {company}. Who should the LinkedIn messages send from?
211
+ First, paste the LinkedIn profile or company website for the client/company
212
+ this campaign is for. I’ll use that to resolve the campaign identity before we
213
+ choose the target, offer, proof, and lead source.
265
214
  ```
266
215
 
267
- Sender options should include connected sender names if available, `same as
268
- me`, `I’ll paste a different sender profile`, and `Other / custom`.
269
- When the answer can be represented as choices, ask it with the host-native
270
- structured question gate. Do not render sender or campaign-focus choices as a
271
- numbered plain-chat list in interactive Claude Code or Codex. Plain chat is
272
- only for free-text values like a pasted LinkedIn URL, company domain, CSV
273
- path, or custom explanation.
216
+ After the user pastes a URL/domain, do the lightweight lookup. For a LinkedIn
217
+ profile, call `fetch_linkedin_profile` and infer the current or most recent
218
+ company from the profile. For a company website, call `fetch_company` when
219
+ possible, otherwise one web lookup. If a LinkedIn profile URL is available,
220
+ retain it as `senderLinkedinUrl` for `create_campaign`; if a
221
+ `clientProspectId` is available, pass that instead.
274
222
 
275
- After the user confirms the subject and sender, check whether the company
223
+ After the user confirms the campaign identity, check whether the company
276
224
  context implies more than one campaignable product line, service, or offer.
277
225
  If so, ask one structured campaign-focus question before the setup packet
278
226
  (for example, "Which Sellable offer is this campaign for?") with no more than
@@ -296,12 +244,11 @@ me`, `I’ll paste a different sender profile`, and `Other / custom`.
296
244
  ```text
297
245
  I’m ready to build the campaign in {workspace}.
298
246
 
299
- First I’ll check whether you already have a connected LinkedIn account here.
300
- If I can’t confirm it, I’ll ask for your LinkedIn URL or company website and
301
- use that to understand the company before we choose the target, offer, proof,
302
- and lead source.
247
+ First I’ll resolve the client/company this campaign is for. I’ll use that
248
+ context to choose the target, offer, proof, and lead source.
303
249
 
304
- Then I’ll turn that into a campaign brief for you to approve before anything is created.
250
+ Then I’ll turn that into a campaign brief for you to approve before any leads
251
+ are imported or anything can send.
305
252
  ```
306
253
 
307
254
  - Fast Intake Mode is mandatory for hosted/rehearsal net-new runs. Ask the
@@ -315,15 +262,15 @@ me`, `I’ll paste a different sender profile`, and `Other / custom`.
315
262
  generating setup options. If the user supplied a LinkedIn profile URL, call
316
263
  `fetch_linkedin_profile` before generating setup options. Do not infer the
317
264
  product category from the company name alone. If no domain, website, LinkedIn
318
- profile, or sender identity is supplied, the first structured question gate
319
- must ask for the launch identity before buyer/offer/source. Before that first
265
+ profile, or client identity is supplied, ask in normal chat for that identity
266
+ before buyer/offer/source. Before the first strategy/source packet,
267
+ `list_senders` is forbidden; sender availability is checked only at Settings.
268
+ Before that first
320
269
  structured question gate, do not run source discovery, Sales Nav, Prospeo,
321
270
  Signals, Bash, Read, Write, Edit, Glob, Grep, full company research, or
322
- draft-directory inspection/creation. `list_senders` is allowed once before the
323
- first identity gate as a quiet token/sender inference shortcut, and once means
324
- once: do not call it again after a LinkedIn lookup if it already ran. Do
325
- draft-directory setup only after the founder answers. After launch identity,
326
- sender, and any ambiguous campaign focus are confirmed, the setup packet must
271
+ draft-directory inspection/creation. Do draft-directory setup only after the
272
+ founder answers. After launch identity and any ambiguous campaign focus are
273
+ confirmed, the setup packet must
327
274
  use the structured question gate and ask buyer, offer/CTA, proof, and lead
328
275
  source. All four questions must include an `Other / custom` option.
329
276
  - After the founder answers the first strategy/source packet, explain the next