{
  "markdown": "# Universal Screenshot MCP\n\n[![npm version](https://img.shields.io/npm/v/universal-screenshot-mcp.svg)](https://www.npmjs.com/package/universal-screenshot-mcp)\n[![MCP Registry](https://img.shields.io/badge/MCP_Registry-io.github.sethbang%2Fscreenshot--server-blue)](https://registry.modelcontextprotocol.io)\n[![License](https://img.shields.io/badge/license-Apache--2.0-green.svg)](LICENSE)\n\nAn [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server that provides AI assistants with screenshot capabilities — both web page capture via [Puppeteer](https://pptr.dev/) and cross-platform system screenshots using native OS tools.\n\n## Features\n\n- **Web Page Screenshots** — Capture any public URL using a headless Chromium browser\n- **Cross-Platform System Screenshots** — Fullscreen, window, or region capture using native OS tools (macOS `screencapture`, Linux `maim`/`scrot`/`gnome-screenshot`/etc., Windows PowerShell+.NET)\n- **Security-First Design** — SSRF prevention, path traversal protection, DNS rebinding defense, command injection prevention, and DoS limiting\n- **MCP Native** — Integrates directly with Claude Desktop, Cursor, and any MCP-compatible client\n\n## Requirements\n\n- **Node.js** >= 18.0.0\n- **Chromium** is downloaded automatically by Puppeteer on first run\n\n### Platform-Specific Requirements for `take_system_screenshot`\n\n| Platform | Required Tools | Notes |\n|----------|---------------|-------|\n| **macOS** | `screencapture` (built-in) | No additional installation needed |\n| **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`. |\n| **Windows** | `powershell` (built-in) | Uses .NET `System.Drawing` — no additional installation needed |\n\n#### Linux Installation Examples\n\n```bash\n# Ubuntu/Debian (recommended)\nsudo apt install maim xdotool\n\n# Fedora\nsudo dnf install maim xdotool\n\n# Arch Linux\nsudo pacman -S maim xdotool\n\n# Wayland (Sway, etc.)\nsudo apt install grim\n```\n\nAfter installing, you can verify your setup with:\n\n```bash\nnpx universal-screenshot-mcp --doctor\n```\n\nThis probes the host and prints copy-pasteable install commands for any missing tools, tailored to your detected distro.\n\n## Quick Start\n\n### Install from npm\n\n```bash\nnpm install -g universal-screenshot-mcp\n```\n\nOr run directly with `npx`:\n\n```bash\nnpx universal-screenshot-mcp\n```\n\n### Install from Source\n\n```bash\ngit clone https://github.com/sethbang/mcp-screenshot-server.git\ncd mcp-screenshot-server\nnpm install\nnpm run build\n```\n\n### Configure Your MCP Client\n\nAdd the server to your MCP client configuration. For **Claude Desktop**, edit `~/Library/Application Support/Claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"screenshot-server\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"universal-screenshot-mcp\"]\n    }\n  }\n}\n```\n\nOr if installed from source:\n\n```json\n{\n  \"mcpServers\": {\n    \"screenshot-server\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/mcp-screenshot-server/build/index.js\"]\n    }\n  }\n}\n```\n\nFor **Claude Code**, register the server with the `claude mcp add` command:\n\n```bash\n# Project scope (current directory only)\nclaude mcp add screenshot-server -- npx -y universal-screenshot-mcp\n\n# User scope (available across all projects)\nclaude mcp add --scope user screenshot-server -- npx -y universal-screenshot-mcp\n```\n\nOr if installed from source:\n\n```bash\nclaude mcp add screenshot-server -- node /absolute/path/to/mcp-screenshot-server/build/index.js\n```\n\nVerify the server registered with `claude mcp list`, or check live status from inside a session with `/mcp`.\n\nFor **Cursor** or other MCP clients, consult their documentation for the equivalent configuration.\n\n## Tools\n\nThe server exposes two MCP tools:\n\n### `take_screenshot`\n\nCaptures a web page (or a specific element) via a headless Puppeteer browser.\n\n| Parameter         | Type    | Required | Description                                      |\n|-------------------|---------|----------|--------------------------------------------------|\n| `url`             | string  | ✅       | URL to capture (http/https only)                 |\n| `width`           | number  | —        | Viewport width (1–3840)                          |\n| `height`          | number  | —        | Viewport height (1–2160)                         |\n| `fullPage`        | boolean | —        | Capture the full scrollable page                 |\n| `selector`        | string  | —        | CSS selector to capture a specific element        |\n| `waitForSelector` | string  | —        | Wait for this selector before capturing          |\n| `waitForTimeout`  | number  | —        | Delay in milliseconds (0–30000)                  |\n| `outputPath`      | string  | —        | Output file path (default: `~/Documents/screenshots`) |\n\n**Example prompt:**\n> Take a screenshot of https://example.com at 1920x1080\n\n### `take_system_screenshot`\n\nCaptures the desktop, a specific application window, or a screen region using native OS tools. Works on **macOS**, **Linux**, and **Windows**.\n\n| Parameter       | Type    | Required | Description                                              |\n|-----------------|---------|----------|----------------------------------------------------------|\n| `mode`          | enum    | ✅       | `fullscreen`, `window`, or `region`                      |\n| `windowId`      | number  | —        | Window ID for window mode                                |\n| `windowName`    | string  | —        | App name (e.g. `\"Safari\"`, `\"Firefox\"`) for window mode  |\n| `region`        | object  | —        | `{ x, y, width, height }` for region mode                |\n| `display`       | number  | —        | Display number for multi-monitor setups                  |\n| `includeCursor` | boolean | —        | Include the mouse cursor in the capture                  |\n| `format`        | enum    | —        | `png` (default) or `jpg`                                 |\n| `delay`         | number  | —        | Capture delay in seconds (0–10)                          |\n| `outputPath`    | string  | —        | Output file path (default: `~/Documents/screenshots`)    |\n\n#### Cross-Platform Feature Support\n\n| Feature | macOS | Linux | Windows |\n|---------|-------|-------|---------|\n| Fullscreen | ✅ | ✅ | ✅ |\n| Region | ✅ | ✅ (maim, scrot, grim, import) | ✅ |\n| Window by name | ✅ | ⚠️ X11 + xdotool | ⚠️ best-effort |\n| Window by ID | ✅ | ✅ X11 only | ⚠️ HWND |\n| Multi-display | ✅ | ⚠️ tool-dependent | ✅ |\n| Include cursor | ✅ | ⚠️ tool-dependent | ⚠️ |\n| Delay | ✅ | ✅ | ✅ |\n\n**Example prompt:**\n> Take a system screenshot of the Safari window\n\n## Configuration\n\n### Environment Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `SCREENSHOT_OUTPUT_DIR` | `Documents/screenshots` | Default output directory relative to `~` |\n| `ALLOW_LOCAL` | `false` | Set to `true` to allow screenshotting `localhost`/`127.x.x.x`/`[::1]` (useful for local dev servers) |\n\n### Output Directories\n\nScreenshots are saved to `~/Documents/screenshots` by default (configurable via `SCREENSHOT_OUTPUT_DIR`). Custom output paths must resolve to one of these allowed directories:\n\n| Directory              | Description              |\n|------------------------|--------------------------|\n| `~/Documents/screenshots` | Default output location (configurable) |\n| `~/Desktop/Screenshots`| Original default location |\n| `~/Downloads`          | User downloads folder    |\n| `~/Documents`          | User documents folder    |\n| `/tmp`                 | System temp directory    |\n\n## Security\n\nThis server implements multiple layers of security hardening:\n\n| ID      | Threat                | Mitigation                                                                                  |\n|---------|-----------------------|---------------------------------------------------------------------------------------------|\n| 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 |\n| SEC-003 | Command injection     | All subprocesses use `execFile` (no shell); app names validated against `SAFE_APP_NAME_PATTERN` |\n| SEC-004 | Path traversal        | Output paths validated with `fs.realpath()` symlink resolution; restricted to allowed directories |\n| SEC-005 | Denial of service     | Concurrent Puppeteer instances limited to 3 via semaphore                                   |\n\nFor full details, see [`docs/security.md`](docs/security.md).\n\n## Development\n\n### Scripts\n\n| Command              | Description                            |\n|----------------------|----------------------------------------|\n| `npm run build`      | Compile TypeScript to `build/`         |\n| `npm run watch`      | Recompile on file changes              |\n| `npm test`           | Unit tests (fast, fully mocked)        |\n| `npm run test:integration` | Integration tests (real DNS/filesystem) |\n| `npm run test:e2e`   | E2E tests (real Puppeteer/native tools)|\n| `npm run test:all`   | All test tiers together                |\n| `npm run test:linux` | Linux e2e via Docker (requires Docker) |\n| `npm run test:watch` | Run tests in watch mode                |\n| `npm run test:coverage` | Run tests with coverage report      |\n| `npm run lint`       | Lint source with ESLint                |\n| `npm run inspector`  | Launch MCP Inspector for debugging     |\n\n### Project Structure\n\n```\nsrc/\n├── index.ts                 # Entry point — stdio transport\n├── server.ts                # MCP server factory\n├── config/\n│   ├── index.ts             # Static constants (limits, allowed dirs)\n│   └── runtime.ts           # Singleton semaphore, default directory\n├── tools/\n│   ├── take-screenshot.ts   # Web page capture tool\n│   └── take-system-screenshot.ts  # macOS system capture tool\n├── types/\n│   └── index.ts             # Shared TypeScript interfaces\n├── utils/\n│   ├── helpers.ts           # Response builders, file utilities\n│   ├── screenshot-provider.ts # Cross-platform provider interface + factory\n│   ├── macos-provider.ts    # macOS: screencapture wrapper\n│   ├── linux-provider.ts    # Linux: maim/scrot/gnome-screenshot/etc.\n│   ├── windows-provider.ts  # Windows: PowerShell + .NET System.Drawing\n│   ├── macos.ts             # Window ID lookup via CoreGraphics\n│   └── semaphore.ts         # Async concurrency limiter\n└── validators/\n    ├── path.ts              # Output path validation (SEC-004)\n    └── url.ts               # URL/SSRF validation (SEC-001)\n```\n\n### Testing\n\nTests use [Vitest](https://vitest.dev/) in three tiers:\n\n- **Unit** (`npm test`) — Full dependency injection, no real I/O. Fast feedback loop.\n- **Integration** (`npm run test:integration`) — Real DNS resolution, real filesystem with temp directories, real Puppeteer against a local HTTP server.\n- **E2E** (`npm run test:e2e`) — Real native screenshot tools. macOS tests run natively; Linux tests run in Docker via `npm run test:linux`.\n\n```bash\nnpm test                 # Unit tests (~300ms)\nnpm run test:linux       # Linux provider tests in Docker\nnpm run test:all         # Everything\n```\n\n### Debugging with MCP Inspector\n\n```bash\nnpm run inspector\n```\n\nThis launches the [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector) connected to your built server, allowing you to invoke tools interactively.\n\n## License\n\n[Apache-2.0](LICENSE) — Copyright 2026 Seth Bang\n",
  "bytes": 11576,
  "sha": "4a81f27b516c84ffbe76120e9b1296fd5e2bbe016a8ef3d362f998078f83df78",
  "repo_slug": "sethbang/mcp-screenshot-server",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_sethbang_screenshot_server_c984f14f/readme"
}