@sellable/mcp 0.1.956 → 0.1.957

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.
@@ -4440,6 +4440,44 @@ export declare function loadCsvDomains(input: LoadCsvDomainsInput): Promise<{
4440
4440
  guidance?: undefined;
4441
4441
  }>;
4442
4442
  export declare function loadCsvLinkedinLeads(input: LoadCsvLinkedinLeadsInput): Promise<{
4443
+ ok: boolean;
4444
+ requiresConfirmation: boolean;
4445
+ resolvedFilePath: string;
4446
+ leadListId: string;
4447
+ leadListName: string;
4448
+ createdLeadList: boolean;
4449
+ selectedLeadListIdUpdated: boolean;
4450
+ rowsInserted: number;
4451
+ jobId: string | null;
4452
+ importStatus: string;
4453
+ validCount: number;
4454
+ suggestedToolCalls: {
4455
+ tool: string;
4456
+ args: {
4457
+ campaignOfferId?: string | undefined;
4458
+ targetLeadCount: number;
4459
+ jobId?: string | undefined;
4460
+ leadListId: string;
4461
+ provider: string;
4462
+ };
4463
+ }[];
4464
+ guidance: string;
4465
+ linkedInColumn?: undefined;
4466
+ selectedColumns?: undefined;
4467
+ standardMappings?: undefined;
4468
+ customColumnTargets?: undefined;
4469
+ invalidCount?: undefined;
4470
+ duplicateCount?: undefined;
4471
+ emptyLinkedInRowCount?: undefined;
4472
+ ignoredReservedColumns?: undefined;
4473
+ reservedColumnWarning?: undefined;
4474
+ duplicatePolicy?: undefined;
4475
+ limits?: undefined;
4476
+ warnings?: undefined;
4477
+ readinessWarning?: undefined;
4478
+ preview?: undefined;
4479
+ confirmationToken?: undefined;
4480
+ } | {
4443
4481
  ok: boolean;
4444
4482
  requiresConfirmation: boolean;
4445
4483
  resolvedFilePath: string;
@@ -4480,10 +4518,6 @@ export declare function loadCsvLinkedinLeads(input: LoadCsvLinkedinLeadsInput):
4480
4518
  preview: import("./csv-linkedin.js").CsvLinkedinPreview;
4481
4519
  suggestedToolCalls: never[];
4482
4520
  resolvedFilePath?: undefined;
4483
- linkedInColumn?: undefined;
4484
- selectedColumns?: undefined;
4485
- standardMappings?: undefined;
4486
- customColumnTargets?: undefined;
4487
4521
  leadListId?: undefined;
4488
4522
  leadListName?: undefined;
4489
4523
  createdLeadList?: undefined;
@@ -4492,6 +4526,11 @@ export declare function loadCsvLinkedinLeads(input: LoadCsvLinkedinLeadsInput):
4492
4526
  jobId?: undefined;
4493
4527
  importStatus?: undefined;
4494
4528
  validCount?: undefined;
4529
+ guidance?: undefined;
4530
+ linkedInColumn?: undefined;
4531
+ selectedColumns?: undefined;
4532
+ standardMappings?: undefined;
4533
+ customColumnTargets?: undefined;
4495
4534
  invalidCount?: undefined;
4496
4535
  duplicateCount?: undefined;
4497
4536
  emptyLinkedInRowCount?: undefined;
@@ -4501,7 +4540,6 @@ export declare function loadCsvLinkedinLeads(input: LoadCsvLinkedinLeadsInput):
4501
4540
  limits?: undefined;
4502
4541
  warnings?: undefined;
4503
4542
  readinessWarning?: undefined;
4504
- guidance?: undefined;
4505
4543
  confirmationToken?: undefined;
4506
4544
  } | {
4507
4545
  ok: boolean;
@@ -4521,10 +4559,6 @@ export declare function loadCsvLinkedinLeads(input: LoadCsvLinkedinLeadsInput):
4521
4559
  };
4522
4560
  }[];
4523
4561
  resolvedFilePath?: undefined;
4524
- linkedInColumn?: undefined;
4525
- selectedColumns?: undefined;
4526
- standardMappings?: undefined;
4527
- customColumnTargets?: undefined;
4528
4562
  leadListId?: undefined;
4529
4563
  leadListName?: undefined;
4530
4564
  createdLeadList?: undefined;
@@ -4533,6 +4567,11 @@ export declare function loadCsvLinkedinLeads(input: LoadCsvLinkedinLeadsInput):
4533
4567
  jobId?: undefined;
4534
4568
  importStatus?: undefined;
4535
4569
  validCount?: undefined;
4570
+ guidance?: undefined;
4571
+ linkedInColumn?: undefined;
4572
+ selectedColumns?: undefined;
4573
+ standardMappings?: undefined;
4574
+ customColumnTargets?: undefined;
4536
4575
  invalidCount?: undefined;
4537
4576
  duplicateCount?: undefined;
4538
4577
  emptyLinkedInRowCount?: undefined;
@@ -4542,7 +4581,6 @@ export declare function loadCsvLinkedinLeads(input: LoadCsvLinkedinLeadsInput):
4542
4581
  limits?: undefined;
4543
4582
  warnings?: undefined;
4544
4583
  readinessWarning?: undefined;
4545
- guidance?: undefined;
4546
4584
  }>;
4547
4585
  export declare function loadCsvDncEntriesTool(input: LoadCsvDncEntriesInput & {
4548
4586
  workspaceId?: string | null;
@@ -1534,7 +1534,7 @@ export const leadToolDefinitions = [
1534
1534
  },
1535
1535
  {
1536
1536
  name: "search_sales_nav",
1537
- description: 'Search LinkedIn Sales Navigator. Requires exact provider prompt preflight. Pass exactly one owner: campaignOfferId for campaign work or findLeadsRunId plus runVersion for a campaignless run.',
1537
+ description: "Search LinkedIn Sales Navigator. Requires exact provider prompt preflight. Pass exactly one owner: campaignOfferId for campaign work or findLeadsRunId plus runVersion for a campaignless run.",
1538
1538
  inputSchema: {
1539
1539
  type: "object",
1540
1540
  properties: {
@@ -1559,9 +1559,18 @@ export const leadToolDefinitions = [
1559
1559
  type: "string",
1560
1560
  description: "Campaign offer ID to associate search",
1561
1561
  },
1562
- findLeadsRunId: { type: "string", description: "Campaignless run/list ID" },
1563
- runVersion: { type: "number", description: "Current durable run version" },
1564
- targetLeadCount: { type: "number", description: "Approved bounded source cap" },
1562
+ findLeadsRunId: {
1563
+ type: "string",
1564
+ description: "Campaignless run/list ID",
1565
+ },
1566
+ runVersion: {
1567
+ type: "number",
1568
+ description: "Current durable run version",
1569
+ },
1570
+ targetLeadCount: {
1571
+ type: "number",
1572
+ description: "Approved bounded source cap",
1573
+ },
1565
1574
  searchName: {
1566
1575
  type: "string",
1567
1576
  description: "Optional name for the search",
@@ -2001,9 +2010,18 @@ export const leadToolDefinitions = [
2001
2010
  type: "string",
2002
2011
  description: "Campaign offer ID to associate search",
2003
2012
  },
2004
- findLeadsRunId: { type: "string", description: "Campaignless run/list ID" },
2005
- runVersion: { type: "number", description: "Current durable run version" },
2006
- targetLeadCount: { type: "number", description: "Approved bounded source cap" },
2013
+ findLeadsRunId: {
2014
+ type: "string",
2015
+ description: "Campaignless run/list ID",
2016
+ },
2017
+ runVersion: {
2018
+ type: "number",
2019
+ description: "Current durable run version",
2020
+ },
2021
+ targetLeadCount: {
2022
+ type: "number",
2023
+ description: "Approved bounded source cap",
2024
+ },
2007
2025
  workspaceId: {
2008
2026
  type: "string",
2009
2027
  description: "Explicit request-scoped workspace id. Pass this instead of switching the shared active workspace.",
@@ -2070,8 +2088,14 @@ export const leadToolDefinitions = [
2070
2088
  type: "string",
2071
2089
  description: "Campaign offer ID to associate search. Optional for directional preview runs.",
2072
2090
  },
2073
- findLeadsRunId: { type: "string", description: "Campaignless run/list ID" },
2074
- runVersion: { type: "number", description: "Current durable run version" },
2091
+ findLeadsRunId: {
2092
+ type: "string",
2093
+ description: "Campaignless run/list ID",
2094
+ },
2095
+ runVersion: {
2096
+ type: "number",
2097
+ description: "Current durable run version",
2098
+ },
2075
2099
  currentStep: {
2076
2100
  type: ["string", "null"],
2077
2101
  description: "Headless workflow step ID",
@@ -2117,8 +2141,14 @@ export const leadToolDefinitions = [
2117
2141
  type: "string",
2118
2142
  description: "Campaign offer ID",
2119
2143
  },
2120
- findLeadsRunId: { type: "string", description: "Campaignless run/list ID" },
2121
- runVersion: { type: "number", description: "Current durable run version" },
2144
+ findLeadsRunId: {
2145
+ type: "string",
2146
+ description: "Campaignless run/list ID",
2147
+ },
2148
+ runVersion: {
2149
+ type: "number",
2150
+ description: "Current durable run version",
2151
+ },
2122
2152
  workspaceId: {
2123
2153
  type: "string",
2124
2154
  description: "Explicit request-scoped workspace id. Pass this instead of switching the shared active workspace.",
@@ -2189,8 +2219,14 @@ export const leadToolDefinitions = [
2189
2219
  },
2190
2220
  },
2191
2221
  oneOf: [
2192
- { required: ["campaignOfferId"], not: { required: ["findLeadsRunId"] } },
2193
- { required: ["findLeadsRunId", "runVersion", "provider"], not: { required: ["campaignOfferId"] } }
2222
+ {
2223
+ required: ["campaignOfferId"],
2224
+ not: { required: ["findLeadsRunId"] },
2225
+ },
2226
+ {
2227
+ required: ["findLeadsRunId", "runVersion", "provider"],
2228
+ not: { required: ["campaignOfferId"] },
2229
+ },
2194
2230
  ],
2195
2231
  additionalProperties: false,
2196
2232
  },
@@ -2232,9 +2268,15 @@ export const leadToolDefinitions = [
2232
2268
  type: "string",
2233
2269
  description: "Campaign offer ID",
2234
2270
  },
2235
- findLeadsRunId: { type: "string", description: "Campaignless run/list ID" },
2271
+ findLeadsRunId: {
2272
+ type: "string",
2273
+ description: "Campaignless run/list ID",
2274
+ },
2236
2275
  signalTabId: { type: "string", description: "Signal Discovery tab ID" },
2237
- runVersion: { type: "number", description: "Current durable run version" },
2276
+ runVersion: {
2277
+ type: "number",
2278
+ description: "Current durable run version",
2279
+ },
2238
2280
  workspaceId: {
2239
2281
  type: "string",
2240
2282
  description: "Explicit request-scoped workspace id. Pass this instead of switching the shared active workspace.",
@@ -3608,7 +3650,42 @@ export async function loadCsvLinkedinLeads(input) {
3608
3650
  if (readiness.reason === "import_failed") {
3609
3651
  throw new Error(readiness.error || "CSV import failed. Please retry the upload.");
3610
3652
  }
3611
- throw new Error("CSV import is still processing. Re-run the tool shortly.");
3653
+ // The lead list exists and the import is running. Hand back its ids so
3654
+ // the caller waits on this import; running this tool again would create
3655
+ // a second lead list and import every row twice.
3656
+ const targetLeadCount = importStart.effectiveTargetLeadCount ??
3657
+ importStart.targetLeadCount ??
3658
+ previewBuild.preview.validLinkedInRowCount;
3659
+ return {
3660
+ ok: true,
3661
+ requiresConfirmation: false,
3662
+ resolvedFilePath: previewBuild.preview.resolvedFilePath,
3663
+ leadListId,
3664
+ leadListName,
3665
+ createdLeadList,
3666
+ selectedLeadListIdUpdated: Boolean(input.campaignOfferId),
3667
+ rowsInserted: typeof readiness.rowCount === "number" ? readiness.rowCount : 0,
3668
+ jobId: importStart.jobId ?? null,
3669
+ importStatus: "importing",
3670
+ validCount: previewBuild.preview.validLinkedInRowCount,
3671
+ suggestedToolCalls: [
3672
+ {
3673
+ tool: "wait_for_lead_list_ready",
3674
+ args: {
3675
+ leadListId,
3676
+ provider: "csv-linkedin",
3677
+ ...(importStart.jobId ? { jobId: importStart.jobId } : {}),
3678
+ targetLeadCount,
3679
+ ...(input.campaignOfferId
3680
+ ? { campaignOfferId: input.campaignOfferId }
3681
+ : {}),
3682
+ },
3683
+ },
3684
+ ],
3685
+ guidance: "The lead list was created and the CSV import is still running. Call wait_for_lead_list_ready with this leadListId and jobId until it reports ready" +
3686
+ (input.campaignOfferId ? ", then confirm_lead_list" : "") +
3687
+ ". Do not run load_csv_linkedin_leads again for this file: that creates a second lead list and imports every row twice.",
3688
+ };
3612
3689
  }
3613
3690
  return {
3614
3691
  ok: true,
@@ -3807,8 +3884,7 @@ export async function importLeads(input) {
3807
3884
  throw new Error("Campaignless sourceLeadListId must equal findLeadsRunId");
3808
3885
  }
3809
3886
  assertProviderPromptLoaded({ provider, findLeadsRunId: runId });
3810
- const targetLeadCount = Math.min(normalizeTargetLeadCount(input.targetLeadCount, getMaxImportCount(provider)) ??
3811
- defaultProviderSourceListTarget, getMaxImportCount(provider));
3887
+ const targetLeadCount = Math.min(normalizeTargetLeadCount(input.targetLeadCount, getMaxImportCount(provider)) ?? defaultProviderSourceListTarget, getMaxImportCount(provider));
3812
3888
  let response;
3813
3889
  if (provider === "sales-nav") {
3814
3890
  if (!input.searchId) {
@@ -3855,7 +3931,10 @@ export async function importLeads(input) {
3855
3931
  status: response.status ?? (response.success === false ? "failed" : "queued"),
3856
3932
  counts: {
3857
3933
  requested: targetLeadCount,
3858
- rows: response.rowCount ?? response.leadsImported ?? response.importedCount ?? 0,
3934
+ rows: response.rowCount ??
3935
+ response.leadsImported ??
3936
+ response.importedCount ??
3937
+ 0,
3859
3938
  },
3860
3939
  retryable: response.retryable ?? response.success !== false,
3861
3940
  replay: response.replay === true,
@@ -4349,8 +4428,12 @@ export async function confirmLeadList(input) {
4349
4428
  });
4350
4429
  let resolvedLeadListId = sourceLeadListId;
4351
4430
  let resolvedProvider;
4352
- const isSameSourceRefillCopy = currentStep === null && Array.isArray(sourceRowIds) && sourceRowIds.length > 0;
4353
- if (!resolvedLeadListId || currentStep === undefined || !isSameSourceRefillCopy) {
4431
+ const isSameSourceRefillCopy = currentStep === null &&
4432
+ Array.isArray(sourceRowIds) &&
4433
+ sourceRowIds.length > 0;
4434
+ if (!resolvedLeadListId ||
4435
+ currentStep === undefined ||
4436
+ !isSameSourceRefillCopy) {
4354
4437
  const campaign = requestOptions
4355
4438
  ? await api.get(`/api/v2/campaign-offers/${campaignOfferId}`, requestOptions)
4356
4439
  : await api.get(`/api/v2/campaign-offers/${campaignOfferId}`);
@@ -4966,7 +5049,7 @@ Approval card should say:
4966
5049
  }
4967
5050
  export async function setHeadlineICPCriteria(input) {
4968
5051
  const api = getApi();
4969
- const { campaignOfferId, headlineICPCriteria, currentStep, workspaceId, } = input;
5052
+ const { campaignOfferId, headlineICPCriteria, currentStep, workspaceId } = input;
4970
5053
  const requestOptions = workspaceRequestOptions(workspaceId);
4971
5054
  // Persist criteria to the campaign so import_leads can rely on backend state.
4972
5055
  await api.patch(`/api/v3/campaigns/${campaignOfferId}/signal-discovery/posts`, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.956",
3
+ "version": "0.1.957",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code, Codex, and Hermes campaign workflows",
6
6
  "main": "dist/index.js",