alterlab-mcp-server
You can scrape, extract, screenshot, crawl, search, map, batch-scrape, and manage authenticated sessions for web data with automatic anti-bot bypass and cost controls.
Scrape any URL to markdown, text, HTML, or JSON with tiered anti-bot bypass, JS rendering, proxies, actions, and structured extraction.
Extract structured data from HTML, text, or markdown using pre-built profiles (product, article, job posting, etc.) or custom JSON schemas.
Capture full-page screenshots of any URL, including pages behind a login.
Batch scrape up to 20 URLs synchronously or up to 100 URLs asynchronously with per-URL options.
Crawl entire websites with sitemap/link discovery, pattern filtering, per-page extraction, and change tracking.
Search the web via Google, Bing, or DuckDuckGo and optionally scrape each result page.
Map/discover all URLs on a site for planning scrapes or crawls.
Manage authenticated sessions: create, list, get, update, refresh, validate, and delete stored cookies/headers.
Estimate scraping costs, check balance/usage, and fetch async job results.
List, enable, or disable beta features on your account.
Provides automatic anti-bot bypass for Akamai-protected websites, enabling reliable scraping of sites behind Akamai.
Allows scraping of Amazon product pages, extraction of product details (name, price, rating, etc.), and session management for authenticated scraping.
Provides automatic anti-bot bypass for Cloudflare-protected websites, enabling reliable scraping of sites behind Cloudflare.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@alterlab-mcp-serverScrape the HTML content of https://example.com"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
One-Line Install
Claude Code
claude mcp add alterlab -- npx -y alterlab-mcp-server@latestThen set your API key: export ALTERLAB_API_KEY=sk_live_... or add it to .claude.json (see full setup below).
Cursor
# Add to .cursor/mcp.json — see full config belowSmithery
npx -y @smithery/cli install alterlab-mcp-server --client claudeRelated MCP server: Decodo MCP Server
Why AlterLab Instead of WebFetch or Browser MCP?
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.
AlterLab replaces broken fetch tools with one MCP server that actually works:
Capability | WebFetch / fetch() | Browser MCP | AlterLab MCP |
Anti-bot bypass (Cloudflare, DataDome, Akamai) | No | Partial | Yes — automatic |
JavaScript rendering (React, Angular, Vue SPAs) | No | Yes (slow) | Yes — headless Chromium |
Structured data extraction (JSON, Schema.org) | No | No | Yes — built-in profiles |
Smart tier escalation (cheapest method first) | N/A | N/A | Yes — saves 60-80% |
Residential proxy rotation (195+ countries) | No | No | Yes |
Screenshot and PDF capture | No | Screenshot only | Yes — both |
OCR text extraction from images | No | No | Yes |
Cost per request | Free (but fails) | Free (but slow) | From $0.0002 |
How Does AlterLab Web Scraping Work?
AlterLab uses a multi-tier scraping architecture. It automatically selects the cheapest method capable of fetching each URL:
Curl ($0.0002/req) — Direct HTTP for static pages, RSS feeds, public APIs
HTTP ($0.0003/req) — TLS fingerprint rotation for moderately protected sites
Stealth ($0.002/req) — Browser impersonation for Cloudflare/DataDome-protected sites
Light JS ($0.0025/req) — Lightweight JS extraction from server-rendered HTML
Browser ($0.004/req) — Full headless Chromium for JavaScript-heavy SPAs
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.
Installation
Install in Claude Desktop / Claude Code
Add to your Claude config file (~/.claude.json for Claude Code, or Settings for Claude Desktop):
{
"mcpServers": {
"alterlab": {
"command": "npx",
"args": ["-y", "alterlab-mcp-server@latest"],
"env": {
"ALTERLAB_API_KEY": "sk_live_your_key_here"
}
}
}
}Install in Cursor
Add to .cursor/mcp.json in your project root:
{
"mcpServers": {
"alterlab": {
"command": "npx",
"args": ["-y", "alterlab-mcp-server@latest"],
"env": {
"ALTERLAB_API_KEY": "sk_live_your_key_here"
}
}
}
}Install in Windsurf
Add to Windsurf MCP settings (~/.codeium/windsurf/mcp_config.json):
{
"mcpServers": {
"alterlab": {
"command": "npx",
"args": ["-y", "alterlab-mcp-server@latest"],
"env": {
"ALTERLAB_API_KEY": "sk_live_your_key_here"
}
}
}
}Install via Smithery
npx -y @smithery/cli install alterlab-mcp-server --client claudeGet Your API Key
Sign up free — $1 free balance on signup
Go to Dashboard → API Keys and copy your key
Paste it into the
ALTERLAB_API_KEYfield in your MCP config
Tools
alterlab_scrape — Scrape Any Webpage
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.
"Scrape https://www.amazon.com/dp/B0BSHF7WHW and summarize the product"Parameter | Type | Default | Description |
| string | required | URL to scrape |
|
|
| Scraping mode |
| enum / string / enum / object |
| POST support (1.5x cost) and custom target headers |
|
|
| Output formats |
| object / string | — | LLM extraction (+$0.001) |
| enum | — |
|
| enum / string | — | BYOK LLM selection |
| boolean | — | Extraction behaviour |
| boolean / number / boolean | — | Response caching ( |
| boolean | | API default | Headless browser (forces Browser tier, $0.004) |
| boolean, string | — | Premium proxy (+$0.0002) and geo-targeting |
| boolean, boolean, string | — | Bring-your-own-proxy selection |
| boolean | — | Omit (recommended) = verify, fall back on invalid certs; |
| string | — | Selector / load-event waits |
| object[] (max 20) | — | Browser actions: |
| boolean | — | Add-ons (+$0.0002 / +$0.0004 / +$0.001) |
| boolean / 1-10 / boolean | — | Lazy-load handling |
| boolean | — | Rendering options |
| object | — | Filter for |
| UUID, object, object | — | Authenticated scraping |
| string, 300-7200 | — | Reuse cookies and exit IP across calls (paid plans) |
|
| — | Geo-targeting |
| object | — |
|
| object | — |
|
|
|
| Wait behaviour for long scrapes |
| number, number, boolean |
| Limits and raw output |
| boolean |
| Run a free cost estimate first |
Not exposed: source (dashboard tracking tag), sync (the tool is always synchronous), webhook_url (use alterlab_batch/alterlab_crawl webhooks). If a scrape outlives the ~85s synchronous window the tool returns a job_id; fetch it with alterlab_get_job.
alterlab_extract — Extract Structured Data
Extract structured fields from HTML, text or markdown content using pre-built profiles or custom JSON Schema. Returns clean JSON — ready for databases, spreadsheets, or downstream processing.
"Extract the product name, price, and rating from this Amazon page"Parameter | Type | Default | Description |
| string (max 500,000) | required | HTML, text or markdown you already have (this tool does not fetch a URL) |
|
|
| Type of |
| enum | — | Profile: |
| object | — | Custom JSON Schema for structured output |
| string | — | Natural language extraction instructions |
| enum / string | — | BYOK LLM selection |
| enum[] |
| Output formats |
| string, boolean | — | Context URL and provenance |
|
|
| Extraction result cache |
To scrape and extract in one step, use alterlab_scrape with extraction_schema.
Extraction profiles:
Product — name, price, currency, rating, reviews, availability, images, description
Article — title, author, published date, body text, featured image
Job Posting — title, company, location, salary, description, requirements
FAQ — question-answer pairs
Recipe — ingredients, instructions, prep time, servings
Event — name, date, location, description, organizer
alterlab_screenshot — Screenshot Any Page
Take a full-page screenshot of any URL. Returns a PNG image directly in the conversation — no URLs to copy, no files to download.
"Take a screenshot of our landing page at https://alterlab.io"Parameter | Type | Default | Description |
| string | required | URL to screenshot |
| string | — | CSS selector to wait for before capture |
| enum |
|
|
| number |
| Timeout in seconds (1-300) |
| boolean, string | — | Premium proxy and geo-targeting |
| UUID, object | — | Screenshot pages behind a login |
|
| — | Geo-targeting |
alterlab_estimate_cost — Estimate Before You Scrape
Check how much a scrape will cost before running it. Returns the predicted tier, cost per request, and confidence level.
"How much would it cost to scrape linkedin.com?"Parameter | Type | Default | Description |
| string | required | URL to estimate |
| enum |
| Scraping mode |
|
|
| POST costs 1.5x |
| boolean | |
| Include JS rendering cost |
| boolean |
| Include proxy cost / BYOP discount |
| boolean | — | Include add-on cost |
alterlab_get_job — Fetch an Async Job
Fetch the status and result of a scrape that returned a job_id (a scrape that outlived the synchronous wait window). Parameter: job_id (string, required).
alterlab_check_balance — Check Your Credits
Check your account balance, total deposited, and total spent. No parameters needed.
"Check my AlterLab balance"alterlab_list_sessions — List Stored Sessions
List all stored sessions for authenticated scraping. Sessions contain cookies for specific domains, allowing you to scrape content behind login walls.
"List my stored sessions"alterlab_create_session — Create a Session
Create a new stored session with cookies from a logged-in browser. The session is stored securely and can be reused across multiple scrape requests.
"Create an Amazon session with these cookies: session-id=abc123, session-token=xyz789"Parameter | Type | Default | Description |
| string | required | Human-readable name (e.g., "My Amazon Account") |
| string | required | Domain (e.g., "amazon.com") |
| boolean | required | Must be |
|
| — | Cookies as key-value pairs or |
|
| — | Custom headers (e.g. a User-Agent) |
| string | — | Expiry (ISO 8601) and notes |
| boolean |
| Health checks and notifications |
| UUID, boolean | — | Organization sharing |
alterlab_validate_session — Validate a Session
Check whether a stored session is still active and its cookies are valid.
"Is my Amazon session still valid?"Parameter | Type | Default | Description |
| string (UUID) | required | Session ID to validate |
alterlab_delete_session — Delete a Session
Permanently delete a stored session and its cookies.
"Delete session abc-123-def"Parameter | Type | Default | Description |
| string (UUID) | required | Session ID to delete |
Authenticated Scraping
AlterLab MCP supports scraping pages that require authentication. This enables AI agents to access user-specific content like order histories, account dashboards, and member-only pricing.
How It Works
Create a session with cookies from a logged-in browser using
alterlab_create_sessionScrape authenticated pages by passing the
session_idtoalterlab_scrapeManage sessions with list, validate, and delete tools
Example: Check Amazon Prime Pricing
User: "What's my Prime member price for this product?"
Claude: [calls alterlab_list_sessions → finds Amazon session]
Claude: [calls alterlab_scrape with session_id for authenticated pricing]
Claude: "The Prime member price is $24.99 (public price: $34.99)"Inline Cookies vs Stored Sessions
Stored sessions (
session_id): Best for repeated access to the same domain. Create once, reuse across requests.Inline cookies (
cookies): Best for one-off authenticated requests where you don't need to save the session.
What Can You Do with AlterLab MCP?
Research and Analysis
Ask Claude to scrape and analyze websites in real-time:
"Scrape the top 5 results from this Google search and summarize them"
"Extract all product prices from this Amazon category page"
"Compare the pricing pages of these 3 competitors"
Code Generation with Real Data
Let Cursor or Windsurf fetch live data while building:
"Scrape this API documentation page and generate TypeScript types from it"
"Extract the color palette from this website and create a Tailwind config"
"Screenshot this design and recreate it in React"
Content and SEO
Use Claude to analyze content at scale:
"Scrape this blog post and suggest improvements for SEO"
"Extract all FAQ entries from this help center and create a structured dataset"
"Compare our landing page to the competitor's and identify gaps"
Monitoring and Alerts
Build agentic workflows that watch the web:
"Check if this product is back in stock"
"Scrape this page daily and alert me when the price drops below $50"
"Monitor this job board for new senior engineering positions"
Pricing — Pay-As-You-Go Web Scraping
No subscriptions. No monthly minimums. Add balance and use it whenever you need it.
Base Scraping Costs
Tier | Method | Cost per Request | Use Case |
Curl | Direct HTTP | $0.0002 | Static pages, RSS feeds, public APIs |
HTTP | TLS fingerprinting | $0.0003 | Sites with basic bot detection |
Stealth | Browser impersonation | $0.002 | Cloudflare, DataDome, PerimeterX protected sites |
Light JS | JSON extraction | $0.0025 | Server-rendered pages needing structured data |
Browser | Headless Chromium | $0.004 | Full JavaScript SPAs (React, Angular, Vue) |
Optional Add-Ons
Add-On | Extra Cost | Description |
JavaScript Rendering | forces Browser tier | No separate add-on: |
PDF Generation | +$0.0004 | PDF of the rendered page |
LLM Extraction / Embeddings | +$0.001 |
|
POST requests | x1.5 |
|
Own proxy (BYOP) | -20% |
|
Search | $0.001 / $0.004 | duckduckgo / google and bing engines |
Screenshot Capture | +$0.0002 | Full-page PNG screenshot |
Premium Proxy | +$0.0002 | Geo-targeted residential proxy (195+ countries) |
OCR Text Extraction | +$0.001 | Extract text from images on the page |
$1 = 5,000 light scrapes. New accounts get $1 free balance on signup.
Environment Variables
Variable | Required | Default | Description |
| Yes | — | Your API key (get one free) |
| No |
| API base URL (for self-hosted or development) |
Frequently Asked Questions
How do I add web scraping to Claude, Cursor, or Windsurf?
Install the AlterLab MCP server. For Claude Code, run claude mcp add alterlab -- npx -y alterlab-mcp-server@latest 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.
Can Claude scrape websites that are behind Cloudflare or anti-bot protection?
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.
What is an MCP server and how does it work with Claude?
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 23 tools: scrape, extract, screenshot, crawl, search, map, batch scraping, session management, beta features, and more.
How is AlterLab different from Firecrawl, ScrapingBee, or Apify MCP servers?
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.).
Can I scrape Amazon, Walmart, and other e-commerce sites from Claude?
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.
Can Cursor scrape documentation and generate code from it?
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.
Does AlterLab MCP work with JavaScript-heavy sites (React, Angular, Vue)?
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.
What output format is best for AI and LLM context windows?
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.
Is there rate limiting?
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).
Can I use this MCP server for large-scale scraping?
Yes. For parallel scraping, use alterlab_batch to scrape up to 100 URLs in a single request — much faster than sequential calls. For crawling entire domains, use alterlab_crawl. You can also build agentic workflows that scrape many URLs sequentially, or use the n8n integration for workflow automation.
Error Handling
The MCP server returns helpful error messages with suggested next actions:
Error | What Happens | Suggested Action |
401 Unauthorized | Invalid API key | Check |
402 Insufficient Credits | Balance too low | Run |
403 Forbidden | Site blocked the request | Try |
429 Rate Limited | Too many requests | Automatic retry with backoff |
504 Gateway Timeout | Scrape took too long | Increase |
Agentic Workflows — AI Agents That Scrape the Web
AlterLab MCP turns any AI agent into a web-capable agent. Instead of relying on stale training data, your agent can fetch live information from any website during execution.
Use Cases for AI Agents
Research agents — scrape multiple sources, cross-reference facts, generate reports with citations
Data pipeline agents — extract structured product/pricing/job data on a schedule
Competitive intelligence — monitor competitor pages, track pricing changes, detect new features
Content generation — scrape real data to ground LLM output in facts, not hallucinations
Lead enrichment — scrape company websites to enrich CRM records with live data
Compliance monitoring — check regulatory pages, terms of service, and policy updates
Compatible AI Frameworks and Clients
Works with any tool that supports MCP (Model Context Protocol):
Claude Desktop / Claude Code — Anthropic's AI assistant
Cursor — AI-powered code editor
Windsurf — Codeium's AI IDE
Cline — VS Code AI assistant
GitHub Copilot — via MCP configuration
Custom agents — any framework using the MCP SDK (Python, TypeScript, Go)
n8n — workflow automation via n8n-nodes-alterlab
Contributing
git clone https://github.com/RapierCraft/alterlab-mcp-server.git
cd alterlab-mcp-server
npm install
npm run buildSupport
License
Available Tools
26 toolsalterlab_batchAInspect
Start an asynchronous batch job for a large URL set (up to 100 per call) and poll for results later. Use when a normal fetch returns 403/429, a bot-protection challenge page, a CAPTCHA, or an empty JavaScript shell. Each URL can have its own mode, formats and extraction_schema. Returns a batch_id immediately; results are available from GET /api/v1/batch/{batch_id}.
| Name | Required | Description | Default |
|---|---|---|---|
| urls | Yes | List of URLs to scrape (max 100) | |
| export | No | Export batch results to a storage integration when the batch finishes | |
| session_id | No | UUID of a stored session applied to every URL in the batch (see alterlab_list_sessions) | |
| webhook_url | No | Webhook URL to receive batch.completed event when all jobs finish | |
| extraction_prompt | No | Batch-level natural language extraction instruction | |
| extraction_schema | No | Batch-level JSON schema for structured extraction applied to every URL | |
| extraction_profile | No | Batch-level pre-built extraction profile applied to every URL | |
| extraction_provider | No | Batch-level BYOK LLM provider for extraction |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does reasonably well: it discloses that the operation is asynchronous, returns immediately with a batch_id rather than results, and that results must be polled from GET /api/v1/batch/{batch_id}. Gaps remain around partial-failure behavior, cost implications, and rate limits for a 100-URL job.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with the core action and scope, then usage trigger, then per-URL nuance, then return semantics. No filler and nothing redundant given the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an async tool with 8 params, heavy nesting, and no output schema, the description covers the essential lifecycle (submit → get batch_id → poll). It is incomplete on how to retrieve results with the sibling status tool, what a completed batch payload looks like, and any webhook/export caveats beyond what the schema already says.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 8 top-level parameters and the deeply nested per-URL options. The description adds only that per-URL mode, formats, and extraction_schema are honored independently, which is marginally useful but largely restates the schema structure. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Start an asynchronous batch job for a large URL set') plus a scope cap (up to 100 per call) and the return shape (batch_id). It does not, however, distinguish itself from the sibling alterlab_batch_scrape, which sounds functionally identical, so the agent cannot disambiguate from the description alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides an explicit trigger condition — use when a normal fetch returns 403/429, a bot-protection page, a CAPTCHA, or an empty JS shell — which is real usage guidance. But it never names an alternative tool, gives no when-not conditions, and offers no routing between this tool, alterlab_batch_scrape, and alterlab_batch_status.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_batch_scrapeAInspect
Scrape 2-20 URLs in parallel and get every result back in one synchronous call, no polling required. Use when a normal fetch returns 403/429, a bot-protection challenge page, a CAPTCHA, or an empty JavaScript shell. Failed URLs report their error; successful ones return content. For 20+ URLs use alterlab_batch.
| Name | Required | Description | Default |
|---|---|---|---|
| urls | Yes | List of URLs to scrape (max 20). All results are returned synchronously. | |
| formats | No | Output formats applied to every URL. 'markdown' is best for LLM consumption. | |
| timeout | No | Request timeout in seconds per URL (1-300). | |
| render_js | No | Render JavaScript using headless browser for all URLs. Required for JS-heavy sites. Forces tier 4 ($0.004/req). | |
| use_proxy | No | Route all requests through premium proxy (+$0.0002/req). | |
| max_concurrent | No | Maximum number of URLs to scrape in parallel (1-10, default 3). Higher values finish faster but consume more concurrent connections. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description must carry behavior, and it does disclose the key traits: fully synchronous execution with no polling, and per-URL error containment so one failure does not abort the batch. It omits auth requirements, rate limits, and cost behavior beyond what the schema already states.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with the core capability, then trigger conditions, then return semantics, then the escape hatch to the sibling. No filler sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter tool with no annotations and no output schema, the description covers execution model, failure handling, and tool selection adequately. It could say more about the shape of the aggregated response (e.g. result ordering or whether errors are inline per URL), which matters for a batch call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the parameters are self-documenting, so baseline is 3. The description reinforces parallelism but does not explain formats, timeout, or proxy trade-offs beyond the schema, and its '2-20 URLs' range slightly conflicts with the schema's minItems of 1.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (scrape URLs) plus the defining scope: parallel, synchronous, 2-20 URLs, no polling. It differentiates itself from the sibling alterlab_batch by count threshold, so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use triggers (403/429, bot-protection challenge, CAPTCHA, empty JS shell) and names the alternative for the out-of-scope case (20+ URLs → alterlab_batch). Both the selection condition and the exclusion are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_batch_statusAInspect
Poll the status and results of a submitted batch. Call this after alterlab_batch to check progress and retrieve scraped content. Status values: processing, completed, failed, partially_failed. When completed, results contains the content for each URL.
| Name | Required | Description | Default |
|---|---|---|---|
| batch_id | Yes | Batch ID returned by alterlab_batch |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses return behavior with status values and when results are returned. No annotations are provided, so the description carries the burden; it covers the key behaviors for a polling tool, though it doesn't explicitly state non-destructiveness.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences that are well-structured, front-loading the purpose and then providing status values and results. No redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequately covers usage, status values, and result content. No output schema, but the description explains what to expect. For a simple polling tool with one parameter, this is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter (batch_id) with 100% schema description coverage. The tool description reinforces that the batch_id comes from alterlab_batch, but adds no new semantic detail beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (poll) and resource (status and results of a submitted batch), and it distinguishes from siblings by specifying that this is to be used after alterlab_batch.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says to call after alterlab_batch, providing clear usage context. Does not mention when not to use or alternatives, but the context is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_check_balanceAInspect
Check your AlterLab account balance, status, and credit usage. Call this before expensive operations (batch scrapes, large crawls) to verify sufficient funds. Returns current balance in dollars, balance status (healthy/low/critical/exhausted), total deposited, and total spent. For a full spending breakdown by time window and top domains, use alterlab_get_usage instead. No parameters required — uses your API key for identification.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Describes exactly what is returned (balance, status, deposited, spent) and notes that no parameters are required, using API key for identification. No annotations exist, so description fully covers behavioral traits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no wasted words, front-loaded with purpose, and includes a tip and an alternative reference.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description fully explains return values and provides context about when to use and alternative tools, making it complete for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters in schema, and the description explicitly states 'No parameters required — uses your API key for identification,' adding value beyond the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool checks account balance, status, and credit usage. It distinguishes from sibling alterlab_get_usage by noting that tool provides a full spending breakdown.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises calling before expensive operations like batch scrapes or large crawls. Also provides an alternative tool (alterlab_get_usage) for detailed breakdown, giving both when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_crawlAInspect
Crawl a whole website and return the content of every page, for RAG, indexing or site-wide export. Use when you need many pages from one domain; for one URL use alterlab_scrape, for a URL list only use alterlab_map. Works on JavaScript-heavy and protected sites, with anti-bot handling on every page. Returns a crawl_id immediately; results are available from GET /api/v1/crawl/{crawl_id}.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Start URL for the crawl | |
| cache | No | Serve pages from the response cache when available | |
| delay | No | Politeness delay between page requests, in seconds (0-30) | |
| budget | No | Per-path page budget: glob pattern -> max pages, most specific pattern wins, '*' is the catch-all (e.g., {"/products/*": 100, "/blog/*": 50, "*": 5}). max_pages stays the hard cap. | |
| formats | No | Output formats for each scraped page. 'markdown' is best for LLM consumption. 'json_v2' returns a structured section tree (headings + content blocks). 'rag' returns chunked text optimized for retrieval-augmented generation. 'raw' returns the raw response body without extraction. 'content' returns body_markdown + content_hash + images + links for AI/KB pipelines. | |
| headers | No | Custom HTTP headers injected into every page request during the crawl (e.g., {"Authorization": "Bearer token"}). Maximum 50 headers. | |
| sitemap | No | Sitemap mode: include (default), skip (link extraction only), only (sitemap URLs only) | include |
| storage | No | Where crawl results are stored (API default 'redis') | |
| timeout | No | Per-page request timeout in seconds (1-300) | |
| webhook | No | Detailed webhook config (events, signing secret, headers); use instead of webhook_url | |
| priority | No | Crawl prioritisation hints (keywords, boost_patterns, demote_patterns) | |
| wait_for | No | CSS selector to wait for before extracting each page (e.g., '#main-content'). Applied to all pages in the crawl. | |
| cache_ttl | No | Cache TTL in seconds (60-86400). Requires cache=true | |
| max_depth | No | Maximum link-following depth from start URL (0 = start page only) | |
| max_pages | No | Maximum number of pages to scrape | |
| render_js | No | Render JavaScript on crawled pages. true=always (Tier 4, $0.004/page), false=never, auto=smart detection per page | |
| use_proxy | No | Route all crawl requests through premium proxy (+$0.0002/page) | |
| extraction | No | Set to 'auto' for automatic page-type detection and extraction without a user-defined schema. Mutually exclusive with extraction_schema. | |
| screenshot | No | Capture a screenshot of each crawled page (requires render_js) | |
| webhook_url | No | Webhook URL to notify on crawl completion | |
| sitemap_path | No | Explicit path to the sitemap file (e.g., '/sitemap_index.xml'). Use when the sitemap is not at the standard /sitemap.xml location. | |
| cost_controls | No | Cost controls for the entire crawl — cap total spend or pin the scraping tier | |
| force_refresh | No | Bypass the cache and fetch every page fresh | |
| depth_strategy | No | Link-discovery strategy (API default 'sequential') | |
| respect_robots | No | Respect robots.txt rules for the target domain | |
| change_tracking | No | Track page changes between crawls | |
| max_concurrency | No | Maximum concurrent pages to scrape simultaneously | |
| exclude_patterns | No | Glob patterns — skip URLs whose path matches any (e.g., ['/tag/*', '/author/*']) | |
| extraction_model | No | Per-request LLM model override in provider-specific format (e.g. 'gpt-4o', 'claude-opus-4-5-20251101', 'llama3-70b-8192'). Overrides the model saved in your BYOK key settings for this request only. | |
| include_patterns | No | Glob patterns — only scrape URLs whose path matches at least one (e.g., ['/blog/*', '/docs/*']) | |
| extraction_schema | No | JSON schema for structured extraction on each page | |
| extraction_profile | No | Pre-defined extraction profile applied to every crawled page. 'auto' detects the page type automatically. | |
| include_subdomains | No | Include links to subdomains during discovery | |
| extraction_provider | No | BYOK LLM provider used for extraction on each page | |
| extraction_template | No | Alias for extraction_profile (mutually exclusive with it) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and delivers the single most important behavioral fact: it is asynchronous, returning a crawl_id immediately with results fetched from GET /api/v1/crawl/{crawl_id} — which changes how an agent must sequence follow-up calls (likely to alterlab_crawl_status). It also discloses anti-bot/JS handling across all pages. It omits cost/politeness implications and that the job can be cancelled, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences with zero filler: purpose and use cases first, sibling routing second, operational return contract last. Appropriate size for a 35-parameter tool and front-loaded with the scope constraint.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a very complex, high-parameter, async tool with no annotations and no output schema, the description covers the essentials: what it produces, async polling contract, and scope. Remaining gaps (cost tier behavior, robots.txt default, cancellation) are all documented in the schema or handled by sibling tools such as alterlab_crawl_status and alterlab_crawl_cancel.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% across all 35 parameters, so the schema already documents url, budget, cost_controls, extraction, and the rest in detail. The description adds no parameter-level meaning beyond the implicit note that anti-bot handling applies per page. Baseline 3 is correct when the schema does this much work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Crawl a whole website and return the content of every page') plus the intended use cases (RAG, indexing, site-wide export). It explicitly distinguishes itself from alterlab_scrape (one URL) and alterlab_map (URL list only), so an agent can route between the three without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use ('many pages from one domain') and when-not-to-use, naming both alternatives and the conditions that select them. This is textbook sibling routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_crawl_cancelAInspect
Cancel an ongoing crawl and refund unused pre-debited credits. Already-scraped pages are kept and available via alterlab_crawl_status. Cancelled crawls cannot be resumed.
| Name | Required | Description | Default |
|---|---|---|---|
| crawl_id | Yes | Crawl ID to cancel |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, description carries full burden. It discloses key behaviors: cancellation stops crawling, refunds credits, keeps already-scraped pages (via alterlab_crawl_status), and prohibits resumption. Sufficiently transparent for a simple cancellation tool, though auth or rate limits are not mentioned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste. First sentence captures primary action and refund. Second sentence adds important details about persistence and non-resumability. Efficient and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and no output schema or annotations, the description fully covers what the tool does, what happens to scraped pages, and what cannot be done afterwards. No significant gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter 'crawl_id' with schema coverage 100%. Description adds no extra meaning beyond the schema's 'Crawl ID to cancel'. Baseline 3 is appropriate as schema already documents the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'cancel', resource 'ongoing crawl', and additional action 'refund unused pre-debited credits'. Distinguishes from sibling tools like alterlab_crawl and alterlab_crawl_status by specifying cancellation and refund behavior.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description implies when to use (to stop a crawl) and notes that cancelled crawls cannot be resumed, but does not explicitly state when not to use or mention alternative tools. Provides context about already-scraped pages but lacks exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_crawl_statusAInspect
Poll the status and results of an ongoing or completed crawl. Call this after alterlab_crawl to check progress and retrieve scraped pages. Status values: queued, running, completed, failed, cancelled. When completed, results contains the scraped page content.
| Name | Required | Description | Default |
|---|---|---|---|
| crawl_id | Yes | Crawl ID returned by alterlab_crawl |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It explains polling behavior and that results are present when completed, but does not specify idempotency, whether results persist after first read, or any side effects. Adequate but not deep.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no wasted words. Front-loaded with purpose, then adds details on status values and output. Excellent conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, so description explains that 'results contains the scraped page content' when completed. Lists status values. Could mention if results are paginated or size limits, but complete enough for a simple status poll tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline 3. Description adds context by noting crawl_id is returned by alterlab_crawl, helping the agent understand the parameter source. Slight improvement over bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it polls status and results of a crawl, explicitly naming the action and resource. It distinguishes itself from siblings like alterlab_crawl and alterlab_crawl_cancel by specifying it is the follow-up call for progress checking.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Call this after alterlab_crawl' and lists status values, providing clear context. Does not include explicit when-not-to-use or alternative tools, but given sibling set, this is the only status poll for crawls.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_create_sessionAInspect
Create a new stored session for authenticated scraping. Provide cookies from a logged-in browser session to enable scraping behind login walls. The session is stored securely and can be reused across multiple scrape requests via session_id. Requires consent=true (explicit GDPR consent to store the cookies); optional headers, expires_at, notes, auto_refresh/notification flags and organization sharing are supported.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Human-readable name for this session (e.g., 'My Amazon Account') | |
| notes | No | Free-text notes about this session | |
| domain | Yes | Domain this session is for (e.g., 'amazon.com') | |
| shared | No | Share the session with organization members immediately (API default false) | |
| consent | Yes | Explicit GDPR consent from the account owner to store these session cookies. Must be true — the API rejects session creation with CONSENT_REQUIRED otherwise. Only set true after the user has agreed to AlterLab storing their cookies. | |
| cookies | No | Cookies for authentication. Cookies as a {name: value} object (e.g. {"session-id": "abc123"}) or as a list (max 100) of cookie objects with metadata: {name, value, domain?, path?, secure?, httpOnly?, sameSite?, expires?}. | |
| headers | No | Custom headers sent with this session (e.g., a User-Agent or Authorization header) | |
| expires_at | No | Session expiry in ISO 8601 format (e.g., '2026-12-31T23:59:59Z') | |
| organization_id | No | Organization to assign the session to (org admins only) | |
| notify_on_failure | No | Notify when session validation fails (API default true) | |
| auto_refresh_enabled | No | Enable proactive expiry detection and health checks (API default true) | |
| notify_before_expiry | No | Notify when the session is about to expire (API default true) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full load and does it well: it discloses that cookies are stored securely, that the session is reusable via session_id, that consent=true is mandatory (API rejects with CONSENT_REQUIRED), and that org sharing and auto-refresh/notification flags exist. It doesn't cover what happens on failed validation beyond the notify flag, but this is solid behavioral context for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core action and the login-wall use case before prerequisites. The final sentence is a somewhat dense enumeration of optional parameters, but nothing is wasted and it remains scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter mutation tool with no annotations and no output schema, the description covers purpose, prerequisites, consent semantics, and reusability. It implies the returned session_id but doesn't explicitly state what the caller gets back or any failure modes beyond consent — a minor gap, though no output schema exists to fill it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all 12 parameters (including nested cookie metadata and the important consent semantics) are already documented in the schema. The description echoes the consent requirement and enumerates optional features, adding orientation but no syntax or meaning beyond the schema — the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource ('Create a new stored session') and immediately scopes it to authenticated scraping, which cleanly separates it from the session-management siblings (list/get/validate/update/refresh/delete). The purpose and the persistence model are unambiguous without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the trigger condition clearly: use this when you need to scrape behind login walls and can supply cookies from a logged-in browser session. It also surfaces the consent prerequisite. It stops short of naming explicit alternatives or when-not-to-use cases (e.g. using a one-off cookie header on alterlab_scrape instead), so it's strong but not complete routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_delete_sessionAInspect
Delete a stored session. This permanently removes the session and its cookies. Use this when a session is no longer needed or has been compromised.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | UUID of the session to delete |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Since no annotations are provided, the description carries full weight. It discloses that the deletion is permanent and removes cookies, which are critical behavioral traits. No contradictory or missing safety cues.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long, front-loaded with the main action, and contains no superfluous words. Every sentence adds value: purpose and usage context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter, no output schema, and no annotations, the description is complete. It covers action, effect, and appropriate use case, leaving no obvious gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already fully describes the single parameter (session_id as a UUID). The description does not add new semantic information beyond the schema; it simply references the session. With 100% schema coverage, the baseline score is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Delete a stored session' and emphasizes permanence, distinguishing it from sibling session tools like create, get, update, or refresh. The verb 'delete' and resource 'session' are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear when-to-use guidance: 'Use this when a session is no longer needed or has been compromised.' This is explicit context, though it does not formally exclude alternatives. However, the purpose is sufficiently distinct from siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_disable_beta_featureAInspect
Opt out of a beta feature on your AlterLab account. This operation is idempotent — calling it when not opted in returns success. GA (generally available) features cannot be disabled.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | URL-safe slug of the beta feature to opt out of (e.g., 'v2-extraction', 'stealth-v3'). Use alterlab_list_my_beta_features to see your currently active slugs. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses idempotency ('calling it when not opted in returns success') and the limitation on GA features. It does not mention side effects, auth needs, or error behavior, but the operation is simple enough that this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, front-loading the purpose, then adding idempotency and constraint. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter and no output schema, the description covers purpose, idempotency, and a constraint. It also references a sibling tool for listing slugs. Minor gaps: no mention of return values or error states, but overall adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% since the parameter 'slug' already has a description. The tool description adds no new semantic detail beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Opt out of a beta feature on your AlterLab account.' It uses a specific verb-resource pair and distinguishes from sibling tools like 'alterlab_enable_beta_feature' by noting that GA features cannot be disabled.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides context by mentioning idempotency and the constraint that GA features cannot be disabled. It also directs users to 'alterlab_list_my_beta_features' to find valid slugs. However, it does not explicitly contrast with enabling or list all alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_enable_beta_featureAInspect
Opt in to a beta feature on your AlterLab account. Beta features are experimental capabilities available before general release. This operation is idempotent — calling it when already opted in returns success. Use alterlab_list_beta_features to discover available feature slugs.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | Yes | URL-safe slug of the beta feature to opt in to (e.g., 'v2-extraction', 'stealth-v3'). Use alterlab_list_beta_features to see available slugs. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description mentions idempotency and experimental nature, but does not disclose potential side effects, permissions required, or reversibility (e.g., via 'alterlab_disable_beta_feature'). More behavioral context would be beneficial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description consists of two concise sentences with no wasted words. It front-loads the action and efficiently adds necessary context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with no output schema, the description adequately covers purpose, parameter guidance, and a related sibling. It could mention the response format, but it's not essential.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description adds value by providing an example slug format and referencing the list endpoint for discovery, going beyond the schema's minimal description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Opt in to a beta feature'), the resource ('AlterLab account'), and distinguishes it from siblings like 'disable_beta_feature' and 'list_beta_features'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description advises to use 'alterlab_list_beta_features' to discover available slugs, guiding when to use the tool. It does not explicitly state when not to use it, but the context is sufficient for a simple opt-in tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_estimate_costAInspect
Estimate the credit cost of scraping a URL before you run it. Use when cost matters or before a large job; no credits are charged. Returns the predicted tier, estimated cost and confidence. Full machine-readable price list: GET https://alterlab.io/api/v1/pricing (public, no auth).
| Name | Required | Description | Default |
|---|---|---|---|
| ocr | No | Include the OCR add-on (+$0.001) | |
| url | Yes | URL to estimate scraping cost for | |
| mode | No | Scraping mode | auto |
| method | No | HTTP method. POST requests cost 1.5x the base tier price. | |
| formats | No | Output formats to include in the estimate. Passed to the API but does not currently affect the cost estimate — the endpoint uses URL-pattern heuristics only. 'markdown' is best for LLM consumption. 'json_v2' returns a structured section tree (headings + content blocks). 'rag' returns chunked text optimized for retrieval-augmented generation. 'raw' returns the raw response body without extraction. 'content' returns body_markdown + content_hash + images + links for AI/KB pipelines. | |
| render_js | No | Enable JS rendering (forces Tier 4 minimum, $0.004 — no separate add-on charge) | |
| use_proxy | No | Include premium proxy cost (+$0.0002) | |
| screenshot | No | Include the screenshot add-on (+$0.0002) | |
| generate_pdf | No | Include the PDF add-on (+$0.0004) | |
| use_own_proxy | No | Price the request with your own proxy integration (20% BYOP discount) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full behavioral burden. It usefully discloses that nothing is billed and that the return carries tier, cost and confidence, but it says nothing about auth requirements for the tool itself, rate limits, or whether the estimate can diverge from the actual charge beyond the heuristic caveat buried in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short sentences, front-loaded with the purpose and the safety fact, then the return shape, then an escape hatch to the public pricing endpoint. Nothing is redundant with the schema or the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter tool with no annotations and no output schema, the description covers purpose, cost safety, and the shape of the response. What is missing is the unit/naming of the returned cost figure and whether the estimate is authoritative, but the core calling decisions are covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and each parameter already documents its own cost impact (POST 1.5x, render_js forces Tier 4, add-on prices), so the description adds no parameter meaning of its own. The baseline 3 applies: the schema does all the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (estimate) and resource (credit cost of scraping a URL) plus the ordering constraint 'before you run it', which distinguishes it from the sibling alterlab_scrape. An agent can tell immediately this is a dry-run pricing tool rather than an execution tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear trigger ('when cost matters or before a large job') and the key reassurance 'no credits are charged', which is exactly the condition an agent needs to decide whether it is safe to call. It does not explicitly name a sibling alternative, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_extractAInspect
Extract structured data (prices, product info, contact details, custom fields) as JSON from HTML, text or markdown you already hold. Use when you have content and need specific fields. Does not fetch a URL: to fetch and extract in one step, use alterlab_scrape with extraction_schema.
| Name | Required | Description | Default |
|---|---|---|---|
| cache | No | Cache control for LLM extraction results. 'auto': return cached result if available (default). 'skip': bypass cache lookup, always call LLM (result is still stored). 'only': return cached result or 404 if not cached — never calls the LLM. | auto |
| content | Yes | Raw content to extract from — HTML, text, or markdown. Bring your own pre-fetched content; this endpoint does NOT scrape a URL. | |
| formats | No | Output formats for content transformation. 'json' is best for structured extraction. 'content' returns filtered/cleaned content. 'raw' returns the unprocessed response body. | |
| evidence | No | Include field provenance/evidence for extracted fields (which part of the content each field came from) | |
| cache_ttl | No | TTL for caching this extraction result, in seconds. Defaults to server setting (3600s). Max 86400s (24 hours). | |
| source_url | No | Original URL of the content (for context only — not fetched). Helps the extractor understand the content's domain. | |
| content_type | No | Type of the provided content | html |
| extraction_model | No | Per-request LLM model override in provider-specific format (e.g. 'gpt-4o', 'claude-opus-4-5-20251101', 'llama3-70b-8192'). Overrides the model saved in your BYOK key settings for this request only. | |
| extraction_prompt | No | Natural language instructions for LLM extraction (e.g., 'Extract all product prices and ratings'). Charged at LLM extraction rate when provided. | |
| extraction_schema | No | Custom JSON Schema for extraction. Fields are mapped from content. Overrides extraction_profile when provided | |
| extraction_profile | No | Pre-defined extraction profile. 'product' extracts price/title/reviews, 'article' extracts title/author/body, etc. 'auto' detects the page type. Mutually exclusive with extraction_template. | |
| extraction_provider | No | LLM provider to use for extraction. Selects the matching BYOK key registered at /dashboard/settings/llm-keys. When omitted, the most recently used registered key is used. | |
| extraction_template | No | Shorthand alias for extraction_profile — selects the same pre-built schema template. Mutually exclusive with extraction_profile. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full burden. It does disclose the key behavioral boundary (no URL fetching, bring-your-own content) and that output is JSON. It omits operationally important traits: that extraction is billed at an LLM rate unless a schema is supplied, that a BYOK provider key is required, and that results are cached by default.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the purpose and output type, followed by the usage rule and the negative boundary. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 13-parameter, nested-schema tool with no output schema, the description still communicates the essential contract and routes to the correct sibling. The remaining gap is that nothing warns about LLM cost, BYOK key dependency, or default caching, which an agent calling this blindly could get wrong.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the 13 parameters are richly documented (cache modes, TTL, provider, profile/template aliasing, evidence provenance). The description adds essentially nothing beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Extract structured data ... as JSON from HTML, text or markdown') with concrete example field types, and explicitly contrasts itself with the fetching sibling. An agent can distinguish it from alterlab_scrape immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit use condition ('Use when you have content and need specific fields'), an explicit exclusion ('Does not fetch a URL'), and names the alternative tool plus its parameter (alterlab_scrape with extraction_schema) for the fetch-and-extract case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_get_jobAInspect
Fetch the status and result of an asynchronous scrape job by job_id. Use this when alterlab_scrape or alterlab_screenshot returns a job_id instead of content (a long-running scrape that outlived the synchronous wait window). Status values: queued, processing, succeeded, failed, rejected (rejected = not processed due to insufficient balance; stop polling and check the balance). Polling is free; do not re-run the scrape, which would be billed again.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | Job ID returned by an async or downgraded scrape (alterlab_scrape reports it when a scrape outlives the ~85s synchronous window) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose key behavioral traits: the polling cost model ('Polling is free'), the billing consequence of misuse, and the meaning of each terminal status, including 'rejected' due to insufficient balance. It does not cover permissions/auth or the shape of the returned result, leaving some gaps for an unannotated tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the purpose, then the usage condition, then the status semantics and the cost warning. Every sentence earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description compensates by enumerating the five status values and clarifying the terminal 'rejected' state. For a single-parameter polling tool, nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and there is a single parameter, so the schema already documents job_id fully. The description still adds value by explaining the provenance of the ID (an async or downgraded scrape outliving the ~85s synchronous window), reinforcing the schema's own note.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Fetch the status and result of an asynchronous scrape job by job_id') and explicitly distinguishes itself from the siblings that generate jobs (alterlab_scrape, alterlab_screenshot). An agent can route correctly without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger condition ('when alterlab_scrape or alterlab_screenshot returns a job_id instead of content') and a clear directive for the terminal case ('rejected ... stop polling and check the balance'). It also warns against the wrong action (do not re-run the scrape, which would be billed again), which is strong when-to/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_get_sessionAInspect
Get detailed information about a specific stored session. Returns session status, cookie names, usage statistics (total requests, success rate), expiry info, and notes. Use this to inspect a session before deciding to validate, refresh, or delete it.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | UUID of the session to retrieve |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It describes the data returned (status, cookie names, usage stats, expiry, notes) and implies a read operation. It does not mention side effects, auth, or rate limits, but for a simple get operation this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences: first states function and return, second gives usage guidance. No wasted words, front-loaded with key information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given one required parameter, full schema coverage, no output schema, and clear sibling context (CRUD for sessions), the description fully covers what an agent needs to know to use this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter (session_id) with 100% schema coverage (UUID format). The description adds context for why the parameter is needed ('inspect a session') beyond the schema, providing extra value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get detailed information about a specific stored session' and lists specific return fields (status, cookie names, usage statistics, expiry info, notes). It distinguishes from sibling tools by saying 'inspect a session before deciding to validate, refresh, or delete it.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use this to inspect a session before deciding to validate, refresh, or delete it.' This gives clear context for when to use. It doesn't explicitly exclude scenarios, but the guidance is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_get_usageAInspect
Get account usage for the current billing period — balance, credits consumed this period, account tier and entitlement source. Use this to track spend against your plan; use alterlab_check_balance for deposit and spend totals. No parameters required — uses your API key for identification.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose the identification mechanism ('uses your API key') and the exact data returned, which is the main behavioral concern for a zero-argument read tool. It stops short of explicitly declaring the operation read-only or noting any rate limiting, so it is strong but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three front-loaded sentences: purpose and payload first, then the sibling routing rule, then the no-parameter/auth note. Every sentence adds information and none is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by listing the returned fields. For a simple no-argument read tool with a named alternative, nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes no parameters, so there is nothing to disambiguate; the description reinforces this with 'No parameters required.' Baseline for a zero-parameter tool is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get account usage for the current billing period') and enumerates the returned fields (balance, credits consumed, tier, entitlement source). It is clearly distinguishable from the sibling alterlab_check_balance, which is named explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit usage rule: use this to track spend against the plan, and use alterlab_check_balance for deposit and spend totals. The selecting condition between the two sibling tools is stated rather than inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_list_beta_featuresAInspect
List all public beta and GA features available on AlterLab, with your current opt-in state for each. Beta features require opting in; GA features are available to all users. Use alterlab_enable_beta_feature to opt in to any beta feature that interests you.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, description transparently states it lists features and opt-in state, implying read-only behavior. Does not disclose performance or rate limits, but sufficient for safe use.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences, front-loaded with key action and result. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and no output schema, the description fully covers what the tool does and its output (list with opt-in state). Refers to sibling for next action.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters exist; schema coverage is 100%. Description adds nothing about parameters, but baseline 4 is appropriate for zero-parameter tools.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it lists all public beta and GA features with opt-in state, using specific verb 'list' and resource 'features'. It differentiates from sibling 'alterlab_enable_beta_feature' by mentioning that tool for opting in.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context: use to view features and opt-in state, and suggests 'alterlab_enable_beta_feature' for opting in. Does not explicitly contrast with 'alterlab_list_my_beta_features', but overall guidance is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_list_my_beta_featuresAInspect
List all beta and GA features currently active on your account — a compact slug list for quick checks. Includes all GA features plus any beta features you have opted in to. Use this to verify which features are available before making API calls that require them.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; description reveals it is a read operation returning a compact slug list. Notes that list includes GA features and opted-in beta features. Lacks details on pagination or format but sufficient for a simple list.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each with clear purpose: action, content, usage guidance. No redundant words; highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless, no-output-schema tool, description fully covers what it does, what it returns, and why to use it. Context with sibling tools is sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters; schema coverage is 100% trivially. Description adds meaning by explaining the composition of the list (GA + opted-in beta features), which is beyond schema structure.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb 'list' and resource 'beta and GA features active on your account'. It differentiates from sibling 'alterlab_list_beta_features' by specifying scope is only active features on the user's account.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use: 'to verify which features are available before making API calls that require them'. Does not explicitly name alternatives but context implies use sibling for full list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_list_sessionsAInspect
List all stored sessions for authenticated scraping. Sessions contain cookies for specific domains, allowing you to scrape content that requires login (e.g., Amazon order history, LinkedIn profiles). Use the returned session_id with alterlab_scrape to scrape authenticated pages.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It clearly describes the read-only listing behavior ('List all stored sessions') and adds context about authenticated scraping. No side effects are mentioned, which is appropriate for a listing tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with verb and resource, no filler. Every word adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and no output schema, the description is complete enough. It explains the purpose of sessions (cookies, login) and the workflow with alterlab_scrape. A minor gap: no mention of return format or pagination, but for a list tool this is sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has no parameters (0 params, 100% coverage). The description adds no parameter info, which is acceptable since none exist. Baseline 4 for zero parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List all stored sessions for authenticated scraping' with a specific verb and resource. It distinguishes from sibling tools like alterlab_create_session, alterlab_delete_session, and alterlab_get_session.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: to obtain session_id for alterlab_scrape. Implicitly excludes other operations (create, delete, get) via sibling names. Could add explicit when-not or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_mapAInspect
List every URL on a site via sitemap parsing and link extraction, without fetching page content. Use before alterlab_crawl or alterlab_batch to choose pages; to read the content itself use alterlab_crawl. Works on JavaScript-heavy and protected sites.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Starting URL for site discovery | |
| search | No | Query to filter and rank discovered URLs by relevance (returns relevance_score per URL) | |
| sitemap | No | Sitemap handling: include (parse sitemaps + follow links), skip (links only), only (sitemap URLs only) | include |
| max_depth | No | Link-following depth (0 = start page + sitemap only) | |
| max_pages | No | Maximum URLs to discover | |
| sitemap_path | No | Explicit path to the sitemap file (e.g., '/sitemap_index.xml'). Use when the sitemap is not at the standard /sitemap.xml location. | |
| respect_robots | No | Respect robots.txt directives | |
| exclude_patterns | No | Glob patterns — exclude URLs whose path matches any (e.g., ['/tag/*', '/page/*']) | |
| include_metadata | No | Fetch title and meta description for each URL via lightweight GET (adds latency) | |
| include_patterns | No | Glob patterns — only include URLs whose path matches at least one (e.g., ['/docs/*']) | |
| include_subdomains | No | Include URLs from subdomains of the target domain |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full behavioral burden. It does disclose a meaningful trait — no page content is fetched — and hints at resilience on "JavaScript-heavy and protected sites," but it says nothing about robots.txt defaults, rate limits, URL caps, or what the result set looks like. There is also no output schema to cover the return format.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences with zero filler; the core action is front-loaded and the routing advice follows immediately. Every clause carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 11-parameter discovery tool with no annotations and no output schema, the description covers purpose, ordering relative to siblings, and the key no-content-fetch behavior. It stops short of describing the returned URL structure or default limits, which is a minor gap given the fully documented schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all 11 parameters (search ranking, sitemap modes, depth, patterns, subdomains) are already documented in the schema. The description adds only the high-level notion of sitemap parsing plus link extraction and does not clarify interactions between parameters. Baseline 3 applies when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource ("List every URL on a site") and the mechanism ("sitemap parsing and link extraction"), plus an explicit scope boundary ("without fetching page content"). An agent can immediately distinguish this from alterlab_crawl, which it names directly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives sequencing guidance ("Use before alterlab_crawl or alterlab_batch to choose pages") and names the alternative for the other job ("to read the content itself use alterlab_crawl"). The when-to-use / when-not-to-use split is stated outright rather than inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_refresh_sessionAInspect
Refresh a session by rotating its cookies and resetting failure counters. This is the preferred way to update cookies after re-authenticating in your browser. The session status is reset to active. If cookies are omitted, only the failure counters are reset.
| Name | Required | Description | Default |
|---|---|---|---|
| cookies | No | New cookies to replace the old ones. If omitted, only failure counters are reset. Cookies as a {name: value} object (e.g. {"session-id": "abc123"}) or as a list (max 100) of cookie objects with metadata: {name, value, domain?, path?, secure?, httpOnly?, sameSite?, expires?}. | |
| headers | No | Updated custom headers to include with the session | |
| session_id | Yes | UUID of the session to refresh |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does well: it discloses the mutation (cookie rotation), the side effect of resetting status to active, and the fallback behavior when cookies are omitted. It omits auth/permission requirements and reversibility, so not a full 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core action, then usage context, then the edge-case behavior. No filler and each sentence adds distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 3-param mutation tool with nested objects and no annotations or output schema, the description adequately conveys what changes and when. It could still note authentication prerequisites or what the refreshed session returns, keeping it short of 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all three parameters (including the cookies conditional and format). The description largely restates the omit-cookies behavior that the schema already encodes, adding little beyond the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (refresh) and resource (session) and enumerates the concrete effects: rotating cookies, resetting failure counters, and setting status to active. The phrase 'preferred way to update cookies' implicitly distinguishes it from sibling tools like alterlab_update_session, letting an agent tell them apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a clear when-to-use trigger ('after re-authenticating in your browser') and the conditional path when cookies are omitted. It stops short of naming alternatives or explicit exclusions, so it clears the 4 bar but not the 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_scrapeAInspect
Fetch one URL and return its content as clean markdown, text, HTML, or JSON. Use when a normal fetch returns 403/429, a bot-protection challenge page, a CAPTCHA, or an empty JavaScript shell. Website challenges and JavaScript-heavy pages are handled automatically by a 5-tier system that starts at the cheapest tier that works and escalates only when needed. Returns markdown by default, ready for LLM context. Supports GET and POST via method, structured extraction via extraction_schema or extraction_prompt, and cost caps via cost_controls. Supports browser actions via actions, plus screenshot and generate_pdf; the response includes action_results, one entry per action with index, type, success, error, result (evaluate) and screenshot_url (screenshot actions).
| Name | Required | Description | Default |
|---|---|---|---|
| ocr | No | Extract text from images using OCR (+$0.001) | |
| url | Yes | URL to scrape | |
| body | No | Request body for POST requests. For GraphQL: JSON string with 'query' and optional 'variables' fields (e.g., '{"query": "{ user { id name } }"}').For REST APIs: JSON-encoded payload string. For form submissions: URL-encoded key=value pairs (e.g., 'name=Alice&email=alice@example.com'). Omit for GET requests. | |
| mode | No | Scraping mode: auto (recommended), html, js (headless browser), pdf, or ocr | auto |
| cache | No | Enable caching for this request. When true, repeat requests with identical parameters may return cached results. Only use for idempotent requests (GET pages, read-only POSTs). | |
| method | No | HTTP method for the request. Default GET (standard page scraping). Use POST for GraphQL endpoints, form submissions, and REST API calls. When using POST, provide body with the request payload. POST costs 1.5x base tier price. | GET |
| actions | No | Browser automation actions run in order after page load (max 20, requires render_js=true). Failed actions are skipped without aborting the sequence. Results are returned in action_results. Each action has a 'type': wait, wait_for, click, fill, press, scroll, infinite_scroll, screenshot, evaluate. | |
| cookies | No | Inline cookies as key-value pairs for authenticated scraping (e.g., {"session_token": "abc123"}). Use this for one-off requests; use session_id for reusable sessions. | |
| formats | No | Output formats. 'markdown' is best for LLM consumption. 'json_v2' returns a structured section tree (headings + content blocks). 'rag' returns chunked text optimized for retrieval-augmented generation. 'raw' returns the raw response body without extraction. 'content' returns body_markdown + content_hash + images + links for AI/KB pipelines. | |
| headers | No | Custom HTTP headers to send to the target URL. Hop-by-hop headers (Connection, Transfer-Encoding, Host, etc.) are not allowed. | |
| timeout | No | Request timeout in seconds (1-300) | |
| evidence | No | Include provenance/evidence snippets alongside extracted fields. Each extracted value will include the source text passage it was derived from. Requires extraction_schema or extraction_prompt. | |
| location | No | Geo-targeting parameters for localized content scraping. Controls proxy country routing, Accept-Language header, and browser locale. | |
| template | No | DEPRECATED alias for extraction_template, kept for backward compatibility. Sent to the API as extraction_template; prefer extraction_template. | |
| wait_for | No | CSS selector to wait for before extracting content (e.g., '#main-content') | |
| cache_ttl | No | Cache TTL in seconds (60–86400). Defaults to 3600 (60 min) when cache=true. Requires cache=true. | |
| fail_fast | No | Fail immediately if the page requires an expensive tier (browser/captcha) instead of auto-escalating. Shorthand for cost_controls.fail_fast. Returns an error with the required tier instead of upgrading. | |
| render_js | No | Render JavaScript using a headless browser (forces Tier 4 minimum, $0.004/req — no separate add-on charge). Required for JS-heavy sites. Set to 'auto' for smart detection (probes each page, only renders JS-heavy pages with a browser — saves 30-60% on mixed sites). | |
| use_proxy | No | Route through AlterLab's premium proxy (+$0.0002). Helps bypass geo-restrictions and anti-bot | |
| embeddings | No | Chunk the scraped text and embed it with OpenAI models (+$0.001 per page). Set enabled=true; model, chunk_size (64-8191) and chunk_overlap (0-2048) are optional. | |
| pdf_format | No | Output format for mode='pdf' extraction (API default 'markdown') | |
| screenshot | No | Capture a full-page screenshot (+$0.0002, requires render_js). The URL is returned as screenshot_url. Use alterlab_screenshot to get the image inline. | |
| session_id | No | UUID of a stored session for authenticated scraping. Use alterlab_list_sessions to find available sessions. The session's cookies will be injected into the request. | |
| wait_until | No | Page load event to wait for before extracting (networkidle, domcontentloaded or load; API default networkidle) | |
| prefer_cost | No | Optimize for lowest cost — try cheaper tiers first before escalating. Shorthand for cost_controls.prefer_cost. Mutually exclusive intent with prefer_speed. | |
| sync_policy | No | Synchronous wait policy. 'auto' (default) may return an early 202 with a job_id for predicted T3/T4 jobs; 'wait_until_deadline' keeps the connection open until the terminal result or the safe sync deadline (~85s). | |
| block_images | No | Block image downloads during browser rendering. Reduces proxy bandwidth and speeds up scrapes. Only effective with render_js=true. | |
| content_type | No | Content-Type header for the request body. Defaults to 'application/json' when body is provided. Use 'application/graphql' for raw GraphQL queries. Use 'application/x-www-form-urlencoded' for HTML form submissions. Requires body to be set. | |
| generate_pdf | No | Generate a PDF of the rendered page (+$0.0004, requires render_js) | |
| ocr_language | No | Tesseract language code for OCR (API default 'eng') | |
| prefer_speed | No | Optimize for speed — skip to a reliable tier immediately instead of escalating from Tier 1. Shorthand for cost_controls.prefer_speed. Mutually exclusive intent with prefer_cost. | |
| scroll_count | No | Number of scroll iterations when scroll_to_load is enabled (1-10, API default 3) | |
| cost_controls | No | Fine-grained cost and tier controls. Use to cap spending, pin a tier, or trade off cost vs speed. | |
| enable_scroll | No | Force scrolling for lazy-load images. true: always scroll (+5-10s), false: never scroll, omit: auto (scroll unless social media site). | |
| force_refresh | No | Bypass the cache and always fetch a fresh copy of the page. Use when you need real-time content and a cached result would be stale. | |
| proxy_country | No | ISO country code for proxy geo-targeting (e.g., 'US', 'DE'). Requires use_proxy=true | |
| use_own_proxy | No | Use your own proxy integration (bring-your-own-proxy) instead of the system proxy. BYOP requests get a 20% discount on the tier price. | |
| estimate_first | No | Run a cost estimate before scraping and include it in the response. Adds one lightweight API call (~50ms) with no credit charge. The estimated tier, cost, and confidence are prepended to the scrape result. Useful for unfamiliar or potentially expensive sites — see cost before committing. | |
| filter_content | No | Apply quality filtering to extracted content. When false (default), returns all parsed content without quality thresholds (lossless mode). When true, filters low-quality boilerplate. | |
| scroll_to_load | No | Scroll page to trigger lazy-loaded content (requires render_js). Performs explicit viewport-height scrolls to load dynamic content. Adds ~2-3s latency. | |
| section_filter | No | Filter for the json_v2 section tree. Only applies when 'json_v2' is in formats. | |
| sticky_session | No | Sticky-session handle. Scrapes that pass the same value reuse the cookie jar captured on the first call and, best-effort, the same exit IP (~10 min). Alphanumeric, '-' and '_' only. Requires a paid plan (growth tier or above). | |
| wait_condition | No | Wait condition for JS rendering: domcontentloaded, networkidle or load | |
| include_iframes | No | Inline iframe content into the main document (free, requires render_js). Same-origin iframes are read directly; cross-origin iframes are marked but not fetched. | |
| session_headers | No | Inline auth headers sent to the target (e.g. Authorization: Bearer ...). Merged with the stored session's headers when session_id is also set. | |
| extraction_model | No | Per-request LLM model override in provider-specific format (e.g. 'gpt-4o', 'claude-opus-4-5-20251101', 'llama3-70b-8192'). Overrides the model saved in your BYOK key settings for this request only. | |
| include_raw_html | No | Include raw HTML in the response alongside formatted content | |
| use_system_proxy | No | Override your default proxy integration and use AlterLab's system proxy for this request. | |
| extraction_prompt | No | Natural language extraction instruction. Describes what fields to extract from the page. Mutually exclusive with extraction_schema. Example: "Extract the product name, price, and availability". | |
| extraction_schema | No | JSON schema for structured extraction. The API extracts fields matching this schema from the scraped page using LLM (+$0.001). Result is returned in extraction_result. Example: { "title": "string", "price": "number", "in_stock": "boolean" } | |
| extraction_profile | No | Pre-built extraction schema template. auto: detect best template (API default). product: e-commerce product details. article: news/blog article fields. job_posting: job listing fields. faq: FAQ entries. recipe: recipe ingredients and instructions. event: event details. ecommerce_homepage: homepage product listings. directory_listing: directory/listing page entries. Mutually exclusive with extraction_template. | |
| flatten_shadow_dom | No | Flatten Shadow DOM roots into regular DOM for extraction (free, requires render_js). | |
| max_response_bytes | No | Soft cap on raw response body size in bytes. When the downloaded HTML exceeds this value it is truncated before extraction. Default: 5 MB (5242880). Set to 0 for no limit. Maximum: 50 MB (52428800). Useful for very large pages where you only need the beginning of the content. | |
| promote_schema_org | No | Use Schema.org JSON-LD/Microdata as the primary structured-data source when present (API default true). Promotes machine-readable metadata embedded in the page over LLM extraction. Most effective on e-commerce, recipe, and news article pages. | |
| sticky_session_ttl | No | Sticky-session cookie-jar lifetime in seconds (300-7200, API default 1800). Ignored unless sticky_session is set. | |
| extraction_provider | No | LLM provider to use for extraction. Selects the matching BYOK key registered at /dashboard/settings/llm-keys. When omitted, the most recently used registered key is used automatically. Requires extraction_schema or extraction_prompt. | |
| extraction_template | No | Shorthand alias for extraction_profile — selects the same pre-built template. Mutually exclusive with extraction_profile. | |
| proxy_integration_id | No | Specific proxy integration ID to use (requires use_own_proxy=true) | |
| remove_cookie_banners | No | Remove cookie consent banners from HTML before content extraction (free; the API default is true) | |
| skip_tls_verification | No | TLS certificate verification for the target. Omit (recommended): certificates are verified, and if the site's own certificate is invalid (expired, self-signed, wrong hostname, incomplete chain) the page is still fetched without verification. true skips verification from the start. false always requires a valid certificate, so sites with an invalid certificate fail. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the burden and does substantial work: it discloses the 5-tier escalation model ('starts at the cheapest tier that works and escalates only when needed'), the default output format, and the shape of the returned action_results array with per-action fields. It does not mention the async path (early 202 with job_id) or failure behavior, both of which matter for a tool this expensive to run.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded correctly: purpose first, then the trigger condition, then capability summary. Five dense sentences with no filler. The final sentence on action_results is somewhat captured by the schema, but it earns its place as a return-value cue given there is no output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 60-parameter tool with no annotations and no output schema, the description covers the main happy path but skips significant surface area an agent would need: the async job flow, session/auth reuse via session_id, caching/force_refresh interaction, and error semantics. It is adequate to make a first call correctly, not adequate to use the tool well across its full feature set.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 60 parameters, including tier costs, mutually exclusive extraction options, and action types. The description only names clusters (method, extraction_schema/extraction_prompt, cost_controls, actions, screenshot, generate_pdf) without adding interpretation. That is the definition of the baseline case: helpful as orientation, but redundant with the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a concrete verb and resource plus the return formats: 'Fetch one URL and return its content as clean markdown, text, HTML, or JSON.' The scope (single URL, multi-format) is unambiguous. It stops short of the top score because it never names the adjacent tools (alterlab_crawl, alterlab_extract, alterlab_batch_scrape) that an agent must choose between.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a sharp trigger condition: use when a normal fetch returns 403/429, a challenge page, a CAPTCHA, or an empty JS shell. That is a real decision rule an agent can apply. It lacks an explicit when-not clause and never points to alterlab_extract for pure structured extraction or alterlab_crawl for multi-page work, leaving sibling routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_screenshotAInspect
Capture a full-page PNG screenshot of one URL, an image rather than text content. Use when a normal fetch returns 403/429, a bot-protection challenge page, a CAPTCHA, or an empty JavaScript shell. Works on anti-bot-protected sites, rendered in a real headless browser. Use wait_for to wait for an element and wait_until to control load timing. Pass actions (for example dismiss_consent or evaluate) to prepare the page; the screenshot is captured after they run and action_results is returned.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | URL to take a screenshot of | |
| cookies | No | Inline cookies for a one-off authenticated screenshot | |
| timeout | No | Request timeout in seconds (1-300, API default 90) | |
| location | No | Geo-targeting parameters for localized content scraping. Controls proxy country routing, Accept-Language header, and browser locale. | |
| wait_for | No | CSS selector to wait for before taking screenshot | |
| use_proxy | No | Route through AlterLab's premium proxy (+$0.0002) | |
| session_id | No | UUID of a stored session, to screenshot a logged-in page | |
| wait_until | No | Page load event to wait for before screenshot | networkidle |
| proxy_country | No | ISO country code for proxy geo-targeting. Requires use_proxy=true |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does good work on the rendering model ('real headless browser', anti-bot handling) and on operation ordering (actions run before capture). However, it never says what the response actually contains as an image (base64? URL? how large?), and it instructs the agent to 'pass actions' with 'action_results' returned — neither of which exists in the input schema, which would mislead an agent into a failed call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded and dense: purpose in sentence one, failure triggers in sentence two, timing and ordering after. The final sentence about actions/action_results is the only bloat, and it is also the one passage that is factually wrong about the tool's signature.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 9 parameters, nested objects, no annotations and no output schema, the description should at minimum say what a caller receives back for the screenshot and note the auth/session options. It covers the tricky timing and anti-bot behavior well but leaves the return value, the cookie/session path, and the geo/proxy options entirely to the schema, and references a phantom actions parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the description mainly restates what the schema already documents for wait_for and wait_until. Worse, the only parameter-level detail it adds — the 'actions' object and 'action_results' return — is not in the schema at all (additionalProperties: false), so it adds noise rather than meaning, while cookies, session_id, location, proxy_country and timeout get no coverage in the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb and resource — capture a full-page PNG screenshot of one URL — and immediately disambiguates output type ('an image rather than text content'), which separates it from text-returning siblings like alterlab_scrape and alterlab_extract. An agent can pick this tool without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit triggering conditions: normal fetch returning 403/429, a bot-protection challenge, a CAPTCHA, or an empty JavaScript shell. That is a named alternative (plain fetch) plus the exact failure conditions that should route the agent here, with no guessing required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_searchAInspect
Search the web and get structured results (URLs, titles, snippets). Use when you have a question or topic but no URL yet; follow up with alterlab_scrape to read a page, or set scrape_results=true to read every result in one call. Use domain to restrict to one site and time_range to filter by recency.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Result page number (1-indexed). Page 2 returns results 11-20, etc. | |
| query | Yes | Search query (max 500 characters) | |
| domain | No | Restrict results to a specific domain (applied as site: prefix, e.g. 'docs.example.com') | |
| engine | No | Search engine (API default duckduckgo). duckduckgo costs $0.001/query; google and bing use browser rendering and cost $0.004/query. | |
| country | No | ISO 3166-1 alpha-2 country code for geo-targeted results (e.g., 'US', 'GB', 'DE') | |
| formats | No | Output formats when scrape_results=true | |
| language | No | Language code for results (e.g., 'en', 'fr', 'de') | |
| time_range | No | Filter results by recency | |
| num_results | No | Number of results to return (1-30) | |
| safe_search | No | Safe search filtering to exclude adult content from results (API default true). Set false to disable. | |
| scrape_results | No | If true, scrape each result page and include content in response. Each page is billed at its scraping tier cost in addition to the base search fee. | |
| extraction_schema | No | JSON schema for structured extraction when scrape_results=true |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full behavioral burden. It does disclose the return shape and that scrape_results=true fetches every result's page in one call, but says nothing about cost implications, rate limits, or failure behavior — notable gaps for a tool whose schema advertises per-engine and per-page billing. The workflow disclosure is useful but partial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with purpose then routing then modifiers, with zero filler. The final sentence on domain and time_range largely duplicates the schema and is the one line that does not fully earn its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter tool with no annotations and no output schema, the description covers the core search-vs-scrape decision well. However it is silent on pagination, the extraction_schema/formats pair, cost tradeoffs between engines, and billing when scrape_results=true — meaningful gaps given the schema's breadth.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so parameter documentation is already handled and 3 is the baseline. The description's mentions of domain and time_range only restate what the schema states more precisely (site: prefix, recency enum), adding no new semantics beyond the scrape_results workflow pointer.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Search the web') and immediately specifies the return shape (URLs, titles, snippets). It explicitly contrasts with the sibling alterlab_scrape ('no URL yet... follow up with alterlab_scrape'), so an agent can route between search and scrape without inspecting either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the selecting condition ('when you have a question or topic but no URL yet') and the alternative to use otherwise, plus a second mode (scrape_results=true) that bypasses a separate scrape call. Both the when-to-use and the escalation path are stated rather than inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_update_sessionAInspect
Update a stored session's properties. You can change the name, rotate cookies, update custom headers, set a new expiration, or add notes. When cookies are provided, they replace ALL existing cookies (not merged). Use this instead of delete+recreate when you need to rotate credentials.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | New name for the session | |
| notes | No | Notes or description for this session | |
| cookies | No | New cookies — replaces ALL existing cookies. Cookies as a {name: value} object (e.g. {"session-id": "abc123"}) or as a list (max 100) of cookie objects with metadata: {name, value, domain?, path?, secure?, httpOnly?, sameSite?, expires?}. | |
| headers | No | New custom headers — replaces ALL existing headers | |
| expires_at | No | New expiration date in ISO 8601 format (e.g., '2026-12-31T23:59:59Z') | |
| session_id | Yes | UUID of the session to update | |
| notify_on_failure | No | Enable or disable the validation-failure notification | |
| auto_refresh_enabled | No | Enable or disable proactive expiry detection and health checks | |
| notify_before_expiry | No | Enable or disable the before-expiry notification |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It does add one genuinely important destructive trait — cookies 'replace ALL existing cookies (not merged)' — which an agent must know. However, it says nothing about permissions, whether the update is partial, the fate of unspecified headers, or reversibility, so the disclosure is helpful but incomplete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the purpose, then the mutable fields, then the critical replace-semantics caveat and the usage recommendation. Every sentence earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 9-parameter mutation tool with no annotations and no output schema, the description omits the notification/auto-refresh/health-check parameters entirely and never states whether the operation is partial or full-replace across all fields. The cookie caveat helps, but enough behavioral context is missing that it is only minimally adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 9 parameters, including the cookie replace-all semantics and the notification/auto-refresh booleans. The description restates a subset of fields (name, notes, headers, expiration) without adding format or constraint detail beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb (update) plus resource (stored session) with an enumerated list of mutable properties (name, cookies, headers, expiration, notes). It distinguishes itself from the delete+recreate pattern and is clearly separable from siblings like get_session, list_sessions, or refresh_session.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete when-to-use rule: 'Use this instead of delete+recreate when you need to rotate credentials.' That is stronger than implied usage, but it never mentions the closely related refresh_session or create_session siblings, so routing among the session-lifecycle tools is only partially resolved.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
alterlab_validate_sessionAInspect
Validate whether a stored session is still active and its cookies are valid. Run this before scraping if you suspect a session may have expired. Returns the session status and a reason if invalid.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | UUID of the session to validate |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that it checks session activity and cookie validity, returns status and reason if invalid. No annotations provided, so description carries burden; no side effects mentioned but validation is inherently read-only.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the main action, no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Adequately covers purpose, usage context, and return information for a simple validation tool with one parameter and no output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter (session_id) with 100% schema description coverage. The description does not add meaningful detail beyond what the schema already provides (UUID for session). Baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states validation of session activity and cookie validity. Distinguishes from sibling tools like create, delete, refresh, get by focusing solely on checking status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Run this before scraping if you suspect a session may have expired,' providing clear context for use. No explicit exclusions but implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
13 tool updates
v1.9.0- Changed
alterlab_batch30 fields changed- added
Input schema / properties / exportAdded value: +{ + "additionalProperties": false, + "description": "Export batch results to a storage integration when the batch finishes", + "properties": { + "format": { + "description": "Export file format (API default jsonl)", + "enum": [ + "jsonl", + "csv", + "json" + ], + "type": "string" + }, + "integration_id": { + "description": "ID of a storage integration (S3/R2/GCS) configured in the dashboard", + "type": "string" + }, + "prefix": { + "description": "Object key prefix for exported files", + "maxLength": 500, + "type": "string" + } + }, + "required": [ + "integration_id" + ], + "type": "object" +} - added
Input schema / properties / extraction_profileAdded value: +{ + "description": "Batch-level pre-built extraction profile applied to every URL", + "enum": [ + "auto", + "product", + "article", + "job_posting", + "faq", + "recipe", + "event" + ], + "type": "string" +} - added
Input schema / properties / extraction_promptAdded value: +{ + "description": "Batch-level natural language extraction instruction", + "maxLength": 2000, + "type": "string" +} - added
Input schema / properties / extraction_providerAdded value: +{ + "$ref": "#/properties/urls/items/properties/extraction_provider", + "description": "Batch-level BYOK LLM provider for extraction" +} - added
Input schema / properties / extraction_schemaAdded value: +{ + "additionalProperties": {}, + "description": "Batch-level JSON schema for structured extraction applied to every URL", + "type": "object" +} - added
Input schema / properties / session_idAdded value: +{ + "description": "UUID of a stored session applied to every URL in the batch (see alterlab_list_sessions)", + "format": "uuid", + "type": "string" +} - added
Input schema / properties / urls / items / properties / advancedAdded value: +{ + "additionalProperties": false, + "description": "Advanced scrape options for this URL (render_js, use_proxy, use_own_proxy, actions, session_id, cookies, skip_tls_verification, sticky_session, ...). Same fields as the alterlab_scrape parameters of the same name.", + "properties": { + "actions": { + "description": "Browser automation actions run in order after page load (max 20, requires render_js=true). Failed actions are skipped without aborting the sequence. Results are returned in action_results. Each action has a 'type': wait, wait_for, click, fill, press, scroll, infinite_scroll, screenshot, evaluate.", + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "milliseconds": { + "maximum": 30000, + "minimum": 100, + "type": "integer" + }, + "selector": { + "description": "CSS selector to wait for visibility", + "maxLength": 500, + "type": "string" + }, + "type": { + "const": "wait", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "selector": { + "maxLength": 500, + "type": "string" + }, + "timeout": { + "description": "Timeout in ms (default 10000)", + "maximum": 30000, + "minimum": 1000, + "type": "integer" + }, + "type": { + "const": "wait_for", + "type": "string" + } + }, + "required": [ + "type", + "selector" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "selector": { + "maxLength": 500, + "type": "string" + }, + "type": { + "const": "click", + "type": "string" + } + }, + "required": [ + "type", + "selector" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "selector": { + "maxLength": 500, + "type": "string" + }, + "type": { + "const": "fill", + "type": "string" + }, + "value": { + "maxLength": 5000, + "type": "string" + } + }, + "required": [ + "type", + "selector", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "key": { + "description": "Key to press, e.g. 'Enter', 'Tab', 'Escape'", + "maxLength": 50, + "type": "string" + }, + "type": { + "const": "press", + "type": "string" + } + }, + "required": [ + "type", + "key" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "amount": { + "description": "Viewport heights to scroll", + "maximum": 20, + "minimum": 1, + "type": "integer" + }, + "direction": { + "enum": [ + "down", + "up" + ], + "type": "string" + }, + "type": { + "const": "scroll", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "delay": { + "description": "Delay between scrolls in ms", + "maximum": 5000, + "minimum": 200, + "type": "integer" + }, + "end_selector": { + "description": "Stop scrolling when this selector appears", + "maxLength": 500, + "type": "string" + }, + "max_scrolls": { + "maximum": 50, + "minimum": 1, + "type": "integer" + }, + "type": { + "const": "infinite_scroll", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "full_page": { + "type": "boolean" + }, + "type": { + "const": "screenshot", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "script": { + "description": "JavaScript to run in the page (max 5120 chars). Network APIs (fetch, XMLHttpRequest, WebSocket) and dynamic code execution (eval, Function) are blocked.", + "maxLength": 5120, + "type": "string" + }, + "type": { + "const": "evaluate", + "type": "string" + } + }, + "required": [ + "type", + "script" + ], + "type": "object" + } + ] + }, + "maxItems": 20, + "type": "array" + }, + "block_images": { + "description": "Block image downloads during browser rendering. Reduces proxy bandwidth and speeds up scrapes. Only effective with render_js=true.", + "type": "boolean" + }, + "cookies": { + "additionalProperties": { + "type": "string" + }, + "description": "Inline cookies as key-value pairs for authenticated scraping (e.g., {\"session_token\": \"abc123\"}). Use this for one-off requests; use session_id for reusable sessions.", + "type": "object" + }, + "flatten_shadow_dom": { + "description": "Flatten Shadow DOM roots into regular DOM for extraction (free, requires render_js).", + "type": "boolean" + }, + "generate_pdf": { + "description": "Generate a PDF of the rendered page (+$0.0004, requires render_js)", + "type": "boolean" + }, + "include_iframes": { + "description": "Inline iframe content into the main document (free, requires render_js). Same-origin iframes are read directly; cross-origin iframes are marked but not fetched.", + "type": "boolean" + }, + "markdown": { + "description": "Extract content as Markdown for this URL (free)", + "type": "boolean" + }, + "ocr": { + "description": "Extract text from images using OCR (+$0.001)", + "type": "boolean" + }, + "proxy_country": { + "description": "ISO country code for proxy geo-targeting (e.g., 'US', 'DE'). Requires use_proxy=true", + "type": "string" + }, + "proxy_integration_id": { + "description": "Specific proxy integration ID to use (requires use_own_proxy=true)", + "type": "string" + }, + "remove_cookie_banners": { + "description": "Remove cookie consent banners from HTML before content extraction (free; the API default is true)", + "type": "boolean" + }, + "render_js": { + "anyOf": [ + { + "type": "boolean" + }, + { + "const": "auto", + "type": "string" + } + ], + "description": "Render JavaScript using a headless browser (forces Tier 4 minimum, $0.004/req — no separate add-on charge). Required for JS-heavy sites. Set to 'auto' for smart detection (probes each page, only renders JS-heavy pages with a browser — saves 30-60% on mixed sites)." + }, + "screenshot": { + "description": "Capture a full-page screenshot of this URL (+$0.0002, requires render_js)", + "type": "boolean" + }, + "scroll_count": { + "description": "Number of scroll iterations when scroll_to_load is enabled (1-10, API default 3)", + "maximum": 10, + "minimum": 1, + "type": "integer" + }, + "scroll_to_load": { + "description": "Scroll page to trigger lazy-loaded content (requires render_js). Performs explicit viewport-height scrolls to load dynamic content. Adds ~2-3s latency.", + "type": "boolean" + }, + "section_filter": { + "additionalProperties": false, + "description": "Filter for the json_v2 section tree. Only applies when 'json_v2' is in formats.", + "properties": { + "content_only": { + "type": "boolean" + }, + "exclude_content_types": { + "items": { + "type": "string" + }, + "type": "array" + }, + "min_content_blocks": { + "minimum": 0, + "type": "integer" + } + }, + "type": "object" + }, + "session_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Inline auth headers sent to the target (e.g. Authorization: Bearer ...). Merged with the stored session's headers when session_id is also set.", + "type": "object" + }, + "session_id": { + "description": "UUID of a stored session for authenticated scraping. Use alterlab_list_sessions to find available sessions. The session's cookies will be injected into the request.", + "format": "uuid", + "type": "string" + }, + "skip_tls_verification": { + "description": "TLS certificate verification for the target. Omit (recommended): certificates are verified, and if the site's own certificate is invalid (expired, self-signed, wrong hostname, incomplete chain) the page is still fetched without verification. true skips verification from the start. false always requires a valid certificate, so sites with an invalid certificate fail.", + "type": "boolean" + }, + "sticky_session": { + "description": "Sticky-session handle. Scrapes that pass the same value reuse the cookie jar captured on the first call and, best-effort, the same exit IP (~10 min). Alphanumeric, '-' and '_' only. Requires a paid plan (growth tier or above).", + "maxLength": 128, + "type": "string" + }, + "sticky_session_ttl": { + "description": "Sticky-session cookie-jar lifetime in seconds (300-7200, API default 1800). Ignored unless sticky_session is set.", + "maximum": 7200, + "minimum": 300, + "type": "integer" + }, + "use_own_proxy": { + "description": "Use your own proxy integration (bring-your-own-proxy) instead of the system proxy. BYOP requests get a 20% discount on the tier price.", + "type": "boolean" + }, + "use_proxy": { + "description": "Route through AlterLab's premium proxy (+$0.0002). Helps bypass geo-restrictions and anti-bot", + "type": "boolean" + }, + "use_system_proxy": { + "description": "Override your default proxy integration and use AlterLab's system proxy for this request.", + "type": "boolean" + }, + "wait_condition": { + "description": "Wait condition for JS rendering: domcontentloaded, networkidle or load", + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / urls / items / properties / bodyAdded value: +{ + "description": "Request body for POST requests to this URL", + "type": "string" +} - removed
Input schema / properties / urls / items / properties / cache / defaultRemoved value: -false - added
Input schema / properties / urls / items / properties / content_typeAdded value: +{ + "description": "Content-Type of the POST body for this URL", + "enum": [ + "application/json", + "application/x-www-form-urlencoded", + "text/plain", + "application/graphql" + ], + "type": "string" +} - added
Input schema / properties / urls / items / properties / cost_controlsAdded value: +{ + "additionalProperties": false, + "description": "Cost and tier controls for this URL (max_tier, force_tier, max_credits, ...)", + "properties": { + "fail_fast": { + "description": "Return error instead of escalating to more expensive tiers on failure.", + "type": "boolean" + }, + "force_tier": { + "description": "Pin execution to this exact tier, bypassing escalation (1=curl $0.0002, 2=http $0.0003, 3=stealth $0.002, 3.5=lightjs $0.0025, 4=browser $0.004). Use to guarantee a specific engine is used regardless of site difficulty.", + "enum": [ + "1", + "2", + "3", + "3.5", + "4" + ], + "type": "string" + }, + "max_credits": { + "description": "Hard spending cap for this request in credits. Request fails if cost would exceed this.", + "exclusiveMinimum": 0, + "type": "number" + }, + "max_tier": { + "$ref": "#/properties/urls/items/properties/cost_controls/properties/force_tier", + "description": "Cap automatic escalation at this tier. Scrape will not escalate beyond it even if lower tiers fail. Cannot exceed force_tier when both are set. Combining render_js=true with a max_tier below 4 is rejected (render_js forces tier 4)." + }, + "prefer_cost": { + "description": "Optimize for cost — try cheaper tiers first, accept lower success probability.", + "type": "boolean" + }, + "prefer_speed": { + "description": "Optimize for speed — skip to the most reliable tier for this domain.", + "type": "boolean" + }, + "time_budget": { + "description": "Total wall-clock budget in seconds for the entire tier escalation sequence (5–300s). Escalation stops when remaining budget is insufficient for the next tier attempt.", + "maximum": 300, + "minimum": 5, + "type": "number" + } + }, + "type": "object" +} - added
Input schema / properties / urls / items / properties / extraction_profileAdded value: +{ + "description": "Pre-built extraction profile for this URL (mutually exclusive with extraction_template)", + "enum": [ + "auto", + "product", + "article", + "job_posting", + "faq", + "recipe", + "event", + "ecommerce_homepage", + "directory_listing" + ], + "type": "string" +} - added
Input schema / properties / urls / items / properties / extraction_promptAdded value: +{ + "description": "Natural language extraction instruction for this URL", + "maxLength": 2000, + "type": "string" +} - added
Input schema / properties / urls / items / properties / extraction_providerAdded value: +{ + "description": "BYOK LLM provider for extraction on this URL", + "enum": [ + "openai", + "anthropic", + "openrouter", + "groq" + ], + "type": "string" +} - added
Input schema / properties / urls / items / properties / extraction_templateAdded value: +{ + "$ref": "#/properties/urls/items/properties/extraction_profile", + "description": "Alias for extraction_profile (mutually exclusive with it)" +} - changed
Input schema / properties / urls / items / properties / formats / descriptionPrevious value: -"Output formats for this URL (overrides batch-level formats)"New value: +"Output formats for this URL. 'markdown' is best for LLM consumption. 'json_v2' returns a structured section tree (headings + content blocks). 'rag' returns chunked text optimized for retrieval-augmented generation. 'raw' returns the raw response body without extraction. 'content' returns body_markdown + content_hash + images + links for AI/KB pipelines." - changed
Input schema / properties / urls / items / properties / formats / items / enumPrevious value: -[ - "text", - "json", - "json_v2", - "html", - "markdown", - "rag" -]New value: +[ + "text", + "json", + "json_v2", + "html", + "markdown", + "rag", + "content", + "raw" +] - added
Input schema / properties / urls / items / properties / include_raw_htmlAdded value: +{ + "description": "Include raw HTML in the result for this URL", + "type": "boolean" +} - added
Input schema / properties / urls / items / properties / locationAdded value: +{ + "additionalProperties": false, + "description": "Geo-targeting for this URL (country, language)", + "properties": { + "country": { + "description": "ISO 3166-1 alpha-2 country code for geo-targeting (e.g., 'US', 'DE', 'JP'). Routes request through a proxy in the specified country.", + "maxLength": 2, + "minLength": 2, + "type": "string" + }, + "language": { + "description": "ISO 639-1 language code (e.g., 'en', 'de', 'ja'). Sets the Accept-Language header and browser locale.", + "maxLength": 5, + "minLength": 2, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / urls / items / properties / methodAdded value: +{ + "description": "HTTP method for this URL. POST costs 1.5x the base tier price.", + "enum": [ + "GET", + "POST" + ], + "type": "string" +} - removed
Input schema / properties / urls / items / properties / mode / defaultRemoved value: -"auto" - changed
Input schema / properties / urls / items / properties / mode / descriptionPrevious value: -"Scraping mode for this URL"New value: +"Scraping mode for this URL (API default auto)" - added
Input schema / properties / urls / items / properties / render_js / anyOfAdded value: +[ + { + "type": "boolean" + }, + { + "const": "auto", + "type": "string" + } +] - changed
Input schema / properties / urls / items / properties / render_js / descriptionPrevious value: -"Render JavaScript for this URL"New value: +"Shortcut for advanced.render_js for this URL" - removed
Input schema / properties / urls / items / properties / render_js / typeRemoved value: -"boolean" - removed
Input schema / properties / urls / items / properties / timeout / defaultRemoved value: -90 - changed
Input schema / properties / urls / items / properties / timeout / descriptionPrevious value: -"Timeout in seconds for this URL"New value: +"Timeout in seconds for this URL (1-300, API default 90)" - added
Input schema / properties / urls / items / properties / url / maxLengthAdded value: +2083 - changed
Input schema / properties / urls / items / properties / use_proxy / descriptionPrevious value: -"Use premium proxy for this URL"New value: +"Shortcut for advanced.use_proxy for this URL" - added
Input schema / properties / webhook_url / maxLengthAdded value: +2083
- Changed
alterlab_batch_scrape4 fields changed- changed
Input schema / properties / formats / items / enumPrevious value: -[ - "text", - "json", - "json_v2", - "html", - "markdown", - "rag", - "content" -]New value: +[ + "text", + "json", + "json_v2", + "html", + "markdown", + "rag", + "content", + "raw" +] - changed
Input schema / properties / render_js / descriptionPrevious value: -"Render JavaScript using headless browser for all URLs. Required for JS-heavy sites. Increases cost to tier 4 (~$0.001/req)."New value: +"Render JavaScript using headless browser for all URLs. Required for JS-heavy sites. Forces tier 4 ($0.004/req)." - added
Input schema / properties / urls / items / maxLengthAdded value: +2083 - changed
Input schema / properties / use_proxy / descriptionPrevious value: -"Route all requests through premium proxy (+~$0.0002/req)."New value: +"Route all requests through premium proxy (+$0.0002/req)."
- Changed
alterlab_crawl28 fields changed- removed
Input schema / properties / block_imagesRemoved value: -{ - "default": false, - "description": "Block image downloads during browser rendering on each crawled page. Reduces proxy bandwidth and speeds up crawls. Only effective with render_js=true.", - "type": "boolean" -} - added
Input schema / properties / budgetAdded value: +{ + "additionalProperties": { + "type": "integer" + }, + "description": "Per-path page budget: glob pattern -> max pages, most specific pattern wins, '*' is the catch-all (e.g., {\"/products/*\": 100, \"/blog/*\": 50, \"*\": 5}). max_pages stays the hard cap.", + "type": "object" +} - added
Input schema / properties / cacheAdded value: +{ + "description": "Serve pages from the response cache when available", + "type": "boolean" +} - added
Input schema / properties / cache_ttlAdded value: +{ + "description": "Cache TTL in seconds (60-86400). Requires cache=true", + "maximum": 86400, + "minimum": 60, + "type": "integer" +} - added
Input schema / properties / change_trackingAdded value: +{ + "additionalProperties": false, + "description": "Track page changes between crawls", + "properties": { + "enabled": { + "type": "boolean" + }, + "include_diff": { + "description": "Include a diff of changed pages", + "type": "boolean" + }, + "mode": { + "enum": [ + "content", + "structured" + ], + "type": "string" + }, + "tracking_id": { + "description": "Stable ID to compare this crawl against earlier crawls with the same ID", + "maxLength": 200, + "type": "string" + } + }, + "type": "object" +} - changed
Input schema / properties / cost_controls / properties / max_tier / descriptionPrevious value: -"Maximum tier to use for page scrapes (1=curl $0.0002, 2=http $0.0003, 3=stealth $0.002, 3.5=lightjs $0.0025, 4=browser $0.004)"New value: +"Maximum tier to use for page scrapes (1=curl $0.0002, 2=http $0.0003, 3=stealth $0.002, 3.5=lightjs $0.0025, 4=browser $0.004). render_js=true with a max_tier below 4 is rejected (render_js forces tier 4)." - added
Input schema / properties / delayAdded value: +{ + "description": "Politeness delay between page requests, in seconds (0-30)", + "maximum": 30, + "minimum": 0, + "type": "number" +} - added
Input schema / properties / depth_strategyAdded value: +{ + "description": "Link-discovery strategy (API default 'sequential')", + "enum": [ + "eager", + "sequential" + ], + "type": "string" +} - added
Input schema / properties / exclude_patterns / maxItemsAdded value: +50 - added
Input schema / properties / extractionAdded value: +{ + "const": "auto", + "description": "Set to 'auto' for automatic page-type detection and extraction without a user-defined schema. Mutually exclusive with extraction_schema.", + "type": "string" +} - changed
Input schema / properties / extraction_profile / enumPrevious value: -[ - "auto", - "product", - "article", - "job_posting", - "faq", - "recipe", - "event" -]New value: +[ + "auto", + "product", + "article", + "job_posting", + "faq", + "recipe", + "event", + "ecommerce_homepage", + "directory_listing" +] - added
Input schema / properties / extraction_providerAdded value: +{ + "description": "BYOK LLM provider used for extraction on each page", + "enum": [ + "openai", + "anthropic", + "openrouter", + "groq" + ], + "type": "string" +} - added
Input schema / properties / extraction_templateAdded value: +{ + "$ref": "#/properties/extraction_profile", + "description": "Alias for extraction_profile (mutually exclusive with it)" +} - added
Input schema / properties / force_refreshAdded value: +{ + "description": "Bypass the cache and fetch every page fresh", + "type": "boolean" +} - changed
Input schema / properties / formats / descriptionPrevious value: -"Output formats for each scraped page"New value: +"Output formats for each scraped page. 'markdown' is best for LLM consumption. 'json_v2' returns a structured section tree (headings + content blocks). 'rag' returns chunked text optimized for retrieval-augmented generation. 'raw' returns the raw response body without extraction. 'content' returns body_markdown + content_hash + images + links for AI/KB pipelines." - changed
Input schema / properties / formats / items / enumPrevious value: -[ - "text", - "json", - "json_v2", - "html", - "markdown" -]New value: +[ + "text", + "json", + "json_v2", + "html", + "markdown", + "rag", + "content" +] - added
Input schema / properties / include_patterns / maxItemsAdded value: +50 - added
Input schema / properties / priorityAdded value: +{ + "additionalProperties": false, + "description": "Crawl prioritisation hints (keywords, boost_patterns, demote_patterns)", + "properties": { + "boost_patterns": { + "description": "URL glob patterns to crawl earlier", + "items": { + "type": "string" + }, + "type": "array" + }, + "demote_patterns": { + "description": "URL glob patterns to crawl later", + "items": { + "type": "string" + }, + "type": "array" + }, + "keywords": { + "description": "Crawl pages matching these keywords first", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" +} - removed
Input schema / properties / render_js / defaultRemoved value: -false - changed
Input schema / properties / render_js / descriptionPrevious value: -"Render JavaScript on crawled pages. true=always (Tier 4), false=never, auto=smart detection per page"New value: +"Render JavaScript on crawled pages. true=always (Tier 4, $0.004/page), false=never, auto=smart detection per page" - added
Input schema / properties / screenshotAdded value: +{ + "description": "Capture a screenshot of each crawled page (requires render_js)", + "type": "boolean" +} - added
Input schema / properties / storageAdded value: +{ + "description": "Where crawl results are stored (API default 'redis')", + "enum": [ + "redis", + "s3", + "r2" + ], + "type": "string" +} - changed
Input schema / properties / timeout / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / url / maxLengthAdded value: +2083 - removed
Input schema / properties / use_proxy / defaultRemoved value: -false - changed
Input schema / properties / use_proxy / descriptionPrevious value: -"Route all crawl requests through premium proxy"New value: +"Route all crawl requests through premium proxy (+$0.0002/page)" - added
Input schema / properties / webhookAdded value: +{ + "additionalProperties": false, + "description": "Detailed webhook config (events, signing secret, headers); use instead of webhook_url", + "properties": { + "events": { + "description": "Event names to deliver (default: all)", + "items": { + "type": "string" + }, + "type": "array" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "metadata": { + "additionalProperties": {}, + "description": "Opaque metadata echoed in every event", + "type": "object" + }, + "secret": { + "description": "Signing secret for webhook payloads (8-256 chars)", + "maxLength": 256, + "minLength": 8, + "type": "string" + }, + "url": { + "format": "uri", + "maxLength": 2083, + "type": "string" + } + }, + "required": [ + "url" + ], + "type": "object" +} - added
Input schema / properties / webhook_url / maxLengthAdded value: +2083
- Changed
alterlab_create_session17 fields changed- added
Input schema / properties / auto_refresh_enabledAdded value: +{ + "description": "Enable proactive expiry detection and health checks (API default true)", + "type": "boolean" +} - added
Input schema / properties / consentAdded value: +{ + "description": "Explicit GDPR consent from the account owner to store these session cookies. Must be true — the API rejects session creation with CONSENT_REQUIRED otherwise. Only set true after the user has agreed to AlterLab storing their cookies.", + "type": "boolean" +} - removed
Input schema / properties / cookies / additionalPropertiesRemoved value: -{ - "type": "string" -} - added
Input schema / properties / cookies / anyOfAdded value: +[ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "items": { + "additionalProperties": true, + "properties": { + "domain": { + "type": "string" + }, + "expires": { + "type": "number" + }, + "httpOnly": { + "type": "boolean" + }, + "name": { + "minLength": 1, + "type": "string" + }, + "path": { + "type": "string" + }, + "sameSite": { + "type": "string" + }, + "secure": { + "type": "boolean" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + } +] - changed
Input schema / properties / cookies / descriptionPrevious value: -"Cookie key-value pairs for authentication (e.g., {\"session-id\": \"abc123\", \"session-token\": \"xyz789\"})"New value: +"Cookies for authentication. Cookies as a {name: value} object (e.g. {\"session-id\": \"abc123\"}) or as a list (max 100) of cookie objects with metadata: {name, value, domain?, path?, secure?, httpOnly?, sameSite?, expires?}." - removed
Input schema / properties / cookies / typeRemoved value: -"object" - added
Input schema / properties / domain / maxLengthAdded value: +255 - changed
Input schema / properties / domain / minLengthPrevious value: -1New value: +3 - added
Input schema / properties / expires_atAdded value: +{ + "description": "Session expiry in ISO 8601 format (e.g., '2026-12-31T23:59:59Z')", + "type": "string" +} - added
Input schema / properties / headersAdded value: +{ + "additionalProperties": { + "type": "string" + }, + "description": "Custom headers sent with this session (e.g., a User-Agent or Authorization header)", + "type": "object" +} - added
Input schema / properties / notesAdded value: +{ + "description": "Free-text notes about this session", + "maxLength": 1000, + "type": "string" +} - added
Input schema / properties / notify_before_expiryAdded value: +{ + "description": "Notify when the session is about to expire (API default true)", + "type": "boolean" +} - added
Input schema / properties / notify_on_failureAdded value: +{ + "description": "Notify when session validation fails (API default true)", + "type": "boolean" +} - added
Input schema / properties / organization_idAdded value: +{ + "description": "Organization to assign the session to (org admins only)", + "format": "uuid", + "type": "string" +} - added
Input schema / properties / sharedAdded value: +{ + "description": "Share the session with organization members immediately (API default false)", + "type": "boolean" +} - removed
Input schema / properties / user_agentRemoved value: -{ - "description": "Browser User-Agent string to use with this session", - "type": "string" -} - changed
Input schema / requiredPrevious value: -[ - "name", - "domain", - "cookies" -]New value: +[ + "name", + "domain", + "consent" +]
- Changed
alterlab_estimate_cost11 fields changed- changed
Input schema / properties / formats / descriptionPrevious value: -"Output formats to include in the estimate. Passed to the API but does not currently affect the cost estimate — the endpoint uses URL-pattern heuristics only. 'json_v2' returns a structured section tree. 'rag' returns chunked text for retrieval-augmented generation. 'content' returns body_markdown + content_hash + images + links. 'raw' returns the response body byte-for-byte with no transformation."New value: +"Output formats to include in the estimate. Passed to the API but does not currently affect the cost estimate — the endpoint uses URL-pattern heuristics only. 'markdown' is best for LLM consumption. 'json_v2' returns a structured section tree (headings + content blocks). 'rag' returns chunked text optimized for retrieval-augmented generation. 'raw' returns the raw response body without extraction. 'content' returns body_markdown + content_hash + images + links for AI/KB pipelines." - added
Input schema / properties / generate_pdfAdded value: +{ + "description": "Include the PDF add-on (+$0.0004)", + "type": "boolean" +} - added
Input schema / properties / methodAdded value: +{ + "description": "HTTP method. POST requests cost 1.5x the base tier price.", + "enum": [ + "GET", + "POST" + ], + "type": "string" +} - added
Input schema / properties / ocrAdded value: +{ + "description": "Include the OCR add-on (+$0.001)", + "type": "boolean" +} - added
Input schema / properties / render_js / anyOfAdded value: +[ + { + "type": "boolean" + }, + { + "const": "auto", + "type": "string" + } +] - changed
Input schema / properties / render_js / descriptionPrevious value: -"Enable JS rendering (forces Tier 4 minimum — no separate add-on charge)"New value: +"Enable JS rendering (forces Tier 4 minimum, $0.004 — no separate add-on charge)" - removed
Input schema / properties / render_js / typeRemoved value: -"boolean" - added
Input schema / properties / screenshotAdded value: +{ + "description": "Include the screenshot add-on (+$0.0002)", + "type": "boolean" +} - added
Input schema / properties / url / maxLengthAdded value: +2083 - added
Input schema / properties / use_own_proxyAdded value: +{ + "description": "Price the request with your own proxy integration (20% BYOP discount)", + "type": "boolean" +} - changed
Input schema / properties / use_proxy / descriptionPrevious value: -"Include premium proxy cost (+1 credit)"New value: +"Include premium proxy cost (+$0.0002)"
- Changed
alterlab_extract3 fields changed- added
Input schema / properties / content / maxLengthAdded value: +500000 - added
Input schema / properties / extraction_model / anyOfAdded value: +[ + { + "maxLength": 256, + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / extraction_model / typeRemoved value: -[ - "string", - "null" -]
- Added
alterlab_get_job - Changed
alterlab_map4 fields changed- added
Input schema / properties / exclude_patterns / maxItemsAdded value: +50 - added
Input schema / properties / include_patterns / maxItemsAdded value: +50 - added
Input schema / properties / sitemap_path / maxLengthAdded value: +500 - added
Input schema / properties / url / maxLengthAdded value: +2083
- Changed
alterlab_refresh_session4 fields changed- removed
Input schema / properties / cookies / additionalPropertiesRemoved value: -{ - "type": "string" -} - added
Input schema / properties / cookies / anyOfAdded value: +[ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "items": { + "additionalProperties": true, + "properties": { + "domain": { + "type": "string" + }, + "expires": { + "type": "number" + }, + "httpOnly": { + "type": "boolean" + }, + "name": { + "minLength": 1, + "type": "string" + }, + "path": { + "type": "string" + }, + "sameSite": { + "type": "string" + }, + "secure": { + "type": "boolean" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + } +] - changed
Input schema / properties / cookies / descriptionPrevious value: -"New cookie key-value pairs to replace the old ones. If omitted, only failure counters are reset."New value: +"New cookies to replace the old ones. If omitted, only failure counters are reset. Cookies as a {name: value} object (e.g. {\"session-id\": \"abc123\"}) or as a list (max 100) of cookie objects with metadata: {name, value, domain?, path?, secure?, httpOnly?, sameSite?, expires?}." - removed
Input schema / properties / cookies / typeRemoved value: -"object"
- Changed
alterlab_scrape50 fields changed- added
Input schema / properties / actionsAdded value: +{ + "description": "Browser automation actions run in order after page load (max 20, requires render_js=true). Failed actions are skipped without aborting the sequence. Results are returned in action_results. Each action has a 'type': wait, wait_for, click, fill, press, scroll, infinite_scroll, screenshot, evaluate.", + "items": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "milliseconds": { + "maximum": 30000, + "minimum": 100, + "type": "integer" + }, + "selector": { + "description": "CSS selector to wait for visibility", + "maxLength": 500, + "type": "string" + }, + "type": { + "const": "wait", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "selector": { + "maxLength": 500, + "type": "string" + }, + "timeout": { + "description": "Timeout in ms (default 10000)", + "maximum": 30000, + "minimum": 1000, + "type": "integer" + }, + "type": { + "const": "wait_for", + "type": "string" + } + }, + "required": [ + "type", + "selector" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "selector": { + "maxLength": 500, + "type": "string" + }, + "type": { + "const": "click", + "type": "string" + } + }, + "required": [ + "type", + "selector" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "selector": { + "maxLength": 500, + "type": "string" + }, + "type": { + "const": "fill", + "type": "string" + }, + "value": { + "maxLength": 5000, + "type": "string" + } + }, + "required": [ + "type", + "selector", + "value" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "key": { + "description": "Key to press, e.g. 'Enter', 'Tab', 'Escape'", + "maxLength": 50, + "type": "string" + }, + "type": { + "const": "press", + "type": "string" + } + }, + "required": [ + "type", + "key" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "amount": { + "description": "Viewport heights to scroll", + "maximum": 20, + "minimum": 1, + "type": "integer" + }, + "direction": { + "enum": [ + "down", + "up" + ], + "type": "string" + }, + "type": { + "const": "scroll", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "delay": { + "description": "Delay between scrolls in ms", + "maximum": 5000, + "minimum": 200, + "type": "integer" + }, + "end_selector": { + "description": "Stop scrolling when this selector appears", + "maxLength": 500, + "type": "string" + }, + "max_scrolls": { + "maximum": 50, + "minimum": 1, + "type": "integer" + }, + "type": { + "const": "infinite_scroll", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "full_page": { + "type": "boolean" + }, + "type": { + "const": "screenshot", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "script": { + "description": "JavaScript to run in the page (max 5120 chars). Network APIs (fetch, XMLHttpRequest, WebSocket) and dynamic code execution (eval, Function) are blocked.", + "maxLength": 5120, + "type": "string" + }, + "type": { + "const": "evaluate", + "type": "string" + } + }, + "required": [ + "type", + "script" + ], + "type": "object" + } + ] + }, + "maxItems": 20, + "type": "array" +} - removed
Input schema / properties / block_images / defaultRemoved value: -false - changed
Input schema / properties / cache_ttl / typePrevious value: -"number"New value: +"integer" - changed
Input schema / properties / cost_controls / descriptionPrevious value: -"Fine-grained cost and tier controls. Use to cap spending, pin a tier, or trade off cost vs speed. Prefer these over the top-level prefer_cost/prefer_speed/fail_fast fields for full control."New value: +"Fine-grained cost and tier controls. Use to cap spending, pin a tier, or trade off cost vs speed." - changed
Input schema / properties / cost_controls / properties / max_tier / descriptionPrevious value: -"Cap automatic escalation at this tier. Scrape will not escalate beyond it even if lower tiers fail. Cannot exceed force_tier when both are set."New value: +"Cap automatic escalation at this tier. Scrape will not escalate beyond it even if lower tiers fail. Cannot exceed force_tier when both are set. Combining render_js=true with a max_tier below 4 is rejected (render_js forces tier 4)." - added
Input schema / properties / embeddingsAdded value: +{ + "additionalProperties": false, + "description": "Chunk the scraped text and embed it with OpenAI models (+$0.001 per page). Set enabled=true; model, chunk_size (64-8191) and chunk_overlap (0-2048) are optional.", + "properties": { + "chunk_overlap": { + "maximum": 2048, + "minimum": 0, + "type": "integer" + }, + "chunk_size": { + "maximum": 8191, + "minimum": 64, + "type": "integer" + }, + "enabled": { + "type": "boolean" + }, + "model": { + "enum": [ + "text-embedding-3-small", + "text-embedding-3-large" + ], + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / enable_scrollAdded value: +{ + "description": "Force scrolling for lazy-load images. true: always scroll (+5-10s), false: never scroll, omit: auto (scroll unless social media site).", + "type": [ + "boolean", + "null" + ] +} - added
Input schema / properties / extraction_model / anyOfAdded value: +[ + { + "maxLength": 256, + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / extraction_model / typeRemoved value: -[ - "string", - "null" -] - changed
Input schema / properties / extraction_profile / descriptionPrevious value: -"Pre-built extraction schema template. auto: detect best template. product: e-commerce product details. article: news/blog article fields. job_posting: job listing fields. faq: FAQ entries. recipe: recipe ingredients and instructions. event: event details. ecommerce_homepage: homepage product listings. directory_listing: directory/listing page entries."New value: +"Pre-built extraction schema template. auto: detect best template (API default). product: e-commerce product details. article: news/blog article fields. job_posting: job listing fields. faq: FAQ entries. recipe: recipe ingredients and instructions. event: event details. ecommerce_homepage: homepage product listings. directory_listing: directory/listing page entries. Mutually exclusive with extraction_template." - changed
Input schema / properties / extraction_schema / descriptionPrevious value: -"JSON schema for structured extraction. The API extracts fields matching this schema from the scraped page using LLM. Result is returned in extraction_result. Example: { \"title\": \"string\", \"price\": \"number\", \"in_stock\": \"boolean\" }"New value: +"JSON schema for structured extraction. The API extracts fields matching this schema from the scraped page using LLM (+$0.001). Result is returned in extraction_result. Example: { \"title\": \"string\", \"price\": \"number\", \"in_stock\": \"boolean\" }" - added
Input schema / properties / extraction_templateAdded value: +{ + "$ref": "#/properties/extraction_profile", + "description": "Shorthand alias for extraction_profile — selects the same pre-built template. Mutually exclusive with extraction_profile." +} - changed
Input schema / properties / fail_fast / descriptionPrevious value: -"Fail immediately if the page requires an expensive tier (browser/captcha) instead of auto-escalating. Use this to protect against unexpected credit spend on protected pages. Returns an error with the required tier instead of automatically upgrading."New value: +"Fail immediately if the page requires an expensive tier (browser/captcha) instead of auto-escalating. Shorthand for cost_controls.fail_fast. Returns an error with the required tier instead of upgrading." - added
Input schema / properties / flatten_shadow_domAdded value: +{ + "description": "Flatten Shadow DOM roots into regular DOM for extraction (free, requires render_js).", + "type": "boolean" +} - changed
Input schema / properties / formats / items / enumPrevious value: -[ - "text", - "json", - "json_v2", - "html", - "markdown", - "rag", - "raw", - "content" -]New value: +[ + "text", + "json", + "json_v2", + "html", + "markdown", + "rag", + "content", + "raw" +] - added
Input schema / properties / generate_pdfAdded value: +{ + "description": "Generate a PDF of the rendered page (+$0.0004, requires render_js)", + "type": "boolean" +} - added
Input schema / properties / headersAdded value: +{ + "additionalProperties": { + "type": "string" + }, + "description": "Custom HTTP headers to send to the target URL. Hop-by-hop headers (Connection, Transfer-Encoding, Host, etc.) are not allowed.", + "type": "object" +} - added
Input schema / properties / include_iframesAdded value: +{ + "description": "Inline iframe content into the main document (free, requires render_js). Same-origin iframes are read directly; cross-origin iframes are marked but not fetched.", + "type": "boolean" +} - removed
Input schema / properties / max_response_bytes / defaultRemoved value: -5242880 - added
Input schema / properties / ocrAdded value: +{ + "description": "Extract text from images using OCR (+$0.001)", + "type": "boolean" +} - added
Input schema / properties / ocr_languageAdded value: +{ + "description": "Tesseract language code for OCR (API default 'eng')", + "type": "string" +} - added
Input schema / properties / pdf_formatAdded value: +{ + "description": "Output format for mode='pdf' extraction (API default 'markdown')", + "type": "string" +} - changed
Input schema / properties / prefer_cost / descriptionPrevious value: -"Optimize for lowest cost — try cheaper tiers first before escalating. Best for non-time-sensitive scrapes where minimizing credit spend matters. Mutually exclusive intent with prefer_speed."New value: +"Optimize for lowest cost — try cheaper tiers first before escalating. Shorthand for cost_controls.prefer_cost. Mutually exclusive intent with prefer_speed." - changed
Input schema / properties / prefer_speed / descriptionPrevious value: -"Optimize for speed — skip to a reliable tier immediately instead of escalating from Tier 1. Best for time-sensitive scrapes where latency matters more than cost. Mutually exclusive intent with prefer_cost."New value: +"Optimize for speed — skip to a reliable tier immediately instead of escalating from Tier 1. Shorthand for cost_controls.prefer_speed. Mutually exclusive intent with prefer_cost." - changed
Input schema / properties / promote_schema_org / descriptionPrevious value: -"Use Schema.org JSON-LD/Microdata as the primary structured-data source when present. Promotes machine-readable metadata embedded in the page over LLM extraction. Most effective on e-commerce, recipe, and news article pages."New value: +"Use Schema.org JSON-LD/Microdata as the primary structured-data source when present (API default true). Promotes machine-readable metadata embedded in the page over LLM extraction. Most effective on e-commerce, recipe, and news article pages." - changed
Input schema / properties / proxy_country / descriptionPrevious value: -"ISO country code for geo-targeting (e.g., 'US', 'DE'). Requires use_proxy=true"New value: +"ISO country code for proxy geo-targeting (e.g., 'US', 'DE'). Requires use_proxy=true" - added
Input schema / properties / proxy_integration_idAdded value: +{ + "description": "Specific proxy integration ID to use (requires use_own_proxy=true)", + "type": "string" +} - removed
Input schema / properties / remove_cookie_banners / defaultRemoved value: -true - changed
Input schema / properties / remove_cookie_banners / descriptionPrevious value: -"Remove cookie consent banners from HTML before content extraction (free, enabled by default)"New value: +"Remove cookie consent banners from HTML before content extraction (free; the API default is true)" - removed
Input schema / properties / render_js / defaultRemoved value: -false - changed
Input schema / properties / render_js / descriptionPrevious value: -"Render JavaScript using headless browser (forces Tier 4 minimum — no separate add-on charge). Required for JS-heavy sites. Set to 'auto' for smart detection (probes each page, only renders JS-heavy pages with browser — saves 30-60% on mixed sites)."New value: +"Render JavaScript using a headless browser (forces Tier 4 minimum, $0.004/req — no separate add-on charge). Required for JS-heavy sites. Set to 'auto' for smart detection (probes each page, only renders JS-heavy pages with a browser — saves 30-60% on mixed sites)." - added
Input schema / properties / screenshotAdded value: +{ + "description": "Capture a full-page screenshot (+$0.0002, requires render_js). The URL is returned as screenshot_url. Use alterlab_screenshot to get the image inline.", + "type": "boolean" +} - removed
Input schema / properties / scroll_count / defaultRemoved value: -3 - changed
Input schema / properties / scroll_count / descriptionPrevious value: -"Number of scroll iterations when scroll_to_load is enabled (1-10, default 3)"New value: +"Number of scroll iterations when scroll_to_load is enabled (1-10, API default 3)" - removed
Input schema / properties / scroll_to_load / defaultRemoved value: -false - added
Input schema / properties / section_filterAdded value: +{ + "additionalProperties": false, + "description": "Filter for the json_v2 section tree. Only applies when 'json_v2' is in formats.", + "properties": { + "content_only": { + "type": "boolean" + }, + "exclude_content_types": { + "items": { + "type": "string" + }, + "type": "array" + }, + "min_content_blocks": { + "minimum": 0, + "type": "integer" + } + }, + "type": "object" +} - added
Input schema / properties / session_headersAdded value: +{ + "additionalProperties": { + "type": "string" + }, + "description": "Inline auth headers sent to the target (e.g. Authorization: Bearer ...). Merged with the stored session's headers when session_id is also set.", + "type": "object" +} - added
Input schema / properties / skip_tls_verificationAdded value: +{ + "description": "TLS certificate verification for the target. Omit (recommended): certificates are verified, and if the site's own certificate is invalid (expired, self-signed, wrong hostname, incomplete chain) the page is still fetched without verification. true skips verification from the start. false always requires a valid certificate, so sites with an invalid certificate fail.", + "type": "boolean" +} - added
Input schema / properties / sticky_sessionAdded value: +{ + "description": "Sticky-session handle. Scrapes that pass the same value reuse the cookie jar captured on the first call and, best-effort, the same exit IP (~10 min). Alphanumeric, '-' and '_' only. Requires a paid plan (growth tier or above).", + "maxLength": 128, + "type": "string" +} - added
Input schema / properties / sticky_session_ttlAdded value: +{ + "description": "Sticky-session cookie-jar lifetime in seconds (300-7200, API default 1800). Ignored unless sticky_session is set.", + "maximum": 7200, + "minimum": 300, + "type": "integer" +} - added
Input schema / properties / sync_policyAdded value: +{ + "description": "Synchronous wait policy. 'auto' (default) may return an early 202 with a job_id for predicted T3/T4 jobs; 'wait_until_deadline' keeps the connection open until the terminal result or the safe sync deadline (~85s).", + "enum": [ + "auto", + "wait_until_deadline" + ], + "type": "string" +} - changed
Input schema / properties / template / descriptionPrevious value: -"Named extraction template to apply to the scrape result. Accepts standard template names (e.g. 'product', 'article', 'job_posting') or a custom template name registered in your account. When provided, routes the request through template-based extraction."New value: +"DEPRECATED alias for extraction_template, kept for backward compatibility. Sent to the API as extraction_template; prefer extraction_template." - changed
Input schema / properties / timeout / typePrevious value: -"number"New value: +"integer" - added
Input schema / properties / url / maxLengthAdded value: +2083 - added
Input schema / properties / use_own_proxyAdded value: +{ + "description": "Use your own proxy integration (bring-your-own-proxy) instead of the system proxy. BYOP requests get a 20% discount on the tier price.", + "type": "boolean" +} - removed
Input schema / properties / use_proxy / defaultRemoved value: -false - changed
Input schema / properties / use_proxy / descriptionPrevious value: -"Route through premium proxy (+$0.0002). Helps bypass geo-restrictions and anti-bot"New value: +"Route through AlterLab's premium proxy (+$0.0002). Helps bypass geo-restrictions and anti-bot" - added
Input schema / properties / use_system_proxyAdded value: +{ + "description": "Override your default proxy integration and use AlterLab's system proxy for this request.", + "type": "boolean" +} - added
Input schema / properties / wait_conditionAdded value: +{ + "description": "Wait condition for JS rendering: domcontentloaded, networkidle or load", + "type": "string" +} - added
Input schema / properties / wait_untilAdded value: +{ + "description": "Page load event to wait for before extracting (networkidle, domcontentloaded or load; API default networkidle)", + "type": "string" +}
- Changed
alterlab_screenshot7 fields changed- added
Input schema / properties / cookiesAdded value: +{ + "additionalProperties": { + "type": "string" + }, + "description": "Inline cookies for a one-off authenticated screenshot", + "type": "object" +} - added
Input schema / properties / locationAdded value: +{ + "additionalProperties": false, + "description": "Geo-targeting parameters for localized content scraping. Controls proxy country routing, Accept-Language header, and browser locale.", + "properties": { + "country": { + "description": "ISO 3166-1 alpha-2 country code for geo-targeting (e.g., 'US', 'DE', 'JP'). Routes request through a proxy in the specified country.", + "maxLength": 2, + "minLength": 2, + "type": "string" + }, + "language": { + "description": "ISO 639-1 language code (e.g., 'en', 'de', 'ja'). Sets the Accept-Language header and browser locale.", + "maxLength": 5, + "minLength": 2, + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / proxy_countryAdded value: +{ + "description": "ISO country code for proxy geo-targeting. Requires use_proxy=true", + "type": "string" +} - added
Input schema / properties / session_idAdded value: +{ + "description": "UUID of a stored session, to screenshot a logged-in page", + "format": "uuid", + "type": "string" +} - added
Input schema / properties / timeoutAdded value: +{ + "description": "Request timeout in seconds (1-300, API default 90)", + "maximum": 300, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / url / maxLengthAdded value: +2083 - added
Input schema / properties / use_proxyAdded value: +{ + "description": "Route through AlterLab's premium proxy (+$0.0002)", + "type": "boolean" +}
- Changed
alterlab_search4 fields changed- added
Input schema / properties / domain / maxLengthAdded value: +253 - added
Input schema / properties / engineAdded value: +{ + "description": "Search engine (API default duckduckgo). duckduckgo costs $0.001/query; google and bing use browser rendering and cost $0.004/query.", + "enum": [ + "duckduckgo", + "google", + "bing" + ], + "type": "string" +} - changed
Input schema / properties / formats / items / enumPrevious value: -[ - "text", - "json", - "json_v2", - "html", - "markdown" -]New value: +[ + "text", + "json", + "json_v2", + "html", + "markdown", + "rag", + "content" +] - changed
Input schema / properties / safe_search / descriptionPrevious value: -"Enable safe search filtering to exclude adult content from results. Defaults to the search engine's own safe-search setting when omitted."New value: +"Safe search filtering to exclude adult content from results (API default true). Set false to disable."
- Changed
alterlab_update_session7 fields changed- added
Input schema / properties / auto_refresh_enabledAdded value: +{ + "description": "Enable or disable proactive expiry detection and health checks", + "type": "boolean" +} - removed
Input schema / properties / cookies / additionalPropertiesRemoved value: -{ - "type": "string" -} - added
Input schema / properties / cookies / anyOfAdded value: +[ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "items": { + "additionalProperties": true, + "properties": { + "domain": { + "type": "string" + }, + "expires": { + "type": "number" + }, + "httpOnly": { + "type": "boolean" + }, + "name": { + "minLength": 1, + "type": "string" + }, + "path": { + "type": "string" + }, + "sameSite": { + "type": "string" + }, + "secure": { + "type": "boolean" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "type": "object" + }, + "maxItems": 100, + "type": "array" + } +] - changed
Input schema / properties / cookies / descriptionPrevious value: -"New cookie key-value pairs — replaces ALL existing cookies (e.g., {\"session-id\": \"new123\", \"session-token\": \"newxyz\"})"New value: +"New cookies — replaces ALL existing cookies. Cookies as a {name: value} object (e.g. {\"session-id\": \"abc123\"}) or as a list (max 100) of cookie objects with metadata: {name, value, domain?, path?, secure?, httpOnly?, sameSite?, expires?}." - removed
Input schema / properties / cookies / typeRemoved value: -"object" - added
Input schema / properties / notify_before_expiryAdded value: +{ + "description": "Enable or disable the before-expiry notification", + "type": "boolean" +} - added
Input schema / properties / notify_on_failureAdded value: +{ + "description": "Enable or disable the validation-failure notification", + "type": "boolean" +}
7 tool updates
v1.8.0- Added
alterlab_batch_scrape - Changed
alterlab_crawl6 fields changed- added
Input schema / properties / cost_controlsAdded value: +{ + "additionalProperties": false, + "description": "Cost controls for the entire crawl — cap total spend or pin the scraping tier", + "properties": { + "force_tier": { + "$ref": "#/properties/cost_controls/properties/max_tier", + "description": "Force all pages to use this exact tier, bypassing per-page escalation" + }, + "max_credits": { + "description": "Hard spending cap in credits for the entire crawl", + "exclusiveMinimum": 0, + "type": "integer" + }, + "max_tier": { + "description": "Maximum tier to use for page scrapes (1=curl $0.0002, 2=http $0.0003, 3=stealth $0.002, 3.5=lightjs $0.0025, 4=browser $0.004)", + "enum": [ + "1", + "2", + "3", + "3.5", + "4" + ], + "type": "string" + } + }, + "type": "object" +} - added
Input schema / properties / extraction_profileAdded value: +{ + "description": "Pre-defined extraction profile applied to every crawled page. 'auto' detects the page type automatically.", + "enum": [ + "auto", + "product", + "article", + "job_posting", + "faq", + "recipe", + "event" + ], + "type": "string" +} - added
Input schema / properties / headersAdded value: +{ + "additionalProperties": { + "type": "string" + }, + "description": "Custom HTTP headers injected into every page request during the crawl (e.g., {\"Authorization\": \"Bearer token\"}). Maximum 50 headers.", + "type": "object" +} - added
Input schema / properties / sitemap_pathAdded value: +{ + "description": "Explicit path to the sitemap file (e.g., '/sitemap_index.xml'). Use when the sitemap is not at the standard /sitemap.xml location.", + "type": "string" +} - added
Input schema / properties / timeoutAdded value: +{ + "description": "Per-page request timeout in seconds (1-300)", + "maximum": 300, + "minimum": 1, + "type": "number" +} - added
Input schema / properties / wait_forAdded value: +{ + "description": "CSS selector to wait for before extracting each page (e.g., '#main-content'). Applied to all pages in the crawl.", + "type": "string" +}
- Changed
alterlab_estimate_cost1 field changed- changed
Input schema / properties / formats / descriptionPrevious value: -"Output formats to include in the estimate. Affects cost prediction accuracy. 'json_v2' returns a structured section tree. 'rag' returns chunked text for retrieval-augmented generation. 'content' returns body_markdown + content_hash + images + links. 'raw' returns the response body byte-for-byte with no transformation."New value: +"Output formats to include in the estimate. Passed to the API but does not currently affect the cost estimate — the endpoint uses URL-pattern heuristics only. 'json_v2' returns a structured section tree. 'rag' returns chunked text for retrieval-augmented generation. 'content' returns body_markdown + content_hash + images + links. 'raw' returns the response body byte-for-byte with no transformation."
- Added
alterlab_get_usage - Changed
alterlab_map1 field changed- added
Input schema / properties / sitemap_pathAdded value: +{ + "description": "Explicit path to the sitemap file (e.g., '/sitemap_index.xml'). Use when the sitemap is not at the standard /sitemap.xml location.", + "type": "string" +}
- Changed
alterlab_scrape19 fields changed- changed
Input schema / properties / body / descriptionPrevious value: -"Request body for POST/PUT/PATCH requests. For GraphQL: JSON string with 'query' and optional 'variables' fields (e.g., '{\"query\": \"{ user { id name } }\"}').For REST APIs: JSON-encoded payload string. For form submissions: URL-encoded key=value pairs (e.g., 'name=Alice&email=alice@example.com'). Omit for GET/HEAD/DELETE requests."New value: +"Request body for POST requests. For GraphQL: JSON string with 'query' and optional 'variables' fields (e.g., '{\"query\": \"{ user { id name } }\"}').For REST APIs: JSON-encoded payload string. For form submissions: URL-encoded key=value pairs (e.g., 'name=Alice&email=alice@example.com'). Omit for GET requests." - added
Input schema / properties / cacheAdded value: +{ + "description": "Enable caching for this request. When true, repeat requests with identical parameters may return cached results. Only use for idempotent requests (GET pages, read-only POSTs).", + "type": "boolean" +} - added
Input schema / properties / cache_ttlAdded value: +{ + "description": "Cache TTL in seconds (60–86400). Defaults to 3600 (60 min) when cache=true. Requires cache=true.", + "maximum": 86400, + "minimum": 60, + "type": "number" +} - added
Input schema / properties / content_typeAdded value: +{ + "description": "Content-Type header for the request body. Defaults to 'application/json' when body is provided. Use 'application/graphql' for raw GraphQL queries. Use 'application/x-www-form-urlencoded' for HTML form submissions. Requires body to be set.", + "enum": [ + "application/json", + "application/x-www-form-urlencoded", + "text/plain", + "application/graphql" + ], + "type": "string" +} - added
Input schema / properties / cost_controlsAdded value: +{ + "additionalProperties": false, + "description": "Fine-grained cost and tier controls. Use to cap spending, pin a tier, or trade off cost vs speed. Prefer these over the top-level prefer_cost/prefer_speed/fail_fast fields for full control.", + "properties": { + "fail_fast": { + "description": "Return error instead of escalating to more expensive tiers on failure.", + "type": "boolean" + }, + "force_tier": { + "description": "Pin execution to this exact tier, bypassing escalation (1=curl $0.0002, 2=http $0.0003, 3=stealth $0.002, 3.5=lightjs $0.0025, 4=browser $0.004). Use to guarantee a specific engine is used regardless of site difficulty.", + "enum": [ + "1", + "2", + "3", + "3.5", + "4" + ], + "type": "string" + }, + "max_credits": { + "description": "Hard spending cap for this request in credits. Request fails if cost would exceed this.", + "exclusiveMinimum": 0, + "type": "number" + }, + "max_tier": { + "$ref": "#/properties/cost_controls/properties/force_tier", + "description": "Cap automatic escalation at this tier. Scrape will not escalate beyond it even if lower tiers fail. Cannot exceed force_tier when both are set." + }, + "prefer_cost": { + "description": "Optimize for cost — try cheaper tiers first, accept lower success probability.", + "type": "boolean" + }, + "prefer_speed": { + "description": "Optimize for speed — skip to the most reliable tier for this domain.", + "type": "boolean" + }, + "time_budget": { + "description": "Total wall-clock budget in seconds for the entire tier escalation sequence (5–300s). Escalation stops when remaining budget is insufficient for the next tier attempt.", + "maximum": 300, + "minimum": 5, + "type": "number" + } + }, + "type": "object" +} - added
Input schema / properties / estimate_firstAdded value: +{ + "default": false, + "description": "Run a cost estimate before scraping and include it in the response. Adds one lightweight API call (~50ms) with no credit charge. The estimated tier, cost, and confidence are prepended to the scrape result. Useful for unfamiliar or potentially expensive sites — see cost before committing.", + "type": "boolean" +} - added
Input schema / properties / evidenceAdded value: +{ + "description": "Include provenance/evidence snippets alongside extracted fields. Each extracted value will include the source text passage it was derived from. Requires extraction_schema or extraction_prompt.", + "type": "boolean" +} - changed
Input schema / properties / extraction_schema / descriptionPrevious value: -"JSON schema for structured extraction. The API extracts fields matching this schema from the scraped page using LLM. Result is returned in content.json (add 'json' to formats) and in the top-level filtered_content field. Example: { \"title\": \"string\", \"price\": \"number\", \"in_stock\": \"boolean\" }"New value: +"JSON schema for structured extraction. The API extracts fields matching this schema from the scraped page using LLM. Result is returned in extraction_result. Example: { \"title\": \"string\", \"price\": \"number\", \"in_stock\": \"boolean\" }" - added
Input schema / properties / fail_fastAdded value: +{ + "description": "Fail immediately if the page requires an expensive tier (browser/captcha) instead of auto-escalating. Use this to protect against unexpected credit spend on protected pages. Returns an error with the required tier instead of automatically upgrading.", + "type": "boolean" +} - added
Input schema / properties / filter_contentAdded value: +{ + "description": "Apply quality filtering to extracted content. When false (default), returns all parsed content without quality thresholds (lossless mode). When true, filters low-quality boilerplate.", + "type": "boolean" +} - added
Input schema / properties / force_refreshAdded value: +{ + "description": "Bypass the cache and always fetch a fresh copy of the page. Use when you need real-time content and a cached result would be stale.", + "type": "boolean" +} - changed
Input schema / properties / formats / descriptionPrevious value: -"Output formats. 'markdown' is best for LLM consumption. 'json_v2' returns a structured section tree (headings + content blocks). 'rag' returns chunked text optimized for retrieval-augmented generation. 'content' returns body_markdown + content_hash + images + links for AI/KB pipelines."New value: +"Output formats. 'markdown' is best for LLM consumption. 'json_v2' returns a structured section tree (headings + content blocks). 'rag' returns chunked text optimized for retrieval-augmented generation. 'raw' returns the raw response body without extraction. 'content' returns body_markdown + content_hash + images + links for AI/KB pipelines." - changed
Input schema / properties / formats / items / enumPrevious value: -[ - "text", - "json", - "json_v2", - "html", - "markdown", - "rag", - "content" -]New value: +[ + "text", + "json", + "json_v2", + "html", + "markdown", + "rag", + "raw", + "content" +] - changed
Input schema / properties / method / descriptionPrevious value: -"HTTP method for the request. Default GET (standard page scraping). Use POST for GraphQL endpoints, form submissions, REST API calls. Use PUT/PATCH for REST API updates. When using POST/PUT/PATCH, provide body with the request payload."New value: +"HTTP method for the request. Default GET (standard page scraping). Use POST for GraphQL endpoints, form submissions, and REST API calls. When using POST, provide body with the request payload. POST costs 1.5x base tier price." - changed
Input schema / properties / method / enumPrevious value: -[ - "GET", - "POST", - "PUT", - "PATCH", - "DELETE", - "HEAD" -]New value: +[ + "GET", + "POST" +] - added
Input schema / properties / prefer_costAdded value: +{ + "description": "Optimize for lowest cost — try cheaper tiers first before escalating. Best for non-time-sensitive scrapes where minimizing credit spend matters. Mutually exclusive intent with prefer_speed.", + "type": "boolean" +} - added
Input schema / properties / prefer_speedAdded value: +{ + "description": "Optimize for speed — skip to a reliable tier immediately instead of escalating from Tier 1. Best for time-sensitive scrapes where latency matters more than cost. Mutually exclusive intent with prefer_cost.", + "type": "boolean" +} - added
Input schema / properties / promote_schema_orgAdded value: +{ + "description": "Use Schema.org JSON-LD/Microdata as the primary structured-data source when present. Promotes machine-readable metadata embedded in the page over LLM extraction. Most effective on e-commerce, recipe, and news article pages.", + "type": "boolean" +} - added
Input schema / properties / templateAdded value: +{ + "description": "Named extraction template to apply to the scrape result. Accepts standard template names (e.g. 'product', 'article', 'job_posting') or a custom template name registered in your account. When provided, routes the request through template-based extraction.", + "type": "string" +}
- Changed
alterlab_search1 field changed- added
Input schema / properties / safe_searchAdded value: +{ + "description": "Enable safe search filtering to exclude adult content from results. Defaults to the search engine's own safe-search setting when omitted.", + "type": "boolean" +}
2 tool updates
v1.7.0- Changed
alterlab_crawl1 field changed- added
Input schema / properties / block_imagesAdded value: +{ + "default": false, + "description": "Block image downloads during browser rendering on each crawled page. Reduces proxy bandwidth and speeds up crawls. Only effective with render_js=true.", + "type": "boolean" +}
- Changed
alterlab_scrape1 field changed- added
Input schema / properties / block_imagesAdded value: +{ + "default": false, + "description": "Block image downloads during browser rendering. Reduces proxy bandwidth and speeds up scrapes. Only effective with render_js=true.", + "type": "boolean" +}
23 tool updates
v1.5.0- First observed
alterlab_batch - First observed
alterlab_batch_status - First observed
alterlab_check_balance - First observed
alterlab_crawl - First observed
alterlab_crawl_cancel - First observed
alterlab_crawl_status - First observed
alterlab_create_session - First observed
alterlab_delete_session - First observed
alterlab_disable_beta_feature - First observed
alterlab_enable_beta_feature - First observed
alterlab_estimate_cost - First observed
alterlab_extract - First observed
alterlab_get_session - First observed
alterlab_list_beta_features - First observed
alterlab_list_my_beta_features - First observed
alterlab_list_sessions - First observed
alterlab_map - First observed
alterlab_refresh_session - First observed
alterlab_scrape - First observed
alterlab_screenshot - First observed
alterlab_search - First observed
alterlab_update_session - First observed
alterlab_validate_session
TDQS
Scored across 26 tools
Most tools occupy clearly distinct slots, and descriptions explicitly cross-reference neighbors (scrape vs batch_scrape vs batch; crawl vs map; check_balance vs get_usage). A few clusters still risk misselection: three separate status pollers (get_job, crawl_status, batch_status) and the update_session vs refresh_session pair require careful reading. Overlap is managed by documentation rather than by structure, but boundaries are generally discoverable.
All tools use the alterlab_ prefix and snake_case, with a strong verb_noun pattern (list_sessions, create_session, get_usage, estimate_cost). Minor deviations exist: alterlab_batch and alterlab_crawl are bare verb/noun names, and alterlab_crawl_status / alterlab_batch_status use noun_status rather than a verb. Still highly predictable overall.
At 26 tools the server sits just above the heavy threshold, with the surface spread across scraping, bulk jobs, account/cost, sessions, and beta-flag management. The groups are each internally coherent, but the 7 session tools and 4 beta-feature tools push the count higher than the core scraping purpose strictly requires. Well-organized but on the bulky side.
The core lifecycle is well covered: single and batch scraping, async jobs with polling, crawling with status and cancel, site mapping, search, cost estimation, balance/usage, and full session CRUD plus validate/refresh. Minor gaps remain — there is a crawl_cancel but no equivalent cancel/abort for batch jobs, and no way to delete or clean up stored crawl/batch results. Agents can work around these but they are real dead ends.
Maintenance
Related MCP Connectors
Crawl, scrape, search the web, and automate browsers at scale with anti-bot bypass.
Fetch and extract data from any public web page, even JS-rendered or anti-bot protected
Fetch, crawl, and browse protected pages with anti-bot handling - renders in a real browser and
Markdown scrape, site map, page metadata, screenshots, web search and PDF to text. Pay per call
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables web scraping and document processing with JavaScript execution, anti-detection measures, batch processing, and structured data extraction. Supports multiple formats including markdown, HTML, screenshots, and handles PDFs with OCR capabilities.4MIT
- AlicenseAqualityBmaintenanceEnables web scraping and data extraction from websites with geographic flexibility, privacy features, and anti-detection capabilities. Supports scraping general websites, Google Search, Amazon Search, and Reddit with customizable parameters for rendering, geolocation, and locale.33757 npm39ISC
- AlicenseNot gradedqualityFmaintenanceEnables intelligent web scraping with support for static pages, JavaScript-rendered SPAs, and natural language data extraction.MIT
- AlicenseAqualityCmaintenanceEnables crawling websites, including JavaScript-rendered pages, and returns extracted page content as JSON with structured error reporting.1MIT