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":"wallet.tools.d.ts","sourceRoot":"","sources":["../../src/tools/wallet.tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAQvD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,QA+EtE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { formatResult, formatPaginatedResult, formatErrorResult, } from "../utils/response.js";
|
|
3
|
+
export function registerWalletTools(server, client) {
|
|
4
|
+
server.tool("lb_wallet_get_balance", "Get Listing Bureau wallet balance (credits and USD). May include a warning if data is temporarily unavailable.", {}, { readOnlyHint: true }, async () => {
|
|
5
|
+
try {
|
|
6
|
+
const res = await client.request("GET", "/api/v1/wallet");
|
|
7
|
+
return formatResult(res.data);
|
|
8
|
+
}
|
|
9
|
+
catch (e) {
|
|
10
|
+
return formatErrorResult(e);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
server.tool("lb_wallet_get_transactions", "Get Listing Bureau wallet transaction history (paginated). Last page may include legacy entries beyond per_page count.", {
|
|
14
|
+
page: z.number().int().min(1).optional().describe("Page number (default 1)"),
|
|
15
|
+
per_page: z
|
|
16
|
+
.number()
|
|
17
|
+
.int()
|
|
18
|
+
.min(1)
|
|
19
|
+
.max(100)
|
|
20
|
+
.optional()
|
|
21
|
+
.describe("Results per page (default 50, max 100)"),
|
|
22
|
+
}, { readOnlyHint: true }, async (params) => {
|
|
23
|
+
try {
|
|
24
|
+
const query = {};
|
|
25
|
+
if (params.page !== undefined)
|
|
26
|
+
query.page = String(params.page);
|
|
27
|
+
if (params.per_page !== undefined)
|
|
28
|
+
query.per_page = String(params.per_page);
|
|
29
|
+
const res = await client.request("GET", "/api/v1/wallet/transactions", undefined, query);
|
|
30
|
+
if (res.meta) {
|
|
31
|
+
return formatPaginatedResult(res.data, res.meta);
|
|
32
|
+
}
|
|
33
|
+
return formatResult(res.data);
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
return formatErrorResult(e);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
server.tool("lb_wallet_topup", "Generate a Stripe checkout URL to top up wallet balance. Returns a URL to complete payment.", {
|
|
40
|
+
amount: z
|
|
41
|
+
.number()
|
|
42
|
+
.min(5)
|
|
43
|
+
.max(5000)
|
|
44
|
+
.describe("Top-up amount in USD (minimum $5, maximum $5,000)"),
|
|
45
|
+
}, {}, async (params) => {
|
|
46
|
+
try {
|
|
47
|
+
const res = await client.request("POST", "/api/v1/wallet/topup", { amount: params.amount });
|
|
48
|
+
return formatResult(res.data);
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
return formatErrorResult(e);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=wallet.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wallet.tools.js","sourceRoot":"","sources":["../../src/tools/wallet.tools.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,MAAgB;IACrE,MAAM,CAAC,IAAI,CACT,uBAAuB,EACvB,gHAAgH,EAChH,EAAE,EACF,EAAE,YAAY,EAAE,IAAI,EAAG,EACvB,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAC9B,KAAK,EACL,gBAAgB,CACjB,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;IAEF,MAAM,CAAC,IAAI,CACT,4BAA4B,EAC5B,wHAAwH,EACxH;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;QAC5E,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,GAAG,CAAC;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,wCAAwC,CAAC;KACtD,EACD,EAAE,YAAY,EAAE,IAAI,EAAG,EACvB,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,KAAK,GAA2B,EAAE,CAAC;YACzC,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;gBAAE,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAChE,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS;gBAC/B,KAAK,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC3C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAC9B,KAAK,EACL,6BAA6B,EAC7B,SAAS,EACT,KAAK,CACN,CAAC;YACF,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;gBACb,OAAO,qBAAqB,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YACnD,CAAC;YACD,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;IAEF,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,6FAA6F,EAC7F;QACE,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,IAAI,CAAC;aACT,QAAQ,CAAC,mDAAmD,CAAC;KACjE,EACD,EAAE,EACF,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,OAAO,CAC9B,MAAM,EACN,sBAAsB,EACtB,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAC1B,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,50 @@
|
|
|
1
|
+
import type { ServiceRates, ScheduleEntry } from "../client/types.js";
|
|
2
|
+
export interface DailyCost {
|
|
3
|
+
date: string;
|
|
4
|
+
atc: number;
|
|
5
|
+
sfb: number;
|
|
6
|
+
pgv: number;
|
|
7
|
+
total: number;
|
|
8
|
+
}
|
|
9
|
+
export interface CostEstimate {
|
|
10
|
+
num_days: number;
|
|
11
|
+
totals: {
|
|
12
|
+
atc: number;
|
|
13
|
+
pgv: number;
|
|
14
|
+
sfb: number;
|
|
15
|
+
grand_total: number;
|
|
16
|
+
};
|
|
17
|
+
avg_daily_cost: number;
|
|
18
|
+
daily_breakdown?: DailyCost[];
|
|
19
|
+
}
|
|
20
|
+
/** Full SFB per-unit cost including product price, tax, and passthrough. */
|
|
21
|
+
export declare function sfbUnitCost(rates: ServiceRates, retailPrice?: number): number;
|
|
22
|
+
/**
|
|
23
|
+
* Compute cost estimate from a normalized schedule (array of daily volumes).
|
|
24
|
+
* Each entry uses { date, atc, sfb, pgv } with MCP-facing field names.
|
|
25
|
+
*/
|
|
26
|
+
export declare function estimateCost(schedule: {
|
|
27
|
+
date: string;
|
|
28
|
+
atc: number;
|
|
29
|
+
sfb: number;
|
|
30
|
+
pgv: number;
|
|
31
|
+
}[], rates: ServiceRates, retailPrice?: number): CostEstimate;
|
|
32
|
+
/**
|
|
33
|
+
* Map backend ScheduleEntry (purchase/pageview) to cost-friendly shape (sfb/pgv).
|
|
34
|
+
* Separates dated entries from the ongoing entry for independent cost calculation.
|
|
35
|
+
*/
|
|
36
|
+
export declare function mapScheduleEntries(entries: ScheduleEntry[]): {
|
|
37
|
+
dated: {
|
|
38
|
+
date: string;
|
|
39
|
+
atc: number;
|
|
40
|
+
sfb: number;
|
|
41
|
+
pgv: number;
|
|
42
|
+
}[];
|
|
43
|
+
ongoing: {
|
|
44
|
+
atc: number;
|
|
45
|
+
sfb: number;
|
|
46
|
+
pgv: number;
|
|
47
|
+
} | null;
|
|
48
|
+
};
|
|
49
|
+
export declare function round2(n: number): number;
|
|
50
|
+
//# sourceMappingURL=cost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../../src/utils/cost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEtE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IACvE,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,SAAS,EAAE,CAAC;CAC/B;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAO7E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,EACnE,KAAK,EAAE,YAAY,EACnB,WAAW,CAAC,EAAE,MAAM,GACnB,YAAY,CAkDd;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,aAAa,EAAE,GACvB;IACD,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjE,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC3D,CAyBA;AAWD,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAExC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/** Full SFB per-unit cost including product price, tax, and passthrough. */
|
|
2
|
+
export function sfbUnitCost(rates, retailPrice) {
|
|
3
|
+
if (retailPrice == null) {
|
|
4
|
+
return rates.sfb_service_fee;
|
|
5
|
+
}
|
|
6
|
+
const tax = retailPrice * rates.sfb_tax_rate;
|
|
7
|
+
const passthrough = (retailPrice + tax) * rates.sfb_passthrough_rate;
|
|
8
|
+
return rates.sfb_service_fee + retailPrice + tax + passthrough;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Compute cost estimate from a normalized schedule (array of daily volumes).
|
|
12
|
+
* Each entry uses { date, atc, sfb, pgv } with MCP-facing field names.
|
|
13
|
+
*/
|
|
14
|
+
export function estimateCost(schedule, rates, retailPrice) {
|
|
15
|
+
if (schedule.length === 0) {
|
|
16
|
+
return {
|
|
17
|
+
num_days: 0,
|
|
18
|
+
totals: { atc: 0, pgv: 0, sfb: 0, grand_total: 0 },
|
|
19
|
+
avg_daily_cost: 0,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const sfbUnit = sfbUnitCost(rates, retailPrice);
|
|
23
|
+
const includeDailyBreakdown = schedule.length <= 14;
|
|
24
|
+
let totalAtc = 0;
|
|
25
|
+
let totalSfb = 0;
|
|
26
|
+
let totalPgv = 0;
|
|
27
|
+
const dailyBreakdown = [];
|
|
28
|
+
for (const day of schedule) {
|
|
29
|
+
const dayAtc = day.atc * rates.atc;
|
|
30
|
+
const daySfb = day.sfb * sfbUnit;
|
|
31
|
+
const dayPgv = day.pgv * rates.pgv;
|
|
32
|
+
totalAtc += dayAtc;
|
|
33
|
+
totalSfb += daySfb;
|
|
34
|
+
totalPgv += dayPgv;
|
|
35
|
+
if (includeDailyBreakdown) {
|
|
36
|
+
dailyBreakdown.push({
|
|
37
|
+
date: day.date,
|
|
38
|
+
atc: round2(dayAtc),
|
|
39
|
+
sfb: round2(daySfb),
|
|
40
|
+
pgv: round2(dayPgv),
|
|
41
|
+
total: round2(dayAtc + daySfb + dayPgv),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const grandTotal = totalAtc + totalSfb + totalPgv;
|
|
46
|
+
const numDays = schedule.length;
|
|
47
|
+
return {
|
|
48
|
+
num_days: numDays,
|
|
49
|
+
totals: {
|
|
50
|
+
atc: round2(totalAtc),
|
|
51
|
+
pgv: round2(totalPgv),
|
|
52
|
+
sfb: round2(totalSfb),
|
|
53
|
+
grand_total: round2(grandTotal),
|
|
54
|
+
},
|
|
55
|
+
avg_daily_cost: round2(numDays > 0 ? grandTotal / numDays : 0),
|
|
56
|
+
...(includeDailyBreakdown ? { daily_breakdown: dailyBreakdown } : {}),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Map backend ScheduleEntry (purchase/pageview) to cost-friendly shape (sfb/pgv).
|
|
61
|
+
* Separates dated entries from the ongoing entry for independent cost calculation.
|
|
62
|
+
*/
|
|
63
|
+
export function mapScheduleEntries(entries) {
|
|
64
|
+
const dated = [];
|
|
65
|
+
let ongoing = null;
|
|
66
|
+
for (const e of entries) {
|
|
67
|
+
// Backend sets both id and date to "ongoing" for the perpetual entry — check both defensively
|
|
68
|
+
if (e.id === "ongoing" || e.date === "ongoing") {
|
|
69
|
+
ongoing = { atc: e.atc, sfb: e.purchase, pgv: e.pageview };
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
// Only include entries with a recognizable date format (MM/DD/YYYY or YYYY-MM-DD)
|
|
73
|
+
const normalized = normalizeDateToIso(e.date);
|
|
74
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(normalized)) {
|
|
75
|
+
console.warn(`[cost] Skipping schedule entry with unrecognized date format: "${e.date}"`);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
dated.push({
|
|
79
|
+
date: normalized,
|
|
80
|
+
atc: e.atc,
|
|
81
|
+
sfb: e.purchase,
|
|
82
|
+
pgv: e.pageview,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return { dated, ongoing };
|
|
86
|
+
}
|
|
87
|
+
/** Normalize backend date format (MM/DD/YYYY) to ISO (YYYY-MM-DD). Passes through other formats. */
|
|
88
|
+
function normalizeDateToIso(date) {
|
|
89
|
+
// Groups: [1]=MM, [2]=DD, [3]=YYYY → reorder to YYYY-MM-DD
|
|
90
|
+
const match = date.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
|
|
91
|
+
if (match)
|
|
92
|
+
return `${match[3]}-${match[1]}-${match[2]}`;
|
|
93
|
+
return date;
|
|
94
|
+
}
|
|
95
|
+
export function round2(n) {
|
|
96
|
+
return Math.round(n * 100) / 100;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=cost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../../src/utils/cost.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Custom error class for Listing Bureau API errors. */
|
|
2
|
+
export declare class LBApiError extends Error {
|
|
3
|
+
readonly statusCode: number;
|
|
4
|
+
readonly code: string;
|
|
5
|
+
constructor(statusCode: number, code: string, message: string);
|
|
6
|
+
}
|
|
7
|
+
/** Format an LBApiError (or unknown error) into a human-readable string. */
|
|
8
|
+
export declare function formatError(error: unknown): string;
|
|
9
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,qBAAa,UAAW,SAAQ,KAAK;aAEjB,UAAU,EAAE,MAAM;aAClB,IAAI,EAAE,MAAM;gBADZ,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EAC5B,OAAO,EAAE,MAAM;CAKlB;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQlD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Custom error class for Listing Bureau API errors. */
|
|
2
|
+
export class LBApiError extends Error {
|
|
3
|
+
statusCode;
|
|
4
|
+
code;
|
|
5
|
+
constructor(statusCode, code, message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.statusCode = statusCode;
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.name = "LBApiError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/** Format an LBApiError (or unknown error) into a human-readable string. */
|
|
13
|
+
export function formatError(error) {
|
|
14
|
+
if (error instanceof LBApiError) {
|
|
15
|
+
return `API Error [${error.code}] (${error.statusCode}): ${error.message}`;
|
|
16
|
+
}
|
|
17
|
+
if (error instanceof Error) {
|
|
18
|
+
return `Error: ${error.message}`;
|
|
19
|
+
}
|
|
20
|
+
return `Unknown error: ${String(error)}`;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,MAAM,OAAO,UAAW,SAAQ,KAAK;IAEjB;IACA;IAFlB,YACkB,UAAkB,EAClB,IAAY,EAC5B,OAAe;QAEf,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,eAAU,GAAV,UAAU,CAAQ;QAClB,SAAI,GAAJ,IAAI,CAAQ;QAI5B,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF;AAED,4EAA4E;AAC5E,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,OAAO,cAAc,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC,UAAU,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;IAC7E,CAAC;IACD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC;IACnC,CAAC;IACD,OAAO,kBAAkB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Format a successful API response as an MCP tool result.
|
|
4
|
+
* Handles both entity responses and message-only responses.
|
|
5
|
+
* Surfaces `warning` and `balance_warning` fields independently.
|
|
6
|
+
*/
|
|
7
|
+
export declare function formatResult(data: unknown): CallToolResult;
|
|
8
|
+
/**
|
|
9
|
+
* Format a paginated API response as an MCP tool result.
|
|
10
|
+
* Includes pagination metadata.
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatPaginatedResult(data: unknown, meta: {
|
|
13
|
+
page: number;
|
|
14
|
+
per_page: number;
|
|
15
|
+
total: number;
|
|
16
|
+
total_pages: number;
|
|
17
|
+
}): CallToolResult;
|
|
18
|
+
/** Format an error as an MCP tool error result. */
|
|
19
|
+
export declare function formatErrorResult(error: unknown): CallToolResult;
|
|
20
|
+
//# sourceMappingURL=response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAGzE;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAuC1D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,OAAO,EACb,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC3E,cAAc,CAQhB;AAED,mDAAmD;AACnD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAKhE"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { formatError } from "./errors.js";
|
|
2
|
+
/**
|
|
3
|
+
* Format a successful API response as an MCP tool result.
|
|
4
|
+
* Handles both entity responses and message-only responses.
|
|
5
|
+
* Surfaces `warning` and `balance_warning` fields independently.
|
|
6
|
+
*/
|
|
7
|
+
export function formatResult(data) {
|
|
8
|
+
const warnings = [];
|
|
9
|
+
let cleaned = data;
|
|
10
|
+
if (data && typeof data === "object") {
|
|
11
|
+
const obj = { ...data };
|
|
12
|
+
// Top-level warning string
|
|
13
|
+
if ("warning" in obj && typeof obj.warning === "string") {
|
|
14
|
+
warnings.push(obj.warning);
|
|
15
|
+
delete obj.warning;
|
|
16
|
+
}
|
|
17
|
+
// balance_warning object (independent of warning)
|
|
18
|
+
if ("balance_warning" in obj && obj.balance_warning && typeof obj.balance_warning === "object") {
|
|
19
|
+
const bw = obj.balance_warning;
|
|
20
|
+
const parts = [];
|
|
21
|
+
if (typeof bw.warning === "string" && bw.warning.trim())
|
|
22
|
+
parts.push(bw.warning);
|
|
23
|
+
if (typeof bw.daily_cost_estimate === "number")
|
|
24
|
+
parts.push(`Daily cost estimate: $${bw.daily_cost_estimate.toFixed(2)}`);
|
|
25
|
+
if (typeof bw.balance === "number")
|
|
26
|
+
parts.push(`Balance: $${bw.balance.toFixed(2)}`);
|
|
27
|
+
if (typeof bw.days_remaining === "number")
|
|
28
|
+
parts.push(`Days remaining: ${bw.days_remaining.toFixed(1)}`);
|
|
29
|
+
if (parts.length > 0)
|
|
30
|
+
warnings.push(parts.join(" | "));
|
|
31
|
+
delete obj.balance_warning;
|
|
32
|
+
}
|
|
33
|
+
cleaned = obj;
|
|
34
|
+
}
|
|
35
|
+
let text = JSON.stringify(cleaned, null, 2);
|
|
36
|
+
for (const w of warnings) {
|
|
37
|
+
text += `\n\n⚠️ Warning: ${w}`;
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
content: [{ type: "text", text }],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Format a paginated API response as an MCP tool result.
|
|
45
|
+
* Includes pagination metadata.
|
|
46
|
+
*/
|
|
47
|
+
export function formatPaginatedResult(data, meta) {
|
|
48
|
+
const result = {
|
|
49
|
+
data,
|
|
50
|
+
pagination: meta,
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** Format an error as an MCP tool error result. */
|
|
57
|
+
export function formatErrorResult(error) {
|
|
58
|
+
return {
|
|
59
|
+
content: [{ type: "text", text: formatError(error) }],
|
|
60
|
+
isError: true,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response.js","sourceRoot":"","sources":["../../src/utils/response.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate and normalize a base URL for API requests.
|
|
3
|
+
* - Rejects invalid URLs and non-http(s) protocols
|
|
4
|
+
* - Non-localhost URLs must use https://
|
|
5
|
+
* - Returns URL.origin (never includes trailing slash per WHATWG spec)
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateBaseUrl(raw: string): string;
|
|
8
|
+
//# sourceMappingURL=validate-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-url.d.ts","sourceRoot":"","sources":["../../src/utils/validate-url.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA8BnD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate and normalize a base URL for API requests.
|
|
3
|
+
* - Rejects invalid URLs and non-http(s) protocols
|
|
4
|
+
* - Non-localhost URLs must use https://
|
|
5
|
+
* - Returns URL.origin (never includes trailing slash per WHATWG spec)
|
|
6
|
+
*/
|
|
7
|
+
export function validateBaseUrl(raw) {
|
|
8
|
+
let parsed;
|
|
9
|
+
try {
|
|
10
|
+
parsed = new URL(raw);
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
throw new Error(`Invalid LB_BASE_URL: "${raw}" is not a valid URL`);
|
|
14
|
+
}
|
|
15
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
16
|
+
throw new Error(`Invalid LB_BASE_URL: protocol "${parsed.protocol}" is not allowed (must be http: or https:)`);
|
|
17
|
+
}
|
|
18
|
+
const isLocalhost = parsed.hostname === "localhost" ||
|
|
19
|
+
parsed.hostname.startsWith("127.") ||
|
|
20
|
+
parsed.hostname === "[::1]" ||
|
|
21
|
+
// IPv4-mapped IPv6 loopback — Node normalizes 127.x.y.z to [::ffff:7fXX:XXXX]
|
|
22
|
+
(parsed.hostname.startsWith("[::ffff:7f") && parsed.hostname.endsWith("]"));
|
|
23
|
+
if (parsed.protocol === "http:" && !isLocalhost) {
|
|
24
|
+
throw new Error(`Invalid LB_BASE_URL: http:// is only allowed for localhost — use https:// for "${parsed.hostname}"`);
|
|
25
|
+
}
|
|
26
|
+
return parsed.origin;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=validate-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-url.js","sourceRoot":"","sources":["../../src/utils/validate-url.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,yBAAyB,GAAG,sBAAsB,CACnD,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CACb,kCAAkC,MAAM,CAAC,QAAQ,4CAA4C,CAC9F,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GACf,MAAM,CAAC,QAAQ,KAAK,WAAW;QAC/B,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC;QAClC,MAAM,CAAC,QAAQ,KAAK,OAAO;QAC3B,8EAA8E;QAC9E,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAE9E,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CACb,kFAAkF,MAAM,CAAC,QAAQ,GAAG,CACrG,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "listingbureau-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Amazon organic ranking MCP server. Run ranking campaigns, track keyword positions, and monitor rank movement from any AI assistant.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"listingbureau-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/index.js",
|
|
13
|
+
"dev": "tsc --watch",
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"test:watch": "vitest",
|
|
16
|
+
"prepublishOnly": "npm run build"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"mcp",
|
|
20
|
+
"mcp-server",
|
|
21
|
+
"model-context-protocol",
|
|
22
|
+
"amazon",
|
|
23
|
+
"amazon-ranking",
|
|
24
|
+
"amazon-seller",
|
|
25
|
+
"amazon-fba",
|
|
26
|
+
"amazon-seo",
|
|
27
|
+
"organic-ranking",
|
|
28
|
+
"rank-tracker",
|
|
29
|
+
"ecommerce",
|
|
30
|
+
"listing-optimization",
|
|
31
|
+
"claude",
|
|
32
|
+
"cursor",
|
|
33
|
+
"ai-tools",
|
|
34
|
+
"seller-tools"
|
|
35
|
+
],
|
|
36
|
+
"author": "Listing Bureau",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=20.0.0"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@modelcontextprotocol/sdk": "^1.27.0",
|
|
43
|
+
"zod": "^3.23.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^20.0.0",
|
|
47
|
+
"typescript": "^5.5.0",
|
|
48
|
+
"vitest": "^2.0.0"
|
|
49
|
+
},
|
|
50
|
+
"files": [
|
|
51
|
+
"dist",
|
|
52
|
+
"README.md",
|
|
53
|
+
"LICENSE"
|
|
54
|
+
]
|
|
55
|
+
}
|