@sellable/mcp 0.1.470 → 0.1.471

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/server.js CHANGED
@@ -11,6 +11,7 @@ import { fillCampaignHorizon } from "./tools/campaign-horizon-fill.js";
11
11
  import { cancelPrepareCampaignMessages, getPrepareCampaignMessagesStatus, startPrepareCampaignMessages, } from "./tools/campaign-message-preparation.js";
12
12
  import { getCampaignRefillState } from "./tools/campaign-refill-state.js";
13
13
  import { getRefillTargetPlan } from "./tools/refill-target-plan.js";
14
+ import { getSchedulerFillCapacity } from "./tools/scheduler-fill-capacity.js";
14
15
  import { getCampaignTableSchema, queueCampaignCells, recordCampaignReviewBatch, reviseMessageTemplateAndRerun, selectCampaignCells, waitForCampaignProcessing, } from "./tools/campaign-processing.js";
15
16
  import { archiveCampaign, createCampaign, duplicateCampaign, getCampaign, getCampaignMessagesPreview, getCampaigns, pauseCampaign, startCampaign, updateCampaign, updateCampaignBrief, } from "./tools/campaigns.js";
16
17
  import { queueCells, updateCell } from "./tools/cells.js";
@@ -225,6 +226,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
225
226
  case "get_refill_target_plan":
226
227
  result = await getRefillTargetPlan(args);
227
228
  break;
229
+ case "get_scheduler_fill_capacity":
230
+ result = await getSchedulerFillCapacity(args);
231
+ break;
228
232
  case "refill_sends":
229
233
  result = refillSendsCommand(args);
230
234
  break;
@@ -7,6 +7,7 @@ type RefillSendsCommandInput = {
7
7
  senderNames?: string[];
8
8
  horizonSendDays?: number;
9
9
  untilDate?: string;
10
+ targetDate?: string;
10
11
  campaignId?: string;
11
12
  tableId?: string;
12
13
  intent?: RefillSendsIntent;
@@ -54,6 +55,11 @@ export declare const refillSendsToolDefinitions: {
54
55
  pattern: string;
55
56
  description: string;
56
57
  };
58
+ targetDate: {
59
+ type: string;
60
+ pattern: string;
61
+ description: string;
62
+ };
57
63
  campaignId: {
58
64
  type: string;
59
65
  description: string;
@@ -84,12 +90,21 @@ export declare function refillSendsCommand(input?: RefillSendsCommandInput): {
84
90
  workflowPromptName: string;
85
91
  yolo: boolean;
86
92
  intent: RefillSendsIntent;
93
+ targetDate: string | null;
87
94
  untilDate: string | null;
88
95
  horizonSendDays: number | null;
89
96
  fillWindow: {
97
+ mode: string;
98
+ targetDate: string;
99
+ description: string;
100
+ untilDate?: undefined;
101
+ horizonSendDays?: undefined;
102
+ horizonHours?: undefined;
103
+ } | {
90
104
  mode: string;
91
105
  untilDate: string;
92
106
  description: string;
107
+ targetDate?: undefined;
93
108
  horizonSendDays?: undefined;
94
109
  horizonHours?: undefined;
95
110
  } | {
@@ -97,6 +112,7 @@ export declare function refillSendsCommand(input?: RefillSendsCommandInput): {
97
112
  horizonSendDays: number | null;
98
113
  horizonHours: number | null;
99
114
  description: string;
115
+ targetDate?: undefined;
100
116
  untilDate?: undefined;
101
117
  };
102
118
  approvalMode: RefillSendsApprovalMode;
@@ -121,6 +137,7 @@ export declare function refillSendsCommand(input?: RefillSendsCommandInput): {
121
137
  senders: string[];
122
138
  senderIds: string[];
123
139
  senderNames: string[];
140
+ targetDate: string | null;
124
141
  untilDate: string | null;
125
142
  horizonSendDays: number | null;
126
143
  campaignId: string | undefined;
@@ -34,6 +34,25 @@ function normalizeUntilDate(value) {
34
34
  }
35
35
  return trimmed;
36
36
  }
37
+ function normalizeTargetDate(value) {
38
+ if (value === undefined || value === null || value === "")
39
+ return null;
40
+ if (typeof value !== "string") {
41
+ throw new Error("targetDate must be a string in YYYY-MM-DD format.");
42
+ }
43
+ const trimmed = value.trim();
44
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) {
45
+ throw new Error("targetDate must use YYYY-MM-DD format.");
46
+ }
47
+ const [year, month, day] = trimmed.split("-").map((part) => Number(part));
48
+ const parsed = new Date(Date.UTC(year, month - 1, day));
49
+ if (parsed.getUTCFullYear() !== year ||
50
+ parsed.getUTCMonth() !== month - 1 ||
51
+ parsed.getUTCDate() !== day) {
52
+ throw new Error("targetDate must be a valid calendar date.");
53
+ }
54
+ return trimmed;
55
+ }
37
56
  export const refillSendsToolDefinitions = [
38
57
  {
39
58
  name: "refill_sends",
@@ -71,6 +90,11 @@ export const refillSendsToolDefinitions = [
71
90
  pattern: "^\\d{4}-\\d{2}-\\d{2}$",
72
91
  description: "Optional sender-local YYYY-MM-DD date to fill through, inclusive. Overrides the default scheduler-forward 48-hour target window.",
73
92
  },
93
+ targetDate: {
94
+ type: "string",
95
+ pattern: "^\\d{4}-\\d{2}-\\d{2}$",
96
+ description: "Optional exact sender-local YYYY-MM-DD date to fill. This prepares rows only for scheduler-fillable slots on that date and is distinct from untilDate.",
97
+ },
74
98
  campaignId: {
75
99
  type: "string",
76
100
  description: "Optional exact CampaignOffer.id to narrow routing. Do not pass campaign names.",
@@ -101,8 +125,9 @@ export function refillSendsCommand(input = {}) {
101
125
  const senderNames = normalizeStrings(input.senderNames);
102
126
  const hasSenderSelectors = senders.length > 0 || senderIds.length > 0 || senderNames.length > 0;
103
127
  const yolo = input.yolo === true;
104
- const untilDate = normalizeUntilDate(input.untilDate);
105
- const horizonSendDays = untilDate
128
+ const targetDate = normalizeTargetDate(input.targetDate);
129
+ const untilDate = targetDate ? null : normalizeUntilDate(input.untilDate);
130
+ const horizonSendDays = targetDate || untilDate
106
131
  ? null
107
132
  : normalizeHorizonSendDays(input.horizonSendDays);
108
133
  const intent = input.intent ?? "plain";
@@ -119,24 +144,31 @@ export function refillSendsCommand(input = {}) {
119
144
  workflowPromptName: "refill-sends-workflow",
120
145
  yolo,
121
146
  intent,
147
+ targetDate,
122
148
  untilDate,
123
149
  horizonSendDays,
124
- fillWindow: untilDate
150
+ fillWindow: targetDate
125
151
  ? {
126
- mode: "until_date",
127
- untilDate,
128
- description: "Fill through this sender-local date inclusive, skipping no-send days and never extending beyond the date without a new packet.",
152
+ mode: "target_date",
153
+ targetDate,
154
+ description: "Fill only this sender-local date by preparing rows for scheduler-fillable slots on that date.",
129
155
  }
130
- : {
131
- mode: horizonSendDays === null
132
- ? "scheduler_forward_48h"
133
- : "horizon_send_days",
134
- horizonSendDays,
135
- horizonHours: horizonSendDays === null ? DEFAULT_SCHEDULER_FORWARD_HOURS : null,
136
- description: horizonSendDays === null
137
- ? "Fill the default scheduler-forward 48-hour target window."
138
- : "Fill the explicit compatibility horizon by sender-local send days.",
139
- },
156
+ : untilDate
157
+ ? {
158
+ mode: "until_date",
159
+ untilDate,
160
+ description: "Fill through this sender-local date inclusive, skipping no-send days and never extending beyond the date without a new packet.",
161
+ }
162
+ : {
163
+ mode: horizonSendDays === null
164
+ ? "scheduler_forward_48h"
165
+ : "horizon_send_days",
166
+ horizonSendDays,
167
+ horizonHours: horizonSendDays === null ? DEFAULT_SCHEDULER_FORWARD_HOURS : null,
168
+ description: horizonSendDays === null
169
+ ? "Fill the default scheduler-forward 48-hour target window."
170
+ : "Fill the explicit compatibility horizon by sender-local send days.",
171
+ },
140
172
  approvalMode,
141
173
  campaignId: input.campaignId ?? null,
142
174
  tableId: input.tableId ?? null,
@@ -153,22 +185,26 @@ export function refillSendsCommand(input = {}) {
153
185
  ? `, senderIds: ${JSON.stringify(senderIds)}`
154
186
  : ""}${senderNames.length > 0
155
187
  ? `, senderNames: ${JSON.stringify(senderNames)}`
156
- : ""}${senders.length > 0 ? `, senders: ${JSON.stringify(senders)}` : ""}${untilDate
157
- ? `, untilDate: "${untilDate}"`
158
- : horizonSendDays === null
159
- ? ""
160
- : `, horizonSendDays: ${horizonSendDays}`}, approvalMode: "${approvalMode}" }) before any import, prep, approval, start, or schedule-affecting action.`,
188
+ : ""}${senders.length > 0 ? `, senders: ${JSON.stringify(senders)}` : ""}${targetDate
189
+ ? `, targetDate: "${targetDate}"`
190
+ : untilDate
191
+ ? `, untilDate: "${untilDate}"`
192
+ : horizonSendDays === null
193
+ ? ""
194
+ : `, horizonSendDays: ${horizonSendDays}`}, approvalMode: "${approvalMode}" }) before any import, prep, approval, start, or schedule-affecting action.`,
161
195
  "If get_refill_target_plan returns status complete, report eligible sender ledger, gross target, selected days, sent count, scheduled count, projected count, campaign ids, targetShapeRevision, and no-op proof without asking for approval.",
162
196
  "Refill target lanes are only connection invites (send_invite) or paid InMails (send_inmail_closed). Do not count send_dm or send_inmail_open as horizon target capacity; they may exist in sequences, but the planner must pick the refill lane from the most recent active campaign-backed send evidence for each sender.",
163
197
  "If remainingReadyOrProjectedGap is 0 but remainingProjectedGap is positive, run only a persistent read-only scheduler wait/reread loop; do not ask for prep/import/approval and do not close out while scheduler pickup is the only remaining state.",
164
198
  `Resolve route with resolve_campaign_fill_route({ intent: "${intent}"${input.campaignId ? `, campaignId: "${input.campaignId}"` : ""}${input.tableId ? `, tableId: "${input.tableId}"` : ""} }).`,
165
199
  'If the plain route shows stale managed waterfall evidence, archived/completed shared slots, or targets that do not cover the selected sender set, immediately call resolve_campaign_fill_route({ intent: "active" }) and inspect current dashboard-active ACTIVE/PAUSED campaign-backed sequence campaigns before declaring a sender blocked.',
166
200
  "Call list_senders and get_sender_routing, then resolve sender selectors against active enrolled campaign-backed sequence senders.",
167
- untilDate
168
- ? `Use fill window untilDate="${untilDate}" as the inclusive sender-local through date; do not extend beyond that date without a new approval packet.`
169
- : horizonSendDays === null
170
- ? "Use the default scheduler-forward 48-hour target window from get_refill_target_plan; do not reinterpret it as two calendar days from today."
171
- : `Use the explicit compatibility fill window of ${horizonSendDays} sender-local send days.`,
201
+ targetDate
202
+ ? `Use fill window targetDate="${targetDate}" as one exact sender-local date; prepare rows only for scheduler-fillable slots on that date. Do not treat it as an inclusive through-date.`
203
+ : untilDate
204
+ ? `Use fill window untilDate="${untilDate}" as the inclusive sender-local through date; do not extend beyond that date without a new approval packet.`
205
+ : horizonSendDays === null
206
+ ? "Use the default scheduler-forward 48-hour target window from get_refill_target_plan; do not reinterpret it as two calendar days from today."
207
+ : `Use the explicit compatibility fill window of ${horizonSendDays} sender-local send days.`,
172
208
  "Read get_campaign_refill_state for enough exact candidate campaigns to pick the best per-sender target by recent/future scheduler-owned sends, then recent result evidence, then source health.",
173
209
  "Treat current dashboard-active PAUSED campaign-backed sequence campaigns as start-eligible candidates: read refill state before deciding whether to prep, approve, start, or skip.",
174
210
  "Fresh reread get_campaign_refill_state immediately before any import, prep, approval, or horizon-fill mutation.",
@@ -196,11 +232,13 @@ export function refillSendsCommand(input = {}) {
196
232
  hostExamples: {
197
233
  claude: [
198
234
  "/sellable:refill-sends --yolo",
235
+ "/sellable:refill-sends --yolo --target-date 2026-07-01",
199
236
  "/sellable:refill-sends --yolo --until 2026-06-30",
200
237
  '/sellable:refill-sends --sender "Christian Reyes" --sender "Thomas Nobbs"',
201
238
  ],
202
239
  codex: [
203
240
  "$sellable:refill-sends --yolo",
241
+ "$sellable:refill-sends --yolo --target-date 2026-07-01",
204
242
  "$sellable:refill-sends --yolo --until 2026-06-30",
205
243
  '$sellable:refill-sends --sender "Christian Reyes" --sender "Thomas Nobbs"',
206
244
  ],
@@ -211,6 +249,7 @@ export function refillSendsCommand(input = {}) {
211
249
  senders,
212
250
  senderIds,
213
251
  senderNames,
252
+ targetDate,
214
253
  untilDate,
215
254
  horizonSendDays,
216
255
  campaignId: input.campaignId,
@@ -4,6 +4,7 @@ type GetRefillTargetPlanInput = {
4
4
  intent?: RefillTargetPlanIntent;
5
5
  horizonSendDays?: number;
6
6
  untilDate?: string;
7
+ targetDate?: string;
7
8
  campaignId?: string;
8
9
  tableId?: string;
9
10
  senderIds?: string[];
@@ -34,6 +35,11 @@ export declare const refillTargetPlanToolDefinitions: {
34
35
  pattern: string;
35
36
  description: string;
36
37
  };
38
+ targetDate: {
39
+ type: string;
40
+ pattern: string;
41
+ description: string;
42
+ };
37
43
  campaignId: {
38
44
  type: string;
39
45
  description: string;
@@ -252,6 +252,11 @@ export const refillTargetPlanToolDefinitions = [
252
252
  pattern: "^\\d{4}-\\d{2}-\\d{2}$",
253
253
  description: "Optional sender-local YYYY-MM-DD date to inspect through, inclusive. Overrides the default scheduler-forward 48-hour target window.",
254
254
  },
255
+ targetDate: {
256
+ type: "string",
257
+ pattern: "^\\d{4}-\\d{2}-\\d{2}$",
258
+ description: "Optional exact sender-local YYYY-MM-DD date to fill. Distinct from untilDate: targetDate asks how many scheduler-fillable slots exist on only this date.",
259
+ },
255
260
  campaignId: {
256
261
  type: "string",
257
262
  description: "Optional exact CampaignOffer.id to narrow routing. Do not pass campaign names.",
@@ -299,6 +304,7 @@ export async function getRefillTargetPlan(input = {}) {
299
304
  intent: input.intent,
300
305
  horizonSendDays: input.horizonSendDays,
301
306
  untilDate: input.untilDate,
307
+ targetDate: input.targetDate,
302
308
  campaignId: input.campaignId,
303
309
  tableId: input.tableId,
304
310
  senderIds: input.senderIds,
@@ -660,6 +660,55 @@ export declare const allTools: ({
660
660
  additionalProperties: boolean;
661
661
  required?: undefined;
662
662
  };
663
+ } | {
664
+ name: string;
665
+ description: string;
666
+ inputSchema: {
667
+ type: string;
668
+ properties: {
669
+ capacityRequests: {
670
+ type: string;
671
+ minItems: number;
672
+ items: {
673
+ type: string;
674
+ properties: {
675
+ senderId: {
676
+ type: string;
677
+ description: string;
678
+ };
679
+ actionType: {
680
+ type: string;
681
+ enum: string[];
682
+ description: string;
683
+ };
684
+ cellId: {
685
+ type: string;
686
+ description: string;
687
+ };
688
+ columnId: {
689
+ type: string;
690
+ description: string;
691
+ };
692
+ };
693
+ required: string[];
694
+ additionalProperties: boolean;
695
+ };
696
+ description: string;
697
+ };
698
+ targetDate: {
699
+ type: string;
700
+ pattern: string;
701
+ description: string;
702
+ };
703
+ mode: {
704
+ type: string;
705
+ enum: string[];
706
+ description: string;
707
+ };
708
+ };
709
+ required: string[];
710
+ additionalProperties: boolean;
711
+ };
663
712
  } | {
664
713
  name: string;
665
714
  description: string;
@@ -37,6 +37,7 @@ import { refillTargetPlanToolDefinitions } from "./refill-target-plan.js";
37
37
  import { refillSendsToolDefinitions } from "./refill-sends.js";
38
38
  import { rowToolDefinitions } from "./rows.js";
39
39
  import { rubricToolDefinitions } from "./rubrics.js";
40
+ import { schedulerFillCapacityToolDefinitions } from "./scheduler-fill-capacity.js";
40
41
  import { senderRoutingToolDefinitions } from "./sender-routing.js";
41
42
  import { senderToolDefinitions } from "./senders.js";
42
43
  import { sequencerToolDefinitions } from "./sequencer.js";
@@ -52,6 +53,7 @@ export const allTools = [
52
53
  ...campaignFillRoutingToolDefinitions,
53
54
  ...campaignRefillStateToolDefinitions,
54
55
  ...refillTargetPlanToolDefinitions,
56
+ ...schedulerFillCapacityToolDefinitions,
55
57
  ...refillSendsToolDefinitions,
56
58
  ...setupEvergreenCampaignsToolDefinitions,
57
59
  ...campaignHorizonFillToolDefinitions,
@@ -0,0 +1,65 @@
1
+ type SchedulerFillCapacityActionType = "send_invite" | "send_inmail_closed" | "send_inmail_open" | "send_dm" | "react_and_comment";
2
+ type SchedulerFillCapacityMode = "default_horizon" | "target_date";
3
+ type SchedulerFillCapacityRequest = {
4
+ senderId: string;
5
+ actionType: SchedulerFillCapacityActionType;
6
+ cellId?: string;
7
+ columnId?: string;
8
+ };
9
+ type GetSchedulerFillCapacityInput = {
10
+ capacityRequests: SchedulerFillCapacityRequest[];
11
+ targetDate?: string;
12
+ mode?: SchedulerFillCapacityMode;
13
+ };
14
+ export declare const schedulerFillCapacityToolDefinitions: {
15
+ name: string;
16
+ description: string;
17
+ inputSchema: {
18
+ type: string;
19
+ properties: {
20
+ capacityRequests: {
21
+ type: string;
22
+ minItems: number;
23
+ items: {
24
+ type: string;
25
+ properties: {
26
+ senderId: {
27
+ type: string;
28
+ description: string;
29
+ };
30
+ actionType: {
31
+ type: string;
32
+ enum: string[];
33
+ description: string;
34
+ };
35
+ cellId: {
36
+ type: string;
37
+ description: string;
38
+ };
39
+ columnId: {
40
+ type: string;
41
+ description: string;
42
+ };
43
+ };
44
+ required: string[];
45
+ additionalProperties: boolean;
46
+ };
47
+ description: string;
48
+ };
49
+ targetDate: {
50
+ type: string;
51
+ pattern: string;
52
+ description: string;
53
+ };
54
+ mode: {
55
+ type: string;
56
+ enum: string[];
57
+ description: string;
58
+ };
59
+ };
60
+ required: string[];
61
+ additionalProperties: boolean;
62
+ };
63
+ }[];
64
+ export declare function getSchedulerFillCapacity(input: GetSchedulerFillCapacityInput): Promise<unknown>;
65
+ export {};
@@ -0,0 +1,70 @@
1
+ import { getApi } from "../api.js";
2
+ async function postSchedulerFillCapacity(body) {
3
+ const api = getApi();
4
+ return api.post("/api/v3/mcp/scheduler-fill-capacity", body);
5
+ }
6
+ export const schedulerFillCapacityToolDefinitions = [
7
+ {
8
+ name: "get_scheduler_fill_capacity",
9
+ description: "read-only scheduler capacity query for refill-sends before any refill mutation. It asks the product scheduler model how many additional cells the scheduler will try to place for exact sender/action requests, using the default scheduler-forward horizon or one exact targetDate. It returns scheduler-fillable slots, occupied scheduled/processing slots, sender sendability gates, cooldowns, Sales Navigator status for paid InMail, cached paid-InMail credit feasibility, threshold source, blockers, warnings, and explicit sideEffects false. This tool does not create rows, import leads, prepare messages, approve messages, does not schedule sends, does not refresh paid InMail credits, mutate thresholds, start campaigns, launch, or send. Use exact senderId values only; never pass sender names.",
10
+ inputSchema: {
11
+ type: "object",
12
+ properties: {
13
+ capacityRequests: {
14
+ type: "array",
15
+ minItems: 1,
16
+ items: {
17
+ type: "object",
18
+ properties: {
19
+ senderId: {
20
+ type: "string",
21
+ description: "Exact Sender.id to inspect. Do not pass sender names.",
22
+ },
23
+ actionType: {
24
+ type: "string",
25
+ enum: [
26
+ "send_invite",
27
+ "send_inmail_closed",
28
+ "send_inmail_open",
29
+ "send_dm",
30
+ "react_and_comment",
31
+ ],
32
+ description: "Exact scheduler action lane to inspect for this sender.",
33
+ },
34
+ cellId: {
35
+ type: "string",
36
+ description: "Optional exact WorkflowTableCell.id for paid-InMail threshold context. Invalid scoped ids block instead of falling back to defaults.",
37
+ },
38
+ columnId: {
39
+ type: "string",
40
+ description: "Optional exact WorkflowTableColumn.id for paid-InMail threshold context. Invalid scoped ids block instead of falling back to defaults.",
41
+ },
42
+ },
43
+ required: ["senderId", "actionType"],
44
+ additionalProperties: false,
45
+ },
46
+ description: "One or more exact sender/action capacity requests. Example: [{ senderId:'snd_...', actionType:'send_invite' }].",
47
+ },
48
+ targetDate: {
49
+ type: "string",
50
+ pattern: "^\\d{4}-\\d{2}-\\d{2}$",
51
+ description: "Optional sender-local YYYY-MM-DD date to inspect. When present, the query uses target_date mode.",
52
+ },
53
+ mode: {
54
+ type: "string",
55
+ enum: ["default_horizon", "target_date"],
56
+ description: "Optional mode hint. Omit for default_horizon; target_date requires targetDate.",
57
+ },
58
+ },
59
+ required: ["capacityRequests"],
60
+ additionalProperties: false,
61
+ },
62
+ },
63
+ ];
64
+ export function getSchedulerFillCapacity(input) {
65
+ return postSchedulerFillCapacity({
66
+ capacityRequests: input.capacityRequests,
67
+ targetDate: input.targetDate,
68
+ mode: input.mode,
69
+ });
70
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellable/mcp",
3
- "version": "0.1.470",
3
+ "version": "0.1.471",
4
4
  "type": "module",
5
5
  "description": "Sellable MCP server for Claude Code and Codex campaign workflows",
6
6
  "main": "dist/index.js",
@@ -5,6 +5,7 @@ visibility: public
5
5
  allowed-tools:
6
6
  - mcp__sellable__refill_sends
7
7
  - mcp__sellable__get_refill_target_plan
8
+ - mcp__sellable__get_scheduler_fill_capacity
8
9
  - mcp__sellable__refresh_paid_inmail_credits
9
10
  - mcp__sellable__get_auth_status
10
11
  - mcp__sellable__start_cli_login
@@ -71,16 +72,21 @@ Accepted invocation flags in the same user request:
71
72
  senders.
72
73
  - `--until <YYYY-MM-DD>`: fill through that sender-local date, inclusive,
73
74
  instead of the default scheduler-forward 48-hour target window.
75
+ - `--target-date <YYYY-MM-DD>`: fill only that sender-local date. This means
76
+ prepare rows for scheduler-fillable slots on that date, not every remaining
77
+ daily-limit slot and not an inclusive through-date.
74
78
  - `senderIds: <id>, <id>` or `senderNames: <name>, <name>`: explicit selector
75
79
  alternatives when the host preserves natural-language arguments better than
76
80
  shell-style flags.
77
81
  - `untilDate: YYYY-MM-DD`: explicit date selector alternative when the host
78
82
  preserves natural-language arguments better than shell-style flags.
83
+ - `targetDate: YYYY-MM-DD`: exact-date selector alternative when the host
84
+ preserves natural-language arguments better than shell-style flags.
79
85
 
80
86
  When the host can call typed MCP tools, start with:
81
87
 
82
88
  ```text
83
- refill_sends({ yolo?: boolean, senders?: string[], senderIds?: string[], senderNames?: string[], horizonSendDays?: number, untilDate?: "YYYY-MM-DD" })
89
+ refill_sends({ yolo?: boolean, senders?: string[], senderIds?: string[], senderNames?: string[], horizonSendDays?: number, untilDate?: "YYYY-MM-DD", targetDate?: "YYYY-MM-DD" })
84
90
  ```
85
91
 
86
92
  That command helper only normalizes arguments and returns the execution
@@ -137,6 +143,11 @@ two lanes to fill. If a stale target plan selects `send_dm` or
137
143
  `send_inmail_open`, stop and re-plan with the current planner before mutation.
138
144
  Short form: trust the target plan's inferred lane only when it is a
139
145
  connection-invite or paid-InMail refill lane.
146
+ For exact-date requests, pass `targetDate` to `get_refill_target_plan`. If you
147
+ need raw proof, call the read-only `get_scheduler_fill_capacity` query for the
148
+ same sender/action/date; it tells the MCP how many cells the product scheduler
149
+ will try to place and does not import, approve, schedule, refresh credits, or
150
+ mutate.
140
151
  If the target plan is complete by projected coverage, report that the selected
141
152
  target is already filled and no-op without asking for approval. If the ready
142
153
  buffer covers the projected gap but scheduled coverage is still short, keep the
@@ -229,8 +240,10 @@ blocked only because it is still `awaiting_scheduler_after_ready_buffer`; keep
229
240
  waiting unless Christian stops the run or the host cannot continue.
230
241
 
231
242
  In `--yolo`, the default fill target is the scheduler-forward 48-hour window
232
- unless `--until`/`untilDate` or an explicit compatibility `horizonSendDays` is
233
- provided. If an until date is provided, compute bounded gaps through that
243
+ unless `--target-date`/`targetDate`, `--until`/`untilDate`, or an explicit
244
+ compatibility `horizonSendDays` is provided. If a target date is provided,
245
+ compute bounded gaps for only that sender-local date using scheduler-fillable
246
+ slots. If an until date is provided, compute bounded gaps through that
234
247
  sender-local date inclusive, skipping no-send days and never extending beyond
235
248
  that date without a new packet. For each target sender, compute the bounded gap
236
249
  from that sender's healthy daily capacity, existing future scheduler-owned
@@ -4,6 +4,7 @@ description: Internal skill-led refill sends workflow for regular campaigns and
4
4
  visibility: internal
5
5
  allowed-tools:
6
6
  - mcp__sellable__get_refill_target_plan
7
+ - mcp__sellable__get_scheduler_fill_capacity
7
8
  - mcp__sellable__refresh_paid_inmail_credits
8
9
  - mcp__sellable__list_senders
9
10
  - mcp__sellable__get_sender_routing
@@ -88,6 +89,12 @@ in-progress wait state, not a reason to mark the goal complete or blocked.
88
89
  mutation.
89
90
  Short form: trust the target plan's inferred lane only when it is a
90
91
  connection-invite or paid-InMail refill lane.
92
+ For exact-date requests, pass `targetDate` to `get_refill_target_plan`.
93
+ When you need raw diagnostic proof, call `get_scheduler_fill_capacity` for
94
+ the same exact sender/action/date. That query is read-only and tells the MCP
95
+ how many cells the product scheduler will try to place for that sender; it
96
+ does not create rows, import, approve, schedule, refresh paid-InMail credits,
97
+ or mutate thresholds.
91
98
  If `status:"complete"`, report the target, selected dates, sent count,
92
99
  scheduled count, projected count, campaign ids, and no-op proof without
93
100
  asking for approval or mutating.
@@ -213,24 +220,24 @@ skip a visible paused shared campaign that can be started through a bounded
213
220
  packet.
214
221
 
215
222
  Default `--yolo` target is the scheduler-forward 48-hour window when the user
216
- asks to fill, refill, load, or max sends without naming a different horizon.
223
+ asks to fill, refill, load, or max sends without naming a different horizon or
224
+ exact `targetDate`.
217
225
  The planner selects sender-local days whose configured sending windows overlap
218
226
  that rolling target window; do not treat weekends or other no-send-hour days as
219
227
  fillable capacity. If the user explicitly names a no-send calendar date, report
220
228
  that date as unschedulable and continue only for the next valid send day when
221
229
  the packet says "send days" or the user asked to max/refill senders broadly.
222
230
 
223
- For campaign-scoped requests, compute the target from the selected campaign's
224
- healthy sender daily capacity in the scheduler-forward target window, minus
225
- already scheduler-owned future scheduled sends for those days and minus rows
226
- already ready to schedule. For sender-scoped requests, compute that gap per
227
- target sender across all active enrolled campaigns for that sender; count future
228
- scheduled cells and ready-to-schedule cells in any active enrolled campaign
229
- toward that sender's gap before preparing more rows. If ready/scheduled rows
230
- already cover a sender's gap, do not add rows or prep for that sender; report
231
- that the sender is loaded, awaiting scheduler. If the gap is positive, prepare
232
- only the gap in the best same-sender campaign and keep all source-copy/prep caps
233
- tied to that target-window packet.
231
+ For campaign-scoped requests, compute the target from scheduler-fillable
232
+ capacity in the selected target window/date, not the full daily limit. For
233
+ sender-scoped requests, compute that scheduler-fillable gap per target sender
234
+ across all active enrolled campaigns for that sender; count ready-to-schedule
235
+ cells in any active enrolled campaign toward that sender's fillable gap before
236
+ preparing more rows. If ready rows already cover a sender's scheduler-fillable
237
+ gap, do not add rows or prep for that sender; report that the sender is loaded,
238
+ awaiting scheduler. If the gap is positive, prepare only the gap in the best
239
+ same-sender campaign and keep all source-copy/prep caps tied to that target
240
+ window/date packet.
234
241
  Short form: default `--yolo refill senders` target is each eligible sender's
235
242
  scheduler-forward 48-hour gap.
236
243