alterlab-mcp-server 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +384 -0
- package/dist/client.d.ts +14 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +84 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +10 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +136 -0
- package/dist/errors.js.map +1 -0
- package/dist/format.d.ts +19 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +122 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/balance.d.ts +7 -0
- package/dist/tools/balance.d.ts.map +1 -0
- package/dist/tools/balance.js +32 -0
- package/dist/tools/balance.js.map +1 -0
- package/dist/tools/estimate.d.ts +22 -0
- package/dist/tools/estimate.d.ts.map +1 -0
- package/dist/tools/estimate.js +53 -0
- package/dist/tools/estimate.js.map +1 -0
- package/dist/tools/extract.d.ts +28 -0
- package/dist/tools/extract.d.ts.map +1 -0
- package/dist/tools/extract.js +68 -0
- package/dist/tools/extract.js.map +1 -0
- package/dist/tools/scrape.d.ts +37 -0
- package/dist/tools/scrape.d.ts.map +1 -0
- package/dist/tools/scrape.js +84 -0
- package/dist/tools/scrape.js.map +1 -0
- package/dist/tools/screenshot.d.ts +19 -0
- package/dist/tools/screenshot.d.ts.map +1 -0
- package/dist/tools/screenshot.js +84 -0
- package/dist/tools/screenshot.js.map +1 -0
- package/dist/types.d.ts +79 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +26 -0
- package/dist/types.js.map +1 -0
- package/package.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AlterLab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo.png" alt="AlterLab Logo" width="120" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">AlterLab MCP Server</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>Give Claude, Cursor, and Windsurf the ability to scrape any website, extract structured data, and take screenshots — with automatic anti-bot bypass.</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/alterlab-mcp-server"><img src="https://img.shields.io/npm/v/alterlab-mcp-server.svg" alt="npm version" /></a>
|
|
13
|
+
<a href="https://www.npmjs.com/package/alterlab-mcp-server"><img src="https://img.shields.io/npm/dm/alterlab-mcp-server.svg" alt="npm downloads" /></a>
|
|
14
|
+
<a href="https://github.com/RapierCraft/alterlab-mcp-server/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/alterlab-mcp-server.svg" alt="license" /></a>
|
|
15
|
+
<a href="https://smithery.ai/server/alterlab-mcp-server"><img src="https://smithery.ai/badge/alterlab-mcp-server" alt="Smithery" /></a>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="https://app.alterlab.io/signin?redirect=/dashboard/keys&source=mcp&utm_source=mcp&utm_medium=integration&utm_campaign=mcp_server"><strong>Get Started Free →</strong></a> $1 free balance on signup — up to 5,000 scrapes.
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## One-Line Install
|
|
25
|
+
|
|
26
|
+
### Claude Code
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
claude mcp add alterlab -- npx -y alterlab-mcp-server
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Then set your API key: `export ALTERLAB_API_KEY=sk_live_...` or add it to `.claude.json` (see [full setup](#install-in-claude-desktop--claude-code) below).
|
|
33
|
+
|
|
34
|
+
### Cursor
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Add to .cursor/mcp.json — see full config below
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Smithery
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npx -y @smithery/cli install alterlab-mcp-server --client claude
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Why AlterLab Instead of WebFetch or Browser MCP?
|
|
49
|
+
|
|
50
|
+
Claude's built-in `WebFetch` tool and open-source browser MCP servers fail on most real-world websites. They cannot bypass Cloudflare, render JavaScript SPAs, or extract structured data.
|
|
51
|
+
|
|
52
|
+
AlterLab replaces broken fetch tools with **one MCP server** that actually works:
|
|
53
|
+
|
|
54
|
+
| Capability | WebFetch / fetch() | Browser MCP | AlterLab MCP |
|
|
55
|
+
|---|---|---|---|
|
|
56
|
+
| Anti-bot bypass (Cloudflare, DataDome, Akamai) | No | Partial | Yes — automatic |
|
|
57
|
+
| JavaScript rendering (React, Angular, Vue SPAs) | No | Yes (slow) | Yes — headless Chromium |
|
|
58
|
+
| Structured data extraction (JSON, Schema.org) | No | No | Yes — built-in profiles |
|
|
59
|
+
| Smart tier escalation (cheapest method first) | N/A | N/A | Yes — saves 60-80% |
|
|
60
|
+
| Residential proxy rotation (195+ countries) | No | No | Yes |
|
|
61
|
+
| Screenshot and PDF capture | No | Screenshot only | Yes — both |
|
|
62
|
+
| OCR text extraction from images | No | No | Yes |
|
|
63
|
+
| Cost per request | Free (but fails) | Free (but slow) | From $0.0002 |
|
|
64
|
+
|
|
65
|
+
## How Does AlterLab Web Scraping Work?
|
|
66
|
+
|
|
67
|
+
AlterLab uses a multi-tier scraping architecture. It automatically selects the cheapest method capable of fetching each URL:
|
|
68
|
+
|
|
69
|
+
1. **Curl** ($0.0002/req) — Direct HTTP for static pages, RSS feeds, public APIs
|
|
70
|
+
2. **HTTP** ($0.0003/req) — TLS fingerprint rotation for moderately protected sites
|
|
71
|
+
3. **Stealth** ($0.0005/req) — Browser impersonation for Cloudflare/DataDome-protected sites
|
|
72
|
+
4. **Light JS** ($0.0007/req) — Lightweight JS extraction from server-rendered HTML
|
|
73
|
+
5. **Browser** ($0.001/req) — Full headless Chromium for JavaScript-heavy SPAs
|
|
74
|
+
|
|
75
|
+
Auto mode starts at Tier 1 and escalates only when blocked. Most websites resolve at Tiers 1-2, so **$1 gets you 1,000 to 5,000 scrapes** depending on the sites you target.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Installation
|
|
80
|
+
|
|
81
|
+
### Install in Claude Desktop / Claude Code
|
|
82
|
+
|
|
83
|
+
Add to your Claude config file (`~/.claude.json` for Claude Code, or Settings for Claude Desktop):
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"mcpServers": {
|
|
88
|
+
"alterlab": {
|
|
89
|
+
"command": "npx",
|
|
90
|
+
"args": ["-y", "alterlab-mcp-server"],
|
|
91
|
+
"env": {
|
|
92
|
+
"ALTERLAB_API_KEY": "sk_live_your_key_here"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Install in Cursor
|
|
100
|
+
|
|
101
|
+
Add to `.cursor/mcp.json` in your project root:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"mcpServers": {
|
|
106
|
+
"alterlab": {
|
|
107
|
+
"command": "npx",
|
|
108
|
+
"args": ["-y", "alterlab-mcp-server"],
|
|
109
|
+
"env": {
|
|
110
|
+
"ALTERLAB_API_KEY": "sk_live_your_key_here"
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Install in Windsurf
|
|
118
|
+
|
|
119
|
+
Add to Windsurf MCP settings (`~/.codeium/windsurf/mcp_config.json`):
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"mcpServers": {
|
|
124
|
+
"alterlab": {
|
|
125
|
+
"command": "npx",
|
|
126
|
+
"args": ["-y", "alterlab-mcp-server"],
|
|
127
|
+
"env": {
|
|
128
|
+
"ALTERLAB_API_KEY": "sk_live_your_key_here"
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Install via Smithery
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
npx -y @smithery/cli install alterlab-mcp-server --client claude
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Get Your API Key
|
|
142
|
+
|
|
143
|
+
1. [Sign up free](https://app.alterlab.io/signin?redirect=/dashboard/keys&source=mcp&utm_source=mcp&utm_medium=integration&utm_campaign=mcp_server) — $1 free balance on signup
|
|
144
|
+
2. Go to **Dashboard → API Keys** and copy your key
|
|
145
|
+
3. Paste it into the `ALTERLAB_API_KEY` field in your MCP config
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Tools
|
|
150
|
+
|
|
151
|
+
### `alterlab_scrape` — Scrape Any Webpage
|
|
152
|
+
|
|
153
|
+
Scrape a URL and return its content as markdown, text, HTML, or JSON. Automatically handles anti-bot protection with tier escalation. Returns markdown by default — optimized for LLM context windows.
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
"Scrape https://www.amazon.com/dp/B0BSHF7WHW and summarize the product"
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
| Parameter | Type | Default | Description |
|
|
160
|
+
|---|---|---|---|
|
|
161
|
+
| `url` | string | required | URL to scrape |
|
|
162
|
+
| `mode` | `auto` \| `html` \| `js` \| `pdf` \| `ocr` | `auto` | Scraping mode |
|
|
163
|
+
| `formats` | `(text\|json\|html\|markdown)[]` | `["markdown"]` | Output formats |
|
|
164
|
+
| `render_js` | boolean | `false` | Use headless browser (+3 credits) |
|
|
165
|
+
| `use_proxy` | boolean | `false` | Premium proxy (+1 credit) |
|
|
166
|
+
| `proxy_country` | string | — | ISO country code for geo-targeting (e.g., `US`, `DE`) |
|
|
167
|
+
| `wait_for` | string | — | CSS selector to wait for before extraction |
|
|
168
|
+
| `timeout` | number | `90` | Timeout in seconds (1-300) |
|
|
169
|
+
| `include_raw_html` | boolean | `false` | Include raw HTML alongside formatted content |
|
|
170
|
+
|
|
171
|
+
### `alterlab_extract` — Extract Structured Data
|
|
172
|
+
|
|
173
|
+
Extract structured fields from any webpage using pre-built profiles or custom JSON Schema. Returns clean JSON — ready for databases, spreadsheets, or downstream processing.
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
"Extract the product name, price, and rating from this Amazon page"
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
| Parameter | Type | Default | Description |
|
|
180
|
+
|---|---|---|---|
|
|
181
|
+
| `url` | string | required | URL to extract from |
|
|
182
|
+
| `extraction_profile` | enum | `auto` | Profile: `product`, `article`, `job_posting`, `faq`, `recipe`, `event` |
|
|
183
|
+
| `extraction_schema` | object | — | Custom JSON Schema for structured output |
|
|
184
|
+
| `extraction_prompt` | string | — | Natural language extraction instructions |
|
|
185
|
+
| `render_js` | boolean | `false` | Use headless browser |
|
|
186
|
+
| `use_proxy` | boolean | `false` | Premium proxy |
|
|
187
|
+
|
|
188
|
+
**Extraction profiles:**
|
|
189
|
+
|
|
190
|
+
- **Product** — name, price, currency, rating, reviews, availability, images, description
|
|
191
|
+
- **Article** — title, author, published date, body text, featured image
|
|
192
|
+
- **Job Posting** — title, company, location, salary, description, requirements
|
|
193
|
+
- **FAQ** — question-answer pairs
|
|
194
|
+
- **Recipe** — ingredients, instructions, prep time, servings
|
|
195
|
+
- **Event** — name, date, location, description, organizer
|
|
196
|
+
|
|
197
|
+
### `alterlab_screenshot` — Screenshot Any Page
|
|
198
|
+
|
|
199
|
+
Take a full-page screenshot of any URL. Returns a PNG image directly in the conversation — no URLs to copy, no files to download.
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
"Take a screenshot of our landing page at https://alterlab.io"
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
| Parameter | Type | Default | Description |
|
|
206
|
+
|---|---|---|---|
|
|
207
|
+
| `url` | string | required | URL to screenshot |
|
|
208
|
+
| `wait_for` | string | — | CSS selector to wait for before capture |
|
|
209
|
+
| `wait_until` | enum | `networkidle` | `networkidle`, `domcontentloaded`, or `load` |
|
|
210
|
+
|
|
211
|
+
### `alterlab_estimate_cost` — Estimate Before You Scrape
|
|
212
|
+
|
|
213
|
+
Check how much a scrape will cost before running it. Returns the predicted tier, cost per request, and confidence level.
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
"How much would it cost to scrape linkedin.com?"
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
| Parameter | Type | Default | Description |
|
|
220
|
+
|---|---|---|---|
|
|
221
|
+
| `url` | string | required | URL to estimate |
|
|
222
|
+
| `mode` | enum | `auto` | Scraping mode |
|
|
223
|
+
| `render_js` | boolean | `false` | Include JS rendering cost |
|
|
224
|
+
| `use_proxy` | boolean | `false` | Include proxy cost |
|
|
225
|
+
|
|
226
|
+
### `alterlab_check_balance` — Check Your Credits
|
|
227
|
+
|
|
228
|
+
Check your account balance, total deposited, and total spent. No parameters needed.
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
"Check my AlterLab balance"
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## What Can You Do with AlterLab MCP?
|
|
237
|
+
|
|
238
|
+
### Research and Analysis
|
|
239
|
+
|
|
240
|
+
Ask Claude to scrape and analyze websites in real-time:
|
|
241
|
+
|
|
242
|
+
- *"Scrape the top 5 results from this Google search and summarize them"*
|
|
243
|
+
- *"Extract all product prices from this Amazon category page"*
|
|
244
|
+
- *"Compare the pricing pages of these 3 competitors"*
|
|
245
|
+
|
|
246
|
+
### Code Generation with Real Data
|
|
247
|
+
|
|
248
|
+
Let Cursor or Windsurf fetch live data while building:
|
|
249
|
+
|
|
250
|
+
- *"Scrape this API documentation page and generate TypeScript types from it"*
|
|
251
|
+
- *"Extract the color palette from this website and create a Tailwind config"*
|
|
252
|
+
- *"Screenshot this design and recreate it in React"*
|
|
253
|
+
|
|
254
|
+
### Content and SEO
|
|
255
|
+
|
|
256
|
+
Use Claude to analyze content at scale:
|
|
257
|
+
|
|
258
|
+
- *"Scrape this blog post and suggest improvements for SEO"*
|
|
259
|
+
- *"Extract all FAQ entries from this help center and create a structured dataset"*
|
|
260
|
+
- *"Compare our landing page to the competitor's and identify gaps"*
|
|
261
|
+
|
|
262
|
+
### Monitoring and Alerts
|
|
263
|
+
|
|
264
|
+
Build agentic workflows that watch the web:
|
|
265
|
+
|
|
266
|
+
- *"Check if this product is back in stock"*
|
|
267
|
+
- *"Scrape this page daily and alert me when the price drops below $50"*
|
|
268
|
+
- *"Monitor this job board for new senior engineering positions"*
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Pricing — Pay-As-You-Go Web Scraping
|
|
273
|
+
|
|
274
|
+
No subscriptions. No monthly minimums. Add balance and use it whenever you need it.
|
|
275
|
+
|
|
276
|
+
### Base Scraping Costs
|
|
277
|
+
|
|
278
|
+
| Tier | Method | Cost per Request | Use Case |
|
|
279
|
+
|---|---|---|---|
|
|
280
|
+
| Curl | Direct HTTP | $0.0002 | Static pages, RSS feeds, public APIs |
|
|
281
|
+
| HTTP | TLS fingerprinting | $0.0003 | Sites with basic bot detection |
|
|
282
|
+
| Stealth | Browser impersonation | $0.0005 | Cloudflare, DataDome, PerimeterX protected sites |
|
|
283
|
+
| Light JS | JSON extraction | $0.0007 | Server-rendered pages needing structured data |
|
|
284
|
+
| Browser | Headless Chromium | $0.001 | Full JavaScript SPAs (React, Angular, Vue) |
|
|
285
|
+
|
|
286
|
+
### Optional Add-Ons
|
|
287
|
+
|
|
288
|
+
| Add-On | Extra Cost | Description |
|
|
289
|
+
|---|---|---|
|
|
290
|
+
| JavaScript Rendering | +$0.0006 | Headless Chromium for dynamic content |
|
|
291
|
+
| Screenshot Capture | +$0.0002 | Full-page PNG screenshot |
|
|
292
|
+
| Premium Proxy | +$0.0002 | Geo-targeted residential proxy (195+ countries) |
|
|
293
|
+
| OCR Text Extraction | +$0.001 | Extract text from images on the page |
|
|
294
|
+
|
|
295
|
+
**$1 = 5,000 light scrapes.** New accounts get $1 free balance on signup.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## Environment Variables
|
|
300
|
+
|
|
301
|
+
| Variable | Required | Default | Description |
|
|
302
|
+
|---|---|---|---|
|
|
303
|
+
| `ALTERLAB_API_KEY` | Yes | — | Your API key ([get one free](https://app.alterlab.io/signin?redirect=/dashboard/keys&source=mcp&utm_source=mcp&utm_medium=integration&utm_campaign=mcp_server)) |
|
|
304
|
+
| `ALTERLAB_API_URL` | No | `https://api.alterlab.io` | API base URL (for self-hosted or development) |
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Frequently Asked Questions
|
|
309
|
+
|
|
310
|
+
### How do I add web scraping to Claude, Cursor, or Windsurf?
|
|
311
|
+
|
|
312
|
+
Install the AlterLab MCP server. For Claude Code, run `claude mcp add alterlab -- npx -y alterlab-mcp-server` and set your `ALTERLAB_API_KEY`. For Claude Desktop, Cursor, or Windsurf, add the JSON config block to your MCP settings file. Once configured, your AI assistant can scrape any URL, extract structured data, and take screenshots directly in conversation.
|
|
313
|
+
|
|
314
|
+
### Can Claude scrape websites that are behind Cloudflare or anti-bot protection?
|
|
315
|
+
|
|
316
|
+
Yes. AlterLab automatically handles Cloudflare, DataDome, PerimeterX, Akamai, and other anti-bot systems. It uses a multi-tier approach that starts with the cheapest method and escalates only when blocked. You don't need to configure anything — anti-bot bypass is fully automatic.
|
|
317
|
+
|
|
318
|
+
### What is an MCP server and how does it work with Claude?
|
|
319
|
+
|
|
320
|
+
MCP (Model Context Protocol) is Anthropic's open standard for connecting AI assistants to external tools and data sources. An MCP server is a small program that exposes tools — like web scraping — that Claude, Cursor, or Windsurf can call during a conversation. The AlterLab MCP server gives your AI assistant 5 tools: scrape, extract, screenshot, estimate cost, and check balance.
|
|
321
|
+
|
|
322
|
+
### How is AlterLab different from Firecrawl, ScrapingBee, or Apify MCP servers?
|
|
323
|
+
|
|
324
|
+
AlterLab starts at $0.0002 per request — 5-20x cheaper than most scraping APIs — because it only uses expensive browser rendering when a site actually requires it. Smart tier escalation means you pay for what each site needs, not the maximum. AlterLab also includes built-in structured data extraction with pre-built profiles (product, article, job posting, etc.) at no extra cost.
|
|
325
|
+
|
|
326
|
+
### Can I scrape Amazon, Walmart, and other e-commerce sites from Claude?
|
|
327
|
+
|
|
328
|
+
Yes. AlterLab handles all major e-commerce anti-bot protection. Use the `alterlab_extract` tool with `extraction_profile: "product"` to get structured JSON: product name, price, currency, rating, review count, availability, and images — ready for analysis, comparison, or data pipelines.
|
|
329
|
+
|
|
330
|
+
### Can Cursor scrape documentation and generate code from it?
|
|
331
|
+
|
|
332
|
+
Yes. With AlterLab MCP installed in Cursor, you can ask it to scrape API documentation, library docs, or any reference page and generate TypeScript types, API clients, or component code from the live content. This is more reliable than relying on the LLM's training data, which may be outdated.
|
|
333
|
+
|
|
334
|
+
### Does AlterLab MCP work with JavaScript-heavy sites (React, Angular, Vue)?
|
|
335
|
+
|
|
336
|
+
Yes. Use `render_js: true` or set `mode: "js"` to enable full headless Chromium rendering. AlterLab renders the complete page including all JavaScript, waits for dynamic content to load, then extracts content from the fully rendered DOM. This works for React, Angular, Vue, Next.js, and any other JavaScript framework.
|
|
337
|
+
|
|
338
|
+
### What output format is best for AI and LLM context windows?
|
|
339
|
+
|
|
340
|
+
Use markdown (the default). It preserves document structure — headings, tables, lists, links — while being 60-80% smaller than raw HTML. Claude, GPT-4, and other LLMs process markdown significantly better than HTML. AlterLab's markdown output is specifically optimized for LLM context windows.
|
|
341
|
+
|
|
342
|
+
### Is there rate limiting?
|
|
343
|
+
|
|
344
|
+
Free-tier accounts have rate limits. Adding any balance removes rate limits. The MCP server includes automatic retry with exponential backoff for transient rate limit errors (429).
|
|
345
|
+
|
|
346
|
+
### Can I use this MCP server for large-scale scraping?
|
|
347
|
+
|
|
348
|
+
Yes. The MCP server processes one request at a time through the conversation interface, but you can build agentic workflows that scrape many URLs sequentially. For batch processing, use the AlterLab API directly or the [n8n integration](https://www.npmjs.com/package/n8n-nodes-alterlab).
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## Error Handling
|
|
353
|
+
|
|
354
|
+
The MCP server returns helpful error messages with suggested next actions:
|
|
355
|
+
|
|
356
|
+
| Error | What Happens | Suggested Action |
|
|
357
|
+
|---|---|---|
|
|
358
|
+
| **401** Unauthorized | Invalid API key | Check `ALTERLAB_API_KEY` is set correctly |
|
|
359
|
+
| **402** Insufficient Credits | Balance too low | Run `alterlab_check_balance`, add funds |
|
|
360
|
+
| **403** Forbidden | Site blocked the request | Try `render_js: true` + `use_proxy: true` |
|
|
361
|
+
| **429** Rate Limited | Too many requests | Automatic retry with backoff |
|
|
362
|
+
| **504** Gateway Timeout | Scrape took too long | Increase `timeout`, simplify request |
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## Contributing
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
git clone https://github.com/RapierCraft/alterlab-mcp-server.git
|
|
370
|
+
cd alterlab-mcp-server
|
|
371
|
+
npm install
|
|
372
|
+
npm run build
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## Support
|
|
376
|
+
|
|
377
|
+
- [API Documentation](https://docs.alterlab.io/api?utm_source=mcp&utm_medium=integration&utm_campaign=mcp_server)
|
|
378
|
+
- [Dashboard & API Keys](https://app.alterlab.io/dashboard?utm_source=mcp&utm_medium=integration&utm_campaign=mcp_server)
|
|
379
|
+
- [GitHub Issues](https://github.com/RapierCraft/alterlab-mcp-server/issues)
|
|
380
|
+
- [support@alterlab.io](mailto:support@alterlab.io)
|
|
381
|
+
|
|
382
|
+
## License
|
|
383
|
+
|
|
384
|
+
[MIT](LICENSE)
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Config } from "./config.js";
|
|
2
|
+
import { type BalanceResponse, type CostEstimate, type UnifiedScrapeRequest, type UnifiedScrapeResponse } from "./types.js";
|
|
3
|
+
export declare class AlterLabClient {
|
|
4
|
+
private apiKey;
|
|
5
|
+
private apiUrl;
|
|
6
|
+
private userAgent;
|
|
7
|
+
constructor(config: Config);
|
|
8
|
+
private request;
|
|
9
|
+
scrape(params: UnifiedScrapeRequest): Promise<UnifiedScrapeResponse>;
|
|
10
|
+
estimate(params: UnifiedScrapeRequest): Promise<CostEstimate>;
|
|
11
|
+
getBalance(): Promise<BalanceResponse>;
|
|
12
|
+
fetchScreenshotAsBase64(screenshotUrl: string): Promise<string>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC3B,MAAM,YAAY,CAAC;AAOpB,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,EAAE,MAAM;YAMZ,OAAO;IAkDf,MAAM,CACV,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,qBAAqB,CAAC;IAQ3B,QAAQ,CACZ,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,YAAY,CAAC;IAQlB,UAAU,IAAI,OAAO,CAAC,eAAe,CAAC;IAItC,uBAAuB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAsBtE"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AlterLabClient = void 0;
|
|
4
|
+
// Read version from package.json at build time is complex with ESM,
|
|
5
|
+
// so we hardcode it and keep in sync with package.json.
|
|
6
|
+
const VERSION = "1.0.0";
|
|
7
|
+
const MAX_RETRIES = 2;
|
|
8
|
+
class AlterLabClient {
|
|
9
|
+
apiKey;
|
|
10
|
+
apiUrl;
|
|
11
|
+
userAgent;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.apiKey = config.apiKey;
|
|
14
|
+
this.apiUrl = config.apiUrl;
|
|
15
|
+
this.userAgent = `alterlab-mcp-server/${VERSION}`;
|
|
16
|
+
}
|
|
17
|
+
async request(method, path, body, retryCount = 0) {
|
|
18
|
+
const url = `${this.apiUrl}${path}`;
|
|
19
|
+
const headers = {
|
|
20
|
+
"X-API-Key": this.apiKey,
|
|
21
|
+
"User-Agent": this.userAgent,
|
|
22
|
+
"Content-Type": "application/json",
|
|
23
|
+
};
|
|
24
|
+
const response = await fetch(url, {
|
|
25
|
+
method,
|
|
26
|
+
headers,
|
|
27
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
28
|
+
});
|
|
29
|
+
// Retry transient errors (429, 503) — NOT 504 (credits may be consumed)
|
|
30
|
+
if ((response.status === 429 || response.status === 503) &&
|
|
31
|
+
retryCount < MAX_RETRIES) {
|
|
32
|
+
const retryAfter = response.headers.get("Retry-After");
|
|
33
|
+
const delay = retryAfter
|
|
34
|
+
? parseInt(retryAfter, 10) * 1000
|
|
35
|
+
: Math.min(1000 * 2 ** retryCount, 8000);
|
|
36
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
37
|
+
return this.request(method, path, body, retryCount + 1);
|
|
38
|
+
}
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
let detail;
|
|
41
|
+
try {
|
|
42
|
+
const errorBody = await response.json();
|
|
43
|
+
detail =
|
|
44
|
+
typeof errorBody.detail === "string"
|
|
45
|
+
? errorBody.detail
|
|
46
|
+
: JSON.stringify(errorBody.detail || errorBody);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
detail = response.statusText;
|
|
50
|
+
}
|
|
51
|
+
const apiError = { status: response.status, detail };
|
|
52
|
+
throw apiError;
|
|
53
|
+
}
|
|
54
|
+
return (await response.json());
|
|
55
|
+
}
|
|
56
|
+
async scrape(params) {
|
|
57
|
+
return this.request("POST", "/api/v1/scrape", params);
|
|
58
|
+
}
|
|
59
|
+
async estimate(params) {
|
|
60
|
+
return this.request("POST", "/api/v1/scrape/estimate", params);
|
|
61
|
+
}
|
|
62
|
+
async getBalance() {
|
|
63
|
+
return this.request("GET", "/api/v1/billing/balance");
|
|
64
|
+
}
|
|
65
|
+
async fetchScreenshotAsBase64(screenshotUrl) {
|
|
66
|
+
// screenshot_url is a relative path like /downloads/screenshots/...
|
|
67
|
+
const fullUrl = screenshotUrl.startsWith("http")
|
|
68
|
+
? screenshotUrl
|
|
69
|
+
: `${this.apiUrl}${screenshotUrl}`;
|
|
70
|
+
const response = await fetch(fullUrl, {
|
|
71
|
+
headers: {
|
|
72
|
+
"X-API-Key": this.apiKey,
|
|
73
|
+
"User-Agent": this.userAgent,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
if (!response.ok) {
|
|
77
|
+
throw new Error(`Failed to fetch screenshot: ${response.status} ${response.statusText}`);
|
|
78
|
+
}
|
|
79
|
+
const buffer = await response.arrayBuffer();
|
|
80
|
+
return Buffer.from(buffer).toString("base64");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.AlterLabClient = AlterLabClient;
|
|
84
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,UAAU,IAAI,MAAM,CAiBnC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadConfig = loadConfig;
|
|
4
|
+
function loadConfig() {
|
|
5
|
+
const apiKey = process.env.ALTERLAB_API_KEY;
|
|
6
|
+
if (!apiKey) {
|
|
7
|
+
console.error("Error: ALTERLAB_API_KEY environment variable is required.\n\n" +
|
|
8
|
+
"Get your API key at https://alterlab.io/dashboard/api-keys\n\n" +
|
|
9
|
+
"Then add it to your MCP config:\n" +
|
|
10
|
+
' "env": { "ALTERLAB_API_KEY": "sk_live_..." }');
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
const apiUrl = process.env.ALTERLAB_API_URL?.replace(/\/+$/, "") ||
|
|
14
|
+
"https://api.alterlab.io";
|
|
15
|
+
return { apiKey, apiUrl };
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAKA,gCAiBC;AAjBD,SAAgB,UAAU;IACxB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CACX,+DAA+D;YAC7D,gEAAgE;YAChE,mCAAmC;YACnC,gDAAgD,CACnD,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GACV,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACjD,yBAAyB,CAAC;IAE5B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export interface ApiError {
|
|
3
|
+
status: number;
|
|
4
|
+
detail?: string;
|
|
5
|
+
url?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function formatErrorResult(error: ApiError | Error, context?: {
|
|
8
|
+
url?: string;
|
|
9
|
+
}): CallToolResult;
|
|
10
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,QAAQ,GAAG,KAAK,EACvB,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACzB,cAAc,CAmJhB"}
|