MCP (Model Context Protocol) server inspector and tester for Neovim. Think of it as a Postman/Bruno for MCP — connect to servers, browse their tools, resources, and prompts, call them interactively, and inspect the raw JSON-RPC wire traffic.
Designed to feel at home alongside http.nvim: same split panel, same winbar navigation, same keymaps.
- Both transports: stdio (local subprocesses) and Streamable HTTP (remote servers)
- Interactive inspector: browse Tools / Resources / Prompts with schema-aware param forms
- Call history: re-run previous calls, inspect request/response pairs
- Debug log: raw JSON-RPC wire log for every session
{{var}}substitution: reference env vars in server config (headers, env, URLs)- Protocol spec 2025-11-25: full capability negotiation, version negotiation, graceful decline of server→client requests
- Neovim 0.9+
curl(for HTTP transport)- Node.js /
npx(only if using stdio servers that require it)
With lazy.nvim:
{
"cnrrobertson/mcp.nvim",
config = function()
require("mcp").setup({
servers = {
filesystem = {
transport = "stdio",
cmd = "npx",
args = { "-y", "@modelcontextprotocol/server-filesystem", "/tmp" },
},
},
})
end,
}With deps.nvim:
require("deps").add("cnrrobertson/mcp.nvim")
require("mcp").setup({ ... })require("mcp").setup({
servers = {
-- stdio server (local subprocess)
filesystem = {
transport = "stdio", -- default, can be omitted
cmd = "npx",
args = { "-y", "@modelcontextprotocol/server-filesystem", "/tmp" },
env = {}, -- extra env vars merged into the subprocess environment
},
-- stdio server with env var substitution
my_server = {
cmd = "/path/to/server",
args = {},
env = { API_KEY = "{{MY_API_KEY}}" }, -- reads $MY_API_KEY from environment
},
-- Streamable HTTP server
remote = {
transport = "http",
url = "https://my-mcp-server.example.com/mcp",
headers = { Authorization = "Bearer {{MY_TOKEN}}" },
},
},
windows = {
size = 0.40, -- fraction of screen width/height
position = "right", -- "right" | "left" | "below" | "above"
},
winbar = {
show = true,
sections = { "servers", "inspector", "response", "history", "debug" },
default_section = "servers",
show_keymap_hints = true,
},
request_timeout = 30000, -- ms before a pending request is timed out
vars = {}, -- additional {{key}} = "value" substitution pairs
})| Command | Description |
|---|---|
:Mcp / :Mcp open |
Open the MCP panel |
:Mcp close |
Close the panel |
:Mcp toggle |
Toggle the panel |
:Mcp connect [name] |
Connect to a configured server |
:Mcp disconnect <name> |
Disconnect from a server |
:Mcp call <server> <tool> [json] |
Call a tool directly |
:Mcp view <section> |
Jump to a section |
:Mcp navigate [±n] |
Cycle sections |
All server names and tool names have tab-completion.
:Mcp connect filesystem— opens the panel, connects to the server, auto-fetches tools/resources/prompts- Navigate to Inspector (
]vor click the winbar tab) - Move cursor to a tool →
<CR>to open the param form - Fill in params with
i(opensvim.ui.inputprompt per field) →<CR>to call - Response view opens automatically with the result
- History keeps every call;
<CR>to re-run,ofor detail float,yto yank JSON-RPC - Debug shows the raw JSON-RPC wire log
| Key | Where | Action |
|---|---|---|
q |
any | Close panel |
]v / [v |
any | Next / prev section |
gr |
any | Re-run last call |
g? |
any | Keymap help float |
<CR> |
Servers | Connect / disconnect |
<CR> |
Inspector | Expand item / submit form |
i |
Inspector (form) | Edit parameter via input prompt |
<Esc> |
Inspector (form) | Cancel form |
y |
Response | Yank response JSON |
<CR> |
History | Re-run entry |
o |
History | Detail float |
y |
History | Yank JSON-RPC pair |
| Section | Description |
|---|---|
| Servers | All configured servers with connection status (● ready, ◌ connecting, ○ disconnected, ✗ error) |
| Inspector | Tools, Resources, and Prompts for the active server. Schema-aware param form for tools/prompts. |
| Response | Last call result. Tool content items, resource text/binary, or prompt messages. |
| History | All calls this session with status and elapsed time. |
| Debug | Raw JSON-RPC wire log (every line sent and received). |
Values in env (stdio) and headers (HTTP) support {{VAR_NAME}} placeholders, which are resolved against:
config.vars(explicit key/value table in setup)- The current shell environment (
vim.env)
-- In config
servers = {
secure = {
transport = "http",
url = "{{MCP_SERVER_URL}}",
headers = { Authorization = "Bearer {{MCP_TOKEN}}" },
},
}
-- $MCP_SERVER_URL and $MCP_TOKEN are read from the shell environment- Implements MCP spec 2025-11-25
- Sends
initializewithprotocolVersion = "2025-11-25", negotiates with server response - Warns (via
vim.notify) if server returns a different version - Gracefully declines server→client requests (sampling, roots, elicitation) with JSON-RPC
-32601 - HTTP transport: captures
Mcp-Session-Idheader, sends it on all subsequent requests, sendsDELETEon disconnect
- No
.mcpscriptable test files (planned) - No resource subscriptions
- No progress notification display / cancellation UI
- No tool annotations display
- No SSE resumability (
Last-Event-ID) - Server→client requests (sampling, roots, elicitation) are declined
- http.nvim — HTTP client for Neovim (same author, same UI feel)
- MCP Inspector — official browser-based inspector
- MCP Specification