An MCP server that gives AI agents a focused, windowed editing experience — the way a human uses an editor.
Built-in Read/Edit/Write tools force agents to load entire files, match strings blindly against the full text, and risk ambiguous replacements. viewport-editor replaces this with viewports: focused windows into files where every edit is scoped, every change can be staged and reviewed, and the agent always knows exactly what file, range, and mode it is working in.
AI agents edit files differently than humans. A human opens a 500-line file, sees a 30-line window, works within it, scrolls when needed, and saves. An agent using current tooling must:
- Read the entire 500-line file (costly context)
- Construct a string match against all 500 lines (ambiguous)
- Blindly replace and write back (no review)
viewport-editor collapses this to: open a viewport, edit within it, review before saving.
A viewport is a focused window into a file. The server uses the current working directory as the project root. All file paths are relative to this root — no absolute or host-specific paths in agent-facing interfaces. Every operation returns the full context:
viewport_entry:
file: src/main.py
start_line: 10
end_line: 40
mtime: 1716500000
size: 12345
mode: bufferedThe agent always knows what it is looking at, where it is, and what mode it is in.
Each viewport has a buffer. In buffered mode (default), edits stage into the buffer and write to disk only on explicit save. The agent can make multiple changes, preview a diff, and decide whether to commit.
In immediate mode, each edit writes to disk atomically.
Buffer state is scoped to the MCP connection. Multiple agent sessions can edit the same file without collision. Staleness is detected via mtime + size — soft warning on operations, hard block on save (with a force override).
All operations are exposed through 11 tools with an action parameter. This keeps initial context load low while giving the agent rich expressiveness.
| tool | actions |
|---|---|
| viewport | open, close, list, scroll, page-up, page-down, jump, autosave, set-display-mode |
| edit | replace, replace-all, insert-lines, delete-lines, swap-lines, move-lines |
| file | save, discard, new, save-as, delete |
| diff | show, apply |
| clipboard | copy, cut, paste, show, stash, pop, swap, stash-list |
| search | find |
| regex | test, escape |
| read_file | composite: open + scroll — single-call file read with viewport lifecycle |
| write_file | composite: open + replace-all + save + close — single-call file write with conflict detection |
| edit_text | composite: open + replace + save + close — single-call targeted edit with conflict detection |
| find_text | composite: search wrapper — single-call text search |
No setup required. The project root is the current working directory at server start.
Run directly from the tagged release — no PyPI install, no repo clone needed:
{
// Other MCP Clients (Claude, Cursor, etc.)
"mcpServers": {
"editor": {
"command": "uvx",
"args": ["--from", "git+https://github.com/michael-conrad/viewport-editor@v0.5.0", "viewport-editor"]
}
}
}git clone git@github.com:michael-conrad/viewport-editor.git
cd viewport-editor
uv run viewport-editor
When adding viewport-editor as an MCP plugin, configure it in your opencode.jsonc:
{
"mcp": {
"editor": {
"type": "local",
"command": ["uvx", "--from", "git+https://github.com/michael-conrad/viewport-editor@v0.5.0", "viewport-editor"],
"enabled": true
}
}
}Then add the following stanza to your repository's AGENTS.md:
### editor MCP Plugin
This repo uses [viewport-editor](https://github.com/michael-conrad/viewport-editor) as its editing MCP server.
**11-tool surface** (see README for full action lists):
| Tool | Purpose |
|------|---------|
| **viewport** | Open, navigate, and manage focused editing windows |
| **edit** | Stage text changes into viewport buffers (replace, insert, delete, swap, move) |
| **file** | Commit or discard staged changes to disk |
| **diff** | Show unified diffs of pending edits before saving |
| **clipboard** | Copy/cut/paste content across viewports with provenance tracking |
| **search** | Find text with substring or regex matching |
| **regex** | Test and escape regex patterns |
| **read_file** | Composite: open + scroll — preferred over built-in `read` for single-call reading |
| **write_file** | Composite: open + replace-all + save — preferred over built-in `write` for conflict-safe writing |
| **edit_text** | Composite: open + replace + save — preferred over built-in `edit` for targeted changes with conflict detection |
| **find_text** | Composite: search — preferred over built-in `grep` for structured results |
**recommended agent behavior:**
- Use `read_file`, `write_file`, `edit_text`, `find_text` for single-call operations (empirically validated — see viewport-editor#63 V1 results)
- Use `viewport` + `edit` + `file` for multi-step editing with diff review
- Always call `diff:show` before `file:save` to verify staged changes
- File paths are relative to project root (MCP resolver defaults to `os.getcwd()`)
- Session management is automatic (MCP framework handles session IDs)
- Conflict detection: server tracks file mtime+size externally; stale-file soft warning on reads, hard block on `file:save` (use `force: true` override if change is intentional)- Prose + YAML only — tool descriptions, input schemas, and responses use natural language and YAML. No JSON.
- list_tools for discovery — no dedicated help tool. The MCP protocol's standard discovery mechanism is sufficient.
- True delta diffs —
diff:showalways compares against the original file on disk, not the last save. - apply-diff always stages — diffs are never applied directly to disk. Review first with
diff:show, thenfile:save. - Per-viewport mode — each viewport selects its own mode (buffered or immediate). Switch modes with
viewport:set-display-mode(refuses if buffer is dirty).
| tool | relationship |
|---|---|
| Built-in Read/Edit/Write | Coexist. Use for simple whole-file operations. Use viewport-editor for complex editing. |
- Phase 1 (MVP): All 6 tools, both operational modes, conflict detection, multi-viewport, session isolation
- Phase 2: AST-based structural navigation, configuration file for defaults
MIT
🤖 Co-authored with AI: OpenCode (ollama-cloud/deepseek-v4-flash)