@sellable/mcp 0.1.225 → 0.1.226
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/tools/leads.js +215 -1
- package/package.json +1 -1
- package/skills/create-campaign/SKILL.md +0 -1
package/dist/tools/leads.js
CHANGED
|
@@ -63,6 +63,47 @@ const prospeoCompanySearchTokenRefs = new Map();
|
|
|
63
63
|
let prospeoCompanySearchTokenRefCounter = 0;
|
|
64
64
|
const PROSPEO_COMPANY_SEARCH_TOKEN_REF_PREFIX = "mcp-prospeo-company-search-token:";
|
|
65
65
|
const MAX_PROSPEO_COMPANY_SEARCH_TOKEN_REFS = 200;
|
|
66
|
+
const PROSPEO_LARGE_TITLE_INCLUDE_BOOLEAN_THRESHOLD = 8;
|
|
67
|
+
const prospeoCompanyKeywordIncludeAliases = new Map([
|
|
68
|
+
["ai", "artificial intelligence"],
|
|
69
|
+
["api", "application programming interface"],
|
|
70
|
+
["gtm", "go to market"],
|
|
71
|
+
["saas", "software as a service"],
|
|
72
|
+
]);
|
|
73
|
+
const prospeoCompanyIcpRegionAliases = new Map([
|
|
74
|
+
["north america", ["United States", "Canada"]],
|
|
75
|
+
["na", ["United States", "Canada"]],
|
|
76
|
+
["us", ["United States"]],
|
|
77
|
+
["usa", ["United States"]],
|
|
78
|
+
["u.s.", ["United States"]],
|
|
79
|
+
["u.s.a.", ["United States"]],
|
|
80
|
+
]);
|
|
81
|
+
const prospeoCompanyIcpDepartments = new Set([
|
|
82
|
+
"Consumers",
|
|
83
|
+
"Customer Success",
|
|
84
|
+
"Data",
|
|
85
|
+
"Design",
|
|
86
|
+
"Engineering",
|
|
87
|
+
"Finance",
|
|
88
|
+
"HR",
|
|
89
|
+
"IT",
|
|
90
|
+
"Legal",
|
|
91
|
+
"Marketing",
|
|
92
|
+
"Operations",
|
|
93
|
+
"Procurement",
|
|
94
|
+
"SMB Owners",
|
|
95
|
+
"Sales",
|
|
96
|
+
"Security",
|
|
97
|
+
]);
|
|
98
|
+
const prospeoKeyCustomerCompanionFilters = [
|
|
99
|
+
"company_attributes",
|
|
100
|
+
"company_headcount_range",
|
|
101
|
+
"company_headcount_custom",
|
|
102
|
+
"company_industry",
|
|
103
|
+
"company_keywords",
|
|
104
|
+
"company_website_search",
|
|
105
|
+
"company_icp",
|
|
106
|
+
];
|
|
66
107
|
const prospeoFilterValueSchema = {
|
|
67
108
|
type: "object",
|
|
68
109
|
description: "Include/exclude list filter (values must match Prospeo enums)",
|
|
@@ -2375,13 +2416,185 @@ function normalizeProspeoCompanySearchInputForMcp(input) {
|
|
|
2375
2416
|
!Array.isArray(lookalike) &&
|
|
2376
2417
|
"company_oids" in lookalike) {
|
|
2377
2418
|
delete lookalike.company_oids;
|
|
2419
|
+
removeEmptyObjectFilter(filters, "company_lookalike");
|
|
2378
2420
|
}
|
|
2379
2421
|
}
|
|
2422
|
+
normalizeMcpCompanyKeywords(filters);
|
|
2423
|
+
normalizeMcpCompanyIcp(filters);
|
|
2424
|
+
stripMcpDuplicateCompanyIndustry(filters);
|
|
2425
|
+
stripMcpKeyCustomerCompanionFilters(filters);
|
|
2380
2426
|
return {
|
|
2381
2427
|
...input,
|
|
2382
2428
|
filters,
|
|
2383
2429
|
};
|
|
2384
2430
|
}
|
|
2431
|
+
function normalizeProspeoSearchInputForMcp(input) {
|
|
2432
|
+
const filters = input?.filters && typeof input.filters === "object"
|
|
2433
|
+
? clonePlainObject(input.filters)
|
|
2434
|
+
: {};
|
|
2435
|
+
normalizeMcpPersonJobTitle(filters);
|
|
2436
|
+
return {
|
|
2437
|
+
...input,
|
|
2438
|
+
filters,
|
|
2439
|
+
};
|
|
2440
|
+
}
|
|
2441
|
+
function normalizeMcpCompanyKeywords(filters) {
|
|
2442
|
+
const keywords = filters.company_keywords;
|
|
2443
|
+
if (!isPlainObject(keywords)) {
|
|
2444
|
+
return;
|
|
2445
|
+
}
|
|
2446
|
+
const include = normalizeStringArray(keywords.include).map((keyword) => {
|
|
2447
|
+
const alias = prospeoCompanyKeywordIncludeAliases.get(keyword.toLowerCase());
|
|
2448
|
+
return alias ?? keyword;
|
|
2449
|
+
});
|
|
2450
|
+
const validInclude = include.filter((keyword) => keyword.length >= 3);
|
|
2451
|
+
if (validInclude.length > 0) {
|
|
2452
|
+
keywords.include = uniqueStrings(validInclude);
|
|
2453
|
+
}
|
|
2454
|
+
else {
|
|
2455
|
+
delete keywords.include;
|
|
2456
|
+
delete keywords.exclude;
|
|
2457
|
+
}
|
|
2458
|
+
if (keywords.exclude !== undefined && validInclude.length === 0) {
|
|
2459
|
+
delete keywords.exclude;
|
|
2460
|
+
}
|
|
2461
|
+
removeEmptyObjectFilter(filters, "company_keywords");
|
|
2462
|
+
}
|
|
2463
|
+
function normalizeMcpCompanyIcp(filters) {
|
|
2464
|
+
const icp = filters.company_icp;
|
|
2465
|
+
if (!isPlainObject(icp)) {
|
|
2466
|
+
return;
|
|
2467
|
+
}
|
|
2468
|
+
const scope = typeof icp.geographic_scope === "string"
|
|
2469
|
+
? icp.geographic_scope.trim()
|
|
2470
|
+
: "";
|
|
2471
|
+
const scopeMarkets = expandMcpCompanyIcpMarket(scope);
|
|
2472
|
+
if (scopeMarkets.length > 0) {
|
|
2473
|
+
icp.geographic_scope = "multi_country";
|
|
2474
|
+
icp.geographic_markets = uniqueStrings([
|
|
2475
|
+
...scopeMarkets,
|
|
2476
|
+
...normalizeMcpCompanyIcpMarkets(icp.geographic_markets),
|
|
2477
|
+
]);
|
|
2478
|
+
}
|
|
2479
|
+
else if (scope &&
|
|
2480
|
+
scope !== "single_country" &&
|
|
2481
|
+
scope !== "multi_country") {
|
|
2482
|
+
delete icp.geographic_scope;
|
|
2483
|
+
}
|
|
2484
|
+
if (icp.geographic_markets !== undefined) {
|
|
2485
|
+
icp.geographic_markets = normalizeMcpCompanyIcpMarkets(icp.geographic_markets);
|
|
2486
|
+
if (Array.isArray(icp.geographic_markets) &&
|
|
2487
|
+
icp.geographic_markets.length === 0) {
|
|
2488
|
+
delete icp.geographic_markets;
|
|
2489
|
+
}
|
|
2490
|
+
}
|
|
2491
|
+
normalizeMcpCompanyIcpDepartments(icp);
|
|
2492
|
+
removeEmptyObjectFilter(filters, "company_icp");
|
|
2493
|
+
}
|
|
2494
|
+
function normalizeMcpCompanyIcpDepartments(icp) {
|
|
2495
|
+
const departments = icp.departments;
|
|
2496
|
+
if (Array.isArray(departments)) {
|
|
2497
|
+
const valid = departments
|
|
2498
|
+
.filter((department) => typeof department === "string")
|
|
2499
|
+
.filter((department) => prospeoCompanyIcpDepartments.has(department));
|
|
2500
|
+
if (valid.length > 0) {
|
|
2501
|
+
icp.departments = uniqueStrings(valid);
|
|
2502
|
+
}
|
|
2503
|
+
else {
|
|
2504
|
+
delete icp.departments;
|
|
2505
|
+
}
|
|
2506
|
+
return;
|
|
2507
|
+
}
|
|
2508
|
+
if (!isPlainObject(departments)) {
|
|
2509
|
+
return;
|
|
2510
|
+
}
|
|
2511
|
+
const include = normalizeStringArray(departments.include).filter((department) => prospeoCompanyIcpDepartments.has(department));
|
|
2512
|
+
const exclude = normalizeStringArray(departments.exclude).filter((department) => prospeoCompanyIcpDepartments.has(department));
|
|
2513
|
+
if (include.length > 0) {
|
|
2514
|
+
departments.include = uniqueStrings(include);
|
|
2515
|
+
}
|
|
2516
|
+
else {
|
|
2517
|
+
delete departments.include;
|
|
2518
|
+
}
|
|
2519
|
+
if (exclude.length > 0) {
|
|
2520
|
+
departments.exclude = uniqueStrings(exclude);
|
|
2521
|
+
}
|
|
2522
|
+
else {
|
|
2523
|
+
delete departments.exclude;
|
|
2524
|
+
}
|
|
2525
|
+
if (departments.include === undefined && departments.exclude === undefined) {
|
|
2526
|
+
delete icp.departments;
|
|
2527
|
+
}
|
|
2528
|
+
}
|
|
2529
|
+
function normalizeMcpCompanyIcpMarkets(input) {
|
|
2530
|
+
const markets = normalizeStringArray(input);
|
|
2531
|
+
return uniqueStrings(markets.flatMap(expandMcpCompanyIcpMarket));
|
|
2532
|
+
}
|
|
2533
|
+
function expandMcpCompanyIcpMarket(market) {
|
|
2534
|
+
const trimmed = market.trim();
|
|
2535
|
+
if (!trimmed) {
|
|
2536
|
+
return [];
|
|
2537
|
+
}
|
|
2538
|
+
return prospeoCompanyIcpRegionAliases.get(trimmed.toLowerCase()) ?? [trimmed];
|
|
2539
|
+
}
|
|
2540
|
+
function stripMcpDuplicateCompanyIndustry(filters) {
|
|
2541
|
+
const icp = filters.company_icp;
|
|
2542
|
+
if (isPlainObject(icp) &&
|
|
2543
|
+
Array.isArray(icp.industries) &&
|
|
2544
|
+
icp.industries.length > 0) {
|
|
2545
|
+
delete filters.company_industry;
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
function stripMcpKeyCustomerCompanionFilters(filters) {
|
|
2549
|
+
const keyCustomers = filters.company_key_customers;
|
|
2550
|
+
if (!isPlainObject(keyCustomers)) {
|
|
2551
|
+
return;
|
|
2552
|
+
}
|
|
2553
|
+
const include = normalizeStringArray(keyCustomers.include);
|
|
2554
|
+
if (include.length === 0) {
|
|
2555
|
+
return;
|
|
2556
|
+
}
|
|
2557
|
+
for (const filterName of prospeoKeyCustomerCompanionFilters) {
|
|
2558
|
+
delete filters[filterName];
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
function normalizeMcpPersonJobTitle(filters) {
|
|
2562
|
+
const jobTitle = filters.person_job_title;
|
|
2563
|
+
if (!isPlainObject(jobTitle)) {
|
|
2564
|
+
return;
|
|
2565
|
+
}
|
|
2566
|
+
const include = normalizeStringArray(jobTitle.include);
|
|
2567
|
+
const exclude = normalizeStringArray(jobTitle.exclude);
|
|
2568
|
+
if (include.length > PROSPEO_LARGE_TITLE_INCLUDE_BOOLEAN_THRESHOLD &&
|
|
2569
|
+
exclude.length === 0 &&
|
|
2570
|
+
typeof jobTitle.boolean_search !== "string") {
|
|
2571
|
+
delete jobTitle.include;
|
|
2572
|
+
jobTitle.boolean_search = include
|
|
2573
|
+
.map((title) => `"${title.replace(/"/g, '\\"')}"`)
|
|
2574
|
+
.join(" OR ");
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
function isPlainObject(input) {
|
|
2578
|
+
return Boolean(input) && typeof input === "object" && !Array.isArray(input);
|
|
2579
|
+
}
|
|
2580
|
+
function normalizeStringArray(input) {
|
|
2581
|
+
if (!Array.isArray(input)) {
|
|
2582
|
+
return [];
|
|
2583
|
+
}
|
|
2584
|
+
return input
|
|
2585
|
+
.filter((value) => typeof value === "string")
|
|
2586
|
+
.map((value) => value.trim())
|
|
2587
|
+
.filter((value) => value.length > 0);
|
|
2588
|
+
}
|
|
2589
|
+
function uniqueStrings(input) {
|
|
2590
|
+
return Array.from(new Set(input));
|
|
2591
|
+
}
|
|
2592
|
+
function removeEmptyObjectFilter(filters, filterName) {
|
|
2593
|
+
const filter = filters[filterName];
|
|
2594
|
+
if (isPlainObject(filter) && Object.keys(filter).length === 0) {
|
|
2595
|
+
delete filters[filterName];
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2385
2598
|
function clonePlainObject(input) {
|
|
2386
2599
|
return JSON.parse(JSON.stringify(input));
|
|
2387
2600
|
}
|
|
@@ -2514,7 +2727,8 @@ export async function searchProspeo(input) {
|
|
|
2514
2727
|
nestedCompany?.names !== undefined) {
|
|
2515
2728
|
throw new Error("search_prospeo does not accept filters.company.websites or filters.company.names. For known accounts, resolve names/domains into a domainFilterId with load_csv_domains or save_domain_filters. For company/account lookalikes, use search_prospeo_companies first, then confirm_prospeo_company_accounts.");
|
|
2516
2729
|
}
|
|
2517
|
-
const
|
|
2730
|
+
const safeInput = normalizeProspeoSearchInputForMcp(input);
|
|
2731
|
+
const response = await api.post(`/api/v3/prospeo/search`, safeInput);
|
|
2518
2732
|
return compactProspeoSearchResponse(response);
|
|
2519
2733
|
}
|
|
2520
2734
|
function compactProspeoSearchResponse(response) {
|
package/package.json
CHANGED
|
@@ -219,7 +219,6 @@ Package-backed MCP may return a short `mcp-prospeo-company-search-token:*`
|
|
|
219
219
|
reference to avoid long-token copy errors. Account rows are not people leads
|
|
220
220
|
yet. The confirmation creates the `domainFilterId` that constrains the follow-on
|
|
221
221
|
`search_prospeo` people search.
|
|
222
|
-
Always copy the `companySearchToken` exactly.
|
|
223
222
|
|
|
224
223
|
Prospeo company/account search is useful when the source plan depends on
|
|
225
224
|
website traffic (`company_website_traffic`), confirmed AI Attributes including
|