screen-mcp
screen-mcp
An MCP (Model Context Protocol) server that gives AI agents eyes on an
Omarchy / Hyprland Wayland desktop. It captures screenshots via grim and
offers optional image analysis powered by the Gemini API — useful when the
calling model has no native vision encoder.
Features
Tool | What it does | Returns |
| Enumerate Hyprland windows via | Text listing with addresses, titles, workspaces, sizes |
| Capture a pixel rectangle | Inline PNG image (base64) |
| Capture a window by title, class, address, or | Inline PNG image (base64) |
| Capture the entire screen | Inline PNG image (base64) |
| Send an image (base64 or file path) to Gemini for reasoning | Text response |
| Capture a region and analyze it in one call | Text (Gemini response) |
Screenshots use grim (wlroots screencopy protocol) — no X11 required.
Prerequisites
Omarchy, Hyprland, or any wlroots-based Wayland compositor
grim— Wayland screenshot toolslurp— (optional) interactive region selection helperhyprctl— Hyprland window/query CLIjq— (optional) used by some helper scripts
Check with:
grim --help && hyprctl clients -j | head -c 20For image analysis (optional)
A Gemini API key — get one at https://aistudio.google.com
Export it in your environment:
export GEMINI_API_KEY="your-api-key-here"Without the key, the screenshot tools still work; only analyze_image and
screenshot_and_analyze will return an error.
Installation
Via Claude Desktop
Add this to your Claude Desktop claude_desktop_config.json:
{
"mcpServers": {
"screen-mcp": {
"command": "npx",
"args": ["-y", "screen-mcp"],
"env": {
"GEMINI_API_KEY": "your-api-key-here"
}
}
}
}Via npx
npx -y screen-mcp
# Or install globally:
npm install -g screen-mcpUsage examples
Capture a screen region
screenshot_region(x=100, y=200, width=800, height=600, include_cursor=true)Capture a specific window
First list available windows to get an address or title:
list_windows()Then capture by title (substring match), address, or "focused":
screenshot_window(window="Spotify")
screenshot_window(window="focused")
screenshot_window(window="0x557ba79b4900")Analyze an image with Gemini
analyze_image(
image_path="/tmp/my-screenshot.png",
prompt="What applications are visible in this screenshot?",
model="gemini-2.5-flash"
)Or pass base64-encoded image data directly:
analyze_image(
image="<base64-encoded-image>",
prompt="Describe what you see in this image.",
mime_type="image/png"
)Capture and analyze in one call
screenshot_and_analyze(
x=0, y=0, width=1920, height=1080,
prompt="Count the number of windows open and list their titles.",
scale=0.5,
model="gemini-2.5-flash"
)Development
# Install deps
npm install
# Build
npm run build
# Run
npm start
# Development (recompile on change)
npm run devHow it works
Capture:
src/capture.tswrapsgrim(screenshots) andhyprctl(window enumeration). Window capture first triesgrim -T <stableId>(foreign-toplevel handle), falling back togrim -g "<x>,<y> <w>x<h>"(geometry from hyprctl).Analysis:
src/gemini.tsuses the official@google/genaiSDK. Images are passed inline as base64 to the Gemini API'sinteractions.createendpoint.Server:
src/index.tswires everything together as a stdio-transported MCP server using@modelcontextprotocol/server.
License
MIT