neovim-use-mcp
This server lets an AI agent edit files through a real Neovim instance, giving access to LSP features, formatting, and plugins instead of plain text editing.
Open and read files as numbered Neovim buffers
Edit files with minimal diffs: replace line ranges, insert lines, or replace exact text
Save buffers without triggering format-on-save autocmds
Get LSP diagnostics, code actions, hover info, definitions, references, and symbol outlines
Rename symbols across the whole workspace via LSP
Format whole files or line ranges
Run arbitrary Neovim Ex commands or Lua code to drive plugins
List open buffers and search workspace symbols
Support multi-file workflows with staged saves
Choose a minimal (10 tools) or full (18 tools) tool set
Edits files through a real Neovim instance, providing LSP diagnostics, code actions, symbol renaming, references, hover, formatting, and access to Neovim commands and Lua scripting.
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., "@neovim-use-mcpFix all TypeScript errors in src/utils.ts using LSP diagnostics and code actions"
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.
neovim-use-mcp
An MCP server that edits files through a real Neovim instance. Your agent gets your language servers, your formatters and your plugins, not a plain text writer.
Real LSP — diagnostics after every edit, rename, code actions, hover, references, document and workspace symbols.
Minimal diffs — edit tools save the buffer with
noautocmd writeby default, soBufWritePre(format-on-save) does not run. Only the edited lines change. Usenvim_formatto format explicitly.Plugin access —
nvim_commandandnvim_exec_luareach anything else.stdio transport — the server starts with the agent and stops with it. It also stops the Neovim child process.
Requirements
Item | Version | Note |
Node.js | 18 or later | The server runs on Node. |
Neovim | 0.10 or later | The server calls |
A Neovim config | optional | Without one, you get edits but no LSP. |
Check your Neovim first:
nvim --version
nvim --headless --embed # must start and stay quiet; press Ctrl-C to stopIf that command prints errors, a plugin breaks headless start. Use
--config-mode minimal until you fix the plugin.
Related MCP server: nvim-mcp
Install
From npm (recommended)
npm install -g neovim-use-mcpOr use npx without a global install:
npx neovim-use-mcpFrom source
git clone https://github.com/santanusinha/neovim-use-mcp.git
cd neovim-use-mcp
npm install
npm run buildThe build writes dist/index.js. That file is the server.
Connect an agent
Add the server to your MCP client config.
With npx (no install needed):
{
"mcpServers": {
"neovim": {
"command": "npx",
"args": ["neovim-use-mcp"],
"env": {
"NVIM_MCP_CWD": "/absolute/path/to/your/project"
}
}
}
}With a global install:
{
"mcpServers": {
"neovim": {
"command": "neovim-use-mcp",
"env": {
"NVIM_MCP_CWD": "/absolute/path/to/your/project"
}
}
}
}From a local build:
{
"mcpServers": {
"neovim": {
"command": "node",
"args": ["/absolute/path/to/neovim-use-mcp/dist/index.js"],
"env": {
"NVIM_MCP_CWD": "/absolute/path/to/your/project"
}
}
}
}NVIM_MCP_CWD sets the project root. The language server uses that root to
find tsconfig.json, go.mod, Cargo.toml and so on. If you leave it out,
the server uses the directory that the agent starts it in.
The server needs no start or stop command. The agent starts it over stdio and stops it on exit. The server then stops its Neovim child process.
First run
Ask your agent to open a file:
Open
src/util/format.tswith the Neovim tools.
A correct answer looks like this:
Opened src/util/format.ts (buffer 1, 59 lines, filetype typescript).
LSP clients: null-ls, quick_lint_js, ts_lsIf you see No LSP client attached, read
When no LSP attaches.
How an agent should work
The tools follow one simple order.
Open the file(s) with
nvim_open_file. Pass an array of paths to open several files at once. This starts the language server. Every LSP tool needs an open buffer.Read with
nvim_read_fileto get numbered lines.Edit with
nvim_edit_text,nvim_edit_linesornvim_insert_lines. Each edit saves the file and returns fresh diagnostics.Fix any new diagnostic with
nvim_code_actions.
Three rules make the results much better:
Use
nvim_rename_symbolfor a rename. Do not use a text replace. The LSP changes every file, and a text replace does not.Use
nvim_edit_textwhen you know the exact text. It fails if the text is not unique, which stops a wrong edit.Stage a multi-file change with
save: false, then callnvim_save_bufferonce per file.
Tools
The server loads one of two tiers. The --tools flag picks the tier.
minimal is the default and loads the 10 tools an agent runs all day.
full loads all 18 tools. No tool is deleted; the tier only decides what
loads into the agent's context.
Minimal tier (default, 10 tools)
Tool | Arguments | Purpose |
|
| Pre-warm files or tune the LSP wait. Other tools open files on demand |
|
| Read numbered lines |
|
| Replace a range, or insert before a line with |
|
| Format a file or a range |
|
| Rename across the workspace |
|
| Find a definition |
|
| Find every reference |
|
| Type and documentation |
|
| List or apply a quick fix |
|
| Run Lua inside Neovim |
Full tier adds (8 tools)
Tool | Arguments | Purpose |
|
| Replace exact text. Tolerates whitespace drift and preserves indentation |
|
| Insert text before a line. Prefer |
|
| Write a buffer (no format-on-save autocmds) |
|
| Errors and warnings for one file or all buffers |
| — | List open buffers |
|
| Outline a file |
|
| Search symbols in the project |
|
| Run an Ex command, for example a plugin command |
Lines and columns start at 1.
Edit tools save the buffer by default and return fresh diagnostics, both as
text and as a structured payload: { saved, line_count, errors, warnings, infos, diagnostics[] }.
nvim_exec_lua runs any code. Turn it off with --no-exec if the agent is
not trusted.
not trusted.
Recipes
Fix every error in a file
nvim_open_file path=src/app.ts
nvim_diagnostics path=src/app.ts severity=error
nvim_code_actions path=src/app.ts line=42 column=9 # list
nvim_code_actions path=src/app.ts line=42 column=9 apply_index=1Rename a symbol everywhere
nvim_open_file path=src/util/format.ts
nvim_document_symbols path=src/util/format.ts # find the line
nvim_rename_symbol path=src/util/format.ts line=28 column=17 new_name=renderIssuesThe tool returns the list of files that it changed and saved.
Change several places, then save once
nvim_edit_text path=src/a.ts old_text="foo(" new_text="bar(" save=false
nvim_edit_text path=src/a.ts old_text="= foo" new_text="= bar" save=false
nvim_save_buffer path=src/a.tsRun a plugin command
nvim_command command="Telescope find_files"
nvim_exec_lua code="return vim.fn.getcwd()"Options
Command line flags win over environment variables.
Flag | Environment | Default | Meaning |
|
|
|
|
|
| — | Socket for attach mode |
|
|
| Path to the nvim binary |
|
|
|
|
|
| exec on | Turn off |
|
|
|
|
|
| process cwd | Project root for the LSP |
|
|
| Default LSP wait |
|
|
| Diagnostics settle wait after an edit; floor 250 |
|
| off | Debug lines on stderr |
Watch the agent work
Attach mode shows you every edit in your own window, live.
Recipes
Fix every error in a file
nvim_read_file path=src/app.ts # implicit open
nvim_edit_lines path=src/app.ts start_line=42 end_line=42 text="..."
# feedback carries diagnostics
nvim_code_actions path=src/app.ts line=42 column=9 apply_index=1Rename a symbol everywhere
nvim_rename_symbol path=src/util/format.ts line=28 column=17 new_name=renderIssuesThe tool returns the list of files that it changed and saved.
Insert before a line
nvim_edit_lines path=src/app.ts start_line=5 end_line=4 text="import { join } from \"node:path\";"start_line = end_line + 1 means insert before start_line.
Stage several edits, then save once (full tier)
nvim_edit_lines path=src/a.ts start_line=10 end_line=10 text="..." save=false
nvim_edit_lines path=src/a.ts start_line=20 end_line=20 text="..." save=false
nvim_save_buffer path=src/a.tsRun a plugin command (full tier)
nvim_command command="Telescope find_files"
nvim_exec_lua code="return vim.fn.getcwd()"A tool is missing
The minimal tier loads 10 tools. Start the server with --tools full to load
all 18. Full-tier tool descriptions start with "Full-tier tool".
A language server does not attach
Check that the file type has a language server in your Neovim config.
Call
nvim_open_filewith a longerwait_ms, for example10000.Confirm the server starts in your own Neovim for the same file.
A stale swap file blocks or warns
The server never writes swap files and never stops on the E325 prompt. A
swap file that sits next to a target file is stale, or another editor owns
it. nvim_open_file still opens the file and prints a note:
Stale swap file ignored: /path/.file.txt.swp. Delete it to remove this note.Delete the .swp file to remove the note. The structured result carries
the path in stale_swap.
The server does not start
Run it by hand and read stderr:
NVIM_MCP_DEBUG=1 node dist/index.jsA healthy start prints:
[nvim-mcp] ready (mode=embedded, tools=minimal, exec=true, cwd=/your/project)A plugin breaks headless Neovim
Use --config-mode minimal. The server then runs nvim --clean. You keep the
edit tools, but you lose your plugins and your LSP setup.
Diagnostics look wrong or stale
A linter bridge, for example null-ls with eslint_d, reports an error when
the project has no lint config. Add the config, or make the null-ls source
conditional on a config file. This is an editor setup problem, not a server
problem.
A tool says the text is not unique
nvim_edit_text refuses an ambiguous match on purpose. Add more context lines
to old_text, or set replace_all: true if you truly want every match.
Development
npm run dev # tsc --watch
npm test # vitest, uses a real headless nvim
npm run typecheck # tsc --noEmit
npm run inspect # MCP Inspector UIDocker
A Dockerfile is included for isolated or CI usage. The image bundles Node and Neovim, but has no user Neovim config. Mount your config if you need LSP:
docker build -t neovim-use-mcp .
docker run --rm neovim-use-mcpReleasing
Releases publish to npm through GitHub Actions with OIDC trusted publishing. No npm token is stored.
Bump the version in
package.json.Tag and push:
git tag v0.x.0 && git push origin v0.x.0.Create a GitHub Release from the tag.
The
Publish to npmworkflow builds, tests, and publishes automatically.
Licence
MIT
This is completely vibe coded. I guarantee absolutely nothing!!
Available Tools
10 toolsnvim_code_actionsList or apply a code actionADestructive
List LSP code actions at a position. Pass apply_index to apply one and save the file. Use this to apply quick fixes for diagnostics.
| Name | Required | Description | Default |
|---|---|---|---|
| line | Yes | Line number, 1-based | |
| path | Yes | File path | |
| column | Yes | Column number, 1-based | |
| wait_ms | No | LSP timeout | |
| apply_index | No | Index from a previous list call; omit to only list |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses that applying an action saves the file, adding a concrete behavioral detail beyond the destructiveHint annotation. It also clarifies the list vs. apply distinction, which is helpful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences front-load the main purpose (list or apply code actions) and immediately follow with the optional apply_index behavior and the common use case. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core functionality, the file-saving side effect, and the intended use case. It does not detail return values, but with no output schema and a straightforward list operation, the provided info is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents apply_index semantics ('Index from a previous list call; omit to only list'). The description reinforces this but adds little new meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists LSP code actions at a position and can apply one by passing apply_index. It uses specific verbs (list/apply) and names the resource (LSP code actions), distinguishing it from sibling tools like nvim_diagnostics.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: 'Use this to apply quick fixes for diagnostics.' It does not explicitly name alternatives or exclusions, but this guidance is sufficient for an agent to know when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvim_edit_linesReplace a line rangeADestructive
This is the default way to edit files. Use the provided line numbers to directly replace lines start_line..end_line (1-based, inclusive) with new text. To insert before a line, pass start_line = end_line + 1 (for example start 5, end 4 inserts before line 5). Saves the buffer by default without running format-on-save autocmds, so the diff is minimal. Returns fresh LSP diagnostics for the file. Use nvim_format to format after editing once editing and fixes on that are done.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path | |
| save | No | Write the buffer, default true | |
| text | Yes | Replacement text; use \n for several lines | |
| end_line | Yes | Last line to replace, inclusive. start_line - 1 means insert | |
| start_line | Yes | First line to replace, 1-based |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as destructive and non-readOnly; the description adds valuable specifics: it saves by default, skips format-on-save autocmds, produces minimal diffs, and returns fresh LSP diagnostics. This goes well beyond what the annotations alone reveal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences deliver the core purpose, range semantics, insert behavior, save behavior, and post-edit formatting guidance with no wasted words. The most important scoping information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a mutating file-editing tool: it covers how to specify the range, how to insert, save semantics, autocmd behavior, return diagnostics, and follow-up formatting. With no output schema, the return-value note is especially useful and there are no critical gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all five parameters. The description reinforces the 1-based inclusive range and the insert trick, but does not add substantial meaning beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: replace lines start_line..end_line with new text in a file. It also frames itself as the default way to edit files, which helps distinguish it from sibling tools like nvim_format and nvim_code_actions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly states this is the default editing method and explicitly directs the agent to use nvim_format after editing is done. It also explains the insert-before convention. It does not enumerate when to prefer other editing-related siblings, but the guidance is sufficient for a safe choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvim_exec_luaRun Lua in NeovimADestructive
Run a Lua chunk inside Neovim and return its value. The chunk receives its arguments through ... and must use return to send a value back. Use this to reach plugins that have no dedicated tool.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Values passed to the chunk as ... | |
| code | Yes | Lua source; use return to send a value back |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, covering the safety profile. The description adds valuable protocol details about how arguments are passed ('through `...`') and the requirement to use `return` to send a value back, which is not explicitly stated in annotations but is essential for correct invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core function, then the argument/return contract, then usage guidance. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool is a generic execution hook, the description adequately covers the execution contract (args, return), the use case (plugins without dedicated tool), and the safety profile through annotations. It lacks an explicit mention of error behavior or supported Lua value types for args/returns, but for a code-execution tool this is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and already documents `code` as 'Lua source; use return to send a value back' and `args` as 'Values passed to the chunk as ...'. The description repeats these details without adding new meaning, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource: 'Run a Lua chunk inside Neovim and return its value.' It clearly distinguishes from higher-level sibling tools by positioning this as a generic escape hatch for 'plugins that have no dedicated tool'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use this to reach plugins that have no dedicated tool,' which implies using dedicated sibling tools when available and only falling back to this generic executor. This provides clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvim_formatFormat a fileAIdempotent
Format a whole file or a line range with the formatter Neovim is configured to use, then save it.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path | |
| wait_ms | No | Format timeout | |
| end_line | No | Range end, inclusive | |
| start_line | No | Range start, 1-based |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already indicate a non-read-only, idempotent, and non-destructive tool. The description adds meaningful behavioral context by explicitly stating that the file is saved after formatting, which is not derivable from the annotations alone. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the action and resource. It contains no filler or redundant information and earns its place entirely.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity, the description covers the essential aspects: scope (whole file or range), the action (format and save), and the formatter context. The schema and annotations cover the remaining details, and an output schema is absent so return values do not need explanation. It is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides descriptions for all parameters (100% coverage), so the description does not need to explain parameters in detail. It does add a slight contextual hint about whole file vs. range, but this adds minimal value over the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Format') on a specific resource ('a whole file or a line range') and additionally notes that it saves afterwards. It distinguishes itself from sibling tools by focusing solely on formatting, which is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool: formatting either an entire file or a specific line range. It does not, however, explicitly exclude alternatives or name sibling tools like nvim_code_actions that might also be able to format, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvim_goto_definitionFind a definitionARead-onlyIdempotent
Find where the symbol at a position is defined, through the LSP.
| Name | Required | Description | Default |
|---|---|---|---|
| line | Yes | Line number, 1-based | |
| path | Yes | File path | |
| column | Yes | Column number, 1-based | |
| wait_ms | No | LSP timeout |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is already disclosed. The description adds that it works through LSP, which is useful dependency context. However, it doesn't clarify whether the tool returns a location, navigates the buffer, or what happens when no definition is found. With annotations covering the read-only aspect, this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler or redundancy. It efficiently communicates the tool's core function in just 10 words, exactly what's needed for a simple LSP query tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with 4 parameters and no output schema. The description covers the basic operation but leaves ambiguous the return value or any cursor/buffer side effects. For a tool without an output schema, a bit more detail about the expected result or failure behavior would improve completeness, but it remains minimally viable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides clear descriptions for all 4 parameters, including line/column being 1-based and wait_ms being an LSP timeout (100% coverage). The description's phrase 'at a position' adds little beyond the schema. Baseline of 3 is appropriate because the schema handles parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Find where the symbol at a position is defined') and the mechanism ('through the LSP'). It distinguishes itself from siblings like nvim_references and nvim_hover by focusing specifically on definitions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool: when you need to locate a definition. It does not explicitly mention alternatives or exclusions, but the focused purpose makes the intended usage obvious. Sibling tool names like nvim_references and nvim_hover further clarify the distinction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvim_hoverGet hover informationARead-onlyIdempotent
Get type and documentation information for the symbol at a position, the same text the editor shows on hover.
| Name | Required | Description | Default |
|---|---|---|---|
| line | Yes | Line number, 1-based | |
| path | Yes | File path | |
| column | Yes | Column number, 1-based | |
| wait_ms | No | LSP timeout |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, and non-destructive behavior. The description adds useful behavioral context by stating it returns the same text the editor shows on hover, which helps the agent understand the output without contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that starts with the action verb and includes the essential scope and output equivalence. There is no wasted wording or unnecessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there is no output schema, the description does a good job of indicating the return content ('same text the editor shows on hover'). It lacks details about exact formatting (e.g., plain text vs. markdown), but it is sufficient for a simple read-only tool with strong annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already has 100% parameter coverage with descriptions for path, line, column, and wait_ms. The description does not add any additional parameter-level semantics, so it meets the baseline but doesn't exceed it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Get' and clearly defines the resource as 'type and documentation information for the symbol at a position'. It further clarifies by noting this is 'the same text the editor shows on hover', which distinguishes it from sibling tools like nvim_goto_definition or nvim_references.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies the tool is for retrieving hover-style information, which is contextually distinct from other tools. However, it does not explicitly mention when not to use it or point to alternatives, so it stops short of full explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvim_open_fileOpen files in NeovimAIdempotent
Open one or more files in Neovim buffers and start their LSP clients. Pass a single path or an array of paths. Returns the buffer id, filetype, line count and attached LSP clients for each file. Optional: use it to pre-warm files or tune wait_ms. Other tools open files on demand.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path, or an array of file paths, absolute or relative to the server cwd | |
| wait_ms | No | Milliseconds to wait for the LSP client to attach |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool idempotent and non-destructive. The description adds behavioral context by stating it starts LSP clients and supports a wait_ms control for client attachment, which goes beyond the structured hints and helps the agent anticipate side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences: core action, input/output summary, and optional use. Information is front-loaded, and every sentence serves a purpose with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description explains return values (buffer id, filetype, line count, LSP clients). It also covers input format, optional waiting behavior, and distinguishes from siblings. Nothing essential for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description's parameter hints ('single path or array', 'tune wait_ms') largely restate the schema and add little semantic value beyond the structured field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action: 'Open one or more files in Neovim buffers and start their LSP clients.' It names the verb, resource, and distinctive side effect. It also differentiates from siblings by noting 'Other tools open files on demand,' giving the tool a clear identity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: 'use it to pre-warm files or tune wait_ms' and notes that other tools open files on demand. This helps an agent decide when to use the tool, though it doesn't name specific sibling alternatives or state explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvim_read_fileRead lines from a Neovim bufferARead-onlyIdempotent
Read a file through Neovim with line numbers. Opens the file if needed. Use start_line and end_line to read a slice of a large file.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path | |
| end_line | No | Last line, inclusive | |
| start_line | No | First line, 1-based |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is clear. The description adds valuable behavioral context beyond annotations: 'Opens the file if needed' discloses a potential side effect, and 'with line numbers' hints at the return format. This goes beyond what annotations provide, though it does not detail error handling or exact output structure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three short sentences, front-loaded with the core purpose. Every sentence earns its place: the first states what it does, the second explains a key behavior (opening the file), and the third gives parameter guidance. There is no redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read tool with strong annotations and complete schema, the description is largely sufficient. It covers the tool's core behavior, optional parameters, and a key side effect. While it could mention error cases or return format in more detail, the absence of an output schema and the simplicity of the operation make this a minor gap. The description is complete enough for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with each parameter described. The description adds practical context by explaining that start_line and end_line are for 'read a slice of a large file,' which clarifies their purpose beyond the schema's individual descriptions. This reinforces the 1-based inclusive semantics and provides a use-case scenario, adding value over the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Read a file through Neovim with line numbers.' It uses a specific verb (read) and resource (file/buffer), and distinguishes itself from sibling edit tools like nvim_edit_lines and nvim_insert_lines by emphasizing read-only behavior and line-numbered output. The title 'Read lines from a Neovim buffer' reinforces this.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by mentioning 'Use start_line and end_line to read a slice of a large file,' which gives context for when parameters are relevant. However, it does not explicitly contrast with alternatives such as nvim_open_file or nvim_edit_lines, nor does it state when not to use this tool. The usage guidance is present but implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvim_referencesFind referencesARead-onlyIdempotent
Find every reference to the symbol at a position, through the LSP. Use this before a rename or a signature change.
| Name | Required | Description | Default |
|---|---|---|---|
| line | Yes | Line number, 1-based | |
| path | Yes | File path | |
| column | Yes | Column number, 1-based | |
| wait_ms | No | LSP timeout |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds that it uses LSP and finds 'every' reference, but does not disclose return format, error behavior, or how it handles the wait_ms timeout. It provides some context beyond annotations but not rich detail, so a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste. The first sentence states the purpose, and the second gives usage context. Perfectly concise and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, the schema covers parameters, and annotations cover safety. The description explains the purpose and use case. It doesn't describe return value or edge cases, but for a read-only LSP references tool with no output schema, this is adequately complete for an agent to invoke correctly. A 4 fits.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, meaning all four parameters (path, line, column, wait_ms) have descriptions in the schema. The tool description does not add extra semantic meaning beyond that, so the baseline 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Find every reference'), the target ('symbol at a position'), and the method ('through the LSP'). This distinguishes it from siblings like nvim_goto_definition (jump to definition) and nvim_hover (show info), making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use this before a rename or a signature change,' giving a clear when-to-use context. However, it does not explicitly name alternatives or say when not to use it, which would move it to a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
nvim_rename_symbolRename a symbolADestructive
Rename a symbol across the whole workspace with the LSP, then save every changed file. Safer than a text search and replace.
| Name | Required | Description | Default |
|---|---|---|---|
| line | Yes | Line number, 1-based | |
| path | Yes | File path | |
| column | Yes | Column number, 1-based | |
| wait_ms | No | LSP timeout | |
| new_name | Yes | New symbol name |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint annotation, the description discloses that it 'save[s] every changed file' and operates 'across the whole workspace,' which is important behavioral context. It doesn't cover undoability or permission requirements, but it adds meaningful detail about side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences with no fluff. The first sentence front-loads the action and scope, and the second provides a comparative benefit. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there is no output schema, the description covers key aspects: what it does (LSP rename), scope (workspace), and side effects (saves changed files). It is sufficiently complete for this straightforward mutation tool, though it could mention potential reliability dependencies on the LSP.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with each parameter already having a clear description. The tool description does not add extra meaning to the parameters, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Rename a symbol across the whole workspace with the LSP, then save every changed file.' It uses a specific verb and resource (rename symbol) and distinguishes itself from sibling editing tools by emphasizing workspace-wide LSP-based renaming.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides context by stating 'Safer than a text search and replace,' which implies when this tool should be preferred over naive text editing. It does not explicitly name alternatives or exclusions, but the rationale gives a clear usage signal.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
9 tool updates
v0.2.1- Removed
nvim_command - Removed
nvim_diagnostics - Removed
nvim_document_symbols - Changed
nvim_edit_lines1 field changed- changed
Input schema / properties / end_line / descriptionPrevious value: -"Last line to replace, inclusive"New value: +"Last line to replace, inclusive. start_line - 1 means insert"
- Removed
nvim_edit_text - Removed
nvim_insert_lines - Removed
nvim_list_buffers - Removed
nvim_save_buffer - Removed
nvim_workspace_symbols
1 tool update
v0.1.4- Changed
nvim_open_file3 fields changed- added
Input schema / properties / path / anyOfAdded value: +[ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / path / descriptionPrevious value: -"File path, absolute or relative to the server cwd"New value: +"File path, or an array of file paths, absolute or relative to the server cwd" - removed
Input schema / properties / path / typeRemoved value: -"string"
18 tool updates
v0.1.0- First observed
nvim_code_actions - First observed
nvim_command - First observed
nvim_diagnostics - First observed
nvim_document_symbols - First observed
nvim_edit_lines - First observed
nvim_edit_text - First observed
nvim_exec_lua - First observed
nvim_format - First observed
nvim_goto_definition - First observed
nvim_hover - First observed
nvim_insert_lines - First observed
nvim_list_buffers - First observed
nvim_open_file - First observed
nvim_read_file - First observed
nvim_references - First observed
nvim_rename_symbol - First observed
nvim_save_buffer - First observed
nvim_workspace_symbols
TDQS
Scored across 10 tools
Each tool has a clearly distinct responsibility: LSP lookups (hover, definition, references), mutations (rename, edit, format, code actions), file I/O (read, open), and an escape hatch (exec lua). Even the similar-looking open vs read tools differ clearly in purpose: one returns buffer metadata, the other returns file content.
All tools share the consistent nvim_ prefix and most use a verb_noun pattern like nvim_read_file and nvim_rename_symbol. Minor deviations like nvim_references and nvim_code_actions being noun phrases, plus bare-verb tools like nvim_format and nvim_hover, keep this from being a perfect 5.
10 tools is a well-scoped set for a Neovim-powered editing and LSP server. Each tool covers a meaningful operation, and there is no obvious redundancy or bloat.
The core workflows are well covered: read, open, edit, format, rename, reference lookup, definition lookup, hover info, and code actions. Minor gaps exist around secondary LSP features like a dedicated diagnostics-only tool, document symbols, or explicit file create/delete operations, but agents can work around these.
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
MCP server for agentverse documentation, generated by doc2mcp.
Official MCP server for Agentwork — delegate tasks to AI agents with human-in-the-loop
An MCP server that gives your AI access to the source code and docs of all public github repos
Related MCP Servers
- FlicenseBqualityDmaintenanceAn MCP server that enables AI agents to control Neovim instances running in tmux sessions.12-
- AlicenseAqualityDmaintenanceMake Neovim feel like Cursor. This MCP server gives an agent full control over the Neovim session it is running inside, including buffers, windows, diagnostics, LSP language intelligence, and terminals.23MIT
- AlicenseNot gradedqualityBmaintenanceAn MCP server that exposes LSP-backed code navigation and editing tools to LLM agents using a single global config file to route file extensions to language servers.MIT
- AlicenseNot gradedqualityBmaintenanceMCP server bridging tool calls to Neovim editor actions via RPC. Enables AI agents to open files, run Lua, manage quickfix lists, fetch diagnostics, and send notifications.GPL 2.0