nvim-mcp-server 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +52 -0
- data/README.md +49 -3
- data/exe/nvim-mcp-server +15 -4
- data/lib/nvim-mcp-server/tools/update_buffer_tool.rb +114 -0
- data/lib/nvim-mcp-server/version.rb +1 -1
- data/lib/nvim_mcp_server.rb +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6fb63496112d2e52b2107995965bc2af9f5b335c0119e64c9a08c2a8725904ed
|
4
|
+
data.tar.gz: 3653a0dd083d33c1f876d5ad8b990031e6a1a32f5e02ce68cb4c8d4139ce7bc0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f2b647116afb3904e3d29f95eecc70d642d02c997046030b6556621ddc595f8e787ad2d7e8655d04ac0f56b94326144ef7f84c02ff1d5157ee0dce6afba43e6
|
7
|
+
data.tar.gz: 1b9a694bf4a198e342814eb066ae4e0382bca37073ec6ea93aa771c05287b0d536772982d75ceb0faf9b765a24b832e04fac271d10689622430ebe73f3135fdf
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,57 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
1
8
|
## [Unreleased]
|
2
9
|
|
10
|
+
## [0.2.1] - 2025-07-21
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
- **Network Access Support**: New `--bind-all` flag for HTTP mode to allow access from local network
|
15
|
+
- Binds to `0.0.0.0` instead of `localhost` when enabled
|
16
|
+
- Allows connections from local network IP ranges (192.168.x.x, 10.x.x.x, 172.16.x.x)
|
17
|
+
- Accepts connections from `.local` domain names (e.g., `my-computer.local`)
|
18
|
+
- Maintains security features with origin validation and IP filtering
|
19
|
+
|
20
|
+
### Improved
|
21
|
+
|
22
|
+
- **Security Configuration**: Enhanced allowed origins and IP configuration when using `--bind-all`
|
23
|
+
- Automatically configures appropriate security settings for local network access
|
24
|
+
- Preserves localhost-only mode by default for security
|
25
|
+
- Clear documentation of security implications
|
26
|
+
|
27
|
+
### Changed
|
28
|
+
|
29
|
+
- HTTP server binding address is now configurable via `--bind-all` flag
|
30
|
+
- Updated help text to include new network access option
|
31
|
+
- Fixed typo in default response text (was showing "Rails MCP Server" instead of "Neovim MCP Server")
|
32
|
+
|
33
|
+
## [0.2.0] - 2025-07-08
|
34
|
+
|
35
|
+
### Added
|
36
|
+
|
37
|
+
- New `update_buffer` tool that allows MCP clients to update buffer content in Neovim
|
38
|
+
- Ability to save updated buffers to disk and reload them automatically
|
39
|
+
- Support for external tools (like AI assistants) to modify files open in Neovim
|
40
|
+
|
41
|
+
### Changed
|
42
|
+
|
43
|
+
- Updated tool registration to include both `GetProjectBuffersTool` and `UpdateBufferTool`
|
44
|
+
|
3
45
|
## [0.1.0] - 2025-05-17
|
4
46
|
|
47
|
+
### Added
|
48
|
+
|
5
49
|
- Initial release
|
50
|
+
- Basic MCP server implementation for Neovim
|
51
|
+
- Support for both STDIO and HTTP modes
|
52
|
+
- `get_project_buffers` tool to query open buffers in Neovim instances
|
53
|
+
- Integration with Claude Desktop
|
54
|
+
- Logging functionality with configurable log levels
|
55
|
+
- XDG Base Directory Specification compliance for configuration files
|
56
|
+
- Support for multiple Neovim instances via Unix sockets
|
57
|
+
- MCP Inspector compatibility for testing and debugging
|
data/README.md
CHANGED
@@ -12,6 +12,7 @@ This Neovim MCP Server implements the MCP specification to give AI models access
|
|
12
12
|
|
13
13
|
- Connect to running Neovim instances
|
14
14
|
- Query buffers across multiple Neovim sessions
|
15
|
+
- Update and save buffers with new content
|
15
16
|
- Follow the Model Context Protocol standard
|
16
17
|
- Seamless integration with LLM clients
|
17
18
|
|
@@ -30,7 +31,6 @@ After installation, the `nvim-mcp-server` executable will be available in your P
|
|
30
31
|
The Neovim MCP Server follows the XDG Base Directory Specification for configuration files:
|
31
32
|
|
32
33
|
- On macOS: `$XDG_CONFIG_HOME/nvim-mcp` or `~/.config/nvim-mcp` if XDG_CONFIG_HOME is not set
|
33
|
-
- On Linux: `$XDG_CONFIG_HOME/nvim-mcp` or `~/.config/nvim-mcp` if XDG_CONFIG_HOME is not set
|
34
34
|
- On Windows: `%APPDATA%\nvim-mcp`
|
35
35
|
|
36
36
|
The server will automatically create these directories and a log file the first time it runs.
|
@@ -53,6 +53,9 @@ nvim-mcp-server --mode http
|
|
53
53
|
|
54
54
|
# Start in HTTP mode on a custom port
|
55
55
|
nvim-mcp-server --mode http -p 8080
|
56
|
+
|
57
|
+
# Start in HTTP mode binding to all interfaces (for local network access)
|
58
|
+
nvim-mcp-server --mode http --bind-all
|
56
59
|
```
|
57
60
|
|
58
61
|
When running in HTTP mode, the server provides two endpoints:
|
@@ -60,6 +63,27 @@ When running in HTTP mode, the server provides two endpoints:
|
|
60
63
|
- JSON-RPC endpoint: `http://localhost:<port>/mcp/messages`
|
61
64
|
- SSE endpoint: `http://localhost:<port>/mcp/sse`
|
62
65
|
|
66
|
+
### Network Access (HTTP Mode)
|
67
|
+
|
68
|
+
By default, the HTTP server only binds to localhost for security. If you need to access the server from other machines on your local network (e.g., for testing with multiple devices), you can use the `--bind-all` flag:
|
69
|
+
|
70
|
+
```bash
|
71
|
+
# Allow access from any machine on your local network
|
72
|
+
nvim-mcp-server --mode http --bind-all
|
73
|
+
|
74
|
+
# With a custom port
|
75
|
+
nvim-mcp-server --mode http --bind-all -p 8080
|
76
|
+
```
|
77
|
+
|
78
|
+
When using `--bind-all`:
|
79
|
+
|
80
|
+
- The server binds to `0.0.0.0` instead of `localhost`
|
81
|
+
- Access is allowed from local network IP ranges (192.168.x.x, 10.x.x.x, 172.16.x.x)
|
82
|
+
- The server accepts connections from `.local` domain names (e.g., `my-computer.local`)
|
83
|
+
- Security features remain active to prevent unauthorized access
|
84
|
+
|
85
|
+
**Security Note**: Only use `--bind-all` on trusted networks. The server includes built-in security features to validate origins and IP addresses, but exposing any service to your network increases the attack surface.
|
86
|
+
|
63
87
|
### Logging Options
|
64
88
|
|
65
89
|
The server logs to a file in your config directory by default. You can customize logging with these options:
|
@@ -77,12 +101,10 @@ The Neovim MCP Server can be used with Claude Desktop by manually configuring th
|
|
77
101
|
|
78
102
|
1. Create the appropriate config directory for your platform:
|
79
103
|
- macOS: `$XDG_CONFIG_HOME/nvim-mcp` or `~/.config/nvim-mcp` if XDG_CONFIG_HOME is not set
|
80
|
-
- Linux: `$XDG_CONFIG_HOME/nvim-mcp` or `~/.config/nvim-mcp` if XDG_CONFIG_HOME is not set
|
81
104
|
- Windows: `%APPDATA%\nvim-mcp`
|
82
105
|
|
83
106
|
2. Find or create the Claude Desktop configuration file:
|
84
107
|
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
85
|
-
- Linux: `~/.config/Claude/claude_desktop_config.json`
|
86
108
|
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
87
109
|
|
88
110
|
3. Add or update the MCP server configuration:
|
@@ -198,6 +220,30 @@ I'd like to know what files I'm currently working on in the "blog" project.
|
|
198
220
|
List all the buffers for the "nvim-mcp-server" project.
|
199
221
|
```
|
200
222
|
|
223
|
+
### 2. `update_buffer`
|
224
|
+
|
225
|
+
**Description:** Updates a buffer with new content provided by the MCP client, saves it to disk, and reloads it. This tool connects to a running Neovim instance, replaces the entire buffer content with the provided content, writes it to disk, and then reloads the buffer. This is useful for applying external changes (like from an AI assistant) to files open in Neovim.
|
226
|
+
|
227
|
+
**Parameters:**
|
228
|
+
|
229
|
+
- `project_name`: (String, required) The name of the project directory. This is used to locate the Neovim socket at /tmp/nvim-{project_name}.sock.
|
230
|
+
- `file_path`: (String, required) The absolute or relative file path of the buffer to update. This should match the path as shown in Neovim's buffer list.
|
231
|
+
- `content`: (String, required) The new content to write to the buffer. This will replace the entire current content of the buffer.
|
232
|
+
|
233
|
+
#### Examples
|
234
|
+
|
235
|
+
```
|
236
|
+
Please update the file "src/main.rb" in my "my-project" Neovim instance with the refactored code.
|
237
|
+
```
|
238
|
+
|
239
|
+
```
|
240
|
+
Replace the content of "/home/user/projects/blog/app/controllers/posts_controller.rb" in the "blog" project with the updated controller code.
|
241
|
+
```
|
242
|
+
|
243
|
+
```
|
244
|
+
Update the README.md file in the "nvim-mcp-server" project with the new documentation.
|
245
|
+
```
|
246
|
+
|
201
247
|
## Testing and Debugging
|
202
248
|
|
203
249
|
The easiest way to test and debug the Neovim MCP Server is by using the MCP Inspector, a developer tool designed specifically for testing and debugging MCP servers.
|
data/exe/nvim-mcp-server
CHANGED
@@ -32,11 +32,13 @@ if ARGV[0] == "--help" || ARGV[0] == "-h"
|
|
32
32
|
puts " --log-level LEVEL Log level: debug, info, warn, error (default: info)"
|
33
33
|
puts " --mode MODE Server mode: http or stdio (default: stdio)"
|
34
34
|
puts " -p, --port PORT Port to listen on (default: 6030)"
|
35
|
+
puts " --bind-all Bind to 0.0.0.0 instead of localhost (HTTP mode only)"
|
35
36
|
puts " version Display version information"
|
36
37
|
puts " --help, -h Display this help message"
|
37
38
|
puts ""
|
38
39
|
puts "Example:"
|
39
40
|
puts " #{File.basename($0)} --log-level debug -p 6060"
|
41
|
+
puts " #{File.basename($0)} --mode http --bind-all"
|
40
42
|
puts " #{File.basename($0)} --mode stdio"
|
41
43
|
exit 0
|
42
44
|
end
|
@@ -44,6 +46,7 @@ end
|
|
44
46
|
# Default values
|
45
47
|
port = 6030
|
46
48
|
mode = "stdio"
|
49
|
+
bind_all = false
|
47
50
|
|
48
51
|
# Parse command-line arguments
|
49
52
|
i = 0
|
@@ -62,6 +65,9 @@ while i < ARGV.length
|
|
62
65
|
exit 1
|
63
66
|
end
|
64
67
|
i += 2
|
68
|
+
when "--bind-all"
|
69
|
+
bind_all = true
|
70
|
+
i += 1
|
65
71
|
else
|
66
72
|
i += 1
|
67
73
|
end
|
@@ -75,15 +81,17 @@ NvimMcpServer.log(:info, "Starting Neovim MCP Server in #{mode} mode...")
|
|
75
81
|
|
76
82
|
# Create tools configuration for both modes
|
77
83
|
def setup_mcp_tools(server)
|
78
|
-
server.register_tools(NvimMcpServer::GetProjectBuffersTool)
|
84
|
+
server.register_tools(NvimMcpServer::GetProjectBuffersTool, NvimMcpServer::UpdateBufferTool)
|
79
85
|
end
|
80
86
|
|
81
87
|
case mode
|
82
88
|
when "http"
|
89
|
+
bind_address = bind_all ? "0.0.0.0" : "localhost"
|
90
|
+
|
83
91
|
puts "Starting Rack application with MCP middleware on http://localhost:#{port}"
|
84
92
|
puts "MCP endpoints:"
|
85
|
-
puts " - http
|
86
|
-
puts " - http
|
93
|
+
puts " - http://#{bind_address}:#{port}/mcp/sse (SSE endpoint)"
|
94
|
+
puts " - http://#{bind_address}:#{port}/mcp/messages (JSON-RPC endpoint)"
|
87
95
|
puts ""
|
88
96
|
puts "Version #{NvimMcpServer::VERSION}"
|
89
97
|
puts ""
|
@@ -95,12 +103,15 @@ when "http"
|
|
95
103
|
mcp_app = FastMcp.rack_middleware(
|
96
104
|
rack_app,
|
97
105
|
name: "nvim-mcp-server", version: NvimMcpServer::VERSION,
|
106
|
+
allowed_origins: bind_all ? ["127.0.0.1", "localhost", /.*\.local$/] : ["127.0.0.1", "localhost"],
|
107
|
+
localhost_only: !bind_all,
|
108
|
+
allowed_ips: bind_all ? ["192.168.0.0/16", "10.0.0.0/8", "172.16.0.0/12"] : ["127.0.0.1", "::1"],
|
98
109
|
logger: NvimMcpServer.logger
|
99
110
|
) { |server| setup_mcp_tools(server) }
|
100
111
|
|
101
112
|
app = Rack::Builder.new { run mcp_app }
|
102
113
|
config = Puma::Configuration.new do |user_config|
|
103
|
-
user_config.bind "tcp
|
114
|
+
user_config.bind "tcp://#{bind_address}:#{port}"
|
104
115
|
user_config.app app
|
105
116
|
end
|
106
117
|
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module NvimMcpServer
|
2
|
+
class UpdateBufferTool < BaseTool
|
3
|
+
tool_name "update_buffer"
|
4
|
+
|
5
|
+
description "Updates a buffer with new content provided by the MCP client, saves it to disk, and reloads it. This tool connects to a running Neovim instance, replaces the entire buffer content with the provided content, writes it to disk, and then reloads the buffer. This is useful for applying external changes (like from an AI assistant) to files open in Neovim."
|
6
|
+
|
7
|
+
arguments do
|
8
|
+
required(:project_name).filled(:string).description("The name of the project directory. This is used to locate the Neovim socket at /tmp/nvim-{project_name}.sock.")
|
9
|
+
required(:file_path).filled(:string).description("The absolute or relative file path of the buffer to update. This should match the path as shown in Neovim's buffer list.")
|
10
|
+
required(:content).filled(:string).description("The new content to write to the buffer. This will replace the entire current content of the buffer.")
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(project_name:, file_path:, content:)
|
14
|
+
socket_path = "/tmp/nvim-#{project_name}.sock"
|
15
|
+
log(:info, "Updating buffer #{file_path} for project #{project_name} using socket #{socket_path}")
|
16
|
+
|
17
|
+
result = {
|
18
|
+
status: "success",
|
19
|
+
project_name: project_name,
|
20
|
+
socket_path: socket_path,
|
21
|
+
file_path: file_path,
|
22
|
+
updated: false,
|
23
|
+
saved: false,
|
24
|
+
reloaded: false
|
25
|
+
}
|
26
|
+
|
27
|
+
begin
|
28
|
+
# Check if socket exists
|
29
|
+
unless File.exist?(socket_path)
|
30
|
+
result[:status] = "error"
|
31
|
+
result[:message] = "Neovim socket not found: #{socket_path}"
|
32
|
+
return result
|
33
|
+
end
|
34
|
+
|
35
|
+
# Connect to Neovim
|
36
|
+
client = Neovim.attach_unix(socket_path)
|
37
|
+
|
38
|
+
# Get all buffers to find the one with the specified file
|
39
|
+
all_buffers = client.list_bufs
|
40
|
+
target_buffer = nil
|
41
|
+
|
42
|
+
all_buffers.each do |buffer|
|
43
|
+
buffer_name = buffer.name
|
44
|
+
|
45
|
+
# Skip unnamed buffers
|
46
|
+
next if buffer_name.nil? || buffer_name.empty?
|
47
|
+
|
48
|
+
# Check if this buffer matches the file path (exact match or ends with the path)
|
49
|
+
if buffer_name == file_path || buffer_name.end_with?(file_path)
|
50
|
+
target_buffer = buffer
|
51
|
+
result[:actual_path] = buffer_name
|
52
|
+
break
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if target_buffer.nil?
|
57
|
+
result[:status] = "error"
|
58
|
+
result[:message] = "Buffer not found for file: #{file_path}"
|
59
|
+
return result
|
60
|
+
end
|
61
|
+
|
62
|
+
# Store original content info
|
63
|
+
original_line_count = target_buffer.line_count
|
64
|
+
result[:original_line_count] = original_line_count
|
65
|
+
|
66
|
+
# Find a window displaying this buffer or use the current window
|
67
|
+
windows = client.list_wins
|
68
|
+
target_window = windows.find { |win| win.buffer.number == target_buffer.number }
|
69
|
+
|
70
|
+
if target_window
|
71
|
+
# If we found a window with this buffer, switch to it
|
72
|
+
client.set_current_win(target_window)
|
73
|
+
else
|
74
|
+
# Otherwise, load the buffer in the current window
|
75
|
+
client.command("buffer #{target_buffer.number}")
|
76
|
+
end
|
77
|
+
|
78
|
+
# Split content into lines
|
79
|
+
new_lines = content.split("\n")
|
80
|
+
result[:new_line_count] = new_lines.length
|
81
|
+
|
82
|
+
# Replace the entire buffer content
|
83
|
+
# First, delete all existing lines
|
84
|
+
target_buffer.lines = new_lines
|
85
|
+
result[:updated] = true
|
86
|
+
|
87
|
+
# Save the buffer to disk
|
88
|
+
client.command("write")
|
89
|
+
result[:saved] = true
|
90
|
+
log(:info, "Saved updated buffer: #{result[:actual_path]}")
|
91
|
+
|
92
|
+
# Reload the buffer to ensure it's in sync
|
93
|
+
client.command("edit")
|
94
|
+
result[:reloaded] = true
|
95
|
+
|
96
|
+
result[:message] = "Successfully updated, saved, and reloaded buffer"
|
97
|
+
|
98
|
+
# Close the connection
|
99
|
+
client.shutdown
|
100
|
+
rescue => e
|
101
|
+
log(:error, "Error updating buffer in Neovim using socket #{socket_path}: #{e.message}")
|
102
|
+
|
103
|
+
# Handle connection and other errors gracefully
|
104
|
+
result[:status] = "error"
|
105
|
+
result[:message] = e.message
|
106
|
+
result[:updated] = false
|
107
|
+
result[:saved] = false
|
108
|
+
result[:reloaded] = false
|
109
|
+
end
|
110
|
+
|
111
|
+
result
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/lib/nvim_mcp_server.rb
CHANGED
@@ -5,6 +5,7 @@ require_relative "nvim-mcp-server/version"
|
|
5
5
|
require_relative "nvim-mcp-server/config"
|
6
6
|
require_relative "nvim-mcp-server/tools/base_tool"
|
7
7
|
require_relative "nvim-mcp-server/tools/get_project_buffers_tool"
|
8
|
+
require_relative "nvim-mcp-server/tools/update_buffer_tool"
|
8
9
|
|
9
10
|
module NvimMcpServer
|
10
11
|
@levels = {debug: Logger::DEBUG, info: Logger::INFO, error: Logger::ERROR}
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nvim-mcp-server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mario Alberto Chávez
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 2025-07-27 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: fast-mcp
|
@@ -112,6 +112,7 @@ files:
|
|
112
112
|
- lib/nvim-mcp-server/config.rb
|
113
113
|
- lib/nvim-mcp-server/tools/base_tool.rb
|
114
114
|
- lib/nvim-mcp-server/tools/get_project_buffers_tool.rb
|
115
|
+
- lib/nvim-mcp-server/tools/update_buffer_tool.rb
|
115
116
|
- lib/nvim-mcp-server/version.rb
|
116
117
|
- lib/nvim_mcp_server.rb
|
117
118
|
- sig/nvim/mcp/server.rbs
|
@@ -137,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
138
|
- !ruby/object:Gem::Version
|
138
139
|
version: '0'
|
139
140
|
requirements: []
|
140
|
-
rubygems_version: 3.6.
|
141
|
+
rubygems_version: 3.6.2
|
141
142
|
specification_version: 4
|
142
143
|
summary: MCP server for Neovim
|
143
144
|
test_files: []
|