oleks 9a9d477d5c v0.7.0: name MCP tools by leaf, not fully-qualified
Hardcoding mcp__neovim__vim_* in the agent/skill prose was wrong on
two counts: (1) the prefix was flat-out incorrect — a plugin-shipped
.mcp.json server is namespaced mcp__plugin_<plugin>_<key>__, not
mcp__<key>__; (2) hardcoding any fully-qualified MCP tool name in
prose is fragile — it depends on registration method and topology
(metamcp aggregation injected/removed a segment).

- frontmatter tools:/allowed-tools: use the correct prefix wildcard
  mcp__plugin_nvim-agentic-companion_neovim__* (the allowlist needs a
  real pattern; one place; stable with plugin name + .mcp.json key)
- all prose now names tools by leaf (vim_command, vim_health, …) and
  tells the agent to match those against its actual runtime toolset
  rather than assume a prefix
2026-05-21 13:44:04 +03:00

nvim-agentic-companion

A Claude Code plugin that turns the user's running Neovim into a first-class collaborator.

It assumes two things are already wired up:

  1. mcp-neovim-server reaching the running nvim's RPC socket (default /run/user/1000/nvim.sock, created by NixVim's extraConfigLuaPre serverstart at editor startup). The plugin ships a .mcp.json that points the neovim MCP server at the mcp-session-pool over Streamable-HTTP (pool.localhost:12010/p/neovim/mcp); the pool fronts a supervised stdio→HTTP bridge. Tools surface as vim_*.
  2. coder/claudecode.nvim loaded inside nvim, with <leader>a* keymaps wired (toggle, focus, send, accept/deny diff).

This plugin doesn't ship those — it depends on them and ties them together with one agent and three skills.

Connection path

Claude Code session
  └─ .mcp.json → http://pool.localhost:12010/p/neovim/mcp   (Streamable-HTTP)
       └─ mcp-session-pool (:12010, M=1 session pooler, /repin endpoint)
            └─ nvim-mcp-bridge — supergateway (:12016, --stateful)
                 └─ mcp-neovim-server (stdio child)
                      └─ /run/user/1000/nvim.sock           (nvim msgpack-RPC)
                           └─ the running Neovim

No MetaMCP in this path: nvim is ephemeral and MetaMCP never re-dials a restarted upstream. The pool does re-establish (a fresh initialize), so pool→bridge self-heals. Recovery is event-driven — a systemd.path watching the nvim socket fires a oneshot that POSTs /repin to the pool when the socket (re)appears; no polling. The pool and bridge run on emmett as systemd services under user oleks, so the per-user socket is directly reachable. If vim_* tools are missing: socket exists? systemctl status nvim-mcp-bridge? http://127.0.0.1:12010/pools/neovim pinned? session restarted since the wiring landed?

Layout

nvim-agentic-companion/
├── .claude-plugin/plugin.json    # manifest + userConfig (socket, config path)
├── agents/
│   └── companion.md              # the nvim-companion agent identity
└── skills/
    ├── editor-introspect/        # read live state via the vim_* MCP tools
    ├── editor-act/                # drive nvim safely (open, jump, toggle, run)
    └── claude-code-handoff/       # delegate buffer edits to the in-editor Claude

Agent

companion — answers questions about the running nvim ("what's bound to <leader>ff?", "is lualine actually using catppuccin-mocha?") and acts on it ("open neovim.nix at the lualine block"). It reads the declarative NixVim config as the source-of-truth for why things are set up the way they are, and the live editor for what is actually loaded right now.

Skills

  • editor-introspect — read-only queries against the live nvim (keymaps, buffers, options, diagnostics, plugins, messages, cursor, selection).
  • editor-act — safe driving: open files, jump to definitions, trigger user keymaps, toggle UI. Does not edit buffer contents.
  • claude-code-handoff — when the work is "change code in this buffer," hand it to the in-editor Claude Code session so the user gets a diff to accept or reject inline.

Why split it three ways

The companion's three jobs have different blast radii:

  • Reads are free; do them eagerly.
  • Edits to navigation/UI are cheap to undo; do them when asked.
  • Edits to code deserve a diff and human review; route them through the inner Claude that already has the right UX for that.

The skills enforce that separation so the agent doesn't drift into running nvim_buf_set_text directly when it should be sending to the Claude Code split.

Configuration

  • nvim_socket — default /run/user/1000/nvim.sock. Where the running nvim listens; must match NVIM_SOCKET_PATH in the nvim-mcp-bridge service that mcp-neovim-server runs under.
  • config_path — default /home/oleks/projects/servers/emmett/nixos/neovim.nix. The declarative NixVim source the companion cites from.

License

MIT.

S
Description
Neovim companion plugin for Claude Code — pairs the running editor (via mcp-neovim-server) with the in-editor coder/claudecode.nvim session. Agent + 3 skills for introspecting live nvim state, driving the editor safely, and delegating buffer edits to the inner Claude Code session.
Readme MIT
199 KiB
Languages
Markdown 100%