14 AI Screenshots

Jotain can render the current frame to an image file so an AI assistant (or you) can see how Emacs looks. The capture uses the built-in x-export-frames, which draws the frame straight to PNG/SVG/PDF on cairo builds — no external screenshot tool, no window-manager wrangling. The technique follows Automating Emacs Screenshots Emacs Redux.

Two entry points share the same code path: an interactive command for live sessions, and a headless just recipe for terminal-only environments such as CI or a cloud agent container.

14.1 M-x jotain-screenshot

Captures the selected frame and writes it to var/screenshots/<timestamp>.png (the path is echoed and pushed onto the kill ring). From Lisp, both the output file and the format are parameters:

(jotain-screenshot)                    ; var/screenshots/<timestamp>.png
(jotain-screenshot "/tmp/frame.svg" 'svg)

The command needs a graphical frame on a cairo build (the default Linux X11 build; pgtk also carries cairo). It signals a user-error on tty frames and on builds without x-export-frames — noGui (nix-on-droid) and the macOS NS port.

14.2 The emacs_screenshot MCP tool

init-ai.el registers the command as a custom MCP tool with claude-code-ide, so a Claude Code session attached to Emacs (C-c q) can call emacs_screenshot, get back the image path, and read the file to see the frame.

For the tool to be served, claude-code-ide-enable-mcp-server must be non-nil — Jotain now sets it in the claude-code-ide block. This starts a small local MCP server per Claude session (loopback only); it also enables claude-code-ide’s built-in Emacs tools for the session.

A typical exchange: ask Claude "take a screenshot and check the mode line" — it calls emacs_screenshot, then views the returned PNG.

14.3 Headless: just screenshot

For environments with no display at all — CI, a cloud agent container, an SSH box — the screenshot recipe builds Emacs via Nix, launches it with this repo’s config under a virtual X server (Xvfb, 1920×1080), captures the frame once startup settles, and exits:

just screenshot                      # → var/screenshots/headless.png
just screenshot /tmp/frame.png       # explicit output path

xvfb-run comes from the devenv shell (Linux only — Xvfb is X11, and the macOS ports lack x-export-frames anyway). Exit status is 0 on success, 2 if init or the capture failed, non-zero from timeout if the run wedged.

Caveats: