layout-debug
Allows inspecting and debugging a running Android app on a device or emulator via adb: captures screenshots, walks the Compose layout tree, lets you select layers, drag/resize elements, and apply live overrides without a rebuild.
Provides integration with Jetpack Compose / Compose Multiplatform apps, exposing the composition tree with source file:line anchors and enabling live UI overrides directly on the running composition.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@layout-debugapply the pending layout tweaks"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
layout-debug-mcp
Point at a layer in a running UI, drag it — the real screen moves — then tell your AI agent what to change.
The agent gets the exact element (source file:line when available, anchors, box, parents, siblings, your live tweaks) instead of a vague description.
One window, two targets, one snapshot format:
Web — any real DOM page on your dev server (React, Vue, plain HTML; Tailwind classes become strong grep anchors).
Android — Jetpack Compose / Compose Multiplatform on a device or emulator via
adb: full composition tree withfile:linefrom the compiler, and live overrides on the device without a rebuild.
What the tool sees. It captures screenshots and the layout tree of the UI you point it at and hands them to the agent you connect. Don't run it against screens that show data you wouldn't paste into that agent.
Features
Select any layer — hover highlights, click selects; breadcrumbs go up to parents, the "Inside" list goes down to children. Works on wrappers and containers, not only on accessible nodes.
Live edit — drag to move, corner handle to resize. On the web it's inline styles; on Android the override is applied to the running composition, no Gradle build.
Hand-off to an agent — write a comment, send it; the element's artifacts go with it. Live tweaks are passed as a measured intent (delta in
dp/css-px, box before and after, parent and siblings), with an instruction to express it via padding / gap / size in code.Two ways in — an MCP server for any MCP client (Claude Code, Cursor, VS Code, …), or an optional built-in chat on the Claude Agent SDK.
Local only — window, server and MCP process run on your machine. No cloud, no telemetry.
Related MCP server: Autonomo MCP
Requirements
Node.js 20+
For Android:
adbinPATH, an app built in debug with the on-device agent (see Android)
Quick start
Try it on the bundled demo page — no configuration:
git clone https://github.com/AntonChuraev99/Layout-debug-mcp.git
cd Layout-debug-mcp
npm install
npm run devOpen http://localhost:5174. The demo page is already loaded: hover, click, drag, write a comment.
npm run dev starts three processes: the inspector bundle in watch mode, the server on 127.0.0.1:5175, and the UI on 5174. Keep it running — the MCP server is a thin client of this server.
Then connect your MCP client and ask the agent: "take the pending layout requests and apply them".
Connect your MCP client
The MCP server is a stdio process: npx tsx <repo>/src/mcp/index.ts. Use an absolute path to the cloned repo — clients don't start it from the repo directory.
One-command install (
npx layout-debug-mcp, MCP Registry, Claude Code plugin) is on the roadmap.
Claude Code
claude mcp add --transport stdio --scope user layout-debug -- npx tsx /abs/path/to/Layout-debug-mcp/src/mcp/index.tsOn native Windows npx needs a shell wrapper (PowerShell or cmd; in Git Bash write cmd //c, otherwise MSYS rewrites /c into a path):
claude mcp add --transport stdio --scope user layout-debug -- cmd /c npx tsx C:/path/to/Layout-debug-mcp/src/mcp/index.ts--scope user makes it available in every project. --scope project writes it into the project's shared .mcp.json — with an absolute path that only works on your machine.
Check it: claude mcp list in a terminal, or /mcp inside a session. A server added mid-session shows up after the session restarts.
Cursor
~/.cursor/mcp.json (global) or .cursor/mcp.json (project):
{
"mcpServers": {
"layout-debug": {
"command": "npx",
"args": ["tsx", "/abs/path/to/Layout-debug-mcp/src/mcp/index.ts"]
}
}
}VS Code
.vscode/mcp.json — note the key is servers and type is required:
{
"servers": {
"layout-debug": {
"type": "stdio",
"command": "npx",
"args": ["tsx", "/abs/path/to/Layout-debug-mcp/src/mcp/index.ts"]
}
}
}Claude Desktop
claude_desktop_config.json (Windows: %APPDATA%\Claude\, macOS: ~/Library/Application Support/Claude/):
{
"mcpServers": {
"layout-debug": {
"command": "npx",
"args": ["tsx", "/abs/path/to/Layout-debug-mcp/src/mcp/index.ts"]
}
}
}Codex CLI
~/.codex/config.toml:
[mcp_servers.layout-debug]
command = "npx"
args = ["tsx", "/abs/path/to/Layout-debug-mcp/src/mcp/index.ts"]Windsurf, Gemini CLI, others
Same command / args pair under mcpServers in the client's MCP config (Windsurf: ~/.codeium/windsurf/mcp_config.json, Gemini CLI: settings.json).
Tools
Tool | What it does | Parameters |
| Tree of the latest snapshot: nodes, sizes, anchors for finding them in code. Depth-limited |
|
| What the user has selected in the window right now: box, anchors, parent chain, live tweaks | — |
| Requests sent from the window: comment + element artifacts + drag measurements |
|
| Writes to the window's chat — what changed, which files, what's left. The user watches the window, not the terminal |
|
The first three read state, the last one adds to it. If the window is closed, the reply is kept and shown next time it opens.
Using the window
Action | What happens |
Hover | Highlights the element under the cursor (the tightest box) |
Click | Selects the layer; breadcrumbs go up to parents, the "Inside" list goes down to children |
Drag | Moves the element in the page / on the device; the panel shows the offset |
Corner handle | Resizes |
Selection mode off | Clicks go to the page — press buttons and navigate the app |
Reset edits | Removes all live tweaks |
Send | Comment + artifacts go to the built-in agent, or to the queue for MCP |
Connect your own web project
Add the inspector to your page, dev only:
<script src="http://127.0.0.1:5175/inspector.js"></script>It talks only to the parent window (the tool's UI) and sends nothing anywhere else.
Copy
layout-debug.config.example.jsontolayout-debug.config.jsonin the tool's directory:{ "targetUrl": "http://localhost:3000", "projectDir": "/abs/path/to/my-web-app" }projectDiris the repo the built-in chat agent may edit. Without it the chat is off and requests queue up for MCP.
For source mapping add a build step that writes data-source-loc="file:line" on JSX elements; without it the agent finds the element by data-testid, id and the class string.
Android
The on-device agent is a small debug-only component: it walks the real Compose tree via ui-tooling (asTree() gives boxes and compiler source info), serves it with a PixelCopy screenshot over HTTP, and applies live overrides. The tool reaches it through adb forward, which it sets up and re-establishes by itself.
Status: the agent works in a spike app and is not yet packaged as a library. Publishing it to Maven Central as a one-line
debugImplementationis the next Android milestone. Until then Android mode is for early testers.
Run the tool in Android mode:
LD_TARGET=android LD_DEVICE=emulator-5554 LD_PROJECT_DIR=/abs/path/to/my-app npm run devPowerShell:
$env:LD_TARGET='android'; $env:LD_DEVICE='emulator-5554'; $env:LD_PROJECT_DIR='C:/path/to/my-app'; npm run devLD_DEVICE is needed only when more than one device is attached. The app must be running in a debug build.
Configuration
Environment variables override layout-debug.config.json, which overrides defaults.
Env var | Config key | Default | Meaning |
|
|
|
|
|
| bundled demo | Page to inspect (web) |
|
| — | Repo the built-in chat agent may edit; unset = chat off |
|
| — |
|
|
|
| On-device agent port (android) |
| — |
| Where the MCP process finds the server |
Ports: UI 5174, server 5175.
How it works
target page / Android app your machine
┌────────────────────┐ postMessage / adb forward ┌──────────────────────┐
│ inspector / agent │ ◄───────────────────────────► │ server 127.0.0.1:5175│
└────────────────────┘ │ snapshot · selection │
│ request queue │
┌──────────────┐ WebSocket └───┬──────────────┬───┘
│ UI :5174 │ ◄──────────────────────────────┘ local HTTP │
│ frame+overlay│ ┌──────────────▼───┐
│ chat │ │ MCP stdio server │ ◄── your agent
└──────────────┘ └──────────────────┘Both adapters produce the same normalized snapshot — nodes with boxes in frame pixels, pxPerUnit to convert to dp / css-px, anchors (sourceLoc, test id, classes, text) and a flat bag of platform properties. The UI, the chat and MCP don't know which platform the data came from.
Security
The server listens on
127.0.0.1only and checksOriginandHoston HTTP and WebSocket requests, so a web page open in your browser can't drive it (including via DNS rebinding).The built-in chat agent may use only
Read,Edit,Write,Grep,Glob; writes are limited toprojectDir, and.git/,.claude/,.mcp.jsonand.env*are off limits. It loads the project's settings andCLAUDE.md, not your user-level Claude Code settings. Reads are not limited yet — see SECURITY.md for known gaps.Nothing leaves your machine except what goes to the agent you connect: through MCP, your client's agent; through the built-in chat, Claude via the Claude Agent SDK.
The web inspector is added only in dev. The Android agent lives in the debug source set; the spike app still keeps a small inert bridge in the main source set, which the library will split into
-agent/-noopartifacts.
Found a vulnerability? See SECURITY.md.
Limitations
Live edits are a preview, not code: they vanish on page reload or app rebuild.
Tool output, UI and prompts are in Russian for now; English is planned.
npm auditreports a moderate issue in@hono/node-server, a transitive dependency of the MCP SDK's HTTP transport. This project uses only the stdio transport, so that code never runs; downgrading the SDK breaks the Agent SDK's peer dependency.Web: the page is shown in an
iframe— a target that sendsX-Frame-Options/frame-ancestorswon't render. Tree capture is capped at 4000 nodes and synced at most once a second.Android: the frame is a snapshot on request, not a video stream. What moves is the selected node: select an inner
Rowand its content moves while the background stays — go up the breadcrumbs. An override lives until that composable recomposes; the tool re-applies active overrides after each tree refresh.@UiToolingDataApihas no compatibility guarantees; verified on Compose Multiplatform 1.11 / Kotlin 2.3.20. Element text isn't in the artifacts yet —asTree()doesn't expose it without parsing parameters; thefile:lineanchor is more precise anyway.
Troubleshooting
Symptom | Check |
MCP tools answer "server unavailable" |
|
Client doesn't list the server | Absolute path in the config; |
Windows: | Use the |
Server exits with "port 5175 is taken" | Another instance or another dev server holds the port — stop it |
Window says the inspector didn't respond | The script tag is in the page, the target allows framing ( |
Roadmap
Pre-1.0. Next up:
Android agent as a published library (Maven Central,
debugImplementation).One-command install:
npx, MCP Registry, Claude Code plugin.Visible errors for every failure path (adb, device, empty tree, blocked iframe), English UI, tests and CI.
Checked with Claude Code, Cursor, Codex CLI and VS Code.
Later, driven by demand: Compose Desktop, Android Views, Flutter, live video stream from the device.
Contributing
See CONTRIBUTING.md. Bug reports and ideas — issues.
License
This server cannot be deployed
Maintenance
Related MCP Connectors
Control real Android and iOS devices with LLM agents — tap, swipe, type, automate flows.
UI design from prompts, screenshots, and URLs for AI coding agents and theme tokens.
Agent-Native design tool - create and edit visual designs with agent assistance
Live browser debugging for AI assistants — DOM, console, network via MCP.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to read and manipulate visual UI designs drawn on a canvas, translating them into precise JSON specs for production code generation.11,972 npm4ISC
- FlicenseNot gradedqualityCmaintenanceGives AI coding assistants live, structured access to running apps' state and UI elements, enabling real-time verification and interaction across web, mobile, and desktop.36-
- AlicenseNot gradedqualityDmaintenanceEnables AI coding agents to visually interact with frontend apps by taking screenshots, clicking elements, reading console logs, and performing visual diffs.4 npm3MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to perceive and interact with web interfaces by extracting a unified UI Scene Graph from live URLs, providing tools for navigation, element detection, visual analysis, and state tracking.1-