@sellable/mcp 0.1.235 → 0.1.237
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/README.md +19 -14
- package/dist/index-dev.js +0 -0
- package/dist/index.js +0 -0
- package/dist/server.js +28 -0
- package/dist/tools/campaigns.js +10 -7
- package/dist/tools/content-posts.d.ts +308 -0
- package/dist/tools/content-posts.js +611 -0
- package/dist/tools/leads.d.ts +2 -2
- package/dist/tools/registry.d.ts +105 -0
- package/dist/tools/registry.js +2 -0
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +6 -4
- package/skills/create-campaign-v2/SOUL.md +6 -4
- package/skills/create-campaign-v2/core/flow.v2.json +1 -1
- package/skills/create-campaign-v2/references/gold-standard-message-validation-example.md +21 -0
- package/skills/create-campaign-v2/references/validation-criteria.md +7 -0
- package/skills/create-campaign-v2/references/watch-link-handoff.md +6 -4
- package/skills/create-campaign-v2-validation/SKILL.md +7 -0
- package/skills/create-post/SKILL.md +204 -1273
- package/skills/create-post/references/hook-research-playbook.md +68 -0
- package/skills/create-post/references/post-file-contract.md +88 -0
- package/skills/create-post/references/post-validation.md +95 -0
- package/skills/generate-messages/SKILL.md +45 -3
- package/skills/interview/SKILL.md +19 -0
- package/skills/load-voice/SKILL.md +8 -2
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ There are three public Sellable entrypoints shared across hosts:
|
|
|
20
20
|
|
|
21
21
|
- `sellable:create-campaign`
|
|
22
22
|
- `sellable:interview`
|
|
23
|
-
- `sellable:
|
|
23
|
+
- `sellable:create-post`
|
|
24
24
|
|
|
25
25
|
The create-campaign public wrapper at
|
|
26
26
|
`mcp/sellable/skills/create-campaign/SKILL.md` handles auth/bootstrap and loads
|
|
@@ -33,12 +33,15 @@ from:
|
|
|
33
33
|
|
|
34
34
|
- `mcp/sellable/skills/interview/SKILL.md`
|
|
35
35
|
|
|
36
|
-
The
|
|
37
|
-
|
|
36
|
+
The create-post public wrapper captures raw ideas, loads voice internally,
|
|
37
|
+
researches hooks, validates proof/AI tells, and saves content artifacts under
|
|
38
|
+
`~/.sellable/content/linkedin/**` from:
|
|
38
39
|
|
|
39
|
-
- `mcp/sellable/skills/
|
|
40
|
+
- `mcp/sellable/skills/create-post/SKILL.md`
|
|
40
41
|
|
|
41
|
-
Keep `create-campaign-v2` internal. Do not advertise
|
|
42
|
+
Keep `create-campaign-v2` and `load-voice` internal. Do not advertise either as
|
|
43
|
+
a public command. `load-voice` remains a direct MCP utility for generic writing
|
|
44
|
+
surfaces that are not posts or campaigns.
|
|
42
45
|
|
|
43
46
|
### 1. One-Command Agent Install
|
|
44
47
|
|
|
@@ -134,8 +137,8 @@ The installer does the full local setup:
|
|
|
134
137
|
|
|
135
138
|
After the installer passes, fully quit and reopen Codex Desktop. Start a new
|
|
136
139
|
thread and select `Sellable Create Campaign`, `Sellable Identity Interview`, or
|
|
137
|
-
`Sellable
|
|
138
|
-
`$sellable:interview`, or `$sellable:
|
|
140
|
+
`Sellable Create Post`; or invoke `$sellable:create-campaign`,
|
|
141
|
+
`$sellable:interview`, or `$sellable:create-post`. If the app still says
|
|
139
142
|
`mcp__sellable__*` tools are missing after the installer passes, check that
|
|
140
143
|
`~/.codex/config.toml` contains both `[marketplaces.sellable]` and
|
|
141
144
|
`[plugins."sellable@sellable"]`.
|
|
@@ -148,24 +151,26 @@ Use these names consistently:
|
|
|
148
151
|
|
|
149
152
|
- Claude Code command: `/sellable:create-campaign`
|
|
150
153
|
- Claude Code command: `/sellable:interview`
|
|
151
|
-
- Claude Code command: `/sellable:
|
|
154
|
+
- Claude Code command: `/sellable:create-post`
|
|
152
155
|
- Codex command: `$sellable:create-campaign`
|
|
153
156
|
- Codex command: `$sellable:interview`
|
|
154
|
-
- Codex command: `$sellable:
|
|
157
|
+
- Codex command: `$sellable:create-post`
|
|
155
158
|
- Codex Desktop plugin: `sellable@sellable`
|
|
156
159
|
- Codex visible skill: `Sellable Create Campaign`
|
|
157
160
|
- Codex visible skill: `Sellable Identity Interview`
|
|
158
|
-
- Codex visible skill: `Sellable
|
|
161
|
+
- Codex visible skill: `Sellable Create Post`
|
|
159
162
|
- Codex skill frontmatter name: `create-campaign`
|
|
160
163
|
- Codex skill frontmatter name: `interview`
|
|
161
|
-
- Codex skill frontmatter name: `
|
|
164
|
+
- Codex skill frontmatter name: `create-post`
|
|
162
165
|
- MCP server name: `sellable`
|
|
163
166
|
- Internal workflow prompt: `create-campaign-v2`
|
|
164
167
|
|
|
165
168
|
Never tell users to run `/sellable:create-campaign-v2`,
|
|
166
|
-
`$sellable:create-campaign-v2`,
|
|
167
|
-
`create-campaign-v2` is an internal MCP
|
|
168
|
-
`get_subskill_prompt({ subskillName: "create-campaign-v2" })`.
|
|
169
|
+
`$sellable:create-campaign-v2`, `$sellable:load-voice`, or
|
|
170
|
+
`$sellable:sellable:create-campaign`. `create-campaign-v2` is an internal MCP
|
|
171
|
+
subskill loaded by `get_subskill_prompt({ subskillName: "create-campaign-v2" })`.
|
|
172
|
+
`load-voice` is an internal direct MCP utility; `create-post` loads voice
|
|
173
|
+
silently for post drafting.
|
|
169
174
|
|
|
170
175
|
## Structured Question Parity
|
|
171
176
|
|
package/dist/index-dev.js
CHANGED
|
File without changes
|
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/server.js
CHANGED
|
@@ -10,6 +10,7 @@ import { getCampaignTableSchema, queueCampaignCells, reviseMessageTemplateAndRer
|
|
|
10
10
|
import { queueCells, updateCell } from "./tools/cells.js";
|
|
11
11
|
import { handleStartCliLogin, handleWaitForCliLogin, } from "./tools/cli-login.js";
|
|
12
12
|
import { getCampaignContext, hydrateCampaignContextFromCampaign, markCampaignContextDirty, } from "./tools/context.js";
|
|
13
|
+
import { capturePostIdeaTool, getPostDraftTool, getPostIdeaTool, listPostDraftsTool, listPostIdeasTool, listPublishedPostsTool, markPostPublishedTool, saveHookResearchTool, savePostDraftTool, } from "./tools/content-posts.js";
|
|
13
14
|
import { addToCommentCampaign, addToConnectionCampaign, addToInmailCampaign, getEngagedPosts, getOrCreateDirectCampaignTable, pauseDirectCampaign, startDirectCampaign, } from "./tools/direct-campaigns.js";
|
|
14
15
|
import { bootstrapEngage, bootstrapEngageMulti, } from "./tools/engage-bootstrap.js";
|
|
15
16
|
import { searchEngagementPosts } from "./tools/engage-discovery.js";
|
|
@@ -222,6 +223,33 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
222
223
|
case "get_campaign_navigation_state":
|
|
223
224
|
result = await getCampaignNavigationState(args);
|
|
224
225
|
break;
|
|
226
|
+
case "capture_post_idea":
|
|
227
|
+
result = capturePostIdeaTool(args);
|
|
228
|
+
break;
|
|
229
|
+
case "list_post_ideas":
|
|
230
|
+
result = listPostIdeasTool(args);
|
|
231
|
+
break;
|
|
232
|
+
case "get_post_idea":
|
|
233
|
+
result = getPostIdeaTool(args);
|
|
234
|
+
break;
|
|
235
|
+
case "save_hook_research":
|
|
236
|
+
result = saveHookResearchTool(args);
|
|
237
|
+
break;
|
|
238
|
+
case "save_post_draft":
|
|
239
|
+
result = savePostDraftTool(args);
|
|
240
|
+
break;
|
|
241
|
+
case "list_post_drafts":
|
|
242
|
+
result = listPostDraftsTool(args);
|
|
243
|
+
break;
|
|
244
|
+
case "get_post_draft":
|
|
245
|
+
result = getPostDraftTool(args);
|
|
246
|
+
break;
|
|
247
|
+
case "mark_post_published":
|
|
248
|
+
result = markPostPublishedTool(args);
|
|
249
|
+
break;
|
|
250
|
+
case "list_published_posts":
|
|
251
|
+
result = listPublishedPostsTool(args);
|
|
252
|
+
break;
|
|
225
253
|
case "get_table_rows":
|
|
226
254
|
result = await getTableRows(args?.tableId, {
|
|
227
255
|
limit: args?.limit,
|
package/dist/tools/campaigns.js
CHANGED
|
@@ -49,24 +49,27 @@ function getCampaignBuilderWatchModeFromUrl(watchUrl) {
|
|
|
49
49
|
export function getCampaignBuilderWatchModeDriverLabel(mode = getCampaignBuilderWatchModeParam()) {
|
|
50
50
|
return mode === "codex" ? "Codex" : "Claude Code";
|
|
51
51
|
}
|
|
52
|
-
function
|
|
53
|
-
const width =
|
|
52
|
+
function buildWatchHandoffHeadlineBox(headline) {
|
|
53
|
+
const width = 52;
|
|
54
54
|
const visibleHeadline = headline.length > width ? headline.slice(0, width) : headline;
|
|
55
55
|
const padding = Math.max(width - visibleHeadline.length, 0);
|
|
56
56
|
const left = Math.floor(padding / 2);
|
|
57
57
|
const right = padding - left;
|
|
58
|
+
const border = `+${"-".repeat(width + 2)}+`;
|
|
58
59
|
return [
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
"```text",
|
|
61
|
+
border,
|
|
62
|
+
`| ${" ".repeat(left)}${visibleHeadline}${" ".repeat(right)} |`,
|
|
63
|
+
border,
|
|
64
|
+
"```",
|
|
62
65
|
].join("\n");
|
|
63
66
|
}
|
|
64
67
|
export function buildCampaignWatchHandoffMarkdown(watchUrl, mode = getCampaignBuilderWatchModeFromUrl(watchUrl) ??
|
|
65
68
|
getCampaignBuilderWatchModeParam()) {
|
|
66
69
|
const driverLabel = getCampaignBuilderWatchModeDriverLabel(mode);
|
|
67
|
-
const headline = `
|
|
70
|
+
const headline = `WATCH ${driverLabel.toUpperCase()} BUILD THE CAMPAIGN LIVE`;
|
|
68
71
|
return [
|
|
69
|
-
|
|
72
|
+
buildWatchHandoffHeadlineBox(headline),
|
|
70
73
|
"",
|
|
71
74
|
`[Open live campaign builder](${watchUrl})`,
|
|
72
75
|
"",
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
type ContentKind = "idea" | "hook_research" | "draft" | "published_post";
|
|
2
|
+
type ArtifactMetadata = {
|
|
3
|
+
id: string;
|
|
4
|
+
type: ContentKind;
|
|
5
|
+
status: string;
|
|
6
|
+
createdAt: string;
|
|
7
|
+
updatedAt: string;
|
|
8
|
+
title?: string;
|
|
9
|
+
ideaId?: string;
|
|
10
|
+
hookResearchId?: string;
|
|
11
|
+
publishUrl?: string;
|
|
12
|
+
publishedAt?: string;
|
|
13
|
+
sourceType?: string;
|
|
14
|
+
sourceUrl?: string;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
};
|
|
17
|
+
export type ContentPostSummary = {
|
|
18
|
+
id: string;
|
|
19
|
+
type: ContentKind;
|
|
20
|
+
status: string;
|
|
21
|
+
path: string;
|
|
22
|
+
title?: string;
|
|
23
|
+
updatedAt: string;
|
|
24
|
+
preview: string;
|
|
25
|
+
};
|
|
26
|
+
export declare const contentPostToolDefinitions: ({
|
|
27
|
+
name: string;
|
|
28
|
+
description: string;
|
|
29
|
+
inputSchema: {
|
|
30
|
+
type: string;
|
|
31
|
+
properties: {
|
|
32
|
+
rawSource: {
|
|
33
|
+
type: string;
|
|
34
|
+
description: string;
|
|
35
|
+
};
|
|
36
|
+
title: {
|
|
37
|
+
type: string;
|
|
38
|
+
};
|
|
39
|
+
distilledBrief: {
|
|
40
|
+
type: string;
|
|
41
|
+
description: string;
|
|
42
|
+
};
|
|
43
|
+
ideaId: {
|
|
44
|
+
type: string;
|
|
45
|
+
description: string;
|
|
46
|
+
};
|
|
47
|
+
sourceType: {
|
|
48
|
+
type: string;
|
|
49
|
+
};
|
|
50
|
+
sourceUrl: {
|
|
51
|
+
type: string;
|
|
52
|
+
};
|
|
53
|
+
capturedAt: {
|
|
54
|
+
type: string;
|
|
55
|
+
};
|
|
56
|
+
researchId?: undefined;
|
|
57
|
+
topic?: undefined;
|
|
58
|
+
keywords?: undefined;
|
|
59
|
+
sourcePosts?: undefined;
|
|
60
|
+
selectedPatterns?: undefined;
|
|
61
|
+
notes?: undefined;
|
|
62
|
+
createdAt?: undefined;
|
|
63
|
+
draftId?: undefined;
|
|
64
|
+
hookResearchId?: undefined;
|
|
65
|
+
body?: undefined;
|
|
66
|
+
validationReceipt?: undefined;
|
|
67
|
+
status?: undefined;
|
|
68
|
+
};
|
|
69
|
+
required: string[];
|
|
70
|
+
additionalProperties: boolean;
|
|
71
|
+
};
|
|
72
|
+
} | {
|
|
73
|
+
name: string;
|
|
74
|
+
description: string;
|
|
75
|
+
inputSchema: {
|
|
76
|
+
type: string;
|
|
77
|
+
properties: {
|
|
78
|
+
limit: {
|
|
79
|
+
type: string;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
required: never[];
|
|
83
|
+
additionalProperties: boolean;
|
|
84
|
+
};
|
|
85
|
+
} | {
|
|
86
|
+
name: string;
|
|
87
|
+
description: string;
|
|
88
|
+
inputSchema: {
|
|
89
|
+
type: string;
|
|
90
|
+
properties: {
|
|
91
|
+
[x: string]: {
|
|
92
|
+
type: string;
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
required: string[];
|
|
96
|
+
additionalProperties: boolean;
|
|
97
|
+
};
|
|
98
|
+
} | {
|
|
99
|
+
name: string;
|
|
100
|
+
description: string;
|
|
101
|
+
inputSchema: {
|
|
102
|
+
type: string;
|
|
103
|
+
properties: {
|
|
104
|
+
researchId: {
|
|
105
|
+
type: string;
|
|
106
|
+
};
|
|
107
|
+
ideaId: {
|
|
108
|
+
type: string;
|
|
109
|
+
description?: undefined;
|
|
110
|
+
};
|
|
111
|
+
topic: {
|
|
112
|
+
type: string;
|
|
113
|
+
};
|
|
114
|
+
keywords: {
|
|
115
|
+
type: string;
|
|
116
|
+
items: {
|
|
117
|
+
type: string;
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
sourcePosts: {
|
|
121
|
+
type: string;
|
|
122
|
+
items: {
|
|
123
|
+
type: string;
|
|
124
|
+
additionalProperties: boolean;
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
selectedPatterns: {
|
|
128
|
+
type: string;
|
|
129
|
+
items: {
|
|
130
|
+
type: string;
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
notes: {
|
|
134
|
+
type: string;
|
|
135
|
+
};
|
|
136
|
+
createdAt: {
|
|
137
|
+
type: string;
|
|
138
|
+
};
|
|
139
|
+
rawSource?: undefined;
|
|
140
|
+
title?: undefined;
|
|
141
|
+
distilledBrief?: undefined;
|
|
142
|
+
sourceType?: undefined;
|
|
143
|
+
sourceUrl?: undefined;
|
|
144
|
+
capturedAt?: undefined;
|
|
145
|
+
draftId?: undefined;
|
|
146
|
+
hookResearchId?: undefined;
|
|
147
|
+
body?: undefined;
|
|
148
|
+
validationReceipt?: undefined;
|
|
149
|
+
status?: undefined;
|
|
150
|
+
};
|
|
151
|
+
required: never[];
|
|
152
|
+
additionalProperties: boolean;
|
|
153
|
+
};
|
|
154
|
+
} | {
|
|
155
|
+
name: string;
|
|
156
|
+
description: string;
|
|
157
|
+
inputSchema: {
|
|
158
|
+
type: string;
|
|
159
|
+
properties: {
|
|
160
|
+
draftId: {
|
|
161
|
+
type: string;
|
|
162
|
+
};
|
|
163
|
+
ideaId: {
|
|
164
|
+
type: string;
|
|
165
|
+
description?: undefined;
|
|
166
|
+
};
|
|
167
|
+
hookResearchId: {
|
|
168
|
+
type: string;
|
|
169
|
+
};
|
|
170
|
+
title: {
|
|
171
|
+
type: string;
|
|
172
|
+
};
|
|
173
|
+
body: {
|
|
174
|
+
type: string;
|
|
175
|
+
};
|
|
176
|
+
validationReceipt: {
|
|
177
|
+
description: string;
|
|
178
|
+
};
|
|
179
|
+
createdAt: {
|
|
180
|
+
type: string;
|
|
181
|
+
};
|
|
182
|
+
status: {
|
|
183
|
+
type: string;
|
|
184
|
+
};
|
|
185
|
+
rawSource?: undefined;
|
|
186
|
+
distilledBrief?: undefined;
|
|
187
|
+
sourceType?: undefined;
|
|
188
|
+
sourceUrl?: undefined;
|
|
189
|
+
capturedAt?: undefined;
|
|
190
|
+
researchId?: undefined;
|
|
191
|
+
topic?: undefined;
|
|
192
|
+
keywords?: undefined;
|
|
193
|
+
sourcePosts?: undefined;
|
|
194
|
+
selectedPatterns?: undefined;
|
|
195
|
+
notes?: undefined;
|
|
196
|
+
};
|
|
197
|
+
required: string[];
|
|
198
|
+
additionalProperties: boolean;
|
|
199
|
+
};
|
|
200
|
+
})[];
|
|
201
|
+
export declare function resolveContentRoot(): string;
|
|
202
|
+
export declare function ensureContentLayout(root?: string): {
|
|
203
|
+
root: string;
|
|
204
|
+
directories: {
|
|
205
|
+
ideas: "linkedin/ideas";
|
|
206
|
+
hookResearch: "linkedin/research/hooks";
|
|
207
|
+
drafts: "linkedin/drafts";
|
|
208
|
+
published: "linkedin/published";
|
|
209
|
+
commentLibrary: "linkedin/comments/library";
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
export declare function capturePostIdeaTool(input: {
|
|
213
|
+
rawSource: string;
|
|
214
|
+
title?: string;
|
|
215
|
+
distilledBrief?: string;
|
|
216
|
+
ideaId?: string;
|
|
217
|
+
sourceType?: string;
|
|
218
|
+
sourceUrl?: string;
|
|
219
|
+
capturedAt?: string;
|
|
220
|
+
}): {
|
|
221
|
+
id: string;
|
|
222
|
+
path: string;
|
|
223
|
+
status: string;
|
|
224
|
+
createdAt: string;
|
|
225
|
+
updatedAt: string;
|
|
226
|
+
preview: string;
|
|
227
|
+
rawSourceExact: boolean;
|
|
228
|
+
};
|
|
229
|
+
export declare function listPostIdeasTool(input?: {
|
|
230
|
+
limit?: number;
|
|
231
|
+
}): ContentPostSummary[];
|
|
232
|
+
export declare function getPostIdeaTool(input: {
|
|
233
|
+
ideaId: string;
|
|
234
|
+
}): {
|
|
235
|
+
id: string;
|
|
236
|
+
path: string;
|
|
237
|
+
metadata: ArtifactMetadata;
|
|
238
|
+
markdown: string;
|
|
239
|
+
rawSource: string | undefined;
|
|
240
|
+
};
|
|
241
|
+
export declare function saveHookResearchTool(input: {
|
|
242
|
+
researchId?: string;
|
|
243
|
+
ideaId?: string;
|
|
244
|
+
topic?: string;
|
|
245
|
+
keywords?: string[];
|
|
246
|
+
sourcePosts?: Array<Record<string, unknown>>;
|
|
247
|
+
selectedPatterns?: string[];
|
|
248
|
+
notes?: string;
|
|
249
|
+
createdAt?: string;
|
|
250
|
+
}): {
|
|
251
|
+
id: string;
|
|
252
|
+
path: string;
|
|
253
|
+
status: string;
|
|
254
|
+
ideaId: string | undefined;
|
|
255
|
+
updatedAt: string;
|
|
256
|
+
preview: string;
|
|
257
|
+
};
|
|
258
|
+
export declare function savePostDraftTool(input: {
|
|
259
|
+
draftId?: string;
|
|
260
|
+
ideaId: string;
|
|
261
|
+
hookResearchId?: string;
|
|
262
|
+
title?: string;
|
|
263
|
+
body: string;
|
|
264
|
+
validationReceipt: unknown;
|
|
265
|
+
createdAt?: string;
|
|
266
|
+
status?: string;
|
|
267
|
+
}): {
|
|
268
|
+
id: string;
|
|
269
|
+
path: string;
|
|
270
|
+
status: string;
|
|
271
|
+
ideaId: string;
|
|
272
|
+
hookResearchId: string | undefined;
|
|
273
|
+
updatedAt: string;
|
|
274
|
+
preview: string;
|
|
275
|
+
};
|
|
276
|
+
export declare function listPostDraftsTool(input?: {
|
|
277
|
+
limit?: number;
|
|
278
|
+
}): ContentPostSummary[];
|
|
279
|
+
export declare function getPostDraftTool(input: {
|
|
280
|
+
draftId: string;
|
|
281
|
+
}): {
|
|
282
|
+
id: string;
|
|
283
|
+
path: string;
|
|
284
|
+
metadata: ArtifactMetadata;
|
|
285
|
+
markdown: string;
|
|
286
|
+
rawSource: string | undefined;
|
|
287
|
+
};
|
|
288
|
+
export declare function markPostPublishedTool(input: {
|
|
289
|
+
draftId?: string;
|
|
290
|
+
publishUrl: string;
|
|
291
|
+
activityId?: string;
|
|
292
|
+
publishedAt?: string;
|
|
293
|
+
finalText?: string;
|
|
294
|
+
title?: string;
|
|
295
|
+
}): {
|
|
296
|
+
id: string;
|
|
297
|
+
path: string;
|
|
298
|
+
status: string;
|
|
299
|
+
draftId: string | undefined;
|
|
300
|
+
publishUrl: string;
|
|
301
|
+
publishedAt: string;
|
|
302
|
+
updatedAt: string;
|
|
303
|
+
preview: string;
|
|
304
|
+
};
|
|
305
|
+
export declare function listPublishedPostsTool(input?: {
|
|
306
|
+
limit?: number;
|
|
307
|
+
}): ContentPostSummary[];
|
|
308
|
+
export {};
|