@sellable/mcp 0.1.323 → 0.1.324
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
|
@@ -41,6 +41,7 @@ import { attachRecommendedSequence, attachSequence, createWorkflowTable, } from
|
|
|
41
41
|
import { exportTableCsv, listTables } from "./tools/tables.js";
|
|
42
42
|
import { handleVerifyTableRow } from "./tools/verify-row.js";
|
|
43
43
|
import { sanitizeWatchUrlsForMcpResult } from "./tools/watch-url-security.js";
|
|
44
|
+
import { getCampaignWaterfall, setCampaignWaterfallOrder, } from "./tools/waterfalls.js";
|
|
44
45
|
import { addTeammate, createWorkspace, getActiveWorkspace, listWorkspaces, setActiveWorkspace, } from "./tools/workspaces.js";
|
|
45
46
|
import { checkForUpdates, logUpdateNotice } from "./update-check.js";
|
|
46
47
|
const server = new Server({
|
|
@@ -378,6 +379,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
378
379
|
case "verify_table_row":
|
|
379
380
|
result = await handleVerifyTableRow(args);
|
|
380
381
|
break;
|
|
382
|
+
case "get_campaign_waterfall":
|
|
383
|
+
result = await getCampaignWaterfall();
|
|
384
|
+
break;
|
|
385
|
+
case "set_campaign_waterfall_order":
|
|
386
|
+
result = await setCampaignWaterfallOrder(args);
|
|
387
|
+
break;
|
|
381
388
|
case "get_rows":
|
|
382
389
|
result = await getRows(args?.tableId, args?.rowIds);
|
|
383
390
|
break;
|
package/dist/tools/registry.d.ts
CHANGED
|
@@ -7421,6 +7421,36 @@ export declare const allTools: ({
|
|
|
7421
7421
|
};
|
|
7422
7422
|
required: string[];
|
|
7423
7423
|
};
|
|
7424
|
+
} | {
|
|
7425
|
+
readonly name: "get_campaign_waterfall";
|
|
7426
|
+
readonly description: "Read the active workspace's managed-campaign waterfall hierarchy: each waterfall (per sender or shared) with its campaign slots in stored priority order. Use this before fill-send-horizon runs to follow the configured lane order, or when the user asks what order their campaigns fill in. Returns empty when the workspace has no managed-campaign program (the hierarchy is created by evergreen reconcile).";
|
|
7427
|
+
readonly inputSchema: {
|
|
7428
|
+
readonly type: "object";
|
|
7429
|
+
readonly properties: {};
|
|
7430
|
+
readonly required: readonly [];
|
|
7431
|
+
readonly additionalProperties: false;
|
|
7432
|
+
};
|
|
7433
|
+
} | {
|
|
7434
|
+
readonly name: "set_campaign_waterfall_order";
|
|
7435
|
+
readonly description: "Reorder one waterfall's campaign slots — the stored hierarchy that decides which lane fills first (e.g. move Shared Signal Discovery above Post Engagers). Pass the waterfallKey from get_campaign_waterfall and orderedSlotKeys containing EXACTLY that waterfall's slot keys in the desired order; priorities are renumbered 10/20/30. Confirm the new order with the user before calling unless they stated it explicitly.";
|
|
7436
|
+
readonly inputSchema: {
|
|
7437
|
+
readonly type: "object";
|
|
7438
|
+
readonly properties: {
|
|
7439
|
+
readonly waterfallKey: {
|
|
7440
|
+
readonly type: "string";
|
|
7441
|
+
readonly description: "Waterfall key from get_campaign_waterfall.";
|
|
7442
|
+
};
|
|
7443
|
+
readonly orderedSlotKeys: {
|
|
7444
|
+
readonly type: "array";
|
|
7445
|
+
readonly items: {
|
|
7446
|
+
readonly type: "string";
|
|
7447
|
+
};
|
|
7448
|
+
readonly description: "All of the waterfall's slot keys in the desired fill order (highest priority first). Must match the existing slot set exactly — no additions or omissions.";
|
|
7449
|
+
};
|
|
7450
|
+
};
|
|
7451
|
+
readonly required: readonly ["waterfallKey", "orderedSlotKeys"];
|
|
7452
|
+
readonly additionalProperties: false;
|
|
7453
|
+
};
|
|
7424
7454
|
} | {
|
|
7425
7455
|
name: string;
|
|
7426
7456
|
description: string;
|
package/dist/tools/registry.js
CHANGED
|
@@ -35,6 +35,7 @@ import { senderToolDefinitions } from "./senders.js";
|
|
|
35
35
|
import { sequencerToolDefinitions } from "./sequencer.js";
|
|
36
36
|
import { tableToolDefinitions } from "./tables.js";
|
|
37
37
|
import { verifyRowToolDefinitions } from "./verify-row.js";
|
|
38
|
+
import { waterfallToolDefinitions } from "./waterfalls.js";
|
|
38
39
|
import { workspaceToolDefinitions } from "./workspaces.js";
|
|
39
40
|
export const allTools = [
|
|
40
41
|
...campaignToolDefinitions,
|
|
@@ -76,4 +77,5 @@ export const allTools = [
|
|
|
76
77
|
...columnDeleteToolDefinitions,
|
|
77
78
|
...columnReorderToolDefinitions,
|
|
78
79
|
...verifyRowToolDefinitions,
|
|
80
|
+
...waterfallToolDefinitions,
|
|
79
81
|
];
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export interface WaterfallSlotEntry {
|
|
2
|
+
slotKey: string;
|
|
3
|
+
priority: number;
|
|
4
|
+
displayName: string;
|
|
5
|
+
campaignOfferId: string | null;
|
|
6
|
+
workflowTableId: string | null;
|
|
7
|
+
sourceType: string;
|
|
8
|
+
sourceScope: string;
|
|
9
|
+
slotStatus: string;
|
|
10
|
+
}
|
|
11
|
+
export interface WaterfallEntry {
|
|
12
|
+
programKey: string;
|
|
13
|
+
waterfallKey: string;
|
|
14
|
+
displayName: string;
|
|
15
|
+
senderRefs: string[];
|
|
16
|
+
slots: WaterfallSlotEntry[];
|
|
17
|
+
}
|
|
18
|
+
export interface GetCampaignWaterfallResponse {
|
|
19
|
+
waterfalls: WaterfallEntry[];
|
|
20
|
+
}
|
|
21
|
+
export interface SetWaterfallOrderInput {
|
|
22
|
+
waterfallKey: string;
|
|
23
|
+
orderedSlotKeys: string[];
|
|
24
|
+
}
|
|
25
|
+
export declare const waterfallToolDefinitions: readonly [{
|
|
26
|
+
readonly name: "get_campaign_waterfall";
|
|
27
|
+
readonly description: "Read the active workspace's managed-campaign waterfall hierarchy: each waterfall (per sender or shared) with its campaign slots in stored priority order. Use this before fill-send-horizon runs to follow the configured lane order, or when the user asks what order their campaigns fill in. Returns empty when the workspace has no managed-campaign program (the hierarchy is created by evergreen reconcile).";
|
|
28
|
+
readonly inputSchema: {
|
|
29
|
+
readonly type: "object";
|
|
30
|
+
readonly properties: {};
|
|
31
|
+
readonly required: readonly [];
|
|
32
|
+
readonly additionalProperties: false;
|
|
33
|
+
};
|
|
34
|
+
}, {
|
|
35
|
+
readonly name: "set_campaign_waterfall_order";
|
|
36
|
+
readonly description: "Reorder one waterfall's campaign slots — the stored hierarchy that decides which lane fills first (e.g. move Shared Signal Discovery above Post Engagers). Pass the waterfallKey from get_campaign_waterfall and orderedSlotKeys containing EXACTLY that waterfall's slot keys in the desired order; priorities are renumbered 10/20/30. Confirm the new order with the user before calling unless they stated it explicitly.";
|
|
37
|
+
readonly inputSchema: {
|
|
38
|
+
readonly type: "object";
|
|
39
|
+
readonly properties: {
|
|
40
|
+
readonly waterfallKey: {
|
|
41
|
+
readonly type: "string";
|
|
42
|
+
readonly description: "Waterfall key from get_campaign_waterfall.";
|
|
43
|
+
};
|
|
44
|
+
readonly orderedSlotKeys: {
|
|
45
|
+
readonly type: "array";
|
|
46
|
+
readonly items: {
|
|
47
|
+
readonly type: "string";
|
|
48
|
+
};
|
|
49
|
+
readonly description: "All of the waterfall's slot keys in the desired fill order (highest priority first). Must match the existing slot set exactly — no additions or omissions.";
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
readonly required: readonly ["waterfallKey", "orderedSlotKeys"];
|
|
53
|
+
readonly additionalProperties: false;
|
|
54
|
+
};
|
|
55
|
+
}];
|
|
56
|
+
export declare function getCampaignWaterfall(): Promise<GetCampaignWaterfallResponse | {
|
|
57
|
+
waterfalls: never[];
|
|
58
|
+
_notice: string;
|
|
59
|
+
}>;
|
|
60
|
+
export declare function setCampaignWaterfallOrder(input: SetWaterfallOrderInput): Promise<{
|
|
61
|
+
waterfallKey: string;
|
|
62
|
+
slots: Array<{
|
|
63
|
+
slotKey: string;
|
|
64
|
+
priority: number;
|
|
65
|
+
}>;
|
|
66
|
+
previousOrder: string[];
|
|
67
|
+
}>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { getApi } from "../api.js";
|
|
2
|
+
export const waterfallToolDefinitions = [
|
|
3
|
+
{
|
|
4
|
+
name: "get_campaign_waterfall",
|
|
5
|
+
description: "Read the active workspace's managed-campaign waterfall hierarchy: each waterfall (per sender or shared) with its campaign slots in stored priority order. Use this before fill-send-horizon runs to follow the configured lane order, or when the user asks what order their campaigns fill in. Returns empty when the workspace has no managed-campaign program (the hierarchy is created by evergreen reconcile).",
|
|
6
|
+
inputSchema: {
|
|
7
|
+
type: "object",
|
|
8
|
+
properties: {},
|
|
9
|
+
required: [],
|
|
10
|
+
additionalProperties: false,
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: "set_campaign_waterfall_order",
|
|
15
|
+
description: "Reorder one waterfall's campaign slots — the stored hierarchy that decides which lane fills first (e.g. move Shared Signal Discovery above Post Engagers). Pass the waterfallKey from get_campaign_waterfall and orderedSlotKeys containing EXACTLY that waterfall's slot keys in the desired order; priorities are renumbered 10/20/30. Confirm the new order with the user before calling unless they stated it explicitly.",
|
|
16
|
+
inputSchema: {
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
waterfallKey: {
|
|
20
|
+
type: "string",
|
|
21
|
+
description: "Waterfall key from get_campaign_waterfall.",
|
|
22
|
+
},
|
|
23
|
+
orderedSlotKeys: {
|
|
24
|
+
type: "array",
|
|
25
|
+
items: { type: "string" },
|
|
26
|
+
description: "All of the waterfall's slot keys in the desired fill order (highest priority first). Must match the existing slot set exactly — no additions or omissions.",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
required: ["waterfallKey", "orderedSlotKeys"],
|
|
30
|
+
additionalProperties: false,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
export async function getCampaignWaterfall() {
|
|
35
|
+
const api = getApi();
|
|
36
|
+
const response = await api.get("/api/v3/managed-campaigns/waterfalls");
|
|
37
|
+
if (!response.waterfalls || response.waterfalls.length === 0) {
|
|
38
|
+
return {
|
|
39
|
+
waterfalls: [],
|
|
40
|
+
_notice: "No managed-campaign waterfalls exist in this workspace yet. Run the evergreen reconcile (create-evergreen-campaigns) to materialize the hierarchy, or fall back to the per-invocation order.",
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return response;
|
|
44
|
+
}
|
|
45
|
+
export async function setCampaignWaterfallOrder(input) {
|
|
46
|
+
const api = getApi();
|
|
47
|
+
return api.put("/api/v3/managed-campaigns/waterfalls", {
|
|
48
|
+
waterfallKey: input.waterfallKey,
|
|
49
|
+
orderedSlotKeys: input.orderedSlotKeys,
|
|
50
|
+
});
|
|
51
|
+
}
|
package/package.json
CHANGED
|
@@ -33,19 +33,22 @@ For each target campaign:
|
|
|
33
33
|
<waterfall>
|
|
34
34
|
## Campaign hierarchy (waterfall order)
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
The fill order is **stored workspace state**, not something each automation restates. Resolve it in this precedence:
|
|
37
37
|
|
|
38
|
-
1. **
|
|
39
|
-
2. **
|
|
40
|
-
3. **
|
|
41
|
-
|
|
38
|
+
1. **Stored hierarchy (default)**: call `get_campaign_waterfall` first. It returns each waterfall (per sender or shared) with slots in stored priority order — campaign offer IDs included. Fill in that order.
|
|
39
|
+
2. **Per-invocation override**: if the invoking prompt states an explicit order ("fill in this order: Signal Discovery, Post Engagers"), use it for this run only and say in the report that the stored order was overridden. To change the order durably, use `set_campaign_waterfall_order` — but only when the user/automation explicitly asks to change the hierarchy, never as a side effect of a fill run.
|
|
40
|
+
3. **No stored hierarchy** (tool returns empty — evergreen reconcile hasn't run): fall back to the conventional order `<Sender> - Post Engagers` (warmest) → `Shared Signal Discovery` → `Shared Cold Fallback` (coldest), and note that running `create-evergreen-campaigns` will materialize a stored hierarchy.
|
|
41
|
+
|
|
42
|
+
Fill mechanics, whatever the source of the order:
|
|
43
|
+
|
|
44
|
+
- **Fill the top lane first.** Move to the next lane ONLY when the current one stops with source exhaustion / no more eligible rows — never because it is merely slow.
|
|
45
|
+
- **Stop descending once the horizon target is met.** If the warm lane alone fills the horizon, the cold lanes get nothing this run — that is correct, not a gap.
|
|
46
|
+
- **Report per lane** so the operator can see the waterfall working:
|
|
42
47
|
|
|
43
48
|
```
|
|
44
|
-
csreyes92 waterfall: Post Engagers filled 4/4 (horizon met — lower lanes skipped)
|
|
45
|
-
thomas waterfall: Post Engagers 1/4 (source thin) → Shared Signal Discovery 3/3 remaining
|
|
49
|
+
csreyes92 waterfall (stored order): Post Engagers filled 4/4 (horizon met — lower lanes skipped)
|
|
50
|
+
thomas waterfall (stored order): Post Engagers 1/4 (source thin) → Shared Signal Discovery 3/3 remaining
|
|
46
51
|
```
|
|
47
|
-
|
|
48
|
-
To **change the hierarchy**, the scheduled automation just states the new order in its prompt — the order is an input to this skill, not stored state.
|
|
49
52
|
</waterfall>
|
|
50
53
|
|
|
51
54
|
<safety>
|