@sellable/mcp 0.1.254 → 0.1.256
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/api.d.ts +3 -0
- package/dist/api.js +24 -13
- package/dist/index-dev.js +0 -0
- package/dist/index.js +0 -0
- package/dist/server.js +13 -4
- package/dist/tools/campaigns.d.ts +41 -0
- package/dist/tools/campaigns.js +22 -3
- package/dist/tools/registry.d.ts +483 -412
- package/dist/tools/tables.d.ts +53 -2
- package/dist/tools/tables.js +78 -0
- package/package.json +1 -1
- package/skills/create-post/SKILL.md +52 -17
- package/skills/create-post/references/gold-standard-post-pack.md +11 -0
- package/skills/create-post/references/hook-research-playbook.md +57 -14
- package/skills/create-post/references/linkedin-preview-rendering.md +163 -0
- package/skills/create-post/references/post-file-contract.md +7 -0
- package/skills/create-post/references/post-validation.md +68 -15
- package/skills/research/config.json +9 -0
package/dist/api.d.ts
CHANGED
|
@@ -10,8 +10,11 @@ export declare class SellableApiError extends Error {
|
|
|
10
10
|
constructor(status: number, body: string, guidance?: string);
|
|
11
11
|
}
|
|
12
12
|
export declare class SellableApi {
|
|
13
|
+
private buildError;
|
|
14
|
+
private requestResponse;
|
|
13
15
|
private request;
|
|
14
16
|
get<T>(path: string): Promise<T>;
|
|
17
|
+
getText(path: string): Promise<string>;
|
|
15
18
|
post<T>(path: string, body?: object): Promise<T>;
|
|
16
19
|
put<T>(path: string, body?: object): Promise<T>;
|
|
17
20
|
patch<T>(path: string, body?: object): Promise<T>;
|
package/dist/api.js
CHANGED
|
@@ -14,7 +14,21 @@ export class SellableApiError extends Error {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
export class SellableApi {
|
|
17
|
-
|
|
17
|
+
buildError(status, errorText) {
|
|
18
|
+
const isAuthError = status === 401 || status === 403;
|
|
19
|
+
const missingWorkspace = status === 400 && errorText.includes("Workspace");
|
|
20
|
+
const guidance = isAuthError
|
|
21
|
+
? "Sellable authentication failed.\n\n" +
|
|
22
|
+
`Update ${getConfigPath()} with a valid token from Sellable Settings -> Integrations, then retry.\n\n` +
|
|
23
|
+
"NOTE: If the token was just updated via the LLM (editing the config file), " +
|
|
24
|
+
"the change should take effect immediately. If it still fails, restart Claude Code to restart the MCP server."
|
|
25
|
+
: missingWorkspace
|
|
26
|
+
? "No active workspace selected.\n\n" +
|
|
27
|
+
"Run list_workspaces then set_active_workspace to choose a workspace."
|
|
28
|
+
: undefined;
|
|
29
|
+
return new SellableApiError(status, errorText, guidance);
|
|
30
|
+
}
|
|
31
|
+
async requestResponse(method, path, body) {
|
|
18
32
|
// Re-read config on every request so workspace switches take effect immediately
|
|
19
33
|
const config = getConfig();
|
|
20
34
|
const url = `${config.apiUrl}${path}`;
|
|
@@ -30,24 +44,21 @@ export class SellableApi {
|
|
|
30
44
|
});
|
|
31
45
|
if (!response.ok) {
|
|
32
46
|
const errorText = await response.text();
|
|
33
|
-
|
|
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);
|
|
47
|
+
throw this.buildError(response.status, errorText);
|
|
45
48
|
}
|
|
49
|
+
return response;
|
|
50
|
+
}
|
|
51
|
+
async request(method, path, body) {
|
|
52
|
+
const response = await this.requestResponse(method, path, body);
|
|
46
53
|
return response.json();
|
|
47
54
|
}
|
|
48
55
|
async get(path) {
|
|
49
56
|
return this.request("GET", path);
|
|
50
57
|
}
|
|
58
|
+
async getText(path) {
|
|
59
|
+
const response = await this.requestResponse("GET", path);
|
|
60
|
+
return response.text();
|
|
61
|
+
}
|
|
51
62
|
async post(path, body) {
|
|
52
63
|
return this.request("POST", path, body);
|
|
53
64
|
}
|
package/dist/index-dev.js
CHANGED
|
File without changes
|
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/server.js
CHANGED
|
@@ -5,12 +5,12 @@ import { getSkillByName, listSkills } from "./skills.js";
|
|
|
5
5
|
import { getAuthStatus } from "./tools/auth.js";
|
|
6
6
|
import { handleAddColumn, handleCommitBlueprint, } from "./tools/blueprint-commit.js";
|
|
7
7
|
import { bootstrapCreateCampaign } from "./tools/bootstrap.js";
|
|
8
|
-
import { createCampaign, getCampaign, getCampaignMessagesPreview, getCampaigns, pauseCampaign, startCampaign, updateCampaign, updateCampaignBrief, } from "./tools/campaigns.js";
|
|
9
8
|
import { getCampaignTableSchema, queueCampaignCells, reviseMessageTemplateAndRerun, selectCampaignCells, waitForCampaignProcessing, } from "./tools/campaign-processing.js";
|
|
9
|
+
import { createCampaign, duplicateCampaign, getCampaign, getCampaignMessagesPreview, getCampaigns, pauseCampaign, startCampaign, updateCampaign, updateCampaignBrief, } from "./tools/campaigns.js";
|
|
10
10
|
import { queueCells, updateCell } from "./tools/cells.js";
|
|
11
11
|
import { handleStartCliLogin, handleWaitForCliLogin, } from "./tools/cli-login.js";
|
|
12
|
+
import { capturePostIdeaTool, getPostDraftTool, getPostIdeaTool, getPublishedPostTool, listPostDraftIterationsTool, listPostDraftsTool, listPostIdeasTool, listPublishedPostsTool, markPostPublishedTool, saveHookResearchTool, savePostDraftTool, updatePostDraftTool, updatePublishedPostMetricsTool, } from "./tools/content-posts.js";
|
|
12
13
|
import { getCampaignContext, hydrateCampaignContextFromCampaign, markCampaignContextDirty, } from "./tools/context.js";
|
|
13
|
-
import { capturePostIdeaTool, getPublishedPostTool, getPostDraftTool, getPostIdeaTool, listPostDraftIterationsTool, listPostDraftsTool, listPostIdeasTool, listPublishedPostsTool, markPostPublishedTool, saveHookResearchTool, savePostDraftTool, updatePostDraftTool, updatePublishedPostMetricsTool, } from "./tools/content-posts.js";
|
|
14
14
|
import { addToCommentCampaign, addToConnectionCampaign, addToInmailCampaign, getEngagedPosts, getOrCreateDirectCampaignTable, pauseDirectCampaign, startDirectCampaign, } from "./tools/direct-campaigns.js";
|
|
15
15
|
import { bootstrapEngage, bootstrapEngageMulti, } from "./tools/engage-bootstrap.js";
|
|
16
16
|
import { searchEngagementPosts } from "./tools/engage-discovery.js";
|
|
@@ -18,7 +18,7 @@ import { copySenderConfigTool, getEngageMemoryTool, migrateFlatConfigsTool, reco
|
|
|
18
18
|
import { getEngageStateTool, setEngageStateTool, } from "./tools/engage-state.js";
|
|
19
19
|
import { bulkEnrichWithProspeo, enrichWithProspeo, getProspeoCredits, } from "./tools/enrichment.js";
|
|
20
20
|
import { getCampaignFramework } from "./tools/framework.js";
|
|
21
|
-
import { cancelLeadImport,
|
|
21
|
+
import { cancelLeadImport, confirmLeadList, confirmProspeoCompanyAccounts, getProviderPrompt, importLeads, loadCsvDncEntriesTool, loadCsvDomains, loadCsvLinkedinLeads, lookupSalesNavFilter, saveDomainFilters, searchApollo, searchProspeo, searchProspeoCompanies, searchSalesNav, searchSignals, selectPromisingPosts, setHeadlineICPCriteria, } from "./tools/leads.js";
|
|
22
22
|
import { fetchCompany, fetchCompanyPosts, fetchLinkedInPosts, fetchLinkedInProfile, fetchPostEngagers, getLinkedInProfile, getUserPosts, } from "./tools/linkedin.js";
|
|
23
23
|
import { getCampaignNavigationState } from "./tools/navigation.js";
|
|
24
24
|
import { addOnDemandLeads, createOnDemandCampaign, createOnDemandTable, initOnDemandSequence, pauseOnDemandCampaign, startOnDemandCampaign, } from "./tools/one-off.js";
|
|
@@ -30,7 +30,7 @@ import { getRows, getTableRows, getTableRowsMinimal } from "./tools/rows.js";
|
|
|
30
30
|
import { addRubricItem, checkRubric, deleteRubricItem, draftRubrics, saveRubrics, selectNecessaryRubrics, updateRubricItem, waitForRubricResults, } from "./tools/rubrics.js";
|
|
31
31
|
import { getSender, listSenders } from "./tools/senders.js";
|
|
32
32
|
import { attachRecommendedSequence, attachSequence, createWorkflowTable, } from "./tools/sequencer.js";
|
|
33
|
-
import { listTables } from "./tools/tables.js";
|
|
33
|
+
import { exportTableCsv, listTables } from "./tools/tables.js";
|
|
34
34
|
import { handleVerifyTableRow } from "./tools/verify-row.js";
|
|
35
35
|
import { sanitizeWatchUrlsForMcpResult } from "./tools/watch-url-security.js";
|
|
36
36
|
import { addTeammate, createWorkspace, getActiveWorkspace, listWorkspaces, setActiveWorkspace, } from "./tools/workspaces.js";
|
|
@@ -208,6 +208,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
208
208
|
case "pause_campaign":
|
|
209
209
|
result = await pauseCampaign(args?.campaignId);
|
|
210
210
|
break;
|
|
211
|
+
case "duplicate_campaign":
|
|
212
|
+
result = await duplicateCampaign(args?.campaignId);
|
|
213
|
+
if (result?.campaignOfferId) {
|
|
214
|
+
markCampaignContextDirty(result.campaignOfferId, "duplicate_campaign");
|
|
215
|
+
}
|
|
216
|
+
break;
|
|
211
217
|
case "update_campaign_brief":
|
|
212
218
|
result = await updateCampaignBrief(args?.campaignId, args?.campaignBrief);
|
|
213
219
|
if (args?.campaignId) {
|
|
@@ -277,6 +283,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
277
283
|
case "list_tables":
|
|
278
284
|
result = await listTables(args);
|
|
279
285
|
break;
|
|
286
|
+
case "export_table_csv":
|
|
287
|
+
result = await exportTableCsv(args);
|
|
288
|
+
break;
|
|
280
289
|
case "commit_blueprint":
|
|
281
290
|
result = await handleCommitBlueprint(args);
|
|
282
291
|
break;
|
|
@@ -150,6 +150,42 @@ export interface UpdateCampaignInput {
|
|
|
150
150
|
rubric?: unknown[];
|
|
151
151
|
}
|
|
152
152
|
export declare const campaignToolDefinitions: ({
|
|
153
|
+
name: string;
|
|
154
|
+
description: string;
|
|
155
|
+
inputSchema: {
|
|
156
|
+
type: string;
|
|
157
|
+
properties: {
|
|
158
|
+
campaignId: {
|
|
159
|
+
type: string;
|
|
160
|
+
description: string;
|
|
161
|
+
};
|
|
162
|
+
limit?: undefined;
|
|
163
|
+
tableId?: undefined;
|
|
164
|
+
leadLimit?: undefined;
|
|
165
|
+
page?: undefined;
|
|
166
|
+
filters?: undefined;
|
|
167
|
+
name?: undefined;
|
|
168
|
+
clientProspectId?: undefined;
|
|
169
|
+
senderLinkedinUrl?: undefined;
|
|
170
|
+
offerPositioning?: undefined;
|
|
171
|
+
campaignBrief?: undefined;
|
|
172
|
+
messageGenerationMode?: undefined;
|
|
173
|
+
currentStep?: undefined;
|
|
174
|
+
watchNarration?: undefined;
|
|
175
|
+
leadSourceType?: undefined;
|
|
176
|
+
leadSourceProvider?: undefined;
|
|
177
|
+
selectedLeadListId?: undefined;
|
|
178
|
+
senderIds?: undefined;
|
|
179
|
+
interactionMode?: undefined;
|
|
180
|
+
enableICPFilters?: undefined;
|
|
181
|
+
useMessagingTemplate?: undefined;
|
|
182
|
+
rubric?: undefined;
|
|
183
|
+
flowVersion?: undefined;
|
|
184
|
+
};
|
|
185
|
+
required: string[];
|
|
186
|
+
additionalProperties: boolean;
|
|
187
|
+
};
|
|
188
|
+
} | {
|
|
153
189
|
name: string;
|
|
154
190
|
description: string;
|
|
155
191
|
inputSchema: {
|
|
@@ -600,6 +636,11 @@ export declare function startCampaign(campaignId: string): Promise<{
|
|
|
600
636
|
export declare function pauseCampaign(campaignId: string): Promise<{
|
|
601
637
|
success: boolean;
|
|
602
638
|
}>;
|
|
639
|
+
export declare function duplicateCampaign(campaignId: string): Promise<{
|
|
640
|
+
campaignOfferId: string;
|
|
641
|
+
campaignName: string;
|
|
642
|
+
workflowTableId: string | null;
|
|
643
|
+
}>;
|
|
603
644
|
export declare function updateCampaignBrief(campaignId: string, campaignBrief: string): Promise<{
|
|
604
645
|
success: boolean;
|
|
605
646
|
campaignBrief: string;
|
package/dist/tools/campaigns.js
CHANGED
|
@@ -49,8 +49,7 @@ function getCampaignBuilderWatchModeFromUrl(watchUrl) {
|
|
|
49
49
|
export function getCampaignBuilderWatchModeDriverLabel(mode = getCampaignBuilderWatchModeParam()) {
|
|
50
50
|
return mode === "codex" ? "Codex" : "Claude Code";
|
|
51
51
|
}
|
|
52
|
-
export function buildCampaignWatchHandoffMarkdown(watchUrl, mode = getCampaignBuilderWatchModeFromUrl(watchUrl) ??
|
|
53
|
-
getCampaignBuilderWatchModeParam()) {
|
|
52
|
+
export function buildCampaignWatchHandoffMarkdown(watchUrl, mode = getCampaignBuilderWatchModeFromUrl(watchUrl) ?? getCampaignBuilderWatchModeParam()) {
|
|
54
53
|
const driverLabel = getCampaignBuilderWatchModeDriverLabel(mode);
|
|
55
54
|
const headline = `WATCH ${driverLabel.toUpperCase()} BUILD THE CAMPAIGN LIVE`;
|
|
56
55
|
return [
|
|
@@ -85,6 +84,21 @@ function assertBriefHandoffWatchUrl(watchUrl, campaignId) {
|
|
|
85
84
|
"with create_campaign({ campaignId }) or get_campaign before asking for approval.");
|
|
86
85
|
}
|
|
87
86
|
export const campaignToolDefinitions = [
|
|
87
|
+
{
|
|
88
|
+
name: "duplicate_campaign",
|
|
89
|
+
description: "Duplicate a campaign by calling Sellable's existing duplicate endpoint. Returns campaignOfferId, campaignName, and workflowTableId for the new copy.",
|
|
90
|
+
inputSchema: {
|
|
91
|
+
type: "object",
|
|
92
|
+
properties: {
|
|
93
|
+
campaignId: {
|
|
94
|
+
type: "string",
|
|
95
|
+
description: "Source campaign ID to duplicate.",
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
required: ["campaignId"],
|
|
99
|
+
additionalProperties: false,
|
|
100
|
+
},
|
|
101
|
+
},
|
|
88
102
|
{
|
|
89
103
|
name: "get_campaigns",
|
|
90
104
|
description: "List campaigns for the authenticated user. Returns id, name, createdAt. Ordered by most recent first.",
|
|
@@ -845,7 +859,8 @@ export async function createCampaign(input) {
|
|
|
845
859
|
name,
|
|
846
860
|
clientProspectId,
|
|
847
861
|
offerPositioning,
|
|
848
|
-
...(shouldPersistSourceStateOnCreate &&
|
|
862
|
+
...(shouldPersistSourceStateOnCreate &&
|
|
863
|
+
input.leadSourceProvider !== undefined
|
|
849
864
|
? { leadSourceProvider: normalizedLeadSourceProvider }
|
|
850
865
|
: {}),
|
|
851
866
|
currentStep: effectiveCurrentStep,
|
|
@@ -950,6 +965,10 @@ export async function pauseCampaign(campaignId) {
|
|
|
950
965
|
const api = getApi();
|
|
951
966
|
return api.post(`/api/v3/campaigns/${campaignId}/pause`);
|
|
952
967
|
}
|
|
968
|
+
export async function duplicateCampaign(campaignId) {
|
|
969
|
+
const api = getApi();
|
|
970
|
+
return api.post(`/api/v3/campaigns/${campaignId}/duplicate`);
|
|
971
|
+
}
|
|
953
972
|
export async function updateCampaignBrief(campaignId, campaignBrief) {
|
|
954
973
|
const api = getApi();
|
|
955
974
|
return api.patch(`/api/v3/mcp/campaigns/${campaignId}`, { campaignBrief });
|