mcp-interactive-editor
Click on "Install 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., "@mcp-interactive-editorPropose a rewrite of config.json in the diff editor so I can approve before anything touches disk."
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.
mcp-interactive-editor
An interactive editor in front of every file write.
Claude proposes a write. An editor opens with the proposed content on the left and a live diff against what is actually on disk on the right. You edit the proposal by hand — it is your text now — and nothing touches the filesystem until you press the button.
The point is not the confirmation prompt. The point is the editing. When a generated file is 95% right, fixing the last 5% by typing takes a second and changes nothing else. Asking for it in prose costs a round trip and usually rewrites two other things you liked.
┌─────────────────────────────────────────────────────────────────────┐
│▐ HELD .github/workflows/deploy.yml · overwrite +1 −25 │
│ Collapse the three jobs into one. │
├─────────────────────────────────────────────────────────────────────┤
│ BLOCKS This removes 25 of 39 lines (64%). │
│ NOTE No trailing newline. [ Add one ] │
├──────────────────────────────┬──────────────────────────────────────┤
│ PROPOSED — EDIT FREELY │ AGAINST DISK │
│ 1 # Deploy pipeline │ 7 - workflow_dispatch: │
│ 2 name: deploy │ 10 - test: │
│ 3 │ 9 + deploy: │
├──────────────────────────────┴──────────────────────────────────────┤
│ LINES 4–9 · 6 lines what is this job for? ▸ [ Send to Claude ] │
├─────────────────────────────────────────────────────────────────────┤
│ ☑ I have read the diff and I mean to remove those lines. │
│ [ Discard ] [▨ Write 15 lines to deploy ] │
└─────────────────────────────────────────────────────────────────────┘How this actually works
The editor is not something you interact with "inside a tool call". That confusion is worth clearing up, because the whole design follows from it.
YOU CLAUDE HOST MCP SERVER
│ │ │ │
│─ "write ci.yml" ──▶│ │ │
│ │─ propose_write ────▶│────────────────── ▶│
│ │◀──── diff + ui:// ──│◀──── result ────────│
│ │ │ │
│ [Claude's turn ENDS here — the tool call is over] │
│ │ │ │
│ │ renders ui:// in an iframe │
│◀═══════ the editor, a live web page in the transcript ════════▶│
│ │ │ │
│─ type, edit, fix ─────────────────────── │ ─ editor_update ───▶│
│─ press the button ────────────────────── │ ─ editor_commit ───▶│ writes
│ │ │ │
│ │◀─ updateModelContext ─ "here's what landed"│Three things fall out of that:
The tool call returns immediately. It returns text for Claude plus a pointer to a
ui://resource. Claude's turn ends. Nothing is blocked or waiting.The editor is a second, independent MCP client. It talks to the same server over postMessage, proxied by the host. When you type and it saves, that is the page calling the server — Claude is not in the loop, not consuming tokens, not aware. You can sit in that editor for ten minutes.
Two clients, two different tool lists. That is what makes
visibility: ["app"]mean something. The agent and the editor are separate callers, so the server can hand them different capabilities. The agent gets tools that open an editor. The editor gets the tool that writes.
You rejoin the conversation only when you choose to: by pressing the button (which reports back what landed), by discarding, or by selecting a passage and sending it to the chat.
Related MCP server: AI Diff Review MCP
Install
Claude Desktop — one click
Grab mcp-interactive-editor.mcpb from
Releases and
double-click it, or drag it onto Claude Desktop's Extensions screen. It will ask
you to pick the folders it is allowed to write in.
Build it yourself with:
npm install && npm run packSettings → Developer → Edit Config, which opens
%APPDATA%\Claude\claude_desktop_config.json on Windows or
~/Library/Application Support/Claude/claude_desktop_config.json on macOS:
{
"mcpServers": {
"interactive-editor": {
"command": "node",
"args": [
"C:\\path\\to\\mcp-interactive-editor\\bundle\\server\\index.js",
"--root",
"C:\\path\\to\\your-project"
]
}
}
}Backslashes doubled — it is JSON. Then quit Claude Desktop completely and reopen; closing the window is not quitting.
VS Code (GitHub Copilot)
Clone it anywhere. bundle/ is committed, so there is nothing to install or
build:
git clone https://github.com/skurekjakub/mcp-interactive-editor.gitThen add .vscode/mcp.json to your workspace, pointing at the clone:
{
"servers": {
"interactive-editor": {
"type": "stdio",
"command": "node",
"args": [
"/absolute/path/to/mcp-interactive-editor/bundle/server/index.js",
"--root",
"${workspaceFolder}"
]
}
}
}${workspaceFolder} is expanded by VS Code, so the root follows whatever project
you have open. The path to the clone has to be absolute.
Claude Code — plugin marketplace
/plugin marketplace add skurekjakub/mcp-interactive-editor/plugin install interactive-editor@interactive-editorThe plugin roots the editor at your current project directory. Read the host support note below before you rely on it — Claude Code cannot render the editor.
Host support, honestly
MCP Apps need a rendering surface. This is the actual state of play:
Host | Renders | Editing | Committing |
Claude Desktop | ✅ | ✅ | ✅ |
Claude web | ✅ | ✅ | ✅ |
VS Code (Copilot) | ✅ | ✅ | ✅ |
Cursor | ✅ | ✅ | ✅ |
Claude Code / any terminal agent | ❌ | ❌ | ❌ by default |
In a terminal host, propose_write still works and still returns the diff as
text, so the agent sees what it proposed. But the editor can never render, so it
can never attach, so nothing can be committed. That is the correct failure —
it degrades to a hard stop, not an open gate.
If you want the server usable in a terminal anyway, --terminal-approval
exposes the commit tool to the agent and leans on your client's own approve/deny
prompt instead. It is a real gate, but a much weaker one: you get a yes/no on a
diff, not an editor, and it evaporates entirely if you allowlist the tool. The
plugin does not turn it on for you.
Using it
Talk normally. This is a tool, not a mode.
Propose a write — the model writes, you correct it:
Write a GitHub Actions workflow that runs the tests on push to main, at
.github/workflows/ci.yml
Open a file — you edit it yourself, the model stays out of it:
Open
src/config.tsso I can fix it
open_file loads the file into the editor and deliberately does not put the
body in the model's result. It goes to the editor, not into the context window.
The commit button stays dead until you actually change something.
Send a passage back to the chat — select lines in the editor, a bar appears below, type a question, press Send. It arrives in the conversation as if you had typed it, quoted with the path and line numbers:
From the draft open in the interactive editor —
deploy.yml, lines 4–9:jobs: deploy: runs-on: ubuntu-latestwhy is this not pinned to a SHA?
That is ui/message, so it starts a normal turn and the answer arrives in the
chat next to the editor.
After you edit, the model is told what actually landed rather than what it proposed — otherwise the rest of the conversation is built on a file that does not exist.
Making Claude reach for it
The server sends usage instructions at connect time and every tool description says "this never writes". Usually enough. If Claude has other filesystem tools and picks the wrong one, add to your Project instructions:
All file writes go through interactive-editor's propose_write. Never use another
filesystem tool to write, create, or delete files. After proposing, stop and
wait — do not re-propose the same write.Why the model cannot approve its own write
Tool | Callable by | What it does |
| model, editor | Opens an editor. Writes nothing. |
| model, editor | Opens an editor. Deletes nothing. |
| model, editor | Loads a file into the editor. |
| model, editor | Reads inside the roots. |
| model, editor | Lists the roots. |
| editor only | Binds the editor to a proposal. |
| editor only | Saves your edits. |
| editor only | Writes to disk. |
| editor only | Drops the proposal. |
Editor-only tools carry _meta.ui.visibility: ["app"]. Under the
MCP Apps spec the host
must keep those out of the model's tool list and must reject any call the
model makes for them. Claude cannot commit a write — not "is asked not to"; the
tool is not in its list, and the host refuses it if it guesses the name.
Belt and braces, the server also refuses to commit a proposal that no editor
ever attached to. A host that ignored visibility entirely still could not get a
write through without a rendered editor.
The rest of the guarantees
Roots are absolute. A path is writable only if, after full resolution including symlinks, it sits inside a
--root. A symlink planted inside a root pointing outside it does not work.A deny list on top:
.git/,node_modules/,.env,.ssh/,id_rsa,.pem,.key,credentials,.aws/,.npmrc.Stale writes are refused. If the file changes on disk while the editor is open, the commit fails: the diff you approved is not the diff that would apply.
Deleting most of a file needs a tick — over half the lines, or emptying it, or deleting it. Small files are exempt; a checkbox in front of every one-line edit trains you to tick without reading.
Writes are atomic — temp file plus rename, so a crash leaves the original intact rather than half a file.
Everything is rechecked server-side at commit. The editor's checks are for your eyes; the server's are the ones with authority.
Options
mcp-interactive-editor --root <dir> [--root <dir> ...] [options]
--root <dir> A directory the editor may write inside. Required, repeatable.
--root-from-cwd Add the working directory as a root.
--deny <substring> Extra path substring to refuse. Repeatable.
--allow-everything-in-roots Drop the built-in deny list.
--dry-run Run the whole flow but never touch disk.
--terminal-approval Expose the commit tool to the agent, for hosts with no UI.INTERACTIVE_EDITOR_DRY_RUN=true does the same as --dry-run, for launchers
that cannot add a flag conditionally. --dry-run is the honest way to try this
on a real project: everything works, the receipt says what would have happened,
nothing changes.
Development
npm install
npm run preview # the editor at localhost:5178, fixture data, no host needed
npm test # 85 tests, unit + end-to-end over a real stdio server
npm run verify # typecheck + format + test, same as CI
npm run pack # build the .mcpb bundlenpm run preview serves the editor in a plain browser tab with an in-memory
server, running the same diff and lint modules as the real thing. No host, no
risk to any file.
Layout
shared/ types, line diff, lint rules — imported by BOTH the server and
the editor, so what you see is computed the way the server checks it
src/ fsGuard (roots, deny list, atomic write), proposals, tools, server
ui/ the editor: React, built to one self-contained HTML file
bundle/ committed distribution artifact — esbuild'd server + the editor.
Claude Code installs plugins by git clone with no build step.
test/unit/ shared modules and the filesystem guard
test/e2e/ a real server over stdio, driven by an MCP client
.claude-plugin/ Claude Code plugin marketplace manifests
server.json MCP registry metadatashared/ exists so the editor can recompute the diff and findings on every
keystroke without a round trip, while the server recomputes the identical thing
before committing. Same code, two audiences, one of them authoritative.
The editor ships as a single inlined HTML file because the host serves it into a
sandbox with connectDomains, resourceDomains and frameDomains all empty. No
CDN, no fonts, no network. An editor that can phone home would be a worse problem
than the writes it is guarding.
Publishing
bundle/ is committed and CI fails if it drifts from src/, because Claude Code
plugin users install straight from the repo tree. Run npm run bundle and commit
the result with any change to the server or editor.
License
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Preventive human-approval write-gate for AI agents: writes commit only after a human approves.
Security reviews for coding agents: diffs checked against your org policy and live infrastructure.
AI agents propose database changes as reviewable requests — no direct write access.
Versioned artifact review for people and AI agents, with contextual comments and human control.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables AI assistants to perform code reviews by providing access to staged files, git diffs, and repository file content. It allows users to evaluate changes and context within any local git repository before committing or pushing.317ISC
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to edit files in VS Code with an interactive diff review panel, allowing users to accept or reject changes.1MIT

CodePeel MCP Serverofficial
FlicenseAqualityDmaintenanceEnables AI agents to review code diffs for bugs, security issues, and bad patterns, and generate fixes.4- AlicenseAqualityFmaintenanceEnables AI assistants to draft content such as PR descriptions, tickets, or messages, with a review window for live preview, editing, and approval before submission.1191MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/skurekjakub/mcp-interactive-editor'
If you have feedback or need assistance with the MCP directory API, please join our Discord server