@scavio/mcp-server 0.12.0 → 0.13.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.
Files changed (101) hide show
  1. package/README.md +365 -4
  2. package/dist/index.js +26 -7
  3. package/dist/index.js.map +1 -1
  4. package/dist/lib/env.d.ts +1 -0
  5. package/dist/lib/env.js +4 -0
  6. package/dist/lib/env.js.map +1 -1
  7. package/dist/lib/tool-error.d.ts +22 -0
  8. package/dist/lib/tool-error.js +28 -0
  9. package/dist/lib/tool-error.js.map +1 -0
  10. package/dist/tools/airbnb.d.ts +3 -0
  11. package/dist/tools/airbnb.js +121 -0
  12. package/dist/tools/airbnb.js.map +1 -0
  13. package/dist/tools/amazon.js +1 -12
  14. package/dist/tools/amazon.js.map +1 -1
  15. package/dist/tools/appstore.d.ts +3 -0
  16. package/dist/tools/appstore.js +59 -0
  17. package/dist/tools/appstore.js.map +1 -0
  18. package/dist/tools/booking.d.ts +3 -0
  19. package/dist/tools/booking.js +116 -0
  20. package/dist/tools/booking.js.map +1 -0
  21. package/dist/tools/capterra.d.ts +3 -0
  22. package/dist/tools/capterra.js +53 -0
  23. package/dist/tools/capterra.js.map +1 -0
  24. package/dist/tools/companieshouse.d.ts +3 -0
  25. package/dist/tools/companieshouse.js +56 -0
  26. package/dist/tools/companieshouse.js.map +1 -0
  27. package/dist/tools/ebay.d.ts +3 -0
  28. package/dist/tools/ebay.js +79 -0
  29. package/dist/tools/ebay.js.map +1 -0
  30. package/dist/tools/extract.d.ts +3 -0
  31. package/dist/tools/extract.js +21 -0
  32. package/dist/tools/extract.js.map +1 -0
  33. package/dist/tools/g2.d.ts +3 -0
  34. package/dist/tools/g2.js +69 -0
  35. package/dist/tools/g2.js.map +1 -0
  36. package/dist/tools/glassdoor.d.ts +3 -0
  37. package/dist/tools/glassdoor.js +72 -0
  38. package/dist/tools/glassdoor.js.map +1 -0
  39. package/dist/tools/google.js +1 -12
  40. package/dist/tools/google.js.map +1 -1
  41. package/dist/tools/googleads.d.ts +3 -0
  42. package/dist/tools/googleads.js +61 -0
  43. package/dist/tools/googleads.js.map +1 -0
  44. package/dist/tools/googleplay.d.ts +3 -0
  45. package/dist/tools/googleplay.js +57 -0
  46. package/dist/tools/googleplay.js.map +1 -0
  47. package/dist/tools/homedepot.d.ts +3 -0
  48. package/dist/tools/homedepot.js +71 -0
  49. package/dist/tools/homedepot.js.map +1 -0
  50. package/dist/tools/indeed.d.ts +3 -0
  51. package/dist/tools/indeed.js +98 -0
  52. package/dist/tools/indeed.js.map +1 -0
  53. package/dist/tools/index.d.ts +42 -1
  54. package/dist/tools/index.js +204 -15
  55. package/dist/tools/index.js.map +1 -1
  56. package/dist/tools/instagram.js +1 -12
  57. package/dist/tools/instagram.js.map +1 -1
  58. package/dist/tools/kuaishou.d.ts +3 -0
  59. package/dist/tools/kuaishou.js +207 -0
  60. package/dist/tools/kuaishou.js.map +1 -0
  61. package/dist/tools/linkedin.js +1 -12
  62. package/dist/tools/linkedin.js.map +1 -1
  63. package/dist/tools/metaads.d.ts +3 -0
  64. package/dist/tools/metaads.js +63 -0
  65. package/dist/tools/metaads.js.map +1 -0
  66. package/dist/tools/reddit.js +1 -12
  67. package/dist/tools/reddit.js.map +1 -1
  68. package/dist/tools/redfin.d.ts +3 -0
  69. package/dist/tools/redfin.js +100 -0
  70. package/dist/tools/redfin.js.map +1 -0
  71. package/dist/tools/sec.d.ts +3 -0
  72. package/dist/tools/sec.js +104 -0
  73. package/dist/tools/sec.js.map +1 -0
  74. package/dist/tools/target.d.ts +3 -0
  75. package/dist/tools/target.js +105 -0
  76. package/dist/tools/target.js.map +1 -0
  77. package/dist/tools/threads.d.ts +3 -0
  78. package/dist/tools/threads.js +93 -0
  79. package/dist/tools/threads.js.map +1 -0
  80. package/dist/tools/tiktok-shop.js +3 -11
  81. package/dist/tools/tiktok-shop.js.map +1 -1
  82. package/dist/tools/tiktok.js +1 -12
  83. package/dist/tools/tiktok.js.map +1 -1
  84. package/dist/tools/tripadvisor.d.ts +3 -0
  85. package/dist/tools/tripadvisor.js +103 -0
  86. package/dist/tools/tripadvisor.js.map +1 -0
  87. package/dist/tools/usage.js +2 -10
  88. package/dist/tools/usage.js.map +1 -1
  89. package/dist/tools/walmart.js +108 -41
  90. package/dist/tools/walmart.js.map +1 -1
  91. package/dist/tools/x.js +1 -12
  92. package/dist/tools/x.js.map +1 -1
  93. package/dist/tools/yelp.d.ts +3 -0
  94. package/dist/tools/yelp.js +65 -0
  95. package/dist/tools/yelp.js.map +1 -0
  96. package/dist/tools/youtube.js +1 -12
  97. package/dist/tools/youtube.js.map +1 -1
  98. package/dist/tools/zillow.d.ts +3 -0
  99. package/dist/tools/zillow.js +123 -0
  100. package/dist/tools/zillow.js.map +1 -0
  101. package/package.json +12 -2
package/README.md CHANGED
@@ -3,7 +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) is a unified [Web Search API](https://scavio.dev/docs/search-api) and MCP server that connects AI agents to Google, YouTube, Amazon, Walmart, TikTok, Instagram, Reddit, X, LinkedIn, and TikTok Shop. 100 tools for web search, product lookup, video discovery, and social media data through a single [Search API](https://scavio.dev/docs/search-api) endpoint.
6
+ [Scavio](https://scavio.dev) is a unified [Web Search API](https://scavio.dev/docs/search-api) 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. 191 tools across 31 platforms plus Extract, one API key.
7
+
8
+ **The 22 platforms added in 0.13.0 are opt-in.** Registering all 191 tools puts 262KB of tool definitions — roughly 70k tokens — into every session before you type anything. So the default is the surface 0.12.x already had, plus Extract: 106 tools, 102KB. Upgrading never removes a tool you were using. Everything else is one env var away: see [Choosing which tools load](#choosing-which-tools-load).
7
9
 
8
10
  ## Remote MCP Server
9
11
 
@@ -190,12 +192,114 @@ Add to settings (`Cmd+,`):
190
192
 
191
193
  ---
192
194
 
195
+ ## Choosing which tools load
196
+
197
+ Scavio exposes 191 tools. Loading all of them costs 262KB of `tools/list` —
198
+ roughly 70k tokens of context in every session before the user has said anything,
199
+ and more tools than some clients will accept at all. So the server registers a
200
+ curated subset by default and lets you pick the rest. The sizes below are
201
+ measured, not estimated: `npm run toolslist` reproduces them.
202
+
203
+ `SCAVIO_PLATFORMS` is a comma-separated allowlist of platform keys:
204
+
205
+ | Value | Registers |
206
+ |-------|-----------|
207
+ | *(unset)* | Everything 0.12.x had, plus `extract` — **106 tools, 102KB** |
208
+ | `all` | every platform — **191 tools, 262KB** |
209
+ | `extract,sec,g2` | just those platforms — 11 tools, 20KB |
210
+ | `default,walmart,metaads` | the default set plus two more — 58 tools |
211
+ | `none` | no platform tools, only `get_usage` |
212
+
213
+ Keys are matched case- and punctuation-insensitively, so `meta-ads`, `metaads`
214
+ and `META_ADS` are the same thing, and `twitter` resolves to `x`. An unknown key
215
+ is logged to stderr and skipped rather than failing the server.
216
+
217
+ `get_usage` always registers — it is free, and it is what every install guide
218
+ tells you to call to check the server works.
219
+
220
+ **Platform keys:** `extract`, `google`, `youtube`, `tiktok`, `instagram`,
221
+ `reddit`, `x`, `linkedin`, `threads`, `kuaishou`, `amazon`, `walmart`, `ebay`,
222
+ `target`, `homedepot`, `tiktok-shop`, `booking`, `airbnb`, `tripadvisor`,
223
+ `yelp`, `zillow`, `redfin`, `indeed`, `glassdoor`, `appstore`, `googleplay`,
224
+ `g2`, `capterra`, `googleads`, `metaads`, `sec`, `companieshouse`
225
+
226
+ ### Local (stdio)
227
+
228
+ ```json
229
+ {
230
+ "mcpServers": {
231
+ "scavio": {
232
+ "command": "npx",
233
+ "args": ["-y", "@scavio/mcp-server"],
234
+ "env": {
235
+ "SCAVIO_API_KEY": "YOUR_SCAVIO_API_KEY",
236
+ "SCAVIO_PLATFORMS": "extract,google,zillow,redfin"
237
+ }
238
+ }
239
+ }
240
+ }
241
+ ```
242
+
243
+ ### Remote (HTTP)
244
+
245
+ The hosted server has no env var to read, so pass the allowlist per connection —
246
+ either as a header or as a query parameter:
247
+
248
+ ```json
249
+ {
250
+ "scavio": {
251
+ "type": "http",
252
+ "url": "https://mcp.scavio.dev/mcp",
253
+ "headers": {
254
+ "x-api-key": "YOUR_SCAVIO_API_KEY",
255
+ "x-scavio-platforms": "extract,google,sec,companieshouse"
256
+ }
257
+ }
258
+ }
259
+ ```
260
+
261
+ ```
262
+ https://mcp.scavio.dev/mcp?platforms=all
263
+ ```
264
+
265
+ ### Upgrading from 0.12.x
266
+
267
+ Nothing to do. The default set is exactly the 10 platforms 0.12.x registered,
268
+ plus Extract — every tool you were using still loads, and the context cost is
269
+ unchanged. Walmart grew from 2 tools to 7, so the count moves 100 → 106.
270
+
271
+ The 22 platforms added in 0.13.0 are opt-in. Add them additively:
272
+
273
+ ```
274
+ SCAVIO_PLATFORMS=default,zillow,redfin,sec
275
+ ```
276
+
277
+ One breaking fix worth knowing: `search_walmart` previously sent
278
+ `fulfillment_speed: "anytime"` on every call, which the API rejects. The
279
+ parameter is now `today` or `tomorrow` with no default.
280
+
281
+ ---
282
+
193
283
  ## Available Tools
194
284
 
195
- Every tool costs 1 credit per call unless its section says otherwise - YouTube,
196
- Instagram and LinkedIn price per endpoint, and `get_amazon_options` and `get_usage`
285
+ Every tool costs 1 credit per call unless its section says otherwise. Several
286
+ platforms price per endpoint (YouTube, Instagram, LinkedIn, Kuaishou) or per
287
+ request body (Extract, Threads, Walmart); `get_amazon_options` and `get_usage`
197
288
  are free.
198
289
 
290
+ ### [Extract](https://scavio.dev/docs/extract)
291
+
292
+ | Tool | Description |
293
+ |------|-------------|
294
+ | `extract_url` | Read any web page and return it as clean Markdown, plain text, or raw HTML |
295
+
296
+ Extract is tier-priced by the `mode` parameter, not flat: `normal` (plain fetch)
297
+ and `advanced` (full JavaScript rendering) cost 1 credit, `ultra` (residential
298
+ proxy, for hard bot walls) costs 2. Start at `normal` and escalate only when the
299
+ content comes back empty or blocked. You are billed only on a successful
300
+ extraction — a dead link, a bot wall or a timeout costs nothing. There is no
301
+ pagination: the whole page comes back in one call.
302
+
199
303
  ### [Google Search API](https://scavio.dev/docs/search-api)
200
304
 
201
305
  | Tool | Description |
@@ -256,6 +360,25 @@ single page.
256
360
  |------|-------------|
257
361
  | `search_walmart` | Search product listings with price and delivery filters |
258
362
  | `get_walmart_product` | Get full product details by product ID |
363
+ | `get_walmart_reviews` | Customer reviews with ratings, text, author, date and the rating breakdown |
364
+ | `get_walmart_category` | Products within a category, same product shape as search |
365
+ | `get_walmart_offers` | The buy-box offer for a product: price, seller, condition, buy-box flag |
366
+ | `get_walmart_seller` | Marketplace seller storefront: name, rating, Pro Seller badge, business details |
367
+ | `get_walmart_seller_products` | A seller's catalogue; `total_count` is the real size |
368
+
369
+ Walmart is priced by the `domain` parameter, not at a flat rate: `com` (US,
370
+ default) and `ca` cost 1 credit, `com.mx` costs 2. Only `search_walmart` and
371
+ `get_walmart_category` accept `domain`, so only those two can cost 2 — the other
372
+ five are always 1. The id-keyed tools are US-only, because walmart.ca product
373
+ pages cannot be fetched.
374
+
375
+ Two shapes to plan for. `get_walmart_offers` returns the buy-box winner only —
376
+ Walmart server-renders just that one offer, so expect a single row even when
377
+ `total_offer_count` is higher. And `get_walmart_seller_products` is capped at
378
+ roughly the first 40 items with no page or cursor parameter; read `total_count`
379
+ to know you are looking at a slice. Both seller tools need the NUMERIC
380
+ `seller_catalog_id` from a product, search or offers response — the GUID-form
381
+ `seller_id` in those same responses 404s.
259
382
 
260
383
  ### [TikTok API](https://scavio.dev/docs/tiktok-api)
261
384
 
@@ -388,6 +511,238 @@ looping. For an id that will not resolve, `get_tiktok_shop_product_reviews` is o
388
511
  across 8 measured ids that failed on detail, 8 of 8 returned HTTP 200 on reviews and 7 of 8 returned
389
512
  at least one review.
390
513
 
514
+ ### [Threads](https://scavio.dev/docs/threads-profile)
515
+
516
+ | Tool | Description |
517
+ |------|-------------|
518
+ | `get_threads_profile` | Profile details for a Threads user, by `user_id` or `username` |
519
+ | `get_threads_user_posts` | A user's Threads posts, cursor-paginated |
520
+ | `get_threads_user_replies` | A user's replies, cursor-paginated |
521
+ | `get_threads_post` | A single post by id or threads.net URL |
522
+ | `get_threads_post_comments` | Replies to a post, cursor-paginated |
523
+ | `search_threads_users` | Profiles matching a name or handle - the only search Threads exposes |
524
+
525
+ Threads is priced by how you address a user, not per endpoint: 2 credits when you pass `user_id`, 4 credits when you pass `username`. Only `get_threads_profile`, `get_threads_user_posts` and `get_threads_user_replies` accept a username; the other three are always 2. Prefer `user_id` - a handle buys a second upstream lookup.
526
+
527
+ ### [Kuaishou (China)](https://scavio.dev/docs/kuaishou-profile)
528
+
529
+ | Tool | Description |
530
+ |------|-------------|
531
+ | `get_kuaishou_profile` | Profile details for a Kuaishou user (10 credits) |
532
+ | `get_kuaishou_user_posts` | A user's top posts, cursor-paginated |
533
+ | `get_kuaishou_user_live` | A user's current live-stream status |
534
+ | `resolve_kuaishou_user` | Turn a Kuaishou share link into a user id |
535
+ | `get_kuaishou_video` | A single video by photo id or URL (2 credits) |
536
+ | `get_kuaishou_video_comments` | Comments on a video, cursor-paginated |
537
+ | `get_kuaishou_comment_replies` | Replies under a root comment |
538
+ | `get_kuaishou_videos_batch` | Up to 20 videos in one call (40 credits) |
539
+ | `search_kuaishou` | Mixed-result search across Kuaishou (10 credits) |
540
+ | `search_kuaishou_videos` | Video search results (10 credits) |
541
+ | `search_kuaishou_users` | User search results (10 credits) |
542
+ | `search_kuaishou_live` | Live-stream search results (10 credits) |
543
+ | `get_kuaishou_tag_feed` | Posts under a hashtag, cursor-paginated |
544
+ | `get_kuaishou_trending` | Hot, live, shopping, brand and music leaderboards |
545
+
546
+ Kuaishou is priced per endpoint, not at a flat rate: `get_kuaishou_profile` and all four search tools cost 10, `get_kuaishou_video` 2, `get_kuaishou_videos_batch` 40, and every other tool 1.
547
+
548
+ ### [eBay](https://scavio.dev/docs/ebay-search)
549
+
550
+ | Tool | Description |
551
+ |------|-------------|
552
+ | `search_ebay` | Search live or SOLD listings: price, condition, bids, shipping, seller feedback |
553
+ | `get_ebay_product` | One listing in full: price, condition, images, item specifics, shipping, returns, auction state |
554
+ | `get_ebay_seller` | Seller profile card: store name, feedback score, items sold, followers, location |
555
+
556
+ 1 credit per call. `get_ebay_seller` is a profile card and cannot enumerate a catalogue - list a seller's inventory with `search_ebay` and `seller` set and no keyword. `sold: true` searches completed listings that actually sold; on that view eBay publishes no headline count, so `total_results` is null. `per_page` accepts only 60, 120 or 240.
557
+
558
+ ### [Target](https://scavio.dev/docs/target-search)
559
+
560
+ | Tool | Description |
561
+ |------|-------------|
562
+ | `search_target_products` | Search Target.com: prices, ratings, badges and promotions |
563
+ | `get_target_category` | Products in a category, same shape as search plus the breadcrumb |
564
+ | `get_target_product` | Product details by TCIN: price, images, specifications, variants, fulfillment |
565
+ | `get_target_reviews` | Reviews with the rating breakdown, per-attribute averages and guest photos |
566
+
567
+ 1 credit per call. `get_target_product` and `get_target_reviews` are single-shot; search and category page with `page` + `count`.
568
+
569
+ ### [Home Depot](https://scavio.dev/docs/home-depot-search)
570
+
571
+ | Tool | Description |
572
+ |------|-------------|
573
+ | `search_home_depot` | Search Home Depot: price, brand and model, ratings, per-store pickup/delivery |
574
+ | `get_home_depot_product` | Full item detail: pricing, media, spec table, dimensions, documents, return policy |
575
+ | `get_home_depot_reviews` | Full review bodies, rating distribution, per-attribute ratings, seller responses |
576
+
577
+ 2 credits per call. Search page size is fixed at 12 and cannot be changed. Reviews return 30 per page; `total_pages` is the last page that exists and asking past it is a 404.
578
+
579
+ ### [Booking.com](https://scavio.dev/docs/booking-search)
580
+
581
+ | Tool | Description |
582
+ |------|-------------|
583
+ | `search_booking` | Properties for a destination and stay: live nightly price, review score, room type |
584
+ | `get_booking_hotel` | One property in full: rooms and rate plans, facilities, house rules, policies, images |
585
+ | `get_booking_reviews` | Guest reviews with the score breakdown by category and Booking's own summary |
586
+
587
+ 1 credit per call. Search returns 25 properties per page; `get_booking_hotel` and `get_booking_reviews` are single-shot.
588
+
589
+ ### [Airbnb](https://scavio.dev/docs/airbnb-search)
590
+
591
+ | Tool | Description |
592
+ |------|-------------|
593
+ | `search_airbnb` | Stays with stay-total and per-night price, the full discount ledger, rating, coordinates |
594
+ | `get_airbnb_listing` | One listing in full: description, capacity, grouped amenities, host, house rules, rating breakdown |
595
+ | `get_airbnb_reviews` | Review bodies with per-review rating, date and reviewer profile |
596
+
597
+ 1 credit per call. `search_airbnb` takes `page` XOR `cursor` - sending both is rejected, and `cursor` wins. 18 listings per page. `get_airbnb_reviews` pages with `limit` + `offset`.
598
+
599
+ ### [Tripadvisor](https://scavio.dev/docs/tripadvisor-locations)
600
+
601
+ | Tool | Description |
602
+ |------|-------------|
603
+ | `resolve_tripadvisor_location` | START HERE - resolve a place or business name to the `geo_id` / `location_id` pair |
604
+ | `search_tripadvisor` | Restaurants, hotels or attractions in a geo, TripAdvisor-ranked |
605
+ | `get_tripadvisor_location` | One location in full: rating histogram, sub-ratings, city ranking, amenities, first review page |
606
+ | `get_tripadvisor_reviews` | A page of reviews: rating, trip date and type, reviewer profile, management response |
607
+
608
+ 2 credits per call. Start with `resolve_tripadvisor_location` for the `geo_id` / `location_id` pair everything else needs. Search returns 30 per page and a page past the last is a 404, not an empty result. Reviews return 15 per page for restaurants and 10 for hotels and attractions, so `category` must match the location's own type on any page past the first.
609
+
610
+ ### [Yelp](https://scavio.dev/docs/yelp-search)
611
+
612
+ | Tool | Description |
613
+ |------|-------------|
614
+ | `search_yelp` | Businesses in Yelp's ranked order: rating, review count, price band, categories, hours |
615
+ | `get_yelp_business` | One business in full: per-star histogram, contact, hours, amenities, health inspections, Q&A |
616
+ | `get_yelp_reviews` | A page of reviews: rating, full text, author profile, photos, owner response |
617
+
618
+ 2 credits per call. Yelp fixes the page size at 10. `get_yelp_business` already includes the first page of reviews at no extra cost. A review page past the last is a 404, not an empty result.
619
+
620
+ ### [Zillow](https://scavio.dev/docs/zillow-search)
621
+
622
+ | Tool | Description |
623
+ |------|-------------|
624
+ | `search_zillow` | Listings in a region: price, beds, baths, living area, Zestimate, coordinates, days on market |
625
+ | `get_zillow_property` | Full listing: price and price history, Zestimate, tax history, RESO facts, schools, photos |
626
+ | `get_zillow_agent_reviews` | A Zillow AGENT's profile and reviews, specialties, licenses, service areas, sales counts |
627
+
628
+ 1 credit per call. Only `search_zillow` paginates. `get_zillow_agent_reviews` is an AGENT profile, not a property.
629
+
630
+ ### [Redfin](https://scavio.dev/docs/redfin-search)
631
+
632
+ | Tool | Description |
633
+ |------|-------------|
634
+ | `search_redfin` | Listings: price, price per sqft, beds, baths, living area, lot size, year built, photos |
635
+ | `get_redfin_property` | Full listing: Redfin Estimate, MLS fact sheet, price and tax history, schools, climate risk, comps |
636
+ | `get_redfin_market` | Market stats for a region: median list and sale price, sale-to-list ratio, days on market, compete score |
637
+
638
+ 1 credit per call. `search_redfin` pages with `page` + `limit`, up to 350 listings per page; the other two are single-shot.
639
+
640
+ ### [Indeed](https://scavio.dev/docs/indeed-search)
641
+
642
+ | Tool | Description |
643
+ |------|-------------|
644
+ | `search_indeed_jobs` | Job postings: title, employer, rating, location, salary range, job type, apply route |
645
+ | `get_indeed_job` | One posting in full: description text and HTML, structured salary, benefits, original ATS link |
646
+ | `get_indeed_company` | Employer profile: industry, HQ, size, revenue, CEO approval, per-category ratings, open roles |
647
+ | `get_indeed_company_reviews` | Employee reviews with per-category ratings, pros/cons, reviewer job title and location |
648
+
649
+ 2 credits per call. Job search returns 10 postings per page, company reviews 20 per page. `get_indeed_job` and `get_indeed_company` are single-shot.
650
+
651
+ ### [Glassdoor](https://scavio.dev/docs/glassdoor-companies)
652
+
653
+ | Tool | Description |
654
+ |------|-------------|
655
+ | `resolve_glassdoor_company` | START HERE - resolve a company name to the `employer_id` the other tools need |
656
+ | `get_glassdoor_company` | Employer profile: ratings, star distribution, CEO approval, size and revenue bands, awards |
657
+ | `get_glassdoor_reviews` | Up to three full reviews with per-axis scores and employer response, plus complete rating statistics |
658
+ | `get_glassdoor_salaries` | Salaries by job title: base-pay and total-pay percentiles P10-P90, sample counts, pay period |
659
+
660
+ 1 credit per call. Start with `resolve_glassdoor_company` for the `employer_id`. Only `get_glassdoor_salaries` paginates (10 job titles per page; `page_count` is how many exist). `get_glassdoor_reviews` returns up to three full reviews plus complete rating statistics - it is not a paginated review feed.
661
+
662
+ ### [Apple App Store](https://scavio.dev/docs/app-store-search)
663
+
664
+ | Tool | Description |
665
+ |------|-------------|
666
+ | `search_app_store` | Up to 200 fully-shaped apps - doubles as a bulk metadata fetch and a publisher lookup |
667
+ | `get_app_store_app` | Full listing: developer identity, price, all-time and current-version ratings, release notes, screenshots |
668
+ | `get_app_store_reviews` | A page of reviews: star rating, title, full text, author, and the app version reviewed |
669
+
670
+ 1 credit per call. Reviews page 1-10 at 50 per page and stop hard at page 10: 500 reviews per storefront is Apple's anonymous ceiling, and you reach further by asking a different `country`. Search and app detail do not paginate.
671
+
672
+ ### [Google Play](https://scavio.dev/docs/google-play-search)
673
+
674
+ | Tool | Description |
675
+ |------|-------------|
676
+ | `search_google_play` | Ranked apps: package name, developer, rating, install count, price and IAP range, screenshots |
677
+ | `get_google_play_app` | Full store listing: the real install count, star histogram, IAPs, permissions, Data safety table |
678
+ | `get_google_play_reviews` | A page of reviews: star score, full text, thumbs-up count, developer reply, app version |
679
+
680
+ 2 credits per call - a separate namespace from `google` and not on the Google-exempt price. Reviews are cursor-paginated, and the cursor is opaque, single-use and encodes the sort as well as the position, so send it back with the same `sort` it came from. A cursor past the last review is a 404. Search and app detail do not paginate.
681
+
682
+ ### [G2 Software Reviews](https://scavio.dev/docs/g2-search)
683
+
684
+ | Tool | Description |
685
+ |------|-------------|
686
+ | `search_g2_software` | Search B2B software: star rating, review count, vendor, categories; each row carries `product_id` |
687
+ | `get_g2_product` | Full profile: per-star histogram, pricing editions, feature groups, integrations, alternatives, AI pros/cons |
688
+ | `get_g2_reviews` | A page of reviews: rating, likes/dislikes, problems solved, reviewer firmographics, validated flags |
689
+
690
+ 5 credits per call - the most expensive platform on Scavio. `search_g2_software` pages with `page` + `limit` (capped at 100 on our side); `get_g2_reviews` is fixed at 10 per page and paginates well past the 10 pages G2's own widget links to. `get_g2_product` is single-shot.
691
+
692
+ ### [Capterra Software Reviews](https://scavio.dev/docs/capterra-search)
693
+
694
+ | Tool | Description |
695
+ |------|-------------|
696
+ | `search_capterra_software` | Search B2B software: 20 ranked products with rating, review count and paid-placement flag |
697
+ | `get_capterra_product` | Full profile: per-star histogram, four scored criteria, pricing table, features, plus 25 recent reviews |
698
+ | `get_capterra_reviews` | A page of reviews: overall plus five per-criterion scores, pros, cons, alternatives considered |
699
+
700
+ 2 credits per call. Only `get_capterra_reviews` paginates: 25 per page, capped at page 100 - past it Capterra answers 200 with page one, so check what came back. `get_capterra_product` already includes the 25 most recent reviews.
701
+
702
+ ### [Google Ads Transparency](https://scavio.dev/docs/google-ads-advertisers)
703
+
704
+ | Tool | Description |
705
+ |------|-------------|
706
+ | `resolve_google_ads_advertiser` | START HERE - resolve a brand name or domain to the `advertiser_id` |
707
+ | `search_google_ads` | Every ad Google is running for one advertiser, with first/last seen dates and days actually run |
708
+ | `get_google_ads_creative` | One creative in full - the only tool carrying size variations, impression bucket and region breakdown |
709
+
710
+ 1 credit per call. Start with `resolve_google_ads_advertiser` to turn a brand name or domain into an `advertiser_id`. `search_google_ads` is cursor-paginated at 100 ads per page - re-send the same filters alongside the cursor. `get_google_ads_creative` is the only tool carrying a creative's history, region breakdown and impression bucket.
711
+
712
+ ### [Meta Ad Library](https://scavio.dev/docs/meta-ads-search)
713
+
714
+ | Tool | Description |
715
+ |------|-------------|
716
+ | `search_meta_ads` | Search the Meta Ad Library with full creative: ad copy, headline, CTA, media, platforms, run dates |
717
+ | `get_meta_ads_advertiser` | Every ad a Facebook Page is running, by numeric page id, with the same creative detail |
718
+ | `get_meta_ad` | One ad in full by archive id: creative, advertiser, run dates, platforms, political disclosure |
719
+
720
+ 1 credit per call, and every cursor page is another credit: page 1 returns 30 ads, then 10 per page thereafter, so the cost of walking a whole query scales with depth. `search_meta_ads` and `get_meta_ads_advertiser` both cursor-paginate - walk `has_next_page`. `get_meta_ad` is single-shot.
721
+
722
+ ### [SEC EDGAR](https://scavio.dev/docs/sec-edgar-lookup)
723
+
724
+ | Tool | Description |
725
+ |------|-------------|
726
+ | `resolve_sec_company` | START HERE - resolve a company name or ticker to the CIK everything else is keyed by |
727
+ | `get_sec_company` | Filer profile: legal and former names, SIC industry, EIN, LEI, fiscal year end, tickers |
728
+ | `get_sec_filings` | A page of one filer's filings: accession number, form, dates, 8-K item codes, document links |
729
+ | `get_sec_concept` | Every value a filer reported for one XBRL concept, newest first, with its source filing |
730
+ | `get_sec_facts` | The index of every XBRL concept a filer reports - use it to find what to ask `get_sec_concept` for |
731
+ | `search_sec_filings` | EDGAR full-text search, 2001-today, with facets by company, form, industry and state |
732
+
733
+ 1 credit per call on the official free EDGAR JSON API. Start with `resolve_sec_company` to turn a name or ticker into a CIK. `get_sec_filings` pages with `page` + `limit`; `search_sec_filings` pages up to 100, because the index refuses a result window past 10,000.
734
+
735
+ ### [Companies House](https://scavio.dev/docs/companies-house-search)
736
+
737
+ | Tool | Description |
738
+ |------|-------------|
739
+ | `search_companies_house` | START HERE - search the UK register by name for the `company_number` |
740
+ | `get_companies_house_company` | Full register entry: status, type, dates, registered office, SIC codes, accounts due dates |
741
+ | `get_companies_house_officers` | Officers current and resigned: role, appointment and resignation dates, nationality, DOB |
742
+ | `get_companies_house_filing_history` | Filings most recent first: date, type code, description, link to the filed PDF |
743
+
744
+ 1 credit per call on the official UK register. Start with `search_companies_house` for a `company_number`. Search returns 20 per page and is capped at page 50 - the register serves a 1000-result window per term whatever hit count it prints, then answers page 51 with a 416. Officers (35/page) and filing history have no upper page bound; past the last page they return an ordinary 200 with an empty list, which looks identical to having none.
745
+
391
746
  ### Account
392
747
 
393
748
  | Tool | Description |
@@ -401,8 +756,14 @@ at least one review.
401
756
  [Scavio](https://scavio.dev) is a unified [search API for AI agents](https://scavio.dev/search-api-for-ai-agents) and a data API for developers. One key, structured JSON, no scraping or proxies:
402
757
 
403
758
  - [Google Search API](https://scavio.dev/google-search-api) — SERP results, news, images, maps, and knowledge graph
404
- - [Amazon Product API](https://scavio.dev/amazon-product-api) and [Walmart Product API](https://scavio.dev/walmart-product-api) — product search and details
759
+ - [Extract](https://scavio.dev/docs/extract) — read any URL as Markdown, plain text or raw HTML
760
+ - [Amazon Product API](https://scavio.dev/amazon-product-api) and [Walmart Product API](https://scavio.dev/walmart-product-api) — product search and details, alongside [eBay](https://scavio.dev/docs/ebay-search), [Target](https://scavio.dev/docs/target-search) and [Home Depot](https://scavio.dev/docs/home-depot-search)
405
761
  - [TikTok API](https://scavio.dev/tiktok-api), [Instagram API](https://scavio.dev/instagram-api), [Reddit API](https://scavio.dev/reddit-api), [X API](https://scavio.dev/x-api), [LinkedIn API](https://scavio.dev/linkedin-api), and [YouTube API](https://scavio.dev/youtube-transcript-api) — social and video data
762
+ - Travel and local — [Booking.com](https://scavio.dev/docs/booking-search), [Airbnb](https://scavio.dev/docs/airbnb-search), [Tripadvisor](https://scavio.dev/docs/tripadvisor-locations), [Yelp](https://scavio.dev/docs/yelp-search)
763
+ - Real estate — [Zillow](https://scavio.dev/docs/zillow-search), [Redfin](https://scavio.dev/docs/redfin-search)
764
+ - Jobs and employer data — [Indeed](https://scavio.dev/docs/indeed-search), [Glassdoor](https://scavio.dev/docs/glassdoor-companies)
765
+ - Apps, software reviews and ad libraries — [App Store](https://scavio.dev/docs/app-store-search), [Google Play](https://scavio.dev/docs/google-play-search), [G2](https://scavio.dev/docs/g2-search), [Capterra](https://scavio.dev/docs/capterra-search), [Google Ads Transparency](https://scavio.dev/docs/google-ads-advertisers), [Meta Ad Library](https://scavio.dev/docs/meta-ads-search)
766
+ - Company filings — [SEC EDGAR](https://scavio.dev/docs/sec-edgar-lookup), [Companies House](https://scavio.dev/docs/companies-house-search)
406
767
 
407
768
  Teams use it as a [SerpAPI alternative](https://scavio.dev/alternatives/serpapi) with structured multi-platform data — see [Tavily vs Scavio](https://scavio.dev/compare/tavily/vs-scavio) for a head-to-head comparison.
408
769
 
package/dist/index.js CHANGED
@@ -1,10 +1,19 @@
1
1
  #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
2
5
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
6
  import { env } from "./lib/env.js";
4
7
  import { ScavioClient } from "./lib/client.js";
5
- import { registerAllTools } from "./tools/index.js";
8
+ import { registerAllTools, PLATFORM_KEYS, DEFAULT_PLATFORMS } from "./tools/index.js";
6
9
  const SERVER_NAME = "scavio-mcp";
7
- const SERVER_VERSION = "0.1.0";
10
+ /**
11
+ * Read from package.json rather than a literal. The literal drifted to five
12
+ * minor versions behind npm, and it is the version every client is handed
13
+ * during `initialize`. src/ and dist/ are both one level under the package
14
+ * root, so this resolves identically under tsx and under node dist/index.js.
15
+ */
16
+ const SERVER_VERSION = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf8")).version;
8
17
  if (env.TRANSPORT === "stdio") {
9
18
  await startStdio();
10
19
  }
@@ -20,17 +29,24 @@ async function startStdio() {
20
29
  }
21
30
  const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION });
22
31
  const client = new ScavioClient(apiKey);
23
- registerAllTools(server, () => client);
32
+ const platforms = registerAllTools(server, () => client);
24
33
  const transport = new StdioServerTransport();
25
34
  await server.connect(transport);
26
- console.error(`${SERVER_NAME} started (stdio)`);
35
+ console.error(`${SERVER_NAME} v${SERVER_VERSION} started (stdio) - platforms: ${platforms.join(", ") || "none"}` +
36
+ `${env.SCAVIO_PLATFORMS ? "" : " (default set; set SCAVIO_PLATFORMS=all for every platform)"}`);
27
37
  }
28
38
  async function startHttp() {
29
39
  const { Hono } = await import("hono");
30
40
  const { serve } = await import("@hono/node-server");
31
41
  const { WebStandardStreamableHTTPServerTransport } = await import("@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js");
32
42
  const app = new Hono();
33
- app.get("/", (c) => c.json({ status: "ok", server: SERVER_NAME }));
43
+ app.get("/", (c) => c.json({
44
+ status: "ok",
45
+ server: SERVER_NAME,
46
+ version: SERVER_VERSION,
47
+ platforms: PLATFORM_KEYS,
48
+ default_platforms: DEFAULT_PLATFORMS,
49
+ }));
34
50
  app.get("/health", (c) => c.json({ status: "ok" }));
35
51
  app.post("/mcp", async (c) => {
36
52
  const apiKey = c.req.header("x-api-key") ??
@@ -39,15 +55,18 @@ async function startHttp() {
39
55
  if (!apiKey) {
40
56
  return c.json({ error: "Missing SCAVIO_API_KEY. Provide x-api-key or Authorization: Bearer header." }, 401);
41
57
  }
58
+ // A hosted remote has no per-user env var, so the allowlist is selectable
59
+ // per connection. Falls back to SCAVIO_PLATFORMS, then to the default set.
60
+ const platforms = c.req.header("x-scavio-platforms") ?? c.req.query("platforms") ?? env.SCAVIO_PLATFORMS;
42
61
  const server = new McpServer({ name: SERVER_NAME, version: SERVER_VERSION });
43
62
  const client = new ScavioClient(apiKey);
44
- registerAllTools(server, () => client);
63
+ registerAllTools(server, () => client, platforms);
45
64
  const transport = new WebStandardStreamableHTTPServerTransport({ sessionIdGenerator: undefined });
46
65
  await server.connect(transport);
47
66
  return transport.handleRequest(c.req.raw);
48
67
  });
49
68
  serve({ fetch: app.fetch, port: env.PORT }, (info) => {
50
- console.error(`${SERVER_NAME} started (http) on port ${info.port}`);
69
+ console.error(`${SERVER_NAME} v${SERVER_VERSION} started (http) on port ${info.port}`);
51
70
  });
52
71
  }
53
72
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,WAAW,GAAG,YAAY,CAAC;AACjC,MAAM,cAAc,GAAG,OAAO,CAAC;AAE/B,IAAI,GAAG,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;IAC9B,MAAM,UAAU,EAAE,CAAC;AACrB,CAAC;KAAM,CAAC;IACN,MAAM,SAAS,EAAE,CAAC;AACpB,CAAC;AAED,KAAK,UAAU,UAAU;IACvB,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAC3C,2CAA2C,CAC5C,CAAC;IAEF,MAAM,MAAM,GAAG,GAAG,CAAC,cAAc,CAAC;IAClC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IAC7E,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IACxC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;IAEvC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,GAAG,WAAW,kBAAkB,CAAC,CAAC;AAClD,CAAC;AAED,KAAK,UAAU,SAAS;IACtB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACpD,MAAM,EAAE,wCAAwC,EAAE,GAAG,MAAM,MAAM,CAC/D,+DAA+D,CAChE,CAAC;IAEF,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;IACnE,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAEpD,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3B,MAAM,MAAM,GACV,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC;YACzB,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;YACrD,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAEzB,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,4EAA4E,EAAE,EAAE,GAAG,CAAC,CAAC;QAC9G,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;QAC7E,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;QACxC,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;QAEvC,MAAM,SAAS,GAAG,IAAI,wCAAwC,CAAC,EAAE,kBAAkB,EAAE,SAAS,EAAE,CAAC,CAAC;QAClG,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,OAAO,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;QACnD,OAAO,CAAC,KAAK,CAAC,GAAG,WAAW,2BAA2B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/lib/env.d.ts CHANGED
@@ -3,4 +3,5 @@ export declare const env: {
3
3
  PORT: number;
4
4
  TRANSPORT: "http" | "stdio";
5
5
  SCAVIO_API_KEY?: string | undefined;
6
+ SCAVIO_PLATFORMS?: string | undefined;
6
7
  };
package/dist/lib/env.js CHANGED
@@ -3,6 +3,10 @@ const envSchema = z.object({
3
3
  SCAVIO_API_BASE_URL: z.string().url()
4
4
  .default("https://api.scavio.dev"),
5
5
  SCAVIO_API_KEY: z.string().optional(),
6
+ // Comma-separated allowlist of platform keys to register (see src/tools/index.ts).
7
+ // Unset = the curated default set. "all" = every platform. Left as a free-form
8
+ // string on purpose: an unknown key is warned about and skipped, never fatal.
9
+ SCAVIO_PLATFORMS: z.string().optional(),
6
10
  PORT: z.coerce.number().int().min(1).max(65535)
7
11
  .default(3000),
8
12
  TRANSPORT: z.enum(["http", "stdio"])
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;SAClC,OAAO,CAAC,wBAAwB,CAAC;IACpC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;SAC5C,OAAO,CAAC,IAAI,CAAC;IAChB,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SACjC,OAAO,CAAC,OAAO,CAAC;CACpB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;SAClC,OAAO,CAAC,wBAAwB,CAAC;IACpC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrC,mFAAmF;IACnF,+EAA+E;IAC/E,8EAA8E;IAC9E,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;SAC5C,OAAO,CAAC,IAAI,CAAC;IAChB,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SACjC,OAAO,CAAC,OAAO,CAAC;CACpB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * The catch block every tool handler shares.
3
+ *
4
+ * This lived as a verbatim copy-paste inside each of the tool modules (plus an
5
+ * inlined 32nd copy in usage.ts). At 11 files that was tolerable; at 33 it was
6
+ * a guaranteed drift surface, so it lives here now and is imported.
7
+ *
8
+ * Two distinct error channels, deliberately:
9
+ * - 401 throws an McpError, because a bad key is a configuration fault the
10
+ * agent cannot recover from by retrying or rewording — the client should
11
+ * surface it to the human.
12
+ * - everything else returns `isError: true`, which the model can read and act
13
+ * on (back off on a 429, try another id on a 404) instead of the call
14
+ * blowing up the turn.
15
+ */
16
+ export declare function handleApiError(err: unknown): never | {
17
+ isError: true;
18
+ content: {
19
+ type: "text";
20
+ text: string;
21
+ }[];
22
+ };
@@ -0,0 +1,28 @@
1
+ import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
2
+ import { ApiError } from "./errors.js";
3
+ /**
4
+ * The catch block every tool handler shares.
5
+ *
6
+ * This lived as a verbatim copy-paste inside each of the tool modules (plus an
7
+ * inlined 32nd copy in usage.ts). At 11 files that was tolerable; at 33 it was
8
+ * a guaranteed drift surface, so it lives here now and is imported.
9
+ *
10
+ * Two distinct error channels, deliberately:
11
+ * - 401 throws an McpError, because a bad key is a configuration fault the
12
+ * agent cannot recover from by retrying or rewording — the client should
13
+ * surface it to the human.
14
+ * - everything else returns `isError: true`, which the model can read and act
15
+ * on (back off on a 429, try another id on a 404) instead of the call
16
+ * blowing up the turn.
17
+ */
18
+ export function handleApiError(err) {
19
+ if (err instanceof ApiError) {
20
+ if (err.status === 429)
21
+ return { isError: true, content: [{ type: "text", text: "Rate limited. Wait and retry." }] };
22
+ if (err.status === 401)
23
+ throw new McpError(ErrorCode.InternalError, "Invalid SCAVIO_API_KEY. Check your configuration.");
24
+ return { isError: true, content: [{ type: "text", text: `Scavio API error (${err.status}): ${err.message}` }] };
25
+ }
26
+ throw new McpError(ErrorCode.InternalError, String(err));
27
+ }
28
+ //# sourceMappingURL=tool-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-error.js","sourceRoot":"","sources":["../../src/lib/tool-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;QAC5B,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,+BAA+B,EAAE,CAAC,EAAE,CAAC;QACrH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,aAAa,EAAE,mDAAmD,CAAC,CAAC;QACzH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,GAAG,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;IAClH,CAAC;IACD,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3D,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 registerAirbnbTools(server: McpServer, getClient: () => ScavioClient): void;