Teaching Claude Code to run commands in Neovim

2026-03-07

Inside a Neovim terminal, the $NVIM environment variable points to the parent Neovim’s Unix socket. This means you can query editor state, inspect buffers, check LSP diagnostics, and even send commands — all through Neovim’s msgpack-RPC API.

What’s quite neat here is that since I run Claude Code inside a Neovim terminal window, I can make Claude use this API to query and hook into the running Neovim session and much more easily debug issues with my Neovim config, develop plugins, or help with something inside Neovim.

I wrote a Claude Code skill that teaches Claude how to use this RPC interface. You can find it in my dotfiles.

What can it do?

With the skill loaded, Claude Code can, among many other things:

How it works

The skill teaches Claude to connect to the $NVIM socket using nvim --server "$NVIM" --remote-expr, which can evaluate any Vimscript expression or run arbitrary Lua via luaeval() — giving access to the entire vim.* namespace. The skill also covers other commands like --remote-send for simulating keystrokes and --remote for opening files.

The NVIM_APPNAME gotcha

One non-obvious issue: when NVIM_APPNAME is set (common if you run multiple Neovim configs), all nvim --server commands emit a warning on stdout. This corrupts any parsed output, especially JSON. The fix is to capture the output first, then filter:

result=$(nvim --server "$NVIM" --remote-expr 'EXPR') \
  && echo "$result" | grep -v '^Warning: Using NVIM_APPNAME='

The skill bakes this pattern into every example so Claude uses it consistently.

Safety guardrails

The skill explicitly instructs Claude to:

Setting it up

Place the skill file at ~/.claude/skills/neovim/SKILL.md. Claude Code auto-discovers skills from this directory and loads them based on the skill’s description field.

I run Claude Code inside Neovim using sidekick.nvim, which embeds it in a split alongside my editor. Combined with this skill, it creates a fully integrated experience — Claude can query the same editor state I see and interact with my session directly. You can find my sidekick config here.