@sellable/mcp 0.1.470 → 0.1.472
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 +4 -0
- package/dist/tools/refill-sends.d.ts +17 -0
- package/dist/tools/refill-sends.js +65 -26
- package/dist/tools/refill-target-plan.d.ts +6 -0
- package/dist/tools/refill-target-plan.js +12 -4
- package/dist/tools/registry.d.ts +49 -0
- package/dist/tools/registry.js +2 -0
- package/dist/tools/scheduler-fill-capacity.d.ts +65 -0
- package/dist/tools/scheduler-fill-capacity.js +70 -0
- package/package.json +1 -1
- package/skills/refill-sends/SKILL.md +16 -3
- package/skills/refill-sends-workflow/SKILL.md +19 -12
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
|
|
105
|
-
const
|
|
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:
|
|
150
|
+
fillWindow: targetDate
|
|
125
151
|
? {
|
|
126
|
-
mode: "
|
|
127
|
-
|
|
128
|
-
description: "Fill
|
|
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
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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)}` : ""}${
|
|
157
|
-
? `,
|
|
158
|
-
:
|
|
159
|
-
? ""
|
|
160
|
-
:
|
|
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
|
-
|
|
168
|
-
? `Use fill window
|
|
169
|
-
:
|
|
170
|
-
?
|
|
171
|
-
:
|
|
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;
|
|
@@ -188,13 +188,15 @@ function sanitizeRefillTargetPlanResult(result) {
|
|
|
188
188
|
const remainingProjectedGap = senderPlans.reduce((sum, plan) => sum + numberValue(plan.remainingProjectedGap), 0);
|
|
189
189
|
const remainingReadyOrProjectedGap = senderPlans.reduce((sum, plan) => sum + numberValue(plan.remainingReadyOrProjectedGap), 0);
|
|
190
190
|
const blockers = sanitizeBlockers(result.blockers, selectedKeys);
|
|
191
|
-
const status = blockers.some((blocker) => ["sender_disconnected", "sender_sales_nav_disconnected"].includes(String(blocker.code)))
|
|
191
|
+
const status = blockers.some((blocker) => ["sender_disconnected", "sender_sales_nav_disconnected"].includes(String(blocker.code)))
|
|
192
192
|
? "blocked"
|
|
193
193
|
: remainingProjectedGap === 0
|
|
194
194
|
? "complete"
|
|
195
|
-
:
|
|
196
|
-
? "
|
|
197
|
-
:
|
|
195
|
+
: grossTarget <= 0
|
|
196
|
+
? "blocked"
|
|
197
|
+
: remainingReadyOrProjectedGap === 0
|
|
198
|
+
? "awaiting_scheduler_after_ready_buffer"
|
|
199
|
+
: "needs_refill";
|
|
198
200
|
return {
|
|
199
201
|
...result,
|
|
200
202
|
status,
|
|
@@ -252,6 +254,11 @@ export const refillTargetPlanToolDefinitions = [
|
|
|
252
254
|
pattern: "^\\d{4}-\\d{2}-\\d{2}$",
|
|
253
255
|
description: "Optional sender-local YYYY-MM-DD date to inspect through, inclusive. Overrides the default scheduler-forward 48-hour target window.",
|
|
254
256
|
},
|
|
257
|
+
targetDate: {
|
|
258
|
+
type: "string",
|
|
259
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2}$",
|
|
260
|
+
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.",
|
|
261
|
+
},
|
|
255
262
|
campaignId: {
|
|
256
263
|
type: "string",
|
|
257
264
|
description: "Optional exact CampaignOffer.id to narrow routing. Do not pass campaign names.",
|
|
@@ -299,6 +306,7 @@ export async function getRefillTargetPlan(input = {}) {
|
|
|
299
306
|
intent: input.intent,
|
|
300
307
|
horizonSendDays: input.horizonSendDays,
|
|
301
308
|
untilDate: input.untilDate,
|
|
309
|
+
targetDate: input.targetDate,
|
|
302
310
|
campaignId: input.campaignId,
|
|
303
311
|
tableId: input.tableId,
|
|
304
312
|
senderIds: input.senderIds,
|
package/dist/tools/registry.d.ts
CHANGED
|
@@ -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;
|
package/dist/tools/registry.js
CHANGED
|
@@ -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
|
@@ -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
|
|
233
|
-
provided. If
|
|
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
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
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
|
|