Live preview + element inspector MCP server for Claude Code. Click any DOM element in a running preview and Claude instantly sees the exact element name (component, id, aria-label, …), code location, computed styles, parent chain, and UI/UX terminology — then edits the file directly.
No external LLM calls. All reasoning happens in Claude itself.
cd servers
npm installRegister the MCP server in ~/.claude.json (replace </path/to> with your absolute checkout path):
"ui-inspector": {
"type": "stdio",
"command": "node",
"args": ["</path/to>/ui-inspector/servers/inspector-server.mjs"]
}Restart Claude Code.
preview_start— new Vite session (react / vue / vanilla template)preview_attach— attach to an existing Next.js/Vite/etc. dev server via inject proxypreview_update— write/delete files and trigger Vite HMRpreview_statuspreview_stoppreview_export— convert to target framework + zippreview_screenshot— capture viewport or single selector (mobile / tablet / desktop / full)preview_errors— runtime errors captured from the page (uncaught errors, unhandled rejections,console.error)
preview_select_element— enable/disable inspector mode or fetch selection (session-scoped)inspector_get_selection— most recent click across all sessions; called when the user says "this", "here", "the selected one"inspector_clear_selectioninspector_highlight— agent → browser visual pointing: flash-highlight an element by CSS selector ordata-atvalue, with optional label ("여기 수정했어요")
annotation_list— all annotations (pins + comments) left by the user in the browser, with full element contextannotation_resolve— mark annotations resolved (pins turn green live in the browser) with an optional note;reopen: trueto undoannotation_remove— delete annotations (ids or all)annotation_to_prompt— convert annotations into an agent-ready markdown task list (same format as the in-browser Copy Prompt button — paste into Claude Code, Codex, or any coding agent)
query_ontology— local design knowledge storevalidate_design— contrast / tap target / hierarchy / spacing rules
The injected toolbar (bottom-right) is a monochrome capsule cluster: a ◉ brand circle (click = exit all modes), a mode capsule with Inspect | Annotate | Manage ▾, and a Copy Prompt (open/total) CTA capsule that inverts on hover. Press ESC any time to exit Inspect/Annotate mode (it first closes an open dialog, pin popup, or menu). The side panel renders as white ticket cards (mono type, red accent) on a near-black ground, and slides the toolbar out of its way.
- Toggle Annotate and click any element — a comment dialog opens (⌘+Enter to save)
- A numbered amber pin appears. Add as many annotations as you want — multiple pins on the same element are supported (they stack side-by-side)
- Drag to batch-select: in Annotate mode, drag a marquee over a region — every top-level element fully inside it gets selected (if the selection collapses to a single wrapper, it descends into its children), then one comment creates a group annotation (one pin, up to 30 elements). The pin popup shows a "요소 N개" chip and outlines every member; the agent receives per-element selectors and source locations
- Click a pin to edit the comment, resolve/reopen, or delete it
- Ask the agent to apply them: it calls
annotation_list, edits the files, then callsannotation_resolveper item — the pin turns into a green ✓ in real time, with the agent's resolution note in the pin popup - Annotations live on the server, so they survive page reloads, navigation, and HMR. Pins re-anchor via
data-at→ CSS path → selector - Pins are page-scoped: each pin only renders on the page (pathname) where it was created — navigating elsewhere hides it, coming back restores it. SPA route changes (pushState) are detected without a reload. The toolbar count and Copy Prompt cover the current page;
annotation_list/annotation_to_promptstill return every page (each item carries itspageUrl) - No MCP? Press Copy Prompt to copy the current page's annotation set as a markdown task list for any AI coding agent
- Bulk manage (Manage ▾): resolve or delete all annotations at once, scoped to this page or all pages. Delete is two-click (arms → confirm) to avoid accidents. Counts update live as you work
Each annotation carries: comment, status, element name, robust CSS path, source location (data-at), UI term, computed styles, text, size, and a truncated HTML snippet.
The annotation UI ships with the inject proxy (
preview_attach). Forpreview_startsessions, attach to the Vite URL if you need annotations.
inspector_get_selection returns:
sourceLocation—{ file, line, column }from thedata-atattribute injected by the Vite pluginelementName— the exact identifier of the element with priority resolution:id→data-testid→aria-label→aria-labelledby→<label for>→ component name (from source filename) →name→alt→title→placeholder→ first class → tag. Returned withprimary,primarySource, plus the full set (componentName,id,testId,ariaLabel,role,selector, …)uiTerm/uiDescription— UI/UX terminology inferred from tag, role, class patterns, and computed-style heuristics (Card, Hero Section, Stack Layout, …)tag,className,textContent(truncated)boundingRect—{ x, y, width, height }computedStyles— background, color, font, padding, margin, display, position, size, border-radius, gapparentChain— up to the body, with id/first-class shorthand
The information panel that pops up in the browser displays the same data — with the exact name shown prominently at the top alongside the source badge.
- Start or attach a preview (
preview_startorpreview_attach) - Toggle the inspector (bottom-right button in the browser, or
preview_select_elementwithaction: enable_inspector) - Click an element in the page — the side panel shows its exact name, source location, design term, and styles
- Ask Claude "change the padding on this"
- Claude calls
inspector_get_selection, reads the file atsourceLocation.file:line, and edits it - Vite HMR reloads automatically
See ~/.claude/skills/ui-inspector/SKILL.md for the skill that wires this up.