@sellable/mcp 0.1.30 → 0.1.32

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.
@@ -102,7 +102,6 @@
102
102
  "allowedTools": [
103
103
  "list_senders",
104
104
  "get_sender",
105
- "enrich_sender",
106
105
  "fetch_company",
107
106
  "fetch_linkedin_profile",
108
107
  "WebFetch",
@@ -174,7 +173,6 @@
174
173
  "get_active_workspace",
175
174
  "list_senders",
176
175
  "get_sender",
177
- "enrich_sender",
178
176
  "complete_sender_research",
179
177
  "fetch_company",
180
178
  "fetch_company_posts",
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: create-post
3
3
  description: Find viral LinkedIn posts, deeply analyze the hooks that are working (80% of the battle), copy those patterns into 25 hooks per topic, draft 5 structural variations, optimize for mobile, and present 5 publish-ready posts. Uses agent teams for parallel hook analysis, generation, and drafting.
4
- visibility: public
4
+ visibility: internal
5
5
  ---
6
6
 
7
7
  # Create Post
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: engage
3
3
  description: Find relevant LinkedIn posts (fresh first, then high-engagement older), optionally mine contrarian takes via interview, draft thoughtful comments per sender's voice, and save session insights for better future discovery. Supports multi-sender sessions and autonomous mode.
4
- visibility: public
4
+ visibility: internal
5
5
  ---
6
6
 
7
7
  # Engage
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: interview
3
3
  description: Voice-first interview to build your commenting style guide and ICP profile. Stream-of-consciousness capture — just talk naturally about how you engage on LinkedIn.
4
- visibility: public
4
+ visibility: internal
5
5
  ---
6
6
 
7
7
  # Voice Interview
@@ -1,7 +1,8 @@
1
1
  ---
2
2
  name: research-sender
3
- description: Parallel-first sender research protocol. One round of batched tool calls, ~10-15s wall time.
3
+ description: "Parallel-first sender research protocol. One round of five batched tool calls (fetch_linkedin_profile + fetch_company + 3× WebSearch), no enrich_sender required, ~30-40s wall time."
4
4
  visibility: internal
5
+ allowed-tools: mcp__sellable__fetch_linkedin_profile mcp__sellable__fetch_company mcp__sellable__complete_sender_research WebSearch ToolSearch
5
6
  ---
6
7
 
7
8
  # Research Sender (Parallel-First)
@@ -12,28 +13,36 @@ This protocol is standalone and does not depend on the generic `research` subski
12
13
  ## Core Idea — Don't Wait, Fan Out
13
14
 
14
15
  Old protocol: call `enrich_sender` → wait for partial → maybe spawn 2-3 subagents → wait.
15
- That's 3-4 sequential rounds and ~60s+ wall time.
16
+ That's 3-4 sequential rounds and ~88s+ wall time.
16
17
 
17
- New protocol: **fire one parallel batch.** `enrich_sender` (5-8s, returns
18
- `clientProspectId` + baseline) runs alongside 2-3 `WebSearch` calls. They all
19
- finish in the same ~10s window, then you synthesize.
18
+ New protocol: **fire one parallel batch.** No `enrich_sender` precondition.
19
+ `fetch_linkedin_profile` (sender background), `fetch_company` (company description /
20
+ industry / employees), and `WebSearch` (proof, growth, positioning) all run in the
21
+ same window. They finish in ~10-15s if truly parallel, ~30-40s when the model
22
+ serializes (interactive mode is best-effort, headless `claude -p` always serializes).
20
23
 
21
- The `enrich_sender` call is still required because downstream tools
22
- (`create_campaign`, `attach_sequence`, message generation) need the
23
- `clientProspectId` it produces and the cached `EnrichedProspect` row it writes.
24
- Don't skip it — just stop waiting for it before doing the rest of the research.
24
+ Then synthesize once into the campaign brief — the brief is what downstream
25
+ message generation reads, not a `clientProspect` row. `clientProspectId` is
26
+ optional in `create_campaign`; pass `senderLinkedinUrl` instead.
25
27
 
26
28
  ## Inputs
27
29
 
28
30
  Provide as many as available. Use `"Unknown"` for missing values.
29
31
 
30
- - `linkedinUrl` (REQUIRED)
32
+ - `linkedinUrl` (REQUIRED — drives `fetch_linkedin_profile`)
31
33
  - `name`
32
34
  - `title`
33
35
  - `companyName`
34
- - `companyDomain` (REQUIRED for WebSearch derive from email or LinkedIn if absent)
36
+ - `companyDomain` (REQUIRED drives `fetch_company` and all three WebSearch queries; derive from email or LinkedIn if absent)
35
37
  - `headline` (optional)
36
38
 
39
+ ## Execution Backend Routing
40
+
41
+ This skill runs differently depending on the host:
42
+
43
+ - **Claude Code host:** the parallel batch uses MCP tools directly — `mcp__sellable__fetch_linkedin_profile`, `mcp__sellable__fetch_company`, and `WebSearch`. Issue all five calls as `tool_use` blocks in a single assistant message.
44
+ - **Codex host:** if MCP `fetch_*` tools are not available, fall back to web-fetch equivalents — use the LinkedIn URL with WebFetch for the sender profile, fetch the company's `/about` page for company facts, and use the same three WebSearch queries below for proof / growth / positioning. Synthesis treats both backends identically.
45
+
37
46
  ## Setup: Pre-Load Deferred Tools (One-Time, Before The Parallel Batch)
38
47
 
39
48
  Some hosts (Claude Code with deferred-tool fetch) require `WebSearch` and
@@ -41,27 +50,28 @@ some MCP tools to be loaded via `ToolSearch` before they can be invoked. If
41
50
  they are not already directly callable, issue this once as the first tool
42
51
  call, on its own:
43
52
 
44
- `ToolSearch({ query: "select:WebSearch,mcp__sellable__enrich_sender,mcp__sellable__complete_sender_research", max_results: 5 })`
53
+ `ToolSearch({ query: "select:WebSearch,mcp__sellable__fetch_linkedin_profile,mcp__sellable__fetch_company,mcp__sellable__complete_sender_research", max_results: 5 })`
45
54
 
46
55
  Skip this turn entirely if the tools are already directly callable.
47
56
 
48
57
  ## The One Round (Parallel Batch)
49
58
 
50
- **HARD RULE:** the four tool calls below MUST be emitted as **four `tool_use`
59
+ **HARD RULE:** the five tool calls below MUST be emitted as **five `tool_use`
51
60
  content blocks inside a single assistant message** (one turn, parallel
52
61
  execution). Do NOT split them across multiple assistant messages.
53
62
 
54
- Concretely, your next assistant message must contain exactly these four
63
+ Concretely, your next assistant message must contain exactly these five
55
64
  `tool_use` blocks, in any order, with no leading or trailing prose:
56
65
 
57
- 1. `enrich_sender({ linkedinUrl, companyDomain })` — baseline + `clientProspectId`.
58
- 2. `WebSearch({ query: 'site:{companyDomain} ("case study" OR "customer story" OR testimonial OR "success story") "{companyName}"' })` proof.
59
- 3. `WebSearch({ query: '"{companyName}" {companyDomain} {currentYear} (funding OR raised OR seed OR series OR hiring OR launch OR "press release")' })` — growth/credibility.
60
- 4. `WebSearch({ query: '"{companyName}" about product site:{companyDomain}' })` — positioning.
66
+ 1. `fetch_linkedin_profile({ linkedinUrl })` — sender's LinkedIn profile (firstName/lastName, currentCompany, experience, follower count, education) for the brief's "sender background" section.
67
+ 2. `fetch_company({ companyDomain })` sender's company LinkedIn page (description, industry, employee range, recent posts). REQUIRED — replaces what `enrich_sender` used to provide for `companySnapshot`.
68
+ 3. `WebSearch({ query: 'site:{companyDomain} ("case study" OR "customer story" OR testimonial OR "success story") "{companyName}"' })` — proof.
69
+ 4. `WebSearch({ query: '"{companyName}" {companyDomain} {currentYear} (funding OR raised OR seed OR series OR hiring OR launch OR "press release")' })` — growth/credibility.
70
+ 5. `WebSearch({ query: '"{companyName}" about product site:{companyDomain}' })` — positioning.
61
71
 
62
- **Self-check before you reply:** if your reply contains fewer than four
72
+ **Self-check before you reply:** if your reply contains fewer than five
63
73
  `tool_use` blocks (after the optional `ToolSearch` setup turn), you are
64
- violating the protocol. Stop, rewrite the reply with all four.
74
+ violating the protocol. Stop, rewrite the reply with all five.
65
75
 
66
76
  **Known limitation (`claude -p` headless mode):** Claude often serializes
67
77
  these calls one-per-turn even with explicit instructions. That's fine — the
@@ -69,35 +79,63 @@ skill still produces the same output, just with sequential tool execution
69
79
  (~30–40s total wall time vs. ~10–15s if truly parallelized). If you can
70
80
  batch, do; if not, proceed sequentially without retrying or re-prompting.
71
81
 
72
- No subagent fan-out. No second round of enrichment polling.
82
+ No subagent fan-out. No second round of enrichment polling. **No `enrich_sender` call.**
73
83
 
74
84
  ## Synthesis (Single Pass After Batch Returns)
75
85
 
76
- Merge the four results. Treat `enrich_sender` as the authoritative baseline
77
- for company/sender facts; treat WebSearch as proof and signals.
86
+ Merge the five results into the campaign brief. Treat `fetch_linkedin_profile` and
87
+ `fetch_company` as authoritative for sender/company facts; treat `WebSearch` as
88
+ proof and signals.
78
89
 
79
90
  ```markdown
80
91
  ## {Company} - Sender Research
81
92
 
82
- **Company Context:** [companySnapshot.description OR positioning WebSearch top result]
83
- **Industry / Size:** [companySnapshot.industry + employeeRange]
84
- **Positioning Notes:** [proofDigest.positioningOneLiner + keyDifferentiators]
85
- **Proof Options:** [proofDigest.caseStudySummary + case-study WebSearch hits pick 1-3 with named customers / metrics]
86
- **Credibility Signals:** [proofDigest.reviewHighlight + growth WebSearch hits (funding, hiring, press)]
93
+ **Sender Background:** [from fetch_linkedin_profile name, current title, follower count, key experience]
94
+ **Company Context:** [from fetch_company.description OR positioning WebSearch top result]
95
+ **Industry / Size:** [from fetch_company.industry + employee range]
96
+ **Positioning Notes:** [positioning WebSearch top results + any positioning one-liner from fetch_company]
97
+ **Proof Options:** [case-study WebSearch hits pick 1-3 with named customers / metrics]
98
+ **Credibility Signals:** [growth WebSearch hits (funding, hiring, press) + any high-signal posts from fetch_company]
87
99
  **Gaps:** [what's still missing — usually fine to ship with this]
88
100
  ```
89
101
 
90
- If `enrich_sender` returns `enrichmentStatus: "partial"`, that's expected and
91
- fine `companySnapshot` and `senderBackground` are populated immediately.
92
- `proofDigest` may be null on partial; in that case rely on WebSearch results
93
- for proof and credibility, not on a second enrichment poll.
102
+ The synthesis result is what feeds the campaign brief, which is what message
103
+ generation reads via `campaignBriefContent` (see `getOfferPositioning()` in
104
+ `prompt.ts:236`). The brief is the load-bearing path now `clientProspect`
105
+ contributes only fallback context and the sender display name (which is
106
+ resolved from the `Sender` row's profileData when `clientProspect` is null).
107
+
108
+ ### Partial Failure Handling
109
+
110
+ The five calls run in parallel, so any one of them can fail independently
111
+ (404, rate-limit, timeout). Synthesis MUST still produce a usable brief.
112
+ Apply these rules:
113
+
114
+ - **If `fetch_company` errors or returns empty:** mark `Company Context` as
115
+ `[unavailable — fetch_company failed]`. Use the positioning WebSearch top
116
+ result as a partial substitute. Set `Industry / Size` to `[unavailable]`
117
+ (do NOT guess). The brief still ships; downstream message generation reads
118
+ the brief verbatim and is null-safe on missing fields.
119
+ - **If `fetch_linkedin_profile` errors:** fall back to WebSearch-derived
120
+ sender background. Set `Sender Background` to a one-liner derived from the
121
+ positioning WebSearch ("found via {companyDomain}/about and other web
122
+ signals — full LinkedIn profile unavailable").
123
+ - **If a WebSearch errors:** mark the corresponding section
124
+ (`Proof Options`, `Credibility Signals`, or `Positioning Notes`) as `[no
125
+ results]` and continue. Do NOT retry — one round only.
126
+ - **NEVER skip `complete_sender_research`** even on partial failure. Pass
127
+ `proofItemsFound: 0`, `caseStudyItemsFound: 0`, `credibilitySignalsFound: 0`
128
+ for the failed sections so the preflight knows the research ran.
129
+
130
+ **The contract:** synthesis always produces SOME brief. `complete_sender_research`
131
+ always fires. The brief ships even with gaps; downstream is null-safe.
94
132
 
95
133
  ## Optional Deepen (Only If Synthesis Reveals A Hard Gap)
96
134
 
97
135
  If after synthesis you genuinely have zero proof and zero credibility
98
136
  signals, AND the campaign fixture/operator told you proof is required, you
99
137
  MAY issue ONE additional WebFetch on the most promising case-study URL from
100
- batch step 2. Cap at one WebFetch. No subagents, no second WebSearch round.
138
+ the proof WebSearch. Cap at one WebFetch. No subagents, no second WebSearch round.
101
139
 
102
140
  If that still yields nothing, set `proofItemsFound: 0` in
103
141
  `complete_sender_research` and proceed; the brief can ship without proof.
@@ -122,7 +160,7 @@ If no reliable evidence is found, set counts to 0 and include that in `notes`.
122
160
  Before issuing the parallel batch:
123
161
 
124
162
  ```
125
- Pulling sender enrichment + case studies + growth signals + positioning in parallel (~10s)...
163
+ Pulling sender profile + company snapshot + case studies + growth signals + positioning in parallel (~10s)...
126
164
  ```
127
165
 
128
166
  After synthesis:
@@ -133,7 +171,11 @@ Sender research ready — {proofItemsFound} proof items, {credibilitySignalsFoun
133
171
 
134
172
  ## What Changed From The Previous Protocol
135
173
 
174
+ - **Removed `enrich_sender` from the parallel batch entirely.** The MCP `create_campaign` tool now accepts `senderLinkedinUrl` as an alternative to `clientProspectId`. `enrich_sender` itself has been removed from the MCP tool registry — calling it returns "tool not found".
175
+ - Replaced with `fetch_company` (REQUIRED) — provides company description, industry, employee data that `enrich_sender` used to give via `companySnapshot`.
176
+ - Five parallel tool calls instead of four (added `fetch_linkedin_profile` + `fetch_company`, dropped `enrich_sender`).
177
+ - Added explicit Partial Failure Handling — synthesis always produces a brief even when one or two of the five calls error.
136
178
  - No "minimal-verification vs deep-proof" branch. Always run the same parallel batch.
137
- - No spawn of `general-purpose` subagents for research — WebSearch from the orchestrator turn is faster and cheaper.
138
- - No waiting on `enrich_sender` before issuing WebSearch.
179
+ - No subagent fan-out — WebSearch from the orchestrator turn is faster and cheaper.
180
+ - Synthesis writes to the campaign brief, not to an `EnrichedProspect` row.
139
181
  - One round, one synthesis, one `complete_sender_research` call.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: workflow-sequences
3
3
  description: Create workflow tables via Sellable MCP, attach outbound sequence templates, inspect existing tables, and handle overwrite or starter-column compatibility issues safely.
4
- visibility: public
4
+ visibility: internal
5
5
  ---
6
6
 
7
7
  # Workflow Sequences