
mcphub.nvim
A powerful Neovim plugin for managing MCP (Model Context Protocol) servers
3 years
Works with Finder
7
Github Watches
22
Github Forks
609
Github Stars
MCP Hub
A powerful Neovim plugin that integrates MCP (Model Context Protocol) servers into your workflow. Configure and manage MCP servers through a centralized config file while providing an intuitive UI for browsing, installing and testing tools and resources. Perfect for LLM integration, offering both programmatic API access and interactive testing capabilities through the :MCPHub
command.
Discord: Join our Discord server for discussions, help, and updates
graph TD
subgraph "MCP Servers"
subgraph "Native MCP Servers"
N1["Buffer (Tools)"]
N2["LSP (Resources)"]
end
subgraph "Community"
C1["GitHub (Tools )"]
C2["Figma (Tools)"]
end
end
H[MCPHub]
M["@mcp tool + MCP Servers in text representation"]
subgraph "Chat Plugins"
A["Avante + @mcp tool"]
CC["CodeCompanion + @mcp tool"]
O[Others + @mcp tool]
end
subgraph "LLM Providers"
OAI[OpenAI]
AC[Claude]
M1[Mistral]
G[Grok]
D[DeepSeek]
end
%% MCP Servers provide capabilities
N1 & N2 --> H
C1 & C2 --> H
%% MCPHub transforms capabilities into system prompt
H --> M
%% Tools to plugins
M --> A
M --> CC
M --> O
%% Plugin to LLM connections
A --> OAI & AC
CC --> M1 & G
O --> D
MCP Hub UI
For detailed documentation, visit our Wiki:
:raised_hands: Support MCPHub
MCPHub is an open source project that relies on your support. If you like this project, please consider supporting to help maintain and improve the project by Sponsoring or :coffee: Buying A Coffee
:purple_heart: Sponsors
Thank you to the following amazing people:
✨ Features
Simple Command Interface
- Single command
:MCPHub
to access all functionality
Integrated Hub View
- Dynamically enable/disable servers and tools to optimize token usage
- Start/stop servers with persistent state
- Enable/disable specific tools per server
- Configure custom instructions per server
- State persists across restarts
Native MCP Server Support
- Create Lua-based MCP servers directly in Neovim (detailed guide)
- Automatically create lua native MCP servers using LLMs with built-in templates
- Write once, use everywhere design
- Clean chained API for tools, resources, and prompts
- Full URI-based resource system with templates
- Chat-style prompts with role management
- Centralized lifecycle management
Built-in MCP Servers
- Neovim Server: Pre-configured with essential development tools
- File operations (read, write, search, replace)
- Command execution and terminal integration
- LSP integration with diagnostics
- Buffer and environment access
- Interactive chat prompts
- Can be disabled if not needed
Chat Plugin Integration
- Deep integration with popular Neovim chat plugins:
- Avante.nvim: Full MCP tool support with auto-approval option
- CodeCompanion.nvim: MCP resources as chat variables and slash commands for prompts
- Real-time variable updates when servers change
- Automatic resource syncing and prompt registration
- Example: MCP resources as chat variables, prompts as slash_commands
Marketplace Integration
- Browse available MCP servers with details and stats
- Sort, filter by category, and search servers
- View server documentation and installation guides
- One-click installation via Avante/CodeCompanion
Interactive Testing
- Real-time tool testing interface
- Resource browsing and access
- Built-in documentation and help
Performance and Reliability
- Full multi-instance support with synchronized state
- Configuration file watching with real-time updates
- Smart shutdown handling (configurable delay)
- Parallel startup for improved performance
- Automatic server lifecycle management
Developer-friendly
- Both sync and async operations supported
- Clean client registration/cleanup
- Comprehensive API for tool and resource access
📦 Installation
Using lazy.nvim:
{
"ravitemer/mcphub.nvim",
dependencies = {
"nvim-lua/plenary.nvim", -- Required for Job and HTTP requests
},
-- comment the following line to ensure hub will be ready at the earliest
cmd = "MCPHub", -- lazy load by default
build = "npm install -g mcp-hub@latest", -- Installs required mcp-hub npm module
-- uncomment this if you don't want mcp-hub to be available globally or can't use -g
-- build = "bundled_build.lua", -- Use this and set use_bundled_binary = true in opts (see Advanced configuration)
config = function()
require("mcphub").setup()
end,
}
Advanced Configuration
Default Config
All options are optional with sensible defaults. Here's a complete example with all available options:
require("mcphub").setup({
port = 37373, -- Default port for MCP Hub
config = vim.fn.expand("~/.config/mcphub/servers.json"), -- Absolute path to config file location (will create if not exists)
native_servers = {}, -- add your native servers here
auto_approve = false, -- Auto approve mcp tool calls
-- Extensions configuration
extensions = {
avante = {
make_slash_commands = true, -- make /slash commands from MCP server prompts
},
codecompanion = {
-- Show the mcp tool result in the chat buffer
-- NOTE:if the result is markdown with headers, content after the headers wont be sent by codecompanion
show_result_in_chat = false,
make_vars = true, -- make chat #variables from MCP server resources
make_slash_commands = true, -- make /slash commands from MCP server prompts
},
},
-- Default window settings
ui = {
window = {
width = 0.8, -- 0-1 (ratio); "50%" (percentage); 50 (raw number)
height = 0.8, -- 0-1 (ratio); "50%" (percentage); 50 (raw number)
relative = "editor",
zindex = 50,
border = "rounded", -- "none", "single", "double", "rounded", "solid", "shadow"
},
wo = { -- window-scoped options (vim.wo)
},
},
-- Event callbacks
on_ready = function(hub)
-- Called when hub is ready
end,
on_error = function(err)
-- Called on errors
end,
--set this to true when using build = "bundled_build.lua"
use_bundled_binary = false, -- Uses bundled mcp-hub script instead of global installation
--WARN: Use the custom setup if you can't use `npm install -g mcp-hub` or cant have `build = "bundled_build.lua"`
-- Custom Server command configuration
--cmd = "node", -- The command to invoke the MCP Hub Server
--cmdArgs = {"/path/to/node_modules/mcp-hub/dist/cli.js"}, -- Additional arguments for the command
-- In cases where mcp-hub server is hosted somewhere, set this to the server URL e.g `http://mydomain.com:customport` or `https://url_without_need_for_port.com`
-- server_url = nil, -- defaults to `http://localhost:port`
-- Multi-instance Support
shutdown_delay = 600000, -- Delay in ms before shutting down the server when last instance closes (default: 10 minutes)
-- Logging configuration
log = {
level = vim.log.levels.WARN,
to_file = false,
file_path = nil,
prefix = "MCPHub",
},
})
~/.config/mcphub/servers.json
MCPHub uses a JSON configuration file to define MCP servers. The default location is ~/.config/mcphub/servers.json
.
Example Configuration
{
"mcpServers": {
"fetch": {
"command": "uvx",
"args": ["mcp-server-fetch"],
"env": {
"API_KEY": "", // Falls back to process.env.API_KEY
"SERVER_URL": null, // Falls back to process.env.SERVER_URL
"DEBUG": "true" // Direct value, no fallback
}
},
"remote-server": {
"url": "https://api.example.com/mcp",
"headers": {
"Authorization": "Bearer your-token"
}
}
}
}
Configuration file (~/.config/mcphub/servers.json
) is watched for changes and updates are applied automatically in real-time across all Neovim instances.
MCP Servers Config
mcphub.nvim
supports both stdio
(local) MCP Servers as well as sse
(remote) MCP Servers. The configuration for each type is as follows:
-
Local Stdio Servers:
-
command
: The command to start the MCP server (required) -
args
: Command arguments as array -
env
: Optional environment variables. Special values:-
""
(empty string): Falls back to process.env.[VAR_NAME] -
null
: Falls back to process.env.[VAR_NAME] - Any other value is used as-is
-
-
-
Remote SSE Servers:
-
url
: url for remote MCP Server (required) -
headers
: Optional headers for the server
-
-
There are other plugin specific options for each server like
disabled
,disabled_tools
,custom_instructions
etc which can be easily updated from the UI.
🚀 Usage
Open the MCPHub UI to manage servers, test tools and monitor status:
:MCPHub
Use hub instance api in your code
local hub = mcphub.get_hub_instance()
-- Call a tool (sync)
local response, err = hub:call_tool("server-name", "tool-name", {
param1 = "value1"
}, {
return_text = true -- Parse response to LLM-suitable text
})
-- Call a tool (async)
hub:call_tool("server-name", "tool-name", {
param1 = "value1"
}, {
return_text = true,
callback = function(response, err)
-- Use response
end
})
-- Access resource (sync)
local response, err = hub:access_resource("server-name", "resource://uri", {
return_text = true
})
-- Get prompt helpers for system prompts
local prompts = hub:generate_prompts()
-- prompts.active_servers: Lists currently active servers
-- prompts.use_mcp_tool: Instructions for tool usage with example
-- prompts.access_mcp_resource: Instructions for resource access with example
🔌 Extensions
MCPHub.nvim provides extensions that integrate with popular Neovim chat plugins. These extensions allow you to use MCP tools and resources directly within your chat interfaces.
Avante.nvim
Add MCP capabilities to Avante by including the MCP tools in your setup:
Set
config.auto_approve = true
orvim.g.mcphub_auto_approve = true
to automatically approve mcp tool requests.
Set
config.extensions.avante.make_slash_commands = true
to enable prompts as slash commands (enabled by default). Server prompts will be available as/mcp:server_name:prompt_name
in chat.
The mcp_tool()
function now returns two separate tools (use_mcp_tool
and access_mcp_resource
) for better schema generation:
extensions = {
avante = {
make_slash_commands = true, -- make /slash commands from MCP server prompts
}
}
require("avante").setup({
-- other config
-- The system_prompt type supports both a string and a function that returns a string. Using a function here allows dynamically updating the prompt with mcphub
system_prompt = function()
local hub = require("mcphub").get_hub_instance()
return hub:get_active_servers_prompt()
end,
-- The custom_tools type supports both a list and a function that returns a list. Using a function here prevents requiring mcphub before it's loaded
custom_tools = function()
return {
require("mcphub.extensions.avante").mcp_tool(),
}
end,
})
⚠️ Tool Conflicts: Disable any built-in Avante tools that might conflict with enabled MCP servers to prevent duplicate functionality or unexpected behavior.
If you are using the builtin Neovim server, you might have to disable the following tools in your avante config to avoid any conflicts.
disabled_tools = {
"list_files",
"search_files",
"read_file",
"create_file",
"rename_file",
"delete_file",
"create_dir",
"rename_dir",
"delete_dir",
"bash",
},
Codecompanion
Add MCP capabilities to CodeCompanion.
Set
config.auto_approve = true
orvim.g.mcphub_auto_approve = true
to automatically approve tool requests.
Set
make_vars = true
to show resources as #variables in the chat buffer
Set
make_slash_commands = true
to show prompts as /slash_commands in the chat buffer
- Type @mcp in the chat (once submitted, it will add available MCP Servers to the system prompts and adds a tool so that the LLM can call tools, resources on MCP Servers etc)
- Server prompts become available as
/mcp:prompt_name
slash commands in chat (Currently very few servers provide prompts, but you can add your own usingmcphub.add_prompt
) - Prompts with arguments are handled using vim.ui.input (cancelling input for required arguments will abort the slash command)
- If the last message from the
/mcp:prompt_name
message is ofuser
role, it will be added to the chat buffer.
-
Whenever the servers are updated, the variables and slash_commands will also be updated in realtime
-
E.g LSP current file diagnostics
Set
show_result_in_chat = true
to view the mcp tool call result in the chat buffer.
extensions = {
codecompanion = {
-- Show the mcp tool result in the chat buffer
show_result_in_chat = true,
make_vars = true, -- make chat #variables from MCP server resources
make_slash_commands = true, -- make /slash_commands from MCP server prompts
},
}
require("codecompanion").setup({
strategies = {
chat = {
tools = {
["mcp"] = {
-- calling it in a function would prevent mcphub from being loaded before it's needed
callback = function() return require("mcphub.extensions.codecompanion") end,
description = "Call tools and resources from the MCP Servers",
}
}
}
}
})
Lualine
require('lualine').setup {
sections = {
lualine_x = {
{require('mcphub.extensions.lualine')},
},
},
}
When connecting show warning state.
When idle shows total number of connected servers.
When a tool or resources is being called, shows spinner.
🎉Lua Native MCP Servers (detailed guide)
Why Use Native MCP Servers?
The Challenge
Many Neovim chat plugins like Avante and CodeCompanion already provide ways to add custom tools:
-- Avante's custom tools
require("avante").setup({
custom_tools = {
get_weather = {
name,
description,
param,
returns,
func
}
}
})
-- CodeCompanion's tools
require("codecompanion").setup({
chat = {
tools = {
get_weather = {
name,
description,
cmds,
schema,
output,
}
}
}
})
This leads to several limitations:
Feature | Regular tools | MCPHub Native Servers |
---|---|---|
Implementation | Needs reimplementing for each plugin | Write once, works everywhere |
Api | Needs plugin specific docs | Intuitive chained api res:text():image():send() |
Instructions | Can't have long schema.description |
Tools,Resources converted to system prompt, instructions in one place |
Resources Support | No built-in resource handling | Full URI-based resource system |
Response Types | No standard types | MCP standard types (text, images, blobs) |
State Management | Per-plugin implementation | Centralized lifecycle management |
Plugin Updates | May break tool implementations | Tools isolated from plugin changes |
MCPHub Solution
MCPHub solves these problems by providing a standardized protocol (MCP) and a central hub for tools and resources:
MCPHub Native MCP Server
Option 1 (Static): add server schema table upfront in config.native_servers
-- Complete server definition with tool, resource, and template
native_servers = {
weather = {
name = "weather",
capabilities = {
tools = {
{
name = "get_weather",
description = "Get current weather information for a city",
inputSchema = {
type = "object",
properties = {
city = {
type = "string",
description = "City name to get weather for",
}
},
},
handler = function(req, res)
res:text("Weather in " .. req.params.city .. ": ☀️ Sunny, 22°C"):send()
end
}
},
resources = {
{
name = "current",
uri = "weather://current/london",
description = "Get current weather data for London",
handler = function(req, res)
res:text("London: ☀️ Sunny, 22°C, Humidity: 65%"):send()
end
}
},
resourceTemplates = {
{
name = "city_weather",
uriTemplate = "weather://forecast/{city}",
description = "Get weather forecast for any city",
handler = function(req, res)
res:text(req.params.city .. " 5-day forecast:\n" ..
"Mon: ☀️ 22°C\n" ..
"Tue: ⛅ 20°C\n" ..
"Wed: 🌧️ 18°C"):send()
end
}
},
prompts = {
name = "weather_chat",
description = "Chat about weather in any city",
arguments = {
{
name = "city",
description = "City to check weather for"
}
},
handler = function(req, res)
return res
:user()
:text(string.format("What's the weather like in %s?", req.params.city))
:llm()
:text(string.format("Let me check the weather in %s for you...", req.params.city)):text(string.format("The weather in %s is ☀️ 22°C. Perfect day for outdoor activities!", req.params.city))
res:send()
end
}
}
}
}
Option 2 (Dynamic) : Usemcphub.add_*
api to build incrementally
local mcphub = require("mcphub")
-- Start by adding a tool. It iwll create the server if it is not already present.
mcphub.add_tool("weather", {
--tool def
})
-- Add a static resource for London weather
mcphub.add_resource("weather", {
--resource def
})
-- Add a template for any city
mcphub.add_resource_template("weather", {
--resource template def
})
-- Add a prompt
mcphub.add_prompt({
--prompt def
})
Preview:
Please read Native README.md (beta) for more information.
MCPHub acts as a central hub that:
- Collects Tools, Resources, Prompts: Gathers capabilities from both native and community servers
-
Standardizes Access: Provides a single interface via
@mcp
tool - Manages State: Handles server lifecycles and capability registration
- Formats Prompts: Transforms complex tool definitions into LLM-friendly formats
Key Benefits
-
Write Once, Use Everywhere
- Implement tools once as native servers
- Works with any chat plugin that supports MCPHub
- Chat plugins focus on their unique features
-
No Limitations
All tools, resources, and templates from the server above are converted into a clean, LLM-friendly system prompt:
## weather
### Available Tools
- get_weather: Get current weather information for a city
Input Schema:
{
type: "object",
properties: {
city: {
type: "string",
description: "City name to get weather for",
examples: ["London", "Tokyo"]
}
}
}
### Available Resources
- weather://current/london: Get current weather data for London
### Resource Templates
- weather://forecast/{city}: Get weather forecast for any city
-
Rich Resource Capabilities
- Static resources with URIs (like weather://current/london)
- Dynamic resource templates (like weather://forecast/{city})
- Resource embedding in tool responses
- Consistent URI patterns across servers
-
Separation of Concerns
- Tool providers focus on implementations
- Chat plugins focus on LLM integration
- MCPHub handles communication and standardization
-
Easy Integration
- Chat plugins need only implement MCPHub support
- Get access to all MCP servers automatically
- Standardized tool and resource interfaces
-
Community Ecosystem
- Share implementations across plugins
- Reduce duplication of effort
- Common platform for tool development
🔨 Troubleshooting
-
Environment Requirements
- Ensure these are installed as they're required by most MCP servers:
node --version # Should be >= 18.0.0 python --version # Should be installed uvx --version # Should be installed
- Most server commands use
npx
oruvx
- verify these work in your terminal
- Ensure these are installed as they're required by most MCP servers:
-
LLM Model Issues
If the LLM isn't making correct tool calls:
- Schema Support
- Models with function calling support (like claude-3.5) work best with Avante's schema format
- Only top-tier models handle XML-based tool formats correctly
- Consider upgrading to a better model if seeing incorrect tool usage
- Common Tool Call Issues
- Missing
action
field - Incorrect
server_name
- Missing
tool_name
oruri
- Malformed arguments
- Recommended Models
- GPT-4o
- Claude 3.5 Sonnet
- Claude 3.7
- Gemini 2.0 Flash
- Gemini 2.0 Pro
- Mistral Large
-
Port Issues
- If you get
EADDRINUSE
error, kill the existing process:lsof -i :[port] # Find process ID kill [pid] # Kill the process
- If you get
-
Configuration File
- Ensure config path is absolute
- Verify file contains valid JSON with
mcpServers
key - Check server-specific configuration requirements
- Validate server command and args are correct for your system
-
MCP Server Issues
- Validate server configurations using either:
- MCP Inspector: GUI tool for verifying server operation
- mcp-cli: Command-line tool for testing servers with config files
- Check server logs in MCPHub UI (Logs view)
- Test tools and resources individually to isolate issues
- Validate server configurations using either:
-
Need Help?
- First try testing it with minimal.lua
- Feel free to open an Issue for bugs or doubts
- Create a Discussion for questions, showcase, or feature requests
🔄 How It Works
MCPHub.nvim uses an Express server to manage MCP servers and handle client requests:
-
When
setup()
is called:- Checks for mcp-hub command installation
- Verifies version compatibility
- Checks if server is already running (multi-instance support)
- If not running, starts mcp-hub with config file watching enabled
- Creates Express server at
http://localhost:[config.port]
or atconfig.server_url
-
After successful setup:
- Calls on_ready callback with hub instance
- Hub instance provides REST API interface
- Real-time UI updates via
:MCPHub
command - Configuration changes auto-sync across instances
-
Express Server Features:
- Real-time config file watching and syncing
- Manages MCP server configurations
- Handles tool execution requests
- Provides resource access
- Multi-instance support with shared state
- Automatic cleanup
-
When Neovim instances close:
- Unregister as clients
- Last client triggers shutdown timer
- Timer cancels if new client connects
This architecture ensures:
- Consistent server management
- Real-time status monitoring
- Efficient resource usage
- Clean process handling
- Multiple client support
Architecture Flows
Server Lifecycle
sequenceDiagram
participant N1 as First Neovim
participant N2 as Other Neovims
participant S as MCP Hub Server
Note over N1,S: First Client Connection
N1->>S: Check if Running
activate S
S-->>N1: Not Running
N1->>S: start_hub()
Note over S: Server Start
S-->>N1: Ready Signal
N1->>S: Register Client
S-->>N1: Registration OK
Note over N2,S: Other Clients
N2->>S: Check if Running
S-->>N2: Running
N2->>S: Register Client
S-->>N2: Registration OK
Note over N1,S: Server stays active
Note over N2,S: Client Disconnection
N2->>S: Unregister Client
S-->>N2: OK
Note over S: Keep Running
Note over N1,S: Last Client Exit
N1->>S: Unregister Client
S-->>N1: OK
Note over S: Grace Period
Note over S: Auto Shutdown
deactivate S
Request flow
sequenceDiagram
participant N as Neovim
participant P as Plugin
participant S as MCP Hub Server
N->>P: start_hub()
P->>S: Health Check
alt Server Not Running
P->>S: Start Server
S-->>P: Ready Signal
end
P->>S: Register Client
S-->>P: Registration OK
N->>P: :MCPHub
P->>S: Get Status
S-->>P: Server Status
P->>N: Display UI
Cleanup flow
flowchart LR
A[VimLeavePre] -->|Trigger| B[Stop Hub]
B -->|If Ready| C[Unregister Client]
C -->|Last Client| D[Server Auto-shutdown]
C -->|Other Clients| E[Server Continues]
B --> F[Clear State]
F --> G[Ready = false]
F --> H[Owner = false]
API Flow
sequenceDiagram
participant C as Chat Plugin
participant H as Hub Instance
participant S as MCP Server
C->>H: call_tool()
H->>H: Check Ready
alt Not Ready
H-->>C: Error: Not Ready
end
H->>S: POST /tools
S-->>H: Tool Result
H-->>C: Return Result
Note over C,S: Similar flow for resources
C->>H: access_resource()
H->>H: Check Ready
H->>S: POST /resources
S-->>H: Resource Data
H-->>C: Return Data
Requirements
- Neovim >= 0.8.0
- Node.js >= 18.0.0
- plenary.nvim
- mcp-hub (automatically installed via build command)
🚧 TODO
- Neovim MCP Server (kind of) with better editing, diffs, terminal integration etc (Ideas are welcome)
- Enhanced help view with comprehensive documentation
- MCP Resources as variables in chat plugins
- MCP Prompts as slash commands in chat plugins
- Support for #variables, /slash_commands in avante
- Support SSE transport
- Composio Integration
- Better Docs and Wiki
👏 Acknowledgements
Thanks to:
- cline/mcp-marketplace for providing the marketplace api
- nui.nvim for inspiring our text highlighting utilities
📚 Documentation
For detailed documentation, visit our Wiki:
相关推荐
Confidential guide on numerology and astrology, based of GG33 Public information
Embark on a thrilling diplomatic quest across a galaxy on the brink of war. Navigate complex politics and alien cultures to forge peace and avert catastrophe in this immersive interstellar adventure.
Converts Figma frames into front-end code for various mobile frameworks.
Advanced software engineer GPT that excels through nailing the basics.
Delivers concise Python code and interprets non-English comments
MCP server to provide Figma layout information to AI coding agents like Cursor
Python code to use the MCP3008 analog to digital converter with a Raspberry Pi or BeagleBone black.
Put an end to hallucinations! GitMCP is a free, open-source, remote MCP server for any GitHub project
The all-in-one Desktop & Docker AI application with built-in RAG, AI agents, No-code agent builder, MCP compatibility, and more.
Reviews

user_BnwdyZPz
I've been using mcphub.nvim by ravitemer for a while now, and it has significantly improved my workflow in Neovim. The plugin is incredibly versatile and easy to use, providing seamless integration with multiple functionalities. The documentation is straightforward, making setup a breeze. Highly recommended for anyone looking to boost their Neovim experience! Check it out here: https://github.com/ravitemer/mcphub.nvim.