@scavio/mcp-server 0.29.1 → 0.30.1

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/README.md CHANGED
@@ -3,9 +3,9 @@
3
3
  ![GitHub Repo stars](https://img.shields.io/github/stars/scavio-ai/scavio-mcp?style=social)
4
4
  ![License](https://img.shields.io/github/license/scavio-ai/scavio-mcp)
5
5
 
6
- [Scavio](https://scavio.dev?utm_source=npm-mcp&utm_medium=package&utm_campaign=readme) is a unified [Web Search API](https://scavio.dev/docs/search-api?utm_source=npm-mcp&utm_medium=package&utm_campaign=readme) and MCP server that gives AI agents web search, page extraction, and structured data from e-commerce, social, travel, jobs, real-estate, app-store, ad-library and company-filing sources. 298 tools across 45 platforms plus Extract, map, crawl and batch, one API key.
6
+ [Scavio](https://scavio.dev?utm_source=npm-mcp&utm_medium=package&utm_campaign=readme) is a unified [Web Search API](https://scavio.dev/docs/search-api?utm_source=npm-mcp&utm_medium=package&utm_campaign=readme) and MCP server that gives AI agents web search, page extraction, and structured data from e-commerce, social, travel, jobs, real-estate, app-store, ad-library and company-filing sources. 318 tools across 51 platforms plus Extract, map, crawl and batch, one API key.
7
7
 
8
- **The 22 platforms added in 0.13.0 are opt-in.** Registering all 298 tools puts ~287KB of tool definitions — roughly 72k tokens — into every session before you type anything. So the default is the platform set 0.12.x already had, plus Extract: 142 tools, 112KB. Upgrading never removes a tool you were using. Everything else is one env var away: see [Choosing which tools load](#choosing-which-tools-load).
8
+ **The 22 platforms added in 0.13.0 are opt-in.** Registering all 318 tools puts ~311KB of tool definitions — roughly 78k tokens — into every session before you type anything. So the default is the platform set 0.12.x already had, plus Extract: 142 tools, 112KB. Upgrading never removes a tool you were using. Everything else is one env var away: see [Choosing which tools load](#choosing-which-tools-load).
9
9
 
10
10
  ## Remote MCP Server
11
11
 
@@ -207,8 +207,8 @@ Add to settings (`Cmd+,`):
207
207
 
208
208
  ## Choosing which tools load
209
209
 
210
- Scavio exposes 298 tools. Loading all of them costs ~287KB of `tools/list` —
211
- roughly 72k tokens of context in every session before the user has said anything,
210
+ Scavio exposes 318 tools. Loading all of them costs ~311KB of `tools/list` —
211
+ roughly 78k tokens of context in every session before the user has said anything,
212
212
  and more tools than some clients will accept at all. So the server registers a
213
213
  curated subset by default and lets you pick the rest. The sizes below are
214
214
  measured, not estimated: `npm run toolslist` reproduces them.
@@ -218,7 +218,7 @@ measured, not estimated: `npm run toolslist` reproduces them.
218
218
  | Value | Registers |
219
219
  |-------|-----------|
220
220
  | *(unset)* or `default` | Every platform 0.12.x had, plus `extract` — **142 tools, 112KB** |
221
- | `all` | every platform — **298 tools, ~287KB** |
221
+ | `all` | every platform — **318 tools, ~311KB** |
222
222
  | `extract,sec,g2` | just those platforms — 18 tools, 21KB |
223
223
  | `default,zillow,metaads` | the default set plus two more — 148 tools, 120KB |
224
224
  | `default,chatgpt,gemini` | the default set plus ChatGPT and Gemini — 144 tools, 115KB |
@@ -233,7 +233,7 @@ tells you to call to check the server works.
233
233
 
234
234
  **Platform keys:** `extract`, `google`, `chatgpt`, `gemini`, `youtube`, `tiktok`, `instagram`,
235
235
  `reddit`, `x`, `linkedin`, `threads`, `kuaishou`, `amazon`, `walmart`, `ebay`,
236
- `target`, `homedepot`, `costco`, `heb`, `kroger`, `decathlon`, `specs`, `lowes`, `samsclub`, `canadiantire`, `dollargeneral`, `mercadolibre`, `tiktok-shop`, `booking`, `airbnb`,
236
+ `target`, `homedepot`, `costco`, `heb`, `kroger`, `decathlon`, `specs`, `lowes`, `samsclub`, `canadiantire`, `dollargeneral`, `sephora`, `ulta`, `aldi`, `microcenter`, `walgreens`, `cvs`, `mercadolibre`, `tiktok-shop`, `booking`, `airbnb`,
237
237
  `tripadvisor`, `yelp`, `zillow`, `redfin`, `realtor`, `rightmove`, `indeed`, `glassdoor`,
238
238
  `appstore`, `googleplay`, `g2`, `capterra`, `trustpilot`, `googleads`, `metaads`, `sec`, `companieshouse`
239
239
 
@@ -811,6 +811,81 @@ review text.
811
811
  required on search, product and deals. Clearance items carry the current price
812
812
  only, with no was-price. Rating and review count only, no review text.
813
813
 
814
+ ### Sephora
815
+
816
+ | Tool | Description |
817
+ |------|-------------|
818
+ | `search_sephora` | Search sephora.com (US): price, list and sale price, rating, review count, bestseller/new/exclusive flags, category facets; `zip` for same-day eligibility |
819
+ | `get_sephora_category` | Products in a category, same fields as search, with subcategories, parent category and breadcrumbs |
820
+ | `get_sephora_product` | One product: every shade or size with price, stock, ingredients and pickup/same-day eligibility, plus a review summary with pro and con sentiment counts |
821
+
822
+ 1 credit per call. `get_sephora_product` takes a result's `url` (faster) or
823
+ `product_id` (e.g. `"P510799"`). The review summary and sentiment counts come
824
+ with no review text.
825
+
826
+ ### Ulta Beauty
827
+
828
+ | Tool | Description |
829
+ |------|-------------|
830
+ | `search_ulta` | Search Ulta Beauty: list and sale price, discount, promo text, rating, review count, badge, variant count |
831
+ | `get_ulta_category` | Products in a category (e.g. `/shop/makeup/lips/lipstick`), same fields as search |
832
+ | `get_ulta_product` | One product by URL: price, GTIN, ingredients, every shade or size variant, ship/pickup/same-day eligibility, five most recent reviews |
833
+ | `get_ulta_stores` | One shade or size at the 10 stores nearest a ZIP: in stock or out of stock per store, hours, distance |
834
+
835
+ 1 credit per call. `get_ulta_stores` takes a result's `product_id` and `sku_id`
836
+ plus a ZIP. Ulta publishes in stock / out of stock per store, not unit counts.
837
+
838
+ ### ALDI
839
+
840
+ | Tool | Description |
841
+ |------|-------------|
842
+ | `search_aldi` | Search at one store: price and was-price, unit price, stock level, aisle location, ALDI-exclusive brand flag, dietary labels |
843
+ | `get_aldi_product` | One product at one store: price, stock, description, ingredients, allergen warnings, images |
844
+ | `get_aldi_stores` | Stores near a ZIP: store_id, address, coordinates, distance |
845
+
846
+ 1 credit per call. Prices are per store and per `service_type`: `instore` (the
847
+ shelf price, default), `pickup` or `delivery` (online prices, often higher).
848
+ Pass `store_id` (from `get_aldi_stores`, e.g. `"151248"`) or a `zip` to use the
849
+ nearest store. ALDI has no product ratings.
850
+
851
+ ### Micro Center
852
+
853
+ | Tool | Description |
854
+ |------|-------------|
855
+ | `search_micro_center` | Search by keyword or category at one store: price, original price, stock count at that store, open-box count and lowest price, rebate text |
856
+ | `get_micro_center_product` | One product: specs, UPC, reviews, the store's stock and open-box units, and an in-stock yes/no for every store |
857
+ | `get_micro_center_stores` | Every store with its 3-digit store_id, city, state and address |
858
+
859
+ 2 credits per call; `get_micro_center_stores` is 1. Stock is per 3-digit
860
+ `store_id` (e.g. `"131"`, Dallas); without one, the web store `029` (shippable
861
+ items) is used. Counts are capped at 25+ (`quantity_capped`).
862
+
863
+ ### Walgreens
864
+
865
+ | Tool | Description |
866
+ |------|-------------|
867
+ | `search_walgreens` | Search retail products (no pharmacy): regular, sale and unit price, promotions, coupons, rating, availability, clearance flag |
868
+ | `get_walgreens_product` | One product: SKU, UPC, price, savings, offers, ingredients, warnings, rating, category path, images |
869
+ | `get_walgreens_stores` | Walgreens and Duane Reade stores near a ZIP or coordinates: store number, address, phone, hours |
870
+ | `get_walgreens_stock` | One product's live stock at up to 20 stores in one call: status, unit count, in_stock |
871
+
872
+ 2 credits per call; `get_walgreens_stock` is 4. Prices are national, the same
873
+ at every store. Store numbers (from `get_walgreens_stores`, e.g. `"9438"`) go to
874
+ `get_walgreens_stock` as `store_ids`.
875
+
876
+ ### CVS
877
+
878
+ | Tool | Description |
879
+ |------|-------------|
880
+ | `search_cvs` | Search front-store products (no pharmacy): regular, sale and unit price, promotions, coupons, rating, and units in store and for pickup at one store |
881
+ | `get_cvs_product` | One product by URL or id: price, promotion end date, UPC, ingredients, directions, warnings, every variant |
882
+ | `get_cvs_stock` | Units at one store for up to 20 SKUs: in store, pickup, online |
883
+
884
+ 1 credit per call. There is no store locator: the store number is on every
885
+ cvs.com store page (e.g. `"7019"`). Search stock defaults to store 7019 (New
886
+ York). Prices are the same at every store. `get_cvs_product` can take 10-30+
887
+ seconds.
888
+
814
889
  ### Kroger
815
890
 
816
891
  | Tool | Description |
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ScavioClient } from "../lib/client.js";
3
+ export declare function registerAldiTools(server: McpServer, getClient: () => ScavioClient): void;
@@ -0,0 +1,53 @@
1
+ import { z } from "zod";
2
+ import { handleApiError } from "../lib/tool-error.js";
3
+ import { trimResponse } from "../lib/trim-response.js";
4
+ // Shapes mirror backend/src/routes/aldi.ts. Cross-field rule the backend
5
+ // enforces and zod here does not: search and product take store_id OR zip
6
+ // (nearest store). No zod `.default()`: the MCP SDK would post a defaulted
7
+ // field on every call.
8
+ const storeId = () => z.string().regex(/^\d{1,10}$/).optional()
9
+ .describe("ALDI store id from get_aldi_stores, e.g. '151248'. Prices and stock are that store's. Pass this, or zip to use the nearest store.");
10
+ const zip = () => z.string().regex(/^\d{5}(-\d{4})?$/).optional()
11
+ .describe("US ZIP code, e.g. '33133'. Without store_id, the nearest ALDI store to it is used.");
12
+ const serviceType = () => z.enum(["instore", "pickup", "delivery"]).optional()
13
+ .describe("Which price: instore (default, the shelf price in the store), pickup or delivery (online prices for ordering from that store, often higher than the shelf price).");
14
+ export function registerAldiTools(server, getClient) {
15
+ const post = (path) => async (params) => {
16
+ try {
17
+ const data = await getClient().post(`/api/v1/aldi/${path}`, params);
18
+ return trimResponse(data);
19
+ }
20
+ catch (err) {
21
+ return handleApiError(err);
22
+ }
23
+ };
24
+ server.tool("search_aldi", `Search ALDI US products at one store (store_id, or the nearest store to a zip). Prices are per store and per service_type: the in-store shelf price by default; pickup and delivery are the online prices, often higher. Each result has product_id, name, brand, size, price and was_price in dollars, discount label, unit price, in_stock and stock level, category, in-store aisle location, ALDI-exclusive brand flag, dietary labels, image and URL. Exact matches only unless include_related is set. ALDI has no product ratings. 1 credit/call.`, {
25
+ query: z.string().min(1).max(200)
26
+ .describe("Search keywords, e.g. 'cheese'."),
27
+ store_id: storeId(),
28
+ zip: zip(),
29
+ service_type: serviceType(),
30
+ sort: z.enum(["best_match", "price_low", "price_high"]).optional()
31
+ .describe("best_match (default), price_low or price_high."),
32
+ limit: z.number().int().min(1).max(60).optional()
33
+ .describe("Products per page, 1-60. Default 30."),
34
+ page: z.number().int().min(1).max(100).optional()
35
+ .describe("Page, 1-based."),
36
+ include_related: z.boolean().optional()
37
+ .describe("Also return the related items ALDI lists after the exact matches. Default false."),
38
+ }, post("search"));
39
+ server.tool("get_aldi_product", `One ALDI US product at one store (store_id, or the nearest store to a zip): price and was_price in dollars for that store and service_type (in-store shelf price by default), unit price, stock, category, brand, size, description, ingredients, allergen warnings, dietary labels and images. An unknown product id is a 404. 1 credit.`, {
40
+ product_id: z.string().min(1).max(300)
41
+ .describe("ALDI product id (a search result's product_id), e.g. '16902710', or an aldi.us product URL."),
42
+ store_id: storeId(),
43
+ zip: zip(),
44
+ service_type: serviceType(),
45
+ }, post("product"));
46
+ server.tool("get_aldi_stores", `ALDI US stores near a ZIP, nearest first: store_id (use it with search_aldi and get_aldi_product), name, street address, city, state, ZIP, coordinates and distance in miles. 1 credit.`, {
47
+ zip: z.string().regex(/^\d{5}(-\d{4})?$/)
48
+ .describe("US ZIP code to search around, e.g. '33131'."),
49
+ limit: z.number().int().min(1).max(50).optional()
50
+ .describe("Stores to return, nearest first, 1-50. Default 10."),
51
+ }, post("stores"));
52
+ }
53
+ //# sourceMappingURL=aldi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aldi.js","sourceRoot":"","sources":["../../src/tools/aldi.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ScavioClient } from "../lib/client.js";
3
+ export declare function registerCvsTools(server: McpServer, getClient: () => ScavioClient): void;
@@ -0,0 +1,43 @@
1
+ import { z } from "zod";
2
+ import { handleApiError } from "../lib/tool-error.js";
3
+ import { trimResponse } from "../lib/trim-response.js";
4
+ // Shapes mirror backend/src/routes/cvs.ts. Cross-field rule the backend
5
+ // enforces and zod here does not: product takes url OR product_id. CVS has no
6
+ // store locator endpoint. No zod `.default()`: the MCP SDK would post a
7
+ // defaulted field on every call.
8
+ const STORE_HELP = 'The store number is on every cvs.com store page ("Store ID: #7019") and in its URL (.../storeid=7019).';
9
+ const numericId = () => z.string().regex(/^\d{3,10}$/);
10
+ export function registerCvsTools(server, getClient) {
11
+ const post = (path) => async (params) => {
12
+ try {
13
+ const data = await getClient().post(`/api/v1/cvs/${path}`, params);
14
+ return trimResponse(data);
15
+ }
16
+ catch (err) {
17
+ return handleApiError(err);
18
+ }
19
+ };
20
+ server.tool("search_cvs", `Search CVS front-store products (no pharmacy). Each result has product_id and sku_id, name, brand, URL, regular, sale and unit price, promotion text, rating, review count, size, image, coupons (ExtraBucks rewards and manufacturer coupons) and stock at one store: units in store and for pickup, plus online ship stock (chain-wide). same_day_delivery is always null: CVS does not report it per store. Prices are in dollars and the same at every store. Stock defaults to store 7019 (New York) when store_id is omitted. Includes brand, price-range and rating facets. 1 credit/call.`, {
21
+ query: z.string().min(1).max(200)
22
+ .describe("Search keywords, e.g. 'toothpaste', or a CVS item number."),
23
+ store_id: z.string().regex(/^\d{1,5}$/).optional()
24
+ .describe(`CVS store number for the stock fields, e.g. '7019'. Default 7019 (150 East 42nd St, New York, NY). ${STORE_HELP}`),
25
+ page: z.number().int().min(1).max(100).optional()
26
+ .describe("Page, 1-based."),
27
+ limit: z.number().int().min(1).max(48).optional()
28
+ .describe("Results per page, 1-48. Default 20."),
29
+ }, post("search"));
30
+ server.tool("get_cvs_product", `One CVS product by URL or id: regular and sale price, unit price, promotion and its end date, rating, review count, UPC, size, description, highlights, ingredients, directions, warnings, attributes, breadcrumbs, images and every variant (sku_id, UPC, size, price, rating). Can take 10-30+ seconds. An unknown product is a 404. 1 credit.`, {
31
+ url: z.string().max(500).optional()
32
+ .describe("cvs.com product URL, https://www.cvs.com/shop/<name>-prodid-<id>. Pass this or product_id."),
33
+ product_id: numericId().optional()
34
+ .describe("CVS product id or SKU id (the number after prodid- in a product URL, or a search result's product_id or sku_id), e.g. '789787'. Pass this or url."),
35
+ }, post("product"));
36
+ server.tool("get_cvs_stock", `Units available at one CVS store for up to 20 SKUs in one call: in_store (on the shelf), pickup (order online, pick up there) and ship (online stock, chain-wide). same_day_delivery is always null: CVS does not report it per store. An unknown SKU or store number reads as 0. 1 credit.`, {
37
+ sku_ids: z.array(numericId()).min(1).max(20)
38
+ .describe("Up to 20 CVS SKU ids (a search result's sku_id or a product's variants[].sku_id), e.g. ['789787', '949346']."),
39
+ store_id: z.string().regex(/^\d{1,5}$/)
40
+ .describe(`CVS store number, e.g. '7019'. ${STORE_HELP}`),
41
+ }, post("stock"));
42
+ }
43
+ //# sourceMappingURL=cvs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cvs.js","sourceRoot":"","sources":["../../src/tools/cvs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,wEAAwE;AACxE,8EAA8E;AAC9E,wEAAwE;AACxE,iCAAiC;AAEjC,MAAM,UAAU,GACd,wGAAwG,CAAC;AAE3G,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AAEvD,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,SAA6B;IAC/E,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,EAAE,MAA+B,EAAE,EAAE;QACvE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,EAAE,CAAC,IAAI,CAAC,eAAe,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;YACnE,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,mkBAAmkB,EACnkB;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;aAC9B,QAAQ,CAAC,2DAA2D,CAAC;QACxE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE;aAC/C,QAAQ,CAAC,sGAAsG,UAAU,EAAE,CAAC;QAC/H,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;aAC9C,QAAQ,CAAC,gBAAgB,CAAC;QAC7B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;aAC9C,QAAQ,CAAC,qCAAqC,CAAC;KACnD,EACD,IAAI,CAAC,QAAQ,CAAC,CACf,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,kVAAkV,EAClV;QACE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;aAChC,QAAQ,CAAC,4FAA4F,CAAC;QACzG,UAAU,EAAE,SAAS,EAAE,CAAC,QAAQ,EAAE;aAC/B,QAAQ,CAAC,mJAAmJ,CAAC;KACjK,EACD,IAAI,CAAC,SAAS,CAAC,CAChB,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,eAAe,EACf,6RAA6R,EAC7R;QACE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;aACzC,QAAQ,CAAC,8GAA8G,CAAC;QAC3H,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC;aACpC,QAAQ,CAAC,kCAAkC,UAAU,EAAE,CAAC;KAC5D,EACD,IAAI,CAAC,OAAO,CAAC,CACd,CAAC;AACJ,CAAC"}
@@ -4,9 +4,9 @@ export declare const PLATFORM_KEYS: string[];
4
4
  /**
5
5
  * What registers when SCAVIO_PLATFORMS is unset.
6
6
  *
7
- * Registering everything is not an option any more. The full surface is 298
8
- * tools, which serialises to 287KB of tools/list (measured with
9
- * `npm run toolslist`, not estimated) — roughly 72k tokens pushed into the
7
+ * Registering everything is not an option any more. The full surface is 318
8
+ * tools, which serialises to 311KB of tools/list (measured with
9
+ * `npm run toolslist`, not estimated) — roughly 78k tokens pushed into the
10
10
  * context of EVERY session before the user has typed anything, and past the
11
11
  * hard tool-count ceiling some clients enforce. The default set below is 142
12
12
  * tools, 112KB (0.20.0: TikTok, YouTube, Reddit and X gained 19 tools; 0.21.0:
@@ -27,7 +27,7 @@ export declare const DEFAULT_PLATFORMS: string[];
27
27
  * Turn a SCAVIO_PLATFORMS value into the canonical platform keys to register.
28
28
  *
29
29
  * Accepts a comma-separated list of platform keys, plus three keywords:
30
- * all — every platform (298 tools)
30
+ * all — every platform (318 tools)
31
31
  * default — expands to DEFAULT_PLATFORMS, so `default,sec,g2` is additive
32
32
  * none — no platform tools at all, leaving only get_usage
33
33
  *
@@ -24,6 +24,12 @@ import { registerLowesTools } from "./lowes.js";
24
24
  import { registerSamsClubTools } from "./samsclub.js";
25
25
  import { registerCanadianTireTools } from "./canadiantire.js";
26
26
  import { registerDollarGeneralTools } from "./dollargeneral.js";
27
+ import { registerSephoraTools } from "./sephora.js";
28
+ import { registerUltaTools } from "./ulta.js";
29
+ import { registerAldiTools } from "./aldi.js";
30
+ import { registerMicroCenterTools } from "./microcenter.js";
31
+ import { registerWalgreensTools } from "./walgreens.js";
32
+ import { registerCvsTools } from "./cvs.js";
27
33
  import { registerMercadoLibreTools } from "./mercadolibre.js";
28
34
  import { registerTiktokShopTools } from "./tiktok-shop.js";
29
35
  import { registerBookingTools } from "./booking.js";
@@ -91,6 +97,12 @@ const PLATFORMS = {
91
97
  samsclub: registerSamsClubTools,
92
98
  canadiantire: registerCanadianTireTools,
93
99
  dollargeneral: registerDollarGeneralTools,
100
+ sephora: registerSephoraTools,
101
+ ulta: registerUltaTools,
102
+ aldi: registerAldiTools,
103
+ microcenter: registerMicroCenterTools,
104
+ walgreens: registerWalgreensTools,
105
+ cvs: registerCvsTools,
94
106
  mercadolibre: registerMercadoLibreTools,
95
107
  "tiktok-shop": registerTiktokShopTools,
96
108
  // Travel and local
@@ -125,9 +137,9 @@ export const PLATFORM_KEYS = Object.keys(PLATFORMS);
125
137
  /**
126
138
  * What registers when SCAVIO_PLATFORMS is unset.
127
139
  *
128
- * Registering everything is not an option any more. The full surface is 298
129
- * tools, which serialises to 287KB of tools/list (measured with
130
- * `npm run toolslist`, not estimated) — roughly 72k tokens pushed into the
140
+ * Registering everything is not an option any more. The full surface is 318
141
+ * tools, which serialises to 311KB of tools/list (measured with
142
+ * `npm run toolslist`, not estimated) — roughly 78k tokens pushed into the
131
143
  * context of EVERY session before the user has typed anything, and past the
132
144
  * hard tool-count ceiling some clients enforce. The default set below is 142
133
145
  * tools, 112KB (0.20.0: TikTok, YouTube, Reddit and X gained 19 tools; 0.21.0:
@@ -183,7 +195,7 @@ function warnOnce(message) {
183
195
  * Turn a SCAVIO_PLATFORMS value into the canonical platform keys to register.
184
196
  *
185
197
  * Accepts a comma-separated list of platform keys, plus three keywords:
186
- * all — every platform (298 tools)
198
+ * all — every platform (318 tools)
187
199
  * default — expands to DEFAULT_PLATFORMS, so `default,sec,g2` is additive
188
200
  * none — no platform tools at all, leaving only get_usage
189
201
  *
@@ -240,6 +252,8 @@ const TITLE_WORDS = {
240
252
  heb: "HEB",
241
253
  lowes: "Lowe's",
242
254
  sams: "Sam's",
255
+ aldi: "ALDI",
256
+ cvs: "CVS",
243
257
  sec: "SEC",
244
258
  g2: "G2",
245
259
  ai: "AI",
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ScavioClient } from "../lib/client.js";
3
+ export declare function registerMicroCenterTools(server: McpServer, getClient: () => ScavioClient): void;
@@ -0,0 +1,46 @@
1
+ import { z } from "zod";
2
+ import { handleApiError } from "../lib/tool-error.js";
3
+ import { trimResponse } from "../lib/trim-response.js";
4
+ // Shapes mirror backend/src/routes/microcenter.ts. Cross-field rule the
5
+ // backend enforces and zod here does not: search takes query, category, or
6
+ // both (at least one). No zod `.default()`: the MCP SDK would post a defaulted
7
+ // field on every call.
8
+ const SORTS = ["best_match", "rating", "review_count", "price_low", "price_high", "newest"];
9
+ const storeId = () => z.string().regex(/^\d{1,3}$/).optional()
10
+ .describe("Micro Center 3-digit store id from get_micro_center_stores, e.g. '131' (Dallas) or '151' (Chicago). Stock counts and open-box units are that store's. Omit for the web store (029), which lists shippable items only.");
11
+ export function registerMicroCenterTools(server, getClient) {
12
+ const post = (path) => async (params) => {
13
+ try {
14
+ const data = await getClient().post(`/api/v1/microcenter/${path}`, params);
15
+ return trimResponse(data);
16
+ }
17
+ catch (err) {
18
+ return handleApiError(err);
19
+ }
20
+ };
21
+ server.tool("search_micro_center", `Search Micro Center by keyword or category at one store, up to 96 per page. Each product has product_id, SKU, name, brand, category, price and original price in dollars, highlights, and that store's stock: the label as printed ("4 IN STOCK", "25+ IN STOCK", "NOT CARRIED"), quantity, quantity_capped (counts are capped at 25+), in_stock and not_carried. Open-box count and lowest price, rebate text and in-store-only flag where shown; sponsored placements are flagged. Without store_id the web store (029) is used. 2 credits/call.`, {
22
+ query: z.string().min(1).max(200).optional()
23
+ .describe("Search keywords, e.g. 'rtx 5070'. Pass this, category, or both."),
24
+ category: z.string().min(1).max(500).optional()
25
+ .describe("Category id, e.g. '518' (Graphics Cards), a 'category:Graphics Cards|518' value, or a microcenter.com listing URL carrying one. Product breadcrumbs carry category ids."),
26
+ store_id: storeId(),
27
+ page: z.number().int().min(1).max(100).optional()
28
+ .describe("Page, 1-based."),
29
+ per_page: z.union([z.literal(24), z.literal(48), z.literal(96)]).optional()
30
+ .describe("Results per page: 24, 48 or 96 (default)."),
31
+ sort: z.enum(SORTS).optional()
32
+ .describe("best_match (default), rating, review_count, price_low, price_high or newest."),
33
+ include_out_of_stock: z.boolean().optional()
34
+ .describe("Also list products the store has no stock of or does not carry. Default false."),
35
+ }, post("search"));
36
+ server.tool("get_micro_center_product", `One Micro Center product: SKU, MPN, UPC, name, brand, description, price, original price, availability, ship and pickup flags, images, rating, review count, up to 10 recent reviews, breadcrumbs with category ids and the full spec table. selected_store has that store's address, stock (label, quantity, quantity_capped at 25+, in_stock) and each open-box unit (condition, warranty, price). stores_in_stock lists every store with a yes/no in_stock flag, not a count. An unknown product id is a 404. 2 credits.`, {
37
+ product_id: z.string().min(1).max(500)
38
+ .describe("Micro Center product id (a search result's product_id, the number after /product/ in a microcenter.com URL), e.g. '691231', or the product URL. Not the SKU."),
39
+ store_id: storeId(),
40
+ }, post("product"));
41
+ server.tool("get_micro_center_stores", `Every Micro Center store with its 3-digit store_id (what search_micro_center and get_micro_center_product take), name, city, state and store page URL; street address and ZIP where known. The web store 029 is not listed but is accepted as a store_id. 1 credit.`, {
42
+ state: z.string().regex(/^[A-Za-z]{2}$/).optional()
43
+ .describe("2-letter US state code to filter by, e.g. 'TX'."),
44
+ }, post("stores"));
45
+ }
46
+ //# sourceMappingURL=microcenter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microcenter.js","sourceRoot":"","sources":["../../src/tools/microcenter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,wEAAwE;AACxE,2EAA2E;AAC3E,+EAA+E;AAC/E,uBAAuB;AAEvB,MAAM,KAAK,GAAG,CAAC,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,CAAU,CAAC;AAErG,MAAM,OAAO,GAAG,GAAG,EAAE,CACnB,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE;KACrC,QAAQ,CAAC,uNAAuN,CAAC,CAAC;AAEvO,MAAM,UAAU,wBAAwB,CAAC,MAAiB,EAAE,SAA6B;IACvF,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,EAAE,MAA+B,EAAE,EAAE;QACvE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,EAAE,CAAC,IAAI,CAAC,uBAAuB,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;YAC3E,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,ohBAAohB,EACphB;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;aACzC,QAAQ,CAAC,iEAAiE,CAAC;QAC9E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;aAC5C,QAAQ,CAAC,yKAAyK,CAAC;QACtL,QAAQ,EAAE,OAAO,EAAE;QACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;aAC9C,QAAQ,CAAC,gBAAgB,CAAC;QAC7B,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;aACxE,QAAQ,CAAC,2CAA2C,CAAC;QACxD,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE;aAC3B,QAAQ,CAAC,8EAA8E,CAAC;QAC3F,oBAAoB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;aACzC,QAAQ,CAAC,gFAAgF,CAAC;KAC9F,EACD,IAAI,CAAC,QAAQ,CAAC,CACf,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,0BAA0B,EAC1B,6fAA6f,EAC7f;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;aACnC,QAAQ,CAAC,8JAA8J,CAAC;QAC3K,QAAQ,EAAE,OAAO,EAAE;KACpB,EACD,IAAI,CAAC,SAAS,CAAC,CAChB,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,yBAAyB,EACzB,qQAAqQ,EACrQ;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE;aAChD,QAAQ,CAAC,iDAAiD,CAAC;KAC/D,EACD,IAAI,CAAC,QAAQ,CAAC,CACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ScavioClient } from "../lib/client.js";
3
+ export declare function registerSephoraTools(server: McpServer, getClient: () => ScavioClient): void;
@@ -0,0 +1,41 @@
1
+ import { z } from "zod";
2
+ import { handleApiError } from "../lib/tool-error.js";
3
+ import { trimResponse } from "../lib/trim-response.js";
4
+ // Shapes mirror backend/src/routes/sephora.ts. Cross-field rule the backend
5
+ // enforces and zod here does not: product takes url OR product_id. No zod
6
+ // `.default()`: the MCP SDK would post a defaulted field on every call.
7
+ const SORTS = ["relevance", "best_selling", "rating", "price_low", "price_high", "newest"];
8
+ const page = () => z.number().int().min(1).max(100).optional()
9
+ .describe("Page, 1-based, 60 per page.");
10
+ export function registerSephoraTools(server, getClient) {
11
+ const post = (path) => async (params) => {
12
+ try {
13
+ const data = await getClient().post(`/api/v1/sephora/${path}`, params);
14
+ return trimResponse(data);
15
+ }
16
+ catch (err) {
17
+ return handleApiError(err);
18
+ }
19
+ };
20
+ server.tool("search_sephora", `Search sephora.com (US) products, 60 per page. Each result has product_id, sku_id, brand, name, url, price, list and sale price in dollars (price_range when sizes are priced differently), value price for sets, rating, review count, extra colors, and bestseller, new, Sephora-exclusive, online-only, limited-edition and sponsored flags. Pass zip for same-day delivery eligibility. Also returns category facets with product counts and related searches. Use a result's url with get_sephora_product. 1 credit/call.`, {
21
+ query: z.string().min(1).max(200)
22
+ .describe("Search keywords, e.g. 'lipstick'."),
23
+ page: page(),
24
+ sort: z.enum(SORTS).optional()
25
+ .describe("relevance (default), best_selling, rating, price_low, price_high or newest."),
26
+ zip: z.string().regex(/^\d{5}(-\d{4})?$/).optional()
27
+ .describe("US ZIP code, e.g. '10001'. Each product then carries same_day_eligible for that ZIP."),
28
+ }, post("search"));
29
+ server.tool("get_sephora_category", `Products in a sephora.com (US) category, 60 per page, same fields as search_sephora, plus the category's id, name and URL, total product count, parent category, subcategories with product counts and breadcrumbs. An unknown category is a 404. 1 credit/call.`, {
30
+ category: z.string().min(1).max(300)
31
+ .describe("Category name as in a sephora.com/shop/ URL (e.g. 'lipstick', 'face-serum', 'makeup-cosmetics'), or the full https://www.sephora.com/shop/... URL."),
32
+ page: page(),
33
+ }, post("category"));
34
+ server.tool("get_sephora_product", `One sephora.com (US) product: name, brand, rating, review count, loves count, price range, description, suggested usage, category and breadcrumbs, a summary of what reviews say with pro and con sentiment counts (no review text), and every shade or size as a sku with sku_id, shade, size, price, list and sale price, in_stock, only_few_left, ingredients, images, swatch, and pickup and same-day eligibility. An unknown product is a 404. 1 credit.`, {
35
+ url: z.string().min(1).max(500).optional()
36
+ .describe("sephora.com product URL (a search or category result's url), e.g. 'https://www.sephora.com/product/mac-cosmetics-m-a-cximal-silky-matte-lipstick-P510799'. Preferred: it answers faster. Pass this or product_id."),
37
+ product_id: z.string().regex(/^[Pp]\d{3,12}$/).optional()
38
+ .describe("Sephora product id (a result's product_id), e.g. 'P510799'. Pass this or url."),
39
+ }, post("product"));
40
+ }
41
+ //# sourceMappingURL=sephora.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sephora.js","sourceRoot":"","sources":["../../src/tools/sephora.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,4EAA4E;AAC5E,0EAA0E;AAC1E,wEAAwE;AAExE,MAAM,KAAK,GAAG,CAAC,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,CAAU,CAAC;AAEpG,MAAM,IAAI,GAAG,GAAG,EAAE,CAChB,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;KACxC,QAAQ,CAAC,6BAA6B,CAAC,CAAC;AAE7C,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,SAA6B;IACnF,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,EAAE,MAA+B,EAAE,EAAE;QACvE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,EAAE,CAAC,IAAI,CAAC,mBAAmB,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;YACvE,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,ggBAAggB,EAChgB;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;aAC9B,QAAQ,CAAC,mCAAmC,CAAC;QAChD,IAAI,EAAE,IAAI,EAAE;QACZ,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE;aAC3B,QAAQ,CAAC,6EAA6E,CAAC;QAC1F,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE;aACjD,QAAQ,CAAC,sFAAsF,CAAC;KACpG,EACD,IAAI,CAAC,QAAQ,CAAC,CACf,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,kQAAkQ,EAClQ;QACE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;aACjC,QAAQ,CAAC,oJAAoJ,CAAC;QACjK,IAAI,EAAE,IAAI,EAAE;KACb,EACD,IAAI,CAAC,UAAU,CAAC,CACjB,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,+bAA+b,EAC/b;QACE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;aACvC,QAAQ,CAAC,mNAAmN,CAAC;QAChO,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE;aACtD,QAAQ,CAAC,+EAA+E,CAAC;KAC7F,EACD,IAAI,CAAC,SAAS,CAAC,CAChB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ScavioClient } from "../lib/client.js";
3
+ export declare function registerUltaTools(server: McpServer, getClient: () => ScavioClient): void;
@@ -0,0 +1,45 @@
1
+ import { z } from "zod";
2
+ import { handleApiError } from "../lib/tool-error.js";
3
+ import { trimResponse } from "../lib/trim-response.js";
4
+ // Shapes mirror backend/src/routes/ulta.ts. No zod `.default()`: the MCP SDK
5
+ // would post a defaulted field on every call.
6
+ const page = () => z.number().int().min(1).max(100).optional()
7
+ .describe("Page, 1-based, 64 per page plus sponsored placements.");
8
+ const skuId = () => z.string().regex(/^\d{3,12}$/)
9
+ .describe("Ulta sku id of a shade or size (a result's sku_id or a product's variants[].sku_id), e.g. '2648428'.");
10
+ const CARD_FIELDS = "Each product has product_id, sku_id, brand, name, url, list and sale price in dollars (the low end when shades are priced differently, with list_price_range / sale_price_range), discount, promo text, rating, review count, badge, variant label (e.g. '16 colors'), limited-stock flag and sponsored.";
11
+ export function registerUltaTools(server, getClient) {
12
+ const post = (path) => async (params) => {
13
+ try {
14
+ const data = await getClient().post(`/api/v1/ulta/${path}`, params);
15
+ return trimResponse(data);
16
+ }
17
+ catch (err) {
18
+ return handleApiError(err);
19
+ }
20
+ };
21
+ server.tool("search_ulta", `Search Ulta Beauty products by keyword, 64 per page plus sponsored placements. ${CARD_FIELDS} Sponsored placements can repeat products from other pages; dedupe by product_id. Use a result's url with get_ulta_product, or its product_id and sku_id with get_ulta_stores. 1 credit/call.`, {
22
+ query: z.string().min(1).max(200)
23
+ .describe("Search keywords, e.g. 'lipstick'."),
24
+ page: page(),
25
+ }, post("search"));
26
+ server.tool("get_ulta_category", `Products in an Ulta Beauty category, 64 per page plus sponsored placements, with the category title and total_results. ${CARD_FIELDS} 1 credit/call.`, {
27
+ category: z.string().min(1).max(300)
28
+ .describe("An ulta.com category that lists products: the full URL or its path, e.g. '/shop/makeup/lips/lipstick'. Landing pages with no product grid (e.g. /shop/makeup) are a 404."),
29
+ page: page(),
30
+ }, post("category"));
31
+ server.tool("get_ulta_product", `One Ulta Beauty product by page URL, for the selected shade or size: list and sale price, discount, availability, GTIN, rating, review count, badges, summary, description, usage, ingredients, restrictions, category and breadcrumbs, images, every shade or size variant (sku_id, name, shade description, available, swatch), ship / pickup / same-day eligibility, and the five most recent customer reviews. An unknown product is a 404. 1 credit.`, {
32
+ url: z.string().min(1).max(500)
33
+ .describe("Ulta product page URL, /p/<name>-<productId> (a search or category result's url), e.g. 'https://www.ulta.com/p/serum-lipstick-pimprod2057119'. The name part is required."),
34
+ sku: z.string().regex(/^\d{3,12}$/).optional()
35
+ .describe("Shade or size to select, by sku id (a variants[].sku_id). Defaults to the URL's ?sku=, else the product's default."),
36
+ }, post("product"));
37
+ server.tool("get_ulta_stores", `In-store pickup availability of one Ulta Beauty shade or size at the 10 stores nearest a US ZIP: store id, name, address, distance in miles, open now and hours label, curbside label, in_stock and the availability label. Ulta publishes in stock / out of stock per store, not unit counts. 1 credit.`, {
38
+ product_id: z.string().regex(/^[A-Za-z]*\d+$/)
39
+ .describe("Ulta product id (a search or product result's product_id), e.g. 'pimprod2057119'."),
40
+ sku_id: skuId(),
41
+ zip: z.string().regex(/^\d{5}(-\d{4})?$/)
42
+ .describe("US ZIP code to search around, e.g. '10001'."),
43
+ }, post("stores"));
44
+ }
45
+ //# sourceMappingURL=ulta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ulta.js","sourceRoot":"","sources":["../../src/tools/ulta.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,6EAA6E;AAC7E,8CAA8C;AAE9C,MAAM,IAAI,GAAG,GAAG,EAAE,CAChB,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;KACxC,QAAQ,CAAC,uDAAuD,CAAC,CAAC;AAEvE,MAAM,KAAK,GAAG,GAAG,EAAE,CACjB,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC;KAC3B,QAAQ,CAAC,sGAAsG,CAAC,CAAC;AAEtH,MAAM,WAAW,GACf,0SAA0S,CAAC;AAE7S,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,SAA6B;IAChF,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,EAAE,MAA+B,EAAE,EAAE;QACvE,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,EAAE,CAAC,IAAI,CAAC,gBAAgB,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;YACpE,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,aAAa,EACb,kFAAkF,WAAW,+LAA+L,EAC5R;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;aAC9B,QAAQ,CAAC,mCAAmC,CAAC;QAChD,IAAI,EAAE,IAAI,EAAE;KACb,EACD,IAAI,CAAC,QAAQ,CAAC,CACf,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,0HAA0H,WAAW,iBAAiB,EACtJ;QACE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;aACjC,QAAQ,CAAC,0KAA0K,CAAC;QACvL,IAAI,EAAE,IAAI,EAAE;KACb,EACD,IAAI,CAAC,UAAU,CAAC,CACjB,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB,2bAA2b,EAC3b;QACE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;aAC5B,QAAQ,CAAC,2KAA2K,CAAC;QACxL,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE;aAC3C,QAAQ,CAAC,oHAAoH,CAAC;KAClI,EACD,IAAI,CAAC,SAAS,CAAC,CAChB,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,0SAA0S,EAC1S;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,gBAAgB,CAAC;aAC3C,QAAQ,CAAC,mFAAmF,CAAC;QAChG,MAAM,EAAE,KAAK,EAAE;QACf,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC;aACtC,QAAQ,CAAC,6CAA6C,CAAC;KAC3D,EACD,IAAI,CAAC,QAAQ,CAAC,CACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ScavioClient } from "../lib/client.js";
3
+ export declare function registerWalgreensTools(server: McpServer, getClient: () => ScavioClient): void;
@@ -0,0 +1,67 @@
1
+ import { z } from "zod";
2
+ import { handleApiError } from "../lib/tool-error.js";
3
+ import { trimResponse } from "../lib/trim-response.js";
4
+ // Shapes mirror backend/src/routes/walgreens.ts. Cross-field rule the backend
5
+ // enforces and zod here does not: stores takes zip OR latitude+longitude. No
6
+ // zod `.default()`: the MCP SDK would post a defaulted field on every call.
7
+ const SORTS = [
8
+ "relevance",
9
+ "top_sellers",
10
+ "price_low_to_high",
11
+ "price_high_to_low",
12
+ "unit_price_low_to_high",
13
+ "brand_name_asc",
14
+ "brand_name_desc",
15
+ "most_reviewed",
16
+ "highest_rated",
17
+ "most_viewed",
18
+ "newest_arrival",
19
+ ];
20
+ const storeNumber = () => z.string().regex(/^\d{1,5}$/)
21
+ .describe("Walgreens store number from get_walgreens_stores (field store_number), e.g. '9438'.");
22
+ const productId = () => z.string().min(3).max(500)
23
+ .describe("Walgreens product id (a search result's product_id), e.g. '300452904' or 'prod6345045', or a walgreens.com product URL.");
24
+ export function registerWalgreensTools(server, getClient) {
25
+ const post = (path) => async (params) => {
26
+ try {
27
+ const data = await getClient().post(`/api/v1/walgreens/${path}`, params);
28
+ return trimResponse(data);
29
+ }
30
+ catch (err) {
31
+ return handleApiError(err);
32
+ }
33
+ };
34
+ server.tool("search_walgreens", `Search Walgreens retail products (no pharmacy), up to 70 per page. Each result has product_id, SKU, UPC, name, brand, size, regular and sale price, unit price, promotion, coupon, loyalty and rebate messages, rating, review count, image, URL, ship/pickup/delivery availability, online stock status and clearance flag. Prices are in dollars and national (the same at every store). Pass store_id for that store's availability text. Use a result's product_id with get_walgreens_product and get_walgreens_stock. 2 credits/call.`, {
35
+ query: z.string().min(1).max(200)
36
+ .describe("Search keywords, e.g. 'shampoo'."),
37
+ page: z.number().int().min(1).max(100).optional()
38
+ .describe("Page, 1-based, up to 70 per page."),
39
+ sort: z.enum(SORTS).optional()
40
+ .describe("relevance (default), top_sellers, price_low_to_high, price_high_to_low, unit_price_low_to_high, brand_name_asc, brand_name_desc, most_reviewed, highest_rated, most_viewed or newest_arrival."),
41
+ store_id: storeNumber().optional()
42
+ .describe("Walgreens store number, e.g. '9438'. Each result's availability text then describes that store (e.g. 'Not sold at your store')."),
43
+ }, post("search"));
44
+ server.tool("get_walgreens_product", `One Walgreens retail product: SKU, UPC, GTIN, name, brand, size, regular and sale price, savings, unit price, offers (rewards and rebates), description, ingredients, warnings, rating and review count, category path, images, ship and pickup availability, clearance flag. Prices are in dollars and national. For in-store stock use get_walgreens_stock. An unknown id is a 404. 2 credits.`, {
45
+ product_id: productId(),
46
+ }, post("product"));
47
+ server.tool("get_walgreens_stores", `Walgreens and Duane Reade stores near a US ZIP or coordinates, nearest first: store number, name, brand, address, phone, coordinates, distance in miles, opening and closing time, time zone and store page URL. Paged (total_results, total_pages, has_more). Use store numbers with search_walgreens (store_id) and get_walgreens_stock (store_ids). 2 credits/call.`, {
48
+ zip: z.string().regex(/^\d{5}(-\d{4})?$/).optional()
49
+ .describe("US ZIP code, e.g. '60601'. Pass this or latitude and longitude."),
50
+ latitude: z.number().min(-90).max(90).optional()
51
+ .describe("Latitude, e.g. 40.7484."),
52
+ longitude: z.number().min(-180).max(180).optional()
53
+ .describe("Longitude, e.g. -73.9857."),
54
+ radius: z.number().min(1).max(100).optional()
55
+ .describe("Search radius in miles. Default 25."),
56
+ page: z.number().int().min(1).max(100).optional()
57
+ .describe("Page, 1-based."),
58
+ limit: z.number().int().min(1).max(25).optional()
59
+ .describe("Stores per page, 1-25. Default 10."),
60
+ }, post("stores"));
61
+ server.tool("get_walgreens_stock", `Live in-store stock of one Walgreens product at up to 20 stores in one call: per store the status (In Stock, Out of Stock, or Not Available when the store does not carry it), the unit count and in_stock. Store numbers Walgreens does not recognise are listed in unknown_store_ids. An unknown product id is a 404. 4 credits.`, {
62
+ product_id: productId(),
63
+ store_ids: z.array(storeNumber()).min(1).max(20)
64
+ .describe("Walgreens store numbers to check, up to 20, e.g. ['9438', '14318']."),
65
+ }, post("stock"));
66
+ }
67
+ //# sourceMappingURL=walgreens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walgreens.js","sourceRoot":"","sources":["../../src/tools/walgreens.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@scavio/mcp-server",
3
- "version": "0.29.1",
3
+ "version": "0.30.1",
4
4
  "mcpName": "io.github.scavio-ai/scavio-mcp",
5
- "description": "MCP server connecting AI agents to Scavio: web search, page extraction, and structured e-commerce, social, travel, jobs, real-estate, app-store, ad-library and company-filing data. 298 tools across 45 platforms plus Extract, site map, crawl and batch extraction, one API key.",
5
+ "description": "MCP server connecting AI agents to Scavio: web search, page extraction, and structured e-commerce, social, travel, jobs, real-estate, app-store, ad-library and company-filing data. 318 tools across 51 platforms plus Extract, site map, crawl and batch extraction, one API key.",
6
6
  "type": "module",
7
7
  "license": "MIT",
8
8
  "author": "Scavio",
@@ -27,6 +27,12 @@
27
27
  "sams-club",
28
28
  "canadian-tire",
29
29
  "dollar-general",
30
+ "sephora",
31
+ "ulta",
32
+ "aldi",
33
+ "micro-center",
34
+ "walgreens",
35
+ "cvs",
30
36
  "mercadolibre",
31
37
  "mercado-libre",
32
38
  "tiktok",