Third Eye
Privacy-first screen capture and recording for any MCP-compatible AI coding agent: Claude Desktop, Cursor, Windsurf, Continue, and more.
What is Third Eye?
Third Eye is an MCP (Model Context Protocol) server that gives AI coding agents the ability to capture your screen. It works with Claude Desktop, Cursor, Windsurf, Continue, and any other MCP-compatible client. It runs 100% locally with no cloud uploads, giving you complete control over when and what gets captured.
Privacy First
No cloud uploads. No telemetry. Screenshots stay on your machine.
Multi-Monitor
List all displays and capture from any one of them.
Screen Recording
Change-based keyframe capture with grid output and scheduled bursts.
Freemium
10 free captures/day. Upgrade for unlimited.
Installation
Third Eye requires Node.js 18+ installed on your system. The package is auto-downloaded by Claude - you just need to configure it.
npx third-eye-mcp when needed. Just configure and restart.
Prerequisites
Download and install Node.js from nodejs.org (LTS version recommended).
Configuration
Claude Desktop (Recommended)
Follow these steps to add Third Eye to Claude Desktop:
Step 1: Open Config File
Open your Claude Desktop configuration file in a text editor:
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Linux:
~/.config/claude/claude_desktop_config.json
Tip: On Windows, press Win+R, paste the path, and press Enter to open the folder.
Step 2: Add Third Eye Config
Add the following to your config file (create the file if it doesn't exist):
{
"mcpServers": {
"third-eye": {
"command": "npx",
"args": ["third-eye-mcp"]
}
}
}
If you already have other MCP servers configured, add "third-eye" inside the existing mcpServers object.
Step 3: Restart Claude Desktop
Close and reopen Claude Desktop completely for the changes to take effect.
Step 4: Test It
Ask Claude: "Take a screenshot of my screen"
Claude Code CLI
If using Claude Code CLI, run this command:
claude mcp add third-eye "npx third-eye-mcp"
Cursor
Add to your Cursor MCP settings (~/.cursor/mcp.json or via Settings > MCP):
{
"mcpServers": {
"third-eye": {
"command": "npx",
"args": ["third-eye-mcp"]
}
}
}
Windsurf / Continue / Other MCP Clients
Any MCP-compatible client can use Third Eye. The configuration format is typically the same - add the server to your client's MCP configuration:
# Command to run:
npx third-eye-mcp
# Or if you prefer explicit paths:
node /path/to/third-eye/build/index.js
Check your specific client's documentation for where to add MCP server configurations.
From Source (Advanced)
For developers who want to build from source:
git clone https://github.com/Osseni94/third-eye
cd third-eye
npm install
npm run build
Then configure Claude Desktop to point to your local build:
{
"mcpServers": {
"third-eye": {
"command": "node",
"args": ["C:/path/to/third-eye/build/index.js"]
}
}
}
Quick Start
Once configured, you can ask Claude things like:
- "Take a screenshot of my screen"
- "Capture the Unreal Engine window" (uses 5s delay)
- "List all my monitors"
- "Record my screen for 30 seconds"
- "Get frame 5 from the recording"
- "How many captures do I have left today?"
Available Tools
screen.list_displays
All TiersList all available displays/monitors with their properties.
screen.list_displays()
# Returns:
{
"displays": [
{
"index": 0,
"name": "Display 1",
"width": 2560,
"height": 1440,
"x": 0,
"y": 0,
"isPrimary": true,
"scaleFactor": 1
}
],
"count": 1
}
screen.capture
All TiersCapture a full screenshot of a display. Returns base64 PNG with metadata.
| Parameter | Type | Default | Description |
|---|---|---|---|
displayIndex |
number | 0 | Display index (0-based) |
max_width |
number | - | Downscale if wider than this |
delay |
number | 5 | Seconds to wait before capture (0-10) |
instant |
boolean | false | If true, capture immediately (no delay) |
# Default: 5 second delay
screen.capture()
# Instant capture (no delay)
screen.capture({ instant: true })
# Capture second monitor, downscaled
screen.capture({ displayIndex: 1, max_width: 1280 })
screen.capture_region
All TiersCapture a specific rectangular region of the screen.
| Parameter | Type | Required | Description |
|---|---|---|---|
x |
number | Yes | X coordinate of top-left corner |
y |
number | Yes | Y coordinate of top-left corner |
width |
number | Yes | Width of region in pixels |
height |
number | Yes | Height of region in pixels |
delay |
number | No | Seconds to wait (default: 5) |
instant |
boolean | No | Skip delay if true |
screen.capture_region({ x: 100, y: 100, width: 500, height: 300 })
screen.latest
All TiersRetrieve the most recent capture from this session. Useful for re-analyzing a previous screenshot.
screen.latest()
# Returns the last captured image and metadata
screen.record
All TiersRecord the screen with change-based keyframe capture. Returns a grid image (contact sheet) with timestamps showing what changed.
| Parameter | Type | Default | Description |
|---|---|---|---|
duration |
number | 30 | Recording duration in seconds (1-120) |
interval |
number | 1.0 | Capture interval in seconds (0.25-10) |
displayIndex |
number | 0 | Display to record (0-based) |
changeThreshold |
number | 2.0 | Min change % to keep frame (0-100) |
maxFrames |
number | 30 | Maximum frames to keep (5-100) |
# Record for 30 seconds
screen.record()
# Record for 60 seconds, capture every 0.5s
screen.record({ duration: 60, interval: 0.5 })
# Returns grid image + metadata with recordingId
screen.scheduled_record
All TiersRecord with scheduled snapshot bursts at specific times. Useful for longer recordings (up to 10 min) where you want to capture specific moments.
| Parameter | Type | Default | Description |
|---|---|---|---|
totalDuration |
number | 60 | Total duration in seconds (10-600) |
snapshots |
array | required | List of snapshot burst configs |
displayIndex |
number | 0 | Display to record (0-based) |
Snapshot Burst Config:
| Property | Type | Default | Description |
|---|---|---|---|
at |
number | required | When to start burst (seconds from start) |
count |
number | 3 | Number of snapshots in burst (1-20) |
interval |
number | 1.0 | Time between snapshots (0.25-10) |
# 4-minute recording with bursts at start, middle, and end
screen.scheduled_record({
totalDuration: 240,
snapshots: [
{ at: 0, count: 3, interval: 1.0 },
{ at: 120, count: 5, interval: 0.5 },
{ at: 230, count: 3, interval: 1.0 }
]
})
screen.get_frame
All TiersRetrieve a full-resolution frame from a recording. Use the recordingId from screen.record or screen.scheduled_record response.
| Parameter | Type | Required | Description |
|---|---|---|---|
recordingId |
string | Yes | Recording ID from screen.record response |
frameIndex |
number | No | Frame index to retrieve (0-based) |
timestamp |
number | No | Timestamp to find closest frame |
# Get frame by index
screen.get_frame({ recordingId: "abc12345", frameIndex: 3 })
# Get frame closest to timestamp
screen.get_frame({ recordingId: "abc12345", timestamp: 15.5 })
screen.status
All TiersCheck your capture quota and license status.
screen.status()
# Returns:
{
"isPaid": false,
"dailyLimit": 10,
"capturesUsedToday": 3,
"capturesRemaining": 7,
"message": "Free tier: 7 of 10 captures remaining today."
}
screen.activate_license
PaidActivate a license key to unlock unlimited captures.
screen.activate_license({ licenseKey: "TEYE-XXXX-XXXX-XXXX" })
# Returns:
{
"success": true,
"message": "License activated successfully! You now have unlimited captures."
}
Free vs Paid
| Feature | Free | Unlimited ($10) |
|---|---|---|
| Daily Captures | 10 | Unlimited |
| All 9 Tools | ✓ | ✓ |
| Multi-Monitor | ✓ | ✓ |
| Screen Recording | ✓ | ✓ |
| Scheduled Recording | ✓ | ✓ |
| Downscaling | ✓ | ✓ |
| License Type | - | Lifetime, any machine |
License Activation
After purchasing, you'll receive a license key in the format TEYE-XXXX-XXXX-XXXX.
Activate in Claude
Simply ask Claude to activate your license:
"Activate my Third Eye license: TEYE-XXXX-XXXX-XXXX"
Or use the tool directly:
screen.activate_license({ licenseKey: "TEYE-XXXX-XXXX-XXXX" })
Storage Location
License and usage data are stored locally in:
- Windows:
%APPDATA%\ThirdEye\usage.json - macOS/Linux:
~/.thirdeye/usage.json
Error Codes
| Code | Description |
|---|---|
CAPTURE_FAILED |
OS permission or policy blocking access |
PERMISSION_DENIED |
Explicit permission denial detected |
INVALID_DISPLAY |
Display index doesn't exist |
OUT_OF_BOUNDS |
Region extends outside monitor |
LIMIT_REACHED |
Daily capture limit exceeded (free tier) |
Support
- GitHub Issues: github.com/Osseni94/third-eye/issues
- Email: admin@grandnasser.com