# Control protocol `lightcraft --control 7980` (or `LIGHTCRAFT_CONTROL_PORT=7980`) starts a JSON-lines server on `127.0.0.1:7980` (loopback only). One request per line, one reply per line, in order: ```text → {"id": 1, "method": "engine.execute", "params": {"command": "photo.rate", "params": {"rating": 4}}} ← {"id": 1, "ok": true, "result": null} ← {"id": 2, "ok": false, "error": "unknown command `nope`"} ``` Requests are answered on the UI thread between frames (timeout 60 s). The MCP server's connect mode ([mcp.md](mcp.md)) is a thin layer over this channel. Implementation: `crates/ui-egui/src/control.rs` (methods) and `apps/lightcraft/src/control_server.rs` (transport). ## Methods | Method | Params | Result | |---|---|---| | `engine.execute` (alias `ui.menu.invoke`) | `{command, params?}` | Run any engine or UI command (see `engine.commands`) | | `engine.commands` | — | Engine + UI commands: id, label, menu, shortcut, params doc, enabled | | `ui.menu.list` | — | Menu entries | | `ui.inspect` | — | UI state, window, canvas/image rects, active photo, selection, perf, status | | `ui.widgets` | `{filter?}` | On-screen widgets `{id, rect: [x, y, w, h]}` (screen points) | | `ui.clickWidget` / `ui.dragWidget` | `{id, count?, fx?, fy?}` / `{id, toX?, toY?, dx?, dy?, steps?}` | Real egui input on a widget | | `ui.move` / `ui.click` / `ui.drag` | `{x, y, count?, button?}` / `{x, y, toX, toY, steps?}` | Raw pointer input, screen points | | `ui.pointer` | `{events: [{kind: down\|drag\|up, x, y}], alt?, shift?, cmd?}` | Gesture in normalized image coordinates (Detail view) | | `ui.key` | `{key, cmd?, shift?, alt?, ctrl?}` | Key press | | `ui.text` | `{text}` | Text input | | `ui.scroll` | `{dx, dy}` | Mouse wheel | | `ui.set` | partial UI state, e.g. `{"view": "detail"}` | Resulting UI state | | `ui.dialog.confirm` / `ui.dialog.cancel` | — | Close the open dialog | | `ui.resize` | `{width, height}` | Resize the window | | `ui.screenshot` | `{path?}` | `{path, width, height}` once the frame (with finished renders) is captured | | `ui.render` | `{id?, size?, path?}` | Render a photo (PNG to `path`), `{width, height}` | | `app.quit` | — | Close the app |