@sellable/mcp 0.1.38 → 0.1.40

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/auth.js CHANGED
@@ -57,9 +57,11 @@ function normalizeConfig(raw) {
57
57
  };
58
58
  }
59
59
  export function getConfig() {
60
- if (cachedConfig && !DISABLE_CONFIG_CACHE) {
61
- return cachedConfig;
62
- }
60
+ // Config cache removed 2026-05-04: we always re-read from disk so
61
+ // workspace switches (set_active_workspace) take effect immediately
62
+ // for ALL downstream tools (list_senders, fetch_*, etc.) without
63
+ // relying on every mutating tool to remember to invalidate the cache.
64
+ // Disk read is <5ms — the simplicity is worth the cost.
63
65
  const configPathCandidates = getConfigPathCandidates();
64
66
  const configPath = getConfigPath();
65
67
  if (!fs.existsSync(configPath)) {
@@ -100,7 +102,6 @@ export function getConfig() {
100
102
  if (!config.token.startsWith("skt_")) {
101
103
  throw new Error("Invalid token format - must start with 'skt_'");
102
104
  }
103
- cachedConfig = config;
104
105
  return config;
105
106
  }
106
107
  catch (error) {
@@ -138,8 +138,8 @@ export async function getAuthStatus() {
138
138
  "5) Call `mcp__sellable__wait_for_cli_login({ sessionId })` using the sessionId returned by start_cli_login. " +
139
139
  "6) If the result is `error.type === 'tool_timeout_guard'`, IMMEDIATELY re-call wait_for_cli_login with the SAME sessionId — do not narrate, do not call start_cli_login again. Loop until you get a different result. " +
140
140
  "7) On `ok: true`, the user is signed in and `~/.sellable/config.json` has been written. Branch on `isReturningUser`: " +
141
- "if true, say `You're in — {activeWorkspaceName} workspace, ready to roll.\\n\\nNow — paste the LinkedIn profile URL of the person you'll be sending campaigns from. Usually that's you (the founder), or whoever's voice the messages should sound like.\\n\\ne.g. https://www.linkedin.com/in/your-handle`; " +
142
- "if false, say `You're set up — your {activeWorkspaceName} workspace is ready.\\n\\nNow — paste the LinkedIn profile URL of the person you'll be sending campaigns from. Usually that's you (the founder), or whoever's voice the messages should sound like.\\n\\ne.g. https://www.linkedin.com/in/your-handle`";
141
+ "if true, say `You're in — {activeWorkspaceName} workspace, ready to roll.\\n\\nNow — paste the LinkedIn profile URL of the person you'll be sending campaigns from. Usually that's you, or whoever's voice the messages should sound like.\\n\\ne.g. https://www.linkedin.com/in/your-handle`; " +
142
+ "if false, say `You're set up — your {activeWorkspaceName} workspace is ready.\\n\\nNow — paste the LinkedIn profile URL of the person you'll be sending campaigns from. Usually that's you, or whoever's voice the messages should sound like.\\n\\ne.g. https://www.linkedin.com/in/your-handle`";
143
143
  if (error instanceof SellableApiError && error.isAuthError) {
144
144
  return {
145
145
  ...base,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.38",
3
+ "version": "0.1.40",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -253,10 +253,18 @@ Cool — I have this campaign as {company}. Who should the LinkedIn messages sen
253
253
  Sender options should include connected sender names if available, `same as
254
254
  me`, `I’ll paste a different sender profile`, and `Other / custom`.
255
255
 
256
- After the user confirms the subject and sender, run one lightweight company
257
- lookup if it has not already run, then ask the campaign setup questions. The
258
- setup questions should use the confirmed company context so they do not feel
259
- generic.
256
+ After the user confirms the subject and sender, run one bounded lightweight
257
+ company-context pass before asking the campaign setup questions. A sender
258
+ LinkedIn profile lookup is not enough by itself unless it clearly includes the
259
+ company's website, product category, customer, and offer context. If the host can
260
+ run tools in parallel, use one parallel batch with at most 2-3 cheap lookups:
261
+ `mcp__sellable__fetch_company` on a LinkedIn company URL from the profile when
262
+ available; `WebFetch` for the company website/domain when available; otherwise
263
+ one `WebSearch` for `{company} official website` or `{company} product`. If
264
+ parallel tool calls are unavailable, do the single highest-confidence lookup
265
+ first and continue. Do not run full company research, source discovery, Sales
266
+ Nav, Prospeo, Signals, or multi-query browsing here. The goal is a fast 15-30
267
+ second context read so the four setup questions feel specific.
260
268
 
261
269
  Before the identity gate, use this customer-facing shape:
262
270
 
@@ -400,7 +408,7 @@ updates.
400
408
  ```text
401
409
  You're in — {activeWorkspaceName} workspace, ready to roll.
402
410
 
403
- Now — paste the LinkedIn profile URL of the person you'll be sending campaigns from. Usually that's you (the founder), or whoever's voice the messages should sound like.
411
+ Now — paste the LinkedIn profile URL of the person you'll be sending campaigns from. Usually that's you, or whoever's voice the messages should sound like.
404
412
 
405
413
  e.g. https://www.linkedin.com/in/your-handle
406
414
  ```
@@ -411,7 +419,7 @@ updates.
411
419
  ```text
412
420
  You're set up — your {activeWorkspaceName} workspace is ready.
413
421
 
414
- Now — paste the LinkedIn profile URL of the person you'll be sending campaigns from. Usually that's you (the founder), or whoever's voice the messages should sound like.
422
+ Now — paste the LinkedIn profile URL of the person you'll be sending campaigns from. Usually that's you, or whoever's voice the messages should sound like.
415
423
 
416
424
  e.g. https://www.linkedin.com/in/your-handle
417
425
  ```
@@ -226,11 +226,20 @@ Validated draft directory:
226
226
  Sender options should include connected sender names if available, `same as
227
227
  me`, `I’ll paste a different sender profile`, and `Other / custom`.
228
228
 
229
- After the user confirms the subject and sender, run one lightweight company
230
- lookup if it has not already run, then ask the campaign setup questions. The
231
- setup questions should use the confirmed company context so they do not feel
232
- generic. If identity is still unavailable, use neutral/custom intake options
233
- instead of guessed vertical-specific options.
229
+ After the user confirms the subject and sender, run one bounded lightweight
230
+ company-context pass before asking the campaign setup questions. A sender
231
+ LinkedIn profile lookup is not enough by itself unless it clearly includes the
232
+ company's website, product category, customer, and offer context. If the host
233
+ can run tools in parallel, use one parallel batch with at most 2-3 cheap
234
+ lookups: `fetch_company` on a LinkedIn company URL from the profile when
235
+ available; `WebFetch` for the company website/domain when available; otherwise
236
+ one `WebSearch` for `{company} official website` or `{company} product`. If
237
+ parallel tool calls are unavailable, do the single highest-confidence lookup
238
+ first and continue. Do not run full company research, source discovery, Sales
239
+ Nav, Prospeo, Signals, or multi-query browsing here. The goal is a fast 15-30
240
+ second context read so the four setup questions feel specific. If identity is
241
+ still unavailable, use neutral/custom intake options instead of guessed
242
+ vertical-specific options.
234
243
 
235
244
  - Before the identity gate, use this customer-facing shape:
236
245
 
@@ -250,7 +259,9 @@ me`, `I’ll paste a different sender profile`, and `Other / custom`.
250
259
  that first packet, the first assistant turn may only call
251
260
  `bootstrap_create_campaign`, load this workflow prompt with
252
261
  `get_subskill_prompt({ subskillName: "create-campaign-v2" })`, optionally run
253
- one lightweight identity lookup, then use the structured question gate. If the user
262
+ one lightweight identity lookup, then use the structured question gate. After
263
+ identity is confirmed, run the bounded lightweight company-context pass above
264
+ before generating buyer/offer/proof/source options. If the user
254
265
  supplied a company website/domain, call exactly one of `fetch_company`,
255
266
  `WebFetch`, or `WebSearch` to identify what the company actually does before
256
267
  generating setup options. If the user supplied a LinkedIn profile URL, call