Skip to main content
Glama
Website-Screenshot-Online

WebsiteScreenshot.online MCP Server

Official
README.md
# WebsiteScreenshot.online MCP Server

[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Node >= 18.18](https://img.shields.io/badge/node-%E2%89%A5%2018.18-green.svg)](package.json)
[![MCP](https://img.shields.io/badge/MCP-compatible-purple.svg)](https://modelcontextprotocol.io/)

A [Model Context Protocol](https://modelcontextprotocol.io/) server that wraps
the [WebsiteScreenshot.online](https://websitescreenshot.online) REST API and
exposes it as three MCP tools any MCP-compatible host (Claude Desktop,
Claude Code, Cursor, Cline, Continue, Zed, Raycast, โ€ฆ) can call directly.

---

## โšก Most users don't need this package

If you just want your AI assistant to take screenshots and record videos,
**use the hosted endpoint instead** โ€” zero install, one line of JSON:

> **<https://websitescreenshot.online/api/mcp>**

See the [per-host configuration snippets](https://websitescreenshot.online/en/docs/mcp)
for Claude Code, Claude Desktop, Cursor, Cline, Codex CLI, Gemini CLI,
Continue, Windsurf, and Zed.

You only need this npm package if **one of the following applies**:

- ๐Ÿ›ฐ๏ธ **Air-gapped or restricted network** โ€” your AI host cannot reach
  `websitescreenshot.online` directly.
- ๐Ÿ  **Self-hosted WebsiteScreenshot** โ€” you run your own instance and need
  `SCREENSHOT_API_BASE` pointing at it.
- ๐Ÿ”ง **You want to audit / modify the server** โ€” this is the same code the
  hosted endpoint runs, just without the Next.js wrapper.

In every other case, the hosted endpoint is strictly better (no Node
dependency, automatic updates, no maintenance burden).

---

## 1. Prerequisites

- **Node.js โ‰ฅ 18.18** (LTS recommended)
- A free or paid [WebsiteScreenshot.online](https://websitescreenshot.online) account
- A WebsiteScreenshot.online **API key** (see [ยง 2](#2-get-an-api-key))

---

## 2. Get an API key

1. Sign up at <https://websitescreenshot.online> (GitHub OAuth or email).
2. Switch to your locale if needed (e.g. `/en/dashboard/api-keys`,
   `/zh-CN/dashboard/api-keys`).
3. Open **Dashboard โ†’ API Keys โ†’ Create new key**.
4. Copy the key. It starts with `ws_` followed by 64 hex chars
   (e.g. `ws_<your-key-here>`)
   and is shown **once** โ€” store it somewhere safe.

> The MCP server only ever reads the key from the environment. It is never
> logged, never sent to the model, and never written to disk by this package.

---

## 3. Install & build

```bash
git clone https://github.com/Website-Screenshot-Online/websitescreenshot-mcp.git
cd websitescreenshot-mcp
npm install
npm run build
```

That's it โ€” `build/index.js` is a self-contained executable you can wire into
any MCP host.

---

## 4. Configure your MCP host

### Claude Desktop โ€” `claude_desktop_config.json`

`~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or
`%APPDATA%/Claude/claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "websitescreenshot": {
      "command": "node",
      "args": ["/absolute/path/to/websitescreenshot-mcp/build/index.js"],
      "env": {
        "SCREENSHOT_API_KEY": "ws_replace_with_your_real_api_key",
        "SCREENSHOT_REQUEST_TIMEOUT_MS": "60000"
      }
    }
  }
}
```

### Claude Code โ€” `~/.claude.json`

```jsonc
{
  "mcpServers": {
    "websitescreenshot": {
      "type": "stdio",
      "command": "node",
      "args": ["/absolute/path/to/websitescreenshot-mcp/build/index.js"],
      "env": {
        "SCREENSHOT_API_KEY": "ws_replace_with_your_real_api_key"
      }
    }
  }
}
```

### Cursor / VS Code (`.cursor/mcp.json`)

```json
{
  "mcpServers": {
    "websitescreenshot": {
      "command": "node",
      "args": ["/absolute/path/to/websitescreenshot-mcp/build/index.js"],
      "env": { "SCREENSHOT_API_KEY": "ws_replace_with_your_real_api_key" }
    }
  }
}
```

### Cline / Continue / Zed / Raycast

All accept the same `command + args + env` shape โ€” just point them at
`build/index.js` and pass `SCREENSHOT_API_KEY` through `env`.

Restart the host after editing its config and the three tools will show up in
its tool palette.

---

## 5. Self-hosted WebsiteScreenshot

If you run your own WebsiteScreenshot instance, point the server at it:

```json
"env": {
  "SCREENSHOT_API_KEY": "ws_replace_with_your_real_api_key",
  "SCREENSHOT_API_BASE": "https://your-self-hosted.example.com"
}
```

---

## 6. Usage examples

> You don't write JSON manually โ€” the model does. These are the payloads the
> model will actually send.

### Screenshot โ€” viewport of a landing page

```text
take_screenshot({
  url: "https://example.com",
  resolution: { width: 1440, height: 900 },
  format: "png",
  fullSize: false,
  blockAds: true,
  blockCookiesGdpr: true,
  delay: 1
})
```

### Screenshot โ€” full-page PDF for archival

```text
take_screenshot({
  url: "https://news.ycombinator.com",
  fullSize: true,
  format: "pdf"
})
```

### Synchronous video (โ‰ค 6 min)

```text
record_website_video({
  url: "https://stripe.com",
  format: "mp4",
  scrollMode: "smooth",
  smoothScrollSpeed: "normal",
  resolution: { width: 1280, height: 720 }
})
```

### Async video + status polling

```text
record_website_video({ url: "https://stripe.com", async: true })
// โ†’ { "success": true, "requestId": "f7c1..." }

check_video_status({ requestId: "f7c1..." })
// โ†’ { "status": "pending", ... }  // poll again
// โ†’ { "status": "completed", "videoUrl": "https://...", ... }
```

---

## 7. Tool reference

### `take_screenshot`

| Field             | Type                          | Default     | Notes                                   |
| ----------------- | ----------------------------- | ----------- | -------------------------------------- |
| `url`             | string (URL)                  | โ€”           | **required**                           |
| `resolution`      | `{ width, height }`           | 1920ร—1080   | Any preset or custom size              |
| `fullSize`        | bool                          | `false`     | Capture entire scrollable page         |
| `format`          | `png` \| `jpeg` \| `pdf`      | `png`       |                                        |
| `blockCookiesGdpr`| bool                          | `true`      | Dismiss cookie banners first           |
| `blockAds`        | bool                          | `true`      | Block ad networks                      |
| `delay`           | int (0โ€“10 seconds)            | `1`         | Wait before capturing                  |

Response shape:

```json
{
  "success": true,
  "imageUrl": "https://websitescreenshot.online/screenshots/abc.png",
  "filename": "abc.png"
}
```

### `record_website_video`

Same fields as above plus:

| Field              | Type                            | Default   |
| ------------------ | ------------------------------- | --------- |
| `format`           | `webm` \| `mp4` \| `gif`        | `webm`    |
| `scrollMode`       | `step` \| `smooth`              | `step`    |
| `smoothScrollSpeed`| `slow` \| `normal` \| `fast`    | `normal`  |
| `scrollDistance`   | int 100โ€“1000 (px)               | `500`     |
| `scrollDelay`      | int 200โ€“5000 (ms)               | `1000`    |
| `async`            | bool                            | `false`   |

Sync response:

```json
{ "success": true, "videoUrl": "https://โ€ฆ/abc.webm", "filename": "abc.webm" }
```

Async response:

```json
{ "success": true, "requestId": "f7c1โ€ฆ" }
```

### `check_video_status`

| Field        | Type   |
| ------------ | ------ |
| `requestId`  | string |

Response:

```json
{
  "status": "completed",
  "siteUrl": "https://โ€ฆ",
  "result": { "success": true, "videoUrl": "https://โ€ฆ", "filename": "abc.webm" },
  "updatedAt": 1730000000000
}
```

`status` is one of `pending` | `completed` | `error`. Results are kept
for **24 hours** then deleted.

---

## 8. Error handling

Every API error is mapped to an MCP `isError: true` result containing
`code`, `status`, and `error` fields. Common codes:

| Code                  | Meaning                                              |
| --------------------- | ---------------------------------------------------- |
| `UNAUTHORIZED`        | Missing / revoked key                                |
| `RATE_LIMITED`        | Per-key or per-IP limit hit; retry later             |
| `USAGE_LIMIT_EXCEEDED`| Plan quota exhausted                                 |
| `INVALID_PARAMETERS`  | Input failed Zod validation                          |
| `INTERNAL_ERROR`      | Server-side bug; retry with backoff                  |
| `TIMEOUT`             | Request took longer than `SCREENSHOT_REQUEST_TIMEOUT_MS` |
| `NOT_FOUND`           | `requestId` unknown or expired                       |

Rate limits: **10 screenshots / min** and **5 videos / min** per API key.

---

## 9. Environment variables

| Variable                          | Required | Default                              | Purpose                                |
| --------------------------------- | -------- | ------------------------------------ | ------------------------------------- |
| `SCREENSHOT_API_KEY`              | **yes**  | โ€”                                    | The Bearer token sent to the API      |
| `SCREENSHOT_API_BASE`             | no       | `https://websitescreenshot.online`   | Override for self-hosted / staging      |
| `SCREENSHOT_REQUEST_TIMEOUT_MS`   | no       | `60000`                              | Per-request abort timeout (ms)         |

---

## 10. Development

```bash
npm run dev       # tsx, hot reload stdio
npm run lint      # type-check only
npm run build     # emit build/index.js
```

To point the dev server at a self-hosted API:

```bash
SCREENSHOT_API_BASE=http://localhost:3000 \
SCREENSHOT_API_KEY=ws_dev_replace_me \
npm run dev
```

---

## 11. License

MIT ยฉ Crownbyte LTD โ€” see [LICENSE](LICENSE).

> Website: <https://websitescreenshot.online>
> Hosted MCP: <https://websitescreenshot.online/api/mcp>
> Docs: <https://websitescreenshot.online/en/docs/mcp>
> Support: <support@websitescreenshot.online>

TDQS

A4.2/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct role: take_screenshot captures an image, record_website_video captures a video, and check_video_status polls an async video job. There is no ambiguity about which tool to select for a given task.

Naming Consistency5/5

All tool names follow a consistent snake_case verb_noun pattern: take_screenshot, record_website_video, check_video_status. The pattern is predictable and clearly indicates the action being performed.

Tool Count5/5

Three tools is well-scoped for a screenshot/video capture server: one for screenshots, one for video, and one for async status polling. Each tool earns its place without unnecessary redundancy.

Completeness4/5

The core capture lifecycle is covered: synchronous screenshot capture, synchronous or asynchronous video capture, and async job polling. Minor gaps exist such as listing or canceling active video jobs, but the main workflows are fully usable.

Maintenance

ActivityMaintained
ResponsivenessNo issues