mcp-desktop
mcp-desktop
macOS desktop automation for AI agents — screenshot any screen, switch apps and tabs, click, type, and scroll. Built as two separate MCP servers so you can install only the trust level you need.
Packages
Package | npm | What it does | Trust level |
|
| Screenshots, app switching, tab switching | Low — read-only |
|
| Everything above + click, type, scroll | Higher — can interact with your UI |
Tip: Install only
mcp-desktop-screenshotif you want an AI to observe your screen. Installmcp-desktop-controlif you want it to act on your screen too — it includes all screenshot tools.
Requirements
macOS (Apple Silicon or Intel)
Node.js 18+
Screen Recording permission for your terminal app (System Settings → Privacy & Security → Screen Recording)
Accessibility permission for your terminal app — only needed for
mcp-desktop-control(System Settings → Privacy & Security → Accessibility)
Installation
Claude Code (CLI)
# Read-only: screenshots + app/tab switching
claude mcp add --scope user desktop-screenshot -- npx -y @rchavarria06/mcp-desktop-screenshot
# Full control (includes all screenshot tools)
claude mcp add --scope user desktop-control -- npx -y @rchavarria06/mcp-desktop-controlClaude Desktop
Add to your claude_desktop_config.json:
{
"mcpServers": {
"desktop-screenshot": {
"command": "npx",
"args": ["-y", "@rchavarria06/mcp-desktop-screenshot"],
"env": {
"BLOCKED_APPS": "1Password,Keychain"
}
}
}
}Other MCP clients
Any client that supports stdio MCP servers can run:
npx @rchavarria06/mcp-desktop-screenshot
# or
npx @rchavarria06/mcp-desktop-controlPrivacy
Screenshots are ephemeral by default — they're returned as base64 image data in the AI's context and never written to disk. Pass a save_path to any screenshot tool if you want to persist it.
Set BLOCKED_APPS to a comma-separated list of app names the server will refuse to access:
"env": { "BLOCKED_APPS": "1Password,Keychain Access,Signal" }Tools
mcp-desktop-screenshot
Tool | Description | Parameters |
| List connected displays | — |
| List running apps with a visible UI | — |
| List tabs in a browser or terminal |
|
| Capture a display, return as image |
|
| Bring an app to the foreground |
|
| Switch tab by URL substring, title substring, or index |
|
| Switch to app, capture, restore previous app |
|
list_tabs supports: Brave Browser, Google Chrome, Chromium, Arc, Safari, iTerm2, Terminal
mcp-desktop-control
Includes all tools above, plus:
Tool | Description | Parameters |
| Left-click at coordinates |
|
| Double-click at coordinates |
|
| Triple-click — selects all text in an input (mouse-native) |
|
| Right-click at coordinates |
|
| Type text into the focused element |
|
| Press a key or combo ( |
|
| Scroll at coordinates |
|
Pass verify_app to any control tool to abort with an error if the wrong app is frontmost — prevents accidental input to the wrong window.
Example workflows
AI attaches screenshots to a PR description
1. list_displays → find which display has the terminal
2. screenshot_app("Terminal", display: 3) → capture test output
3. switch_tab("Brave Browser", "localhost:3000") → focus preview
4. take_screenshot(display: 2) → capture the UI
5. AI writes PR description with both images embeddedAI fills out a form
1. screenshot_app("Brave Browser") → see current state
2. click(x, y) → focus the input
3. type_text("roberto@example.com") → fill it in
4. key_press("tab") → next field
5. type_text("My message here")
6. key_press("return") → submit
7. take_screenshot(display: 1) → confirm successHow it works
Both servers are built on macOS-native primitives — no third-party automation frameworks:
Screenshots:
screencaptureCLIApp switching / tab control:
osascript(AppleScript)Mouse / keyboard:
System Eventsvia AppleScriptScroll: Swift +
CoreGraphics.CGEvent
Contributing
PRs welcome. The monorepo uses npm workspaces:
git clone https://github.com/mocha06/mcp-desktop
cd mcp-desktop
npm install
npm run build
npm testPackages live in packages/core (shared primitives), packages/mcp-screenshot, and packages/mcp-control.
Testing
Vitest covers pure logic: tab-list parsing and resolution, BLOCKED_APPS matching, AppleScript escaping, key-combo parsing, and the Swift scroll script construction. Side-effectful runners that call osascript, screencapture, or swift are exercised end-to-end on a real macOS machine — please smoke-test mouse/keyboard changes manually before opening a PR.
npm test # one-shot
npm run test:watch # rerun on saveLicense
MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mocha06/mcp-desktop'
If you have feedback or need assistance with the MCP directory API, please join our Discord server