@reneturcios/martdata 0.0.0-stage → 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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rene Turcios
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 CHANGED
@@ -1,3 +1,152 @@
1
- # Temporary Holding Version
1
+ # martdata
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ martdata is a small local bridge to the hosted HasData
4
+ Walmart MCP server, which returns Walmart storefront
5
+ data as JSON. It can pull one product page in full from
6
+ an item id or URL, page through that product's customer
7
+ reviews, and run keyword or category searches across a
8
+ storefront with price, fulfillment and sort filters.
9
+
10
+ The bridge holds no product data of its own. It answers
11
+ the tool list locally, exactly as captured from the
12
+ live endpoint, and forwards each tool call upstream,
13
+ returning whatever comes back untouched. The captured
14
+ surface is three read-only fetches over public
15
+ storefront data: there is no cart, checkout, order or
16
+ payment tool in it, and no individual contact data is
17
+ returned.
18
+
19
+ ## Tools
20
+
21
+ - `hasdata_walmart_product_getWalmartProduct` — fetch
22
+ one Walmart product in full, by `itemId` or by `url`
23
+ (the URL wins when both are given). Optional:
24
+ `domain` (`walmart.com` / `walmart.ca`), `language`
25
+ (`en` / `es` / `fr`), and `otherOffers` to also
26
+ collect competing sellers' offers. Returns title,
27
+ brand, price and availability, the buy-box seller,
28
+ ratings, variants, fulfillment details and the
29
+ other-sellers block. No argument is marked required
30
+ in the captured schema: `itemId` and `url` are
31
+ alternatives for each other.
32
+ - `hasdata_walmart_reviews_getWalmartReviews` — the
33
+ customer reviews of one product, ten a page, by
34
+ `itemId` or `url`. Optional: `domain`, `language`,
35
+ `page`, `sort` (most relevant, most recent, most
36
+ helpful, highest or lowest rated, oldest), `rating`
37
+ (one star value), `aspectId` (one frequent-mention
38
+ topic), `condition`, and `verifiedPurchasesOnly`.
39
+ Returns each review with its rating, text, author and
40
+ vote counts, plus the item's rating breakdown, AI
41
+ review summary, per-aspect scores and the filters
42
+ block naming the values later calls can filter by.
43
+ - `hasdata_walmart_search_getSearchResults` — search
44
+ a storefront by keyword `q`, or browse a category
45
+ with `catId`, or scrape a full search URL via `url`.
46
+ Optional: `domain`, `language`, `sort` (best match,
47
+ price low-to-high or high-to-low, bestseller, highly
48
+ rated, new arrivals), `page`, `minPrice` and
49
+ `maxPrice`, `deliveryType` (`shipping` / `pickup`),
50
+ and `facet` narrowing in `name:value` form. Returns
51
+ the product list with prices, ratings, sellers and
52
+ fulfillment details, plus the facets block and
53
+ pagination.
54
+
55
+ ## Configuration
56
+
57
+ - `HASDATA_WALMART_MCP_URL` (optional) — override the
58
+ upstream endpoint. Defaults to
59
+ `https://mcp.hasdata.com/mcp?apis=walmart`. (The
60
+ override hook is this rebuild's own labelled
61
+ reconstruction.)
62
+ - `HASDATA_API_KEY` (optional) — when set, every
63
+ upstream request carries an `x-api-key: <key>`
64
+ header, for the caller's own HasData API key. When
65
+ it is not set, no key header is sent. (The header
66
+ name and the env name are pinned by the original's
67
+ registry record; forwarding the key from this env
68
+ var is a labelled reconstruction — the original
69
+ surface was captured keyless.)
70
+
71
+ ### Forwarding mechanics
72
+
73
+ On the first tool call the client opens a streamable
74
+ HTTP session upstream: a JSON-RPC `initialize` request
75
+ (protocolVersion `2025-03-26`, clientInfo name
76
+ `martdata`), then a `notifications/initialized`
77
+ notification, then the `tools/call` request carrying
78
+ the caller's arguments unchanged. When the upstream
79
+ answers `initialize` with an `Mcp-Session-Id` header,
80
+ that value rides on every later request of the
81
+ session, which is reused for the life of the process.
82
+ Replies may arrive as plain JSON or as server-sent
83
+ events; both are read.
84
+
85
+ Successful upstream results pass through verbatim,
86
+ including any `isError` flag the upstream sets.
87
+ Failures — a JSON-RPC error, a non-2xx status, an
88
+ unreadable response, or a request that cannot be
89
+ completed — come back as an `isError` result whose
90
+ text starts with `martdata error:` (this rendering is
91
+ this rebuild's own labelled reconstruction).
92
+
93
+ ## CLI
94
+
95
+ Each tool is also a subcommand taking one JSON
96
+ argument string:
97
+
98
+ ```bash
99
+ npx @reneturcios/martdata hasdata_walmart_product_getWalmartProduct '{"itemId":"14977205582"}'
100
+ npx @reneturcios/martdata hasdata_walmart_reviews_getWalmartReviews '{"itemId":"14977205582","sort":"mostRecent"}'
101
+ npx @reneturcios/martdata hasdata_walmart_search_getSearchResults '{"q":"coffee maker","maxPrice":90}'
102
+ npx @reneturcios/martdata --version
103
+ ```
104
+
105
+ Exit codes: `0` on success, `1` on an `isError`
106
+ result, `2` on a usage error.
107
+
108
+ ## MCP server
109
+
110
+ ```bash
111
+ npx -y @reneturcios/martdata mcp
112
+ ```
113
+
114
+ MCP client config:
115
+
116
+ ```json
117
+ {
118
+ "mcpServers": {
119
+ "martdata": {
120
+ "command": "npx",
121
+ "args": ["-y", "@reneturcios/martdata", "mcp"]
122
+ }
123
+ }
124
+ }
125
+ ```
126
+
127
+ ## Docker
128
+
129
+ ```bash
130
+ docker run -i ghcr.io/cloudcorprecords/martdata
131
+ docker run --rm ghcr.io/cloudcorprecords/martdata --version
132
+ ```
133
+
134
+ The container's default command is `mcp`, so the first
135
+ form is a stdio MCP server; any other arguments reach
136
+ the CLI normally.
137
+
138
+ ## Development
139
+
140
+ ```bash
141
+ npm install
142
+ npm run build
143
+ npm test
144
+ npm run dev
145
+ ```
146
+
147
+ The test suite runs entirely against a stubbed
148
+ JSON-RPC upstream — no live network calls.
149
+
150
+ ## License
151
+
152
+ MIT — see `LICENSE`.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * martdata CLI.
4
+ *
5
+ * martdata <tool> '<json-args>'
6
+ * martdata mcp
7
+ * martdata --version
8
+ *
9
+ * <tool> is one of the 3 forwarded tools. Each tool
10
+ * subcommand takes a single JSON argument string holding
11
+ * that tool's arguments, forwards the call the same way
12
+ * the MCP path does, and prints the forwarded result
13
+ * content. Exit codes: 0 success, 1 on an isError
14
+ * result, 2 usage error.
15
+ */
16
+ import { callTool, TOOL_NAMES, VERSION } from "./forward.js";
17
+ function usage() {
18
+ console.error(`Usage:
19
+ martdata <tool> '<json-args>' one of: ${TOOL_NAMES.join(", ")}
20
+ martdata mcp
21
+ martdata --version`);
22
+ process.exit(2);
23
+ }
24
+ function firstText(result) {
25
+ const content = result.content;
26
+ if (Array.isArray(content)) {
27
+ for (const item of content) {
28
+ if (item !== null &&
29
+ typeof item === "object" &&
30
+ item.type === "text" &&
31
+ typeof item.text === "string") {
32
+ return item.text;
33
+ }
34
+ }
35
+ }
36
+ return typeof content === "string" ? content : JSON.stringify(content);
37
+ }
38
+ async function main() {
39
+ const [cmd, ...rest] = process.argv.slice(2);
40
+ if (cmd === "--version" || cmd === "-v") {
41
+ console.log(VERSION);
42
+ return;
43
+ }
44
+ if (cmd === "mcp") {
45
+ if (rest.length !== 0)
46
+ usage();
47
+ const { startMcpServer } = await import("./mcp.js");
48
+ await startMcpServer();
49
+ return;
50
+ }
51
+ if (!TOOL_NAMES.includes(cmd ?? ""))
52
+ usage();
53
+ if (rest.length > 1)
54
+ usage();
55
+ let args = {};
56
+ if (rest.length === 1) {
57
+ try {
58
+ const parsed = JSON.parse(rest[0]);
59
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
60
+ usage();
61
+ }
62
+ args = parsed;
63
+ }
64
+ catch {
65
+ console.error("error: argument must be a JSON object string");
66
+ process.exit(2);
67
+ }
68
+ }
69
+ const result = await callTool(cmd, args);
70
+ if (result.isError) {
71
+ console.error(`error: ${firstText(result)}`);
72
+ process.exit(1);
73
+ }
74
+ console.log(typeof result.content === "string"
75
+ ? result.content
76
+ : JSON.stringify(result.content, null, 2));
77
+ }
78
+ void main();
79
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * martdata core: a forwarding client for the hosted
3
+ * HasData Walmart MCP server.
4
+ *
5
+ * Nothing is scraped or searched locally. tools/list is
6
+ * answered from the literal definitions below, taken
7
+ * verbatim from a live capture of the upstream server
8
+ * (name, title, description and inputSchema exactly as
9
+ * captured, title key included, and with NO `required`
10
+ * key on any inputSchema, exactly as captured). A
11
+ * tools/call travels upstream over a streamable-HTTP
12
+ * JSON-RPC session: an initialize POST, a
13
+ * notifications/initialized POST, then the tools/call
14
+ * POST, carrying the Mcp-Session-Id response header on
15
+ * later requests when the upstream issues one. The
16
+ * session opens lazily on the first forwarded call and
17
+ * is reused for the client's life.
18
+ *
19
+ * The endpoint is pinned to
20
+ * https://mcp.hasdata.com/mcp?apis=walmart — the query
21
+ * string belongs to the pinned URL — and may be replaced
22
+ * with the HASDATA_WALMART_MCP_URL environment variable
23
+ * (that override is a labelled reconstruction). When
24
+ * HASDATA_API_KEY is set, every upstream request carries
25
+ * an `x-api-key: <key>` header (header name pinned by the
26
+ * registry record's remote declaration; forwarding the
27
+ * key from this env var is a labelled reconstruction, as
28
+ * the capture was taken keyless). When it is unset, no
29
+ * key header goes out, and no Authorization header is
30
+ * sent in either case.
31
+ *
32
+ * A successful upstream result is returned exactly as
33
+ * received, isError flag and extra fields included.
34
+ * Failures — an upstream JSON-RPC error, a non-2xx
35
+ * status, a body that cannot be parsed, or a fetch that
36
+ * throws or times out — become an isError result whose
37
+ * text begins with `martdata error:` (that rendering is
38
+ * a labelled reconstruction). Replies may be plain JSON
39
+ * or SSE (`data:` lines); the JSON-RPC message whose id
40
+ * matches the request wins.
41
+ */
42
+ import type { ForwardDeps, ToolArgs, ToolDef, ToolResult } from "./types.js";
43
+ export declare const VERSION = "0.1.0";
44
+ export declare const DEFAULT_ENDPOINT_URL = "https://mcp.hasdata.com/mcp?apis=walmart";
45
+ export declare const DEFAULT_TIMEOUT_MS = 30000;
46
+ export declare const PROTOCOL_VERSION = "2025-03-26";
47
+ export declare const TOOL_DEFS: ToolDef[];
48
+ export declare const TOOL_NAMES: string[];
49
+ /** Whether `name` belongs to the captured surface. */
50
+ export declare function isKnownTool(name: string): boolean;
51
+ /**
52
+ * Read a JSON-RPC response body, tolerating SSE framing.
53
+ * Returns the message whose id matches `expectedId` when
54
+ * present, otherwise the last parseable message, otherwise
55
+ * null when nothing in the body parses.
56
+ */
57
+ export declare function parseRpcBody(text: string, expectedId?: number): Record<string, unknown> | null;
58
+ /**
59
+ * A forwarding client that holds a single upstream
60
+ * session, opened lazily on first use and reused from
61
+ * then on (for the process lifetime in the MCP server,
62
+ * or for a single invocation in the CLI).
63
+ */
64
+ export declare class MartdataClient {
65
+ private readonly deps;
66
+ private sessionId;
67
+ private ready;
68
+ private sessionPromise;
69
+ private idCounter;
70
+ constructor(deps?: ForwardDeps);
71
+ private fetchFn;
72
+ private endpointUrl;
73
+ private apiKey;
74
+ private timeoutMs;
75
+ private nextId;
76
+ private post;
77
+ private ensureSession;
78
+ /** Forward one tool call; upstream failures come back as isError results. */
79
+ callTool(name: string, args: ToolArgs): Promise<ToolResult>;
80
+ }
81
+ /** Build a forwarding client; tests inject a fake fetch and env through deps. */
82
+ export declare function createClient(deps?: ForwardDeps): MartdataClient;
83
+ /** One-shot helper: a fresh client for a single call (the CLI path). */
84
+ export declare function callTool(name: string, args: ToolArgs, deps?: ForwardDeps): Promise<ToolResult>;
@@ -0,0 +1,430 @@
1
+ export const VERSION = "0.1.0";
2
+ export const DEFAULT_ENDPOINT_URL = "https://mcp.hasdata.com/mcp?apis=walmart";
3
+ export const DEFAULT_TIMEOUT_MS = 30000;
4
+ export const PROTOCOL_VERSION = "2025-03-26";
5
+ /* ------------------------------------------------------------------ */
6
+ /* Tool definitions (tools/list literals, verbatim from the live */
7
+ /* capture in harness/fixtures/hasdata-walmart-tools-original.json) */
8
+ /* ------------------------------------------------------------------ */
9
+ export const TOOL_DEFS = [
10
+ {
11
+ "name": "hasdata_walmart_product_getWalmartProduct",
12
+ "title": "walmart_product: GET /",
13
+ "description": "Get Walmart Product Details\n\nScrapes one Walmart product page on a chosen storefront by item id or URL. Returns title, brand, model, UPC, condition, availability, price with strikethrough before-price and unit price, the seller holding the buy box with its rating and return policy, badges, SNAP EBT eligibility, Walmart+ savings, star rating with the per-star review breakdown and AI review summaries, images, category path, highlights, specifications, AI-generated key item features, variant axes with every option and the itemId each combination resolves to, fulfillment details, and the other-sellers block: how many competitors the page advertises always and, when the page shows it, the cheapest competing price, plus - when otherOffers is enabled - the offer list with each seller name, storefront URL, price, condition, shipping cost, delivery date and return policy. Use for price and buy-box monitoring, seller and marketplace competitor tracking, assortment enrichment of item ids harvested from search, and variant mapping.",
14
+ "inputSchema": {
15
+ "type": "object",
16
+ "properties": {
17
+ "itemId": {
18
+ "type": "string",
19
+ "description": "Walmart item id, taken from a product URL or from the id field of the Walmart Search API response. On `walmart.com` it is numeric (for example `14977205582`), on `walmart.ca` an alphanumeric code (for example `6NZMJ5CW6MH2`). Required unless `url` is provided."
20
+ },
21
+ "url": {
22
+ "type": "string",
23
+ "description": "A full Walmart product URL to scrape as is. When provided, it overrides `itemId` and the storefront is taken from the URL itself. Required unless `itemId` is provided."
24
+ },
25
+ "domain": {
26
+ "type": "string",
27
+ "enum": [
28
+ "walmart.com",
29
+ "walmart.ca"
30
+ ],
31
+ "description": "Walmart storefront the item belongs to. Each storefront has its own catalog, item ids, prices and currency, so an id from one storefront does not resolve on another. Ignored when `url` is provided. Default is `walmart.com`."
32
+ },
33
+ "language": {
34
+ "type": "string",
35
+ "enum": [
36
+ "en",
37
+ "es",
38
+ "fr"
39
+ ],
40
+ "description": "Language of the product details. Availability depends on the storefront - `walmart.com` serves `en` and `es`, `walmart.ca` serves `en` and `fr`. A language the storefront does not support falls back to its default."
41
+ },
42
+ "otherOffers": {
43
+ "type": "boolean",
44
+ "description": "Also collect the offers of other sellers competing for this item - each seller name, storefront, price, condition, shipping cost, delivery date and return policy. This takes an extra request to Walmart and costs 5 credits on top of the base 10, whether or not the item turns out to have competing sellers. How many competitors the item advertises, and the cheapest competing price, are returned in the `otherOffers` block whether the switch is on or off, so it can be left off until the count shows there is something to collect. Default is `false`."
45
+ }
46
+ },
47
+ "additionalProperties": false,
48
+ "$schema": "http://json-schema.org/draft-07/schema#"
49
+ }
50
+ },
51
+ {
52
+ "name": "hasdata_walmart_reviews_getWalmartReviews",
53
+ "title": "walmart_reviews: GET /",
54
+ "description": "Get Walmart Product Reviews\n\nScrapes the customer reviews of one Walmart product on a chosen storefront by item id or URL, ten reviews a page. Returns each review with its rating, title, full text with paragraphs preserved, submission date, author, verified-purchase flag, helpful and not-helpful vote counts, badges, marketplace seller, photos and videos, and the review aspects it was tagged with. Alongside the reviews it returns the item rating, how many ratings versus how many written reviews exist, the per-star breakdown, the AI review summary, per-aspect scores such as Quality or Value for money, and a filters block listing exactly which star ratings, frequent mentions and conditions this item can be filtered by, with a count for each - the values in that block are the ones to pass back as request parameters. Sort by most relevant, most recent, most helpful, highest rated, lowest rated or oldest, and filter by star rating, frequent mention, condition or verified purchases only. Use for review mining and sentiment analysis, tracking what buyers praise or complain about per product, monitoring new reviews over time, and pulling only verified-purchase feedback.",
55
+ "inputSchema": {
56
+ "type": "object",
57
+ "properties": {
58
+ "itemId": {
59
+ "type": "string",
60
+ "description": "Walmart item id, taken from a product URL or from the id field of the Walmart Search API response. On `walmart.com` it is numeric (for example `14977205582`), on `walmart.ca` an alphanumeric code (for example `6NZMJ5CW6MH2`). Required unless `url` is provided."
61
+ },
62
+ "url": {
63
+ "type": "string",
64
+ "description": "A full Walmart product URL whose reviews to scrape. When provided, it overrides `itemId` and the storefront is taken from the URL itself. Required unless `itemId` is provided."
65
+ },
66
+ "domain": {
67
+ "type": "string",
68
+ "enum": [
69
+ "walmart.com",
70
+ "walmart.ca"
71
+ ],
72
+ "description": "Walmart storefront the item belongs to. Each storefront has its own catalog, item ids and review pool, so an id from one storefront does not resolve on another. Ignored when `url` is provided. Default is `walmart.com`."
73
+ },
74
+ "language": {
75
+ "type": "string",
76
+ "enum": [
77
+ "en",
78
+ "es",
79
+ "fr"
80
+ ],
81
+ "description": "Language of the review page. Availability depends on the storefront - `walmart.com` serves `en` and `es`, `walmart.ca` serves `en` and `fr`. A language the storefront does not support falls back to its default. Reviews themselves are returned in the language their author wrote them in."
82
+ },
83
+ "page": {
84
+ "type": "number",
85
+ "description": "Page of reviews to return, ten reviews a page. The response reports the last available page in `pagination.totalPages`, the next one in `pagination.nextPage`, and how many reviews the current filters select in `pagination.totalResults`. Note that only reviews carrying written text are paginated, so the ceiling follows `reviewsInformation.totalReviews` rather than the larger `reviewsInformation.totalRatings`. Default is `1`."
86
+ },
87
+ "sort": {
88
+ "type": "string",
89
+ "enum": [
90
+ "mostRelevant",
91
+ "mostRecent",
92
+ "mostHelpful",
93
+ "highestRated",
94
+ "lowestRated",
95
+ "oldest"
96
+ ],
97
+ "description": "Order of the returned reviews, named as the Walmart review page names it. Default is `mostRelevant`."
98
+ },
99
+ "rating": {
100
+ "type": "number",
101
+ "description": "Return only reviews carrying this star rating, from `1` to `5`. The Star rating group of the `filters` block lists the ratings this item actually has, each with the `value` to send here and a `count` of how many reviews to expect."
102
+ },
103
+ "aspectId": {
104
+ "type": "string",
105
+ "description": "Return only reviews mentioning one topic. Send the `value` of the topic you want, taken from the Frequent mentions group of the `filters` block in the response - given `{\"name\": \"Battery Life\", \"value\": \"6049\", \"count\": 8}` you send `6049`, and `count` is how many reviews to expect. **Only one topic per request**, Walmart rejects a list of them. Topics belong to the product rather than to Walmart: a phone offers Battery Life or Display, a coffee offers Flavor or Aroma, and some items offer none at all - so make an unfiltered request first and read the block, instead of reusing a topic id across products."
106
+ },
107
+ "condition": {
108
+ "type": "string",
109
+ "description": "Return only reviews written about one condition of the item. Send the `value` from the Condition group of the `filters` block - given `{\"name\": \"Restored: Like New\", \"value\": \"5\"}` you send `5`. **Only one condition per request.** This group appears for items Walmart sells in several conditions, and only when the request already names one: reach the variant through the `url` parameter with its `conditionGroupCode`, as in `https://www.walmart.com/ip/1028936148?conditionGroupCode=2`, and the block then lists the condition that variant carries. An item sold in a single condition has no such group, and no reviews to separate by it."
110
+ },
111
+ "verifiedPurchasesOnly": {
112
+ "type": "boolean",
113
+ "description": "Return only reviews left by customers whose purchase Walmart confirmed. Narrows the pool considerably, since most reviews are unverified or syndicated from the manufacturer."
114
+ }
115
+ },
116
+ "additionalProperties": false,
117
+ "$schema": "http://json-schema.org/draft-07/schema#"
118
+ }
119
+ },
120
+ {
121
+ "name": "hasdata_walmart_search_getSearchResults",
122
+ "title": "walmart_search: GET /",
123
+ "description": "Get Walmart Search Results\n\nRuns a keyword or category search on a chosen Walmart storefront with pagination, price range and fulfillment filters, facet narrowing, and sort order (best match, price low-to-high, price high-to-low, bestseller, highly rated, new arrivals). Returns the product list with item id, title, product URL, brand, price and strikethrough before-price, star rating, review count, seller, availability, sponsored flag, badges, SNAP EBT eligibility, Walmart+ savings, variants, other offers and fulfillment details (shipping, pickup, delivery messages), plus the facets block listing every filter the query supports with the exact value to send back in the facet parameter, pagination, and the store the prices belong to. Use for SERP monitoring, price and assortment tracking, share-of-shelf analysis, competitor discovery, and harvesting item ids to feed downstream product or reviews endpoints.",
124
+ "inputSchema": {
125
+ "type": "object",
126
+ "properties": {
127
+ "q": {
128
+ "type": "string",
129
+ "description": "The search term for which to get the search results. It can be omitted only when `catId` is provided, to browse a whole category instead of searching."
130
+ },
131
+ "catId": {
132
+ "type": "string",
133
+ "description": "Walmart category id, taken from a category URL (for example `976759_1086446_1229651`). Combine it with `q` to search inside a category, or send it alone to browse the whole category. Required unless `q` is provided."
134
+ },
135
+ "domain": {
136
+ "type": "string",
137
+ "enum": [
138
+ "walmart.com",
139
+ "walmart.ca"
140
+ ],
141
+ "description": "Walmart storefront to search. Each storefront has its own catalog, prices and currency. Default is `walmart.com`."
142
+ },
143
+ "language": {
144
+ "type": "string",
145
+ "enum": [
146
+ "en",
147
+ "es",
148
+ "fr"
149
+ ],
150
+ "description": "Language of the results. Availability depends on the storefront - `walmart.com` serves `en` and `es`, `walmart.ca` serves `en` and `fr`. A language the storefront does not support falls back to its default."
151
+ },
152
+ "sort": {
153
+ "type": "string",
154
+ "enum": [
155
+ "bestMatch",
156
+ "priceLowToHigh",
157
+ "priceHighToLow",
158
+ "bestseller",
159
+ "highlyRated",
160
+ "newArrivals"
161
+ ],
162
+ "description": "The sorting option for the search results."
163
+ },
164
+ "url": {
165
+ "type": "string",
166
+ "description": "A full Walmart search or category URL to scrape as is. When provided, it overrides `q`, `catId` and the other search parameters, and the storefront is taken from the URL itself."
167
+ },
168
+ "page": {
169
+ "type": "number",
170
+ "description": "Page number for pagination (e.g., `1` for the first page, `2` for the second page, etc.). Walmart stops serving results after roughly page 10, returning an empty page beyond that."
171
+ },
172
+ "minPrice": {
173
+ "type": "number",
174
+ "description": "Lower bound of the price range, in the storefront currency."
175
+ },
176
+ "maxPrice": {
177
+ "type": "number",
178
+ "description": "Upper bound of the price range, in the storefront currency."
179
+ },
180
+ "deliveryType": {
181
+ "type": "string",
182
+ "enum": [
183
+ "shipping",
184
+ "pickup"
185
+ ],
186
+ "description": "Keep only the products available with the selected fulfillment method. Default is `shipping`. Note that `pickup` is answered against one Walmart store, so an item in stock nationally can still be unavailable for `pickup` nearby - the response then reports that nothing matched the filters rather than that the query had no results."
187
+ },
188
+ "facet": {
189
+ "type": "string",
190
+ "description": "Walmart filter in the `name:value` form, for example `brand:Great Value`. Every value available for a query is listed in the facets block of the response, each one carrying the exact string to send back here, so a first unfiltered request tells you what can be filtered on. To combine filters, put each one on its own line. The double-pipe form Walmart's own urls use `brand:Great Value||retailer_type:Walmart` is also accepted."
191
+ }
192
+ },
193
+ "additionalProperties": false,
194
+ "$schema": "http://json-schema.org/draft-07/schema#"
195
+ }
196
+ }
197
+ ];
198
+ export const TOOL_NAMES = TOOL_DEFS.map((t) => t.name);
199
+ /** Whether `name` belongs to the captured surface. */
200
+ export function isKnownTool(name) {
201
+ return TOOL_NAMES.includes(name);
202
+ }
203
+ /* ------------------------------------------------------------------ */
204
+ /* Forwarding client */
205
+ /* ------------------------------------------------------------------ */
206
+ function errorResult(detail) {
207
+ return {
208
+ content: [{ type: "text", text: `martdata error: ${detail}` }],
209
+ isError: true,
210
+ };
211
+ }
212
+ function rpcErrorMessage(error) {
213
+ if (error !== null && typeof error === "object") {
214
+ const message = error.message;
215
+ if (typeof message === "string" && message !== "")
216
+ return message;
217
+ return JSON.stringify(error);
218
+ }
219
+ return String(error);
220
+ }
221
+ /**
222
+ * Read a JSON-RPC response body, tolerating SSE framing.
223
+ * Returns the message whose id matches `expectedId` when
224
+ * present, otherwise the last parseable message, otherwise
225
+ * null when nothing in the body parses.
226
+ */
227
+ export function parseRpcBody(text, expectedId) {
228
+ const trimmed = text.trim();
229
+ if (trimmed === "")
230
+ return null;
231
+ const candidates = [];
232
+ const tryPush = (payload) => {
233
+ try {
234
+ const parsed = JSON.parse(payload);
235
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
236
+ candidates.push(parsed);
237
+ }
238
+ }
239
+ catch {
240
+ // Not a JSON payload; skip this candidate.
241
+ }
242
+ };
243
+ if (trimmed.includes("data:")) {
244
+ for (const line of trimmed.split("\n")) {
245
+ const t = line.trim();
246
+ if (!t.startsWith("data:"))
247
+ continue;
248
+ const payload = t.slice("data:".length).trim();
249
+ if (payload !== "" && payload !== "[DONE]")
250
+ tryPush(payload);
251
+ }
252
+ }
253
+ else {
254
+ tryPush(trimmed);
255
+ }
256
+ if (candidates.length === 0)
257
+ return null;
258
+ if (expectedId !== undefined) {
259
+ const match = candidates.find((c) => c.id === expectedId);
260
+ if (match !== undefined)
261
+ return match;
262
+ }
263
+ return candidates[candidates.length - 1];
264
+ }
265
+ async function defaultFetch(url, init) {
266
+ return fetch(url, init);
267
+ }
268
+ /**
269
+ * A forwarding client that holds a single upstream
270
+ * session, opened lazily on first use and reused from
271
+ * then on (for the process lifetime in the MCP server,
272
+ * or for a single invocation in the CLI).
273
+ */
274
+ export class MartdataClient {
275
+ deps;
276
+ sessionId = null;
277
+ ready = false;
278
+ sessionPromise = null;
279
+ idCounter = 0;
280
+ constructor(deps = {}) {
281
+ this.deps = deps;
282
+ }
283
+ fetchFn() {
284
+ return this.deps.fetchFn ?? defaultFetch;
285
+ }
286
+ endpointUrl() {
287
+ if (this.deps.url && this.deps.url.trim() !== "")
288
+ return this.deps.url.trim();
289
+ const raw = (this.deps.env ?? process.env).HASDATA_WALMART_MCP_URL;
290
+ if (raw && raw.trim() !== "")
291
+ return raw.trim();
292
+ return DEFAULT_ENDPOINT_URL;
293
+ }
294
+ apiKey() {
295
+ const raw = (this.deps.env ?? process.env).HASDATA_API_KEY;
296
+ if (raw && raw.trim() !== "")
297
+ return raw.trim();
298
+ return null;
299
+ }
300
+ timeoutMs() {
301
+ if (typeof this.deps.timeoutMs === "number" && this.deps.timeoutMs > 0) {
302
+ return this.deps.timeoutMs;
303
+ }
304
+ return DEFAULT_TIMEOUT_MS;
305
+ }
306
+ nextId() {
307
+ this.idCounter += 1;
308
+ return this.idCounter;
309
+ }
310
+ async post(body, withSession) {
311
+ const headers = {
312
+ "Content-Type": "application/json",
313
+ Accept: "application/json, text/event-stream",
314
+ };
315
+ const key = this.apiKey();
316
+ if (key !== null)
317
+ headers["x-api-key"] = key;
318
+ if (withSession && this.sessionId !== null) {
319
+ headers["Mcp-Session-Id"] = this.sessionId;
320
+ }
321
+ const controller = new AbortController();
322
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs());
323
+ try {
324
+ return await this.fetchFn()(this.endpointUrl(), {
325
+ method: "POST",
326
+ headers,
327
+ body: JSON.stringify(body),
328
+ signal: controller.signal,
329
+ });
330
+ }
331
+ finally {
332
+ clearTimeout(timer);
333
+ }
334
+ }
335
+ async ensureSession() {
336
+ if (this.ready)
337
+ return;
338
+ if (this.sessionPromise === null) {
339
+ this.sessionPromise = (async () => {
340
+ const initId = this.nextId();
341
+ const initRes = await this.post({
342
+ jsonrpc: "2.0",
343
+ id: initId,
344
+ method: "initialize",
345
+ params: {
346
+ protocolVersion: PROTOCOL_VERSION,
347
+ capabilities: {},
348
+ clientInfo: { name: "martdata", version: VERSION },
349
+ },
350
+ }, false);
351
+ const sessionId = initRes.headers.get("mcp-session-id");
352
+ if (sessionId)
353
+ this.sessionId = sessionId;
354
+ const initText = await initRes.text();
355
+ const initParsed = parseRpcBody(initText, initId);
356
+ if (initParsed !== null && initParsed.error) {
357
+ throw new Error(rpcErrorMessage(initParsed.error));
358
+ }
359
+ if (initRes.status < 200 || initRes.status >= 300) {
360
+ throw new Error(`HTTP ${initRes.status}`);
361
+ }
362
+ if (initParsed === null && initText.trim() !== "") {
363
+ throw new Error("malformed response");
364
+ }
365
+ const initializedRes = await this.post({ jsonrpc: "2.0", method: "notifications/initialized" }, true);
366
+ try {
367
+ await initializedRes.text();
368
+ }
369
+ catch {
370
+ // Nothing needed from the notification response body.
371
+ }
372
+ this.ready = true;
373
+ })();
374
+ }
375
+ try {
376
+ await this.sessionPromise;
377
+ }
378
+ catch (err) {
379
+ this.sessionPromise = null;
380
+ this.sessionId = null;
381
+ throw err;
382
+ }
383
+ }
384
+ /** Forward one tool call; upstream failures come back as isError results. */
385
+ async callTool(name, args) {
386
+ try {
387
+ await this.ensureSession();
388
+ }
389
+ catch (err) {
390
+ return errorResult(err instanceof Error ? err.message : String(err));
391
+ }
392
+ const callId = this.nextId();
393
+ let callRes;
394
+ try {
395
+ callRes = await this.post({
396
+ jsonrpc: "2.0",
397
+ id: callId,
398
+ method: "tools/call",
399
+ params: { name, arguments: args ?? {} },
400
+ }, true);
401
+ }
402
+ catch (err) {
403
+ return errorResult(`request failed: ${err instanceof Error ? err.message : String(err)}`);
404
+ }
405
+ const parsed = parseRpcBody(await callRes.text(), callId);
406
+ if (parsed !== null && parsed.error) {
407
+ return errorResult(rpcErrorMessage(parsed.error));
408
+ }
409
+ if (callRes.status < 200 || callRes.status >= 300) {
410
+ return errorResult(`HTTP ${callRes.status}`);
411
+ }
412
+ if (parsed === null)
413
+ return errorResult("malformed response");
414
+ const result = parsed.result;
415
+ if (result === undefined || result === null || typeof result !== "object") {
416
+ return errorResult("malformed response");
417
+ }
418
+ // Hand the upstream result back exactly as received.
419
+ return result;
420
+ }
421
+ }
422
+ /** Build a forwarding client; tests inject a fake fetch and env through deps. */
423
+ export function createClient(deps = {}) {
424
+ return new MartdataClient(deps);
425
+ }
426
+ /** One-shot helper: a fresh client for a single call (the CLI path). */
427
+ export async function callTool(name, args, deps = {}) {
428
+ return new MartdataClient(deps).callTool(name, args);
429
+ }
430
+ //# sourceMappingURL=forward.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forward.js","sourceRoot":"","sources":["../src/forward.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from "./types.js";
2
+ export * from "./forward.js";
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./types.js";
2
+ export * from "./forward.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC"}
package/dist/mcp.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * martdata MCP server. Tools: the 3 captured HasData
3
+ * Walmart tools (see forward.ts).
4
+ *
5
+ * This file uses the low-level Server API rather than
6
+ * McpServer: the high-level helper rebuilds schemas from
7
+ * zod and rewrites what is served, which would break
8
+ * exact parity with the captured tools/list. Here
9
+ * tools/list is answered locally from the core's literal
10
+ * definitions — the verbatim objects from the upstream
11
+ * capture — and every tools/call is forwarded upstream.
12
+ *
13
+ * A forwarded result returns unchanged, upstream isError
14
+ * flag and extra fields included. An upstream failure
15
+ * arrives as an isError result carrying a
16
+ * `martdata error:` text, built by the forwarding
17
+ * client. Unknown tool names are rejected with McpError
18
+ * MethodNotFound, and non-object arguments with McpError
19
+ * InvalidParams, before any network hop is made.
20
+ */
21
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
22
+ import { type MartdataClient } from "./forward.js";
23
+ import type { ForwardDeps, ToolResult } from "./types.js";
24
+ /**
25
+ * Validate and forward a single tools/call through
26
+ * `client`. Exported so this layer can be tested directly
27
+ * without a stdio transport.
28
+ */
29
+ export declare function handleCallTool(client: MartdataClient, name: string, args: unknown): Promise<ToolResult>;
30
+ /** Build the stdio MCP server (transport not yet connected). */
31
+ export declare function createServer(deps?: ForwardDeps): Server;
32
+ /** Connect the MCP server over stdio. */
33
+ export declare function startMcpServer(deps?: ForwardDeps): Promise<void>;
package/dist/mcp.js ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * martdata MCP server. Tools: the 3 captured HasData
3
+ * Walmart tools (see forward.ts).
4
+ *
5
+ * This file uses the low-level Server API rather than
6
+ * McpServer: the high-level helper rebuilds schemas from
7
+ * zod and rewrites what is served, which would break
8
+ * exact parity with the captured tools/list. Here
9
+ * tools/list is answered locally from the core's literal
10
+ * definitions — the verbatim objects from the upstream
11
+ * capture — and every tools/call is forwarded upstream.
12
+ *
13
+ * A forwarded result returns unchanged, upstream isError
14
+ * flag and extra fields included. An upstream failure
15
+ * arrives as an isError result carrying a
16
+ * `martdata error:` text, built by the forwarding
17
+ * client. Unknown tool names are rejected with McpError
18
+ * MethodNotFound, and non-object arguments with McpError
19
+ * InvalidParams, before any network hop is made.
20
+ */
21
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
22
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
23
+ import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js";
24
+ import { createClient, isKnownTool, TOOL_DEFS, VERSION, } from "./forward.js";
25
+ /**
26
+ * Validate and forward a single tools/call through
27
+ * `client`. Exported so this layer can be tested directly
28
+ * without a stdio transport.
29
+ */
30
+ export async function handleCallTool(client, name, args) {
31
+ if (!isKnownTool(name)) {
32
+ throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
33
+ }
34
+ if (args !== undefined &&
35
+ (typeof args !== "object" || args === null || Array.isArray(args))) {
36
+ throw new McpError(ErrorCode.InvalidParams, `Arguments for tool ${name} must be a JSON object`);
37
+ }
38
+ return client.callTool(name, (args ?? {}));
39
+ }
40
+ /** Build the stdio MCP server (transport not yet connected). */
41
+ export function createServer(deps = {}) {
42
+ const client = createClient(deps);
43
+ const server = new Server({ name: "martdata", version: VERSION }, { capabilities: { tools: {} } });
44
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
45
+ tools: TOOL_DEFS,
46
+ }));
47
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
48
+ const { name, arguments: args } = request.params;
49
+ const result = await handleCallTool(client, name, args);
50
+ return result;
51
+ });
52
+ return server;
53
+ }
54
+ /** Connect the MCP server over stdio. */
55
+ export async function startMcpServer(deps = {}) {
56
+ await createServer(deps).connect(new StdioServerTransport());
57
+ }
58
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,SAAS,EACT,sBAAsB,EACtB,QAAQ,GACT,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,YAAY,EACZ,WAAW,EACX,SAAS,EACT,OAAO,GAER,MAAM,cAAc,CAAC;AAGtB;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAsB,EACtB,IAAY,EACZ,IAAa;IAEb,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,iBAAiB,IAAI,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,IACE,IAAI,KAAK,SAAS;QAClB,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAClE,CAAC;QACD,MAAM,IAAI,QAAQ,CAChB,SAAS,CAAC,aAAa,EACvB,sBAAsB,IAAI,wBAAwB,CACnD,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC,CAAC;AACxE,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,YAAY,CAAC,OAAoB,EAAE;IACjD,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,EACtC,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAChC,CAAC;IAEF,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACxD,OAAO,MAAe,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,yCAAyC;AACzC,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAoB,EAAE;IACzD,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * martdata types.
3
+ *
4
+ * This package keeps no product data locally. It is a forwarding
5
+ * client: the captured tool surface is held as data (ToolDef
6
+ * entries served verbatim for tools/list) and each tools/call
7
+ * is sent to the hosted HasData Walmart MCP endpoint via an
8
+ * injectable fetch, so tests can run with no live network.
9
+ */
10
+ /** One captured tool definition, served exactly as captured for tools/list. */
11
+ export interface ToolDef {
12
+ name: string;
13
+ title?: string;
14
+ description: string;
15
+ inputSchema: Record<string, unknown>;
16
+ [key: string]: unknown;
17
+ }
18
+ /** Arguments for a tool call, as decoded JSON. */
19
+ export type ToolArgs = Record<string, unknown>;
20
+ /** A tools/call result: upstream payloads pass through verbatim; local failures use this shape too. */
21
+ export interface ToolResult {
22
+ content?: unknown;
23
+ isError?: boolean;
24
+ [key: string]: unknown;
25
+ }
26
+ /** The narrow part of a fetch Response the forwarding client depends on. */
27
+ export interface FetchResponseLike {
28
+ ok: boolean;
29
+ status: number;
30
+ headers: {
31
+ get(name: string): string | null;
32
+ };
33
+ text(): Promise<string>;
34
+ }
35
+ /** Injectable fetch function, so tests never reach the live network. */
36
+ export type FetchFn = (url: string, init?: {
37
+ method?: string;
38
+ headers?: Record<string, string>;
39
+ body?: string;
40
+ signal?: AbortSignal;
41
+ }) => Promise<FetchResponseLike>;
42
+ /** Injectable runtime dependencies for the forwarding client. */
43
+ export interface ForwardDeps {
44
+ /** Fetch implementation. Defaults to the global fetch. */
45
+ fetchFn?: FetchFn;
46
+ /** Environment (HASDATA_WALMART_MCP_URL, HASDATA_API_KEY). Defaults to process.env. */
47
+ env?: Record<string, string | undefined>;
48
+ /** Endpoint URL override. Defaults to env HASDATA_WALMART_MCP_URL or the pinned default. */
49
+ url?: string;
50
+ /** Per-request timeout in milliseconds. Defaults to 30000. */
51
+ timeoutMs?: number;
52
+ }
package/dist/types.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * martdata types.
3
+ *
4
+ * This package keeps no product data locally. It is a forwarding
5
+ * client: the captured tool surface is held as data (ToolDef
6
+ * entries served verbatim for tools/list) and each tools/call
7
+ * is sent to the hosted HasData Walmart MCP endpoint via an
8
+ * injectable fetch, so tests can run with no live network.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
package/package.json CHANGED
@@ -1,6 +1,41 @@
1
1
  {
2
+ "bin": {
3
+ "martdata": "dist/cli.js"
4
+ },
5
+ "dependencies": {
6
+ "@modelcontextprotocol/sdk": "^1",
7
+ "zod": "^4"
8
+ },
9
+ "description": "Walmart data as JSON from your agent: a local bridge to the hosted HasData Walmart MCP service that fetches one product page in full, pulls that product's customer reviews page by page, and runs storefront searches with price, fulfillment and sort filters, returning everything exactly as the upstream service sends it. One bin serves a small CLI and a stdio MCP server.",
10
+ "devDependencies": {
11
+ "@types/node": "^20",
12
+ "tsx": "^4",
13
+ "typescript": "^5"
14
+ },
15
+ "engines": {
16
+ "node": ">=20"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "server.json"
21
+ ],
22
+ "homepage": "https://github.com/CloudCorpRecords/martdata#readme",
23
+ "license": "MIT",
24
+ "mcpName": "io.github.CloudCorpRecords/martdata",
2
25
  "name": "@reneturcios/martdata",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
26
+ "private": false,
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/CloudCorpRecords/martdata.git"
33
+ },
34
+ "scripts": {
35
+ "build": "tsc",
36
+ "dev": "tsx src/cli.ts",
37
+ "test": "tsx --test test/*.test.ts"
38
+ },
39
+ "type": "module",
40
+ "version": "0.1.0"
41
+ }
package/server.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "description": "Walmart data as JSON: product details, customer reviews, and storefront search with filters.",
4
+ "name": "io.github.CloudCorpRecords/martdata",
5
+ "packages": [
6
+ {
7
+ "identifier": "@reneturcios/martdata",
8
+ "packageArguments": [
9
+ {
10
+ "type": "positional",
11
+ "value": "mcp"
12
+ }
13
+ ],
14
+ "registryBaseUrl": "https://registry.npmjs.org",
15
+ "registryType": "npm",
16
+ "runtimeHint": "npx",
17
+ "transport": {
18
+ "type": "stdio"
19
+ },
20
+ "version": "0.1.0"
21
+ },
22
+ {
23
+ "identifier": "ghcr.io/cloudcorprecords/martdata:0.1.0",
24
+ "packageArguments": [
25
+ {
26
+ "type": "positional",
27
+ "value": "mcp"
28
+ }
29
+ ],
30
+ "registryType": "oci",
31
+ "runtimeArguments": [
32
+ {
33
+ "name": "--rm",
34
+ "type": "named"
35
+ },
36
+ {
37
+ "name": "-i",
38
+ "type": "named"
39
+ }
40
+ ],
41
+ "runtimeHint": "docker",
42
+ "transport": {
43
+ "type": "stdio"
44
+ }
45
+ }
46
+ ],
47
+ "repository": {
48
+ "source": "github",
49
+ "url": "https://github.com/CloudCorpRecords/martdata"
50
+ },
51
+ "version": "0.1.0"
52
+ }