@sellable/mcp 0.1.226 → 0.1.227
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
CHANGED
|
@@ -2404,11 +2404,12 @@ function removeUndefinedValues(input) {
|
|
|
2404
2404
|
return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== undefined));
|
|
2405
2405
|
}
|
|
2406
2406
|
function normalizeProspeoCompanySearchInputForMcp(input) {
|
|
2407
|
+
const seedCompanies = normalizeMcpSeeds(input.seedCompanies, "company");
|
|
2408
|
+
const seedDomains = normalizeMcpSeeds(input.seedDomains, "domain");
|
|
2407
2409
|
const filters = input?.filters && typeof input.filters === "object"
|
|
2408
2410
|
? clonePlainObject(input.filters)
|
|
2409
2411
|
: {};
|
|
2410
|
-
const hasSeeds =
|
|
2411
|
-
(input.seedDomains?.length ?? 0) > 0;
|
|
2412
|
+
const hasSeeds = seedCompanies.length > 0 || seedDomains.length > 0;
|
|
2412
2413
|
if (hasSeeds) {
|
|
2413
2414
|
const lookalike = filters.company_lookalike;
|
|
2414
2415
|
if (lookalike &&
|
|
@@ -2420,11 +2421,15 @@ function normalizeProspeoCompanySearchInputForMcp(input) {
|
|
|
2420
2421
|
}
|
|
2421
2422
|
}
|
|
2422
2423
|
normalizeMcpCompanyKeywords(filters);
|
|
2424
|
+
normalizeMcpCompanyWebsiteSearch(filters);
|
|
2423
2425
|
normalizeMcpCompanyIcp(filters);
|
|
2424
2426
|
stripMcpDuplicateCompanyIndustry(filters);
|
|
2427
|
+
stripMcpSeededLookalikeRiskyRefinements(filters, hasSeeds);
|
|
2425
2428
|
stripMcpKeyCustomerCompanionFilters(filters);
|
|
2426
2429
|
return {
|
|
2427
2430
|
...input,
|
|
2431
|
+
seedCompanies: seedCompanies.length > 0 ? seedCompanies : undefined,
|
|
2432
|
+
seedDomains: seedDomains.length > 0 ? seedDomains : undefined,
|
|
2428
2433
|
filters,
|
|
2429
2434
|
};
|
|
2430
2435
|
}
|
|
@@ -2460,6 +2465,21 @@ function normalizeMcpCompanyKeywords(filters) {
|
|
|
2460
2465
|
}
|
|
2461
2466
|
removeEmptyObjectFilter(filters, "company_keywords");
|
|
2462
2467
|
}
|
|
2468
|
+
function normalizeMcpCompanyWebsiteSearch(filters) {
|
|
2469
|
+
const websiteSearch = filters.company_website_search;
|
|
2470
|
+
if (!isPlainObject(websiteSearch)) {
|
|
2471
|
+
return;
|
|
2472
|
+
}
|
|
2473
|
+
const includeKeywords = normalizeStringArray(websiteSearch.include_keywords);
|
|
2474
|
+
const hasPositiveWebsiteSignal = includeKeywords.length > 0 ||
|
|
2475
|
+
normalizeStringArray(websiteSearch.url_contains).length > 0 ||
|
|
2476
|
+
normalizeStringArray(websiteSearch.urls).length > 0 ||
|
|
2477
|
+
Object.entries(websiteSearch).some(([key, value]) => key.startsWith("has_") && typeof value === "boolean" && value);
|
|
2478
|
+
if (!hasPositiveWebsiteSignal) {
|
|
2479
|
+
delete websiteSearch.exclude_keywords;
|
|
2480
|
+
}
|
|
2481
|
+
removeEmptyObjectFilter(filters, "company_website_search");
|
|
2482
|
+
}
|
|
2463
2483
|
function normalizeMcpCompanyIcp(filters) {
|
|
2464
2484
|
const icp = filters.company_icp;
|
|
2465
2485
|
if (!isPlainObject(icp)) {
|
|
@@ -2545,6 +2565,21 @@ function stripMcpDuplicateCompanyIndustry(filters) {
|
|
|
2545
2565
|
delete filters.company_industry;
|
|
2546
2566
|
}
|
|
2547
2567
|
}
|
|
2568
|
+
function stripMcpSeededLookalikeRiskyRefinements(filters, hasSeeds) {
|
|
2569
|
+
if (!hasSeeds || !isPlainObject(filters.company_lookalike)) {
|
|
2570
|
+
return;
|
|
2571
|
+
}
|
|
2572
|
+
const icp = filters.company_icp;
|
|
2573
|
+
if (isPlainObject(icp) &&
|
|
2574
|
+
Array.isArray(icp.industries) &&
|
|
2575
|
+
icp.industries.length > 0 &&
|
|
2576
|
+
!filters.company_industry) {
|
|
2577
|
+
filters.company_industry = { include: icp.industries };
|
|
2578
|
+
}
|
|
2579
|
+
delete filters.company_icp;
|
|
2580
|
+
delete filters.company_keywords;
|
|
2581
|
+
delete filters.company_website_search;
|
|
2582
|
+
}
|
|
2548
2583
|
function stripMcpKeyCustomerCompanionFilters(filters) {
|
|
2549
2584
|
const keyCustomers = filters.company_key_customers;
|
|
2550
2585
|
if (!isPlainObject(keyCustomers)) {
|
|
@@ -2586,6 +2621,20 @@ function normalizeStringArray(input) {
|
|
|
2586
2621
|
.map((value) => value.trim())
|
|
2587
2622
|
.filter((value) => value.length > 0);
|
|
2588
2623
|
}
|
|
2624
|
+
function normalizeMcpSeeds(input, kind) {
|
|
2625
|
+
return uniqueStrings(normalizeStringArray(input).filter((seed) => kind === "domain" ? isLikelyConcreteDomain(seed) : isLikelyConcreteSeedCompany(seed)));
|
|
2626
|
+
}
|
|
2627
|
+
function isLikelyConcreteDomain(input) {
|
|
2628
|
+
return /^[a-z0-9.-]+\.[a-z]{2,}$/i.test(input);
|
|
2629
|
+
}
|
|
2630
|
+
function isLikelyConcreteSeedCompany(input) {
|
|
2631
|
+
const normalized = input.toLowerCase();
|
|
2632
|
+
return !(normalized.includes("placeholder") ||
|
|
2633
|
+
normalized.includes("another approved") ||
|
|
2634
|
+
normalized.includes("approved seed") ||
|
|
2635
|
+
normalized.includes("best-customer seed") ||
|
|
2636
|
+
normalized.includes("example seed"));
|
|
2637
|
+
}
|
|
2589
2638
|
function uniqueStrings(input) {
|
|
2590
2639
|
return Array.from(new Set(input));
|
|
2591
2640
|
}
|
package/package.json
CHANGED
|
@@ -252,6 +252,12 @@ without an include keyword, and do not duplicate `company_industry` when
|
|
|
252
252
|
search, prefer `person_job_title.boolean_search` for long role synonym lists
|
|
253
253
|
instead of many `person_job_title.include` values plus broad department/seniority
|
|
254
254
|
filters.
|
|
255
|
+
For seeded company lookalikes, keep the first call simple: resolved seed
|
|
256
|
+
company/domain plus `company_lookalike.minimum_tier` and simple confirmed
|
|
257
|
+
attributes, headcount, or industry. Do not add `company_website_search`,
|
|
258
|
+
`company_keywords`, or `company_icp` until the account sample proves the seed
|
|
259
|
+
works. Do not send placeholder seed names like `another approved best-customer seed`,
|
|
260
|
+
and only use concrete companies or domains you actually resolved. Do not send `company_website_search.exclude_keywords` without a positive website include signal.
|
|
255
261
|
Do not use `AI`, `API`, `GTM`, or `SaaS` as company keyword terms.
|
|
256
262
|
Do not combine `company_key_customers` with ICP, website-search, keyword,
|
|
257
263
|
attribute, industry, or headcount filters until the standalone pass proves
|
|
@@ -427,6 +427,12 @@ Use first for broad persona expansion, ABM/domain targeting, hiring-led targetin
|
|
|
427
427
|
- Do not send `company_keywords.exclude` unless at least one include keyword is
|
|
428
428
|
present. Do not duplicate `company_industry` when `company_icp.industries`
|
|
429
429
|
already carries the industry.
|
|
430
|
+
- For seeded company lookalikes, keep the first call simple: resolved seed
|
|
431
|
+
company/domain plus `company_lookalike.minimum_tier` and simple confirmed
|
|
432
|
+
attributes, headcount, or industry. Do not add `company_website_search`,
|
|
433
|
+
`company_keywords`, or `company_icp` until the account sample proves the seed
|
|
434
|
+
works. Do not send placeholder seed names like `another approved best-customer seed`,
|
|
435
|
+
and only use concrete companies or domains you actually resolved. Do not send `company_website_search.exclude_keywords` without a positive website include signal.
|
|
430
436
|
- Do not use `company_intent`. Do not invent unsupported support-channel filters
|
|
431
437
|
or AI Attribute guesses like phone/email/chat/ticket/social.
|
|
432
438
|
- Company/account search returns an account sample only; account rows are not people leads yet. Ask the user to approve the account sample.
|
|
@@ -106,6 +106,9 @@ Avoidable-400 guardrails:
|
|
|
106
106
|
- Do not use `AI`, `API`, `GTM`, or `SaaS` as company keyword terms. Use confirmed attributes such as `uses_ai` / `has_api`, or spell out `artificial intelligence`, `application programming interface`, `go to market`, and `software as a service`.
|
|
107
107
|
- Do not send `company_keywords.exclude` unless at least one include keyword is present.
|
|
108
108
|
- Do not duplicate `company_industry` when `company_icp.industries` already carries the industry.
|
|
109
|
+
- For seeded company lookalikes, keep the first call simple: seed company/domain + `company_lookalike.minimum_tier` + confirmed attributes, headcount, or industry. Do not add `company_website_search`, `company_keywords`, or `company_icp` until the account sample proves the seed works.
|
|
110
|
+
- Do not send placeholder seed names such as `another approved best-customer seed`; use only concrete company names or domains you have actually resolved.
|
|
111
|
+
- Do not send `company_website_search.exclude_keywords` without a positive website include signal.
|
|
109
112
|
- For post-confirm people search, prefer `person_job_title.boolean_search` for long role synonym lists instead of many `person_job_title.include` values plus broad department/seniority filters.
|
|
110
113
|
|
|
111
114
|
Unsupported/caveats:
|
|
@@ -249,6 +252,7 @@ Preference rules:
|
|
|
249
252
|
- `company_keywords.include/exclude` values must be at least 3 characters; use `artificial intelligence` instead of `AI`, or use confirmed attributes such as `uses_ai` when that is the real signal.
|
|
250
253
|
- Do not use `AI`, `API`, `GTM`, or `SaaS` as company keyword terms; use longer phrases such as `artificial intelligence`, `application programming interface`, `go to market`, or `software as a service`.
|
|
251
254
|
- Run `company_key_customers` as a standalone first-pass filter. Do not combine `company_key_customers` with ICP, website-search, keyword, attribute, industry, or headcount filters until the standalone pass proves useful.
|
|
255
|
+
- For seeded lookalikes, avoid first-call `company_website_search`, `company_keywords`, and `company_icp`; use resolved seeds plus lookalike tier and simple attributes/headcount/industry first.
|
|
252
256
|
|
|
253
257
|
### Person Filters
|
|
254
258
|
|