nvim-ui-mcp
nvim-ui-mcp
Playwright for Neovim agents.
An MCP server that lets AI agents see, act on, and verify the real, rendered Neovim UI — not just buffer text and API state.
Table of Contents
Requirements
Installation
npm install -g nvim-ui-mcpMCP Client Configuration
claude mcp add nvim-ui -- npx -y nvim-ui-mcp{
"mcpServers": {
"nvim-ui": {
"command": "npx",
"args": ["-y", "nvim-ui-mcp"]
}
}
}Tools
Exactly 8 tools — deliberately not a generic nvim_* API wrapper.
Usage
The loop is observe → act → wait → observe:
// 1. Start an isolated instance
nvim_launch { "clean": true, "rows": 24, "cols": 80 }
// → { "sessionId": "nvim-1", ... }
// 2. Look at the real screen
nvim_observe { "sessionId": "nvim-1" }
// → { "screen": "…24 rows of text…", "cursor": {...}, "mode": {...} }
// 3. Act
nvim_input { "sessionId": "nvim-1", "keys": "ihello world<Esc>" }
// 4. Synchronize before looking again — see Gotchas below
nvim_wait { "sessionId": "nvim-1", "condition": "contains", "text": "hello world" }
// 5. Verify, cheaply
nvim_observe_diff { "sessionId": "nvim-1" }
// → { "changed": true, "rowChanges": [{ "row": 0, "after": "hello world…" }] }
nvim_close { "sessionId": "nvim-1" }Gotchas
nvim_input and nvim_command return as soon as Neovim accepts the request — not when the
screen has repainted. Observing immediately races the redraw.
contains / not-contains test current screen content, so they work whether the redraw lands
before or after the wait started. redraw, screen-change, and idle are edge-triggered and can
miss a repaint that already happened — use idle only when you cannot predict the resulting text.
Neovim composites floats into a single grid, so popup and float content is already in the
rendered text. The floats array from nvim_observe reports each float's row, col, width,
and height — how you tell a completion popup from buffer text at the same coordinates.
Attach Mode
nvim --listen /tmp/nvim.socknvim_attach { "address": "/tmp/nvim.sock" }The instance belongs to you, so nvim_close refuses it. Neovim sizes the screen to the smallest
attached UI, so requesting a size can shrink your own view.
Development
npm install
npm test # unit + integration, needs a real nvim binary
npm run typecheck
npm run lint
npm run buildSee DESIGN.md for the architecture, the UI event pipeline, and the known gaps.
License
MIT