@sellable/mcp 0.1.223 → 0.1.225
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.d.ts
CHANGED
|
@@ -1246,12 +1246,14 @@ export declare const leadToolDefinitions: ({
|
|
|
1246
1246
|
type: string;
|
|
1247
1247
|
items: {
|
|
1248
1248
|
type: string;
|
|
1249
|
+
minLength: number;
|
|
1249
1250
|
};
|
|
1250
1251
|
};
|
|
1251
1252
|
exclude: {
|
|
1252
1253
|
type: string;
|
|
1253
1254
|
items: {
|
|
1254
1255
|
type: string;
|
|
1256
|
+
minLength: number;
|
|
1255
1257
|
};
|
|
1256
1258
|
};
|
|
1257
1259
|
include_all: {
|
|
@@ -2386,12 +2388,14 @@ export declare const leadToolDefinitions: ({
|
|
|
2386
2388
|
type: string;
|
|
2387
2389
|
items: {
|
|
2388
2390
|
type: string;
|
|
2391
|
+
minLength: number;
|
|
2389
2392
|
};
|
|
2390
2393
|
};
|
|
2391
2394
|
exclude: {
|
|
2392
2395
|
type: string;
|
|
2393
2396
|
items: {
|
|
2394
2397
|
type: string;
|
|
2398
|
+
minLength: number;
|
|
2395
2399
|
};
|
|
2396
2400
|
};
|
|
2397
2401
|
include_all: {
|
package/dist/tools/leads.js
CHANGED
|
@@ -59,6 +59,10 @@ export const MAX_SIGNAL_DISCOVERY_POSTS = 10;
|
|
|
59
59
|
// capacity math instead of raw visible engagement counts.
|
|
60
60
|
const signalDiscoveryReactionFetchLimit = 1000;
|
|
61
61
|
const signalDiscoveryCommentFetchLimit = 1000;
|
|
62
|
+
const prospeoCompanySearchTokenRefs = new Map();
|
|
63
|
+
let prospeoCompanySearchTokenRefCounter = 0;
|
|
64
|
+
const PROSPEO_COMPANY_SEARCH_TOKEN_REF_PREFIX = "mcp-prospeo-company-search-token:";
|
|
65
|
+
const MAX_PROSPEO_COMPANY_SEARCH_TOKEN_REFS = 200;
|
|
62
66
|
const prospeoFilterValueSchema = {
|
|
63
67
|
type: "object",
|
|
64
68
|
description: "Include/exclude list filter (values must match Prospeo enums)",
|
|
@@ -177,10 +181,10 @@ const prospeoFundingFilterSchema = {
|
|
|
177
181
|
};
|
|
178
182
|
const prospeoCompanyKeywordsSchema = {
|
|
179
183
|
type: "object",
|
|
180
|
-
description:
|
|
184
|
+
description: 'Company keyword search. Prospeo requires keyword values to be at least 3 characters; use "artificial intelligence" instead of "AI".',
|
|
181
185
|
properties: {
|
|
182
|
-
include: { type: "array", items: { type: "string" } },
|
|
183
|
-
exclude: { type: "array", items: { type: "string" } },
|
|
186
|
+
include: { type: "array", items: { type: "string", minLength: 3 } },
|
|
187
|
+
exclude: { type: "array", items: { type: "string", minLength: 3 } },
|
|
184
188
|
include_all: { type: "boolean" },
|
|
185
189
|
include_company_description: { type: "boolean" },
|
|
186
190
|
include_company_description_seo: { type: "boolean" },
|
|
@@ -477,12 +481,14 @@ search_prospeo_companies({
|
|
|
477
481
|
}
|
|
478
482
|
})
|
|
479
483
|
Do not invent company_oids. When seedCompanies or seedDomains are present, omit company_oids and let the backend resolve real Prospeo company IDs.
|
|
484
|
+
After account approval, copy the companySearchToken exactly into confirm_prospeo_company_accounts; package-backed MCP may return a short mcp-prospeo-company-search-token:* reference to avoid long-token copy errors.
|
|
480
485
|
For accounts in the news: { "company_news": { "categories": ["Funding & Investment"], "timeframe_days": 90 } }.
|
|
481
486
|
For awards: { "company_awards": { "include": ["G2"], "match_mode": "CONTAINS" } }.
|
|
482
487
|
For website traffic: { "company_website_traffic": { "min_monthly_visits": 50000 } }.
|
|
483
488
|
For products/services, integrations, key customers, and Google discovery use "company_products_services", "company_integrations", "company_key_customers", and "company_google_discovery".
|
|
484
489
|
For headcount by location: { "company_headcount_by_location": { "entries": [{ "country": "United States", "city": "Austin", "min_headcount": 10 }] } }.
|
|
485
490
|
For structured ICP: { "company_icp": { "titles_include": ["Head of RevOps"], "company_sizes": ["midmarket"], "departments": { "include": ["Sales"], "match_mode": "ANY" }, "geographic_scope": "multi_country", "geographic_markets": ["United States", "Canada"] }, "company_headcount_range": ["101-200", "201-500", "501-1000"] }. Pair company_icp.company_sizes with company_headcount_range or rely on MCP normalization that derives the range; inspect the account sample for size drift. Product is not a company_icp.departments value; use titles_include for product roles. geographic_scope only accepts single_country or multi_country.
|
|
491
|
+
Use company_key_customers as a standalone first-pass account filter. Do not combine company_key_customers with company_website_search, company_icp, company_keywords, or broad AI Attributes in the first call. Do not use AI, API, GTM, or SaaS as company keyword terms; use confirmed attributes or spell out artificial intelligence, application programming interface, go to market, and software as a service. Do not send company_keywords.exclude without an include keyword. For post-confirm people search, prefer person_job_title.boolean_search for long role synonym lists.
|
|
486
492
|
company_intent is unsupported; support-channel AI Attribute guesses like phone/email/chat/ticket/social are not exposed. public API rows do not include lookalike tier/score/reason.`;
|
|
487
493
|
function loadSignalDiscoveryConfig() {
|
|
488
494
|
if (!existsSync(signalProviderConfigPath)) {
|
|
@@ -2310,14 +2316,15 @@ export async function searchProspeoCompanies(input) {
|
|
|
2310
2316
|
campaignOfferId: input?.campaignOfferId,
|
|
2311
2317
|
});
|
|
2312
2318
|
const api = getApi();
|
|
2319
|
+
const safeInput = normalizeProspeoCompanySearchInputForMcp(input);
|
|
2313
2320
|
const response = await api.post("/api/v3/prospeo/company-search", removeUndefinedValues({
|
|
2314
|
-
campaignOfferId:
|
|
2315
|
-
seedCompanies:
|
|
2316
|
-
seedDomains:
|
|
2317
|
-
filters:
|
|
2318
|
-
limit:
|
|
2319
|
-
page:
|
|
2320
|
-
sort:
|
|
2321
|
+
campaignOfferId: safeInput?.campaignOfferId,
|
|
2322
|
+
seedCompanies: safeInput?.seedCompanies,
|
|
2323
|
+
seedDomains: safeInput?.seedDomains,
|
|
2324
|
+
filters: safeInput?.filters ?? {},
|
|
2325
|
+
limit: safeInput?.limit,
|
|
2326
|
+
page: safeInput?.page,
|
|
2327
|
+
sort: safeInput?.sort,
|
|
2321
2328
|
}));
|
|
2322
2329
|
return compactProspeoCompanySearchResponse(response);
|
|
2323
2330
|
}
|
|
@@ -2346,7 +2353,7 @@ export async function confirmProspeoCompanyAccounts(input) {
|
|
|
2346
2353
|
const api = getApi();
|
|
2347
2354
|
const response = await api.post("/api/v3/prospeo/company-search/confirm-domain-filter", removeUndefinedValues({
|
|
2348
2355
|
campaignOfferId: input?.campaignOfferId,
|
|
2349
|
-
companySearchToken: input.companySearchToken,
|
|
2356
|
+
companySearchToken: resolveProspeoCompanySearchTokenRef(input.companySearchToken),
|
|
2350
2357
|
selectedCompanyIds: input.selectedCompanyIds,
|
|
2351
2358
|
name: input.name,
|
|
2352
2359
|
}));
|
|
@@ -2355,6 +2362,49 @@ export async function confirmProspeoCompanyAccounts(input) {
|
|
|
2355
2362
|
function removeUndefinedValues(input) {
|
|
2356
2363
|
return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== undefined));
|
|
2357
2364
|
}
|
|
2365
|
+
function normalizeProspeoCompanySearchInputForMcp(input) {
|
|
2366
|
+
const filters = input?.filters && typeof input.filters === "object"
|
|
2367
|
+
? clonePlainObject(input.filters)
|
|
2368
|
+
: {};
|
|
2369
|
+
const hasSeeds = (input.seedCompanies?.length ?? 0) > 0 ||
|
|
2370
|
+
(input.seedDomains?.length ?? 0) > 0;
|
|
2371
|
+
if (hasSeeds) {
|
|
2372
|
+
const lookalike = filters.company_lookalike;
|
|
2373
|
+
if (lookalike &&
|
|
2374
|
+
typeof lookalike === "object" &&
|
|
2375
|
+
!Array.isArray(lookalike) &&
|
|
2376
|
+
"company_oids" in lookalike) {
|
|
2377
|
+
delete lookalike.company_oids;
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
return {
|
|
2381
|
+
...input,
|
|
2382
|
+
filters,
|
|
2383
|
+
};
|
|
2384
|
+
}
|
|
2385
|
+
function clonePlainObject(input) {
|
|
2386
|
+
return JSON.parse(JSON.stringify(input));
|
|
2387
|
+
}
|
|
2388
|
+
function storeProspeoCompanySearchTokenRef(token) {
|
|
2389
|
+
if (typeof token !== "string" || token.length === 0) {
|
|
2390
|
+
return token;
|
|
2391
|
+
}
|
|
2392
|
+
if (token.startsWith(PROSPEO_COMPANY_SEARCH_TOKEN_REF_PREFIX)) {
|
|
2393
|
+
return token;
|
|
2394
|
+
}
|
|
2395
|
+
const ref = `${PROSPEO_COMPANY_SEARCH_TOKEN_REF_PREFIX}${Date.now().toString(36)}-${(++prospeoCompanySearchTokenRefCounter).toString(36)}`;
|
|
2396
|
+
prospeoCompanySearchTokenRefs.set(ref, token);
|
|
2397
|
+
while (prospeoCompanySearchTokenRefs.size > MAX_PROSPEO_COMPANY_SEARCH_TOKEN_REFS) {
|
|
2398
|
+
const oldest = prospeoCompanySearchTokenRefs.keys().next().value;
|
|
2399
|
+
if (!oldest)
|
|
2400
|
+
break;
|
|
2401
|
+
prospeoCompanySearchTokenRefs.delete(oldest);
|
|
2402
|
+
}
|
|
2403
|
+
return ref;
|
|
2404
|
+
}
|
|
2405
|
+
function resolveProspeoCompanySearchTokenRef(token) {
|
|
2406
|
+
return prospeoCompanySearchTokenRefs.get(token) ?? token;
|
|
2407
|
+
}
|
|
2358
2408
|
function compactProspeoCompanySearchResponse(response) {
|
|
2359
2409
|
if (!response || typeof response !== "object") {
|
|
2360
2410
|
return response;
|
|
@@ -2384,7 +2434,7 @@ function compactProspeoCompanySearchResponse(response) {
|
|
|
2384
2434
|
},
|
|
2385
2435
|
requestedFilters: response.normalizedFilters ?? response.filters ?? {},
|
|
2386
2436
|
warnings: Array.isArray(response.warnings) ? response.warnings : [],
|
|
2387
|
-
companySearchToken: response.companySearchToken
|
|
2437
|
+
companySearchToken: storeProspeoCompanySearchTokenRef(response.companySearchToken),
|
|
2388
2438
|
nextStep: "Review accounts, then call confirm_prospeo_company_accounts with companySearchToken and selectedCompanyIds. These accounts are not people leads yet.",
|
|
2389
2439
|
};
|
|
2390
2440
|
}
|
package/dist/tools/registry.d.ts
CHANGED
|
@@ -2585,12 +2585,14 @@ export declare const allTools: ({
|
|
|
2585
2585
|
type: string;
|
|
2586
2586
|
items: {
|
|
2587
2587
|
type: string;
|
|
2588
|
+
minLength: number;
|
|
2588
2589
|
};
|
|
2589
2590
|
};
|
|
2590
2591
|
exclude: {
|
|
2591
2592
|
type: string;
|
|
2592
2593
|
items: {
|
|
2593
2594
|
type: string;
|
|
2595
|
+
minLength: number;
|
|
2594
2596
|
};
|
|
2595
2597
|
};
|
|
2596
2598
|
include_all: {
|
|
@@ -3725,12 +3727,14 @@ export declare const allTools: ({
|
|
|
3725
3727
|
type: string;
|
|
3726
3728
|
items: {
|
|
3727
3729
|
type: string;
|
|
3730
|
+
minLength: number;
|
|
3728
3731
|
};
|
|
3729
3732
|
};
|
|
3730
3733
|
exclude: {
|
|
3731
3734
|
type: string;
|
|
3732
3735
|
items: {
|
|
3733
3736
|
type: string;
|
|
3737
|
+
minLength: number;
|
|
3734
3738
|
};
|
|
3735
3739
|
};
|
|
3736
3740
|
include_all: {
|
package/package.json
CHANGED
|
@@ -214,9 +214,12 @@ before person search, use the Prospeo account approval flow:
|
|
|
214
214
|
First return an account sample and ask the user to approve the account set.
|
|
215
215
|
Only call `confirm_prospeo_company_accounts` with the `companySearchToken`
|
|
216
216
|
returned by `search_prospeo_companies` and selected Prospeo company IDs; never
|
|
217
|
-
reconstruct raw account rows or domains manually
|
|
218
|
-
|
|
219
|
-
|
|
217
|
+
reconstruct raw account rows or domains manually; always copy the `companySearchToken` exactly.
|
|
218
|
+
Package-backed MCP may return a short `mcp-prospeo-company-search-token:*`
|
|
219
|
+
reference to avoid long-token copy errors. Account rows are not people leads
|
|
220
|
+
yet. The confirmation creates the `domainFilterId` that constrains the follow-on
|
|
221
|
+
`search_prospeo` people search.
|
|
222
|
+
Always copy the `companySearchToken` exactly.
|
|
220
223
|
|
|
221
224
|
Prospeo company/account search is useful when the source plan depends on
|
|
222
225
|
website traffic (`company_website_traffic`), confirmed AI Attributes including
|
|
@@ -232,9 +235,28 @@ the MCP backend resolves real Prospeo company IDs. Do not invent company_oids.
|
|
|
232
235
|
For company ICP geography, `geographic_scope` only accepts `single_country` or
|
|
233
236
|
`multi_country`; put North America style regions in `geographic_markets` as
|
|
234
237
|
specific markets such as United States and Canada. Product is not a
|
|
235
|
-
company_icp.departments value; use `titles_include` for product roles.
|
|
236
|
-
|
|
237
|
-
AI
|
|
238
|
+
company_icp.departments value; use `titles_include` for product roles.
|
|
239
|
+
`company_keywords.include/exclude` values must be at least 3 characters; use
|
|
240
|
+
`artificial intelligence` instead of `AI`, or use confirmed attributes such as
|
|
241
|
+
`uses_ai` when that is the actual signal. Do not use `company_intent`, and do
|
|
242
|
+
not invent unsupported support-channel filters or AI Attribute guesses like
|
|
243
|
+
phone/email/chat/ticket/social.
|
|
244
|
+
Use `company_key_customers` as a standalone first-pass account filter; in short,
|
|
245
|
+
run company_key_customers as a standalone first-pass. Do not combine
|
|
246
|
+
`company_key_customers` with `company_website_search`, `company_icp`,
|
|
247
|
+
`company_keywords`, or broad AI Attributes in the first call. Do not use `AI`,
|
|
248
|
+
`API`, `GTM`, or `SaaS` as company keyword terms; use confirmed attributes or
|
|
249
|
+
spell out artificial intelligence, application programming interface, go to
|
|
250
|
+
market, and software as a service. Do not send `company_keywords.exclude`
|
|
251
|
+
without an include keyword, and do not duplicate `company_industry` when
|
|
252
|
+
`company_icp.industries` already carries the industry. For post-confirm people
|
|
253
|
+
search, prefer `person_job_title.boolean_search` for long role synonym lists
|
|
254
|
+
instead of many `person_job_title.include` values plus broad department/seniority
|
|
255
|
+
filters.
|
|
256
|
+
Do not use `AI`, `API`, `GTM`, or `SaaS` as company keyword terms.
|
|
257
|
+
Do not combine `company_key_customers` with ICP, website-search, keyword,
|
|
258
|
+
attribute, industry, or headcount filters until the standalone pass proves
|
|
259
|
+
useful.
|
|
238
260
|
|
|
239
261
|
After scouting, ask for a second approval on Start Import. For
|
|
240
262
|
LinkedIn engagement (`signal-discovery` internally), name how many
|
|
@@ -411,15 +411,36 @@ Use first for broad persona expansion, ABM/domain targeting, hiring-led targetin
|
|
|
411
411
|
product roles. Allowed company ICP departments include Consumers, Customer
|
|
412
412
|
Success, Data, Design, Engineering, Finance, HR, IT, Legal, Marketing,
|
|
413
413
|
Operations, Procurement, SMB Owners, Sales, and Security.
|
|
414
|
+
- `company_keywords.include/exclude` values must be at least 3 characters; use
|
|
415
|
+
`artificial intelligence` instead of `AI`, or use confirmed attributes such
|
|
416
|
+
as `uses_ai` when that is the actual signal.
|
|
417
|
+
- Use `company_key_customers` as a standalone first-pass account filter; in
|
|
418
|
+
short, run company_key_customers as a standalone first-pass. Do not
|
|
419
|
+
combine `company_key_customers` with `company_website_search`, `company_icp`,
|
|
420
|
+
`company_keywords`, or broad AI Attributes in the first call.
|
|
421
|
+
- Do not combine `company_key_customers` with ICP, website-search, keyword,
|
|
422
|
+
attribute, industry, or headcount filters until the standalone pass proves
|
|
423
|
+
useful.
|
|
424
|
+
- Do not use `AI`, `API`, `GTM`, or `SaaS` as company keyword terms; use
|
|
425
|
+
confirmed attributes or spell out artificial intelligence, application
|
|
426
|
+
programming interface, go to market, and software as a service.
|
|
427
|
+
- Do not send `company_keywords.exclude` unless at least one include keyword is
|
|
428
|
+
present. Do not duplicate `company_industry` when `company_icp.industries`
|
|
429
|
+
already carries the industry.
|
|
414
430
|
- Do not use `company_intent`. Do not invent unsupported support-channel filters
|
|
415
431
|
or AI Attribute guesses like phone/email/chat/ticket/social.
|
|
416
432
|
- Company/account search returns an account sample only; account rows are not people leads yet. Ask the user to approve the account sample.
|
|
417
433
|
- After approval, call `confirm_prospeo_company_accounts` with the
|
|
418
434
|
`companySearchToken` and selected Prospeo company IDs from
|
|
419
435
|
`search_prospeo_companies`; do not reconstruct account rows or domains
|
|
420
|
-
manually.
|
|
436
|
+
manually. Always copy the `companySearchToken` exactly; package-backed MCP may
|
|
437
|
+
return a short `mcp-prospeo-company-search-token:*` reference to avoid
|
|
438
|
+
long-token copy errors.
|
|
421
439
|
- Use the returned `domainFilterId` in the follow-on `search_prospeo` people
|
|
422
440
|
search.
|
|
441
|
+
- For post-confirm people search, prefer `person_job_title.boolean_search` for
|
|
442
|
+
long role synonym lists instead of many `person_job_title.include` values plus
|
|
443
|
+
broad department/seniority filters.
|
|
423
444
|
- Prospeo is the terminal fallback for this chain. If projected fit is still
|
|
424
445
|
below the 10% planning floor after reasonable Prospeo refinement, stop and ask
|
|
425
446
|
for a tighter ICP/source direction instead of inventing another provider.
|
|
@@ -80,7 +80,7 @@ confirm_prospeo_company_accounts({
|
|
|
80
80
|
})
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
Use the returned `domainFilterId` in `search_prospeo` with people filters. Do not reconstruct raw account rows or domains manually as Prospeo-sourced provenance.
|
|
83
|
+
Use the returned `domainFilterId` in `search_prospeo` with people filters. Do not reconstruct raw account rows or domains manually as Prospeo-sourced provenance. Always copy the `companySearchToken` exactly from `search_prospeo_companies`; package-backed MCP may return a short `mcp-prospeo-company-search-token:*` reference so the model does not have to copy a long signed backend token.
|
|
84
84
|
|
|
85
85
|
When `seedDomains` or `seedCompanies` are present, omit `company_oids`; the MCP
|
|
86
86
|
backend resolves real Prospeo company IDs. Do not invent company_oids such as
|
|
@@ -100,6 +100,14 @@ company ICP departments include Consumers, Customer Success, Data, Design,
|
|
|
100
100
|
Engineering, Finance, HR, IT, Legal, Marketing, Operations, Procurement, SMB
|
|
101
101
|
Owners, Sales, and Security.
|
|
102
102
|
|
|
103
|
+
Avoidable-400 guardrails:
|
|
104
|
+
|
|
105
|
+
- Use `company_key_customers` as a standalone first-pass account filter; in short, run company_key_customers as a standalone first-pass. Do not combine `company_key_customers` with `company_website_search`, `company_icp`, `company_keywords`, or broad AI Attributes in the first call; inspect the account sample, then refine if needed.
|
|
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
|
+
- Do not send `company_keywords.exclude` unless at least one include keyword is present.
|
|
108
|
+
- Do not duplicate `company_industry` when `company_icp.industries` already carries the industry.
|
|
109
|
+
- 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
|
+
|
|
103
111
|
Unsupported/caveats:
|
|
104
112
|
|
|
105
113
|
- `company_intent` is unsupported by Prospeo public API.
|
|
@@ -234,9 +242,13 @@ Preference rules:
|
|
|
234
242
|
- If user input starts as company names, resolve names to domains first, then use `save_domain_filters`.
|
|
235
243
|
- Prefer comprehensive `person_job_title.include` lists (synonyms + role variants) for role precision.
|
|
236
244
|
- Use `person_department + person_seniority` as supporting constraints when title variance is expected.
|
|
245
|
+
- For long title synonym lists, prefer `person_job_title.boolean_search` with explicit OR terms instead of oversized include arrays.
|
|
237
246
|
- In security, AppSec, SOC, RevOps, Demand Gen, and similar function-specific lanes, do not rely on bare `Head` / `Director` / `VP` widening by itself. Pair seniority with explicit function keywords in `person_job_title` and verify the sample for off-function titles like `Head of Social Media`.
|
|
238
247
|
- Prefer `company_headcount_range` for most sizing; use `company_headcount_custom` for precise numeric bounds.
|
|
239
248
|
- Prefer `company_industry` before `company_keywords`; use keywords for refinement, not first-pass targeting.
|
|
249
|
+
- `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
|
+
- 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
|
+
- 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.
|
|
240
252
|
|
|
241
253
|
### Person Filters
|
|
242
254
|
|