Back to MCP Servers

Page Capture

MCP server that captures webpage screenshots, with viewport or full-page options and base64 PNG output.

search-data-extraction
By chasesaurabh
32Updated 6 months agoTypeScriptMIT

Installation

npx -y mcp-page-capture

Configuration

{
  "mcpServers": {
    "mcp-page-capture": {
      "command": "npx",
      "args": ["-y", "mcp-page-capture"]
    }
  }
}

How to use

  1. Run the installation command above (if needed)
  2. Open your Claude Code settings file (~/.claude/settings.json)
  3. Add the configuration to the mcpServers section
  4. Restart Claude Code to apply changes

mcp-page-capture

npm version GitHub stars License: MIT Node.js MCP Server

mcp-page-capture logo placeholder

mcp-page-capture is a Model Context Protocol (MCP) server that orchestrates headless Chromium via Puppeteer to capture pixel-perfect screenshots of arbitrary URLs. It is optimized for Copilot/MCP-enabled environments and can be embedded into automated workflows or run as a standalone developer tool.

Features

  • šŸ“ø High-fidelity screenshots powered by Puppeteer and headless Chromium
  • āš™ļø LLM-optimized schema with minimal parameters exposed and sensible defaults
  • šŸ” Structured DOM extraction with optional CSS selectors for AI-friendly consumption
  • šŸ“± Device presets for mobile emulation (iPhone, iPad, Android, desktop)
  • šŸŽÆ 6 simplified steps for LLM friendliness: viewport, wait, fill, click, scroll, screenshot
  • šŸ¤– Smart defaults - screenshot auto-captured, field types auto-detected
  • šŸ†• Consistent parameters - target for elements, for for waiting, to for scrolling, device for viewport
  • šŸ”„ Automatic retry with exponential backoff for transient failures
  • šŸ“Š Telemetry hooks for centralized observability and monitoring
  • šŸ’¾ Pluggable storage backends (local filesystem, S3, memory)
  • šŸ›”ļø Structured logging plus defensive error handling for operational visibility
  • šŸ”Œ Launch via npm start, npm run dev, or as a long-lived MCP sidecar
  • 🐳 Docker image with multi-platform support (amd64, arm64)

How It Works

  1. The MCP transport boots a Node.js server and registers the captureScreenshot and extractDom tools.
  2. Incoming tool invocations are validated against the relevant type definitions.
  3. Puppeteer starts (or reuses) a Chromium instance, navigates to the requested URL, and either captures a screenshot or serializes the DOM according to the tool parameters.
  4. The server returns structured content (images, text, DOM trees, metadata) to the caller or downstream workflow.

Requirements

  • Node.js ≄ 18.x
  • npm ≄ 9.x
  • Chromium package download permissions (first run)
  • Network access to the target URLs

🌟 LLM-Friendly Features

Simplified Schema (5-Star LLM Rating)

  • āœ… Only 4 top-level parameters: url, steps, headers, validate
  • āœ… Exactly 6 step types (no more, no less)
  • āœ… Consistent parameter naming across all steps
  • āœ… Automatic screenshot if omitted
  • āœ… Smart field type detection
  • āœ… Actionable error messages with recovery suggestions
  • āœ… Single source of truth for all schemas
  • āœ… Deprecation warnings for legacy parameters
  • āœ… NEW: Validate mode for pre-flight step checking
  • āœ… NEW: Step order enforcement with auto-correction
  • āœ… NEW: Embedded LLM reference in MCP server instructions

Quick Start for LLMs

See LLM Quick Reference for the 6 primary step types and common patterns.

For advanced features, see Advanced Steps.

The 6 Step Types (Exactly 6, No More)

StepPurposeKey ParametersExample
viewportSet devicedevice, width, height{ "type": "viewport", "device": "mobile" }
waitWait for element/timefor OR duration, timeout{ "type": "wait", "for": ".loaded" }
fillFill form fieldtarget, value, submit{ "type": "fill", "target": "#email", "value": "a@b.com" }
clickClick elementtarget, waitFor{ "type": "click", "target": "button", "waitFor": ".result" }
scrollScroll pageto, y{ "type": "scroll", "to": "#footer" }
screenshotCapture (auto-added)fullPage, element{ "type": "screenshot", "fullPage": true }

Step Order: Auto-fixed! viewport auto-moves to first, screenshot auto-added at end.

Composite Patterns (NEW)

High-level patterns that auto-expand to multiple steps:

// Login pattern
{
  "type": "login",
  "email": { "selector": "#email", "value": "user@example.com" },
  "password": { "selector": "#password", "value": "secret" },
  "submit": "button[type=submit]",
  "successIndicator": ".dashboard"
}

// Search pattern  
{
  "type": "search",
  "input": "#search-box",
  "query": "MCP protocol",
  "resultsIndicator": ".search-results"
}

Installation

From source (recommended during development)

git clone https://github.com/chasesaurabh/mcp-page-capture.git
npm install

From npm

# Run without installing globally
npx mcp-page-capture

# Or add it to your toolchain
npm install -g mcp-page-capture
mcp-page-capture

Running the server

npm install
npm run build
npm start

For hot reload while iterating locally, run npm run dev.

Why Docker?

  • Guarantees a consistent Puppeteer + Chromium environment with all system libraries when teammates or CI run the server. No more "it works on my machine" mismatches.
  • Provides a ready-to-deploy container image for hosting mcp-page-capture as a sidecar/service on Kubernetes, ECS, Fly.io, etc.

If you need those guarantees, build and run via:

docker build -t mcp-page-capture .
docker run --rm -it mcp-page-capture

Otherwise you can keep using the standard npm scripts locally.

IDE MCP configuration

{
  "mcpServers": {
    "page-capture": {
      "command": "node",
      "args": ["dist/cli.js"]
    }
  }
}

Note: You may need to use the full path to dist/cli.js or node depending on your working directory and Node.js module resolution configuration.

Programmatic usage

If you want to embed the server inside another Node.js process, import the helpers exposed by the package:

import { startMcpPageCaptureServer } from "mcp-page-capture";

await startMcpPageCaptureServer();
// Optionally pass a custom Transport implementation if you don't want stdio.

Usage

Tool invocation examples

Basic Screenshot

{
  "tool": "captureScreenshot",
  "params": {
    "url": "https://example.com"
  }
}

Note: A screenshot is automatically captured at the end if no explicit screenshot step is provided.

Search with Fill Step (Recommended)

The fill step auto-detects field types and handles text inputs, selects, checkboxes, and radio buttons.

{
  "tool": "captureScreenshot",
  "params": {
    "url": "https://example.com",
    "steps": [
      { "type": "fill", "target": "#search", "value": "MCP protocol", "submit": true },
      { "type": "wait", "for": ".search-results" },
      { "type": "screenshot" }
    ]
  }
}

Login Form Example

{
  "tool": "captureScreenshot",
  "params": {
    "url": "https://example.com/login",
    "steps": [
      { "type": "wait", "for": "#login-form" },
      { "type": "fill", "target": "#email", "value": "user@example.com" },
      { "type": "fill", "target": "#password", "value": "secretpassword" },
      { "type": "fill", "target": "#remember-me", "value": "true" },
      { "type": "click", "target": "button[type=submit]", "waitFor": ".dashboard" },
      { "type": "screenshot" }
    ]
  }
}

Full Page Screenshot

{
  "tool": "captureScreenshot",
  "params": {
    "url": "https://docs.modelcontextprotocol.io",
    "steps": [
      { "type": "screenshot", "fullPage": true }
    ]
  }
}

With Authentication and Cookies

{
  "tool": "captureScreenshot",
  "params": {
    "url": "https://example.com/dashboard",
    "headers": {
      "authorization": "Bearer dev-token"
    },
    "steps": [
      {
        "type": "cookie",
        "action": "set",
        "name": "session",
        "value": "abc123",
        "path": "/secure"
      },
      { "type": "screenshot" }
    ]
  }
}

Extract DOM Content

{
  "tool": "extractDom",
  "params": {
    "url": "https://docs.modelcontextprotocol.io",
    "selector": "main article"
  }
}

Mobile Device Emulation

{
  "tool": "captureScreenshot",
  "params": {
    "url": "https://example.com",
    "steps": [
      { "type": "viewport", "device": "ipad-pro" },
      { "type": "scroll", "to": "#main-content" },
      { "type": "screenshot" }
    ]
  }
}

Step Types

6 Primary Steps (LLM-Exposed)

These are the only steps exposed to LLMs. They cover 95%+ of use cases:

StepPurposeParameters
viewportSet device/screen sizedevice, width, height
waitWait for element/timefor OR duration, timeout
fillFill form fieldtarget, value, submit
clickClick elementtarget, waitFor
scrollScroll pageto (selector), y (pixels)
screenshotCapture (auto-added)fullPage, element

Validate Mode (NEW)

Use validate: true to check steps before execution:

{
  "tool": "captureScreenshot",
  "params": {
    "url": "https://example.com",
    "steps": [
      { "type": "fill", "target": "#email", "value": "test@example.com" },
      { "type": "click", "target": "button" }
    ],
    "validate": true
  }
}

Returns validation analysis including:

  • Errors: Missing required parameters
  • Warnings: Step order issues (e.g., viewport not first)
  • Suggestions: Recommended improvements (e.g., add waitFor to click)
  • Step analysis: Per-step status and notes

Deprecated Steps (Legacy Support Only)

These work at runtime but are not exposed in the LLM schema. Use the 6 primary steps instead:

DeprecatedUse Instead
quickFillfill with submit: true
fillFormMultiple fill steps
waitForSelectorwait with for parameter
delaywait with duration parameter
fullPagescreenshot with fullPage: true

Internal Steps (Not Exposed)

These are for power users only and are not documented in the tool schema:

type, hover, cookie, storage, evaluate, keypress, focus, blur, clear, upload, submit

Legacy Parameter Support

For backward compatibility, these parameters work at runtime but are not exposed in the LLM schema:

Legacy ParameterCanonicalNotes
selectortargetUse target for element selectors
awaitElementforUse for in wait steps
scrollTotoUse to in scroll steps
presetdeviceUse device in viewport steps
captureElementelementUse element in screenshot steps
waitAfterwaitUse wait in click steps

Deprecation warnings are logged when legacy parameters are used.

Example response

{
  "content": [
    {
      "type": "text",
      "text": "mcp-page-capture screenshot\nURL: https://example.com\nCaptured: 2025-12-13T08:30:12.713Z\nFull page: false\nViewport: 1280x720\nDocument: 1280x2000\nScroll position: (0, 0)\nSize: 45.2 KB\nSteps executed: 5"
    },
    {
      "type": "image",
      "mimeType": "image/png",
      "data": "iVBORw0KGgoAAAANSUhEUgA..."
    }
  ]
}

## Supported options

### `captureScreenshot`
- `url` (string, required): Fully-qualified URL to capture
- `headers` (object, optional): Key/value map of HTTP headers to send with the initial page navigation
- `cookies` (array, optional): List of cookies to set before navigation. Each cookie supports `name`, `value`, and optional `url`, `domain`, `path`, `secure`, `httpOnly`, `sameSite`, and `expires` (Unix timestamp, sec

…
View source on GitHub