@sellable/mcp 0.1.336 → 0.1.337

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.
@@ -0,0 +1,92 @@
1
+ type RefillCampaignSendsInput = {
2
+ mode?: "plan" | "apply";
3
+ intent?: "plain" | "evergreen" | "active";
4
+ campaignIds?: string[];
5
+ tableIds?: string[];
6
+ sendWindowDays?: number;
7
+ targetDates?: string[];
8
+ targetScheduledSends?: number;
9
+ approvalMode?: "mark_ready" | "approve";
10
+ yolo?: boolean;
11
+ planRevision?: string;
12
+ actionIds?: string[];
13
+ };
14
+ export declare const refillCampaignSendsToolDefinitions: {
15
+ name: string;
16
+ description: string;
17
+ inputSchema: {
18
+ type: string;
19
+ properties: {
20
+ mode: {
21
+ type: string;
22
+ enum: string[];
23
+ default: string;
24
+ description: string;
25
+ };
26
+ intent: {
27
+ type: string;
28
+ enum: string[];
29
+ description: string;
30
+ };
31
+ campaignIds: {
32
+ type: string;
33
+ items: {
34
+ type: string;
35
+ };
36
+ maxItems: number;
37
+ description: string;
38
+ };
39
+ tableIds: {
40
+ type: string;
41
+ items: {
42
+ type: string;
43
+ };
44
+ maxItems: number;
45
+ description: string;
46
+ };
47
+ sendWindowDays: {
48
+ type: string;
49
+ minimum: number;
50
+ maximum: number;
51
+ description: string;
52
+ };
53
+ targetDates: {
54
+ type: string;
55
+ items: {
56
+ type: string;
57
+ };
58
+ maxItems: number;
59
+ description: string;
60
+ };
61
+ targetScheduledSends: {
62
+ type: string;
63
+ minimum: number;
64
+ maximum: number;
65
+ description: string;
66
+ };
67
+ approvalMode: {
68
+ type: string;
69
+ enum: string[];
70
+ description: string;
71
+ };
72
+ yolo: {
73
+ type: string;
74
+ description: string;
75
+ };
76
+ planRevision: {
77
+ type: string;
78
+ description: string;
79
+ };
80
+ actionIds: {
81
+ type: string;
82
+ items: {
83
+ type: string;
84
+ };
85
+ description: string;
86
+ };
87
+ };
88
+ additionalProperties: boolean;
89
+ };
90
+ }[];
91
+ export declare function refillCampaignSends(input: RefillCampaignSendsInput): Promise<unknown>;
92
+ export {};
@@ -0,0 +1,91 @@
1
+ import { getApi } from "../api.js";
2
+ async function postRefillCampaignSends(body) {
3
+ const api = getApi();
4
+ return api.post("/api/v3/mcp/refill-campaign-sends", body);
5
+ }
6
+ export const refillCampaignSendsToolDefinitions = [
7
+ {
8
+ name: "refill_campaign_sends",
9
+ description: "Default mode is plan and read-only. Use this as the canonical tool for plain fill, refill sends, max out sends, load everyone up, and fill send window requests. It returns a campaign send refill plan for regular campaigns and evergreen campaigns, including campaign/table ids, senders, source state, current evergreen source audit evidence, funnel counts, blockers, stable planRevision, and immutable actionIds. It does not create campaigns, create side campaigns, use unsupported_campaign_type internal targets, does not launch or start campaigns, spend paid InMail opt-in, and does not raw-write scheduler fields. mode apply requires yolo: true, the fresh planRevision from the immediately preceding plan, and selected actionIds only; apply rejects changed caps, source ids, target dates, approval mode, or selectors. Evergreen source fallback is evidence-gated: audit the current evergreen source first and recommend the next source-ladder option only after current-source exhaustion or insufficient good-prospect yield is proven. Scheduled completion is not claimed until scheduler-owned cells are reread with non-null scheduledFor.",
10
+ inputSchema: {
11
+ type: "object",
12
+ properties: {
13
+ mode: {
14
+ type: "string",
15
+ enum: ["plan", "apply"],
16
+ default: "plan",
17
+ description: 'Defaults to "plan"; plan mode is read-only and returns the plan of attack.',
18
+ },
19
+ intent: {
20
+ type: "string",
21
+ enum: ["plain", "evergreen", "active"],
22
+ description: 'Use "plain" for generic fill/refill sends, "evergreen" for explicit evergreen, and "active" for exact active campaign refill.',
23
+ },
24
+ campaignIds: {
25
+ type: "array",
26
+ items: { type: "string" },
27
+ maxItems: 25,
28
+ description: "Optional exact CampaignOffer ids. Do not pass names.",
29
+ },
30
+ tableIds: {
31
+ type: "array",
32
+ items: { type: "string" },
33
+ maxItems: 25,
34
+ description: "Optional exact WorkflowTable ids. Do not pass names.",
35
+ },
36
+ sendWindowDays: {
37
+ type: "number",
38
+ minimum: 1,
39
+ maximum: 30,
40
+ description: "Optional send window size in days.",
41
+ },
42
+ targetDates: {
43
+ type: "array",
44
+ items: { type: "string" },
45
+ maxItems: 30,
46
+ description: "Optional ISO date keys for the send window.",
47
+ },
48
+ targetScheduledSends: {
49
+ type: "number",
50
+ minimum: 1,
51
+ maximum: 500,
52
+ description: "Optional bounded send target. This is not a launch request.",
53
+ },
54
+ approvalMode: {
55
+ type: "string",
56
+ enum: ["mark_ready", "approve"],
57
+ description: "Planning preference. Use approve only when the user explicitly asked for approval; launch remains separate.",
58
+ },
59
+ yolo: {
60
+ type: "boolean",
61
+ description: "Required true for apply. Never use in production without explicit operator approval of exact workspace, campaign/table ids, action ids, caps/dates, and expected side effects.",
62
+ },
63
+ planRevision: {
64
+ type: "string",
65
+ description: "Required for apply. Copy from the fresh read-only plan response.",
66
+ },
67
+ actionIds: {
68
+ type: "array",
69
+ items: { type: "string" },
70
+ description: "Required for apply. Select immutable actionIds from the fresh plan only.",
71
+ },
72
+ },
73
+ additionalProperties: false,
74
+ },
75
+ },
76
+ ];
77
+ export function refillCampaignSends(input) {
78
+ return postRefillCampaignSends({
79
+ mode: input.mode ?? "plan",
80
+ intent: input.intent,
81
+ campaignIds: input.campaignIds,
82
+ tableIds: input.tableIds,
83
+ sendWindowDays: input.sendWindowDays,
84
+ targetScheduledSends: input.targetScheduledSends,
85
+ targetDates: input.targetDates,
86
+ approvalMode: input.approvalMode,
87
+ yolo: input.yolo,
88
+ planRevision: input.planRevision,
89
+ actionIds: input.actionIds,
90
+ });
91
+ }
@@ -480,17 +480,89 @@ export declare const allTools: ({
480
480
  inputSchema: {
481
481
  type: string;
482
482
  properties: {
483
+ intent: {
484
+ type: string;
485
+ enum: string[];
486
+ description: string;
487
+ };
483
488
  campaignId: {
484
489
  type: string;
485
490
  description: string;
486
491
  };
487
492
  tableId: {
488
493
  type: string;
494
+ description: string;
495
+ };
496
+ limit: {
497
+ type: string;
498
+ minimum: number;
499
+ maximum: number;
500
+ description: string;
501
+ };
502
+ };
503
+ required: string[];
504
+ additionalProperties: boolean;
505
+ };
506
+ } | {
507
+ name: string;
508
+ description: string;
509
+ inputSchema: {
510
+ type: string;
511
+ properties: {
512
+ action: {
513
+ type: string;
514
+ enum: string[];
515
+ description: string;
516
+ };
517
+ campaignId: {
518
+ type: string;
519
+ description: string;
520
+ };
521
+ tableId: {
522
+ type: string;
523
+ description: string;
524
+ };
525
+ stateRevision: {
526
+ type: string;
527
+ description: string;
528
+ };
529
+ excludedPostIds: {
530
+ type: string;
531
+ items: {
532
+ type: string;
533
+ };
534
+ maxItems: number;
535
+ description: string;
536
+ };
537
+ excludedPostUrls: {
538
+ type: string;
539
+ items: {
540
+ type: string;
541
+ };
542
+ maxItems: number;
543
+ description: string;
544
+ };
545
+ excludedAuthorProfileUrls: {
546
+ type: string;
547
+ items: {
548
+ type: string;
549
+ };
550
+ maxItems: number;
551
+ description: string;
552
+ };
553
+ excludedAuthorNames: {
554
+ type: string;
555
+ items: {
556
+ type: string;
557
+ };
558
+ maxItems: number;
559
+ description: string;
489
560
  };
490
561
  targetPreparedMessages: {
491
562
  type: string;
492
563
  minimum: number;
493
564
  maximum: number;
565
+ description: string;
494
566
  };
495
567
  maxRowsToCheck: {
496
568
  type: string;
@@ -504,6 +576,46 @@ export declare const allTools: ({
504
576
  maximum: number;
505
577
  description: string;
506
578
  };
579
+ };
580
+ required: string[];
581
+ additionalProperties: boolean;
582
+ };
583
+ } | {
584
+ name: string;
585
+ description: string;
586
+ inputSchema: {
587
+ type: string;
588
+ properties: {
589
+ campaignId: {
590
+ type: string;
591
+ description: string;
592
+ };
593
+ tableId: {
594
+ type: string;
595
+ };
596
+ targetPreparedMessages: {
597
+ type: string;
598
+ minimum: number;
599
+ maximum: number;
600
+ };
601
+ maxRowsToCheck: {
602
+ type: string;
603
+ minimum: number;
604
+ maximum: number;
605
+ description: string;
606
+ };
607
+ batchSize: {
608
+ type: string;
609
+ minimum: number;
610
+ maximum: number;
611
+ description: string;
612
+ };
613
+ maxBatchRows: {
614
+ type: string;
615
+ minimum: number;
616
+ maximum: number;
617
+ description: string;
618
+ };
507
619
  approvalMode: {
508
620
  type: string;
509
621
  enum: string[];
@@ -540,6 +652,7 @@ export declare const allTools: ({
540
652
  targetPreparedMessages?: undefined;
541
653
  maxRowsToCheck?: undefined;
542
654
  batchSize?: undefined;
655
+ maxBatchRows?: undefined;
543
656
  approvalMode?: undefined;
544
657
  autoContinue?: undefined;
545
658
  disableLowPassRateStop?: undefined;
@@ -547,6 +660,82 @@ export declare const allTools: ({
547
660
  additionalProperties: boolean;
548
661
  required?: undefined;
549
662
  };
663
+ } | {
664
+ name: string;
665
+ description: string;
666
+ inputSchema: {
667
+ type: string;
668
+ properties: {
669
+ mode: {
670
+ type: string;
671
+ enum: string[];
672
+ default: string;
673
+ description: string;
674
+ };
675
+ intent: {
676
+ type: string;
677
+ enum: string[];
678
+ description: string;
679
+ };
680
+ campaignIds: {
681
+ type: string;
682
+ items: {
683
+ type: string;
684
+ };
685
+ maxItems: number;
686
+ description: string;
687
+ };
688
+ tableIds: {
689
+ type: string;
690
+ items: {
691
+ type: string;
692
+ };
693
+ maxItems: number;
694
+ description: string;
695
+ };
696
+ sendWindowDays: {
697
+ type: string;
698
+ minimum: number;
699
+ maximum: number;
700
+ description: string;
701
+ };
702
+ targetDates: {
703
+ type: string;
704
+ items: {
705
+ type: string;
706
+ };
707
+ maxItems: number;
708
+ description: string;
709
+ };
710
+ targetScheduledSends: {
711
+ type: string;
712
+ minimum: number;
713
+ maximum: number;
714
+ description: string;
715
+ };
716
+ approvalMode: {
717
+ type: string;
718
+ enum: string[];
719
+ description: string;
720
+ };
721
+ yolo: {
722
+ type: string;
723
+ description: string;
724
+ };
725
+ planRevision: {
726
+ type: string;
727
+ description: string;
728
+ };
729
+ actionIds: {
730
+ type: string;
731
+ items: {
732
+ type: string;
733
+ };
734
+ description: string;
735
+ };
736
+ };
737
+ additionalProperties: boolean;
738
+ };
550
739
  } | {
551
740
  name: string;
552
741
  description: string;
@@ -2,8 +2,11 @@ import { authToolDefinitions } from "./auth.js";
2
2
  import { blueprintCommitToolDefinitions } from "./blueprint-commit.js";
3
3
  import { bootstrapToolDefinitions } from "./bootstrap.js";
4
4
  import { campaignAbTestToolDefinitions } from "./campaign-ab-test.js";
5
+ import { campaignFillRoutingToolDefinitions } from "./campaign-fill-routing.js";
6
+ import { campaignHorizonFillToolDefinitions } from "./campaign-horizon-fill.js";
5
7
  import { campaignMessagePreparationToolDefinitions } from "./campaign-message-preparation.js";
6
8
  import { campaignProcessingToolDefinitions } from "./campaign-processing.js";
9
+ import { refillCampaignSendsToolDefinitions } from "./refill-campaign-sends.js";
7
10
  import { campaignToolDefinitions } from "./campaigns.js";
8
11
  import { cellToolDefinitions } from "./cells.js";
9
12
  import { startCliLoginToolDef, waitForCliLoginToolDef } from "./cli-login.js";
@@ -42,6 +45,9 @@ import { workspaceToolDefinitions } from "./workspaces.js";
42
45
  export const allTools = [
43
46
  ...campaignToolDefinitions,
44
47
  ...campaignAbTestToolDefinitions,
48
+ ...campaignFillRoutingToolDefinitions,
49
+ ...refillCampaignSendsToolDefinitions,
50
+ ...campaignHorizonFillToolDefinitions,
45
51
  ...campaignMessagePreparationToolDefinitions,
46
52
  ...campaignProcessingToolDefinitions,
47
53
  ...authToolDefinitions,
@@ -1,6 +1,10 @@
1
1
  export interface WorkflowTableListItem {
2
2
  id: string;
3
3
  name: string;
4
+ workspaceId: string | null;
5
+ status: string | null;
6
+ campaignStatus: string | null;
7
+ dashboardBucket: "active" | "archived";
4
8
  type: string | null;
5
9
  campaignOfferId: string | null;
6
10
  campaignBacked: boolean;
@@ -6,7 +6,7 @@ import { getApi } from "../api.js";
6
6
  export const tableToolDefinitions = [
7
7
  {
8
8
  name: "list_tables",
9
- description: "List all workflow tables in the active workspace. Returns metadata including whether each table is campaign-backed and whether it has a sequence attached.\n\n" +
9
+ description: "List all workflow tables in the active workspace. Returns metadata including workspaceId, workflow status, campaignStatus, dashboardBucket, whether each table is campaign-backed, and whether it has a sequence attached.\n\n" +
10
10
  "Unlike get_campaigns, this lists every WorkflowTable regardless of how it was created, including create_workflow_table, create_on_demand_table, and UI-created tables.",
11
11
  inputSchema: {
12
12
  type: "object",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.336",
3
+ "version": "0.1.337",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -47,6 +47,9 @@ allowed-tools:
47
47
  - mcp__sellable__record_campaign_review_batch
48
48
  - mcp__sellable__queue_campaign_cells
49
49
  - mcp__sellable__wait_for_campaign_processing
50
+ - mcp__sellable__refill_campaign_sends
51
+ - mcp__sellable__resolve_campaign_fill_route
52
+ - mcp__sellable__fill_campaign_horizon
50
53
  - mcp__sellable__start_campaign_message_preparation
51
54
  - mcp__sellable__get_campaign_message_preparation_status
52
55
  - mcp__sellable__cancel_campaign_message_preparation
@@ -113,27 +116,46 @@ source only when safe relaxation and same-source sampling would still fail or
113
116
  would pass bad-fit rows.
114
117
  The default path stays the existing first campaign-table execution slice:
115
118
  review the normal `reviewBatchLimit:15`, approve reviewed draft rows, then move
116
- to Settings/sequence/final greenlight. Only call
117
- `start_campaign_message_preparation` when the user explicitly asks for more
118
- prepared messages, a send count, or language like "fill up/load sends for these
119
- senders." Treat those requests as capacity-fill preparation: calculate the
120
- bounded target from sender capacity when needed, then let the preparation job
121
- queue pending `Enrich Prospect` cells, wait for ICP/rubric and Generate Message
122
- cells to cascade, and mark ready or approve only the target cohort. Do not
123
- count `checkedRows` as enriched rows; it is only the table cursor. Use
119
+ to Settings/sequence/final greenlight. For any plain post-mint fill request
120
+ such as "fill campaigns", "fill up", "refill sends", "max out sends", or
121
+ "load sends", first call `refill_campaign_sends({ mode:"plan", intent:"plain" })`.
122
+ If the user did not include `--yolo`, report the plan and stop. If the user did
123
+ include `--yolo`, call plan first, inspect blockers, then call
124
+ `refill_campaign_sends({ mode:"apply", yolo:true, planRevision, actionIds })`
125
+ using only the selected immutable action IDs from the fresh plan. Plain fill is
126
+ not an alias for `fill_campaign_horizon` or campaign creation. Keep
127
+ `resolve_campaign_fill_route`, `fill_campaign_horizon`, and
128
+ `start_campaign_message_preparation` as fallback/lower-level diagnostics only
129
+ when `refill_campaign_sends` is unavailable or when the refill command itself
130
+ returns an evergreen subplan. `fill_campaign_horizon` is evergreen-only and
131
+ must not be used for regular campaign refill. When more leads are needed, the
132
+ plan must recommend same-campaign source-ladder replenishment; do not create
133
+ warm-post-engager side campaigns, on-demand campaigns, or unrelated campaigns.
134
+ If fallback `resolve_campaign_fill_route` returns `route:"ask_create"`, ask
135
+ whether to create a normal campaign or evergreen campaigns; campaign creation is
136
+ never the default response to plain fill.
137
+ Treat active fills as capacity-fill preparation: calculate the bounded target
138
+ from sender capacity when needed, then let the preparation job queue pending
139
+ `Enrich Prospect` cells, wait for ICP/rubric and Generate Message cells to
140
+ cascade, and mark ready or approve only the target cohort. Do not count
141
+ `checkedRows` as enriched rows; it is only the table cursor. Use
124
142
  `progress.enrichedRows`, `progress.needsEnrichRows`, `activeCellCount`,
125
- `preparedMessages`, `approvedRows`, target, estimated row budget remaining, and
126
- `stopReason` to explain progress. If the user says "prepare/generate X
127
- messages", set `targetPreparedMessages:X`, omit `maxRowsToCheck`, and keep
143
+ `preparedMessages`, `approvedRows`, active preparation jobs, sender-health
144
+ blockers, target, estimated row budget remaining, and `stopReason` to explain
145
+ progress. If the user says "prepare/generate X messages", set
146
+ `targetPreparedMessages:X`, omit `maxRowsToCheck`, and keep
128
147
  `approvalMode:"mark_ready"`. The backend calibrates on at least 100 actually
129
148
  enriched rows, estimates the row budget from observed rubric/pass yield, caps
130
- `maxRowsToCheck` at 2500, then adapts later batches up to 250 rows while
131
- recalculating yield. If the user says "approve X messages", use
149
+ `maxRowsToCheck` at 300, then continues in batches capped at 100 newly checked
150
+ rows. It will not pull another row batch while the current checked batch still
151
+ has queueable or active cells. If the user says "approve X messages", use
132
152
  `approvalMode:"approve"` but still do not launch. If the user says "schedule X
133
- sends" or asks to fill sender sends, use `approvalMode:"approve"` to approve
134
- exactly the bounded X-message cohort during preparation, then continue through
135
- sender, sequence, and final launch greenlight; the launch path must verify that
136
- bounded cohort and must not broad approve-all.
153
+ sends" or asks to fill sender sends, use `approvalMode:"approve"` only when
154
+ the user explicitly asked for approval, approve exactly the bounded X-message
155
+ cohort during preparation, then re-read scheduled counts; if scheduler-owned
156
+ cells are not present, report prepared/approved/ready awaiting scheduler
157
+ instead of success. Final launch remains a separate explicit user greenlight
158
+ and must verify that bounded cohort and must not broad approve-all.
137
159
  When approving reviewed draft rows in the campaign table, resolve the actual
138
160
  visible `Approved` cells with `select_campaign_cells({ columnRole: "approved",
139
161
  rowSelector: { type: "rowIds", rowIds } })` and `update_cell` those returned
@@ -891,7 +913,11 @@ updates.
891
913
 
892
914
  1. Call `mcp__sellable__get_auth_status({})`.
893
915
  2. If auth is not OK with `error.type === "config"` or `error.type === "auth"`,
894
- the user has not signed in yet. Run the FTUX magic-link handoff:
916
+ the user has not signed in yet. Run first-run login through the FTUX
917
+ magic-link handoff. If a browser page or tool guidance gives the user a
918
+ manual fallback, it must be
919
+ `sellable auth set <token> --workspace-id <workspace_id>`. Do not instruct
920
+ the user to hand-edit JSON auth config.
895
921
 
896
922
  a. Say to the user verbatim:
897
923