scrapeunblocker-mcp 0.3.0 → 0.3.2

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 (2) hide show
  1. package/dist/index.js +17 -197
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import { APIError, ScrapeUnblockerClient } from "scrapeunblocker";
10
10
  import { z } from "zod";
11
11
 
12
12
  // src/plugin-catalog.ts
13
- var CATEGORIES = ["Travel", "Google", "Search engines", "E-commerce", "Classifieds & Resale", "Groceries", "Real estate", "Vehicles", "Jobs", "Reviews & Companies", "Local & Maps", "Apps", "Video, Music & Communities", "SEO & Ads"];
13
+ var CATEGORIES = ["Travel", "Google", "Search engines", "E-commerce", "Classifieds & Resale", "Groceries", "Real estate", "Vehicles", "Jobs", "Reviews & Companies", "Local & Maps", "Apps", "Video & Music", "SEO & Ads"];
14
14
  var PLUGINS = [
15
15
  {
16
16
  "name": "skyscanner_flights",
@@ -2140,7 +2140,7 @@ var PLUGINS = [
2140
2140
  {
2141
2141
  "name": "q",
2142
2142
  "type": "string",
2143
- "required": true,
2143
+ "required": false,
2144
2144
  "description": "Search keyword, e.g. 'led face mask' (or a TikTok Shop keyword URL like 'https://www.tiktok.com/shop/product/led-face-mask'). Either this or `category`."
2145
2145
  },
2146
2146
  {
@@ -2920,6 +2920,12 @@ var PLUGINS = [
2920
2920
  },
2921
2921
  "description": "ALDI Australia (aldi.com.au) products as JSON. `mode=search&query=`, `mode=category&category=` and `mode=specials` return `products`: `id` (SKU), `name`, `brand`, `size`, `url`, `price`, `priceText`, `wasPrice`, `onSale`, `unitPrice` (`price`, `per`, `text`), `bottleDeposit`, `specialBuy` (on-sale date and label), `badges`, `available`, `soldOnline`, `ageRestricted`, `image`, `categories` and `categoryKeys`, plus `totalResults`, `totalPages` and `nextPage`. `mode=specials` lists one Special Buys drop (the current one, or the date / link in `category`; `theme` narrows it) and returns `promotions`, every drop ALDI has announced with its themes. `mode=product&product=` returns `product` with those fields and `description`, `ingredients`, `allergens`, `claims`, `storage`, `usage`, `countryOfOrigin` and `images`. Prices are ALDI's in-store prices in AUD (ALDI Australia does not sell groceries online). Listings collect up to `max_results` from `page` on, billed one unit per page.",
2922
2922
  "params": [
2923
+ {
2924
+ "name": "category",
2925
+ "type": "string",
2926
+ "required": false,
2927
+ "description": "mode=category: a category link (https://www.aldi.com.au/products/dairy-eggs-fridge/milk/k/1111111160) or its key ('1111111160'; '1588161425841179' = Lower Prices). mode=specials: the Special Buys drop - its date ('2026-10-14') or link (https://www.aldi.com.au/special-buys/2026-10-14); blank = the current drop."
2928
+ },
2923
2929
  {
2924
2930
  "name": "theme",
2925
2931
  "type": "string",
@@ -4523,13 +4529,6 @@ var PLUGINS = [
4523
4529
  "required": true,
4524
4530
  "description": "Product name or keyword to search for (mode=search), e.g. 'crm'."
4525
4531
  },
4526
- {
4527
- "name": "page",
4528
- "type": "integer",
4529
- "required": false,
4530
- "description": "1-based review page to start from: 25 reviews per page, at most 100 (Capterra's limit per product). Use the `nextPage` of a previous response to continue.",
4531
- "default": 1
4532
- },
4533
4532
  {
4534
4533
  "name": "max_results",
4535
4534
  "type": "integer",
@@ -5068,12 +5067,6 @@ var PLUGINS = [
5068
5067
  "required": false,
5069
5068
  "description": "App Store country (ISO-2), e.g. 'us', 'gb', 'de'. Prices, ratings and reviews are per country. Default: the country in an app URL, else 'us'."
5070
5069
  },
5071
- {
5072
- "name": "lang",
5073
- "type": "string",
5074
- "required": false,
5075
- "description": "Listing language for mode=app / mode=search, e.g. 'fr' or 'fr-CA' (for countries whose store has several languages). Default: the store's own."
5076
- },
5077
5070
  {
5078
5071
  "name": "max_results",
5079
5072
  "type": "integer",
@@ -5106,7 +5099,7 @@ var PLUGINS = [
5106
5099
  {
5107
5100
  "name": "youtube_channel",
5108
5101
  "title": "Scrape a YouTube channel's videos",
5109
- "category": "Video, Music & Communities",
5102
+ "category": "Video & Music",
5110
5103
  "path": "/content/youtube-channel",
5111
5104
  "fixed": {},
5112
5105
  "description": "Returns a YouTube channel's recent videos as JSON: `videoId`, `title`, `views`, `published`, `thumbnail` and a watch `url`, plus a `channel` summary (name, id). Pass a handle (`@mkbhd`), a channel id (`UC...`) or a channel URL. Returns the channel's first page of videos (about 30).",
@@ -5142,7 +5135,7 @@ var PLUGINS = [
5142
5135
  {
5143
5136
  "name": "youtube_search",
5144
5137
  "title": "Search YouTube",
5145
- "category": "Video, Music & Communities",
5138
+ "category": "Video & Music",
5146
5139
  "path": "/content/youtube-search",
5147
5140
  "fixed": {},
5148
5141
  "description": "Searches YouTube for `query` and returns the results as JSON. For each video: `videoId`, `title`, `url`, `channel` (name/id/url), `publishedText`, `viewCount` (+ text), `lengthSeconds` (+ text), `thumbnails`, `descriptionSnippet`, `badges`, `verified` and `isLive`. Filter with `type` (video / channel / playlist / all) and `sort` (relevance / date / views / rating), and collect up to `max_results` across pages.",
@@ -5182,46 +5175,10 @@ var PLUGINS = [
5182
5175
  }
5183
5176
  ]
5184
5177
  },
5185
- {
5186
- "name": "youtube_comments",
5187
- "title": "Scrape a YouTube video's comments",
5188
- "category": "Video, Music & Communities",
5189
- "path": "/content/youtube-comments",
5190
- "fixed": {},
5191
- "description": "Returns a YouTube video's comments as JSON. For each comment: `commentId`, `author`, `authorChannelId`, `authorThumbnail`, `text`, `likeCount`, `publishedTimeText`, `replyCount`, and the `isPinned`, `isHearted`, `isAuthorVerified` and `isUploader` flags, plus the video `title` and total `commentCount`. Sort by `top` or `newest` and collect up to `max_results` across pages.",
5192
- "params": [
5193
- {
5194
- "name": "video",
5195
- "type": "string",
5196
- "required": true,
5197
- "description": "Video id (dQw4w9WgXcQ) or any YouTube video URL."
5198
- },
5199
- {
5200
- "name": "sort",
5201
- "type": "string",
5202
- "required": false,
5203
- "description": "Comment order: top, newest.",
5204
- "default": "top"
5205
- },
5206
- {
5207
- "name": "max_results",
5208
- "type": "integer",
5209
- "required": false,
5210
- "description": "How many comments to collect across pages (~20 per page).",
5211
- "default": 20
5212
- },
5213
- {
5214
- "name": "proxy_country",
5215
- "type": "string",
5216
- "required": false,
5217
- "description": "Proxy country the request is sent from (ISO-2, e.g. 'US', 'DE') for the watch page. Defaults to US."
5218
- }
5219
- ]
5220
- },
5221
5178
  {
5222
5179
  "name": "youtube_transcript",
5223
5180
  "title": "Get a YouTube video transcript",
5224
- "category": "Video, Music & Communities",
5181
+ "category": "Video & Music",
5225
5182
  "path": "/content/youtube-transcript",
5226
5183
  "fixed": {},
5227
5184
  "description": "Returns a YouTube video's captions as JSON: timestamped `segments` (`start`, `dur`, `text`) and a joined `text`, plus `availableLanguages`, the picked `language`, `isAutoGenerated`, and the video's `title`, `author` and `lengthSeconds`. Pass a video id or any YouTube video URL; choose a caption language with `lang`. Ideal for LLM/RAG pipelines, subtitles and content analysis.",
@@ -5256,7 +5213,7 @@ var PLUGINS = [
5256
5213
  {
5257
5214
  "name": "spotify_search",
5258
5215
  "title": "Scrape Spotify artists, albums, tracks, playlists and search (type=search)",
5259
- "category": "Video, Music & Communities",
5216
+ "category": "Video & Music",
5260
5217
  "path": "/music/spotify",
5261
5218
  "fixed": {
5262
5219
  "type": "search"
@@ -5300,7 +5257,7 @@ var PLUGINS = [
5300
5257
  {
5301
5258
  "name": "spotify_artist",
5302
5259
  "title": "Scrape Spotify artists, albums, tracks, playlists and search (type=artist)",
5303
- "category": "Video, Music & Communities",
5260
+ "category": "Video & Music",
5304
5261
  "path": "/music/spotify",
5305
5262
  "fixed": {
5306
5263
  "type": "artist"
@@ -5331,7 +5288,7 @@ var PLUGINS = [
5331
5288
  {
5332
5289
  "name": "spotify_album",
5333
5290
  "title": "Scrape Spotify artists, albums, tracks, playlists and search (type=album)",
5334
- "category": "Video, Music & Communities",
5291
+ "category": "Video & Music",
5335
5292
  "path": "/music/spotify",
5336
5293
  "fixed": {
5337
5294
  "type": "album"
@@ -5368,7 +5325,7 @@ var PLUGINS = [
5368
5325
  {
5369
5326
  "name": "spotify_track",
5370
5327
  "title": "Scrape Spotify artists, albums, tracks, playlists and search (type=track)",
5371
- "category": "Video, Music & Communities",
5328
+ "category": "Video & Music",
5372
5329
  "path": "/music/spotify",
5373
5330
  "fixed": {
5374
5331
  "type": "track"
@@ -5392,7 +5349,7 @@ var PLUGINS = [
5392
5349
  {
5393
5350
  "name": "spotify_playlist",
5394
5351
  "title": "Scrape Spotify artists, albums, tracks, playlists and search (type=playlist)",
5395
- "category": "Video, Music & Communities",
5352
+ "category": "Video & Music",
5396
5353
  "path": "/music/spotify",
5397
5354
  "fixed": {
5398
5355
  "type": "playlist"
@@ -5426,143 +5383,6 @@ var PLUGINS = [
5426
5383
  }
5427
5384
  ]
5428
5385
  },
5429
- {
5430
- "name": "telegram_channel",
5431
- "title": "Scrape a public Telegram channel: info and posts",
5432
- "category": "Video, Music & Communities",
5433
- "path": "/social/telegram-channel",
5434
- "fixed": {},
5435
- "description": "Reads a public Telegram channel's web preview. Returns `channel` (`username`, `title`, `description`, `avatar`, `verified`, `subscribers` and the other `counters`) and `posts`, newest first: `id`, `url`, `date` (ISO-8601 UTC), `text` (plain), `textHtml`, `views`, `author` (signature), `edited`, `forwardedFrom`, `replyTo`, `media` (photo / video / animation / round_video / voice / audio / document / sticker, with CDN `url`, `thumbnail`, `duration`), `poll`, `linkPreview`, `reactions` (a custom-emoji reaction has its `customEmojiId`, plus the standard `emoji` and `image` Telegram falls back to when the page shows that emoji anywhere), `buttons`, `links`, `hashtags` (the tags Telegram links; a bare '#7' is text) and `mentions`. One page (about 20 posts) by default; `max_posts` (up to 500) pages back through history; `before`, `after` and `since` bound the range, `q` searches inside the channel and `post_id` returns one post. `nextBefore` continues a capped answer. Only channels have a public preview: users, bots, groups and private channels answer 404. Billed one request per page fetched (`pagesFetched`).",
5436
- "params": [
5437
- {
5438
- "name": "channel",
5439
- "type": "string",
5440
- "required": true,
5441
- "description": "Public channel: username ('durov'), '@durov', or a t.me link ('https://t.me/durov', 'https://t.me/s/durov'). A post link ('https://t.me/durov/400') returns that one post."
5442
- },
5443
- {
5444
- "name": "max_posts",
5445
- "type": "integer",
5446
- "required": false,
5447
- "description": "Posts to collect, newest first (1-500), paging back through the channel's history; each page fetched is billed as one request. Omit it for one page, billed once: the newest posts (a page has 20 message slots and an album fills one per photo, so it can hold fewer posts)."
5448
- },
5449
- {
5450
- "name": "before",
5451
- "type": "integer",
5452
- "required": false,
5453
- "description": "Only posts with an id below this one. Pass `nextBefore` of a previous response to continue where it stopped."
5454
- },
5455
- {
5456
- "name": "after",
5457
- "type": "integer",
5458
- "required": false,
5459
- "description": "Stop at this post id: only posts with a higher id are returned."
5460
- },
5461
- {
5462
- "name": "since",
5463
- "type": "string",
5464
- "required": false,
5465
- "description": "Stop at this date: only posts published on or after it (YYYY-MM-DD or an ISO-8601 datetime, UTC when no offset is given)."
5466
- },
5467
- {
5468
- "name": "q",
5469
- "type": "string",
5470
- "required": false,
5471
- "description": "Search inside the channel: only posts matching this text."
5472
- },
5473
- {
5474
- "name": "post_id",
5475
- "type": "integer",
5476
- "required": false,
5477
- "description": "Return only this post (a post id of the channel)."
5478
- },
5479
- {
5480
- "name": "proxy_country",
5481
- "type": "string",
5482
- "required": false,
5483
- "description": "Proxy country the request is sent from (ISO-2, e.g. 'US', 'DE'). Leave blank to let the API pick."
5484
- }
5485
- ]
5486
- },
5487
- {
5488
- "name": "quora_question",
5489
- "title": "Scrape Quora questions, answers and profiles (mode=question)",
5490
- "category": "Video, Music & Communities",
5491
- "path": "/social/quora",
5492
- "fixed": {
5493
- "mode": "question"
5494
- },
5495
- "description": "Given a Quora `question` (URL or slug), returns the `question` (`qid`, `title`, `url`, `answerCount`, `allRelatedCount`, `followerCount`, `commentCount`, `topics`) and its `answers`: `id`, `url`, `relation` (`answer`, `merged` for an answer to a question Quora merged into this one, `related` with `include_related=true`), the answered `question`, `author` (`name`, `uid`, `profileUrl`, `imageUrl`, `credential`, `isVerified`, `isAnonymous`), the full `text` with `images` and `links`, `upvotes`, `views`, `shares`, `comments`, `createdAt`, `updatedAt` and `isAiGenerated`; plus `relatedQuestions`. Answers are in Quora's own order, up to `max_answers` (10 per page after the first few), unique within a call. `nextCursor` as `cursor` continues, best-effort: Quora re-ranks the list on every visit, so a continuation can repeat or skip answers of earlier calls (dedupe by `id`); for a complete list ask for a larger `max_answers` in one call (up to 300). `mode=profile&profile=` returns a public `profile` (`name`, `headline`, `description`, follower / following / answer / question / post counts, `contentViews`, `credentials`, `knowsAbout`, `spaces`, `topWriterYears`, `joinedAt`) with its newest `answers`. No login: only what Quora shows an anonymous visitor - Quora's search is not available that way, and Quora lists only a profile's newest few dozen answers to logged-out visitors (`pagingStopped`: `quora_logged_out_limit`). `pagingStopped` otherwise names why paging ended early (`blocked`, `time`, `unavailable`). Billed one unit per page fetched (`pagesFetched`); a `cursor` continuation bills only its GraphQL pages.",
5496
- "params": [
5497
- {
5498
- "name": "question",
5499
- "type": "string",
5500
- "required": true,
5501
- "description": "Quora question URL (https://www.quora.com/What-is-the-best-way-to-learn-programming), an answer URL on it, or the question slug (What-is-the-best-way-to-learn-programming). Language editions such as es.quora.com are accepted as URLs. Required with mode=question."
5502
- },
5503
- {
5504
- "name": "max_answers",
5505
- "type": "integer",
5506
- "required": false,
5507
- "description": "Answers to return: 1-300 with mode=question (default 20), 0-200 with mode=profile (default 10; 0 = profile only). Answers come 10 per page after the first few; each page is one billed unit."
5508
- },
5509
- {
5510
- "name": "include_related",
5511
- "type": "boolean",
5512
- "required": false,
5513
- "description": "mode=question: also return the answers Quora shows from related questions (its 'All related' view, `relation`='related'). By default only answers to this question and to questions merged into it.",
5514
- "default": false
5515
- },
5516
- {
5517
- "name": "cursor",
5518
- "type": "string",
5519
- "required": false,
5520
- "description": "Continue after a previous call: pass its `nextCursor`. Best-effort: each call is a new Quora visit and Quora re-ranks the list per visit, so a continuation can repeat or skip answers of earlier calls - dedupe by answer `id`. For a complete list ask for a larger `max_answers` in one call (up to 300)."
5521
- },
5522
- {
5523
- "name": "proxy_country",
5524
- "type": "string",
5525
- "required": false,
5526
- "description": "Proxy country the request is sent from (ISO-2, e.g. 'US', 'DE'). Leave blank for the countries chosen for the site."
5527
- }
5528
- ]
5529
- },
5530
- {
5531
- "name": "quora_profile",
5532
- "title": "Scrape Quora questions, answers and profiles (mode=profile)",
5533
- "category": "Video, Music & Communities",
5534
- "path": "/social/quora",
5535
- "fixed": {
5536
- "mode": "profile"
5537
- },
5538
- "description": "Given a Quora `question` (URL or slug), returns the `question` (`qid`, `title`, `url`, `answerCount`, `allRelatedCount`, `followerCount`, `commentCount`, `topics`) and its `answers`: `id`, `url`, `relation` (`answer`, `merged` for an answer to a question Quora merged into this one, `related` with `include_related=true`), the answered `question`, `author` (`name`, `uid`, `profileUrl`, `imageUrl`, `credential`, `isVerified`, `isAnonymous`), the full `text` with `images` and `links`, `upvotes`, `views`, `shares`, `comments`, `createdAt`, `updatedAt` and `isAiGenerated`; plus `relatedQuestions`. Answers are in Quora's own order, up to `max_answers` (10 per page after the first few), unique within a call. `nextCursor` as `cursor` continues, best-effort: Quora re-ranks the list on every visit, so a continuation can repeat or skip answers of earlier calls (dedupe by `id`); for a complete list ask for a larger `max_answers` in one call (up to 300). `mode=profile&profile=` returns a public `profile` (`name`, `headline`, `description`, follower / following / answer / question / post counts, `contentViews`, `credentials`, `knowsAbout`, `spaces`, `topWriterYears`, `joinedAt`) with its newest `answers`. No login: only what Quora shows an anonymous visitor - Quora's search is not available that way, and Quora lists only a profile's newest few dozen answers to logged-out visitors (`pagingStopped`: `quora_logged_out_limit`). `pagingStopped` otherwise names why paging ended early (`blocked`, `time`, `unavailable`). Billed one unit per page fetched (`pagesFetched`); a `cursor` continuation bills only its GraphQL pages.",
5539
- "params": [
5540
- {
5541
- "name": "profile",
5542
- "type": "string",
5543
- "required": true,
5544
- "description": "Quora profile URL (https://www.quora.com/profile/Adam-DAngelo) or profile slug (Adam-DAngelo). Required with mode=profile."
5545
- },
5546
- {
5547
- "name": "max_answers",
5548
- "type": "integer",
5549
- "required": false,
5550
- "description": "Answers to return: 1-300 with mode=question (default 20), 0-200 with mode=profile (default 10; 0 = profile only). Answers come 10 per page after the first few; each page is one billed unit."
5551
- },
5552
- {
5553
- "name": "cursor",
5554
- "type": "string",
5555
- "required": false,
5556
- "description": "Continue after a previous call: pass its `nextCursor`. Best-effort: each call is a new Quora visit and Quora re-ranks the list per visit, so a continuation can repeat or skip answers of earlier calls - dedupe by answer `id`. For a complete list ask for a larger `max_answers` in one call (up to 300)."
5557
- },
5558
- {
5559
- "name": "proxy_country",
5560
- "type": "string",
5561
- "required": false,
5562
- "description": "Proxy country the request is sent from (ISO-2, e.g. 'US', 'DE'). Leave blank for the countries chosen for the site."
5563
- }
5564
- ]
5565
- },
5566
5386
  {
5567
5387
  "name": "similarweb_overview",
5568
5388
  "title": "Get a website's Similarweb traffic overview",
@@ -5837,7 +5657,7 @@ ${details(plugin)}`, true);
5837
5657
  }
5838
5658
 
5839
5659
  // src/index.ts
5840
- var VERSION = "0.3.0";
5660
+ var VERSION = "0.3.2";
5841
5661
  var DEFAULT_BASE_URL = "https://api.scrapeunblocker.com";
5842
5662
  var API_KEY_HEADER = "x-scrapeunblocker-key";
5843
5663
  function resolveApiKey() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scrapeunblocker-mcp",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "mcpName": "com.scrapeunblocker/scrapeunblocker-mcp",
5
5
  "description": "Model Context Protocol (MCP) server for ScrapeUnblocker - lets Claude fetch any web page's HTML (or AI-parsed JSON) and run 100+ site plugins that return structured JSON, through the ScrapeUnblocker anti-bot API, using your own API key.",
6
6
  "keywords": [