@sellable/mcp 0.1.269 → 0.1.272
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/index-dev.js +0 -0
- package/dist/index.js +0 -0
- package/dist/server.js +7 -8
- package/dist/tools/content-posts.d.ts +421 -1
- package/dist/tools/content-posts.js +802 -0
- package/dist/tools/engage-discovery.d.ts +24 -0
- package/dist/tools/engage-discovery.js +114 -9
- package/dist/tools/leads.js +1 -1
- package/dist/tools/registry.d.ts +76 -47
- package/dist/tools/registry.js +0 -2
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +0 -10
- package/skills/create-campaign/core/providers/prospeo.json +2 -5
- package/skills/create-post/SKILL.md +768 -36
- package/skills/create-post/references/hook-research-playbook.md +509 -31
- package/skills/create-post/references/linkedin-preview-rendering.md +221 -0
- package/skills/create-post/references/post-file-contract.md +41 -0
- package/skills/create-post/references/post-validation.md +297 -27
- package/skills/create-post/references/premise-development.md +298 -7
- package/skills/providers/prospeo.md +0 -21
- package/skills/research/config.json +9 -0
- package/dist/tools/harvest-jobs.d.ts +0 -182
- package/dist/tools/harvest-jobs.js +0 -429
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
type FollowerBandFit = "in_target_band" | "below_target_band" | "above_target_band" | "unknown";
|
|
2
|
+
type ReachSignals = {
|
|
3
|
+
targetFollowerMin?: number;
|
|
4
|
+
targetFollowerMax?: number;
|
|
5
|
+
followerBandFit: FollowerBandFit;
|
|
6
|
+
engagementPer1kFollowers: number | null;
|
|
7
|
+
weightedEngagementPer1kFollowers: number | null;
|
|
8
|
+
reachPenaltyMultiplier: number;
|
|
9
|
+
reachAdjustedScore: number;
|
|
10
|
+
confidence: "high" | "medium" | "low";
|
|
11
|
+
};
|
|
1
12
|
export type EngagementPost = {
|
|
2
13
|
postId: string;
|
|
3
14
|
url: string;
|
|
@@ -7,6 +18,7 @@ export type EngagementPost = {
|
|
|
7
18
|
name: string;
|
|
8
19
|
headline: string;
|
|
9
20
|
profileUrl: string;
|
|
21
|
+
followerCount?: number;
|
|
10
22
|
};
|
|
11
23
|
engagement: {
|
|
12
24
|
likes: number;
|
|
@@ -14,6 +26,7 @@ export type EngagementPost = {
|
|
|
14
26
|
shares: number;
|
|
15
27
|
total: number;
|
|
16
28
|
};
|
|
29
|
+
reachSignals?: ReachSignals;
|
|
17
30
|
contentPreview: string;
|
|
18
31
|
};
|
|
19
32
|
export type SearchEngagementPostsInput = {
|
|
@@ -23,6 +36,8 @@ export type SearchEngagementPostsInput = {
|
|
|
23
36
|
minTotalEngagement?: number;
|
|
24
37
|
maxPosts?: number;
|
|
25
38
|
excludePostUrls?: string[];
|
|
39
|
+
targetFollowerMin?: number;
|
|
40
|
+
targetFollowerMax?: number;
|
|
26
41
|
};
|
|
27
42
|
export type SearchEngagementPostsResponse = {
|
|
28
43
|
success: boolean;
|
|
@@ -70,9 +85,18 @@ export declare const engageDiscoveryToolDefinitions: {
|
|
|
70
85
|
};
|
|
71
86
|
description: string;
|
|
72
87
|
};
|
|
88
|
+
targetFollowerMin: {
|
|
89
|
+
type: string;
|
|
90
|
+
description: string;
|
|
91
|
+
};
|
|
92
|
+
targetFollowerMax: {
|
|
93
|
+
type: string;
|
|
94
|
+
description: string;
|
|
95
|
+
};
|
|
73
96
|
};
|
|
74
97
|
required: string[];
|
|
75
98
|
additionalProperties: boolean;
|
|
76
99
|
};
|
|
77
100
|
}[];
|
|
78
101
|
export declare function searchEngagementPosts(input: SearchEngagementPostsInput): Promise<SearchEngagementPostsResponse>;
|
|
102
|
+
export {};
|
|
@@ -32,6 +32,14 @@ export const engageDiscoveryToolDefinitions = [
|
|
|
32
32
|
items: { type: "string" },
|
|
33
33
|
description: "Optional list of post URLs to exclude (e.g. already engaged/scheduled).",
|
|
34
34
|
},
|
|
35
|
+
targetFollowerMin: {
|
|
36
|
+
type: "number",
|
|
37
|
+
description: "Optional lower bound for creator follower count when reach-normalizing hook/source quality.",
|
|
38
|
+
},
|
|
39
|
+
targetFollowerMax: {
|
|
40
|
+
type: "number",
|
|
41
|
+
description: "Optional upper bound for creator follower count when reach-normalizing hook/source quality.",
|
|
42
|
+
},
|
|
35
43
|
},
|
|
36
44
|
required: ["keywords"],
|
|
37
45
|
additionalProperties: false,
|
|
@@ -63,6 +71,79 @@ function safeNumber(value) {
|
|
|
63
71
|
const n = typeof value === "number" ? value : Number(value);
|
|
64
72
|
return Number.isFinite(n) ? n : 0;
|
|
65
73
|
}
|
|
74
|
+
function round3(value) {
|
|
75
|
+
return Number(value.toFixed(3));
|
|
76
|
+
}
|
|
77
|
+
function parseFollowerCount(author) {
|
|
78
|
+
const direct = safeNumber(author?.followerCount);
|
|
79
|
+
if (direct > 0)
|
|
80
|
+
return direct;
|
|
81
|
+
const text = String(author?.followers || author?.followerCountText || "");
|
|
82
|
+
const match = text.match(/([\d,.]+)\s*([kKmM])?/);
|
|
83
|
+
if (!match)
|
|
84
|
+
return undefined;
|
|
85
|
+
const base = Number(match[1].replace(/,/g, ""));
|
|
86
|
+
if (!Number.isFinite(base) || base <= 0)
|
|
87
|
+
return undefined;
|
|
88
|
+
const suffix = match[2]?.toLowerCase();
|
|
89
|
+
if (suffix === "m")
|
|
90
|
+
return Math.round(base * 1_000_000);
|
|
91
|
+
if (suffix === "k")
|
|
92
|
+
return Math.round(base * 1_000);
|
|
93
|
+
return Math.round(base);
|
|
94
|
+
}
|
|
95
|
+
function reachPenaltyMultiplier(followerCount, targetFollowerMin, targetFollowerMax) {
|
|
96
|
+
if (!followerCount || !targetFollowerMin || !targetFollowerMax)
|
|
97
|
+
return 0.4;
|
|
98
|
+
if (followerCount >= targetFollowerMin && followerCount <= targetFollowerMax) {
|
|
99
|
+
return 1;
|
|
100
|
+
}
|
|
101
|
+
if (followerCount < targetFollowerMin)
|
|
102
|
+
return 0.75;
|
|
103
|
+
if (followerCount <= targetFollowerMax * 2)
|
|
104
|
+
return 0.65;
|
|
105
|
+
if (followerCount <= targetFollowerMax * 5)
|
|
106
|
+
return 0.35;
|
|
107
|
+
return 0.15;
|
|
108
|
+
}
|
|
109
|
+
function followerBandFit(followerCount, targetFollowerMin, targetFollowerMax) {
|
|
110
|
+
if (!followerCount || !targetFollowerMin || !targetFollowerMax) {
|
|
111
|
+
return "unknown";
|
|
112
|
+
}
|
|
113
|
+
if (followerCount >= targetFollowerMin && followerCount <= targetFollowerMax) {
|
|
114
|
+
return "in_target_band";
|
|
115
|
+
}
|
|
116
|
+
if (followerCount < targetFollowerMin)
|
|
117
|
+
return "below_target_band";
|
|
118
|
+
return "above_target_band";
|
|
119
|
+
}
|
|
120
|
+
function buildReachSignals(params) {
|
|
121
|
+
const { followerCount, likes, comments, shares, total } = params;
|
|
122
|
+
const hasTarget = Boolean(params.targetFollowerMin && params.targetFollowerMax);
|
|
123
|
+
if (!hasTarget && !followerCount)
|
|
124
|
+
return undefined;
|
|
125
|
+
const weightedEngagement = likes + comments * 4 + shares * 12;
|
|
126
|
+
const penalty = reachPenaltyMultiplier(followerCount, params.targetFollowerMin, params.targetFollowerMax);
|
|
127
|
+
const engagementPer1kFollowers = followerCount
|
|
128
|
+
? round3((total / followerCount) * 1000)
|
|
129
|
+
: null;
|
|
130
|
+
const weightedEngagementPer1kFollowers = followerCount
|
|
131
|
+
? round3((weightedEngagement / followerCount) * 1000)
|
|
132
|
+
: null;
|
|
133
|
+
const reachAdjustedScore = weightedEngagementPer1kFollowers === null
|
|
134
|
+
? 0
|
|
135
|
+
: round3(weightedEngagementPer1kFollowers * penalty);
|
|
136
|
+
return {
|
|
137
|
+
targetFollowerMin: params.targetFollowerMin,
|
|
138
|
+
targetFollowerMax: params.targetFollowerMax,
|
|
139
|
+
followerBandFit: followerBandFit(followerCount, params.targetFollowerMin, params.targetFollowerMax),
|
|
140
|
+
engagementPer1kFollowers,
|
|
141
|
+
weightedEngagementPer1kFollowers,
|
|
142
|
+
reachPenaltyMultiplier: penalty,
|
|
143
|
+
reachAdjustedScore,
|
|
144
|
+
confidence: followerCount ? (hasTarget ? "high" : "medium") : "low",
|
|
145
|
+
};
|
|
146
|
+
}
|
|
66
147
|
export async function searchEngagementPosts(input) {
|
|
67
148
|
const api = getApi();
|
|
68
149
|
const keywords = (input.keywords || [])
|
|
@@ -79,6 +160,12 @@ export async function searchEngagementPosts(input) {
|
|
|
79
160
|
const maxPosts = typeof input.maxPosts === "number" && input.maxPosts > 0
|
|
80
161
|
? Math.min(50, input.maxPosts)
|
|
81
162
|
: 25;
|
|
163
|
+
const targetFollowerMin = typeof input.targetFollowerMin === "number" && input.targetFollowerMin > 0
|
|
164
|
+
? input.targetFollowerMin
|
|
165
|
+
: undefined;
|
|
166
|
+
const targetFollowerMax = typeof input.targetFollowerMax === "number" && input.targetFollowerMax > 0
|
|
167
|
+
? input.targetFollowerMax
|
|
168
|
+
: undefined;
|
|
82
169
|
const exclude = new Set((input.excludePostUrls || [])
|
|
83
170
|
.map((u) => normalizePostUrl(u))
|
|
84
171
|
.filter(Boolean));
|
|
@@ -87,10 +174,10 @@ export async function searchEngagementPosts(input) {
|
|
|
87
174
|
keywords: keywords.map((keyword) => ({ keyword })),
|
|
88
175
|
page,
|
|
89
176
|
});
|
|
90
|
-
const rawPosts = Array.isArray(response?.
|
|
91
|
-
? response.
|
|
92
|
-
: Array.isArray(response?.
|
|
93
|
-
? response.
|
|
177
|
+
const rawPosts = Array.isArray(response?.posts)
|
|
178
|
+
? response.posts
|
|
179
|
+
: Array.isArray(response?.topPostsForLLM)
|
|
180
|
+
? response.topPostsForLLM
|
|
94
181
|
: [];
|
|
95
182
|
const now = Date.now();
|
|
96
183
|
const oldestMs = now - maxAgeDays * 24 * 60 * 60 * 1000;
|
|
@@ -121,6 +208,16 @@ export async function searchEngagementPosts(input) {
|
|
|
121
208
|
tooOld += 1;
|
|
122
209
|
continue;
|
|
123
210
|
}
|
|
211
|
+
const followerCount = parseFollowerCount(p?.author);
|
|
212
|
+
const reachSignals = buildReachSignals({
|
|
213
|
+
followerCount,
|
|
214
|
+
likes,
|
|
215
|
+
comments,
|
|
216
|
+
shares,
|
|
217
|
+
total,
|
|
218
|
+
targetFollowerMin,
|
|
219
|
+
targetFollowerMax,
|
|
220
|
+
});
|
|
124
221
|
kept.push({
|
|
125
222
|
postId: String(p?.id || ""),
|
|
126
223
|
url,
|
|
@@ -132,18 +229,26 @@ export async function searchEngagementPosts(input) {
|
|
|
132
229
|
name: String(p?.author?.name || ""),
|
|
133
230
|
headline: String(p?.author?.headline || ""),
|
|
134
231
|
profileUrl: String(p?.author?.profileUrl || ""),
|
|
232
|
+
...(followerCount ? { followerCount } : {}),
|
|
135
233
|
},
|
|
136
234
|
engagement: { likes, comments, shares, total },
|
|
235
|
+
...(reachSignals ? { reachSignals } : {}),
|
|
137
236
|
contentPreview: previewText(String(p?.content || ""), 220),
|
|
138
237
|
});
|
|
139
|
-
if (kept.length >= maxPosts)
|
|
140
|
-
break;
|
|
141
238
|
}
|
|
142
|
-
|
|
143
|
-
kept.sort((a, b) =>
|
|
239
|
+
const hasReachTarget = Boolean(targetFollowerMin && targetFollowerMax);
|
|
240
|
+
kept.sort((a, b) => {
|
|
241
|
+
if (hasReachTarget) {
|
|
242
|
+
const reachDelta = (b.reachSignals?.reachAdjustedScore || 0) -
|
|
243
|
+
(a.reachSignals?.reachAdjustedScore || 0);
|
|
244
|
+
if (reachDelta !== 0)
|
|
245
|
+
return reachDelta;
|
|
246
|
+
}
|
|
247
|
+
return b.engagement.total - a.engagement.total;
|
|
248
|
+
});
|
|
144
249
|
return {
|
|
145
250
|
success: true,
|
|
146
|
-
posts: kept,
|
|
251
|
+
posts: kept.slice(0, maxPosts),
|
|
147
252
|
totalReturned: rawPosts.length,
|
|
148
253
|
filteredOut: { tooOld, excluded, tooLowEngagement },
|
|
149
254
|
};
|
package/dist/tools/leads.js
CHANGED
|
@@ -1813,7 +1813,7 @@ export const leadToolDefinitions = [
|
|
|
1813
1813
|
},
|
|
1814
1814
|
{
|
|
1815
1815
|
name: "search_prospeo",
|
|
1816
|
-
description: 'Search Prospeo for people using filters and optional domainFilterId. Requires get_provider_prompt({ provider: "prospeo" }) first. Use Prospeo first for hiring-led targeting because it supports company_job_posting_hiring_for and company_job_posting_quantity; Sales Nav does not filter companies by hiring role. When targeting known accounts, call load_csv_domains for CSV-on-disk workflows or save_domain_filters for pasted/raw domain lists, then pass domainFilterId. For
|
|
1816
|
+
description: 'Search Prospeo for people using filters and optional domainFilterId. Requires get_provider_prompt({ provider: "prospeo" }) first. Use Prospeo first for hiring-led targeting because it supports company_job_posting_hiring_for and company_job_posting_quantity; Sales Nav does not filter companies by hiring role. When targeting known accounts, call load_csv_domains for CSV-on-disk workflows or save_domain_filters for pasted/raw domain lists, then pass domainFilterId. For company lookalike/account asks, call search_prospeo_companies first, review accounts, then confirm_prospeo_company_accounts to create a domainFilterId before using search_prospeo for people. Raw domain inputs and company-name targeting are NOT supported in this MCP tool. Strategy: start with 2-3 high-signal filters (title/seniority + industry or domainFilterId + headcount), add job-posting filters for hiring-led campaigns, then tighten one filter at a time. For security, AppSec, SOC, RevOps, Demand Gen, and similar function-specific lanes, do not widen with bare seniority labels like "Head" or "Director" alone; pair them with explicit function-title keywords and inspect the sample for off-function `Head of X` leakage. If output includes warnings/fallback, report that the MCP retried a rejected precise title request with a safer domain-filter people search instead of claiming the original precise filter succeeded. Prefer person location over company HQ unless HQ is explicitly needed. `campaignOfferId` routing rule: OMIT campaignOfferId ONLY in pre-mint Phase 84 `find leads` discovery mode (validating ICP before the commit gate). In every other context — post-mint lead additions, operator-driven searches on a live campaign, any search where the intent is to persist results to a specific campaign — you MUST pass campaignOfferId so the search shows up in that campaign\'s Contact Search panel. Post-mint create-campaign-v2 watch runs MUST pass currentStep: "prospeo". Omitting campaignOfferId post-mint orphans the search from the UI. Returns normalized results with pagination.',
|
|
1817
1817
|
inputSchema: {
|
|
1818
1818
|
type: "object",
|
|
1819
1819
|
properties: {
|
package/dist/tools/registry.d.ts
CHANGED
|
@@ -1260,6 +1260,19 @@ export declare const allTools: ({
|
|
|
1260
1260
|
body?: undefined;
|
|
1261
1261
|
validationReceipt?: undefined;
|
|
1262
1262
|
status?: undefined;
|
|
1263
|
+
postText?: undefined;
|
|
1264
|
+
sourceLabel?: undefined;
|
|
1265
|
+
measurementMode?: undefined;
|
|
1266
|
+
requireBrowserMeasurement?: undefined;
|
|
1267
|
+
clampLines?: undefined;
|
|
1268
|
+
mobileClampLines?: undefined;
|
|
1269
|
+
desktopClampLines?: undefined;
|
|
1270
|
+
mobileTextWidthPx?: undefined;
|
|
1271
|
+
desktopTextWidthPx?: undefined;
|
|
1272
|
+
renderId?: undefined;
|
|
1273
|
+
renderScreenshots?: undefined;
|
|
1274
|
+
requireScreenshots?: undefined;
|
|
1275
|
+
reviewClampLines?: undefined;
|
|
1263
1276
|
updatedAt?: undefined;
|
|
1264
1277
|
publishUrl?: undefined;
|
|
1265
1278
|
activityId?: undefined;
|
|
@@ -1295,6 +1308,7 @@ export declare const allTools: ({
|
|
|
1295
1308
|
properties: {
|
|
1296
1309
|
draftId: {
|
|
1297
1310
|
type: string;
|
|
1311
|
+
description?: undefined;
|
|
1298
1312
|
};
|
|
1299
1313
|
ideaId: {
|
|
1300
1314
|
type: string;
|
|
@@ -1339,6 +1353,19 @@ export declare const allTools: ({
|
|
|
1339
1353
|
selectedPatterns?: undefined;
|
|
1340
1354
|
previewBudget?: undefined;
|
|
1341
1355
|
notes?: undefined;
|
|
1356
|
+
postText?: undefined;
|
|
1357
|
+
sourceLabel?: undefined;
|
|
1358
|
+
measurementMode?: undefined;
|
|
1359
|
+
requireBrowserMeasurement?: undefined;
|
|
1360
|
+
clampLines?: undefined;
|
|
1361
|
+
mobileClampLines?: undefined;
|
|
1362
|
+
desktopClampLines?: undefined;
|
|
1363
|
+
mobileTextWidthPx?: undefined;
|
|
1364
|
+
desktopTextWidthPx?: undefined;
|
|
1365
|
+
renderId?: undefined;
|
|
1366
|
+
renderScreenshots?: undefined;
|
|
1367
|
+
requireScreenshots?: undefined;
|
|
1368
|
+
reviewClampLines?: undefined;
|
|
1342
1369
|
updatedAt?: undefined;
|
|
1343
1370
|
publishUrl?: undefined;
|
|
1344
1371
|
activityId?: undefined;
|
|
@@ -1361,6 +1388,7 @@ export declare const allTools: ({
|
|
|
1361
1388
|
properties: {
|
|
1362
1389
|
draftId: {
|
|
1363
1390
|
type: string;
|
|
1391
|
+
description?: undefined;
|
|
1364
1392
|
};
|
|
1365
1393
|
hookResearchId: {
|
|
1366
1394
|
type: string;
|
|
@@ -1403,6 +1431,19 @@ export declare const allTools: ({
|
|
|
1403
1431
|
previewBudget?: undefined;
|
|
1404
1432
|
notes?: undefined;
|
|
1405
1433
|
createdAt?: undefined;
|
|
1434
|
+
postText?: undefined;
|
|
1435
|
+
sourceLabel?: undefined;
|
|
1436
|
+
measurementMode?: undefined;
|
|
1437
|
+
requireBrowserMeasurement?: undefined;
|
|
1438
|
+
clampLines?: undefined;
|
|
1439
|
+
mobileClampLines?: undefined;
|
|
1440
|
+
desktopClampLines?: undefined;
|
|
1441
|
+
mobileTextWidthPx?: undefined;
|
|
1442
|
+
desktopTextWidthPx?: undefined;
|
|
1443
|
+
renderId?: undefined;
|
|
1444
|
+
renderScreenshots?: undefined;
|
|
1445
|
+
requireScreenshots?: undefined;
|
|
1446
|
+
reviewClampLines?: undefined;
|
|
1406
1447
|
publishUrl?: undefined;
|
|
1407
1448
|
activityId?: undefined;
|
|
1408
1449
|
publishedAt?: undefined;
|
|
@@ -1424,6 +1465,7 @@ export declare const allTools: ({
|
|
|
1424
1465
|
properties: {
|
|
1425
1466
|
draftId: {
|
|
1426
1467
|
type: string;
|
|
1468
|
+
description?: undefined;
|
|
1427
1469
|
};
|
|
1428
1470
|
publishUrl: {
|
|
1429
1471
|
type: string;
|
|
@@ -1464,6 +1506,19 @@ export declare const allTools: ({
|
|
|
1464
1506
|
body?: undefined;
|
|
1465
1507
|
validationReceipt?: undefined;
|
|
1466
1508
|
status?: undefined;
|
|
1509
|
+
postText?: undefined;
|
|
1510
|
+
sourceLabel?: undefined;
|
|
1511
|
+
measurementMode?: undefined;
|
|
1512
|
+
requireBrowserMeasurement?: undefined;
|
|
1513
|
+
clampLines?: undefined;
|
|
1514
|
+
mobileClampLines?: undefined;
|
|
1515
|
+
desktopClampLines?: undefined;
|
|
1516
|
+
mobileTextWidthPx?: undefined;
|
|
1517
|
+
desktopTextWidthPx?: undefined;
|
|
1518
|
+
renderId?: undefined;
|
|
1519
|
+
renderScreenshots?: undefined;
|
|
1520
|
+
requireScreenshots?: undefined;
|
|
1521
|
+
reviewClampLines?: undefined;
|
|
1467
1522
|
updatedAt?: undefined;
|
|
1468
1523
|
publishedPostId?: undefined;
|
|
1469
1524
|
year?: undefined;
|
|
@@ -1516,6 +1571,19 @@ export declare const allTools: ({
|
|
|
1516
1571
|
body?: undefined;
|
|
1517
1572
|
validationReceipt?: undefined;
|
|
1518
1573
|
status?: undefined;
|
|
1574
|
+
postText?: undefined;
|
|
1575
|
+
sourceLabel?: undefined;
|
|
1576
|
+
measurementMode?: undefined;
|
|
1577
|
+
requireBrowserMeasurement?: undefined;
|
|
1578
|
+
clampLines?: undefined;
|
|
1579
|
+
mobileClampLines?: undefined;
|
|
1580
|
+
desktopClampLines?: undefined;
|
|
1581
|
+
mobileTextWidthPx?: undefined;
|
|
1582
|
+
desktopTextWidthPx?: undefined;
|
|
1583
|
+
renderId?: undefined;
|
|
1584
|
+
renderScreenshots?: undefined;
|
|
1585
|
+
requireScreenshots?: undefined;
|
|
1586
|
+
reviewClampLines?: undefined;
|
|
1519
1587
|
updatedAt?: undefined;
|
|
1520
1588
|
publishUrl?: undefined;
|
|
1521
1589
|
activityId?: undefined;
|
|
@@ -1749,6 +1817,14 @@ export declare const allTools: ({
|
|
|
1749
1817
|
};
|
|
1750
1818
|
description: string;
|
|
1751
1819
|
};
|
|
1820
|
+
targetFollowerMin: {
|
|
1821
|
+
type: string;
|
|
1822
|
+
description: string;
|
|
1823
|
+
};
|
|
1824
|
+
targetFollowerMax: {
|
|
1825
|
+
type: string;
|
|
1826
|
+
description: string;
|
|
1827
|
+
};
|
|
1752
1828
|
};
|
|
1753
1829
|
required: string[];
|
|
1754
1830
|
additionalProperties: boolean;
|
|
@@ -1880,53 +1956,6 @@ export declare const allTools: ({
|
|
|
1880
1956
|
};
|
|
1881
1957
|
required: never[];
|
|
1882
1958
|
};
|
|
1883
|
-
} | {
|
|
1884
|
-
name: string;
|
|
1885
|
-
description: string;
|
|
1886
|
-
inputSchema: {
|
|
1887
|
-
type: string;
|
|
1888
|
-
properties: {
|
|
1889
|
-
searchToken: {
|
|
1890
|
-
type: string;
|
|
1891
|
-
description: string;
|
|
1892
|
-
};
|
|
1893
|
-
selectedJobIds: {
|
|
1894
|
-
type: string;
|
|
1895
|
-
items: {
|
|
1896
|
-
type: string;
|
|
1897
|
-
};
|
|
1898
|
-
description: string;
|
|
1899
|
-
};
|
|
1900
|
-
name: {
|
|
1901
|
-
type: string;
|
|
1902
|
-
};
|
|
1903
|
-
outputDir: {
|
|
1904
|
-
type: string;
|
|
1905
|
-
description: string;
|
|
1906
|
-
};
|
|
1907
|
-
fileBaseName: {
|
|
1908
|
-
type: string;
|
|
1909
|
-
description: string;
|
|
1910
|
-
};
|
|
1911
|
-
search?: undefined;
|
|
1912
|
-
searches?: undefined;
|
|
1913
|
-
location?: undefined;
|
|
1914
|
-
geoId?: undefined;
|
|
1915
|
-
postedLimit?: undefined;
|
|
1916
|
-
sortBy?: undefined;
|
|
1917
|
-
workplaceType?: undefined;
|
|
1918
|
-
employmentType?: undefined;
|
|
1919
|
-
experienceLevel?: undefined;
|
|
1920
|
-
easyApply?: undefined;
|
|
1921
|
-
under10Applicants?: undefined;
|
|
1922
|
-
salary?: undefined;
|
|
1923
|
-
pages?: undefined;
|
|
1924
|
-
maxRows?: undefined;
|
|
1925
|
-
artifactFormat?: undefined;
|
|
1926
|
-
};
|
|
1927
|
-
required: string[];
|
|
1928
|
-
additionalProperties: boolean;
|
|
1929
|
-
};
|
|
1930
1959
|
} | {
|
|
1931
1960
|
name: string;
|
|
1932
1961
|
description: string;
|
package/dist/tools/registry.js
CHANGED
|
@@ -14,7 +14,6 @@ import { engageMemoryToolDefinitions } from "./engage-memory.js";
|
|
|
14
14
|
import { engageStateToolDefinitions } from "./engage-state.js";
|
|
15
15
|
import { enrichmentToolDefinitions } from "./enrichment.js";
|
|
16
16
|
import { frameworkToolDefinitions } from "./framework.js";
|
|
17
|
-
import { harvestJobToolDefinitions } from "./harvest-jobs.js";
|
|
18
17
|
import { leadToolDefinitions } from "./leads.js";
|
|
19
18
|
import { linkedinToolDefinitions } from "./linkedin.js";
|
|
20
19
|
import { navigationToolDefinitions } from "./navigation.js";
|
|
@@ -44,7 +43,6 @@ export const allTools = [
|
|
|
44
43
|
...contentPostToolDefinitions,
|
|
45
44
|
...navigationToolDefinitions,
|
|
46
45
|
...leadToolDefinitions,
|
|
47
|
-
...harvestJobToolDefinitions,
|
|
48
46
|
...enrichmentToolDefinitions,
|
|
49
47
|
...processingToolDefinitions,
|
|
50
48
|
...rubricToolDefinitions,
|
package/package.json
CHANGED
|
@@ -29,8 +29,6 @@ allowed-tools:
|
|
|
29
29
|
- mcp__sellable__search_prospeo
|
|
30
30
|
- mcp__sellable__search_prospeo_companies
|
|
31
31
|
- mcp__sellable__confirm_prospeo_company_accounts
|
|
32
|
-
- mcp__sellable__search_harvest_jobs
|
|
33
|
-
- mcp__sellable__confirm_harvest_job_companies
|
|
34
32
|
- mcp__sellable__search_signals
|
|
35
33
|
- mcp__sellable__fetch_post_engagers
|
|
36
34
|
- mcp__sellable__enrich_with_prospeo
|
|
@@ -229,14 +227,6 @@ are likely. Sales Nav is useful for recent LinkedIn activity, role/title
|
|
|
229
227
|
precision, and referral paths, but it does not provide hiring-by-role filters;
|
|
230
228
|
say that distinction plainly in the source-plan gate.
|
|
231
229
|
|
|
232
|
-
When the brief asks for current LinkedIn job-post intent, such as companies
|
|
233
|
-
hiring Power BI developers this month, use Harvest jobs as the account source:
|
|
234
|
-
`search_harvest_jobs -> confirm_harvest_job_companies -> search_prospeo`.
|
|
235
|
-
First write and review the Harvest job artifact. Then confirm selected Harvest
|
|
236
|
-
job IDs into a `domainFilterId`; Prospeo remains the people-search provider.
|
|
237
|
-
Do not paste LinkedIn company URLs as domains. Do not fetch full job details for
|
|
238
|
-
every search row by default; selected batches only.
|
|
239
|
-
|
|
240
230
|
For company lookalikes, best-customer lookalikes, "companies like X",
|
|
241
231
|
lookalike accounts, companies that use AI, companies with API/SSO/Chrome
|
|
242
232
|
extension, news/award/integration/key-customer filters, or account discovery
|
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
"requiredTools": [
|
|
8
8
|
"update_campaign",
|
|
9
9
|
"get_provider_prompt",
|
|
10
|
-
"search_harvest_jobs",
|
|
11
|
-
"confirm_harvest_job_companies",
|
|
12
10
|
"search_prospeo_companies",
|
|
13
11
|
"confirm_prospeo_company_accounts",
|
|
14
12
|
"search_prospeo",
|
|
@@ -26,14 +24,13 @@
|
|
|
26
24
|
"useWhen": [
|
|
27
25
|
"You want Prospeo filters or domain-based search",
|
|
28
26
|
"You need company lookalike account discovery before finding people",
|
|
29
|
-
"You need current LinkedIn job-post evidence before finding hiring stakeholders",
|
|
30
27
|
"You want companies like X, target-domain, best-customer/top-customer, or job-search employer lookalikes, or accounts using AI/API/SSO/Chrome extensions",
|
|
31
28
|
"You need companies hiring for specific roles using job-posting filters",
|
|
32
29
|
"You need high deliverability from Prospeo"
|
|
33
30
|
],
|
|
34
31
|
"avoidWhen": ["You need LinkedIn activity filters"],
|
|
35
|
-
"reason": "Strong for hiring-led search,
|
|
36
|
-
"prose": "Since you're targeting **{icp}**, I'd recommend **Prospeo**.\n\nHere's why:\n- Prospeo can discover lookalike accounts first, then turn approved accounts into a domainFilterId for people search\n-
|
|
32
|
+
"reason": "Strong for hiring-led search, company/account lookalikes, Prospeo-specific filters, verified contacts, and domain lists.",
|
|
33
|
+
"prose": "Since you're targeting **{icp}**, I'd recommend **Prospeo**.\n\nHere's why:\n- Prospeo can discover lookalike accounts first, then turn approved accounts into a domainFilterId for people search\n- Prospeo can filter for companies hiring specific roles with job-posting filters\n- We can pair those company signals with buyer/referrer titles and verified-contact coverage\n\nFor lookalike accounts, I will show an account sample first; those account rows are not people leads yet. After approval, I will use the companySearchToken to confirm the accounts, then search people at the returned domainFilterId. For outbound lookalikes, I will use target/account/customer domains or verified past-customer accounts, not the sender's company. For job-search/application lookalikes, I can use current or past employers as existing-company seeds.\n\nShould I search Prospeo for {icp}?"
|
|
37
34
|
},
|
|
38
35
|
"askOption": {
|
|
39
36
|
"label": "Prospeo",
|