1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-03 15:20:05 -04:00

Add egui_kittest_mcp server

New binary crate that exposes an MCP (Model Context Protocol) server backed by
the `egui_inspection` protocol. The server bridges a running egui peer — a
spawned `egui_kittest` harness child process or an attached live `eframe` app —
to MCP tool handlers that drive it.

Components:
- `bridge.rs`: spawns / attaches a peer over a unix socket, runs reader+writer
  Tokio tasks that pump `HarnessMessage` ↔ `InspectorCommand` and track the
  peer's `Hello`, latest frame, accesskit tree, and blocked / finished state.
- `tools.rs`: `rmcp`-derived tool router with commands for stepping, event
  injection (click / type / scroll / hover / drag / keys), resizing, screenshot
  capture, accesskit tree queries, and lifecycle (launch / attach / kill).
- `tree.rs`: accesskit-tree projection helpers shared by the tools.
- `shim.rs` / `main.rs`: shim role that lets the same binary act as the child
  inspector for kittest harnesses, relaying bytes between the harness stdio
  and the MCP server's unix socket.
- `server.rs`: rmcp stdio entry point.

Live-app example added at `examples/egui_mcp/`.
This commit is contained in:
lucasmerlin
2026-05-21 12:11:00 +02:00
parent e3bdddf306
commit e15ba138d6
11 changed files with 2553 additions and 9 deletions

View File

@@ -0,0 +1,49 @@
[package]
name = "egui_kittest_mcp"
version.workspace = true
authors = ["Lucas Meurer <hi@lucasmerlin.me>"]
description = "MCP server that drives egui apps via the kittest inspector protocol"
edition.workspace = true
rust-version.workspace = true
homepage = "https://github.com/emilk/egui"
license.workspace = true
repository = "https://github.com/emilk/egui"
categories = ["gui", "development-tools::testing"]
keywords = ["egui", "kittest", "mcp", "testing", "accesskit"]
publish = false
[[bin]]
name = "kittest-mcp"
path = "src/main.rs"
[dependencies]
egui_kittest = { workspace = true, features = ["inspector_api", "wgpu", "snapshot"] }
egui_inspection = { workspace = true, features = ["protocol"] }
egui.workspace = true
accesskit.workspace = true
accesskit_consumer.workspace = true
image = { workspace = true, features = ["png"] }
rmp-serde.workspace = true
serde = { workspace = true, features = ["derive"] }
serde_json = "1.0"
schemars = "1.0"
rmcp = { version = "1.7", features = ["server", "macros", "transport-io", "schemars"] }
tempfile.workspace = true
tokio = { version = "1.49", features = [
"rt-multi-thread",
"io-std",
"io-util",
"process",
"net",
"sync",
"macros",
"time",
"signal",
] }
base64 = "0.22"
anyhow = "1.0"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
[lints]
workspace = true