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
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.
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.
Cross-Platform Feature Support
Example prompt:
Take a system screenshot of the Safari window
Configuration
Environment Variables
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:
Security
This server implements multiple layers of security hardening:
For full details, see docs/security.md.
Development
Scripts
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