@scavio/mcp-server 0.13.1 → 0.14.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 (98) hide show
  1. package/README.md +23 -10
  2. package/dist/auth/cimd.d.ts +2 -0
  3. package/dist/auth/cimd.js +20 -0
  4. package/dist/auth/cimd.js.map +1 -0
  5. package/dist/auth/provider.d.ts +12 -0
  6. package/dist/auth/provider.js +43 -0
  7. package/dist/auth/provider.js.map +1 -0
  8. package/dist/auth/routes.d.ts +2 -0
  9. package/dist/auth/routes.js +214 -0
  10. package/dist/auth/routes.js.map +1 -0
  11. package/dist/auth/stores.d.ts +33 -0
  12. package/dist/auth/stores.js +69 -0
  13. package/dist/auth/stores.js.map +1 -0
  14. package/dist/index.js +15 -1
  15. package/dist/index.js.map +1 -1
  16. package/dist/lib/client.js +4 -1
  17. package/dist/lib/client.js.map +1 -1
  18. package/dist/lib/env.d.ts +3 -0
  19. package/dist/lib/env.js +4 -0
  20. package/dist/lib/env.js.map +1 -1
  21. package/dist/lib/errors.d.ts +5 -1
  22. package/dist/lib/errors.js +5 -1
  23. package/dist/lib/errors.js.map +1 -1
  24. package/dist/lib/tool-error.js +10 -0
  25. package/dist/lib/tool-error.js.map +1 -1
  26. package/dist/lib/trim-response.d.ts +6 -0
  27. package/dist/lib/trim-response.js +26 -0
  28. package/dist/lib/trim-response.js.map +1 -0
  29. package/dist/tools/airbnb.js +30 -49
  30. package/dist/tools/airbnb.js.map +1 -1
  31. package/dist/tools/amazon.js +11 -18
  32. package/dist/tools/amazon.js.map +1 -1
  33. package/dist/tools/appstore.js +16 -15
  34. package/dist/tools/appstore.js.map +1 -1
  35. package/dist/tools/booking.js +28 -45
  36. package/dist/tools/booking.js.map +1 -1
  37. package/dist/tools/capterra.js +16 -15
  38. package/dist/tools/capterra.js.map +1 -1
  39. package/dist/tools/companieshouse.js +11 -10
  40. package/dist/tools/companieshouse.js.map +1 -1
  41. package/dist/tools/ebay.js +21 -30
  42. package/dist/tools/ebay.js.map +1 -1
  43. package/dist/tools/extract.js +6 -5
  44. package/dist/tools/extract.js.map +1 -1
  45. package/dist/tools/g2.js +23 -22
  46. package/dist/tools/g2.js.map +1 -1
  47. package/dist/tools/glassdoor.js +18 -17
  48. package/dist/tools/glassdoor.js.map +1 -1
  49. package/dist/tools/google.js +154 -153
  50. package/dist/tools/google.js.map +1 -1
  51. package/dist/tools/googleads.js +20 -19
  52. package/dist/tools/googleads.js.map +1 -1
  53. package/dist/tools/googleplay.js +14 -13
  54. package/dist/tools/googleplay.js.map +1 -1
  55. package/dist/tools/homedepot.js +15 -28
  56. package/dist/tools/homedepot.js.map +1 -1
  57. package/dist/tools/indeed.js +20 -39
  58. package/dist/tools/indeed.js.map +1 -1
  59. package/dist/tools/index.d.ts +5 -4
  60. package/dist/tools/index.js +5 -4
  61. package/dist/tools/index.js.map +1 -1
  62. package/dist/tools/instagram.js +59 -58
  63. package/dist/tools/instagram.js.map +1 -1
  64. package/dist/tools/kuaishou.js +47 -46
  65. package/dist/tools/kuaishou.js.map +1 -1
  66. package/dist/tools/linkedin.js +26 -25
  67. package/dist/tools/linkedin.js.map +1 -1
  68. package/dist/tools/metaads.js +21 -20
  69. package/dist/tools/metaads.js.map +1 -1
  70. package/dist/tools/reddit.js +48 -47
  71. package/dist/tools/reddit.js.map +1 -1
  72. package/dist/tools/redfin.js +29 -28
  73. package/dist/tools/redfin.js.map +1 -1
  74. package/dist/tools/sec.js +36 -35
  75. package/dist/tools/sec.js.map +1 -1
  76. package/dist/tools/target.js +19 -40
  77. package/dist/tools/target.js.map +1 -1
  78. package/dist/tools/threads.js +20 -19
  79. package/dist/tools/threads.js.map +1 -1
  80. package/dist/tools/tiktok-shop.js +38 -37
  81. package/dist/tools/tiktok-shop.js.map +1 -1
  82. package/dist/tools/tiktok.js +54 -53
  83. package/dist/tools/tiktok.js.map +1 -1
  84. package/dist/tools/tripadvisor.js +20 -43
  85. package/dist/tools/tripadvisor.js.map +1 -1
  86. package/dist/tools/usage.js +3 -2
  87. package/dist/tools/usage.js.map +1 -1
  88. package/dist/tools/walmart.js +35 -34
  89. package/dist/tools/walmart.js.map +1 -1
  90. package/dist/tools/x.js +44 -43
  91. package/dist/tools/x.js.map +1 -1
  92. package/dist/tools/yelp.js +21 -20
  93. package/dist/tools/yelp.js.map +1 -1
  94. package/dist/tools/youtube.js +77 -76
  95. package/dist/tools/youtube.js.map +1 -1
  96. package/dist/tools/zillow.js +38 -53
  97. package/dist/tools/zillow.js.map +1 -1
  98. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { handleApiError } from "../lib/tool-error.js";
3
+ import { trimResponse } from "../lib/trim-response.js";
3
4
  // No zod `.default()` anywhere in this file, on purpose. The MCP SDK applies a
4
5
  // zod default BEFORE the handler runs, so a defaulted field is posted on every
5
6
  // single call whether the model set it or not — which is exactly how the
@@ -11,102 +12,84 @@ const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
11
12
  // occupancy block. Built per-tool so no two tool schemas share an instance.
12
13
  const stayFields = () => ({
13
14
  checkin: z.string().regex(ISO_DATE, "checkin must be YYYY-MM-DD").optional()
14
- .describe("Check-in date, YYYY-MM-DD. MUST be sent together with checkout — Booking ignores a lone checkin and prices a default range of its own instead."),
15
+ .describe("YYYY-MM-DD. MUST send with checkout."),
15
16
  checkout: z.string().regex(ISO_DATE, "checkout must be YYYY-MM-DD").optional()
16
- .describe("Check-out date, YYYY-MM-DD. Must be after checkin and sent together with it."),
17
+ .describe("YYYY-MM-DD. MUST send with checkin."),
17
18
  adults: z.number().int().min(1).optional()
18
- .describe("Adults in the party. Upstream default is 2."),
19
+ .describe("Default 2."),
19
20
  children_ages: z.array(z.number().int().min(0).max(17)).max(10).optional()
20
- .describe("One AGE (0-17) per child, not a count — Booking prices children by age. Max 10 entries."),
21
+ .describe("One AGE per child, not a count."),
21
22
  rooms: z.number().int().min(1).optional()
22
- .describe("Rooms required. Upstream default is 1."),
23
+ .describe("Default 1."),
23
24
  currency: z.string().regex(/^[A-Za-z]{3}$/, "currency must be a 3-letter ISO 4217 code").optional()
24
- .describe("ISO 4217 display currency, e.g. 'USD'. Defaults to USD; without it Booking prices off the proxy exit and two identical requests can disagree."),
25
+ .describe("e.g. 'USD'. Default USD."),
25
26
  });
26
27
  const hotelField = () => z.string().min(1).max(500)
27
- .describe("A booking.com property URL, or the bare page slug, e.g. 'citizenm-austin-downtown'. Query parameters on a pasted URL are discarded. Prefer the url a search_booking row returns — a bare slug with the wrong country_code is a real, BILLED 404.");
28
+ .describe("Booking.com URL or slug. Prefer URL from search_booking; wrong slug+country is a BILLED 404.");
28
29
  const countryCodeField = () => z.string().regex(/^[A-Za-z]{2}$/, "country_code must be a two-letter country code").optional()
29
- .describe("Two-letter country segment of the property path, e.g. 'us'. Only consulted for a bare slug (a full URL carries its own). Defaults to us — a wrong value is a billed 404.");
30
+ .describe("e.g. 'us'. Only for bare slugs. Wrong value is a billed 404.");
30
31
  export function registerBookingTools(server, getClient) {
31
- server.tool("search_booking", `Search Booking.com for hotels, apartments, hostels, resorts and other stays in a destination, as JSON. Each property carries its name and property url, the live price for the stay you asked for, review score and review count, star rating, location and distance, room type, and deal badges.
32
-
33
- Either destination or dest_id is required. A search with NEITHER returns Booking's homepage — it still costs a credit and returns nothing. dest_type is silently ignored by Booking without dest_id, so it is rejected here rather than billed.
34
-
35
- checkin and checkout must be sent TOGETHER. Send only one and Booking prices a default range of its own, returning real prices for dates you never asked for. currency defaults to USD; without it Booking prices off the proxy exit and two identical requests can disagree.
36
-
37
- Chain the url on a result row into get_booking_hotel or get_booking_reviews — that is always cheaper than guessing a slug plus country_code, which is a real, BILLED 404 when wrong.
38
-
39
- Paginate with page: 25 properties per page. min_review_score is an ENUM of '6', '7', '8' or '9' — Booking silently drops any other threshold. Costs 1 credit per page.`, {
32
+ server.tool("search_booking", `Search Booking.com stays. Requires destination or dest_id. checkin+checkout MUST be sent together. 25/page. 1 credit/page.`, {
40
33
  destination: z.string().min(1).max(200).optional()
41
- .describe("Free-text destination, e.g. 'Austin, Texas'. Required unless dest_id is given."),
34
+ .describe("e.g. 'Austin, Texas'. Required unless dest_id."),
42
35
  dest_id: z.string().regex(/^\d+$/, "dest_id must be numeric").optional()
43
- .describe("Booking's own NUMERIC destination id, e.g. '20126662'. Use it to pin an ambiguous name; a search response returns the dest_id it resolved. Required unless destination is given."),
36
+ .describe("Numeric destination id. Required unless destination."),
44
37
  dest_type: z.enum(["city", "region", "country", "district", "landmark", "airport", "hotel"]).optional()
45
- .describe("What dest_id refers to. Only meaningful WITH dest_id and rejected without it, because Booking ignores it on its own."),
38
+ .describe("Only with dest_id."),
46
39
  page: z.number().int().min(1).optional()
47
- .describe("Results page, 1-based. 25 properties per page, 1 credit per page."),
40
+ .describe("Page, 1-based."),
48
41
  sort_by: z.enum(["popularity", "price_low", "price_high", "stars_high", "stars_low", "stars_and_price", "distance", "review_score"]).optional()
49
- .describe("Result sort order. Upstream default is 'popularity'. 'distance' ranks from the searched destination centre, not from your location."),
42
+ .describe("Sort order."),
50
43
  min_price: z.number().min(0).optional()
51
- .describe("Minimum price PER NIGHT, in the currency field."),
44
+ .describe("Min price/night."),
52
45
  max_price: z.number().min(0).optional()
53
- .describe("Maximum price PER NIGHT, in the currency field. Must not be below min_price."),
46
+ .describe("Max price/night."),
54
47
  stars: z.array(z.number().int().min(1).max(5)).min(1).max(5).optional()
55
- .describe("Star ratings to keep, e.g. [4, 5]. Multiple values are OR'd."),
48
+ .describe("e.g. [4, 5]."),
56
49
  min_review_score: z.enum(["6", "7", "8", "9"]).optional()
57
- .describe("Minimum guest review score. ONLY '6', '7', '8' or '9' — Booking offers exactly these four floors and silently drops any other threshold."),
50
+ .describe("Min review score."),
58
51
  property_type: z.union([
59
52
  z.enum(["apartments", "hostels", "hotels", "motels", "resorts", "bed_and_breakfasts", "villas", "campgrounds", "vacation_homes", "lodges", "homestays"]),
60
53
  z.number().int().min(1),
61
54
  ]).optional()
62
- .describe("Property type name, or a raw numeric Booking accommodation-type id for a type this list does not name."),
55
+ .describe("Type name or numeric id."),
63
56
  free_cancellation: z.boolean().optional()
64
- .describe("Only properties offering free cancellation."),
57
+ .describe("Free cancellation only."),
65
58
  no_prepayment: z.boolean().optional()
66
- .describe("Only properties that take no prepayment."),
59
+ .describe("No prepayment only."),
67
60
  breakfast_included: z.boolean().optional()
68
- .describe("Only rates that include breakfast."),
61
+ .describe("Breakfast included only."),
69
62
  ...stayFields(),
70
63
  }, async (params) => {
71
64
  try {
72
65
  const data = await getClient().post("/api/v1/booking/search", params);
73
- return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
66
+ return trimResponse(data);
74
67
  }
75
68
  catch (err) {
76
69
  return handleApiError(err);
77
70
  }
78
71
  });
79
- server.tool("get_booking_hotel", `Get one Booking.com property in full as JSON: its rooms and rate plans priced for the stay you asked for, facilities, house rules, check-in and check-out windows, cancellation and prepayment policies, images, location, and review scores.
80
-
81
- It takes dates because Booking prices a STAY, not a property. Omit them and you do not get a property without prices — you get prices for a two-night range Booking chose. The response echoes whichever dates were used, so a price is never for an unknown stay. checkin and checkout must be sent together.
82
-
83
- Accepts a booking.com property URL or the bare page slug. country_code is only consulted for a bare slug and defaults to 'us'; a wrong country on a bare slug is a real, BILLED 404, so chaining the url a search_booking row returns is always cheaper.
84
-
85
- Single-property lookup with NO pagination. Costs 1 credit.`, {
72
+ server.tool("get_booking_hotel", `Full Booking.com property: rooms, rates, facilities, policies. Send checkin+checkout together. 1 credit.`, {
86
73
  hotel: hotelField(),
87
74
  country_code: countryCodeField(),
88
75
  ...stayFields(),
89
76
  }, async (params) => {
90
77
  try {
91
78
  const data = await getClient().post("/api/v1/booking/hotel", params);
92
- return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
79
+ return trimResponse(data);
93
80
  }
94
81
  catch (err) {
95
82
  return handleApiError(err);
96
83
  }
97
84
  });
98
- server.tool("get_booking_reviews", `Get Booking.com guest reviews for one property as JSON, with the score breakdown by category (staff, cleanliness, value, location, comfort, facilities) and Booking's own summary of what guests praised and complained about.
99
-
100
- There is NO PAGE PARAMETER — do not try to paginate this and do not invent one. One call returns one response: total_count is the property's WHOLE review history, count is how many reviews this response actually holds.
101
-
102
- Accepts a booking.com property URL or the bare page slug, exactly like get_booking_hotel; country_code is only consulted for a bare slug and a wrong one is a real, BILLED 404. The stay parameters are accepted because Booking serves the review page inside a priced stay context. Costs 1 credit.`, {
85
+ server.tool("get_booking_reviews", `Booking.com guest reviews with score breakdown. No pagination. 1 credit.`, {
103
86
  hotel: hotelField(),
104
87
  country_code: countryCodeField(),
105
88
  ...stayFields(),
106
89
  }, async (params) => {
107
90
  try {
108
91
  const data = await getClient().post("/api/v1/booking/reviews", params);
109
- return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
92
+ return trimResponse(data);
110
93
  }
111
94
  catch (err) {
112
95
  return handleApiError(err);
@@ -1 +1 @@
1
- {"version":3,"file":"booking.js","sourceRoot":"","sources":["../../src/tools/booking.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"booking.js","sourceRoot":"","sources":["../../src/tools/booking.ts"],"names":[],"mappings":"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"}
@@ -1,49 +1,50 @@
1
1
  import { z } from "zod";
2
2
  import { handleApiError } from "../lib/tool-error.js";
3
+ import { trimResponse } from "../lib/trim-response.js";
3
4
  export function registerCapterraTools(server, getClient) {
4
- server.tool("search_capterra_software", `Capterra, the B2B software review site. Search it for business software and get 20 ranked products back as JSON: name, vendor description, star rating, review count, logo and a paid-placement flag. Every row carries the product_id and slug that get_capterra_product and get_capterra_reviews take, so this is the entry point when you only have a product name or a category. THIS SEARCH DOES NOT PAGINATE AND CANNOT RETURN MORE THAN 20 PRODUCTS: Capterra fixes the result set at 20 and serves identical rows for ?page=2, so there is deliberately no page parameter - narrow the query instead of trying to page. A query (or a url that carries one) is REQUIRED: a term-less Capterra search serves a fixed popular-products list that has nothing to do with what you asked for. Costs 2 credits.`, {
5
+ server.tool("search_capterra_software", `Search Capterra for B2B software. Max 20 results, no pagination. query or url required. 2 credits.`, {
5
6
  query: z.string().min(1).max(200).optional()
6
- .describe("Software search term, e.g. 'help desk' or 'notion'. Either this or url is required - without one, Capterra serves an unrelated popular-products list."),
7
+ .describe("Software search term. Either this or url required."),
7
8
  url: z.string().min(1).max(1000).optional()
8
- .describe("Full Capterra search URL to run verbatim (capterra.com, capterra.co.uk and capterra.com.br are accepted). Either this or query is required."),
9
+ .describe("Capterra search URL. Either this or query required."),
9
10
  }, async (params) => {
10
11
  try {
11
12
  const data = await getClient().post("/api/v1/capterra/search", params);
12
- return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
13
+ return trimResponse(data);
13
14
  }
14
15
  catch (err) {
15
16
  return handleApiError(err);
16
17
  }
17
18
  });
18
- server.tool("get_capterra_product", `Capterra, the B2B software review site. Get one software product's full Capterra profile as JSON: overall rating with the per-star histogram and the four scored criteria, likelihood to recommend, review sentiment and topics, the complete pricing table with every plan and its features, every rated feature, every integration, AI-derived pros and cons with the review each was quoted from, FAQs, screenshots, badges and awards, competitor comparisons and alternatives, and the buyer profile broken down by company size, industry and job function. THE 25 MOST RECENT REVIEWS RIDE ALONG AT NO EXTRA COST - only call get_capterra_reviews when you need to page past them. The vendor field IS ALWAYS NULL here: Capterra does not publish it as structured data on the product page (the individual reviews name the vendor instead). product_id MUST BE A STRING - a JSON number is rejected - and it is the number in a /p/186596/Notion/ URL. The slug parameter is cosmetic on this endpoint. No pagination. Pass product_id or url - at least one is required. Costs 2 credits.`, {
19
+ server.tool("get_capterra_product", `Get full Capterra product profile with 25 most recent reviews included. Use get_capterra_reviews only to page past them. product_id (string, not number) or url required. 2 credits.`, {
19
20
  product_id: z.string().min(1).max(50).optional()
20
- .describe("Capterra product id as a STRING - the number in /p/186596/Notion/, so '186596'. A JSON number is rejected. Either this or url is required."),
21
+ .describe("Product id as string, e.g. '186596'. Either this or url required."),
21
22
  slug: z.string().min(1).max(200).optional()
22
- .describe("Product slug. COSMETIC on this endpoint - /p/186596/Zzzjunk/ returns the same profile byte-for-byte. It is load-bearing on get_capterra_reviews."),
23
+ .describe("Product slug. Cosmetic here, load-bearing on get_capterra_reviews."),
23
24
  url: z.string().min(1).max(1000).optional()
24
- .describe("Full Capterra product URL, e.g. 'https://www.capterra.com/p/186596/Notion/'. Either this or product_id is required."),
25
+ .describe("Capterra product URL. Either this or product_id required."),
25
26
  }, async (params) => {
26
27
  try {
27
28
  const data = await getClient().post("/api/v1/capterra/product", params);
28
- return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
29
+ return trimResponse(data);
29
30
  }
30
31
  catch (err) {
31
32
  return handleApiError(err);
32
33
  }
33
34
  });
34
- server.tool("get_capterra_reviews", `Capterra, the B2B software review site. Get one page of written reviews for a software product as JSON: the overall score plus five per-criterion scores, title, pros, cons, advice to others, how long the reviewer used it, the incentivized flag, alternatives they considered and what they switched from, reviewer job title, industry and company size, and the vendor's response. It also carries a richer competitor list than the profile page does, each alternative with its own rating histogram and starting price. USE THIS ONLY TO PAGE PAST THE FIRST 25 REVIEWS - get_capterra_product already returns the 25 most recent at no extra cost. 25 reviews per page, HARD-CAPPED AT PAGE 100 no matter how many reviews the product has; past page 100 Capterra answers with page one. The slug parameter is LOAD-BEARING here, unlike on the product endpoint: it is case-sensitive upstream and a wrong one silently serves PAGE ONE under a billed success, so pass back the slug or reviews_url you got from search_capterra_software or get_capterra_product. Pass product_id or url - at least one is required. Costs 2 credits per page.`, {
35
+ server.tool("get_capterra_reviews", `Page past the 25 reviews in get_capterra_product. 25/page, max page 100. slug is LOAD-BEARING here (case-sensitive; wrong slug silently returns page 1). product_id or url required. 2 credits/page.`, {
35
36
  product_id: z.string().min(1).max(50).optional()
36
- .describe("Capterra product id as a STRING, e.g. '186596'. Either this or url is required."),
37
+ .describe("Product id as string. Either this or url required."),
37
38
  slug: z.string().min(1).max(200).optional()
38
- .describe("Product slug. LOAD-BEARING here: case-sensitive upstream, and a wrong one silently serves page one under a billed success. Pass back the slug from search_capterra_software or get_capterra_product."),
39
+ .describe("Product slug. LOAD-BEARING, case-sensitive. Use slug from search/product."),
39
40
  url: z.string().min(1).max(1000).optional()
40
- .describe("Full Capterra reviews URL. Passing back reviews_url from get_capterra_product is the most reliable way to page. Either this or product_id is required."),
41
+ .describe("Capterra reviews URL. Prefer reviews_url from get_capterra_product."),
41
42
  page: z.number().int().min(1).max(100).optional()
42
- .describe("Page number, 1-100. 25 reviews per page. 100 is a hard cap whatever the review count says - past it Capterra serves page one again."),
43
+ .describe("Page 1-100. 25/page. Past 100 returns page 1."),
43
44
  }, async (params) => {
44
45
  try {
45
46
  const data = await getClient().post("/api/v1/capterra/reviews", params);
46
- return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
47
+ return trimResponse(data);
47
48
  }
48
49
  catch (err) {
49
50
  return handleApiError(err);
@@ -1 +1 @@
1
- {"version":3,"file":"capterra.js","sourceRoot":"","sources":["../../src/tools/capterra.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capterra.js","sourceRoot":"","sources":["../../src/tools/capterra.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { handleApiError } from "../lib/tool-error.js";
3
+ import { trimResponse } from "../lib/trim-response.js";
3
4
  // Companies House - the official UK company register. Four tools, 1 credit
4
5
  // each, flat.
5
6
  //
@@ -21,36 +22,36 @@ import { handleApiError } from "../lib/tool-error.js";
21
22
  // every call. The backend applies its own defaults when a field is absent;
22
23
  // they are documented in the .describe() text instead.
23
24
  const companyNumber = z.string().min(1).max(20)
24
- .describe("UK company number, from search_companies_house. Zero-padded and upper-cased for you, so '445790', '00445790' and 'sc090312' all resolve. Registry prefixes are supported: SC (Scotland), NI (Northern Ireland), OC/SO/NC (LLPs), FC (overseas), BR (UK establishment), CE (charitable incorporated organisation).");
25
+ .describe("UK company number, e.g. '00445790'. Auto zero-padded/upper-cased.");
25
26
  export function registerCompaniesHouseTools(server, getClient) {
26
27
  const call = (path) => async (params) => {
27
28
  try {
28
29
  const data = await getClient().post(path, params);
29
- return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
30
+ return trimResponse(data);
30
31
  }
31
32
  catch (err) {
32
33
  return handleApiError(err);
33
34
  }
34
35
  };
35
- server.tool("search_companies_house", `START HERE for Companies House, the official UK company register. Search it by company name or number and get back, as JSON, the company_number that every other Companies House tool is keyed by, plus company name, status (active, dissolved, liquidation), incorporation or dissolution date, registered office address and any matched former names. Search matches CURRENT AND FORMER names, so a company that rebranded is still findable under its old one. Paginated with page at 20 results per page and CAPPED AT PAGE 50: the register serves only a 1000-result window per term however many matches it claims (it will report 10,000 for a broad term and then answer page 51 with an HTTP 416), so narrow the query rather than paging further. UK register only - it holds nothing about US or other non-UK companies. Costs 1 credit.`, {
36
+ server.tool("search_companies_house", `Search UK Companies House by name or number. Returns company_number needed by other Companies House tools. UK only, max page 50. 1 credit.`, {
36
37
  query: z.string().min(1).max(200)
37
- .describe("Company name or number to search for, e.g. 'tesco'. Must not be blank. Matches current AND former names."),
38
+ .describe("Company name or number, e.g. 'tesco'."),
38
39
  page: z.number().int().min(1).max(50)
39
40
  .optional()
40
- .describe("Results page, 1-based, 20 per page. Backend default is 1. Hard cap of 50 - the register only serves the first 1000 matches for a term."),
41
+ .describe("Page, 1-based, 20/page. Max 50."),
41
42
  }, call("/api/v1/companieshouse/search"));
42
- server.tool("get_companies_house_company", `Get a UK company's full entry on the Companies House register as JSON: status, company type, incorporation and dissolution dates, registered office address, SIC industry codes, previous names, accounts and confirmation-statement due dates with their overdue flags, and whether it has charges, insolvency history, officers or UK establishments. Overseas companies (FC) also return home registry, legal form and governing law; UK establishments (BR) return the parent company; charitable incorporated organisations (CE) return the charity number. Keyed by company_number - call search_companies_house first if you only have a name. Not paginated. Costs 1 credit.`, {
43
+ server.tool("get_companies_house_company", `Get a UK company's full Companies House record: status, type, dates, address, SIC codes, previous names, accounts. 1 credit.`, {
43
44
  company_number: companyNumber,
44
45
  }, call("/api/v1/companieshouse/company"));
45
- server.tool("get_companies_house_officers", `List a UK company's officers, current and resigned, from the Companies House register as JSON: name, officer role (director, secretary, LLP member), appointment and resignation dates, correspondence address, nationality, country of residence, month-and-year date of birth, and identity-verification status. There is NO server-side active/resigned filter - the register's own is client-side, so filter on each officer's \`status\` in the response. officers_count is every appointment ever made and resignations_count how many ended, so active officers = the difference. Paginated with page at 35 per page with NO upper page bound: past the last page the register returns an ordinary 200 with an empty list, identical to a company that has no officers, so stop when a page comes back empty. Keyed by company_number from search_companies_house. Costs 1 credit.`, {
46
+ server.tool("get_companies_house_officers", `List a UK company's officers (current and resigned). No server-side active filter; check status in response. 35/page, stop on empty page. 1 credit.`, {
46
47
  company_number: companyNumber,
47
48
  page: z.number().int().min(1).optional()
48
- .describe("Results page, 1-based, 35 officers per page. Backend default is 1. No upper bound - a page past the end is a 200 with an empty list, not an error."),
49
+ .describe("Page, 1-based, 35/page. Empty page = no more."),
49
50
  }, call("/api/v1/companieshouse/officers"));
50
- server.tool("get_companies_house_filing_history", `List a UK company's filings from the Companies House register as JSON, most recent first: filing date, filing type code (AA annual accounts, CS01 confirmation statement, SH03 share buyback), description, register annotations and child documents, and a link to the filed PDF with its page count. A filing the register has not finished processing carries a processing_note instead of a document link. Paginated with page and NO upper page bound: past the last page it is an ordinary 200 with an empty list, so stop when a page comes back empty. Keyed by company_number from search_companies_house. Costs 1 credit.`, {
51
+ server.tool("get_companies_house_filing_history", `List a UK company's filing history (most recent first) with PDF links. Stop on empty page. 1 credit.`, {
51
52
  company_number: companyNumber,
52
53
  page: z.number().int().min(1).optional()
53
- .describe("Results page, 1-based. Backend default is 1. No upper bound - a page past the end is a 200 with an empty list, not an error."),
54
+ .describe("Page, 1-based. Empty page = no more."),
54
55
  }, call("/api/v1/companieshouse/filing-history"));
55
56
  }
56
57
  //# sourceMappingURL=companieshouse.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"companieshouse.js","sourceRoot":"","sources":["../../src/tools/companieshouse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,2EAA2E;AAC3E,cAAc;AACd,EAAE;AACF,4EAA4E;AAC5E,sEAAsE;AACtE,4EAA4E;AAC5E,4EAA4E;AAC5E,iBAAiB;AACjB,EAAE;AACF,8EAA8E;AAC9E,gFAAgF;AAChF,yEAAyE;AACzE,0EAA0E;AAC1E,6EAA6E;AAC7E,+EAA+E;AAC/E,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,2EAA2E;AAC3E,uDAAuD;AAEvD,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;KAC5C,QAAQ,CAAC,mTAAmT,CAAC,CAAC;AAEjU,MAAM,UAAU,2BAA2B,CAAC,MAAiB,EAAE,SAA6B;IAC1F,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,IAAI,EAAE,MAAM,CAAC,CAAC;YAClD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACvF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,wzBAAwzB,EACxzB;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;aAC9B,QAAQ,CAAC,0GAA0G,CAAC;QACvH,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;aAClC,QAAQ,EAAE;aACV,QAAQ,CAAC,wIAAwI,CAAC;KACtJ,EACD,IAAI,CAAC,+BAA+B,CAAC,CACtC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,6BAA6B,EAC7B,spBAAspB,EACtpB;QACE,cAAc,EAAE,aAAa;KAC9B,EACD,IAAI,CAAC,gCAAgC,CAAC,CACvC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,8BAA8B,EAC9B,21BAA21B,EAC31B;QACE,cAAc,EAAE,aAAa;QAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;aACrC,QAAQ,CAAC,oJAAoJ,CAAC;KAClK,EACD,IAAI,CAAC,iCAAiC,CAAC,CACxC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,oCAAoC,EACpC,qmBAAqmB,EACrmB;QACE,cAAc,EAAE,aAAa;QAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;aACrC,QAAQ,CAAC,8HAA8H,CAAC;KAC5I,EACD,IAAI,CAAC,uCAAuC,CAAC,CAC9C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"companieshouse.js","sourceRoot":"","sources":["../../src/tools/companieshouse.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,2EAA2E;AAC3E,cAAc;AACd,EAAE;AACF,4EAA4E;AAC5E,sEAAsE;AACtE,4EAA4E;AAC5E,4EAA4E;AAC5E,iBAAiB;AACjB,EAAE;AACF,8EAA8E;AAC9E,gFAAgF;AAChF,yEAAyE;AACzE,0EAA0E;AAC1E,6EAA6E;AAC7E,+EAA+E;AAC/E,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,2EAA2E;AAC3E,uDAAuD;AAEvD,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;KAC5C,QAAQ,CAAC,mEAAmE,CAAC,CAAC;AAEjF,MAAM,UAAU,2BAA2B,CAAC,MAAiB,EAAE,SAA6B;IAC1F,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,IAAI,EAAE,MAAM,CAAC,CAAC;YAClD,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,wBAAwB,EACxB,4IAA4I,EAC5I;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;aAC9B,QAAQ,CAAC,uCAAuC,CAAC;QACpD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;aAClC,QAAQ,EAAE;aACV,QAAQ,CAAC,iCAAiC,CAAC;KAC/C,EACD,IAAI,CAAC,+BAA+B,CAAC,CACtC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,6BAA6B,EAC7B,8HAA8H,EAC9H;QACE,cAAc,EAAE,aAAa;KAC9B,EACD,IAAI,CAAC,gCAAgC,CAAC,CACvC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,8BAA8B,EAC9B,qJAAqJ,EACrJ;QACE,cAAc,EAAE,aAAa;QAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;aACrC,QAAQ,CAAC,+CAA+C,CAAC;KAC7D,EACD,IAAI,CAAC,iCAAiC,CAAC,CACxC,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,oCAAoC,EACpC,sGAAsG,EACtG;QACE,cAAc,EAAE,aAAa;QAC7B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;aACrC,QAAQ,CAAC,sCAAsC,CAAC;KACpD,EACD,IAAI,CAAC,uCAAuC,CAAC,CAC9C,CAAC;AACJ,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { handleApiError } from "../lib/tool-error.js";
3
+ import { trimResponse } from "../lib/trim-response.js";
3
4
  // No zod `.default()` anywhere in this file, on purpose. The MCP SDK applies a
4
5
  // zod default BEFORE the handler runs, so a defaulted field is posted on every
5
6
  // single call whether the model set it or not — which is exactly how the
@@ -7,69 +8,59 @@ import { handleApiError } from "../lib/tool-error.js";
7
8
  // Upstream defaults are documented in the .describe() text instead and left for
8
9
  // the backend to apply.
9
10
  export function registerEbayTools(server, getClient) {
10
- server.tool("search_ebay", `Search live or SOLD eBay listings and return them as JSON. Each result carries the item id and URL, title, price and currency, condition, buying format, bid count and time left for auctions, shipping cost and free-shipping flag, seller username with feedback score, image and position, alongside count and total_results.
11
-
12
- Set sold=true to search COMPLETED listings that actually sold. That is the price-research view and the reason to reach for eBay rather than a retail catalogue: it shows what buyers really paid, not what sellers are asking. On the sold view eBay publishes no headline count, so total_results is NULL — count still tells you how many rows came back.
13
-
14
- Either query or seller is required. Passing seller ALONE with no keyword pages that seller's entire catalogue, and this is the only way to enumerate a seller's inventory — get_ebay_seller is a profile card and cannot list items.
15
-
16
- Paginate with page. per_page accepts ONLY 60, 120 or 240; eBay silently falls back to 60 for any other value rather than erroring. category_id must be numeric — an unrecognised id returns the UNFILTERED result set under a 200, so verify the filter took effect. condition 'refurbished' is eBay's parent condition, not one of its three graded tiers. Costs 1 credit per page.`, {
11
+ server.tool("search_ebay", `Search eBay live or sold listings. sold=true for completed-sale price research. Either query or seller required; seller alone pages their catalogue. per_page only 60/120/240. 1 credit/page.`, {
17
12
  query: z.string().min(1).max(500).optional()
18
- .describe("Keyword search, e.g. 'nikon d750 body'. Either this or seller is required; omit it and pass seller alone to page a seller's whole catalogue."),
13
+ .describe("Search keywords. Either this or seller required."),
19
14
  seller: z.string().min(1).max(64).optional()
20
- .describe("Scope results to one eBay seller username. Usable with NO query to page that seller's entire inventory. Either this or query is required."),
15
+ .describe("Seller username. Alone (no query) pages their catalogue."),
21
16
  page: z.number().int().min(1).optional()
22
- .describe("Results page, 1-based. One page per call, 1 credit each."),
17
+ .describe("Page, 1-based."),
23
18
  sort_by: z.enum(["best_match", "ending_soonest", "newly_listed", "price_low", "price_high"]).optional()
24
- .describe("Sort order. Upstream default is 'best_match'. 'Distance: nearest first' is deliberately unavailable — it would rank against our proxy exit, not your location."),
19
+ .describe("Sort order."),
25
20
  min_price: z.number().min(0).optional()
26
- .describe("Minimum price filter, in the listing currency."),
21
+ .describe("Min price."),
27
22
  max_price: z.number().min(0).optional()
28
- .describe("Maximum price filter, in the listing currency."),
23
+ .describe("Max price."),
29
24
  condition: z.enum(["new", "open_box", "refurbished", "used", "for_parts"]).optional()
30
- .describe("Item condition filter. 'refurbished' is eBay's PARENT condition and covers all three graded refurbished tiers; it does not select one of them."),
25
+ .describe("Condition filter."),
31
26
  buying_format: z.enum(["auction", "buy_it_now", "best_offer"]).optional()
32
- .describe("Listing format filter: timed auction, fixed price, or accepts-best-offer."),
27
+ .describe("Listing format."),
33
28
  free_shipping: z.boolean().optional()
34
- .describe("Restrict to listings with free shipping."),
29
+ .describe("Free shipping only."),
35
30
  sold: z.boolean().optional()
36
- .describe("Search COMPLETED listings that sold, instead of live inventory — the price-research view. On this view total_results is NULL because eBay publishes no headline count for it."),
31
+ .describe("Completed sold listings for price research."),
37
32
  category_id: z.string().optional()
38
- .describe("eBay numeric category id (the _sacat value in a browse URL). MUST be numeric — an unrecognised id returns the UNFILTERED set under a 200 rather than an error."),
33
+ .describe("Numeric eBay category id."),
39
34
  per_page: z.union([z.literal(60), z.literal(120), z.literal(240)]).optional()
40
- .describe("Results per page. ONLY 60, 120 or 240 are accepted; eBay silently downgrades anything else to 60. Upstream default is 60."),
35
+ .describe("Results per page. Only 60, 120, 240."),
41
36
  }, async (params) => {
42
37
  try {
43
38
  const data = await getClient().post("/api/v1/ebay/search", params);
44
- return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
39
+ return trimResponse(data);
45
40
  }
46
41
  catch (err) {
47
42
  return handleApiError(err);
48
43
  }
49
44
  });
50
- server.tool("get_ebay_product", `Get one eBay listing in full as JSON: item id and URL, title, price and currency, condition, item specifics (the seller's own spec table), every image, shipping and handling options, the return policy, auction state (bid count, time left, buy-it-now availability, quantity sold and available), and the seller with feedback score and positive-feedback percentage.
51
-
52
- Accepts an eBay item number or a full ebay.com/itm/... URL — tracking query params are discarded for you. This is a single-listing lookup with no pagination. Costs 1 credit.`, {
45
+ server.tool("get_ebay_product", `Get full eBay listing details: specs, images, shipping, auction state, seller info. 1 credit.`, {
53
46
  item_id: z.string().min(1)
54
- .describe("eBay item number, e.g. '335678901234', or a full ebay.com/itm/... URL. Tracking params are stripped."),
47
+ .describe("Item number or ebay.com/itm/ URL."),
55
48
  }, async (params) => {
56
49
  try {
57
50
  const data = await getClient().post("/api/v1/ebay/product", params);
58
- return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
51
+ return trimResponse(data);
59
52
  }
60
53
  catch (err) {
61
54
  return handleApiError(err);
62
55
  }
63
56
  });
64
- server.tool("get_ebay_seller", `Get an eBay seller's profile card as JSON: store name and username, feedback score, positive-feedback percentage, items sold, follower count, location, member-since date and the categories they sell in.
65
-
66
- PROFILE ONLY — this endpoint CANNOT enumerate a catalogue and returns no listings. To read what a seller currently has for sale, call search_ebay with seller set and no query; that path is paginated. Accepts the username exactly as it appears in ebay.com/usr/<name>. No pagination. Costs 1 credit.`, {
57
+ server.tool("get_ebay_seller", `Get eBay seller profile. No listings; use search_ebay with seller param for inventory. 1 credit.`, {
67
58
  seller: z.string().min(1).max(64)
68
- .describe("eBay seller username as it appears in ebay.com/usr/<name>, e.g. 'musicmagpie'."),
59
+ .describe("Seller username."),
69
60
  }, async (params) => {
70
61
  try {
71
62
  const data = await getClient().post("/api/v1/ebay/seller", params);
72
- return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
63
+ return trimResponse(data);
73
64
  }
74
65
  catch (err) {
75
66
  return handleApiError(err);
@@ -1 +1 @@
1
- {"version":3,"file":"ebay.js","sourceRoot":"","sources":["../../src/tools/ebay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,+EAA+E;AAC/E,+EAA+E;AAC/E,yEAAyE;AACzE,2EAA2E;AAC3E,gFAAgF;AAChF,wBAAwB;AAExB,MAAM,UAAU,iBAAiB,CAAC,MAAiB,EAAE,SAA6B;IAChF,MAAM,CAAC,IAAI,CACT,aAAa,EACb;;;;;;qXAMiX,EACjX;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;aACzC,QAAQ,CAAC,8IAA8I,CAAC;QAC3J,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;aACzC,QAAQ,CAAC,2IAA2I,CAAC;QACxJ,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;aACrC,QAAQ,CAAC,0DAA0D,CAAC;QACvE,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,EAAE;aACpG,QAAQ,CAAC,gKAAgK,CAAC;QAC7K,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;aACpC,QAAQ,CAAC,gDAAgD,CAAC;QAC7D,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;aACpC,QAAQ,CAAC,gDAAgD,CAAC;QAC7D,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,EAAE;aAClF,QAAQ,CAAC,gJAAgJ,CAAC;QAC7J,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,EAAE;aACtE,QAAQ,CAAC,2EAA2E,CAAC;QACxF,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;aAClC,QAAQ,CAAC,0CAA0C,CAAC;QACvD,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;aACzB,QAAQ,CAAC,+KAA+K,CAAC;QAC5L,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;aAC/B,QAAQ,CAAC,gKAAgK,CAAC;QAC7K,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;aAC1E,QAAQ,CAAC,2HAA2H,CAAC;KACzI,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;YACnE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAC9E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB;;8KAE0K,EAC1K;QACE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;aACvB,QAAQ,CAAC,sGAAsG,CAAC;KACpH,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,EAAE,CAAC,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;YACpE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAC9E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB;;0SAEsS,EACtS;QACE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;aAC9B,QAAQ,CAAC,gFAAgF,CAAC;KAC9F,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,EAAE,CAAC,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;YACnE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAC9E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"ebay.js","sourceRoot":"","sources":["../../src/tools/ebay.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,18 @@
1
1
  import { z } from "zod";
2
2
  import { handleApiError } from "../lib/tool-error.js";
3
+ import { trimResponse } from "../lib/trim-response.js";
3
4
  export function registerExtractTool(server, getClient) {
4
- server.tool("extract_url", `Read any web page. Returns the page as clean Markdown, plain text, or raw HTML. This is the general read-a-page primitive: point it at any http(s) URL - an article, a docs page, a product page, a changelog, a competitor's pricing page - and get the body back as text you can reason over. Returns { url, format, mode, content, content_length }. Formats: 'markdown' (readability extraction, the default and the best choice for reading), 'text' (that Markdown flattened to plain prose), 'html' (the raw unprocessed page). COST IS TIER-PRICED BY THE mode PARAMETER, NOT FLAT: mode='normal' (plain fetch) costs 1 credit, mode='advanced' (full JavaScript rendering, for React/Vue pages that are empty without it) costs 1 credit, mode='ultra' (residential proxy, for hard bot walls and heavy protection) costs 2 credits. Start at 'normal' and escalate only when the content comes back empty or blocked. Billing happens ONLY on a successful extraction - a dead link, a bot wall or a timeout costs nothing. http(s) URLs only; a bare host like 'example.com' is upgraded to https, and loopback, private, link-local and cloud-metadata hosts are rejected with a 400. Returns the whole page in one call - there is no pagination.`, {
5
+ server.tool("extract_url", `Read any web page as Markdown, text, or HTML. Tier-priced: normal=1cr, advanced(JS render)=1cr, ultra(residential proxy)=2cr. Start normal, escalate on empty/blocked. Only billed on success.`, {
5
6
  url: z.string().min(1).max(2048)
6
- .describe("The page to read. http(s) only; a bare host such as 'example.com' is upgraded to https. Internal, loopback and private-network hosts are rejected with a 400."),
7
+ .describe("http(s) URL. Bare hosts upgraded to https. Private/loopback rejected."),
7
8
  format: z.enum(["html", "markdown", "text"]).optional()
8
- .describe("Output format. 'markdown' = readability extraction of the main content (default, best for reading). 'text' = that Markdown flattened to plain prose. 'html' = the raw unprocessed page."),
9
+ .describe("'markdown' (default), 'text', or 'html'."),
9
10
  mode: z.enum(["normal", "advanced", "ultra"]).optional()
10
- .describe("THE PRICE-BEARING PARAMETER. 'normal' = plain fetch, 1 credit (default). 'advanced' = full JavaScript rendering for pages that are empty without it, 1 credit. 'ultra' = residential proxy for hard bot walls, 2 credits. Escalate only when a cheaper mode returns empty or blocked content."),
11
+ .describe("PRICE-BEARING. 'normal'=1cr (default), 'advanced'=JS render 1cr, 'ultra'=residential 2cr."),
11
12
  }, async (params) => {
12
13
  try {
13
14
  const data = await getClient().post("/api/v1/extract", params);
14
- return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
15
+ return trimResponse(data);
15
16
  }
16
17
  catch (err) {
17
18
  return handleApiError(err);
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/tools/extract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,SAA6B;IAClF,MAAM,CAAC,IAAI,CACT,aAAa,EACb,gsCAAgsC,EAChsC;QACE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;aAC7B,QAAQ,CAAC,+JAA+J,CAAC;QAC5K,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;aACpD,QAAQ,CAAC,yLAAyL,CAAC;QACtM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;aACrD,QAAQ,CAAC,+RAA+R,CAAC;KAC7S,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;YAC/D,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QAC9E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/tools/extract.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,MAAM,UAAU,mBAAmB,CAAC,MAAiB,EAAE,SAA6B;IAClF,MAAM,CAAC,IAAI,CACT,aAAa,EACb,gMAAgM,EAChM;QACE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;aAC7B,QAAQ,CAAC,uEAAuE,CAAC;QACpF,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE;aACpD,QAAQ,CAAC,0CAA0C,CAAC;QACvD,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;aACrD,QAAQ,CAAC,2FAA2F,CAAC;KACzG,EACD,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,SAAS,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;YAC/D,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}