Universal Screenshot MCP
MCP server for web page and cross-platform system screenshots (macOS, Linux, Windows)
Ask AI about Universal Screenshot MCP
Powered by Claude Β· Grounded in docs
I know everything about Universal Screenshot MCP. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Universal Screenshot MCP
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, Linuxmaim/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
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 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 vianpm 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
