@sellable/mcp 0.1.0
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/.claude-plugin/plugin.json +12 -0
- package/.mcp.json +9 -0
- package/README.md +355 -0
- package/dist/api.d.ts +21 -0
- package/dist/api.js +73 -0
- package/dist/auth.d.ts +60 -0
- package/dist/auth.js +246 -0
- package/dist/engage-memory.d.ts +63 -0
- package/dist/engage-memory.js +354 -0
- package/dist/index-dev.d.ts +2 -0
- package/dist/index-dev.js +17 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +8 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +499 -0
- package/dist/skills.d.ts +11 -0
- package/dist/skills.js +97 -0
- package/dist/tools/auth.d.ts +30 -0
- package/dist/tools/auth.js +124 -0
- package/dist/tools/blueprint-commit.d.ts +174 -0
- package/dist/tools/blueprint-commit.js +286 -0
- package/dist/tools/bootstrap.d.ts +64 -0
- package/dist/tools/bootstrap.js +246 -0
- package/dist/tools/campaigns.d.ts +589 -0
- package/dist/tools/campaigns.js +892 -0
- package/dist/tools/cells.d.ts +58 -0
- package/dist/tools/cells.js +48 -0
- package/dist/tools/context.d.ts +88 -0
- package/dist/tools/context.js +271 -0
- package/dist/tools/csv-domains.d.ts +73 -0
- package/dist/tools/csv-domains.js +464 -0
- package/dist/tools/csv-linkedin.d.ts +102 -0
- package/dist/tools/csv-linkedin.js +712 -0
- package/dist/tools/direct-campaigns.d.ts +240 -0
- package/dist/tools/direct-campaigns.js +250 -0
- package/dist/tools/engage-bootstrap.d.ts +94 -0
- package/dist/tools/engage-bootstrap.js +205 -0
- package/dist/tools/engage-discovery.d.ts +78 -0
- package/dist/tools/engage-discovery.js +150 -0
- package/dist/tools/engage-memory.d.ts +181 -0
- package/dist/tools/engage-memory.js +143 -0
- package/dist/tools/engage-state.d.ts +72 -0
- package/dist/tools/engage-state.js +62 -0
- package/dist/tools/enrichment.d.ts +167 -0
- package/dist/tools/enrichment.js +174 -0
- package/dist/tools/flow-preflight.d.ts +68 -0
- package/dist/tools/flow-preflight.js +138 -0
- package/dist/tools/framework.d.ts +44 -0
- package/dist/tools/framework.js +153 -0
- package/dist/tools/interaction-mode.d.ts +27 -0
- package/dist/tools/interaction-mode.js +102 -0
- package/dist/tools/leads.d.ts +2417 -0
- package/dist/tools/leads.js +2307 -0
- package/dist/tools/linkedin.d.ts +210 -0
- package/dist/tools/linkedin.js +229 -0
- package/dist/tools/navigation.d.ts +91 -0
- package/dist/tools/navigation.js +381 -0
- package/dist/tools/one-off.d.ts +229 -0
- package/dist/tools/one-off.js +273 -0
- package/dist/tools/processing.d.ts +70 -0
- package/dist/tools/processing.js +56 -0
- package/dist/tools/prompts.d.ts +211 -0
- package/dist/tools/prompts.js +210 -0
- package/dist/tools/provider-preflight.d.ts +21 -0
- package/dist/tools/provider-preflight.js +59 -0
- package/dist/tools/readiness.d.ts +261 -0
- package/dist/tools/readiness.js +510 -0
- package/dist/tools/rows.d.ts +126 -0
- package/dist/tools/rows.js +105 -0
- package/dist/tools/rubrics.d.ts +497 -0
- package/dist/tools/rubrics.js +681 -0
- package/dist/tools/senders.d.ts +44 -0
- package/dist/tools/senders.js +69 -0
- package/dist/tools/sequencer.d.ts +127 -0
- package/dist/tools/sequencer.js +194 -0
- package/dist/tools/tables.d.ts +35 -0
- package/dist/tools/tables.js +36 -0
- package/dist/tools/verify-row.d.ts +36 -0
- package/dist/tools/verify-row.js +38 -0
- package/dist/tools/workspaces.d.ts +140 -0
- package/dist/tools/workspaces.js +139 -0
- package/dist/utils/workspace-root.d.ts +1 -0
- package/dist/utils/workspace-root.js +39 -0
- package/package.json +46 -0
- package/skills/building-gtm-tables/SKILL.md +216 -0
- package/skills/building-gtm-tables/core/auto-execute.yaml +19 -0
- package/skills/building-gtm-tables/core/blueprint-schema.json +72 -0
- package/skills/building-gtm-tables/references/brief-to-blueprint.md +334 -0
- package/skills/building-gtm-tables/references/column-type-catalog.md +318 -0
- package/skills/building-gtm-tables/references/common-blueprints.fixtures.ts +199 -0
- package/skills/building-gtm-tables/references/common-blueprints.md +44 -0
- package/skills/building-gtm-tables/references/failure-taxonomy.md +197 -0
- package/skills/building-gtm-tables/references/uat-seed-prompts.md +37 -0
- package/skills/building-gtm-tables/references/verify-loop.md +74 -0
- package/skills/campaign-messages/SKILL.md +173 -0
- package/skills/campaign-messages/flow.v1.json +75 -0
- package/skills/craft-message/SKILL.md +401 -0
- package/skills/create-campaign/ARCHITECTURE.md +232 -0
- package/skills/create-campaign/DISCUSS.md +296 -0
- package/skills/create-campaign/FLOW_ASCII.md +240 -0
- package/skills/create-campaign/HOST-PARITY-CHECKLIST.md +49 -0
- package/skills/create-campaign/README.md +142 -0
- package/skills/create-campaign/SKILL.md +286 -0
- package/skills/create-campaign/context/README.md +67 -0
- package/skills/create-campaign/context/_TEMPLATE.md +12 -0
- package/skills/create-campaign/context/context.md +35 -0
- package/skills/create-campaign/context/learnings.md +16 -0
- package/skills/create-campaign/context/registry.json +19 -0
- package/skills/create-campaign/core/flow.v1.json +217 -0
- package/skills/create-campaign/core/policy.md +191 -0
- package/skills/create-campaign/core/providers/apollo.json +35 -0
- package/skills/create-campaign/core/providers/prospeo.json +34 -0
- package/skills/create-campaign/core/providers/registry.json +31 -0
- package/skills/create-campaign/core/providers/sales-nav.json +37 -0
- package/skills/create-campaign/core/providers/signal-discovery.json +42 -0
- package/skills/create-campaign/references/brief-template.md +64 -0
- package/skills/create-campaign/references/campaign-quality.md +84 -0
- package/skills/create-campaign/references/copy-calibration-examples.md +120 -0
- package/skills/create-campaign/references/offer-patterns.md +108 -0
- package/skills/create-campaign/references/provider-selection-strategy.md +212 -0
- package/skills/create-campaign/references/question-examples.md +167 -0
- package/skills/create-campaign/references/token-fill-examples.md +81 -0
- package/skills/create-campaign-brief/ARCHITECTURE.md +72 -0
- package/skills/create-campaign-brief/DISCUSS.md +64 -0
- package/skills/create-campaign-brief/README.md +176 -0
- package/skills/create-campaign-brief/SKILL.md +537 -0
- package/skills/create-campaign-brief/references/brief-synthesis-rules.md +100 -0
- package/skills/create-campaign-brief/references/brief-template.md +220 -0
- package/skills/create-campaign-brief/references/campaign-idea-options.md +30 -0
- package/skills/create-campaign-brief/references/copy-appendix-template.md +62 -0
- package/skills/create-campaign-brief/references/draft-lifecycle.md +23 -0
- package/skills/create-campaign-brief/references/examples/MANIFEST.json +89 -0
- package/skills/create-campaign-brief/references/examples/briefs/clover.md +223 -0
- package/skills/create-campaign-brief/references/examples/briefs/galley.md +222 -0
- package/skills/create-campaign-brief/references/examples/briefs/gelee.md +220 -0
- package/skills/create-campaign-brief/references/examples/briefs/hey-digital.md +234 -0
- package/skills/create-campaign-brief/references/examples/briefs/persona.md +231 -0
- package/skills/create-campaign-brief/references/examples/briefs/revvix.md +220 -0
- package/skills/create-campaign-brief/references/examples/briefs/sellable-dev.md +220 -0
- package/skills/create-campaign-brief/references/examples/briefs/superposition.md +233 -0
- package/skills/create-campaign-brief/references/examples/briefs/superpower.md +219 -0
- package/skills/create-campaign-brief/references/examples/briefs/westpark-villas.md +220 -0
- package/skills/create-campaign-brief/references/icp-lock-question-bank.md +43 -0
- package/skills/create-campaign-brief/references/messaging-inputs.md +58 -0
- package/skills/create-campaign-brief/references/output-acceptance-rubric.md +62 -0
- package/skills/create-campaign-brief/references/phase75-active-runtime-message-pack.md +248 -0
- package/skills/create-campaign-brief/references/phase75-canonical-brief-template.md +319 -0
- package/skills/create-campaign-brief/references/phase75-good-brief-and-messaging-examples.md +445 -0
- package/skills/create-campaign-brief/references/quick-research-protocol.md +39 -0
- package/skills/create-campaign-brief/references/reference-sheet-protocol.md +60 -0
- package/skills/create-campaign-brief/references/zero-shot-iteration-rules.md +66 -0
- package/skills/create-campaign-v2/SKILL.md +1619 -0
- package/skills/create-campaign-v2/core/auto-execute.README.md +219 -0
- package/skills/create-campaign-v2/core/auto-execute.yaml +121 -0
- package/skills/create-campaign-v2/core/flow.v2.json +1643 -0
- package/skills/create-campaign-v2/core/policy.md +82 -0
- package/skills/create-campaign-v2/references/ai-tells.md +253 -0
- package/skills/create-campaign-v2/references/approval-gate-framing.md +346 -0
- package/skills/create-campaign-v2/references/draft-lifecycle.md +110 -0
- package/skills/create-campaign-v2/references/escalation-ladder.md +119 -0
- package/skills/create-campaign-v2/references/filter-leads.md +495 -0
- package/skills/create-campaign-v2/references/final-handoff-contract.md +176 -0
- package/skills/create-campaign-v2/references/gold-standard-message-examples.md +394 -0
- package/skills/create-campaign-v2/references/gold-standard-message-patterns.md +314 -0
- package/skills/create-campaign-v2/references/gold-standard-message-validation-example.md +212 -0
- package/skills/create-campaign-v2/references/lead-validation-preview.md +172 -0
- package/skills/create-campaign-v2/references/parallel-critique-protocol.md +368 -0
- package/skills/create-campaign-v2/references/sample-validation-loop.md +289 -0
- package/skills/create-campaign-v2/references/step-13-import-leads.md +151 -0
- package/skills/create-campaign-v2/references/step-15-re-cascade.md +90 -0
- package/skills/create-campaign-v2/references/thomas-revision-filters.md +521 -0
- package/skills/create-campaign-v2/references/thomas-variant-selection.md +202 -0
- package/skills/create-campaign-v2/references/tier-routing-matrix.md +66 -0
- package/skills/create-campaign-v2/references/validation-criteria.md +367 -0
- package/skills/create-campaign-v2/references/watch-link-handoff.md +106 -0
- package/skills/create-campaign-v2-validation/SKILL.md +296 -0
- package/skills/create-post/SKILL.md +1308 -0
- package/skills/create-rubric/SKILL.md +251 -0
- package/skills/engage/SKILL.md +549 -0
- package/skills/engage/core/README.md +23 -0
- package/skills/engage/core/proven-searches.json +11 -0
- package/skills/engage/core/style-guide.template.md +47 -0
- package/skills/engage/core/tracked-people.json +10 -0
- package/skills/enrich-prospects/SKILL.md +97 -0
- package/skills/find-leads/SKILL.md +467 -0
- package/skills/generate-messages/SKILL.md +2361 -0
- package/skills/interview/SKILL.md +132 -0
- package/skills/interview/core/ENGAGE_STYLE_GUIDE.template.md +54 -0
- package/skills/interview/core/ICP.template.md +54 -0
- package/skills/interview/core/VOICE_PROFILE.template.md +101 -0
- package/skills/providers/apollo.md +520 -0
- package/skills/providers/prospeo.md +398 -0
- package/skills/providers/sales-nav.md +372 -0
- package/skills/providers/signal-discovery.md +495 -0
- package/skills/research/SKILL.md +258 -0
- package/skills/research/config.json +9 -0
- package/skills/research/override.md +13 -0
- package/skills/research-prospect/SKILL.md +99 -0
- package/skills/research-sender/SKILL.md +158 -0
- package/skills/workflow-sequences/SKILL.md +85 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sellable",
|
|
3
|
+
"description": "Craft personalized LinkedIn messages using Sellable campaigns and the REPLY framework. Access your campaigns, research prospects, and generate high-quality outreach messages.",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Sellable",
|
|
7
|
+
"url": "https://sellable.dev"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://app.sellable.dev",
|
|
10
|
+
"repository": "https://github.com/sellable/claude-code",
|
|
11
|
+
"keywords": ["linkedin", "outreach", "sales", "messaging", "campaigns"]
|
|
12
|
+
}
|
package/.mcp.json
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
# Sellable Claude Code Plugin
|
|
2
|
+
|
|
3
|
+
Craft personalized LinkedIn messages using the REPLY framework directly in Claude Code.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
- Load your Sellable campaigns
|
|
8
|
+
- Create campaigns headlessly with a realtime watch link
|
|
9
|
+
- Research prospects (web search and LinkedIn API)
|
|
10
|
+
- Apply the REPLY framework with 11 quality gates
|
|
11
|
+
- Save and approve messages for sending
|
|
12
|
+
|
|
13
|
+
Each message gets 5+ minutes of Claude attention with deep research - no other tool does this.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
### Prompt Source Of Truth
|
|
18
|
+
|
|
19
|
+
There is one public create-campaign entrypoint shared across hosts:
|
|
20
|
+
|
|
21
|
+
- `sellable:create-campaign`
|
|
22
|
+
|
|
23
|
+
The public wrapper loads the approval-gated workflow from:
|
|
24
|
+
|
|
25
|
+
- `mcp/sellable/skills/create-campaign-v2/SKILL.md`
|
|
26
|
+
|
|
27
|
+
The older `mcp/sellable/skills/create-campaign/SKILL.md` prompt is kept as an
|
|
28
|
+
internal legacy prompt for compatibility only. Do not advertise it as a public
|
|
29
|
+
command.
|
|
30
|
+
|
|
31
|
+
### 1. One-Command Agent Install
|
|
32
|
+
|
|
33
|
+
For Claude Code and Codex CLI:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx -y @sellable/install --host all --token skt_live_your_token_here --workspace-id your_workspace_id
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Agent-readable install instructions are available at:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
https://app.sellable.dev/agent-install.txt
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The reviewable curl installer is:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
curl -fsSL "https://app.sellable.dev/api/v2/cli/install" -o /tmp/sellable-install.sh
|
|
49
|
+
sh /tmp/sellable-install.sh
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Phase 112 v1 uses package stdio MCP through `@sellable/mcp`. Hosted HTTP
|
|
53
|
+
MCP is a future/advanced mode until the hosted endpoint exists.
|
|
54
|
+
|
|
55
|
+
### 2. Generate API Token
|
|
56
|
+
|
|
57
|
+
1. Go to https://app.sellable.dev/settings
|
|
58
|
+
2. Click "Generate Token"
|
|
59
|
+
3. Copy the token (starts with `skt_live_`)
|
|
60
|
+
|
|
61
|
+
### 3. Claude Setup
|
|
62
|
+
|
|
63
|
+
Install MCP server:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
claude mcp add --transport stdio sellable -- npx -y @sellable/mcp
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Create auth config at `~/.claude/sellable.json`:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"token": "skt_live_your_token_here",
|
|
74
|
+
"activeWorkspaceId": "your_workspace_id"
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The token is provided when you generate it. Use `list_workspaces` +
|
|
79
|
+
`set_active_workspace` to choose a workspace if you don't know the ID yet.
|
|
80
|
+
|
|
81
|
+
### 4. Codex Setup
|
|
82
|
+
|
|
83
|
+
For customer/package installs, use:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npx -y @sellable/install --host codex --token skt_live_your_token_here --workspace-id your_workspace_id
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
For local repo/Desktop development, run the installer from this repo:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npm run sellable:codex:install -- --token skt_live_your_token_here --workspace-id your_workspace_id
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The installer does the full local setup:
|
|
96
|
+
|
|
97
|
+
- builds the Sellable MCP server
|
|
98
|
+
- uses repo-local `web` skills by default, so the Codex picker has one Sellable
|
|
99
|
+
entry per workflow
|
|
100
|
+
- removes stale Personal Sellable skill copies, including
|
|
101
|
+
`sellable-create-campaign-v2`
|
|
102
|
+
- writes `~/.codex/sellable.json`
|
|
103
|
+
- registers the `sellable` MCP server with Codex
|
|
104
|
+
- installs the local `sellable@sellable-local` Desktop plugin so Codex
|
|
105
|
+
Desktop loads the `mcp__sellable__*` tools into skill sessions
|
|
106
|
+
- runs a Codex CLI smoke that must load `get_auth_status` and the
|
|
107
|
+
`create-campaign-v2` prompt
|
|
108
|
+
|
|
109
|
+
If you already have `~/.codex/sellable.json`, verify the install without
|
|
110
|
+
rewriting auth:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
npm run sellable:codex:install -- --verify-only
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
For published-package installs instead of this local checkout:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npm run sellable:codex:install -- --server-mode package --skill-scope personal --token skt_live_your_token_here --workspace-id your_workspace_id
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
After the installer passes, fully quit and reopen Codex Desktop. Start a new
|
|
123
|
+
thread from the repo and select the `web` `Sellable Create Campaign` entry. If
|
|
124
|
+
the app still says `mcp__sellable__*` tools are missing after the installer
|
|
125
|
+
passes, check that `~/.codex/config.toml` contains both
|
|
126
|
+
`[marketplaces.sellable-local]` and `[plugins."sellable@sellable-local"]`.
|
|
127
|
+
The skill being visible only proves skill discovery; the plugin is what mounts
|
|
128
|
+
the Sellable MCP tools for Codex Desktop.
|
|
129
|
+
|
|
130
|
+
## Usage
|
|
131
|
+
|
|
132
|
+
### From Sellable UI
|
|
133
|
+
|
|
134
|
+
1. Open any campaign
|
|
135
|
+
2. Go to the Launch tab
|
|
136
|
+
3. Click "Open in Claude Code"
|
|
137
|
+
4. Copy the command shown
|
|
138
|
+
|
|
139
|
+
### From Claude Code
|
|
140
|
+
|
|
141
|
+
Use the create-campaign skill:
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
/sellable:create-campaign
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Then describe intent naturally, for example:
|
|
148
|
+
|
|
149
|
+
- "Let's make a campaign with sellable"
|
|
150
|
+
- "Create a campaign for acme.com"
|
|
151
|
+
- "Launch a LinkedIn campaign for this company"
|
|
152
|
+
|
|
153
|
+
For local UAT-style runs against a company/domain:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
npm run campaign:v2:local -- teaatshiloh.com
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### From Codex
|
|
160
|
+
|
|
161
|
+
Use the Codex skill entrypoint:
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
$sellable:create-campaign
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Skill package path in this repo:
|
|
168
|
+
|
|
169
|
+
- `.agents/skills/sellable-create-campaign/SKILL.md`
|
|
170
|
+
|
|
171
|
+
## Host Parity Runbook (Codex + Claude)
|
|
172
|
+
|
|
173
|
+
Use the same MCP runtime preflight in both hosts:
|
|
174
|
+
|
|
175
|
+
1. `get_auth_status()`
|
|
176
|
+
2. `get_campaign_framework({ flowVersion: "v2", includePlugins: true })`
|
|
177
|
+
3. Optional resume branch with `get_campaign_context({ campaignId, refresh: true })`
|
|
178
|
+
4. Subskill discovery and load via:
|
|
179
|
+
- `list_subskill_prompts` (catalog)
|
|
180
|
+
- `search_subskill_prompts` (lookup)
|
|
181
|
+
- `get_subskill_prompt({ subskillName: "create-campaign-v2" })` (load)
|
|
182
|
+
5. Net-new sender research completion gate before create:
|
|
183
|
+
- `get_subskill_prompt({ subskillName: "research-sender" })`
|
|
184
|
+
- run sender research
|
|
185
|
+
- `complete_sender_research(...)`
|
|
186
|
+
|
|
187
|
+
Canonical shortcut:
|
|
188
|
+
|
|
189
|
+
- `bootstrap_create_campaign({ flowVersion: "v2", campaignId? })`
|
|
190
|
+
|
|
191
|
+
If bootstrap returns blocking errors, fail fast and do not continue into provider
|
|
192
|
+
search/import tools.
|
|
193
|
+
|
|
194
|
+
Provider preflight contract:
|
|
195
|
+
|
|
196
|
+
- Call `get_provider_prompt({ provider, campaignOfferId? })` before any provider action.
|
|
197
|
+
- Provider actions (`search_apollo`, `search_sales_nav`, `search_prospeo`,
|
|
198
|
+
`search_signals`, `import_leads`) are runtime-gated until prompt preload is done.
|
|
199
|
+
|
|
200
|
+
Parallel execution contract:
|
|
201
|
+
|
|
202
|
+
- Claude host: use `Task` subagents for parallel research/crafting units.
|
|
203
|
+
- Codex host: use `multi_tool_use.parallel` for independent tool-call batches.
|
|
204
|
+
- If neither backend is available, run sequentially with the same output schema.
|
|
205
|
+
|
|
206
|
+
Config path resolution (in order):
|
|
207
|
+
|
|
208
|
+
1. `SELLABLE_CONFIG_PATH`
|
|
209
|
+
2. `$CODEX_HOME/sellable.json`
|
|
210
|
+
3. `~/.codex/sellable.json`
|
|
211
|
+
4. `~/.claude/sellable.json` (compatibility fallback)
|
|
212
|
+
|
|
213
|
+
## Hetzner Smoke / UAT
|
|
214
|
+
|
|
215
|
+
For hosted MCP verification, keep the product MCP host separate from the
|
|
216
|
+
`sellable-admin` host:
|
|
217
|
+
|
|
218
|
+
- product MCP: `sellable-web-mcp`
|
|
219
|
+
- admin MCP: `sellable-ops`
|
|
220
|
+
|
|
221
|
+
The product MCP runtime reads auth from the normal `sellable.json` path
|
|
222
|
+
resolution above. `SELLABLE_TOKEN` by itself is not the authoritative runtime
|
|
223
|
+
contract for hosted smoke/UAT runs.
|
|
224
|
+
|
|
225
|
+
Recommended smoke/UAT flow on the VPS:
|
|
226
|
+
|
|
227
|
+
1. use the shared helper in `scripts/lib/vps-common.sh`
|
|
228
|
+
2. rebuild with `npm run mcp:build`
|
|
229
|
+
3. run the direct stdio MCP client in `scripts/mcp/sellable-tool-call.mjs`
|
|
230
|
+
4. use `scripts/run-sellable-mcp-smoke.sh` for the baseline host proof before
|
|
231
|
+
feature-specific UAT
|
|
232
|
+
|
|
233
|
+
For file-path features like CSV upload, create the fixture file on the VPS
|
|
234
|
+
itself and pass the absolute host path to the tool.
|
|
235
|
+
|
|
236
|
+
## Engage Memory (Learns Over Time)
|
|
237
|
+
|
|
238
|
+
The `engage` skill persists user-specific, workspace-scoped memory in a separate
|
|
239
|
+
JSON file so it can learn over time without editing repo or package files.
|
|
240
|
+
|
|
241
|
+
Default path: next to your `sellable.json` (same directory), named:
|
|
242
|
+
|
|
243
|
+
- `sellable.engage.json`
|
|
244
|
+
|
|
245
|
+
Override path with:
|
|
246
|
+
|
|
247
|
+
- `SELLABLE_ENGAGE_MEMORY_PATH`
|
|
248
|
+
|
|
249
|
+
This file stores the commenting style guide (markdown), proven search keywords
|
|
250
|
+
with outcomes, and tracked people (LinkedIn profiles), all scoped by workspace.
|
|
251
|
+
|
|
252
|
+
## Config You Can Edit (Source Of Truth)
|
|
253
|
+
|
|
254
|
+
- Auth + active workspace: your `sellable.json` (via `SELLABLE_CONFIG_PATH`, `$CODEX_HOME/sellable.json`, `~/.codex/sellable.json`, or `~/.claude/sellable.json`)
|
|
255
|
+
- Engage memory (style guide + searches + tracked people): `sellable.engage.json` (or `SELLABLE_ENGAGE_MEMORY_PATH`)
|
|
256
|
+
- Team-editable, project-local configs (recommended to edit in git):
|
|
257
|
+
- `./.sellable/configs/writing/styleguide.md`
|
|
258
|
+
- `./.sellable/configs/audience/icp-filters.md`
|
|
259
|
+
- `./.sellable/configs/proof/claims.md`
|
|
260
|
+
- `./.sellable/configs/discovery/influencers.md`
|
|
261
|
+
- `./.sellable/configs/discovery/post-filters.md`
|
|
262
|
+
|
|
263
|
+
Files under `mcp/sellable/skills/**/core/*` are **package repo files**, not the intended user config surface.
|
|
264
|
+
|
|
265
|
+
## Skills
|
|
266
|
+
|
|
267
|
+
### /sellable:create-campaign
|
|
268
|
+
|
|
269
|
+
Primary public entrypoint for the approval-gated campaign creation flow.
|
|
270
|
+
|
|
271
|
+
### interview
|
|
272
|
+
|
|
273
|
+
Self-interview skill to capture voice + ICP + boundaries into `./.sellable/configs/writing/styleguide.md` and persist it into MCP memory for future sessions.
|
|
274
|
+
|
|
275
|
+
## Available Tools
|
|
276
|
+
|
|
277
|
+
### Workspace Tools (Free)
|
|
278
|
+
|
|
279
|
+
- `list_workspaces` - List accessible workspaces
|
|
280
|
+
- `get_active_workspace` - Show active workspace selection
|
|
281
|
+
- `set_active_workspace` - Set active workspace by ID
|
|
282
|
+
- `create_workspace` - Create a new workspace
|
|
283
|
+
- `add_teammate` - Invite a teammate
|
|
284
|
+
|
|
285
|
+
### Campaign Tools (Free)
|
|
286
|
+
|
|
287
|
+
- `get_campaigns` - List all campaigns
|
|
288
|
+
- `get_campaign` - Get campaign details
|
|
289
|
+
- `create_campaign` - Create a campaign offer
|
|
290
|
+
- `update_campaign` - Update campaign positioning/brief/workflow
|
|
291
|
+
- `get_campaign_messages_preview` - Preview campaign leads for messaging (supports filters + pagination)
|
|
292
|
+
- `get_table_rows` - Get leads list
|
|
293
|
+
- `get_rows_minimal` - Get minimal lead list (fast)
|
|
294
|
+
- `get_rows` - Get full lead data
|
|
295
|
+
- `update_cell` - Save message/approve
|
|
296
|
+
- `get_message_prompt` - Get REPLY framework
|
|
297
|
+
- `start_campaign` / `pause_campaign` - Control sending
|
|
298
|
+
|
|
299
|
+
### Lead Tools (Free)
|
|
300
|
+
|
|
301
|
+
- `search_apollo` - Apollo people search
|
|
302
|
+
- `search_prospeo` - Prospeo people search
|
|
303
|
+
- `search_sales_nav` - Sales Navigator search
|
|
304
|
+
- `search_signals` - Signal discovery search
|
|
305
|
+
- `load_csv_domains` - Preview/confirm a CSV-on-disk company-domain file and return a `domainFilterId`
|
|
306
|
+
- `load_csv_linkedin_leads` - Preview/confirm a CSV-on-disk LinkedIn profile file and create a lead list
|
|
307
|
+
- `import_leads` - Create a lead list and start importing leads
|
|
308
|
+
- `confirm_lead_list` - Import confirmed lead list into campaign table
|
|
309
|
+
|
|
310
|
+
### Processing Tools (Free)
|
|
311
|
+
|
|
312
|
+
- `draft_rubrics` - Draft rubric criteria (stored in MCP state)
|
|
313
|
+
- `select_necessary_rubrics` - Keep/mark required rubric checks
|
|
314
|
+
- `save_rubrics` - Persist rubrics and enable ICP filtering
|
|
315
|
+
- `add_rubric_item` - Add a single rubric criterion
|
|
316
|
+
- `update_rubric_item` - Update a rubric criterion by ID
|
|
317
|
+
- `delete_rubric_item` - Delete a rubric criterion by checkName
|
|
318
|
+
- `check_rubric` - Queue enrichment + scoring sample
|
|
319
|
+
- `wait_for_rubric_results` - Poll pass-rate results
|
|
320
|
+
- `upsert_rubric` - Save rubric to campaign (legacy)
|
|
321
|
+
|
|
322
|
+
### Readiness Tools (Free)
|
|
323
|
+
|
|
324
|
+
- `wait_for_lead_list_ready` - Wait for lead list import to complete (and rows)
|
|
325
|
+
- `wait_for_campaign_table_ready` - Wait for campaign table rows to appear
|
|
326
|
+
|
|
327
|
+
### LinkedIn Tools (Cost Credits)
|
|
328
|
+
|
|
329
|
+
- `fetch_linkedin_posts` - Recent LinkedIn posts
|
|
330
|
+
- `fetch_linkedin_profile` - Full profile data
|
|
331
|
+
- `fetch_company` - Company profile data
|
|
332
|
+
|
|
333
|
+
## Credits
|
|
334
|
+
|
|
335
|
+
- Campaign tools are free (you pay Claude tokens)
|
|
336
|
+
- LinkedIn tools cost Sellable credits
|
|
337
|
+
- WebSearch is free (your Claude subscription)
|
|
338
|
+
|
|
339
|
+
## Troubleshooting
|
|
340
|
+
|
|
341
|
+
### "Sellable not configured" Error
|
|
342
|
+
|
|
343
|
+
Create `~/.claude/sellable.json` with your token. Get one at https://app.sellable.dev/settings/integrations.
|
|
344
|
+
|
|
345
|
+
### Token Not Working
|
|
346
|
+
|
|
347
|
+
1. Make sure token starts with `skt_`
|
|
348
|
+
2. Check token is not revoked
|
|
349
|
+
3. Verify activeWorkspaceId matches your workspace (or run list_workspaces + set_active_workspace)
|
|
350
|
+
|
|
351
|
+
## Support
|
|
352
|
+
|
|
353
|
+
- Issues: https://github.com/csreyes/sellable/issues
|
|
354
|
+
- Docs: https://docs.sellable.dev
|
|
355
|
+
- Email: support@sellable.dev
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface ApiResponse<T> {
|
|
2
|
+
data: T;
|
|
3
|
+
error?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class SellableApiError extends Error {
|
|
6
|
+
status: number;
|
|
7
|
+
body: string;
|
|
8
|
+
isAuthError: boolean;
|
|
9
|
+
guidance?: string;
|
|
10
|
+
constructor(status: number, body: string, guidance?: string);
|
|
11
|
+
}
|
|
12
|
+
export declare class SellableApi {
|
|
13
|
+
private request;
|
|
14
|
+
get<T>(path: string): Promise<T>;
|
|
15
|
+
post<T>(path: string, body?: object): Promise<T>;
|
|
16
|
+
put<T>(path: string, body?: object): Promise<T>;
|
|
17
|
+
patch<T>(path: string, body?: object): Promise<T>;
|
|
18
|
+
delete<T>(path: string): Promise<T>;
|
|
19
|
+
}
|
|
20
|
+
export declare function getApi(): SellableApi;
|
|
21
|
+
export declare function resetApi(): void;
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { getConfig, getConfigPath } from "./auth.js";
|
|
2
|
+
export class SellableApiError extends Error {
|
|
3
|
+
status;
|
|
4
|
+
body;
|
|
5
|
+
isAuthError;
|
|
6
|
+
guidance;
|
|
7
|
+
constructor(status, body, guidance) {
|
|
8
|
+
const prefix = status === 401 || status === 403 ? "AUTH_ERROR" : "API_ERROR";
|
|
9
|
+
super(`${prefix} ${status}: ${body}`);
|
|
10
|
+
this.status = status;
|
|
11
|
+
this.body = body;
|
|
12
|
+
this.isAuthError = status === 401 || status === 403;
|
|
13
|
+
this.guidance = guidance;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class SellableApi {
|
|
17
|
+
async request(method, path, body) {
|
|
18
|
+
// Re-read config on every request so workspace switches take effect immediately
|
|
19
|
+
const config = getConfig();
|
|
20
|
+
const url = `${config.apiUrl}${path}`;
|
|
21
|
+
const workspaceId = config.activeWorkspaceId || config.workspaceId || null;
|
|
22
|
+
const response = await fetch(url, {
|
|
23
|
+
method,
|
|
24
|
+
headers: {
|
|
25
|
+
"Content-Type": "application/json",
|
|
26
|
+
Authorization: `Bearer ${config.token}`,
|
|
27
|
+
...(workspaceId ? { "x-workspaceid": workspaceId } : {}),
|
|
28
|
+
},
|
|
29
|
+
...(body && { body: JSON.stringify(body) }),
|
|
30
|
+
});
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
const errorText = await response.text();
|
|
33
|
+
const isAuthError = response.status === 401 || response.status === 403;
|
|
34
|
+
const missingWorkspace = response.status === 400 && errorText.includes("Workspace");
|
|
35
|
+
const guidance = isAuthError
|
|
36
|
+
? "Sellable authentication failed.\n\n" +
|
|
37
|
+
`Update ${getConfigPath()} with a valid token from Sellable Settings -> Integrations, then retry.\n\n` +
|
|
38
|
+
"NOTE: If the token was just updated via the LLM (editing the config file), " +
|
|
39
|
+
"the change should take effect immediately. If it still fails, restart Claude Code to restart the MCP server."
|
|
40
|
+
: missingWorkspace
|
|
41
|
+
? "No active workspace selected.\n\n" +
|
|
42
|
+
"Run list_workspaces then set_active_workspace to choose a workspace."
|
|
43
|
+
: undefined;
|
|
44
|
+
throw new SellableApiError(response.status, errorText, guidance);
|
|
45
|
+
}
|
|
46
|
+
return response.json();
|
|
47
|
+
}
|
|
48
|
+
async get(path) {
|
|
49
|
+
return this.request("GET", path);
|
|
50
|
+
}
|
|
51
|
+
async post(path, body) {
|
|
52
|
+
return this.request("POST", path, body);
|
|
53
|
+
}
|
|
54
|
+
async put(path, body) {
|
|
55
|
+
return this.request("PUT", path, body);
|
|
56
|
+
}
|
|
57
|
+
async patch(path, body) {
|
|
58
|
+
return this.request("PATCH", path, body);
|
|
59
|
+
}
|
|
60
|
+
async delete(path) {
|
|
61
|
+
return this.request("DELETE", path);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
let apiInstance = null;
|
|
65
|
+
export function getApi() {
|
|
66
|
+
if (!apiInstance) {
|
|
67
|
+
apiInstance = new SellableApi();
|
|
68
|
+
}
|
|
69
|
+
return apiInstance;
|
|
70
|
+
}
|
|
71
|
+
export function resetApi() {
|
|
72
|
+
apiInstance = null;
|
|
73
|
+
}
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface SellableEnvConfig {
|
|
2
|
+
token: string;
|
|
3
|
+
activeWorkspaceId?: string;
|
|
4
|
+
activeWorkspaceName?: string;
|
|
5
|
+
workspaceId?: string;
|
|
6
|
+
workspaceName?: string;
|
|
7
|
+
apiUrl?: string;
|
|
8
|
+
skillState?: SkillState;
|
|
9
|
+
}
|
|
10
|
+
export interface SellableMultiEnvConfig {
|
|
11
|
+
activeEnv: string;
|
|
12
|
+
environments: Record<string, SellableEnvConfig>;
|
|
13
|
+
}
|
|
14
|
+
export type SellableConfig = SellableEnvConfig & {
|
|
15
|
+
/** Name of the active environment (e.g. "local", "prod"). */
|
|
16
|
+
activeEnvName?: string;
|
|
17
|
+
};
|
|
18
|
+
export type EngageWorkspaceState = {
|
|
19
|
+
lastSenderId?: string;
|
|
20
|
+
lastCommentCampaignTableId?: string;
|
|
21
|
+
/** Multi-sender: array of sender IDs from last session. */
|
|
22
|
+
lastSenderIds?: string[];
|
|
23
|
+
/** Multi-sender: map of senderId → comment campaign tableId. */
|
|
24
|
+
lastCommentCampaignTableIds?: Record<string, string>;
|
|
25
|
+
/** Last session mode. */
|
|
26
|
+
lastMode?: "interactive" | "autonomous";
|
|
27
|
+
updatedAt?: string;
|
|
28
|
+
};
|
|
29
|
+
export type EngageSkillState = {
|
|
30
|
+
byWorkspace?: Record<string, EngageWorkspaceState>;
|
|
31
|
+
};
|
|
32
|
+
export type SkillState = {
|
|
33
|
+
engage?: EngageSkillState;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Set which config file to use. Call before getConfig().
|
|
37
|
+
* - "sellable.json" (default) - production
|
|
38
|
+
* - "sellable-dev.json" - local development
|
|
39
|
+
*/
|
|
40
|
+
export declare function setConfigFile(fileName: string): void;
|
|
41
|
+
export declare function getConfigPath(): string;
|
|
42
|
+
export declare function getConfig(): SellableConfig;
|
|
43
|
+
export declare function updateActiveWorkspace(params: {
|
|
44
|
+
workspaceId: string;
|
|
45
|
+
workspaceName?: string | null;
|
|
46
|
+
}): void;
|
|
47
|
+
export declare function getEngageState(): {
|
|
48
|
+
activeWorkspaceId: string | null;
|
|
49
|
+
state: EngageWorkspaceState | null;
|
|
50
|
+
};
|
|
51
|
+
export declare function updateEngageState(patch: {
|
|
52
|
+
lastSenderId?: string;
|
|
53
|
+
lastCommentCampaignTableId?: string | null;
|
|
54
|
+
lastSenderIds?: string[];
|
|
55
|
+
lastCommentCampaignTableIds?: Record<string, string>;
|
|
56
|
+
lastMode?: "interactive" | "autonomous";
|
|
57
|
+
}): {
|
|
58
|
+
activeWorkspaceId: string;
|
|
59
|
+
state: EngageWorkspaceState;
|
|
60
|
+
};
|