Daedalus, screenshot pipeline
How the screenshot MCP tool captures the wizard UI
The MCP screenshot tool captures the current Daedalus window as a PNG. Used by Claude (or any MCP client) to "see" the wizard's state and decide next actions.
Pipeline
MCP screenshot call
→ Rust: ScreenshotService.capture(window_handle)
→ macOS ScreenCaptureKit (via screencapturekit crate)
→ CGImage of the window
→ PNG encode (image crate)
→ bytes
→ sanitize_image (optional, future)
→ base64 encode
→ return as MCP image content blockRust side
daedalus/src-tauri/src/commands/screenshot.rs:
#[tauri::command]
pub async fn screenshot(window: tauri::WebviewWindow) -> Result<String, String> {
let cg_image = screencapturekit::capture_window(window.id())?;
let png_bytes = encode_png(&cg_image)?;
Ok(base64::encode(&png_bytes))
}screencapturekit is a thin Rust wrapper around Apple's ScreenCaptureKit framework.
MCP integration
In mcp/tools.rs, the screenshot tool calls the same function and returns the result as a content block:
async fn screenshot_tool(app: &AppHandle) -> Result<ToolCallResult, String> {
let window = app.get_webview_window("main").ok_or("no main window")?;
let b64_png = capture_window_png(&window).await?;
Ok(ToolCallResult::Content(vec![ContentBlock::Image {
data: b64_png,
mime_type: "image/png".into(),
}]))
}The MCP client (Claude) receives the image inline and renders it.
Why ScreenCaptureKit not screencapture CLI
screencapture (macOS's CLI) requires Disk Recording permission, makes a sound, and shutter-flashes. ScreenCaptureKit:
- Silent.
- No shutter.
- Per-window capture (not full-screen).
- Faster.
Permissions
ScreenCaptureKit requires Screen Recording permission in macOS Privacy & Security. Daedalus prompts on first capture. If denied, the screenshot tool returns an error.
Sensitive content
The screenshot includes whatever's on screen, including secret fields if the Secrets wizard page is visible.
Mitigations:
- The Secrets page deliberately masks values (
••••) unless the operator clicks "show." - Operators using Daedalus with Claude should not be on the Secrets page when calling
screenshot. - A future enhancement: capture-time region masking to blank out specific UI elements.
Performance
Capture latency: ~50-200ms for a 1280×800 window. Encode latency: ~100-300ms (PNG compression). Base64 inflation: 4/3.
Total screenshot round-trip: under 500ms typical.
Linux / Windows support
Currently macOS-only. Linux would use X11 / Wayland; Windows would use DXGI. Not yet implemented, Daedalus is macOS-first.
Testing
cd daedalus/src-tauri
cargo test screenshotThe test mocks the window handle and verifies PNG output structure. Visual fidelity is verified manually.