Skip to content

Add egui_inspection protocol and plugin - #8234

Merged
lucasmerlin merged 11 commits into
mainfrom
lucas/egui-mcp-scoped
Jun 18, 2026
Merged

lucasmerlin merged 11 commits into
mainfrom
lucas/egui-mcp-scoped

Conversation

@lucasmerlin

Copy link
Copy Markdown
Collaborator

Introduces live inspection for running egui apps over a small TCP request/response protocol, plus the egui::Plugin that serves it.

This is the minimal surface to get the egui mcp in, we may want to extend this in the future to add support for the inspection gui.

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown

Preview available at https://egui-pr-preview.github.io/pr/8234-lucasegui-mcp-scoped
Note that it might take a couple seconds for the update to show up after the preview_build workflow has completed.

View snapshot changes at kitdiff

@lucasmerlin
lucasmerlin force-pushed the lucas/egui-mcp-scoped branch 3 times, most recently from 3dd8ebc to 726f89a Compare June 12, 2026 07:22
The input/output hooks previously received only `&mut RawInput` /
`&mut FullOutput`, so a plugin needing the `Context` (to request a repaint
or send a viewport command) had to store a clone — which the `Plugin` docs
explicitly warn against, as it creates a reference cycle that keeps the
`Context` alive. Pass `&Context` into both hooks (as `on_widget_under_pointer`
already does) so plugins can get it on demand instead of holding it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lucasmerlin
lucasmerlin force-pushed the lucas/egui-mcp-scoped branch 4 times, most recently from 8b53aa7 to 39d493b Compare June 12, 2026 09:11
Live inspection for running egui apps over a small TCP request/response
protocol, plus the `egui::Plugin` that serves it.

`egui_inspection`:
- `protocol`: request/response wire format (`Info` / `GetTree` /
  `Screenshot` / `HandleEvents` / `Resize`), MessagePack-framed via shared
  `encode_frame` / `decode_frame_*` helpers.
- `plugin`: `InspectionPlugin`. Requests are submitted through egui's plugin
  handle — `ctx.with_plugin(|p| p.submit(req))` — and serviced on the UI
  thread via a small per-request state machine (inject events, read the
  AccessKit tree, capture a screenshot via a 2-frame round-trip). The hooks
  receive `&Context`, so the plugin stores no `Context` and creates no
  reference cycle. `serve` runs the TCP listener; a host owning its own
  transport (e.g. `re_mcp`) drives the plugin the same way.
- `png`: shared screenshot encoder.
- Env config: `EGUI_INSPECTION` / `EGUI_INSPECTION_ADDR`, default bind
  `127.0.0.1:5719`, with a loud warning when bound non-loopback.

eframe gains an `inspection` feature; `attach_from_env` wires the plugin up
on startup when the env var is set (no-op otherwise, no-op on wasm).
`egui_demo_app` always enables it on native.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lucasmerlin
lucasmerlin force-pushed the lucas/egui-mcp-scoped branch from 39d493b to fe9e4aa Compare June 12, 2026 09:43
@lucasmerlin lucasmerlin added feature New feature or request egui labels Jun 12, 2026
@emilk
emilk marked this pull request as ready for review June 12, 2026 11:00

@emilk emilk left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only 22 comments :)

Comment thread crates/egui_inspection/src/lib.rs Outdated
Comment thread crates/egui_inspection/src/plugin.rs
Comment thread crates/egui_inspection/src/plugin.rs Outdated
Comment thread crates/egui_inspection/src/plugin.rs
Comment thread crates/egui_inspection/src/plugin.rs Outdated
Comment thread crates/egui_inspection/src/plugin.rs Outdated
Comment thread crates/egui_inspection/src/plugin.rs Outdated
Comment thread crates/egui_inspection/src/png.rs Outdated
Comment thread crates/egui_inspection/src/protocol.rs Outdated
Comment thread crates/egui_inspection/src/protocol.rs
@lucasmerlin
lucasmerlin force-pushed the lucas/egui-mcp-scoped branch 5 times, most recently from d0625fa to becc241 Compare June 12, 2026 12:34
lucasmerlin and others added 2 commits June 12, 2026 14:40
Doc backticks (`MessagePack`), `# Errors` sections, short first doc
paragraphs, blank lines before documented fields (egui's lint.py), and
gating eframe's `maybe_attach_inspection_plugin` so it isn't dead code on
wasm / backend-less builds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per @emilk's review of #8234:
- Single `EGUI_INSPECTION` env var (truthy / falsy / bind-addr); dropped
  `EGUI_INSPECTION_ADDR`.
- Connection handshake: 4 magic bytes + 4 version bytes, so an
  incompatible/non-inspection peer is rejected before any MessagePack
  decode (version no longer rides in `Response::Info`).
- Request renames: `GetInfo` / `GetTree` / `GetScreenshot` / `ApplyEvents`;
  `Response::Ack` → `Response::Done` (means *executed*, not just received).
- `EncodedPng { size, bytes }` struct (in `protocol`) with `from_color_image`
  / `from_rgba` ctors, replacing the `encode_png` free fn + tuple.
- Fix screenshot↔request correlation via a `Screenshot::user_data` id, so
  concurrent screenshots map back to the right request.
- `serve_connection` returns `Result`; log/propagate errors instead of
  silently ignoring; loud error when a request times out (app not painting).
- Doc clarifications; `in_flight` doc; `phase != Phase::New`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lucasmerlin
lucasmerlin force-pushed the lucas/egui-mcp-scoped branch from becc241 to ba6b555 Compare June 12, 2026 12:41
lucasmerlin and others added 3 commits June 12, 2026 14:52
The `png` feature doc linked the removed `encode_png` (now `EncodedPng`),
breaking `cargo doc` (broken-intra-doc-links). Drop that link and the
stale `Session` mention in the `plugin` feature doc.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lucasmerlin
lucasmerlin enabled auto-merge (squash) June 18, 2026 08:58
@lucasmerlin
lucasmerlin merged commit 86fcffb into main Jun 18, 2026
46 checks passed
@lucasmerlin
lucasmerlin deleted the lucas/egui-mcp-scoped branch June 18, 2026 09:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

egui feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants