Skip to main content
Glama

NeoVimMCP

MCP server that receives Neovim buffer updates over HTTP and exposes editor context as MCP tools — to clients on this machine or on any other device on your network.

How it works

Neovim (Lua plugin) --HTTP POST--> NeoVimMCP server <--MCP over HTTP-- phone / laptop / any client

Neovim pushes buffer, cursor, selection and yank state to the server on autocmds; the server keeps the latest snapshot per instance in memory and serves it over the MCP Streamable HTTP transport. Nothing depends on a Unix socket, so an MCP client on another device only needs to reach this machine's IP and port.

Related MCP server: @aetherall/mcp-nvim-tmux

Features

  • MCP over Streamable HTTP — reachable from other devices on the same network

  • HTTP ingest endpoint Neovim POSTs to

  • In-memory state store with focus tracking across multiple Neovim instances

  • Tools for cursor context, line ranges, selection, yank, full buffer and paths

  • Optional bearer-token auth

  • stdio transport still available for local-only setups

Start the server

npm install
npm run build
npm start

The startup banner prints the URLs to use:

[MCP] HTTP listening on 0.0.0.0:4389
[MCP]   MCP endpoint:   http://192.168.1.42:4389/mcp
[MCP]   Neovim ingest:  http://192.168.1.42:4389/nvim/state

Environment variables

Variable

Default

Purpose

NVIM_MCP_HOST

0.0.0.0

Bind address. Use 127.0.0.1 to keep it local-only.

NVIM_MCP_PORT

4389

Listen port.

NVIM_MCP_TOKEN

(unset)

When set, every request except /health needs Authorization: Bearer <token>.

NVIM_MCP_TRANSPORT

http

Set to stdio (or pass --stdio) to also serve MCP over stdio.

Security: the default bind exposes your buffer contents to everyone on the network. Set NVIM_MCP_TOKEN whenever the server is not bound to loopback — the server warns at startup if you have not. For access beyond your LAN, put it behind a tunnel or reverse proxy with TLS rather than forwarding the port.

Connect Neovim

Copy nvim/nvim-mcp.lua into your config's lua/ directory (or add this repo's nvim/ folder to your runtimepath), then:

require("nvim-mcp").setup({
  url = "http://127.0.0.1:4389",
  -- token = "your-token",          -- must match NVIM_MCP_TOKEN
  -- instance = "work-laptop",      -- defaults to hostname-pid
})

Requires curl on PATH. Commands: :NvimMcpSync pushes immediately, :NvimMcpStatus shows the configured URL and instance id.

Connect an MCP client

Any client that speaks the MCP Streamable HTTP transport, on any device that can reach the machine:

{
  "mcpServers": {
    "nvim": {
      "type": "http",
      "url": "http://192.168.1.42:4389/mcp",
      "headers": { "Authorization": "Bearer your-token" }
    }
  }
}

In Claude Code: claude mcp add --transport http nvim http://192.168.1.42:4389/mcp.

For a local-only stdio setup instead:

{
  "mcpServers": {
    "nvim": {
      "command": "node",
      "args": ["/absolute/path/to/nvimMCP/dist/server.js", "--stdio"]
    }
  }
}

Note that stdio mode still binds the HTTP ingest port so Neovim has somewhere to POST — only one instance can own that port at a time.

MCP tools exposed

  • list_editors — every registered Neovim instance and how stale it is

  • get_cursor_context

  • get_lines

  • get_selection

  • get_yank

  • get_full_file

  • get_path

Every tool except list_editors takes an optional instance argument; without it, the most recently focused Neovim is used. Responses include age_ms so a client can tell how fresh the snapshot is.

HTTP API

Method

Path

Purpose

POST

/mcp

MCP Streamable HTTP endpoint (also GET/DELETE for sessions)

POST

/nvim/state

Neovim pushes a state snapshot; absent fields keep their previous value

POST

/nvim/focus

Mark { "instance": "..." } as the active editor

POST

/nvim/detach

Remove an instance from the store

GET

/nvim/state

Dump the store (debugging)

GET

/health

Unauthenticated liveness check

Docker

docker build -t nvimmcp .
docker run -p 4389:4389 -e NVIM_MCP_TOKEN=your-token nvimmcp

Available Tools

6 tools
get_cursor_contextGet Cursor ContextA

Returns current file, filetype, cursor position, and nearby lines.

Inputs: no named parameters.

get_full_fileGet Full FileA

Returns full current buffer content.

Inputs: no named parameters.

get_linesGet Line RangeA

Returns lines from start to end (0-indexed, end-exclusive).

Inputs: end (required), start (required).

get_pathGet file path absolute and relativeB

Returns the absolute and relative path of the current file.

Inputs: no named parameters.

get_selectionGet Visual SelectionA

Returns last visual selection based on '< and '> marks.

Inputs: no named parameters.

get_yankGet Yank RegisterA

Returns unnamed register text and register type.

Inputs: no named parameters.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 6 tools

    Disambiguation5/5

    Each tool retrieves a distinct piece of information: cursor context, line range, selection, yank register, full file, and file path. There is no overlap in purpose.

    Naming Consistency5/5

    All tools follow a consistent 'get_' prefix followed by a clear noun describing the fetched data (e.g., get_cursor_context, get_lines). No mixing of styles.

    Tool Count4/5

    With 6 tools covering essential read operations, the count is reasonable for a focused inspection server, though slightly on the lower side.

    Completeness2/5

    The server provides only read operations, lacking any mutation tools like edit, execute commands, or buffer management. This leaves significant gaps for a NeoVim integration.

    Maintenance

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers