Metadata-Version: 2.4
Name: mcp-server-screenshot
Version: 0.1.0
Summary: Pixel-perfect website screenshot service exposed as both REST API and MCP server
Project-URL: Homepage, https://github.com/therealMrFunGuy/mcp-server-screenshot
Project-URL: Repository, https://github.com/therealMrFunGuy/mcp-server-screenshot
Author: MFG
License-Expression: MIT
License-File: LICENSE
Keywords: api,mcp,playwright,screenshot
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Multimedia :: Graphics :: Capture :: Screen Capture
Requires-Python: >=3.11
Requires-Dist: fastapi>=0.115.0
Requires-Dist: mcp>=1.0.0
Requires-Dist: playwright>=1.49.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: uvicorn[standard]>=0.32.0
Description-Content-Type: text/markdown

# Screenshot API

Pixel-perfect website screenshot service that captures any URL as PNG, JPEG, or PDF. Exposed as both a REST API (FastAPI) and an MCP server for use with Claude Desktop, Cursor, and other MCP-compatible clients. Uses Playwright with a pooled Chromium browser for fast, reliable rendering.

## Quick Start

### Docker (recommended)

```bash
docker-compose up -d
```

The API will be available at `http://localhost:8500`.

### Local Development

```bash
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
bash setup_browsers.sh
python server.py
```

## MCP Installation

### Claude Desktop

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "screenshot": {
      "command": "python",
      "args": ["/path/to/mcp-services/screenshot-api/mcp_server.py"]
    }
  }
}
```

### Cursor

Add to your Cursor MCP settings:

```json
{
  "mcpServers": {
    "screenshot": {
      "command": "python",
      "args": ["/path/to/mcp-services/screenshot-api/mcp_server.py"]
    }
  }
}
```

### Via uvx (after PyPI publish)

```json
{
  "mcpServers": {
    "screenshot": {
      "command": "uvx",
      "args": ["mcp-server-screenshot"]
    }
  }
}
```

## API Documentation

### Endpoints

#### `POST /screenshot`

Take a screenshot with full control over parameters.

**Request body (JSON):**

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `url` | string | *required* | URL to capture |
| `viewport_width` | int | 1280 | Viewport width (320-3840) |
| `viewport_height` | int | 720 | Viewport height (240-2160) |
| `full_page` | bool | false | Capture entire scrollable page |
| `format` | string | "png" | Output: "png", "jpeg", or "pdf" |
| `wait_for` | string | null | CSS selector to wait for |
| `block_cookies` | bool | false | Block cookie consent banners |
| `inject_css` | string | null | Custom CSS to inject |
| `delay_ms` | int | 0 | Extra delay after load (0-10000) |

**Example:**

```bash
curl -X POST http://localhost:8500/screenshot \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "full_page": true, "format": "png"}' \
  -o screenshot.png
```

#### `GET /screenshot`

Simple GET-based screenshot (no CSS injection support).

```bash
curl "http://localhost:8500/screenshot?url=https://example.com&width=1920&height=1080&format=jpeg" -o screenshot.jpg
```

**Query parameters:** `url`, `width`, `height`, `full_page`, `format`, `wait_for`, `block_cookies`, `delay_ms`

#### `POST /screenshot/base64`

Same parameters as POST /screenshot, returns JSON with base64-encoded image.

```bash
curl -X POST http://localhost:8500/screenshot/base64 \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'
```

**Response:**

```json
{
  "url": "https://example.com",
  "format": "png",
  "content_type": "image/png",
  "base64": "iVBORw0KGgo...",
  "size_bytes": 45231
}
```

#### `GET /health`

Health check. Returns `{"status": "ok"}`.

#### `GET /stats`

Cache and usage statistics.

#### `POST /admin/keys`

Create API keys (requires `X-Admin-Key` header matching `ADMIN_KEY` env var).

```bash
curl -X POST "http://localhost:8500/admin/keys?key=my-api-key&tier=pro&owner=alice" \
  -H "X-Admin-Key: your-admin-key"
```

### Authentication

| Header | Description |
|--------|-------------|
| `X-API-Key` | Your API key. Omit for free tier. |

### Response Headers

| Header | Description |
|--------|-------------|
| `X-Cache-Key` | Truncated cache key for debugging |
| `X-Rate-Remaining` | Remaining requests today |

## MCP Tools

When used as an MCP server, two tools are available:

### `take_screenshot`

Returns the screenshot as a viewable image (ImageContent for PNG/JPEG, TextContent with base64 for PDF).

### `screenshot_to_base64`

Returns the screenshot as a base64 string in a TextContent response, suitable for passing to other tools or embedding.

Both tools accept: `url`, `viewport_width`, `viewport_height`, `full_page`, `format`, `wait_for`, `inject_css`.

## Pricing Tiers

| Tier | Daily Limit | Auth |
|------|-------------|------|
| Free | 100/day per IP | No key needed |
| Basic | 1,000/day | API key |
| Pro | 10,000/day | API key |
| Enterprise | 100,000/day | API key |

## Caching

Screenshots are cached using SHA256(url + params) as the key. Default TTL is 1 hour (configurable via `CACHE_TTL`). Expired entries are cleaned up automatically every 30 minutes.

## Self-Hosting

### Environment Variables

See `.env.example` for all options. Key settings:

- `CACHE_DIR` - Where cached screenshots are stored (default: `/data/cache`)
- `CACHE_TTL` - Cache duration in seconds (default: `3600`)
- `MAX_FREE_DAILY` - Free tier daily limit (default: `100`)
- `ADMIN_KEY` - Secret key for the admin endpoints
- `PORT` - API port (default: `8500`)

### Docker Resource Limits

The default `docker-compose.yml` limits the container to 2 CPU cores and 2GB RAM. Adjust in the `deploy.resources` section as needed.

### Persistent Storage

The docker-compose file uses a named volume `screenshot-data` for the cache and SQLite database. To use a host directory instead:

```yaml
volumes:
  - /path/on/host:/data
```
