Agent Skills

mcp-screenshot-server

An MCP server that provides AI assistants with screenshot capabilities — both web page capture via Puppeteer and cross-platform system screenshots using native OS tools.

Install

npx -y universal-screenshot-mcp
README.md

Universal Screenshot MCP

npm version MCP Registry License

An MCP (Model Context Protocol) server that provides AI assistants with screenshot capabilities — both web page capture via Puppeteer and cross-platform system screenshots using native OS tools.

Features

  • Web Page Screenshots — Capture any public URL using a headless Chromium browser
  • Cross-Platform System Screenshots — Fullscreen, window, or region capture using native OS tools (macOS screencapture, Linux maim/scrot/gnome-screenshot/etc., Windows PowerShell+.NET)
  • Security-First Design — SSRF prevention, path traversal protection, DNS rebinding defense, command injection prevention, and DoS limiting
  • MCP Native — Integrates directly with Claude Desktop, Cursor, and any MCP-compatible client

Requirements

  • Node.js >= 18.0.0
  • Chromium is downloaded automatically by Puppeteer on first run

Platform-Specific Requirements for take_system_screenshot

Platform Required Tools Notes
macOS screencapture (built-in) No additional installation needed
Linux One of: maim, scrot, gnome-screenshot, spectacle, grim, or import (ImageMagick) maim or scrot recommended for full feature support. For window-by-name capture, also install xdotool.
Windows powershell (built-in) Uses .NET System.Drawing — no additional installation needed

Linux Installation Examples

# Ubuntu/Debian (recommended)
sudo apt install maim xdotool

# Fedora
sudo dnf install maim xdotool

# Arch Linux
sudo pacman -S maim xdotool

# Wayland (Sway, etc.)
sudo apt install grim

After installing, you can verify your setup with:

npx universal-screenshot-mcp --doctor

This probes the host and prints copy-pasteable install commands for any missing tools, tailored to your detected distro.

Quick Start

Install from npm

npm install -g universal-screenshot-mcp

Or run directly with npx:

npx universal-screenshot-mcp

Install from Source

git clone https://github.com/sethbang/mcp-screenshot-server.git
cd mcp-screenshot-server
npm install
npm run build

Configure Your MCP Client

Add the server to your MCP client configuration. For Claude Desktop, edit ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "screenshot-server": {
      "command": "npx",
      "args": ["-y", "universal-screenshot-mcp"]
    }
  }
}

Or if installed from source:

{
  "mcpServers": {
    "screenshot-server": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-screenshot-server/build/index.js"]
    }
  }
}

For Claude Code, register the server with the claude mcp add command:

# Project scope (current directory only)
claude mcp add screenshot-server -- npx -y universal-screenshot-mcp

# User scope (available across all projects)
claude mcp add --scope user screenshot-server -- npx -y universal-screenshot-mcp

Or if installed from source:

claude mcp add screenshot-server -- node /absolute/path/to/mcp-screenshot-server/build/index.js

Verify the server registered with claude mcp list, or check live status from inside a session with /mcp.

For Cursor or other MCP clients, consult their documentation for the equivalent configuration.

Tools

The server exposes two MCP tools:

take_screenshot

Captures a web page (or a specific element) via a headless Puppeteer browser.

Parameter Type Required Description
url string ✅ URL to capture (http/https only)
width number — Viewport width (1–3840)
height number — Viewport height (1–2160)
fullPage boolean — Capture the full scrollable page
selector string — CSS selector to capture a specific element
waitForSelector string — Wait for this selector before capturing
waitForTimeout number — Delay in milliseconds (0–30000)
outputPath string — Output file path (default: ~/Documents/screenshots)

Example prompt:

Take a screenshot of https://example.com at 1920x1080

take_system_screenshot

Captures the desktop, a specific application window, or a screen region using native OS tools. Works on macOS, Linux, and Windows.

Parameter Type Required Description
mode enum ✅ fullscreen, window, or region
windowId number — Window ID for window mode
windowName string — App name (e.g. "Safari", "Firefox") for window mode
region object — { x, y, width, height } for region mode
display number — Display number for multi-monitor setups
includeCursor boolean — Include the mouse cursor in the capture
format enum — png (default) or jpg
delay number — Capture delay in seconds (0–10)
outputPath string — Output file path (default: ~/Documents/screenshots)

Cross-Platform Feature Support

Feature macOS Linux Windows
Fullscreen ✅ ✅ ✅
Region ✅ ✅ (maim, scrot, grim, import) ✅
Window by name ✅ ⚠️ X11 + xdotool ⚠️ best-effort
Window by ID ✅ ✅ X11 only ⚠️ HWND
Multi-display ✅ ⚠️ tool-dependent ✅
Include cursor ✅ ⚠️ tool-dependent ⚠️
Delay ✅ ✅ ✅

Example prompt:

Take a system screenshot of the Safari window

Configuration

Environment Variables

Variable Default Description
SCREENSHOT_OUTPUT_DIR Documents/screenshots Default output directory relative to ~
ALLOW_LOCAL false Set to true to allow screenshotting localhost/127.x.x.x/[::1] (useful for local dev servers)

Output Directories

Screenshots are saved to ~/Documents/screenshots by default (configurable via SCREENSHOT_OUTPUT_DIR). Custom output paths must resolve to one of these allowed directories:

Directory Description
~/Documents/screenshots Default output location (configurable)
~/Desktop/Screenshots Original default location
~/Downloads User downloads folder
~/Documents User documents folder
/tmp System temp directory

Security

This server implements multiple layers of security hardening:

ID Threat Mitigation
SEC-001 SSRF / DNS rebinding URLs validated against blocked IP ranges; DNS resolved pre-request with IP pinning via --host-resolver-rules; navigation redirects re-validated
SEC-003 Command injection All subprocesses use execFile (no shell); app names validated against SAFE_APP_NAME_PATTERN
SEC-004 Path traversal Output paths validated with fs.realpath() symlink resolution; restricted to allowed directories
SEC-005 Denial of service Concurrent Puppeteer instances limited to 3 via semaphore

For full details, see docs/security.md.

Development

Scripts

Command Description
npm run build Compile TypeScript to build/
npm run watch Recompile on file changes
npm test Unit tests (fast, fully mocked)
npm run test:integration Integration tests (real DNS/filesystem)
npm run test:e2e E2E tests (real Puppeteer/native tools)
npm run test:all All test tiers together
npm run test:linux Linux e2e via Docker (requires Docker)
npm run test:watch Run tests in watch mode
npm run test:coverage Run tests with coverage report
npm run lint Lint source with ESLint
npm run inspector Launch MCP Inspector for debugging

Project Structure

src/
├── index.ts                 # Entry point — stdio transport
├── server.ts                # MCP server factory
├── config/
│   ├── index.ts             # Static constants (limits, allowed dirs)
│   └── runtime.ts           # Singleton semaphore, default directory
├── tools/
│   ├── take-screenshot.ts   # Web page capture tool
│   └── take-system-screenshot.ts  # macOS system capture tool
├── types/
│   └── index.ts             # Shared TypeScript interfaces
├── utils/
│   ├── helpers.ts           # Response builders, file utilities
│   ├── screenshot-provider.ts # Cross-platform provider interface + factory
│   ├── macos-provider.ts    # macOS: screencapture wrapper
│   ├── linux-provider.ts    # Linux: maim/scrot/gnome-screenshot/etc.
│   ├── windows-provider.ts  # Windows: PowerShell + .NET System.Drawing
│   ├── macos.ts             # Window ID lookup via CoreGraphics
│   └── semaphore.ts         # Async concurrency limiter
└── validators/
    ├── path.ts              # Output path validation (SEC-004)
    └── url.ts               # URL/SSRF validation (SEC-001)

Testing

Tests use Vitest in three tiers:

  • Unit (npm test) — Full dependency injection, no real I/O. Fast feedback loop.
  • Integration (npm run test:integration) — Real DNS resolution, real filesystem with temp directories, real Puppeteer against a local HTTP server.
  • E2E (npm run test:e2e) — Real native screenshot tools. macOS tests run natively; Linux tests run in Docker via npm run test:linux.
npm test                 # Unit tests (~300ms)
npm run test:linux       # Linux provider tests in Docker
npm run test:all         # Everything

Debugging with MCP Inspector

npm run inspector

This launches the MCP Inspector connected to your built server, allowing you to invoke tools interactively.

License

Apache-2.0 — Copyright 2026 Seth Bang

Search skills and MCP servers

Fuzzy search across 23,137 skills and servers