ZenRows MCP server for AI agents

Live

OAUTH 2.1

WEB SCRAPING

Developer Tools

Any webpage, JavaScript-rendered site, or browser automation your agent needs to run goes through ZenRows' cloud infrastructure. ZenRows MCP gives your agent per-user OAuth access with enterprise anti-bot bypass built in.

  • Acts as the user: Scrape jobs and browser sessions run under the authorizing developer's ZenRows account.
  • Credentials stay vaulted: AES-256, resolved at request time, never in LLM context.
  • Scoped before every call: User permissions enforced. 90-day audit trail.
ZenRows MCP
agent · Acme Q3
Run
Scrape the product listing page on [e-commerce site] and extract all prices and SKUs.
S
zenrowsmcp_scrape
1340ms
Research agent
Extracted 24 products with SKUs and prices. Price range $12–$299. 3 products marked out of stock. Data returned as structured JSON with product name, SKU, price, availability.
Sources: ZenRows scrape, product listing page
zenrowsmcp
24
18:29
Message Claude...

Tools your agent reaches for on ZenRows MCP, scoped per user.

CALL ANY TOOL
Scrape any URL with anti-bot bypass, render JavaScript-heavy sites, and automate cloud browsers. Same toolkit, every framework, no auth plumbing.
zenrowsmcp_account_usage
Account usage
Read the current plan's credit allowance and how much of it is spent. Useful before a large batch, or after a 402 / AUTH004, to see whether the account has credits left and when the allowance renews. The call is free and does not use a concurrency slot. Credit costs per request: 1 basic, 5 js_render, 10 premium_proxy, 25 both. AUTH004 ("usage exceeded") means this allowance is spent until it renews at the end of the billing period (period_ends_at in this tool's response). Plans and credit options are described at https://www.zenrows.com/pricing. AUTH006 is the concurrency limit, not a credit limit. AUTH014 (Batch: api_key_cap_reached) means this API key hit one of its own credit caps while the account still has credits; other keys keep working. The response's api_key.caps lists the calling key's caps: window, credits, used_credits, remaining_credits, resets_at, and unavailable (usage could not be read). Caps are managed at https://app.zenrows.com/settings/api-keys.
Parameters
Name
Type
Required
Description
—
No parameters required
zenrowsmcp_batch_cancel
Cancel batch
zenrowsmcp_batch_create
Create batch
zenrowsmcp_batch_delete
Delete batch
zenrowsmcp_batch_list
List batch
zenrowsmcp_batch_pause
Pause batch
zenrowsmcp_batch_results
Batch results
zenrowsmcp_batch_status
Batch status
zenrowsmcp_browser_check
Check browser
zenrowsmcp_browser_clear_local_storage
Browser clear local storage
zenrowsmcp_browser_close
Close browser
zenrowsmcp_browser_fill
Browser fill
zenrowsmcp_browser_generate_pdf
Browser generate pdf
zenrowsmcp_browser_get_accessibility_tree
Browser get accessibility tree
zenrowsmcp_browser_get_cookies
Browser get cookies
zenrowsmcp_browser_get_local_storage
Browser get local storage
zenrowsmcp_browser_get_title
Browser get title
zenrowsmcp_browser_go_forward
Browser go forward
zenrowsmcp_browser_navigate
Browser navigate
zenrowsmcp_browser_press_key
Browser press key
zenrowsmcp_browser_query_selector_all
Browser query selector all
zenrowsmcp_browser_screenshot
Browser screenshot
zenrowsmcp_browser_set_cookies
Browser set cookies
zenrowsmcp_browser_switch_tab
Browser switch tab
zenrowsmcp_browser_uncheck
Browser uncheck
zenrowsmcp_browser_wait_for_navigation
Browser wait for navigation
zenrowsmcp_crawl_download
Download crawl
zenrowsmcp_crawl_stop
Stop crawl
zenrowsmcp_crawl_wait
Crawl wait
zenrowsmcp_prepare_domain
Prepare domain

For more tools, view docs.

Build your Agent
Drop the toolkit in, point it at the user, and your agent can scrape and automate via ZenRows from the first run.
Python · LlamaIndex
import { ScalekitClient } from "@scalekit-sdk/node";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { z } from "zod";

const sk = new ScalekitClient(envUrl, clientId, clientSecret);

const { tools } = await sk.tools.listScopedTools("user_123", {
filter: { connectionNames: ["zenrowsmcp"], toolNames: ["zenrowsmcp_scrape", "zenrowsmcp_scrape", "zenrowsmcp_browser_screenshot"] },
pageSize: 100,
});

const lcTools = tools.map((t) => new DynamicStructuredTool({
name: t.tool.definition.name,
description: t.tool.definition.description,
schema: z.object({}).passthrough(),
func: async (args) => {
const { data } = await sk.tools.executeTool({
toolName: t.tool.definition.name,
identifier: "user_123",
params: args,
});
return JSON.stringify(data);
},
}));

const agent = createReactAgent({ llm, tools: lcTools });
import { ScalekitClient } from "@scalekit-sdk/node";
import OpenAI from "openai";

const sk = new ScalekitClient(envUrl, clientId, clientSecret);
const openai = new OpenAI();

const { tools } = await sk.tools.listScopedTools("user_123", {
filter: { connectionNames: ["zenrowsmcp"], toolNames: ["zenrowsmcp_scrape", "zenrowsmcp_scrape", "zenrowsmcp_browser_screenshot"] },
pageSize: 100,
});

const llmTools = tools.map((t) => ({
type: "function",
function: {
name: t.tool.definition.name,
description: t.tool.definition.description,
parameters: t.tool.definition.input_schema,
},
}));

const resp = await openai.responses.create({
model: "gpt-4o", input: prompt, tools: llmTools,
});
import { ScalekitClient } from "@scalekit-sdk/node";
import Anthropic from "@anthropic-ai/sdk";

const sk = new ScalekitClient(envUrl, clientId, clientSecret);
const anthropic = new Anthropic();

const { tools } = await sk.tools.listScopedTools("user_123", {
filter: { connectionNames: ["zenrowsmcp"], toolNames: ["zenrowsmcp_scrape", "zenrowsmcp_scrape", "zenrowsmcp_browser_screenshot"] },
pageSize: 100,
});

const llmTools = tools.map((t) => ({
name: t.tool.definition.name,
description: t.tool.definition.description,
input_schema: t.tool.definition.input_schema,
}));

const msg = await anthropic.messages.create({
model: "claude-sonnet-4-6", max_tokens: 1024,
tools: llmTools,
messages: [{ role: "user", content: prompt }],
});
import { Agent } from "@google/adk/agents";
import {
MCPToolset, StreamableHTTPConnectionParams,
} from "@google/adk/tools/mcp";

const toolset = new MCPToolset({
connectionParams: new StreamableHTTPConnectionParams({
url: "https://mcp.scalekit.com/zenrowsmcp",
headers: { Authorization: `Bearer ${userScopedToken}` },
}),
});

const agent = new Agent({
name: "agent", model: "gemini-2.0-flash",
tools: await toolset.getTools(),
});
Try these prompts
Paste any prompt into your research agent to start scraping web content via ZenRows.
Scrape & extract
Copy the prompt
Copied
Scrape [URL] and return the page content as markdown.
Copy the prompt
Copied
Extract all [data type] from [URL] with JavaScript rendering.
Copy the prompt
Copied
Take a full-page screenshot of [URL].
Research
Copy the prompt
Copied
Scrape the pricing page at [URL] and list all plans and prices.
Copy the prompt
Copied
Get structured product data from [e-commerce URL] using a custom schema.
Copy the prompt
Copied
Start a browser session and navigate through [multi-step workflow] on [URL].
SEE HOW AUTH WORKS
Users authorize ZenRows once. Their credentials stay vaulted, every scrape job runs under their account quota, and every call is logged.
1
Authorize
Your user connects
ZenRows MCP
once. We tie it to their identity and the meetings they approved — no shared bot account, no org-wide access
Who:
user ‘A’
when:
Once per user
access:
Limited to user
2
Store
Their
ZenRows MCP
token lives in a vault scoped to them. User A's meetings are never reachable by an agent acting for user B, even on the same connection
vault:
encrypted
scope:
per-user
tokens:
auto-refreshed
3
Resolve
When your agent calls a
ZenRows MCP
tool, we fetch the right token server-side. It never touches your agent, never appears in the LLM context, never shows up in your logs
speed:
~40ms
check:
before every call
seen by:
nobody
4
Audit
Every
ZenRows MCP
tool call is logged — who triggered it, which meeting was fetched, what came back. 90 days of history, tied to the user who authorized it
history:
90 days
export:
SIEM-ready
logged:
every call
Test other agents
Same per-user auth pattern across other developer tool and automation connectors.
Engineering Teams
DevOps assistant agent
Polls GitHub for failing checks and stale PRs, opens Linear issues for the ones that need work, and posts a daily digest to Slack. It acts as the engineer, not a shared service account.
Engineering Teams
Engineering standup agent
Pulls commits from GitHub and GitLab, tracks issue movement in Jira, and posts a per-engineer standup brief to Slack. Each engineer's activity is read on their own delegated OAuth.
Engineering Teams
Auto release notes agent
Reads merged GitHub PRs, groups them into structured release notes, publishes the page to Notion, and announces the release in Slack. Every call runs on the engineer's own delegated OAuth.
Engineering Teams
Slack triage
Polls Slack for new messages, classifies bugs and support requests with a LangGraph router, files GitHub issues or Zendesk tickets, and confirms in the thread.
Test other agents
Same per-user auth pattern across other developer tool and automation connectors.
ENGINEERING
DevOps assistant agent
Poll GitHub for failing checks and stale pull requests, open Linear issues for the ones that need work, and digest to Slack.
ENGINEERING
Auto-release notes agent
Group merged GitHub PRs into structured release notes, publish the page to Notion, and announce the release in Slack.
ENGINEERING
Engineering standup agent
Pull commits from GitHub and GitLab, track Jira issue movement, and post a per-engineer standup brief to Slack.
ENGINEERING
Slack triage agent
Classify new Slack messages as bugs or support requests, file the GitHub issue or Zendesk ticket, and reply in the thread.
Why Scalekit
Secure your agent's access. Connectors ship in minutes
01.
Shared tokens break per-user analytics
A shared token looks fine in a demo. In production every call looks like a service account. Scalekit resolves the real user credential so attribution, audit, and scope stay accurate.
// shared token
 audit → bot_service_account
 user_filter → broken

 // scalekit
 audit → user_abc
 scope → enforced ✓
02.
Authentication is not authorization
03.
Multi-tenancy is architectural
04.
ZenRows MCP today. Others tomorrow.
“Our agents act across Salesforce, Gong, Google Drive, and more, on behalf of every customer. Scalekit behind the scenes meant we can keep adding tools without ever rebuilding how credentials or tool calling work.”
Venu Madhav Kattagoni
Head of Engineering / Von
FAQs
Frequently Asked Questions
Does the agent use a shared ZenRows account or per-user accounts?
Per-user. Each developer's ZenRows credentials are vaulted under their identity. Scrape quota is tracked per user.
Where are ZenRows credentials stored?
In Scalekit's AES-256 vault, namespaced per tenant. Credentials resolve at request time and never appear in prompts.
Can I limit the agent to specific scraping operations?
Yes. Use listScopedTools to allow basic URL scraping without granting JS rendering or browser session creation.
What happens when a user's ZenRows credentials are revoked?
The next scrape call fails closed for that user. Other users remain unaffected. Revocation is logged.
Does this handle CAPTCHAs and bot detection?
Yes. ZenRows' anti-bot bypass handles CAPTCHAs, Cloudflare protection, and fingerprint detection at the infrastructure level.
Start in your coding agent
Up and running in one command
Install the Scalekit skill in your editor of choice. Connector, auth, tools, prompt, all wired up
Claude Code REPL
/plugin marketplace add scalekit-inc/claude-code-authstack
/plugin install agentkit@scalekit-auth-stack
Cursor Code REPL
# ~/.cursor/mcp.json
{
""mcpServers"": {
""zenrowsmcp"": {
""url"": ""https://mcp.scalekit.com/zenrowsmcp"",
""headers"": { ""Authorization"": ""Bearer $SCALEKIT_TOKEN"" }
}
}
}
Codex Code REPL
# ~/.codex/config.toml
[mcp_servers.zenrowsmcp]
url = ""https://mcp.scalekit.com/zenrowsmcp""
auth_env = ""SCALEKIT_TOKEN""
Copilot Code REPL
# .vscode/mcp.json
{
""servers"": {
""zenrowsmcp"": {
""url"": ""https://mcp.scalekit.com/zenrowsmcp"",
""type"": ""http""
}
}
}