listingbureau-mcp 0.1.0
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/LICENSE +21 -0
- package/README.md +152 -0
- package/dist/client/lb-client.d.ts +36 -0
- package/dist/client/lb-client.d.ts.map +1 -0
- package/dist/client/lb-client.js +205 -0
- package/dist/client/lb-client.js.map +1 -0
- package/dist/client/types.d.ts +185 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +2 -0
- package/dist/client/types.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/account.tools.d.ts +4 -0
- package/dist/tools/account.tools.d.ts.map +1 -0
- package/dist/tools/account.tools.js +55 -0
- package/dist/tools/account.tools.js.map +1 -0
- package/dist/tools/cost.tools.d.ts +4 -0
- package/dist/tools/cost.tools.d.ts.map +1 -0
- package/dist/tools/cost.tools.js +123 -0
- package/dist/tools/cost.tools.js.map +1 -0
- package/dist/tools/feedback.tools.d.ts +4 -0
- package/dist/tools/feedback.tools.d.ts.map +1 -0
- package/dist/tools/feedback.tools.js +20 -0
- package/dist/tools/feedback.tools.js.map +1 -0
- package/dist/tools/orders.tools.d.ts +4 -0
- package/dist/tools/orders.tools.d.ts.map +1 -0
- package/dist/tools/orders.tools.js +58 -0
- package/dist/tools/orders.tools.js.map +1 -0
- package/dist/tools/projects.tools.d.ts +4 -0
- package/dist/tools/projects.tools.d.ts.map +1 -0
- package/dist/tools/projects.tools.js +129 -0
- package/dist/tools/projects.tools.js.map +1 -0
- package/dist/tools/schedule.tools.d.ts +4 -0
- package/dist/tools/schedule.tools.d.ts.map +1 -0
- package/dist/tools/schedule.tools.js +117 -0
- package/dist/tools/schedule.tools.js.map +1 -0
- package/dist/tools/wallet.tools.d.ts +4 -0
- package/dist/tools/wallet.tools.d.ts.map +1 -0
- package/dist/tools/wallet.tools.js +55 -0
- package/dist/tools/wallet.tools.js.map +1 -0
- package/dist/utils/cost.d.ts +50 -0
- package/dist/utils/cost.d.ts.map +1 -0
- package/dist/utils/cost.js +98 -0
- package/dist/utils/cost.js.map +1 -0
- package/dist/utils/errors.d.ts +9 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +22 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/response.d.ts +20 -0
- package/dist/utils/response.d.ts.map +1 -0
- package/dist/utils/response.js +63 -0
- package/dist/utils/response.js.map +1 -0
- package/dist/utils/validate-url.d.ts +8 -0
- package/dist/utils/validate-url.d.ts.map +1 -0
- package/dist/utils/validate-url.js +28 -0
- package/dist/utils/validate-url.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE1D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;AACtC,IAAI,CAAC,MAAM,EAAE,CAAC;IACZ,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,OAAO,GAAG,2BAA2B,CAAC;AAC1C,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;IAC5B,IAAI,CAAC;QACH,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE7C,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,eAAe;IACrB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACrC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACpC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACtC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACtC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACpC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACtC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAElC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.tools.d.ts","sourceRoot":"","sources":["../../src/tools/account.tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAIvD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,QAqFvE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatResult, formatErrorResult } from "../utils/response.js";
|
|
3
|
+
export function registerAccountTools(server, client) {
|
|
4
|
+
server.tool("lb_account_get", "Get Listing Bureau account info (email, name, company, plan, account type)", {}, { readOnlyHint: true }, async () => {
|
|
5
|
+
try {
|
|
6
|
+
const res = await client.request("GET", "/api/v1/account");
|
|
7
|
+
return formatResult(res.data);
|
|
8
|
+
}
|
|
9
|
+
catch (e) {
|
|
10
|
+
return formatErrorResult(e);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
server.tool("lb_account_update_profile", "Update Listing Bureau account profile fields (first_name, last_name, company). At least one field required.", {
|
|
14
|
+
first_name: z.string().optional().describe("New first name"),
|
|
15
|
+
last_name: z.string().optional().describe("New last name"),
|
|
16
|
+
company: z.string().optional().describe("New company name"),
|
|
17
|
+
}, { idempotentHint: true }, async (params) => {
|
|
18
|
+
try {
|
|
19
|
+
const body = {};
|
|
20
|
+
if (params.first_name !== undefined)
|
|
21
|
+
body.first_name = params.first_name;
|
|
22
|
+
if (params.last_name !== undefined)
|
|
23
|
+
body.last_name = params.last_name;
|
|
24
|
+
if (params.company !== undefined)
|
|
25
|
+
body.company = params.company;
|
|
26
|
+
if (Object.keys(body).length === 0) {
|
|
27
|
+
return formatErrorResult(new Error("At least one field (first_name, last_name, company) must be provided"));
|
|
28
|
+
}
|
|
29
|
+
const res = await client.request("PATCH", "/api/v1/account/profile", body);
|
|
30
|
+
return formatResult(res.data);
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
return formatErrorResult(e);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
server.tool("lb_account_get_service_rates", "Get current Listing Bureau service pricing rates. Returns empty object if no plan is active.", {}, { readOnlyHint: true }, async () => {
|
|
37
|
+
try {
|
|
38
|
+
const res = await client.request("GET", "/api/v1/account/service-rates");
|
|
39
|
+
return formatResult(res.data);
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
return formatErrorResult(e);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
server.tool("lb_account_get_subscription", "Get Listing Bureau subscription info (plan label, fee, discount, wallet usage)", {}, { readOnlyHint: true }, async () => {
|
|
46
|
+
try {
|
|
47
|
+
const res = await client.request("GET", "/api/v1/account/subscription");
|
|
48
|
+
return formatResult(res.data);
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
return formatErrorResult(e);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=account.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.tools.js","sourceRoot":"","sources":["../../src/tools/account.tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.tools.d.ts","sourceRoot":"","sources":["../../src/tools/cost.tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AA8BvD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,QA4HpE"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { sfbUnitCost, estimateCost, round2 } from "../utils/cost.js";
|
|
3
|
+
import { formatResult, formatErrorResult } from "../utils/response.js";
|
|
4
|
+
const scheduleItemSchema = z.object({
|
|
5
|
+
date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Date must be YYYY-MM-DD format").describe("Date in YYYY-MM-DD format"),
|
|
6
|
+
atc: z.number().int().min(0).optional().describe("Add-to-cart volume (default 0)"),
|
|
7
|
+
sfb: z.number().int().min(0).optional().describe("Search-find-buy volume (default 0)"),
|
|
8
|
+
pgv: z.number().int().min(0).optional().describe("Page view volume (default 0)"),
|
|
9
|
+
});
|
|
10
|
+
const estimateCostShape = {
|
|
11
|
+
atc: z.number().int().min(0).optional().describe("Uniform daily add-to-cart volume"),
|
|
12
|
+
sfb: z.number().int().min(0).optional().describe("Uniform daily search-find-buy volume"),
|
|
13
|
+
pgv: z.number().int().min(0).optional().describe("Uniform daily page view volume"),
|
|
14
|
+
num_days: z.number().int().min(1).max(365).optional().describe("Number of days for uniform volumes"),
|
|
15
|
+
schedule: z
|
|
16
|
+
.array(scheduleItemSchema)
|
|
17
|
+
.min(1)
|
|
18
|
+
.max(365)
|
|
19
|
+
.optional()
|
|
20
|
+
.describe("Per-day schedule entries (alternative to uniform volumes)"),
|
|
21
|
+
retail_price: z
|
|
22
|
+
.number()
|
|
23
|
+
.min(0)
|
|
24
|
+
.optional()
|
|
25
|
+
.describe("Product retail price in USD — needed for accurate SFB cost including product price, tax, and passthrough"),
|
|
26
|
+
};
|
|
27
|
+
export function registerCostTools(server, client) {
|
|
28
|
+
server.tool("lb_estimate_cost", "Estimate campaign cost before committing. Fetches current rates and wallet balance, then computes total cost, daily averages, and wallet sustainability. Provide either uniform daily volumes (atc/sfb/pgv + num_days) or a per-day schedule array. Include retail_price for accurate SFB costs.", estimateCostShape, { readOnlyHint: true }, async (params) => {
|
|
29
|
+
try {
|
|
30
|
+
// Validate: either schedule array, or (volumes + num_days)
|
|
31
|
+
const hasSchedule = params.schedule && params.schedule.length > 0;
|
|
32
|
+
const hasVolume = (params.atc ?? 0) > 0 || (params.sfb ?? 0) > 0 || (params.pgv ?? 0) > 0;
|
|
33
|
+
if (!hasSchedule && !(hasVolume && params.num_days != null)) {
|
|
34
|
+
return formatErrorResult(new Error("Provide either a 'schedule' array, OR at least one volume (atc/sfb/pgv > 0) with 'num_days'"));
|
|
35
|
+
}
|
|
36
|
+
const [ratesRes, walletRes] = await Promise.all([
|
|
37
|
+
client.request("GET", "/api/v1/account/service-rates"),
|
|
38
|
+
client.request("GET", "/api/v1/wallet"),
|
|
39
|
+
]);
|
|
40
|
+
const rates = ratesRes.data;
|
|
41
|
+
const wallet = walletRes.data;
|
|
42
|
+
// Build normalized schedule
|
|
43
|
+
let schedule;
|
|
44
|
+
if (params.schedule && params.schedule.length > 0) {
|
|
45
|
+
schedule = params.schedule.map((s) => ({
|
|
46
|
+
date: s.date,
|
|
47
|
+
atc: s.atc ?? 0,
|
|
48
|
+
sfb: s.sfb ?? 0,
|
|
49
|
+
pgv: s.pgv ?? 0,
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
const numDays = params.num_days;
|
|
54
|
+
// Uniform volumes: "uniform" label signals these aren't real calendar dates.
|
|
55
|
+
// Daily breakdown (for <= 14 days) will show identical rows — this is intentional.
|
|
56
|
+
schedule = Array.from({ length: numDays }, () => ({
|
|
57
|
+
date: "uniform",
|
|
58
|
+
atc: params.atc ?? 0,
|
|
59
|
+
sfb: params.sfb ?? 0,
|
|
60
|
+
pgv: params.pgv ?? 0,
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
const estimate = estimateCost(schedule, rates, params.retail_price);
|
|
64
|
+
// Wallet sustainability (clamp to zero for overdraft, round to match grand_total precision)
|
|
65
|
+
const availableUsd = round2(Math.max(0, wallet.balance_usd - wallet.held_usd));
|
|
66
|
+
// null = unlimited (zero-cost schedule can run indefinitely)
|
|
67
|
+
const daysAffordable = estimate.avg_daily_cost > 0
|
|
68
|
+
? Math.floor(availableUsd / estimate.avg_daily_cost)
|
|
69
|
+
: null;
|
|
70
|
+
const warnings = [];
|
|
71
|
+
// Warn if schedule array was used but uniform params were also provided
|
|
72
|
+
if (hasSchedule && (hasVolume || params.num_days != null)) {
|
|
73
|
+
warnings.push("schedule array provided — num_days and uniform volumes (atc/sfb/pgv) were ignored.");
|
|
74
|
+
}
|
|
75
|
+
// SFB without retail_price warning (0 is effectively the same as omitting)
|
|
76
|
+
const hasSfb = schedule.some((d) => d.sfb > 0);
|
|
77
|
+
if (hasSfb && (params.retail_price == null || params.retail_price === 0)) {
|
|
78
|
+
warnings.push("SFB volumes provided without retail_price — estimate uses service fee only ($" +
|
|
79
|
+
rates.sfb_service_fee.toFixed(2) +
|
|
80
|
+
"/unit). Provide retail_price for full cost including product price, tax, and passthrough.");
|
|
81
|
+
}
|
|
82
|
+
// Affordability warning (skip for zero-cost schedules to avoid confusing "$0.00 exceeds" messages)
|
|
83
|
+
if (estimate.totals.grand_total > 0 && availableUsd < estimate.totals.grand_total) {
|
|
84
|
+
const affordMsg = daysAffordable != null
|
|
85
|
+
? `Can afford ~${daysAffordable} days at current rate.`
|
|
86
|
+
: "";
|
|
87
|
+
warnings.push(`Campaign cost ($${estimate.totals.grand_total.toFixed(2)}) exceeds available balance ($${availableUsd.toFixed(2)}). ${affordMsg}`.trim());
|
|
88
|
+
}
|
|
89
|
+
const sfbUnit = sfbUnitCost(rates, params.retail_price);
|
|
90
|
+
// Note rounding caveat when daily breakdown is present
|
|
91
|
+
if (estimate.daily_breakdown) {
|
|
92
|
+
warnings.push("daily_breakdown rows are rounded independently — their sum may differ from grand_total by a few cents. Trust grand_total for the accurate figure.");
|
|
93
|
+
}
|
|
94
|
+
const result = {
|
|
95
|
+
estimate,
|
|
96
|
+
wallet: {
|
|
97
|
+
balance_usd: wallet.balance_usd,
|
|
98
|
+
held_usd: wallet.held_usd,
|
|
99
|
+
available_usd: round2(availableUsd),
|
|
100
|
+
// >= is intentional: exact-balance means campaign is affordable
|
|
101
|
+
can_afford_campaign: availableUsd >= estimate.totals.grand_total,
|
|
102
|
+
// null = zero-cost schedule (unlimited days), number = finite affordability
|
|
103
|
+
days_affordable: daysAffordable,
|
|
104
|
+
},
|
|
105
|
+
rates_used: {
|
|
106
|
+
atc_per_action: rates.atc,
|
|
107
|
+
pgv_per_action: rates.pgv,
|
|
108
|
+
sfb_per_unit: round2(sfbUnit),
|
|
109
|
+
sfb_formula: rates.sfb_formula,
|
|
110
|
+
sfb_retail_price_provided: params.retail_price != null,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
if (warnings.length > 0) {
|
|
114
|
+
result.warnings = warnings;
|
|
115
|
+
}
|
|
116
|
+
return formatResult(result);
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
return formatErrorResult(e);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=cost.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.tools.js","sourceRoot":"","sources":["../../src/tools/cost.tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.tools.d.ts","sourceRoot":"","sources":["../../src/tools/feedback.tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAIvD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,QAyBxE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatResult, formatErrorResult } from "../utils/response.js";
|
|
3
|
+
export function registerFeedbackTools(server, client) {
|
|
4
|
+
server.tool("lb_feedback_submit", "Submit feedback about the Listing Bureau service (10-5000 characters).", {
|
|
5
|
+
feedback: z
|
|
6
|
+
.string()
|
|
7
|
+
.min(10)
|
|
8
|
+
.max(5000)
|
|
9
|
+
.describe("Feedback text (10-5000 characters)"),
|
|
10
|
+
}, {}, async (params) => {
|
|
11
|
+
try {
|
|
12
|
+
const res = await client.request("POST", "/api/v1/feedback", { feedback: params.feedback });
|
|
13
|
+
return formatResult(res.data);
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
return formatErrorResult(e);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=feedback.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.tools.js","sourceRoot":"","sources":["../../src/tools/feedback.tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEvE,MAAM,UAAU,qBAAqB,CAAC,MAAiB,EAAE,MAAgB;IACvE,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,wEAAwE,EACxE;QACE,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,GAAG,CAAC,EAAE,CAAC;aACP,GAAG,CAAC,IAAI,CAAC;aACT,QAAQ,CAAC,oCAAoC,CAAC;KAClD,EACD,EAAE,EACF,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAC9B,MAAM,EACN,kBAAkB,EAClB,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAC9B,CAAC;YACF,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,iBAAiB,CAAC,CAAC,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orders.tools.d.ts","sourceRoot":"","sources":["../../src/tools/orders.tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAIvD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,QAmFtE"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatResult, formatPaginatedResult, formatErrorResult } from "../utils/response.js";
|
|
3
|
+
export function registerOrdersTools(server, client) {
|
|
4
|
+
server.tool("lb_orders_list", "List Listing Bureau orders (paginated, newest first). Includes order status, campaign, region, and issue report status.", {
|
|
5
|
+
page: z.number().int().min(1).optional().describe("Page number (default 1)"),
|
|
6
|
+
per_page: z
|
|
7
|
+
.number()
|
|
8
|
+
.int()
|
|
9
|
+
.min(1)
|
|
10
|
+
.max(100)
|
|
11
|
+
.optional()
|
|
12
|
+
.describe("Results per page (default 50, max 100)"),
|
|
13
|
+
}, { readOnlyHint: true }, async (params) => {
|
|
14
|
+
try {
|
|
15
|
+
const query = {};
|
|
16
|
+
if (params.page !== undefined)
|
|
17
|
+
query.page = String(params.page);
|
|
18
|
+
if (params.per_page !== undefined)
|
|
19
|
+
query.per_page = String(params.per_page);
|
|
20
|
+
const res = await client.request("GET", "/api/v1/orders", undefined, query);
|
|
21
|
+
if (res.meta) {
|
|
22
|
+
return formatPaginatedResult(res.data, res.meta);
|
|
23
|
+
}
|
|
24
|
+
return formatResult(res.data);
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
return formatErrorResult(e);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
server.tool("lb_orders_get", "Get detailed info for a specific Listing Bureau order.", {
|
|
31
|
+
order_id: z.string().describe("Order identifier"),
|
|
32
|
+
}, { readOnlyHint: true }, async (params) => {
|
|
33
|
+
try {
|
|
34
|
+
const res = await client.request("GET", `/api/v1/orders/${encodeURIComponent(params.order_id)}`);
|
|
35
|
+
return formatResult(res.data);
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
return formatErrorResult(e);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
server.tool("lb_orders_report_issue", "Report an issue with a Listing Bureau order. Maximum 5 issue reports per order -- do not retry if you receive a limit error. Description must be 1-1000 characters.", {
|
|
42
|
+
order_id: z.string().describe("Order identifier"),
|
|
43
|
+
description: z
|
|
44
|
+
.string()
|
|
45
|
+
.min(1)
|
|
46
|
+
.max(1000)
|
|
47
|
+
.describe("Issue description (1-1000 characters)"),
|
|
48
|
+
}, {}, async (params) => {
|
|
49
|
+
try {
|
|
50
|
+
const res = await client.request("POST", `/api/v1/orders/${encodeURIComponent(params.order_id)}/report-issue`, { description: params.description });
|
|
51
|
+
return formatResult(res.data);
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
return formatErrorResult(e);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=orders.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orders.tools.js","sourceRoot":"","sources":["../../src/tools/orders.tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.tools.d.ts","sourceRoot":"","sources":["../../src/tools/projects.tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAavD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,QA8KxE"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatResult, formatErrorResult } from "../utils/response.js";
|
|
3
|
+
// Valid Amazon region codes (validated against CONSTANTS['MARKETPLACES'] in backend)
|
|
4
|
+
const VALID_REGIONS = [
|
|
5
|
+
"US", "CA", "MX", // Americas
|
|
6
|
+
"UK", "DE", "FR", "IT", // Europe
|
|
7
|
+
"ES", "NL", "SE", "TR", // Europe cont.
|
|
8
|
+
"JP", "AU", "IN", // Asia-Pacific
|
|
9
|
+
"AE", "BR", "SG", "SA", // Rest of world
|
|
10
|
+
];
|
|
11
|
+
export function registerProjectsTools(server, client) {
|
|
12
|
+
server.tool("lb_projects_list", "List Listing Bureau Amazon projects with optional filters. Returns ASIN, keyword, active status, and current service volumes.", {
|
|
13
|
+
region: z
|
|
14
|
+
.enum(VALID_REGIONS)
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Filter by Amazon region"),
|
|
17
|
+
active: z.boolean().optional().describe("Filter by active status"),
|
|
18
|
+
}, { readOnlyHint: true }, async (params) => {
|
|
19
|
+
try {
|
|
20
|
+
const query = { marketplace: "amazon" };
|
|
21
|
+
if (params.region !== undefined)
|
|
22
|
+
query.region = params.region;
|
|
23
|
+
if (params.active !== undefined)
|
|
24
|
+
query.active = String(params.active);
|
|
25
|
+
const res = await client.request("GET", "/api/v1/projects", undefined, query);
|
|
26
|
+
return formatResult(res.data);
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
return formatErrorResult(e);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
server.tool("lb_projects_create", "Create a new Listing Bureau Amazon project. If a project with the same ASIN+keyword+region was previously archived, it will be reactivated instead (returns 201). ASIN must be a valid Amazon ASIN. Keyword must be 3-200 characters.", {
|
|
33
|
+
region: z
|
|
34
|
+
.enum(VALID_REGIONS)
|
|
35
|
+
.describe("Amazon region code"),
|
|
36
|
+
asin: z
|
|
37
|
+
.string()
|
|
38
|
+
.describe("Amazon ASIN (e.g. 'B01MTJK06C')"),
|
|
39
|
+
keyword: z
|
|
40
|
+
.string()
|
|
41
|
+
.min(3)
|
|
42
|
+
.max(200)
|
|
43
|
+
.describe("Target keyword (3-200 characters)"),
|
|
44
|
+
expected_retail_price: z
|
|
45
|
+
.number()
|
|
46
|
+
.min(0)
|
|
47
|
+
.optional()
|
|
48
|
+
.describe("Expected retail price of the product in USD. Required for SFB cost estimation and holds."),
|
|
49
|
+
}, {}, async (params) => {
|
|
50
|
+
try {
|
|
51
|
+
const body = {
|
|
52
|
+
marketplace: "amazon",
|
|
53
|
+
region: params.region,
|
|
54
|
+
asin: params.asin,
|
|
55
|
+
keyword: params.keyword,
|
|
56
|
+
};
|
|
57
|
+
if (params.expected_retail_price !== undefined) {
|
|
58
|
+
body.expected_retail_price = params.expected_retail_price;
|
|
59
|
+
}
|
|
60
|
+
const res = await client.request("POST", "/api/v1/projects", body);
|
|
61
|
+
return formatResult(res.data);
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
return formatErrorResult(e);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
server.tool("lb_projects_get", "Get detailed info for a specific Listing Bureau project including schedule, services, and SERP data.", {
|
|
68
|
+
ui_id: z.string().describe("Project unique identifier"),
|
|
69
|
+
}, { readOnlyHint: true }, async (params) => {
|
|
70
|
+
try {
|
|
71
|
+
const res = await client.request("GET", `/api/v1/projects/${encodeURIComponent(params.ui_id)}`);
|
|
72
|
+
return formatResult(res.data);
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
return formatErrorResult(e);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
server.tool("lb_projects_update", "Update a Listing Bureau project. Currently supports toggling the active status (pause/resume). To archive a project, use lb_projects_archive instead.", {
|
|
79
|
+
ui_id: z.string().describe("Project unique identifier"),
|
|
80
|
+
active: z.boolean().optional().describe("Set active status (true=resume, false=pause)"),
|
|
81
|
+
}, { idempotentHint: true }, async (params) => {
|
|
82
|
+
try {
|
|
83
|
+
const body = {};
|
|
84
|
+
if (params.active !== undefined)
|
|
85
|
+
body.active = params.active;
|
|
86
|
+
if (Object.keys(body).length === 0) {
|
|
87
|
+
return formatErrorResult(new Error("At least one field (active) must be provided"));
|
|
88
|
+
}
|
|
89
|
+
const res = await client.request("PATCH", `/api/v1/projects/${encodeURIComponent(params.ui_id)}`, body);
|
|
90
|
+
return formatResult(res.data);
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
return formatErrorResult(e);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
server.tool("lb_projects_archive", "Archive (soft delete) a Listing Bureau Amazon project. The project can be reactivated by creating a new project with the same ASIN+keyword+region.", {
|
|
97
|
+
ui_id: z.string().describe("Project unique identifier"),
|
|
98
|
+
}, { destructiveHint: true }, async (params) => {
|
|
99
|
+
try {
|
|
100
|
+
const res = await client.request("DELETE", `/api/v1/projects/${encodeURIComponent(params.ui_id)}`);
|
|
101
|
+
return formatResult(res.data);
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
return formatErrorResult(e);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
server.tool("lb_projects_get_stats", "Get daily stats for a Listing Bureau project: service execution (SFB, ATC, PGV), SERP rankings, ARA analytics, Brand Referral, and Search Query data. Note: this call may be slow (~1-2s) due to 14+ backend DB queries.", {
|
|
108
|
+
ui_id: z.string().describe("Project unique identifier"),
|
|
109
|
+
days: z
|
|
110
|
+
.number()
|
|
111
|
+
.int()
|
|
112
|
+
.min(1)
|
|
113
|
+
.max(365)
|
|
114
|
+
.optional()
|
|
115
|
+
.describe("Number of days of history (default 30, max 365)"),
|
|
116
|
+
}, { readOnlyHint: true }, async (params) => {
|
|
117
|
+
try {
|
|
118
|
+
const query = {};
|
|
119
|
+
if (params.days !== undefined)
|
|
120
|
+
query.days = String(params.days);
|
|
121
|
+
const res = await client.request("GET", `/api/v1/projects/${encodeURIComponent(params.ui_id)}/stats`, undefined, query);
|
|
122
|
+
return formatResult(res.data);
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
return formatErrorResult(e);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=projects.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.tools.js","sourceRoot":"","sources":["../../src/tools/projects.tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.tools.d.ts","sourceRoot":"","sources":["../../src/tools/schedule.tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAuEvD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,QA+ExE"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatResult, formatErrorResult } from "../utils/response.js";
|
|
3
|
+
import { estimateCost, mapScheduleEntries } from "../utils/cost.js";
|
|
4
|
+
// Write schema: only YYYY-MM-DD dates (backend manages 'ongoing' entries internally)
|
|
5
|
+
const scheduleEntrySchema = z.object({
|
|
6
|
+
date: z
|
|
7
|
+
.string()
|
|
8
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, "Must be YYYY-MM-DD format")
|
|
9
|
+
.describe("Date in YYYY-MM-DD format"),
|
|
10
|
+
atc: z.number().int().min(0).describe("Add-to-cart volume"),
|
|
11
|
+
sfb: z.number().int().min(0).describe("Search-find-buy volume"),
|
|
12
|
+
pgv: z.number().int().min(0).describe("Page view volume"),
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* Best-effort: fetch rates and compute cost summary for a schedule response.
|
|
16
|
+
* Returns the response data augmented with cost_summary, or unchanged on failure.
|
|
17
|
+
*/
|
|
18
|
+
async function appendCostSummary(data, client) {
|
|
19
|
+
const result = { ...data };
|
|
20
|
+
try {
|
|
21
|
+
const ratesRes = await client.request("GET", "/api/v1/account/service-rates");
|
|
22
|
+
const rates = ratesRes.data;
|
|
23
|
+
const { dated, ongoing } = mapScheduleEntries(data.scheduling);
|
|
24
|
+
if (dated.length === 0 && !ongoing)
|
|
25
|
+
return result;
|
|
26
|
+
const sfbNote = "SFB costs use service fee only ($" + rates.sfb_service_fee.toFixed(2) +
|
|
27
|
+
"), matching backend balance check behavior. Use lb_estimate_cost with retail_price for full SFB cost.";
|
|
28
|
+
if (dated.length > 0 && ongoing) {
|
|
29
|
+
// Mixed: dated entries + ongoing
|
|
30
|
+
const est = estimateCost(dated, rates);
|
|
31
|
+
const ongoingDailyCost = estimateCost([{ date: "ongoing", ...ongoing }], rates).avg_daily_cost;
|
|
32
|
+
result.cost_summary = {
|
|
33
|
+
total_estimated_cost: est.totals.grand_total,
|
|
34
|
+
avg_daily_cost: est.avg_daily_cost,
|
|
35
|
+
num_scheduled_days: est.num_days,
|
|
36
|
+
note: `Includes ${dated.length} dated day(s) + ongoing at $${ongoingDailyCost.toFixed(2)}/day. ${sfbNote}`,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
else if (dated.length > 0) {
|
|
40
|
+
// Dated entries only
|
|
41
|
+
const est = estimateCost(dated, rates);
|
|
42
|
+
result.cost_summary = {
|
|
43
|
+
total_estimated_cost: est.totals.grand_total,
|
|
44
|
+
avg_daily_cost: est.avg_daily_cost,
|
|
45
|
+
num_scheduled_days: est.num_days,
|
|
46
|
+
note: sfbNote,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
else if (ongoing) {
|
|
50
|
+
// Ongoing only
|
|
51
|
+
const dailyEst = estimateCost([{ date: "ongoing", ...ongoing }], rates);
|
|
52
|
+
result.cost_summary = {
|
|
53
|
+
total_estimated_cost: null,
|
|
54
|
+
avg_daily_cost: dailyEst.avg_daily_cost,
|
|
55
|
+
num_scheduled_days: null,
|
|
56
|
+
note: `Ongoing schedule — $${dailyEst.avg_daily_cost.toFixed(2)}/day with no fixed end date. ${sfbNote}`,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
// Best-effort: skip cost summary on failure, log for debugging
|
|
62
|
+
console.error("[cost-summary]", e);
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
export function registerScheduleTools(server, client) {
|
|
67
|
+
server.tool("lb_schedule_get", "Get the current schedule for a Listing Bureau project. Shows per-day service volumes (atc, sfb, pgv).", {
|
|
68
|
+
ui_id: z.string().describe("Project unique identifier"),
|
|
69
|
+
}, { readOnlyHint: true }, async (params) => {
|
|
70
|
+
try {
|
|
71
|
+
const res = await client.request("GET", `/api/v1/projects/${encodeURIComponent(params.ui_id)}/schedule`);
|
|
72
|
+
const augmented = await appendCostSummary(res.data, client);
|
|
73
|
+
return formatResult(augmented);
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
return formatErrorResult(e);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
server.tool("lb_schedule_set", "Set the full per-day schedule for a Listing Bureau project. Replaces any existing schedule. Each entry represents one day with volumes for atc, sfb, and pgv. Max 365 entries.", {
|
|
80
|
+
ui_id: z.string().describe("Project unique identifier"),
|
|
81
|
+
schedule: z
|
|
82
|
+
.array(scheduleEntrySchema)
|
|
83
|
+
.min(1)
|
|
84
|
+
.max(365)
|
|
85
|
+
.describe("Array of daily schedule entries"),
|
|
86
|
+
}, { destructiveHint: true, idempotentHint: true }, async (params) => {
|
|
87
|
+
try {
|
|
88
|
+
const res = await client.request("PUT", `/api/v1/projects/${encodeURIComponent(params.ui_id)}/schedule`, { schedule: params.schedule });
|
|
89
|
+
const augmented = await appendCostSummary(res.data, client);
|
|
90
|
+
return formatResult(augmented);
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
return formatErrorResult(e);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
server.tool("lb_schedule_quick_set", "Quick-set uniform daily volumes for a Listing Bureau project. WARNING: This clears any existing per-day schedule and replaces it with uniform values. All omitted fields default to 0.", {
|
|
97
|
+
ui_id: z.string().describe("Project unique identifier"),
|
|
98
|
+
atc: z.number().int().min(0).optional().describe("Add-to-cart volume per day (default 0)"),
|
|
99
|
+
sfb: z.number().int().min(0).optional().describe("Search-find-buy volume per day (default 0)"),
|
|
100
|
+
pgv: z.number().int().min(0).optional().describe("Page view volume per day (default 0)"),
|
|
101
|
+
}, { destructiveHint: true, idempotentHint: true }, async (params) => {
|
|
102
|
+
try {
|
|
103
|
+
const body = {
|
|
104
|
+
atc: params.atc ?? 0,
|
|
105
|
+
sfb: params.sfb ?? 0,
|
|
106
|
+
pgv: params.pgv ?? 0,
|
|
107
|
+
};
|
|
108
|
+
const res = await client.request("POST", `/api/v1/projects/${encodeURIComponent(params.ui_id)}/schedule/quick`, body);
|
|
109
|
+
const augmented = await appendCostSummary(res.data, client);
|
|
110
|
+
return formatResult(augmented);
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
return formatErrorResult(e);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=schedule.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.tools.js","sourceRoot":"","sources":["../../src/tools/schedule.tools.ts"],"names":[],"mappings":"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"}
|