@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.
- package/dist/auth.d.ts +25 -0
- package/dist/auth.js +30 -0
- package/dist/server.js +10 -4
- package/dist/tools/campaigns.d.ts +10 -97
- package/dist/tools/campaigns.js +26 -150
- package/dist/tools/cli-login.d.ts +80 -0
- package/dist/tools/cli-login.js +207 -0
- package/dist/tools/flow-preflight.d.ts +3 -16
- package/dist/tools/flow-preflight.js +6 -25
- package/dist/tools/navigation.js +2 -2
- package/dist/tools/one-off.d.ts +15 -2
- package/dist/tools/one-off.js +23 -6
- package/dist/tools/prompts.d.ts +2 -2
- package/dist/tools/prompts.js +2 -2
- package/dist/tools/readiness.d.ts +1 -0
- package/dist/tools/readiness.js +4 -2
- package/dist/tools/sequencer.d.ts +7 -0
- package/dist/tools/sequencer.js +8 -2
- package/package.json +1 -1
- package/skills/building-gtm-tables/SKILL.md +1 -0
- package/skills/create-campaign/SKILL.md +370 -238
- package/skills/create-campaign-v2/core/flow.v2.json +0 -2
- package/skills/create-post/SKILL.md +1 -1
- package/skills/engage/SKILL.md +1 -1
- package/skills/interview/SKILL.md +1 -1
- package/skills/research-sender/SKILL.md +78 -36
- package/skills/workflow-sequences/SKILL.md +1 -1
|
@@ -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:
|
|
4
|
+
visibility: internal
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Create Post
|
package/skills/engage/SKILL.md
CHANGED
|
@@ -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:
|
|
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:
|
|
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, ~
|
|
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 ~
|
|
16
|
+
That's 3-4 sequential rounds and ~88s+ wall time.
|
|
16
17
|
|
|
17
|
-
New protocol: **fire one parallel batch.** `enrich_sender`
|
|
18
|
-
`
|
|
19
|
-
|
|
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 3× `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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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. `
|
|
58
|
-
2. `
|
|
59
|
-
3. `WebSearch({ query: '
|
|
60
|
-
4. `WebSearch({ query: '"{companyName}"
|
|
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
|
|
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
|
|
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
|
|
77
|
-
for company
|
|
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
|
-
**
|
|
83
|
-
**
|
|
84
|
-
**
|
|
85
|
-
**
|
|
86
|
-
**
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
`
|
|
93
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
138
|
-
-
|
|
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:
|
|
4
|
+
visibility: internal
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Workflow Sequences
|