PeepIt
About
A macOS-only server for capturing and analyzing screenshots with local or cloud-based AI models.
Details
- Author
- mantisware
- Categories
- Productivity, Other, AI
- Tags
- #macos
Jump to
Manual Configuration for Other MCP Clients
{ "server": { "command": "node", "args": ["/path/to/peepit/dist/index.js"], "env": { "PEEPIT_AI_PROVIDERS": "openai/gpt-4o,ollama/llava", "OPENAI_API_KEY": "your-openai-api-key-here" } } }
Capture your Mac's screen and optionally analyze it. Shadows and frames are automatically banished.
- app_target(string, optional): Specifies the capture target. If omitted or empty, captures all screens.
- Examples:
- "screen:INDEX": Captures the screen at the specified zero-based index (e.g.,"screen:0"). (Note: Index selection from multiple screens is planned for full support in the Swift CLI).
- "frontmost": Captures the frontmost window of the currently active application.
- "AppName": Captures all windows of the application namedAppName(e.g.,"Safari","com.apple.Safari"). Fuzzy matching is used.
- "PID:ProcessID": Captures all windows of the application with the specified process ID (e.g.,"PID:663"). Useful when multiple instances of the same app are running.
- "AppName:WINDOW_TITLE:Title": Captures the window ofAppNamethat has the specifiedTitle(e.g.,"Notes:WINDOW_TITLE:My Important Note").
- "AppName:WINDOW_INDEX:Index": Captures the window ofAppNameat the specified zero-basedIndex(e.g.,"Preview:WINDOW_INDEX:0"for the frontmost window of Preview).
- "png"or"jpg": Saves the image to the specifiedpathin the chosen format. For application captures: ifpathis not provided, behaves like"data". For screen captures: always saves to file.
- "data": Returns Base64 encoded PNG data of the image directly in the MCP response. Ifpathis also specified, a PNG file is also saved to thatpath.Note: Screen captures cannot use this format and will automatically fall back to PNG file format.
- Invalid values (empty strings, null, or unrecognized formats) automatically fall back to"png".
- "background": Captures without altering the current window focus (default).
- "foreground": Attempts to bring the target application/window to the foreground before capture. This might be necessary for certain applications or to ensure a specific window is captured if multiple are open.
- If aquestionis provided, the tool will capture the image (saving it topathif specified, or a temporary path otherwise).
- This image is then sent to an AI model for analysis. The AI provider and model are chosen automatically by the server based on yourPEEPIT_AI_PROVIDERSenvironment variable (trying them in order until one succeeds).
- The analysis result is returned asanalysis_textin the response. Image data (Base64) is NOT returned in thecontentarray when a question is asked.
- If a temporary path was used for the image, it's deleted after the analysis attempt.
- content: Can containImageContentItem(ifformat: "data"orpathwas omitted, and noquestion) and/orTextContentItem(for summaries, analysis text, warnings).
- saved_files: Array of objects, each detailing a file saved topath(ifpathwas provided).
- analysis_text: Text from AI (ifquestionwas asked).
- model_used: AI model identifier (ifquestionwas asked).
For detailed parameter documentation, seedocs/spec.md.
PeepIt intelligently manages output paths to prevent file overwrites while respecting your intentions:
Key Principle: Single vs Multiple Captures
When you provide a specific file path (e.g.,~/Desktop/screenshot.png), PeepIt determines whether to use it exactly or add metadata based on the capture context:
- Capturing one specific window
- Capturing one specific screen (when only one display exists)
- Capturing withapp_target: "frontmost"
- Your path is used exactly as specified
- Capturing all windows of an app (mode: "multi"or multiple windows exist)
- Capturing all screens (when multiple displays exist)
- Capturing with no specific target (defaults to all screens)
- Metadata is appended to prevent overwrites
// SINGLE CAPTURES - Use exact path // ================================ // One window of Safari await use_mcp_tool("peepit", "image", { app_target: "Safari", path: "~/Desktop/browser.png" }); // Result: ~/Desktop/browser.png ✓ // Specific screen (when you have only one monitor) await use_mcp_tool("peepit", "image", { app_target: "screen:0", path: "~/Desktop/myscreen.png" }); // Result: ~/Desktop/myscreen.png ✓ // Frontmost window await use_mcp_tool("peepit", "image", { app_target: "frontmost", path: "~/Desktop/active.png" }); // Result: ~/Desktop/active.png ✓ // MULTIPLE CAPTURES - Add metadata // ================================ // All windows of Safari (mode: multi) await use_mcp_tool("peepit", "image", { app_target: "Safari", mode: "multi", path: "~/Desktop/browser.png" }); // Results: ~/Desktop/browser_Safari_window_0_20250610_120000.png // ~/Desktop/browser_Safari_window_1_20250610_120000.png // All screens (multiple monitors) await use_mcp_tool("peepit", "image", { app_target: "screen", // or omit app_target path: "~/Desktop/monitor.png" }); // Results: ~/Desktop/monitor_1_20250610_120000.png // ~/Desktop/monitor_2_20250610_120000.png // DIRECTORY PATHS - Always use generated names // ============================================ // Directory path (note trailing slash) await use_mcp_tool("peepit", "image", { app_target: "Safari", path: "~/Desktop/screenshots/" }); // Result: ~/Desktop/screenshots/Safari_20250610_120000.png
PeepIt automatically handles filesystem limitations:
- Truncates filenames exceeding macOS's 255-byte limit
- Preserves UTF-8 multibyte characters (emoji, non-Latin scripts)
- Ensures metadata is always included when needed
- Never creates invalid filenames
PeepIt MCP: Lightning-fast macOS Screenshots for AI Agents
PeepIt: Because Your AI Deserves to See What You See
Ever wish your AI assistant could justlookat your screen and get it? PeepIt is here to grant your digital sidekick the gift of sight—no magic wands required. Whether you're debugging a UI, capturing a bug in the wild, or just want to know what's lurking behind that mysterious window, PeepIt's got your back (and your screen).
PeepIt is a macOS-only MCP server that lets AI agents capture screenshots of your apps, windows, or the whole system—then analyze them with local or cloud-based AI models. It's like giving your AI a pair of glasses and a magnifying glass, all in one.
- Capture screenshotsof anything: the whole screen, a single app, or that one window you can never find
- Analyze visual contentwith AI vision models (local or cloud—your call)
- List running apps and windowsfor laser-targeted captures
- Work non-intrusively—no window focus stealing, no workflow interruptions, no drama
- 🚀 Fast & Non-intrusive: Blink and you'll miss it—PeepIt uses Apple's ScreenCaptureKit for lightning-fast screenshots, all without hijacking your window focus or interrupting your groove.
- 🎯 Smart Window Targeting: Fuzzy matching so sharp, it'll find the right window even if you only remember half its name (we've all been there).
- 🤖 AI-Powered Analysis: Ask questions about your screenshots and get answers from GPT-4o, Claude, or local models—because sometimes you need a second set of (robotic) eyes.
- 🔒 Privacy-First: Prefer to keep things on the down-low? Run everything locally with Ollama, or call in the cloud cavalry only when you really need it.
- 📦 Easy Installation: One-click install via Cursor, or just a quick npm/npx incantation—no arcane rituals required.
- 🛠️ Developer-Friendly: Clean JSON API, TypeScript support, and logs so comprehensive you'll wonder if PeepIt is secretly writing your memoirs.
- macOS 14.0+(Sonoma or later)
- Node.js 20.0+
- Screen Recording Permission(don't worry, you'll be prompted—no need to go spelunking in System Settings)
Or manually add to your Cursor settings:
{ "mcpServers": { "peepit": { "command": "npx", "args": [ "-y", "@mantisware/peepit-mcp" ], "env": { "PEEPIT_AI_PROVIDERS": "openai/gpt-4o,ollama/llava:latest", "OPENAI_API_KEY": "your-openai-api-key-here" }, "toolCallTimeoutMillis": 120000 } } }
Edit your Claude Desktop configuration file:
- macOS:~/Library/Application Support/Claude/claude_desktop_config.json
- Windows:%APPDATA%\Claude\claude_desktop_config.json
Add the PeepIt configuration (copy, paste, and you're halfway to AI vision):
{ "mcpServers": { "peepit": { "command": "npx", "args": [ "-y", "@mantisware/peepit-mcp" ], "env": { "PEEPIT_AI_PROVIDERS": "openai/gpt-4o,ollama/llava:latest", "OPENAI_API_KEY": "your-openai-api-key-here" } } } }
Then restart Claude Desktop. (Yes, you really do have to restart it. We checked.)
PeepIt is as configurable as your favorite text editor. Use environment variables to tune it to your workflow:
{ "PEEPIT_AI_PROVIDERS": "openai/gpt-4o,ollama/llava:latest", "OPENAI_API_KEY": "your-openai-api-key-here", "PEEPIT_LOG_LEVEL": "debug", "PEEPIT_LOG_FILE": "~/Library/Logs/peepit-mcp-debug.log", "PEEPIT_DEFAULT_SAVE_PATH": "~/Pictures/PeepItCaptures", "PEEPIT_CONSOLE_LOGGING": "true", "PEEPIT_CLI_TIMEOUT": "30000", "PEEPIT_CLI_PATH": "/opt/custom/peepit" }
ThePEEPIT_AI_PROVIDERSvariable is your golden ticket to AI-powered screenshot analysis. Want PeepIt to answer questions about your screen? Just list your favorite models:
PEEPIT_AI_PROVIDERS="openai/gpt-4o,ollama/llava:latest,anthropic/claude-3-haiku-20240307"
Or, if you're a semicolon connoisseur:
PEEPIT_AI_PROVIDERS="openai/gpt-4o;ollama/llava:latest;anthropic/claude-3-haiku-20240307"
Each entry isprovider_name/model_identifier. Supported providers:ollama(for local),openai(for the cloud), and soon,anthropic(for the truly adventurous).
PeepIt will try providers in order, checking for API keys or local services as needed. You can override the model per request if you're feeling particular.
Ollama brings AI vision to your desktop—no cloud required, no data leaving your Mac. (Your secrets are safe. Probably.)
brew install ollama # Or download from https://ollama.ai ollama serve
ollama pull llava:latest ollama pull llava:7b-v1.6 ollama pull llava:13b-v1.6 # For the RAM-rich ollama pull llava:34b-v1.6 # For the RAM-obsessed
- qwen2-vl:7b- ~4GB download, ~6GB RAM (great for mortals)
- llava:7b- ~4.5GB download, ~8GB RAM
- llava:13b- ~8GB download, ~16GB RAM
- llava:34b- ~20GB download, ~40GB RAM (bring snacks)
Add Ollama to your Claude Desktop config:
{ "mcpServers": { "peepit": { "command": "npx", "args": [ "-y", "@mantisware/peepit-mcp@beta" ], "env": { "PEEPIT_AI_PROVIDERS": "ollama/llava:latest" } } } }
{ "mcpServers": { "peepit": { "command": "npx", "args": [ "-y", "@mantisware/peepit-mcp@beta" ], "env": { "PEEPIT_AI_PROVIDERS": "ollama/qwen2-vl:7b" } } } }
{ "env": { "PEEPIT_AI_PROVIDERS": "ollama/llava:latest,openai/gpt-4o", "OPENAI_API_KEY": "your-api-key-here" } }
PeepIt needs a few macOS permissions to work its magic. Don't worry, it's not asking for your Netflix password.
1. Screen Recording Permission (Required)
- System Settings → Privacy & Security - Scroll to Screen & System Audio Recording - Toggle on your terminal or MCP client - Restart the app (yes, again) - System Preferences → Security & Privacy → Privacy - Select Screen Recording - Click the lock, enter your password - Add your terminal or MCP client - Restart the app- Terminal.app
- Claude Desktop
- VS Code
- Cursor
2. Accessibility Permission (Optional, but nice)
- System Settings → Privacy & Security → Accessibility - Toggle on your terminal/MCP client - System Preferences → Security & Privacy → Privacy - Select Accessibility - Add your terminal/MCP clientWant to see PeepIt in action? Fire up theMCP Inspector:
# Test with OpenAI OPENAI_API_KEY="your-key" PEEPIT_AI_PROVIDERS="openai/gpt-4o" npx @modelcontextprotocol/inspector npx -y @mantisware/peepit-mcp # Test with local Ollama PEEPIT_AI_PROVIDERS="ollama/llava:latest" npx @modelcontextprotocol/inspector npx -y @mantisware/peepit-mcp
./peepit --help ./peepit list server_status --json-output ./peepit image --mode screen --format png peepit-mcp
{ "success": true, "data": { "swift_cli_available": true, "permissions": { "screen_recording": true }, "system_info": { "macos_version": "14.0" } } }
PeepIt gives you three main tools—think of them as your AI's Swiss Army knife:
Snap a screenshot of your Mac—screen, app, or window. Shadows and frames? Gone. (You're welcome.)
Note:Screen captures are always saved to files (no Base64 for giant images—your stack won't like it). If you ask forformat: "data", PeepIt will politely ignore you and save a PNG instead, with a gentle warning.
// Capture entire screen await use_mcp_tool("peepit", "image", { app_target: "screen:0", path: "~/Desktop/screenshot.png" }); // Capture a specific app window and analyze it await use_mcp_tool("peepit", "image", { app_target: "Safari", question: "What website is currently open?", format: "data" }); // Capture window by title await use_mcp_tool("peepit", "image", { app_target: "Notes:WINDOW_TITLE:Meeting Notes", path: "~/Desktop/notes.png" }); // Capture the frontmost window await use_mcp_tool("peepit", "image", { app_target: "frontmost", format: "png" }); // Capture by Process ID await use_mcp_tool("peepit", "image", { app_target: "PID:663", path: "~/Desktop/process.png" });
Browser Helper Filtering:PeepIt is smart enough to avoid browser helper processes (no more "Google Chrome Helper (Renderer)" shenanigans). You'll get the real browser window, or a clear message if it's not running.
- Single capture?Your path is used as-is.
- Multiple captures?PeepIt adds metadata to filenames so nothing gets overwritten.
- Directory path?PeepIt generates unique names for you.
- Long filenames?PeepIt trims them to fit macOS's 255-byte limit, keeping your emoji and non-Latin scripts intact.
- Invalid formats?Only PNG and JPEG are allowed. Anything else gets converted, with a friendly warning.
List running apps, windows, or check server status. Because sometimes you just need to know what's out there.
// List all running apps await use_mcp_tool("peepit", "list", { item_type: "running_applications" }); // List windows of a specific app await use_mcp_tool("peepit", "list", { item_type: "application_windows", app: "Preview" }); // List windows by PID await use_mcp_tool("peepit", "list", { item_type: "application_windows", app: "PID:663" }); // Check server status await use_mcp_tool("peepit", "list", { item_type: "server_status" });
Feed an image to your AI and ask it anything. (Well, almost anything.)
// Analyze with auto-selected provider await use_mcp_tool("peepit", "analyze", { image_path: "~/Desktop/screenshot.png", question: "What applications are visible?" }); // Force a specific provider await use_mcp_tool("peepit", "analyze", { image_path: "~/Desktop/diagram.jpg", question: "Explain this diagram", provider_config: { type: "ollama", model: "llava:13b" } });
- Unit Tests: For the code that likes to be alone
- Integration Tests: For the code that plays well with others
- Platform-Specific Tests: Some tests need macOS and the Swift binary
npm test # Run all tests (macOS required for full suite) npm run test:unit # Unit tests only (any platform) npm run test:typescript # TypeScript-only tests (Linux-friendly) npm run test:typescript:watch # Watch mode npm run test:coverage # With coverage
npm run test:swift # Swift CLI tests (macOS only) npm run test:integration # Full integration (TypeScript + Swift)
- macOS: All tests
- Linux/CI: TypeScript-only (Swift tests are skipped)
- Env Vars:
- SKIP_SWIFT_TESTS=true: Skip Swift tests
- CI=true: Skip Swift tests automatically
OPENAI_API_KEY="your-key" PEEPIT_AI_PROVIDERS="openai/gpt-4o" PEEPIT_LOG_LEVEL=debug PEEPIT_CONSOLE_LOGGING=true npx @mantisware/peepit-mcp ./peepit list server_status --json-output
git clone https://github.com/mantisware/peepit.git cd peepit npm install npm run build cd peepit-cli swift build -c release cp .build/release/peepit ../peepit cd .. npm link # Optional: install globally
{ "mcpServers": { "peepit_local": { "command": "peepit-mcp", "args": [], "env": { "PEEPIT_LOG_LEVEL": "debug", "PEEPIT_CONSOLE_LOGGING": "true" } } } }
{ "mcpServers": { "peepit_local_node": { "command": "node", "args": [ "/Users/mantisware/Projects/PeepIt/dist/index.js" ], "env": { "PEEPIT_LOG_LEVEL": "debug", "PEEPIT_CONSOLE_LOGGING": "true" } } } }
Use absolute paths and unique server names to avoid confusion.
Note: No AI analysis or MCP features in this version.
Manual Configuration for Other MCP Clients
{ "server": { "command": "node", "args": ["/path/to/peepit/dist/index.js"], "env": { "PEEPIT_AI_PROVIDERS": "openai/gpt-4o,ollama/llava", "OPENAI_API_KEY": "your-openai-api-key-here" } } }
Capture your Mac's screen and optionally analyze it. Shadows and frames are automatically banished.
- app_target(string, optional): Specifies the capture target. If omitted or empty, captures all screens.
- Examples:
- "screen:INDEX": Captures the screen at the specified zero-based index (e.g.,"screen:0"). (Note: Index selection from multiple screens is planned for full support in the Swift CLI).
- "frontmost": Captures the frontmost window of the currently active application.
- "AppName": Captures all windows of the application namedAppName(e.g.,"Safari","com.apple.Safari"). Fuzzy matching is used.
- "PID:ProcessID": Captures all windows of the application with the specified process ID (e.g.,"PID:663"). Useful when multiple instances of the same app are running.
- "AppName:WINDOW_TITLE:Title": Captures the window ofAppNamethat has the specifiedTitle(e.g.,"Notes:WINDOW_TITLE:My Important Note").
- "AppName:WINDOW_INDEX:Index": Captures the window ofAppNameat the specified zero-basedIndex(e.g.,"Preview:WINDOW_INDEX:0"for the frontmost window of Preview).
- "png"or"jpg": Saves the image to the specifiedpathin the chosen format. For application captures: ifpathis not provided, behaves like"data". For screen captures: always saves to file.
- "data": Returns Base64 encoded PNG data of the image directly in the MCP response. Ifpathis also specified, a PNG file is also saved to thatpath.Note: Screen captures cannot use this format and will automatically fall back to PNG file format.
- Invalid values (empty strings, null, or unrecognized formats) automatically fall back to"png".
- "background": Captures without altering the current window focus (default).
- "foreground": Attempts to bring the target application/window to the foreground before capture. This might be necessary for certain applications or to ensure a specific window is captured if multiple are open.
- If aquestionis provided, the tool will capture the image (saving it topathif specified, or a temporary path otherwise).
- This image is then sent to an AI model for analysis. The AI provider and model are chosen automatically by the server based on yourPEEPIT_AI_PROVIDERSenvironment variable (trying them in order until one succeeds).
- The analysis result is returned asanalysis_textin the response. Image data (Base64) is NOT returned in thecontentarray when a question is asked.
- If a temporary path was used for the image, it's deleted after the analysis attempt.
- content: Can containImageContentItem(ifformat: "data"orpathwas omitted, and noquestion) and/orTextContentItem(for summaries, analysis text, warnings).
- saved_files: Array of objects, each detailing a file saved topath(ifpathwas provided).
- analysis_text: Text from AI (ifquestionwas asked).
- model_used: AI model identifier (ifquestionwas asked).
For detailed parameter documentation, seedocs/spec.md.
PeepIt intelligently manages output paths to prevent file overwrites while respecting your intentions:
Key Principle: Single vs Multiple Captures
When you provide a specific file path (e.g.,~/Desktop/screenshot.png), PeepIt determines whether to use it exactly or add metadata based on the capture context:
- Capturing one specific window
- Capturing one specific screen (when only one display exists)
- Capturing withapp_target: "frontmost"
- Your path is used exactly as specified
- Capturing all windows of an app (mode: "multi"or multiple windows exist)
- Capturing all screens (when multiple displays exist)
- Capturing with no specific target (defaults to all screens)
- Metadata is appended to prevent overwrites
// SINGLE CAPTURES - Use exact path // ================================ // One window of Safari await use_mcp_tool("peepit", "image", { app_target: "Safari", path: "~/Desktop/browser.png" }); // Result: ~/Desktop/browser.png ✓ // Specific screen (when you have only one monitor) await use_mcp_tool("peepit", "image", { app_target: "screen:0", path: "~/Desktop/myscreen.png" }); // Result: ~/Desktop/myscreen.png ✓ // Frontmost window await use_mcp_tool("peepit", "image", { app_target: "frontmost", path: "~/Desktop/active.png" }); // Result: ~/Desktop/active.png ✓ // MULTIPLE CAPTURES - Add metadata // ================================ // All windows of Safari (mode: multi) await use_mcp_tool("peepit", "image", { app_target: "Safari", mode: "multi", path: "~/Desktop/browser.png" }); // Results: ~/Desktop/browser_Safari_window_0_20250610_120000.png // ~/Desktop/browser_Safari_window_1_20250610_120000.png // All screens (multiple monitors) await use_mcp_tool("peepit", "image", { app_target: "screen", // or omit app_target path: "~/Desktop/monitor.png" }); // Results: ~/Desktop/monitor_1_20250610_120000.png // ~/Desktop/monitor_2_20250610_120000.png // DIRECTORY PATHS - Always use generated names // ============================================ // Directory path (note trailing slash) await use_mcp_tool("peepit", "image", { app_target: "Safari", path: "~/Desktop/screenshots/" }); // Result: ~/Desktop/screenshots/Safari_20250610_120000.png
PeepIt automatically handles filesystem limitations:
- Truncates filenames exceeding macOS's 255-byte limit
- Preserves UTF-8 multibyte characters (emoji, non-Latin scripts)
- Ensures metadata is always included when needed
- Never creates invalid filenames
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.





