# CaptureWeb for AI Agents & MCP

CaptureWeb gives AI agents, Claude, Cursor, Codex, and any MCP-compatible client the ability to see the web — screenshots, PDFs, clean Markdown, structured JSON, and full accessibility trees from any URL.

---

## MCP setup (2 minutes)

### 1. Get your API key

Sign up at https://captureweb.dev/signup — 100 free credits, no card required.

### 2. Add to Claude Desktop

Open `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) and add:

```json
{
  "mcpServers": {
    "captureweb": {
      "command": "npx",
      "args": ["-y", "@captureweb/mcp"],
      "env": {
        "CAPTUREWEB_API_KEY": "pk_live_YOUR_KEY"
      }
    }
  }
}
```

Restart Claude Desktop. You'll see CaptureWeb tools in the tool picker.

### 3. Add to Cursor

Open Cursor → Settings → MCP and add:

```json
{
  "captureweb": {
    "command": "npx",
    "args": ["-y", "@captureweb/mcp"],
    "env": {
      "CAPTUREWEB_API_KEY": "pk_live_YOUR_KEY"
    }
  }
}
```

### 4. Add to any MCP client (generic stdio)

```json
{
  "mcpServers": {
    "captureweb": {
      "command": "npx",
      "args": ["-y", "@captureweb/mcp"],
      "env": {
        "CAPTUREWEB_API_KEY": "pk_live_YOUR_KEY"
      }
    }
  }
}
```

---

## Available tools

| Tool | Description | Credits |
|------|-------------|---------|
| `screenshot` | Pixel-accurate PNG/JPEG/WebP from any URL | 1 |
| `pdf` | Export any URL as A4 PDF | 1 |
| `markdown` | Clean, LLM-ready Markdown — nav/footer stripped | 1 |
| `content` | Full rendered HTML after JS execution | 1 |
| `links` | All hyperlinks on a page as a JSON array | 1 |
| `scrape` | Structured data via CSS selectors | 1 |
| `json_extract` | AI-powered JSON extraction with a plain-English prompt | 3 |
| `snapshot` | Screenshot + PDF + HTML + Markdown in one navigation | 2 |
| `a11y` | Full ARIA accessibility tree as JSON | 1 |
| `crawl` | Async full-site crawl with webhook on completion | 1/page |
| `brand` | Logo, favicon, color palette, fonts, and OG data from any domain | 1 |

---

## Tool reference

### `screenshot`

Capture a screenshot of any URL. Renders full JavaScript — works on SPAs.

```
screenshot(url, format?, width?, height?, full_page?, dark_mode?, block_ads?, fresh?)
```

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `url` | string | required | Target URL |
| `format` | png\|jpeg\|webp | png | Image format |
| `width` | number | 1280 | Viewport width |
| `height` | number | 800 | Viewport height |
| `full_page` | boolean | false | Full scrollable page |
| `dark_mode` | boolean | false | Dark colour scheme |
| `block_ads` | boolean | false | Block ad networks |
| `fresh` | boolean | false | Bypass cache |

Returns an **image** content block (rendered inline by Claude Desktop).

---

### `pdf`

Export any URL as a PDF document.

```
pdf(url, fresh?)
```

Returns a **resource** content block with `application/pdf` MIME type.

---

### `markdown`

Extract clean Markdown from any URL. Strips nav, footer, ads, and cookie banners. Ideal for RAG ingestion, summarisation, and feeding pages into context.

```
markdown(url, fresh?)
```

Returns **text** content with the extracted Markdown.

---

### `content`

Fetch the full rendered HTML after JavaScript execution.

```
content(url, clean?, fresh?)
```

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `clean` | boolean | false | Strip scripts, styles, and ad patterns |

---

### `links`

Extract all hyperlinks from a page after JS rendering.

```
links(url, fresh?)
```

Returns a JSON array of absolute URLs.

---

### `scrape`

Extract structured data via CSS selectors.

```
scrape(url, selectors, fresh?)
```

`selectors` is an array of `{ name, selector, attribute? }` objects:

```json
[
  { "name": "title", "selector": "h1" },
  { "name": "price", "selector": ".price", "attribute": "data-value" },
  { "name": "images", "selector": "img.product", "attribute": "src" }
]
```

---

### `json_extract`

AI-powered structured extraction. Describe what you want in plain English — optionally enforce the shape with a JSON Schema.

```
json_extract(url, prompt, schema?, fresh?)
```

Example prompt: `"Extract all pricing tiers with name, monthly price, and feature list"`

---

### `snapshot`

One browser navigation returns everything: screenshot, PDF, HTML, and Markdown. Most efficient when you need multiple formats.

```
snapshot(url, format?, full_page?, fresh?)
```

Returns an **image** block plus a **text** block with extracted Markdown.

---

### `a11y`

Extract the ARIA accessibility tree as JSON. Useful for:
- Giving agents a structured, semantic page representation for navigation
- Identifying interactive elements (buttons, inputs, links) to act on
- Accessibility audits

```
a11y(url, interesting_only?, root?, fresh?)
```

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `interesting_only` | boolean | true | Only semantically meaningful nodes |
| `root` | string | — | CSS selector to anchor tree to a subtree |

---

### `crawl`

Crawl an entire site asynchronously. Returns a job ID immediately — use a webhook or poll `/v1/jobs/{id}` for results.

```
crawl(url, max_depth?, max_pages?, include_pattern?, webhook_url?)
```

| Param | Type | Default | Description |
|-------|------|---------|-------------|
| `max_depth` | number | 2 | Link depth from seed URL |
| `max_pages` | number | 50 | Max pages to crawl |
| `include_pattern` | string | — | Regex — only crawl matching URLs |
| `webhook_url` | string | — | POST results here on completion |

### `brand`

Extract brand assets from any domain in one fast call (plain fetch, no browser needed).

```
brand(url)
```

Returns `{ favicon, logo, og_image, og_title, og_description, colors[], fonts[], twitter_card, timing_ms, credits }`.

---

## Example prompts for Claude

Once the MCP server is connected, try these:

- *"Take a screenshot of stripe.com/pricing and describe the layout"*
- *"Extract all product names and prices from amazon.com/s?k=keyboards as JSON"*
- *"Get the markdown from the OpenAI blog and summarise the last 5 posts"*
- *"Check the accessibility tree of github.com and tell me if the main nav is keyboard-accessible"*
- *"Crawl the docs at docs.example.com (max 20 pages) and compile a single reference document"*
- *"Take a full-page screenshot of linear.app in dark mode"*

---

## Using the REST API directly in agents

If you'd rather call the API directly from your agent code:

```python
import os, requests

API = "https://api.captureweb.dev"
KEY = os.environ["CAPTUREWEB_API_KEY"]

# Extract Markdown for RAG
res = requests.post(f"{API}/v1/markdown",
    headers={"Authorization": f"Bearer {KEY}"},
    json={"url": "https://openai.com/blog"}
)
markdown = res.json()["markdown"]

# Screenshot
res = requests.post(f"{API}/v1/screenshot",
    headers={"Authorization": f"Bearer {KEY}"},
    json={"url": "https://stripe.com/pricing", "full_page": True}
)
open("screenshot.png", "wb").write(res.content)
```

```typescript
const API = "https://api.captureweb.dev"
const KEY = process.env.CAPTUREWEB_API_KEY

// Extract accessibility tree for agent navigation
const res = await fetch(`${API}/v1/a11y`, {
  method: "POST",
  headers: { Authorization: `Bearer ${KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ url: "https://github.com" }),
})
const { tree } = await res.json()
```

---

## Caching

All endpoints cache results for 24 hours in R2. Cache hits are **free** (0 credits). Force a fresh render with `fresh: true`.

## Credits

- Free: 100 credits/month
- Starter ($29/mo): 1,000 credits
- Pro ($99/mo): 10,000 credits
- Ultimate ($249/mo): 50,000 credits

Full pricing: https://captureweb.dev/pricing
