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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Listing Bureau
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# listingbureau-mcp
|
|
2
|
+
|
|
3
|
+
Organic ranking campaigns for Amazon products, managed through your AI assistant.
|
|
4
|
+
|
|
5
|
+
The only ranking-focused Amazon MCP server. Create ranking campaigns, set velocity schedules, track keyword positions, and monitor rank movement from Claude, Cursor, or any MCP-compatible client.
|
|
6
|
+
|
|
7
|
+
Built on the same infrastructure that moved 1,700+ products to page one. Median time: 48 days.
|
|
8
|
+
|
|
9
|
+
## What it does
|
|
10
|
+
|
|
11
|
+
This MCP server connects your AI assistant to [Listing Bureau](https://listingbureau.com)'s Amazon ranking infrastructure. Three signal types drive organic rank improvement:
|
|
12
|
+
|
|
13
|
+
- **Search-Find-Buy (SFB)** signals the A10 algorithm that real shoppers searched for a keyword, found the product, and purchased it
|
|
14
|
+
- **Add-to-Cart (ATC)** builds conversion velocity and purchase intent signals
|
|
15
|
+
- **Page Views (PGV)** generate session-level browsing behavior that supports organic discovery
|
|
16
|
+
|
|
17
|
+
Your assistant handles the entire workflow: create a project for any ASIN and keyword, set a daily velocity schedule, estimate costs before committing, and pull position reports to track movement.
|
|
18
|
+
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
### Claude Desktop
|
|
22
|
+
|
|
23
|
+
Add to `claude_desktop_config.json`:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"mcpServers": {
|
|
28
|
+
"listingbureau": {
|
|
29
|
+
"command": "npx",
|
|
30
|
+
"args": ["listingbureau-mcp"],
|
|
31
|
+
"env": {
|
|
32
|
+
"LB_API_KEY": "your-api-key-here"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Claude Code
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
claude mcp add listingbureau -- npx listingbureau-mcp
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Then set your API key in the MCP config.
|
|
46
|
+
|
|
47
|
+
### Cursor
|
|
48
|
+
|
|
49
|
+
Add to `.cursor/mcp.json`:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"mcpServers": {
|
|
54
|
+
"listingbureau": {
|
|
55
|
+
"command": "npx",
|
|
56
|
+
"args": ["listingbureau-mcp"],
|
|
57
|
+
"env": {
|
|
58
|
+
"LB_API_KEY": "your-api-key-here"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Get an API key
|
|
66
|
+
|
|
67
|
+
Create an account at [listingbureau.com](https://listingbureau.com). Your API key is in the dashboard under Settings.
|
|
68
|
+
|
|
69
|
+
## Environment variables
|
|
70
|
+
|
|
71
|
+
| Variable | Required | Default | Description |
|
|
72
|
+
|----------|----------|---------|-------------|
|
|
73
|
+
| `LB_API_KEY` | Yes | - | Listing Bureau API key |
|
|
74
|
+
| `LB_BASE_URL` | No | `https://listingbureau.com` | API base URL (override for staging/dev) |
|
|
75
|
+
|
|
76
|
+
## Tools
|
|
77
|
+
|
|
78
|
+
21 tools across 7 categories.
|
|
79
|
+
|
|
80
|
+
### Projects (6 tools)
|
|
81
|
+
|
|
82
|
+
| Tool | Description |
|
|
83
|
+
|------|-------------|
|
|
84
|
+
| `lb_projects_list` | List projects with optional region/active filters |
|
|
85
|
+
| `lb_projects_create` | Create a new Amazon project (ASIN + keyword + region) |
|
|
86
|
+
| `lb_projects_get` | Get project details (schedule, services, SERP data) |
|
|
87
|
+
| `lb_projects_update` | Update project (pause/resume) |
|
|
88
|
+
| `lb_projects_archive` | Archive (soft delete) a project |
|
|
89
|
+
| `lb_projects_get_stats` | Get daily stats (SFB, ATC, PGV, SERP, ARA, BR, SQR) |
|
|
90
|
+
|
|
91
|
+
### Schedule (3 tools)
|
|
92
|
+
|
|
93
|
+
| Tool | Description |
|
|
94
|
+
|------|-------------|
|
|
95
|
+
| `lb_schedule_get` | Get current per-day schedule |
|
|
96
|
+
| `lb_schedule_set` | Set full per-day schedule (replaces existing) |
|
|
97
|
+
| `lb_schedule_quick_set` | Quick-set uniform daily volumes |
|
|
98
|
+
|
|
99
|
+
### Cost Estimation (1 tool)
|
|
100
|
+
|
|
101
|
+
| Tool | Description |
|
|
102
|
+
|------|-------------|
|
|
103
|
+
| `lb_estimate_cost` | Estimate campaign cost before committing. Computes total cost, daily averages, and wallet sustainability. |
|
|
104
|
+
|
|
105
|
+
### Wallet (3 tools)
|
|
106
|
+
|
|
107
|
+
| Tool | Description |
|
|
108
|
+
|------|-------------|
|
|
109
|
+
| `lb_wallet_get_balance` | Get wallet balance (credits and USD) |
|
|
110
|
+
| `lb_wallet_get_transactions` | Get transaction history (paginated) |
|
|
111
|
+
| `lb_wallet_topup` | Generate a Stripe checkout URL to top up wallet balance |
|
|
112
|
+
|
|
113
|
+
### Orders (3 tools)
|
|
114
|
+
|
|
115
|
+
| Tool | Description |
|
|
116
|
+
|------|-------------|
|
|
117
|
+
| `lb_orders_list` | List orders (paginated, newest first) |
|
|
118
|
+
| `lb_orders_get` | Get order details |
|
|
119
|
+
| `lb_orders_report_issue` | Report an issue with an order |
|
|
120
|
+
|
|
121
|
+
### Account (4 tools)
|
|
122
|
+
|
|
123
|
+
| Tool | Description |
|
|
124
|
+
|------|-------------|
|
|
125
|
+
| `lb_account_get` | Get account info (email, name, company, plan) |
|
|
126
|
+
| `lb_account_update_profile` | Update profile fields (first_name, last_name, company) |
|
|
127
|
+
| `lb_account_get_service_rates` | Get current service pricing rates |
|
|
128
|
+
| `lb_account_get_subscription` | Get subscription info (plan, fee, discount) |
|
|
129
|
+
|
|
130
|
+
### Feedback (1 tool)
|
|
131
|
+
|
|
132
|
+
| Tool | Description |
|
|
133
|
+
|------|-------------|
|
|
134
|
+
| `lb_feedback_submit` | Submit feedback (10-5000 characters) |
|
|
135
|
+
|
|
136
|
+
## Development
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
npm install
|
|
140
|
+
npm run build
|
|
141
|
+
npm run dev # watch mode
|
|
142
|
+
npm test
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Links
|
|
146
|
+
|
|
147
|
+
- [Landing page](https://listingbureau.com/mcp)
|
|
148
|
+
- [Create an account](https://listingbureau.com)
|
|
149
|
+
|
|
150
|
+
## License
|
|
151
|
+
|
|
152
|
+
MIT
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ApiSuccessResponse } from "./types.js";
|
|
2
|
+
export declare class LBClient {
|
|
3
|
+
private readonly apiKey;
|
|
4
|
+
private readonly baseUrl;
|
|
5
|
+
private jwt;
|
|
6
|
+
private authInProgress;
|
|
7
|
+
private consecutiveAuthFailures;
|
|
8
|
+
private authBackoffDeadline;
|
|
9
|
+
constructor(apiKey: string, baseUrl: string);
|
|
10
|
+
/**
|
|
11
|
+
* Wait until the backoff window has elapsed (no-op if already past deadline).
|
|
12
|
+
* Must only be called while authInProgress is set (ensureAuth holds the mutex).
|
|
13
|
+
*/
|
|
14
|
+
private waitForBackoff;
|
|
15
|
+
/**
|
|
16
|
+
* Ensure we have a valid access token.
|
|
17
|
+
* - No tokens -> authenticate with API key
|
|
18
|
+
* - Expiring in <30s -> proactively refresh
|
|
19
|
+
* - Refresh fails -> re-authenticate from scratch
|
|
20
|
+
*/
|
|
21
|
+
private ensureAuth;
|
|
22
|
+
/** Exchange API key for JWT tokens. */
|
|
23
|
+
private authenticate;
|
|
24
|
+
/**
|
|
25
|
+
* Refresh the access token.
|
|
26
|
+
* On failure, throws so ensureAuth() stays the single re-auth entry point.
|
|
27
|
+
*/
|
|
28
|
+
private refresh;
|
|
29
|
+
/**
|
|
30
|
+
* Make an authenticated API request.
|
|
31
|
+
* Retries once on 401 (token expired mid-request).
|
|
32
|
+
*/
|
|
33
|
+
request<T>(method: string, path: string, body?: Record<string, unknown>, query?: Record<string, string>): Promise<ApiSuccessResponse<T>>;
|
|
34
|
+
private doRequest;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=lb-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lb-client.d.ts","sourceRoot":"","sources":["../../src/client/lb-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,kBAAkB,EAInB,MAAM,YAAY,CAAC;AAepB,qBAAa,QAAQ;IAOjB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B,OAAO,CAAC,GAAG,CAAyB;IACpC,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,uBAAuB,CAAK;IACpC,OAAO,CAAC,mBAAmB,CAAK;gBAGb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM;IAGlC;;;OAGG;YACW,cAAc;IAQ5B;;;;;OAKG;YACW,UAAU;IAkCxB,uCAAuC;YACzB,YAAY;IAgD1B;;;OAGG;YACW,OAAO;IA6CrB;;;OAGG;IACG,OAAO,CAAC,CAAC,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;YA8BnB,SAAS;CA4CxB"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { LBApiError } from "../utils/errors.js";
|
|
2
|
+
/** Decode a JWT payload without verifying signature (we only need `exp`). */
|
|
3
|
+
function decodeJwtExp(token) {
|
|
4
|
+
const parts = token.split(".");
|
|
5
|
+
if (parts.length !== 3)
|
|
6
|
+
throw new Error("Invalid JWT format");
|
|
7
|
+
// Base64url -> Base64 -> Buffer -> JSON
|
|
8
|
+
const payload = Buffer.from(parts[1], "base64url").toString("utf-8");
|
|
9
|
+
const parsed = JSON.parse(payload);
|
|
10
|
+
if (typeof parsed.exp !== "number") {
|
|
11
|
+
throw new Error("JWT missing exp claim");
|
|
12
|
+
}
|
|
13
|
+
return parsed.exp; // Unix seconds
|
|
14
|
+
}
|
|
15
|
+
export class LBClient {
|
|
16
|
+
apiKey;
|
|
17
|
+
baseUrl;
|
|
18
|
+
jwt = null;
|
|
19
|
+
authInProgress = null;
|
|
20
|
+
consecutiveAuthFailures = 0;
|
|
21
|
+
authBackoffDeadline = 0;
|
|
22
|
+
constructor(apiKey, baseUrl) {
|
|
23
|
+
this.apiKey = apiKey;
|
|
24
|
+
this.baseUrl = baseUrl;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Wait until the backoff window has elapsed (no-op if already past deadline).
|
|
28
|
+
* Must only be called while authInProgress is set (ensureAuth holds the mutex).
|
|
29
|
+
*/
|
|
30
|
+
async waitForBackoff() {
|
|
31
|
+
if (this.consecutiveAuthFailures === 0)
|
|
32
|
+
return;
|
|
33
|
+
const remaining = this.authBackoffDeadline - Date.now();
|
|
34
|
+
if (remaining > 0) {
|
|
35
|
+
await new Promise((resolve) => setTimeout(resolve, remaining));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Ensure we have a valid access token.
|
|
40
|
+
* - No tokens -> authenticate with API key
|
|
41
|
+
* - Expiring in <30s -> proactively refresh
|
|
42
|
+
* - Refresh fails -> re-authenticate from scratch
|
|
43
|
+
*/
|
|
44
|
+
async ensureAuth() {
|
|
45
|
+
// Prevent concurrent auth calls
|
|
46
|
+
if (this.authInProgress) {
|
|
47
|
+
await this.authInProgress;
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const nowSec = Math.floor(Date.now() / 1000);
|
|
51
|
+
if (!this.jwt) {
|
|
52
|
+
this.authInProgress = this.authenticate();
|
|
53
|
+
try {
|
|
54
|
+
await this.authInProgress;
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
this.authInProgress = null;
|
|
58
|
+
}
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// Proactive refresh: 30 seconds before expiry
|
|
62
|
+
if (this.jwt.expires_at - nowSec < 30) {
|
|
63
|
+
// Both refresh and fallback re-auth run inside the same authInProgress mutex window
|
|
64
|
+
this.authInProgress = this.refresh().catch(() => {
|
|
65
|
+
// Refresh failed and cleared jwt -- re-authenticate from scratch
|
|
66
|
+
return this.authenticate();
|
|
67
|
+
});
|
|
68
|
+
try {
|
|
69
|
+
await this.authInProgress;
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
this.authInProgress = null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** Exchange API key for JWT tokens. */
|
|
77
|
+
async authenticate() {
|
|
78
|
+
await this.waitForBackoff();
|
|
79
|
+
try {
|
|
80
|
+
const res = await fetch(`${this.baseUrl}/api/v1/auth/token`, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
headers: { "Content-Type": "application/json" },
|
|
83
|
+
body: JSON.stringify({ api_key: this.apiKey }),
|
|
84
|
+
});
|
|
85
|
+
let json;
|
|
86
|
+
try {
|
|
87
|
+
json = (await res.json());
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
throw new LBApiError(res.status, "PARSE_ERROR", `Auth server returned non-JSON response (HTTP ${res.status})`);
|
|
91
|
+
}
|
|
92
|
+
if (json.status === "error") {
|
|
93
|
+
throw new LBApiError(res.status, json.error.code, json.error.message);
|
|
94
|
+
}
|
|
95
|
+
const { access_token, refresh_token } = json.data;
|
|
96
|
+
this.jwt = {
|
|
97
|
+
access_token,
|
|
98
|
+
refresh_token,
|
|
99
|
+
expires_at: decodeJwtExp(access_token),
|
|
100
|
+
};
|
|
101
|
+
this.consecutiveAuthFailures = 0;
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
this.consecutiveAuthFailures++;
|
|
105
|
+
const base = Math.min(1000 * Math.pow(2, this.consecutiveAuthFailures - 1), 60_000);
|
|
106
|
+
const jitter = base * 0.25 * Math.random();
|
|
107
|
+
this.authBackoffDeadline = Date.now() + base + jitter;
|
|
108
|
+
throw e;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Refresh the access token.
|
|
113
|
+
* On failure, throws so ensureAuth() stays the single re-auth entry point.
|
|
114
|
+
*/
|
|
115
|
+
async refresh() {
|
|
116
|
+
if (!this.jwt) {
|
|
117
|
+
throw new Error("Cannot refresh without existing tokens");
|
|
118
|
+
}
|
|
119
|
+
const refreshToken = this.jwt.refresh_token;
|
|
120
|
+
try {
|
|
121
|
+
const res = await fetch(`${this.baseUrl}/api/v1/auth/refresh`, {
|
|
122
|
+
method: "POST",
|
|
123
|
+
headers: {
|
|
124
|
+
"Content-Type": "application/json",
|
|
125
|
+
Authorization: `Bearer ${refreshToken}`,
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
let json;
|
|
129
|
+
try {
|
|
130
|
+
json = (await res.json());
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
throw new LBApiError(res.status, "PARSE_ERROR", `Refresh server returned non-JSON response (HTTP ${res.status})`);
|
|
134
|
+
}
|
|
135
|
+
if (json.status === "error") {
|
|
136
|
+
// Refresh failed -- throw so catch block clears jwt and re-throws
|
|
137
|
+
throw new Error(`Refresh failed: ${json.error.message}`);
|
|
138
|
+
}
|
|
139
|
+
const { access_token } = json.data;
|
|
140
|
+
this.jwt = {
|
|
141
|
+
...this.jwt,
|
|
142
|
+
access_token,
|
|
143
|
+
expires_at: decodeJwtExp(access_token),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
catch (e) {
|
|
147
|
+
// Clear tokens so next ensureAuth() triggers full re-auth
|
|
148
|
+
this.jwt = null;
|
|
149
|
+
throw e;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Make an authenticated API request.
|
|
154
|
+
* Retries once on 401 (token expired mid-request).
|
|
155
|
+
*/
|
|
156
|
+
async request(method, path, body, query) {
|
|
157
|
+
await this.ensureAuth();
|
|
158
|
+
const response = await this.doRequest(method, path, body, query);
|
|
159
|
+
// Single retry on 401
|
|
160
|
+
if (response.status === "error" && response._statusCode === 401) {
|
|
161
|
+
this.jwt = null;
|
|
162
|
+
await this.ensureAuth();
|
|
163
|
+
const retry = await this.doRequest(method, path, body, query);
|
|
164
|
+
if (retry.status === "error") {
|
|
165
|
+
throw new LBApiError(retry._statusCode ?? 500, retry.error.code, retry.error.message);
|
|
166
|
+
}
|
|
167
|
+
return retry;
|
|
168
|
+
}
|
|
169
|
+
if (response.status === "error") {
|
|
170
|
+
throw new LBApiError(response._statusCode ?? 500, response.error.code, response.error.message);
|
|
171
|
+
}
|
|
172
|
+
return response;
|
|
173
|
+
}
|
|
174
|
+
async doRequest(method, path, body, query) {
|
|
175
|
+
let url = `${this.baseUrl}${path}`;
|
|
176
|
+
if (query) {
|
|
177
|
+
const params = new URLSearchParams(Object.entries(query).filter(([, v]) => v !== undefined && v !== ""));
|
|
178
|
+
const qs = params.toString();
|
|
179
|
+
if (qs)
|
|
180
|
+
url += `?${qs}`;
|
|
181
|
+
}
|
|
182
|
+
const headers = {
|
|
183
|
+
Authorization: `Bearer ${this.jwt.access_token}`,
|
|
184
|
+
};
|
|
185
|
+
const options = { method, headers };
|
|
186
|
+
if (body && method !== "GET") {
|
|
187
|
+
headers["Content-Type"] = "application/json";
|
|
188
|
+
options.body = JSON.stringify(body);
|
|
189
|
+
}
|
|
190
|
+
const res = await fetch(url, options);
|
|
191
|
+
// Note: non-JSON responses (e.g., gateway 502/401) throw here and bypass
|
|
192
|
+
// the 401-retry path in request(). This is acceptable -- gateway-level 401s
|
|
193
|
+
// are not recoverable via token refresh anyway.
|
|
194
|
+
let json;
|
|
195
|
+
try {
|
|
196
|
+
json = (await res.json());
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
throw new LBApiError(res.status, "PARSE_ERROR", `Server returned non-JSON response (HTTP ${res.status})`);
|
|
200
|
+
}
|
|
201
|
+
// Attach status code for retry logic
|
|
202
|
+
return { ...json, _statusCode: res.status };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=lb-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lb-client.js","sourceRoot":"","sources":["../../src/client/lb-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/** API response envelope for success responses. */
|
|
2
|
+
export interface ApiSuccessResponse<T> {
|
|
3
|
+
status: "success";
|
|
4
|
+
data: T;
|
|
5
|
+
meta?: PaginationMeta;
|
|
6
|
+
}
|
|
7
|
+
/** API response envelope for error responses. */
|
|
8
|
+
export interface ApiErrorResponse {
|
|
9
|
+
status: "error";
|
|
10
|
+
error: {
|
|
11
|
+
code: string;
|
|
12
|
+
message: string;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export type ApiResponse<T> = ApiSuccessResponse<T> | ApiErrorResponse;
|
|
16
|
+
export interface PaginationMeta {
|
|
17
|
+
page: number;
|
|
18
|
+
per_page: number;
|
|
19
|
+
total: number;
|
|
20
|
+
total_pages: number;
|
|
21
|
+
}
|
|
22
|
+
/** POST /auth/token response -- includes both tokens + optional cid. */
|
|
23
|
+
export interface TokenResponse {
|
|
24
|
+
access_token: string;
|
|
25
|
+
refresh_token: string;
|
|
26
|
+
cid?: string;
|
|
27
|
+
}
|
|
28
|
+
/** POST /auth/refresh response -- access_token only, NO refresh_token. */
|
|
29
|
+
export interface RefreshResponse {
|
|
30
|
+
access_token: string;
|
|
31
|
+
}
|
|
32
|
+
/** Stored JWT state within LBClient. */
|
|
33
|
+
export interface JwtState {
|
|
34
|
+
access_token: string;
|
|
35
|
+
refresh_token: string;
|
|
36
|
+
/** Unix seconds when the access token expires. */
|
|
37
|
+
expires_at: number;
|
|
38
|
+
}
|
|
39
|
+
export interface Account {
|
|
40
|
+
email: string;
|
|
41
|
+
first_name: string;
|
|
42
|
+
last_name: string;
|
|
43
|
+
account_type: string;
|
|
44
|
+
company?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface Subscription {
|
|
47
|
+
account_type: string;
|
|
48
|
+
plan_label: string;
|
|
49
|
+
use_wallet: boolean;
|
|
50
|
+
subscription_fee: number;
|
|
51
|
+
}
|
|
52
|
+
export interface ServiceRates {
|
|
53
|
+
atc: number;
|
|
54
|
+
pgv: number;
|
|
55
|
+
sfb_service_fee: number;
|
|
56
|
+
sfb_tax_rate: number;
|
|
57
|
+
sfb_passthrough_rate: number;
|
|
58
|
+
sfb_formula: string;
|
|
59
|
+
[key: string]: unknown;
|
|
60
|
+
}
|
|
61
|
+
export interface BalanceWarning {
|
|
62
|
+
warning: string;
|
|
63
|
+
daily_cost_estimate: number;
|
|
64
|
+
balance?: number;
|
|
65
|
+
days_remaining?: number;
|
|
66
|
+
}
|
|
67
|
+
export interface CostSummary {
|
|
68
|
+
total_estimated_cost: number | null;
|
|
69
|
+
avg_daily_cost: number;
|
|
70
|
+
num_scheduled_days: number | null;
|
|
71
|
+
note: string;
|
|
72
|
+
}
|
|
73
|
+
export interface WalletBalance {
|
|
74
|
+
balance_usd: number;
|
|
75
|
+
held_usd: number;
|
|
76
|
+
}
|
|
77
|
+
export interface Transaction {
|
|
78
|
+
id: string;
|
|
79
|
+
amount: number;
|
|
80
|
+
balance_after: number;
|
|
81
|
+
type: string;
|
|
82
|
+
description: string;
|
|
83
|
+
reference_id: string;
|
|
84
|
+
created_at: string;
|
|
85
|
+
}
|
|
86
|
+
export interface TopupResponse {
|
|
87
|
+
checkout_url: string;
|
|
88
|
+
}
|
|
89
|
+
export interface Project {
|
|
90
|
+
ui_id: string;
|
|
91
|
+
cid: string;
|
|
92
|
+
marketplace: string;
|
|
93
|
+
region: string;
|
|
94
|
+
asin: string | null;
|
|
95
|
+
itemid: string | null;
|
|
96
|
+
keyword: string;
|
|
97
|
+
active: boolean;
|
|
98
|
+
archived: boolean;
|
|
99
|
+
dt_utc: string;
|
|
100
|
+
product_id: string;
|
|
101
|
+
services: {
|
|
102
|
+
atc: number;
|
|
103
|
+
sfb: number;
|
|
104
|
+
pgv: number;
|
|
105
|
+
};
|
|
106
|
+
scheduling: ScheduleEntry[];
|
|
107
|
+
data: {
|
|
108
|
+
serps: Record<string, unknown>;
|
|
109
|
+
};
|
|
110
|
+
unavailable: boolean;
|
|
111
|
+
}
|
|
112
|
+
export interface ProjectListItem {
|
|
113
|
+
ui_id: string;
|
|
114
|
+
marketplace: string;
|
|
115
|
+
region: string;
|
|
116
|
+
asin: string | null;
|
|
117
|
+
itemid: string | null;
|
|
118
|
+
keyword: string;
|
|
119
|
+
active: boolean;
|
|
120
|
+
archived: boolean;
|
|
121
|
+
product_id: string;
|
|
122
|
+
services: {
|
|
123
|
+
atc: number;
|
|
124
|
+
sfb: number;
|
|
125
|
+
pgv: number;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
export interface ScheduleEntry {
|
|
129
|
+
id: string;
|
|
130
|
+
date: string;
|
|
131
|
+
atc: number;
|
|
132
|
+
purchase: number;
|
|
133
|
+
pageview: number;
|
|
134
|
+
}
|
|
135
|
+
export interface ScheduleResponse {
|
|
136
|
+
ui_id: string;
|
|
137
|
+
services: {
|
|
138
|
+
atc: number;
|
|
139
|
+
sfb: number;
|
|
140
|
+
pgv: number;
|
|
141
|
+
};
|
|
142
|
+
scheduling: ScheduleEntry[];
|
|
143
|
+
balance_warning?: BalanceWarning;
|
|
144
|
+
}
|
|
145
|
+
export interface ProjectStatsResponse {
|
|
146
|
+
days: number;
|
|
147
|
+
total: number;
|
|
148
|
+
stats: ProjectStatsDay[];
|
|
149
|
+
}
|
|
150
|
+
export interface ProjectStatsDay {
|
|
151
|
+
date: string;
|
|
152
|
+
dt: string | null;
|
|
153
|
+
services: {
|
|
154
|
+
sfb: ServiceDayStats;
|
|
155
|
+
atc: ServiceDayStats;
|
|
156
|
+
pgv: ServiceDayStats;
|
|
157
|
+
};
|
|
158
|
+
serp: Record<string, unknown> | null;
|
|
159
|
+
ara: Record<string, unknown> | null;
|
|
160
|
+
br: Record<string, unknown> | null;
|
|
161
|
+
sqr: Record<string, unknown> | null;
|
|
162
|
+
ranks: unknown[] | null;
|
|
163
|
+
}
|
|
164
|
+
export interface ServiceDayStats {
|
|
165
|
+
assignments: number | null;
|
|
166
|
+
executed: number;
|
|
167
|
+
}
|
|
168
|
+
export interface Order {
|
|
169
|
+
order_id: string;
|
|
170
|
+
cid: string;
|
|
171
|
+
status: string;
|
|
172
|
+
dt_utc: string;
|
|
173
|
+
items: unknown[];
|
|
174
|
+
campaign: string;
|
|
175
|
+
region: string;
|
|
176
|
+
asin: string | null;
|
|
177
|
+
keyword: string;
|
|
178
|
+
ui_id: string;
|
|
179
|
+
issue_reported: boolean;
|
|
180
|
+
}
|
|
181
|
+
export interface MessageResponse {
|
|
182
|
+
message: string;
|
|
183
|
+
[key: string]: unknown;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { LBClient } from "./client/lb-client.js";
|
|
5
|
+
import { registerAccountTools } from "./tools/account.tools.js";
|
|
6
|
+
import { registerWalletTools } from "./tools/wallet.tools.js";
|
|
7
|
+
import { registerProjectsTools } from "./tools/projects.tools.js";
|
|
8
|
+
import { registerScheduleTools } from "./tools/schedule.tools.js";
|
|
9
|
+
import { registerOrdersTools } from "./tools/orders.tools.js";
|
|
10
|
+
import { registerFeedbackTools } from "./tools/feedback.tools.js";
|
|
11
|
+
import { registerCostTools } from "./tools/cost.tools.js";
|
|
12
|
+
import { validateBaseUrl } from "./utils/validate-url.js";
|
|
13
|
+
const apiKey = process.env.LB_API_KEY;
|
|
14
|
+
if (!apiKey) {
|
|
15
|
+
console.error("LB_API_KEY environment variable is required");
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
let baseUrl = "https://listingbureau.com";
|
|
19
|
+
if (process.env.LB_BASE_URL) {
|
|
20
|
+
try {
|
|
21
|
+
baseUrl = validateBaseUrl(process.env.LB_BASE_URL);
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
console.error(e.message);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const client = new LBClient(apiKey, baseUrl);
|
|
29
|
+
const server = new McpServer({
|
|
30
|
+
name: "listingbureau",
|
|
31
|
+
version: "0.1.0",
|
|
32
|
+
});
|
|
33
|
+
registerAccountTools(server, client);
|
|
34
|
+
registerWalletTools(server, client);
|
|
35
|
+
registerProjectsTools(server, client);
|
|
36
|
+
registerScheduleTools(server, client);
|
|
37
|
+
registerOrdersTools(server, client);
|
|
38
|
+
registerFeedbackTools(server, client);
|
|
39
|
+
registerCostTools(server, client);
|
|
40
|
+
const transport = new StdioServerTransport();
|
|
41
|
+
await server.connect(transport);
|
|
42
|
+
//# sourceMappingURL=index.js.map
|