@lehaotech/walmart-mcp 0.5.4

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.
Files changed (87) hide show
  1. package/.env.example +25 -0
  2. package/CHANGELOG.md +247 -0
  3. package/LICENSE +21 -0
  4. package/README.md +344 -0
  5. package/build/api/advertising/ad-client.d.ts +24 -0
  6. package/build/api/advertising/ad-client.js +174 -0
  7. package/build/api/advertising/advertising-api.d.ts +50 -0
  8. package/build/api/advertising/advertising-api.js +89 -0
  9. package/build/api/client.d.ts +19 -0
  10. package/build/api/client.js +150 -0
  11. package/build/api/feeds/feeds-api.d.ts +15 -0
  12. package/build/api/feeds/feeds-api.js +53 -0
  13. package/build/api/fulfillment/fulfillment-api.d.ts +37 -0
  14. package/build/api/fulfillment/fulfillment-api.js +81 -0
  15. package/build/api/index.d.ts +44 -0
  16. package/build/api/index.js +56 -0
  17. package/build/api/inventory/inventory-api.d.ts +27 -0
  18. package/build/api/inventory/inventory-api.js +49 -0
  19. package/build/api/items/items-api.d.ts +33 -0
  20. package/build/api/items/items-api.js +67 -0
  21. package/build/api/notifications/notifications-api.d.ts +14 -0
  22. package/build/api/notifications/notifications-api.js +33 -0
  23. package/build/api/orders/orders-api.d.ts +32 -0
  24. package/build/api/orders/orders-api.js +47 -0
  25. package/build/api/pricing/pricing-api.d.ts +32 -0
  26. package/build/api/pricing/pricing-api.js +60 -0
  27. package/build/api/reports/reports-api.d.ts +37 -0
  28. package/build/api/reports/reports-api.js +51 -0
  29. package/build/api/returns/returns-api.d.ts +26 -0
  30. package/build/api/returns/returns-api.js +37 -0
  31. package/build/api/settings/settings-api.d.ts +9 -0
  32. package/build/api/settings/settings-api.js +21 -0
  33. package/build/auth/oauth.d.ts +16 -0
  34. package/build/auth/oauth.js +125 -0
  35. package/build/config/environment.d.ts +22 -0
  36. package/build/config/environment.js +50 -0
  37. package/build/index.d.ts +2 -0
  38. package/build/index.js +180 -0
  39. package/build/scripts/client-configs.d.ts +36 -0
  40. package/build/scripts/client-configs.js +132 -0
  41. package/build/scripts/diagnose.d.ts +15 -0
  42. package/build/scripts/diagnose.js +320 -0
  43. package/build/scripts/setup.d.ts +17 -0
  44. package/build/scripts/setup.js +276 -0
  45. package/build/tools/definitions/advertising.d.ts +664 -0
  46. package/build/tools/definitions/advertising.js +315 -0
  47. package/build/tools/definitions/discovery.d.ts +24 -0
  48. package/build/tools/definitions/discovery.js +65 -0
  49. package/build/tools/definitions/feeds.d.ts +46 -0
  50. package/build/tools/definitions/feeds.js +42 -0
  51. package/build/tools/definitions/fulfillment.d.ts +1127 -0
  52. package/build/tools/definitions/fulfillment.js +272 -0
  53. package/build/tools/definitions/inventory.d.ts +392 -0
  54. package/build/tools/definitions/inventory.js +182 -0
  55. package/build/tools/definitions/items.d.ts +447 -0
  56. package/build/tools/definitions/items.js +223 -0
  57. package/build/tools/definitions/notifications.d.ts +84 -0
  58. package/build/tools/definitions/notifications.js +73 -0
  59. package/build/tools/definitions/orders.d.ts +2659 -0
  60. package/build/tools/definitions/orders.js +298 -0
  61. package/build/tools/definitions/pricing.d.ts +724 -0
  62. package/build/tools/definitions/pricing.js +254 -0
  63. package/build/tools/definitions/reports.d.ts +223 -0
  64. package/build/tools/definitions/reports.js +144 -0
  65. package/build/tools/definitions/returns.d.ts +441 -0
  66. package/build/tools/definitions/returns.js +126 -0
  67. package/build/tools/definitions/settings.d.ts +100 -0
  68. package/build/tools/definitions/settings.js +52 -0
  69. package/build/tools/definitions/shared-schemas.d.ts +40 -0
  70. package/build/tools/definitions/shared-schemas.js +47 -0
  71. package/build/tools/definitions/token-management.d.ts +16 -0
  72. package/build/tools/definitions/token-management.js +41 -0
  73. package/build/tools/index.d.ts +6924 -0
  74. package/build/tools/index.js +379 -0
  75. package/build/utils/api-error.d.ts +41 -0
  76. package/build/utils/api-error.js +97 -0
  77. package/build/utils/endpoint-catalog.d.ts +22 -0
  78. package/build/utils/endpoint-catalog.js +89 -0
  79. package/build/utils/env-file.d.ts +12 -0
  80. package/build/utils/env-file.js +27 -0
  81. package/build/utils/known-issues.d.ts +29 -0
  82. package/build/utils/known-issues.js +122 -0
  83. package/build/utils/logger.d.ts +15 -0
  84. package/build/utils/logger.js +56 -0
  85. package/build/utils/rate-limiter.d.ts +51 -0
  86. package/build/utils/rate-limiter.js +109 -0
  87. package/package.json +1 -0
@@ -0,0 +1,27 @@
1
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
2
+ import { join } from 'path';
3
+ /**
4
+ * Insert or update `KEY=VALUE` pairs in a .env file, preserving the rest of
5
+ * the file. An existing (optionally commented-out) line for a key is replaced
6
+ * in place; otherwise the pair is appended.
7
+ *
8
+ * The replacement uses a *function* form of `String.prototype.replace` so that
9
+ * values containing `$` sequences (e.g. `$1`, `$&`, `$$`) are written literally
10
+ * instead of being interpreted as regex replacement patterns. Walmart access
11
+ * tokens and client secrets are opaque and can contain `$`, which would
12
+ * otherwise corrupt the persisted value and break authentication on restart.
13
+ */
14
+ export function upsertEnvVars(updates, envPath = join(process.cwd(), '.env')) {
15
+ let content = existsSync(envPath) ? readFileSync(envPath, 'utf-8') : '';
16
+ for (const [key, value] of Object.entries(updates)) {
17
+ const regex = new RegExp(`^(#\\s*)?${key}=.*$`, 'gm');
18
+ const newLine = `${key}=${value}`;
19
+ if (regex.test(content)) {
20
+ content = content.replace(regex, () => newLine);
21
+ }
22
+ else {
23
+ content += `\n${newLine}`;
24
+ }
25
+ }
26
+ writeFileSync(envPath, content, 'utf-8');
27
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Walmart known issues / hint lookup.
3
+ *
4
+ * When the marketplace API returns a 4xx/5xx for a documented "broken or
5
+ * deprecated endpoint", we attach a hint to the error response so the LLM can
6
+ * fall back without burning more tokens guessing. This file is the single
7
+ * source of truth — keep README.md "Known Issues" section aligned.
8
+ *
9
+ * Add an entry when:
10
+ * - Walmart's endpoint is confirmed broken or removed (404/405/520).
11
+ * - The endpoint requires a seller-program enrollment (Repricer / WFS / Ads)
12
+ * and the failure pattern is consistent enough that a hint helps.
13
+ * - There is a deterministic workaround a calling agent can apply.
14
+ *
15
+ * Do NOT add entries for:
16
+ * - Transient infrastructure errors (those should retry, not steer).
17
+ * - Per-call validation errors (those should be caught by zod, not here).
18
+ */
19
+ export interface KnownIssue {
20
+ /** HTTP method, uppercase. */
21
+ method: string;
22
+ /** Regex against the request URL path (not host). */
23
+ pathPattern: RegExp;
24
+ /** What the LLM should do instead. Keep one sentence, actionable. */
25
+ hint: string;
26
+ }
27
+ export declare const KNOWN_ISSUES: ReadonlyArray<KnownIssue>;
28
+ /** Returns the workaround hint for a known-broken endpoint, or undefined. */
29
+ export declare function findKnownIssueHint(method: string | undefined, url: string | undefined): string | undefined;
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Walmart known issues / hint lookup.
3
+ *
4
+ * When the marketplace API returns a 4xx/5xx for a documented "broken or
5
+ * deprecated endpoint", we attach a hint to the error response so the LLM can
6
+ * fall back without burning more tokens guessing. This file is the single
7
+ * source of truth — keep README.md "Known Issues" section aligned.
8
+ *
9
+ * Add an entry when:
10
+ * - Walmart's endpoint is confirmed broken or removed (404/405/520).
11
+ * - The endpoint requires a seller-program enrollment (Repricer / WFS / Ads)
12
+ * and the failure pattern is consistent enough that a hint helps.
13
+ * - There is a deterministic workaround a calling agent can apply.
14
+ *
15
+ * Do NOT add entries for:
16
+ * - Transient infrastructure errors (those should retry, not steer).
17
+ * - Per-call validation errors (those should be caught by zod, not here).
18
+ */
19
+ export const KNOWN_ISSUES = [
20
+ // ---------- Insights API ----------
21
+ {
22
+ method: 'GET',
23
+ pathPattern: /\/v3\/insights\/items\/unpublished\/counts/,
24
+ hint: "Walmart's Aurora unpublished-item-service has been returning 404 since 2026-05. " +
25
+ "Use walmart_get_all_items + filter publishedStatus='UNPUBLISHED' client-side.",
26
+ },
27
+ {
28
+ method: 'GET',
29
+ pathPattern: /\/v3\/insights\/items\/listingQuality\/categories/,
30
+ hint: "Walmart removed this Insights aggregation endpoint. No direct replacement; use " +
31
+ "walmart_get_item_quality_details per SKU once that endpoint is restored, or fall back to " +
32
+ "walmart_get_listing_quality for the store-aggregate score.",
33
+ },
34
+ {
35
+ method: 'GET',
36
+ pathPattern: /\/v3\/insights\/items\/listingQuality\/items/,
37
+ hint: "Walmart's documented endpoint signature changed; current implementation returns 405. " +
38
+ "Track via walmart_get_listing_quality (store-aggregate) until docs are updated.",
39
+ },
40
+ // ---------- Returns ----------
41
+ {
42
+ method: 'GET',
43
+ pathPattern: /\/v3\/returns\/count/,
44
+ hint: "Walmart removed /v3/returns/count. Compute client-side: walmart_get_all_returns then " +
45
+ "group by status.",
46
+ },
47
+ // ---------- Settings ----------
48
+ {
49
+ method: 'GET',
50
+ pathPattern: /\/v3\/settings\/shipping/,
51
+ hint: "Walmart's /v3/settings/shipping endpoint returns 404 for sellers without elevated access. " +
52
+ "No known public-API workaround — check Seller Center settings UI manually.",
53
+ },
54
+ // ---------- Items / Hazmat ----------
55
+ {
56
+ method: 'GET',
57
+ pathPattern: /\/v3\/items\/onhold\/hazmat/,
58
+ hint: "walmart_get_hazmat_items now uses POST /v3/items/onhold/search (fixed in v0.3.2). " +
59
+ "If a 405 still appears, the implementation may be calling the old GET path.",
60
+ },
61
+ // ---------- WFS Fulfillment program-gated ----------
62
+ {
63
+ method: 'GET',
64
+ pathPattern: /\/v3\/fulfillment\/inbound-shipments/,
65
+ hint: "WFS endpoints return 404 for sellers without Walmart Fulfillment Services enrollment. " +
66
+ "Enroll at https://seller.walmart.com/ → Walmart Fulfillment Services; otherwise this and " +
67
+ "all walmart_*_wfs_* / walmart_*_inbound_* / walmart_*_mcs_* tools will fail.",
68
+ },
69
+ {
70
+ method: 'GET',
71
+ pathPattern: /\/v3\/fulfillment\/carriers/,
72
+ hint: "Ship-with-Walmart carriers endpoint requires Ship with Walmart enrollment. " +
73
+ "If your seller account is not enrolled, walmart_get_shipping_carriers, walmart_create_shipping_label, " +
74
+ "and walmart_get_shipping_estimate will all 404.",
75
+ },
76
+ // ---------- Repricer program-gated ----------
77
+ {
78
+ method: 'GET',
79
+ pathPattern: /\/v3\/repricer\/strategies/,
80
+ hint: "Walmart Repricer is opt-in; 403 means your account is not enrolled. Apply via Seller Center " +
81
+ "(Pro Seller badge usually required) before walmart_*_repricer_* tools will work.",
82
+ },
83
+ {
84
+ method: 'POST',
85
+ pathPattern: /\/v3\/repricer\/strategies/,
86
+ hint: "Walmart Repricer 403 means your account is not enrolled. Apply via Seller Center " +
87
+ "(Pro Seller badge required).",
88
+ },
89
+ // ---------- Notifications / Subscriptions ----------
90
+ {
91
+ method: 'GET',
92
+ pathPattern: /\/v3\/notifications\/subscriptions/,
93
+ hint: "Walmart Webhooks API requires explicit allowlisting per seller account. If you see 404, " +
94
+ "request access via Seller Support before relying on walmart_*_subscription tools.",
95
+ },
96
+ // ---------- Reports — async download ----------
97
+ {
98
+ method: 'GET',
99
+ pathPattern: /\/v3\/reports\/reportRequests\/.+\/download/,
100
+ hint: "Report download URLs are valid only after status=READY. If you get 404 or 410, the report " +
101
+ "may have expired (Walmart keeps reports ~30 days). Re-request via walmart_create_report.",
102
+ },
103
+ // ---------- Walmart Connect Ads — endpoint catch-all ----------
104
+ // The ad client uses a different base URL, so these patterns are advisory.
105
+ {
106
+ method: 'GET',
107
+ pathPattern: /\/api-proxy\/service\/WPA\/Api/,
108
+ hint: "Walmart Connect (Advertising) needs WALMART_AD_CONSUMER_ID + WALMART_AD_PRIVATE_KEY env " +
109
+ "vars. Apply for Walmart Connect at https://www.walmartconnect.com/ first.",
110
+ },
111
+ ];
112
+ /** Returns the workaround hint for a known-broken endpoint, or undefined. */
113
+ export function findKnownIssueHint(method, url) {
114
+ if (!method || !url)
115
+ return undefined;
116
+ const m = method.toUpperCase();
117
+ for (const issue of KNOWN_ISSUES) {
118
+ if (issue.method === m && issue.pathPattern.test(url))
119
+ return issue.hint;
120
+ }
121
+ return undefined;
122
+ }
@@ -0,0 +1,15 @@
1
+ interface ComponentLogger {
2
+ error: (msg: string, meta?: object) => void;
3
+ warn: (msg: string, meta?: object) => void;
4
+ info: (msg: string, meta?: object) => void;
5
+ debug: (msg: string, meta?: object) => void;
6
+ http: (msg: string, meta?: object) => void;
7
+ }
8
+ export declare function createLogger(component: string): ComponentLogger;
9
+ export declare const serverLogger: ComponentLogger;
10
+ export declare const apiLogger: ComponentLogger;
11
+ export declare const authLogger: ComponentLogger;
12
+ export declare const toolLogger: ComponentLogger;
13
+ export declare const feedLogger: ComponentLogger;
14
+ export declare function truncateData(data: unknown, maxLen?: number): string;
15
+ export {};
@@ -0,0 +1,56 @@
1
+ import winston from 'winston';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ import { mkdirSync } from 'fs';
5
+ const LOG_DIR = join(homedir(), '.walmart-mcp', 'logs');
6
+ const LOG_LEVEL = process.env.WALMART_LOG_LEVEL || 'info';
7
+ const ENABLE_FILE_LOGGING = process.env.WALMART_ENABLE_FILE_LOGGING === 'true';
8
+ const consoleFormat = winston.format.combine(winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.printf(({ level, message, timestamp, ...meta }) => {
9
+ const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';
10
+ return `[${timestamp}] [${level.toUpperCase()}] ${message}${metaStr}`;
11
+ }));
12
+ const transports = [
13
+ new winston.transports.Console({
14
+ format: consoleFormat,
15
+ stderrLevels: ['error', 'warn', 'info', 'http', 'verbose', 'debug', 'silly'],
16
+ }),
17
+ ];
18
+ if (ENABLE_FILE_LOGGING) {
19
+ try {
20
+ mkdirSync(LOG_DIR, { recursive: true });
21
+ }
22
+ catch { /* ignore */ }
23
+ transports.push(new winston.transports.File({
24
+ filename: join(LOG_DIR, 'error.log'),
25
+ level: 'error',
26
+ maxsize: 5 * 1024 * 1024,
27
+ maxFiles: 5,
28
+ }), new winston.transports.File({
29
+ filename: join(LOG_DIR, 'combined.log'),
30
+ maxsize: 10 * 1024 * 1024,
31
+ maxFiles: 5,
32
+ }));
33
+ }
34
+ const logger = winston.createLogger({
35
+ level: LOG_LEVEL,
36
+ transports,
37
+ exitOnError: false,
38
+ });
39
+ export function createLogger(component) {
40
+ return {
41
+ error: (msg, meta) => logger.error(`[${component}] ${msg}`, meta),
42
+ warn: (msg, meta) => logger.warn(`[${component}] ${msg}`, meta),
43
+ info: (msg, meta) => logger.info(`[${component}] ${msg}`, meta),
44
+ debug: (msg, meta) => logger.debug(`[${component}] ${msg}`, meta),
45
+ http: (msg, meta) => logger.http(`[${component}] ${msg}`, meta),
46
+ };
47
+ }
48
+ export const serverLogger = createLogger('Server');
49
+ export const apiLogger = createLogger('API');
50
+ export const authLogger = createLogger('Auth');
51
+ export const toolLogger = createLogger('Tool');
52
+ export const feedLogger = createLogger('Feed');
53
+ export function truncateData(data, maxLen = 1000) {
54
+ const str = typeof data === 'string' ? data : JSON.stringify(data);
55
+ return str.length > maxLen ? str.substring(0, maxLen) + '...[truncated]' : str;
56
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Sliding window rate limiter.
3
+ * Tracks requests in a time window and proactively blocks
4
+ * before hitting Walmart's API limits.
5
+ *
6
+ * Walmart Marketplace: ~20 requests/second (token bucket)
7
+ * Walmart Advertising: ~10 requests/second
8
+ */
9
+ export declare class RateLimiter {
10
+ private maxRequests;
11
+ private windowMs;
12
+ private name;
13
+ private timestamps;
14
+ /** Latest x-current-token-count reported by Walmart (per-endpoint bucket). */
15
+ private latestServerTokens;
16
+ /** Latest x-next-replenish-time ISO 8601 string reported by Walmart. */
17
+ private latestReplenishTime;
18
+ /** When latestServerTokens was last updated (epoch ms). */
19
+ private latestServerSeenAt;
20
+ constructor(maxRequests: number, windowMs: number, name?: string);
21
+ /** Returns wait-time in ms (0 if allowed now). */
22
+ check(): number;
23
+ /** Synchronous acquire: throws if the request would exceed the limit. */
24
+ acquire(): void;
25
+ /** Async acquire: waits instead of throwing. */
26
+ acquireAsync(): Promise<void>;
27
+ /**
28
+ * Update from Walmart response headers. Caches the latest token count +
29
+ * replenish time so getStatus() can surface them via the
30
+ * walmart_get_rate_budget MCP tool.
31
+ */
32
+ updateFromHeaders(headers: Record<string, string>): void;
33
+ /** Snapshot for the rate-budget MCP tool. */
34
+ getStatus(): {
35
+ name: string;
36
+ localMaxRequests: number;
37
+ localWindowMs: number;
38
+ localCurrentCount: number;
39
+ localRemaining: number;
40
+ serverTokensRemaining: number | null;
41
+ serverReplenishTime: string | null;
42
+ serverTokensSeenAt: string | null;
43
+ };
44
+ private prune;
45
+ get currentCount(): number;
46
+ get remaining(): number;
47
+ }
48
+ export declare class RateLimitError extends Error {
49
+ waitMs: number;
50
+ constructor(message: string, waitMs: number);
51
+ }
@@ -0,0 +1,109 @@
1
+ import { apiLogger } from './logger.js';
2
+ /**
3
+ * Sliding window rate limiter.
4
+ * Tracks requests in a time window and proactively blocks
5
+ * before hitting Walmart's API limits.
6
+ *
7
+ * Walmart Marketplace: ~20 requests/second (token bucket)
8
+ * Walmart Advertising: ~10 requests/second
9
+ */
10
+ export class RateLimiter {
11
+ maxRequests;
12
+ windowMs;
13
+ name;
14
+ timestamps = [];
15
+ /** Latest x-current-token-count reported by Walmart (per-endpoint bucket). */
16
+ latestServerTokens = null;
17
+ /** Latest x-next-replenish-time ISO 8601 string reported by Walmart. */
18
+ latestReplenishTime = null;
19
+ /** When latestServerTokens was last updated (epoch ms). */
20
+ latestServerSeenAt = null;
21
+ constructor(maxRequests, windowMs, name = 'default') {
22
+ this.maxRequests = maxRequests;
23
+ this.windowMs = windowMs;
24
+ this.name = name;
25
+ }
26
+ /** Returns wait-time in ms (0 if allowed now). */
27
+ check() {
28
+ this.prune();
29
+ if (this.timestamps.length < this.maxRequests)
30
+ return 0;
31
+ const oldest = this.timestamps[0];
32
+ const waitMs = (oldest ?? Date.now()) + this.windowMs - Date.now();
33
+ return Math.max(0, waitMs);
34
+ }
35
+ /** Synchronous acquire: throws if the request would exceed the limit. */
36
+ acquire() {
37
+ const waitMs = this.check();
38
+ if (waitMs > 0) {
39
+ apiLogger.warn(`[RateLimiter:${this.name}] Rate limit reached (${this.maxRequests}/${this.windowMs}ms). Need to wait ${waitMs}ms.`);
40
+ throw new RateLimitError(`Rate limit reached for ${this.name}. Try again in ${Math.ceil(waitMs / 1000)} seconds.`, waitMs);
41
+ }
42
+ this.timestamps.push(Date.now());
43
+ }
44
+ /** Async acquire: waits instead of throwing. */
45
+ async acquireAsync() {
46
+ const waitMs = this.check();
47
+ if (waitMs > 0) {
48
+ apiLogger.warn(`[RateLimiter:${this.name}] Throttling for ${waitMs}ms (${this.maxRequests}/${this.windowMs}ms)`);
49
+ await new Promise((resolve) => setTimeout(resolve, waitMs));
50
+ }
51
+ this.timestamps.push(Date.now());
52
+ }
53
+ /**
54
+ * Update from Walmart response headers. Caches the latest token count +
55
+ * replenish time so getStatus() can surface them via the
56
+ * walmart_get_rate_budget MCP tool.
57
+ */
58
+ updateFromHeaders(headers) {
59
+ const remaining = headers['x-current-token-count'];
60
+ if (remaining !== undefined) {
61
+ const count = parseInt(remaining, 10);
62
+ if (!Number.isNaN(count)) {
63
+ this.latestServerTokens = count;
64
+ this.latestServerSeenAt = Date.now();
65
+ if (count <= 5) {
66
+ apiLogger.warn(`[RateLimiter:${this.name}] Only ${count} API tokens remaining. Replenish at: ${headers['x-next-replenish-time'] || 'unknown'}`);
67
+ }
68
+ }
69
+ }
70
+ const replenish = headers['x-next-replenish-time'];
71
+ if (replenish !== undefined)
72
+ this.latestReplenishTime = replenish;
73
+ }
74
+ /** Snapshot for the rate-budget MCP tool. */
75
+ getStatus() {
76
+ return {
77
+ name: this.name,
78
+ localMaxRequests: this.maxRequests,
79
+ localWindowMs: this.windowMs,
80
+ localCurrentCount: this.currentCount,
81
+ localRemaining: this.remaining,
82
+ serverTokensRemaining: this.latestServerTokens,
83
+ serverReplenishTime: this.latestReplenishTime,
84
+ serverTokensSeenAt: this.latestServerSeenAt != null ? new Date(this.latestServerSeenAt).toISOString() : null,
85
+ };
86
+ }
87
+ prune() {
88
+ const cutoff = Date.now() - this.windowMs;
89
+ while (this.timestamps.length > 0 && (this.timestamps[0] ?? 0) <= cutoff) {
90
+ this.timestamps.shift();
91
+ }
92
+ }
93
+ get currentCount() {
94
+ this.prune();
95
+ return this.timestamps.length;
96
+ }
97
+ get remaining() {
98
+ this.prune();
99
+ return Math.max(0, this.maxRequests - this.timestamps.length);
100
+ }
101
+ }
102
+ export class RateLimitError extends Error {
103
+ waitMs;
104
+ constructor(message, waitMs) {
105
+ super(message);
106
+ this.waitMs = waitMs;
107
+ this.name = 'RateLimitError';
108
+ }
109
+ }
package/package.json ADDED
@@ -0,0 +1 @@
1
+ { "name": "@lehaotech/walmart-mcp", "version": "0.5.4", "publishConfig": { "access": "public" }, "description": "Walmart Marketplace MCP Server for AI-powered seller operations", "type": "module", "main": "build/index.js", "types": "build/index.d.ts", "bin": { "walmart-mcp": "build/index.js" }, "files": [ "build", "README.md", "CHANGELOG.md", "LICENSE", ".env.example" ], "scripts": { "build": "tsc && tsc-alias", "start": "node build/index.js", "dev": "tsx src/index.ts", "diagnose": "tsx src/scripts/diagnose.ts", "test": "vitest", "test:run": "vitest run", "test:sandbox": "npm run build && node test-sandbox.mjs", "inspect": "npm run build && npx @modelcontextprotocol/inspector node build/index.js", "prepublishOnly": "npm run build", "setup": "tsx src/scripts/setup.ts", "typecheck": "tsc --noEmit", "test:coverage": "vitest run --coverage" }, "keywords": [ "mcp", "model-context-protocol", "walmart", "marketplace", "seller", "claude", "ai" ], "author": "Fakang Yu", "license": "MIT", "repository": { "type": "git", "url": "git+https://github.com/yufakang0826-hue/walmart-mcp.git" }, "bugs": { "url": "https://github.com/yufakang0826-hue/walmart-mcp/issues" }, "homepage": "https://github.com/yufakang0826-hue/walmart-mcp#readme", "dependencies": { "@modelcontextprotocol/sdk": "^1.21.0", "axios": "^1.7.9", "dotenv": "^17.0.0", "winston": "^3.19.0", "zod": "^3.23.8", "zod-to-json-schema": "^3.24.1" }, "devDependencies": { "@types/node": "^22", "tsc-alias": "^1.8.10", "tsx": "^4.19.0", "typescript": "^5.9.0", "vitest": "^3", "@vitest/coverage-v8": "^3" }, "engines": { "node": ">=22" }}