### Nixvim Plugin Setup Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/installation.md Example configuration for integrating mcphub.nvim with Nixvim, including plugin installation and basic setup. ```nix { mcphub-nvim, ... }: { extraPlugins = [mcphub-nvim]; extraConfigLua = '' require("mcphub").setup() ''; } ``` -------------------------------- ### Register Server via Setup Configuration Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcp/native/registration.md Use the `setup` function to register a complete server definition, including its name, display name, and capabilities. This is suitable for initial server setup. ```lua require("mcphub").setup({ native_servers = { -- Define your server example = { -- Required: Server name name = "example", -- Optional: Display name displayName = "Example Server", -- Required: Server capabilities capabilities = { tools = { ... }, resources = { ... }, resourceTemplates = { ... }, prompts = { ... } } } } }) ``` -------------------------------- ### Configuration-Based Setup Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcp/native/registration.md Register a complete server definition using the `setup` function within the MCPHub configuration. ```APIDOC ## Configuration-Based (Setup) Register your complete server through MCPHub's setup: ```lua require("mcphub").setup({ native_servers = { -- Define your server example = { -- Required: Server name name = "example", -- Optional: Display name displayName = "Example Server", -- Required: Server capabilities capabilities = { tools = { ... }, resources = { ... }, resourceTemplates = { ... }, prompts = { ... } } } } }) ``` ``` -------------------------------- ### Dev Installation with Lazy.nvim Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/installation.md Configures the plugin to use a locally cloned mcp-hub repository for development purposes. Specify the command and arguments to start the mcp-hub server. ```lua { "ravitemer/mcphub.nvim", dependencies = { "nvim-lua/plenary.nvim", }, config = function() require("mcphub").setup({ cmd = "node", cmdArgs = {"/path/to/mcp-hub/src/utils/cli.js"}, }) end, } ``` -------------------------------- ### Install mcphub.nvim with lazy.nvim (Global) Source: https://github.com/ravitemer/mcphub.nvim/wiki/Installation Use this configuration with lazy.nvim to install mcphub.nvim and globally install the mcp-hub Node.js package. It includes detailed setup options for server configuration, extensions, UI, and logging. ```lua { "ravitemer/mcphub.nvim", dependencies = { "nvim-lua/plenary.nvim", }, cmd = "MCPHub", -- lazy load by default build = "npm install -g mcp-hub@latest", -- Installs globally config = function() require("mcphub").setup({ -- Server configuration port = 37373, -- Port for MCP Hub Express API config = vim.fn.expand("~/.config/mcphub/servers.json"), -- Config file path native_servers = {}, -- add your native servers here -- Extension configurations auto_approve = false, extensions = { avante = { }, codecompanion = { show_result_in_chat = true, -- Show tool results in chat make_vars = true, -- Create chat variables from resources make_slash_commands = true, -- make /slash_commands from MCP server prompts }, }, -- UI configuration ui = { window = { width = 0.8, -- Window width (0-1 ratio) height = 0.8, -- Window height (0-1 ratio) border = "rounded", -- Window border style relative = "editor", -- Window positioning zindex = 50, -- Window stack order }, }, -- Event callbacks on_ready = function(hub) end, -- Called when hub is ready on_error = function(err) end, -- Called on errors -- Logging configuration log = { level = vim.log.levels.WARN, -- Minimum log level to_file = false, -- Enable file logging file_path = nil, -- Custom log file path prefix = "MCPHub" -- Log message prefix } }) end, } ``` -------------------------------- ### Install mcphub.nvim with Bundled Binary Source: https://github.com/ravitemer/mcphub.nvim/wiki/Installation Use this method when global npm installation is not possible. The bundled binary is updated automatically with the plugin. ```lua { "ravitemer/mcphub.nvim", dependencies = { "nvim-lua/plenary.nvim", }, cmd = "MCPHub", build = "bundled_build.lua", -- Bundles mcp-hub locally config = function() require("mcphub").setup({ use_bundled_binary = true, -- Use local binary -- ... rest of config as shown above }) end, } ``` -------------------------------- ### Avante Custom Tools Setup Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcp/native/index.md Example of setting up custom tools for the Avante chat plugin. This demonstrates how to define a tool with its name, description, schema, and function handler. ```lua -- Avante custom tools require("avante").setup({ custom_tools = { get_weather = { name = "get_weather", description = "Get weather info", schema = { ... }, func = function() end } } }) ``` -------------------------------- ### Default Installation with Lazy.nvim Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/installation.md Installs the mcp-hub node binary globally using npm. This is the recommended method for most users. ```lua { "ravitemer/mcphub.nvim", dependencies = { "nvim-lua/plenary.nvim", }, build = "npm install -g mcp-hub@latest", -- Installs `mcp-hub` node binary globally config = function() require("mcphub").setup() end } ``` -------------------------------- ### Configure blink.cmp for Avante Integration Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/extensions/avante.md Example configuration for blink.cmp to integrate with Avante. This setup ensures that Avante-related completions are available through blink.cmp. ```lua return { "saghen/blink.cmp", dependencies = { "Kaiser-Yang/blink-cmp-avante", }, ---@module 'blink.cmp' ---@type blink.cmp.Config opts = { sources = { default = { "lsp", "avante", "path", "snippets", "buffer" }, providers = { avante = { module = "blink-cmp-avante", name = "Avante", opts = { -- options for blink-cmp-avante }, }, }, }, } } ``` -------------------------------- ### JSON5 Configuration Example Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Example of a JSON5 configuration file demonstrating comments and trailing commas, which can be parsed by MCPHub when configured with lua-json5. ```json5 { // This is a comment "servers": { "github": { "url": "https://api.githubcopilot.com/mcp/", }, // Trailing comma is fine }, } ``` -------------------------------- ### Register Native Server via Setup Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Registers a complete native server definition using MCPHub's setup function. This method is suitable for defining servers during the initial configuration. ```lua require("mcphub").setup({ native_servers = { -- Define your server example = { -- Required: Server name name = "example", -- Optional: Display name displayName = "Example Server", -- Required: Server capabilities capabilities = { tools = { ... }, resources = { ... }, resourceTemplates = { ... }, prompts = { ... } } } } }) ``` -------------------------------- ### Add Basic Chat Prompt Example Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt An example of adding a simple chat prompt named 'example'. It includes a required 'topic' argument and demonstrates setting system and user messages. ```lua mcphub.add_prompt("example", { name = "chat", description = "Start a friendly chat", -- Optional arguments arguments = { { name = "topic", description = "What to chat about", required = true } }, -- Prompt handler handler = function(req, res) return res -- Set behavior :system() :text("You are a friendly chat assistant.\n" .. "Topic: " .. req.params.topic) -- Add example interaction :user() :text("Tell me about " .. req.params.topic) :llm() :text("I'd love to discuss " .. req.params.topic) -- Send prompt :send() end }) ``` -------------------------------- ### Local Installation with Lazy.nvim Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/installation.md Bundles the mcp-hub binary with the neovim plugin for environments where global installations are not feasible. Requires setting `use_bundled_binary` to true. ```lua { "ravitemer/mcphub.nvim", dependencies = { "nvim-lua/plenary.nvim", }, build = "bundled_build.lua", -- Bundles `mcp-hub` binary along with the neovim plugin config = function() require("mcphub").setup({ use_bundled_binary = true, -- Use local `mcp-hub` binary }) end, } ``` -------------------------------- ### CodeCompanion Tools Setup Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcp/native/index.md Example of configuring custom tools for the CodeCompanion chat plugin. It shows the structure for defining a tool, including its name, description, schema, and handler function. ```lua -- CodeCompanion tools require("codecompanion").setup({ chat = { tools = { get_weather = { name = "get_weather", description = "Get weather info", schema = { ... }, handler = function() end } } } }) ``` -------------------------------- ### Setup Events Source: https://github.com/ravitemer/mcphub.nvim/wiki/API-Reference Sets up event handlers for MCPHub, including `on_ready` when the hub is ready and `on_error` for handling errors. ```APIDOC ## Setup Events ### Description Sets up event handlers for MCPHub, including `on_ready` when the hub is ready and `on_error` for handling errors. ### Method ```lua require("mcphub").setup({ on_ready = function(hub) -- Called when hub is ready end, on_error = function(err) -- Called on errors end }) ``` ``` -------------------------------- ### Setup Global Environment for Input Variables Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Configure global environment variables in MCPHub's setup function using Lua. This makes input variables available to all servers. ```lua require("mcphub").setup({ global_env = { ["input:perplexity-key"] = "my-awesome-project", }, -- other config... }) ``` -------------------------------- ### Register Server via Setup Configuration Source: https://github.com/ravitemer/mcphub.nvim/blob/main/lua/mcphub/native/README.md Register a native server by including its definition within the mcphub.setup configuration. This method is suitable for defining all server components at once. ```lua require("mcphub").setup({ native_servers = { weather = { name = "weather", displayName = "Weather Server", capabilities = { tools = { { name = "get_weather", description = "Get current weather for a city", inputSchema = { type = "object", properties = { city = { type = "string", description = "City name", }, }, }, handler = function(req, res) return res:text("Weather in " .. req.params.city .. ": ☀️ 22°C"):send() end, }, }, resources = { { name = "london_weather", uri = "weather://current/london", description = "Current London weather", handler = function(req, res) return res:text("London: ☀️ 22°C"):send() end, }, }, resourceTemplates = { { name = "city_weather", uriTemplate = "weather://current/{city}", description = "Get weather for any city", handler = function(req, res) return res:text(req.params.city .. ": ⛅ 20°C"):send() end, }, }, }, }, }, }) ``` -------------------------------- ### Configure mcphub.nvim with Custom Server Command Source: https://github.com/ravitemer/mcphub.nvim/wiki/Installation Use this setup for custom mcp-hub locations or during development. Manual updates for mcp-hub are required with this method. ```lua require("mcphub").setup({ cmd = "node", cmdArgs = {"/path/to/node_modules/mcp-hub/dist/cli.js"}, -- ... rest of config as shown above }) ``` -------------------------------- ### Add a Code Review Prompt with Rich Content Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Define a 'review_code' prompt that includes rich content like images and resources. This example shows how to get the active buffer, generate a code overview image, and attach diagnostics as a resource. Error handling for no active buffer is included. ```lua mcphub.add_prompt("editor", { name = "review_code", arguments = { { name = "style", description = "Review style", enum = { "brief", "detailed" } } }, handler = function(req, res) -- Get current buffer local buf = req.editor_info.last_active if not buf then return res:error("No active buffer") end -- Generate code overview local overview = generate_overview(buf) return res -- Set review context :system() :text("You are a code reviewer.\n" .. "Style: " .. req.params.style) -- Add code visualization :image(overview, "image/png") :text("Above is a visualization of the code structure.") -- Add relevant resources :resource({ uri = "neovim://diagnostics/current", mimeType = "text/plain" }) :text("Above are the current diagnostics.") -- Send prompt :send() end }) ``` -------------------------------- ### mcphub.add_tool("example", ...) Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Adds a simple 'greet' tool that takes a name as input and returns a greeting. Demonstrates basic tool registration with a static input schema. ```APIDOC ## mcphub.add_tool("example", ...) ### Description Adds a tool named 'greet' that takes a 'name' parameter and returns a personalized greeting. ### Method `mcphub.add_tool` ### Parameters - **tool_name** (string): The name of the tool category (e.g., "example"). - **tool_definition** (table): A table containing the tool's configuration. - **name** (string): The specific name of the tool (e.g., "greet"). - **description** (string): A brief description of the tool's functionality. - **inputSchema** (table): Defines the expected input structure for the tool. - **type** (string): Must be "object". - **properties** (table): Defines the properties of the input object. - **name** (object): - **type** (string): "string". - **description** (string): "Name to greet". - **required** (table): An array of required property names (e.g., ["name"]). - **handler** (function): A function that processes the request and sends a response. - **req** (object): The request object containing parameters. - **res** (object): The response object for sending results. ### Response - **text** (string): A greeting message (e.g., "Hello [name]"). ### Request Example ```lua mcphub.add_tool("example", { name = "greet", description = "Greet a user", inputSchema = { type = "object", properties = { name = { type = "string", description = "Name to greet" } }, required = { "name" } }, handler = function(req, res) return res:text("Hello " .. req.params.name):send() end }) ``` ``` -------------------------------- ### Check Environment Dependencies Source: https://github.com/ravitemer/mcphub.nvim/wiki/Troubleshooting Verify that Node.js, Python, and uvx are installed and meet the minimum version requirements. ```bash node --version # Should be >= 18.0.0 python --version # Should be installed uvx --version # Should be installed ``` -------------------------------- ### Global Server Configuration Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/workspace.md Define global MCP server configurations in the `~/.config/mcphub/servers.json` file. This example sets up a 'memory' server using the 'uvx' command. ```json { "mcpServers": { "memory": { "command": "uvx", "args": ["@modelcontextprotocol/server-memory"] } } } ``` -------------------------------- ### Setup Lualine Component Source: https://github.com/ravitemer/mcphub.nvim/wiki/Lualine Add the MCPHub component to your lualine configuration to display server status. ```lua require('lualine').setup { sections = { lualine_x = { {require('mcphub.extensions.lualine')}, }, }, } ``` -------------------------------- ### Add Basic Greeting Tool Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcp/native/tools.md Example of adding a simple 'greet' tool that takes a name and returns a greeting. Requires the 'name' parameter. ```lua mcphub.add_tool("example", { name = "greet", description = "Greet a user", inputSchema = { type = "object", properties = { name = { type = "string", description = "Name to greet" } }, required = { "name" } }, handler = function(req, res) return res:text("Hello " .. req.params.name):send() end }) ``` -------------------------------- ### Custom Port Assignment Example Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/configuration.md This example demonstrates how to set a custom port assignment logic for workspace hubs. It uses a function to determine the port, allowing for fixed ports for specific projects or falling back to default hash-based generation. ```lua require("mcphub").setup({ workspace = { get_port = function() local project_name = vim.fn.fnamemodify(vim.fn.getcwd(), ":t") if project_name == "critical-project" then return 45000 -- Use fixed port for specific project end return nil -- Use default hash-based port generation end } }) ``` -------------------------------- ### Project-Specific Server Configuration Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/workspace.md Define project-specific MCP server configurations in `.mcphub/servers.json`. This example configures 'filesystem' and 'lsp' servers. ```json { "mcpServers": { "filesystem": { "command": "uvx", "args": ["mcp-server-filesystem", "${CWD}"] }, "lsp": { "command": "mcp-language-server", "args": [ "--workspace", "${CWD}", "--lsp", "lua-language-server", "--", "--stdio" ] } } } ``` -------------------------------- ### Avante Setup with MCPHub System Prompt Source: https://github.com/ravitemer/mcphub.nvim/wiki/Avante Configure Avante to use MCPHub's system prompt, ensuring the LLM has the latest server state. This prompt is re-evaluated for every message. ```lua require("avante").setup({ -- system_prompt as function ensures LLM always has latest MCP server state -- This is evaluated for every message, even in existing chats system_prompt = function() local hub = require("mcphub").get_hub_instance() return hub:get_active_servers_prompt() end, -- Using function prevents requiring mcphub before it's loaded custom_tools = function() return { require("mcphub.extensions.avante").mcp_tool(), } end, }) ``` -------------------------------- ### Setup Events Source: https://github.com/ravitemer/mcphub.nvim/wiki/API-Reference Configure event handlers for MCPHub, specifically for when the hub is ready (`on_ready`) or when an error occurs (`on_error`). This allows for reactive programming based on hub lifecycle events. ```lua require("mcphub").setup({ on_ready = function(hub) -- Called when hub is ready end, on_error = function(err) -- Called on errors end }) ``` -------------------------------- ### Lualine Integration with Static and Dynamic Coloring Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Example demonstrating how to statically color the icon while dynamically coloring the status text in Lualine. ```lua {require('mcphub.extensions.lualine'), icon = { '󰐻', color = {fg = '#eeeeee'}}} ``` -------------------------------- ### Configure blink.cmp for Avante Integration Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Example configuration for blink.cmp to integrate with Avante, enabling Avante as a completion source. Ensure blink-cmp-avante is listed as a dependency. ```lua return { "saghen/blink.cmp", dependencies = { "Kaiser-Yang/blink-cmp-avante", }, ---@module 'blink.cmp' ---@type blink.cmp.Config opts = { sources = { default = { "lsp", "avante", "path", "snippets", "buffer" }, providers = { avante = { module = "blink-cmp-avante", name = "Avante", opts = { -- options for blink-cmp-avante }, }, }, }, } } ``` -------------------------------- ### Error Handling for Prerequisites Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcp/native/best-practices.md Check for necessary prerequisites like installed executables or valid repository states before performing operations. Return specific error messages with relevant context or installation instructions. ```lua mcphub.add_tool("git", { handler = function(req, res) -- Check environment if not vim.fn.executable("git") then return res:error("Git not installed", { install = "https://git-scm.com" }) end -- Check repository if not is_git_repo() then return res:error("Not a git repository", { cwd = vim.fn.getcwd(), action = "Initialize with 'git init'" }) end end }) ``` -------------------------------- ### Install lua-json5 Parser Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Install the lua-json5 parser using a package manager like lazy.nvim to enable JSON5 support for configuration files. ```bash # Using your package manager, e.g., lazy.nvim { "Joakker/lua-json5" } ``` -------------------------------- ### Custom Tools in Avante and CodeCompanion Source: https://github.com/ravitemer/mcphub.nvim/wiki/Native-Servers Illustrates how custom tools are defined in Avante and CodeCompanion, showcasing the differences in their setup structures. ```lua -- Avante's custom tools require("avante").setup({ custom_tools = { get_weather = { name, description, param, returns, func } } }) ``` ```lua -- CodeCompanion's tools require("codecompanion").setup({ chat = { tools = { get_weather = { name, description, cmds, schema, output, } } } }) ``` -------------------------------- ### Setup Lualine Component with Defaults Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/extensions/lualine.md This is a deprecated method that loads MCPHub even with lazy loading enabled. Use the global variables approach instead. ```lua require('lualine').setup { sections = { lualine_x = { {require('mcphub.extensions.lualine')}, -- Uses defaults }, }, } ``` -------------------------------- ### Minimal MCPTool Example Source: https://github.com/ravitemer/mcphub.nvim/blob/main/lua/mcphub/native/README.md Defines a basic tool with a name and a handler function. The handler must accept a ToolRequest and ToolResponse, and can optionally return a table. ```lua ---@class MCPTool ---@field name string Tool name (required) ---@field handler fun(req: ToolRequest, res: ToolResponse): table|nil Tool implementation (required) ---@field description? string Tool description ---@field inputSchema? MCPJsonSchema JSON Schema for arguments -- Example minimal tool: local tool = { name = "greet", handler = function(req, res) return res:text("Hello"):send() end } ``` -------------------------------- ### Add Server Configuration to mcphub Source: https://github.com/ravitemer/mcphub.nvim/blob/main/lua/mcphub/native/NATIVE_SERVER_LLM.md Integrate a pre-defined native server configuration into your mcphub setup. Ensure the server definition is correctly required. ```lua require('mcphub').config({ native_servers = { weather = require('path.to.weather_server') } }) ``` -------------------------------- ### Basic Greeting Tool Example Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt A simple tool that takes a name parameter and returns a greeting. It demonstrates the basic structure of a tool handler using the response builder. ```lua mcphub.add_tool({ name = "greeting", description = "Returns a greeting message", inputSchema = { type = "object", properties = { name = { type = "string", description = "The name to greet" } }, required = {"name"} }, handler = function(req, res) return res:text("Hello, " .. req.params.name .. "!"):send() end }) ``` -------------------------------- ### Universal Placeholder Syntax Examples Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Demonstrates the universal ${} placeholder syntax for resolving environment variables, executing commands, and using VS Code predefined variables. Empty strings and null values in configuration fields fall back to environment variables. ```text Example Becomes Description --------------------------------------------- ---------------------------------- ------------------------------- "API_KEY": "" "API_KEY": "secret" Empty string falls back to process.env.API_KEY "API_KEY": null "API_KEY": "secret" null falls back to process.env.API_KEY "AUTH": "Bearer ${API_KEY}" "AUTH": "Bearer secret" ${} Placeholder values are replaced "AUTH": "Bearer ${env:API_KEY}" "AUTH": "Bearer secret" VS Code style environment variables "PATH": "${workspaceFolder}/bin" "PATH": "/home/user/project/bin" VS Code predefined variables "TOKEN": "${cmd: op read op://vault/token}" "TOKEN": "secret" Commands are executed and output used ``` -------------------------------- ### Minimal MCPResource Example Source: https://github.com/ravitemer/mcphub.nvim/blob/main/lua/mcphub/native/README.md Defines a minimal resource with a URI and a handler function. The handler processes requests and can set the response content. ```lua ---@class MCPResource ---@field uri string Static resource URI (required) ---@field handler fun(req: ResourceRequest, res: ResourceResponse): table|nil Resource implementation (required) ---@field name? string Resource name ---@field description? string Resource description ---@field mimeType? string Resource MIME type -- Example minimal resource: local resource = { uri = "example://greeting", handler = function(req, res) return res:text("Hello"):send() end } ``` -------------------------------- ### Configure MCPHub.nvim with Lua Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Use this Lua code to set up MCPHub.nvim, specifying options for the mcp-hub binary, chat-plugin, and UI. Ensure 'nvim-lua/plenary.nvim' is a dependency and 'mcp-hub' is installed globally via npm. ```lua { "ravitemer/mcphub.nvim", dependencies = { "nvim-lua/plenary.nvim", }, build = "npm install -g mcp-hub@latest", -- Installs `mcp-hub` node binary globally config = function() require("mcphub").setup({ --- `mcp-hub` binary related options------------------- config = vim.fn.expand("~/.config/mcphub/servers.json"), -- Absolute path to MCP Servers config file (will create if not exists) port = 37373, -- The port `mcp-hub` server listens to shutdown_delay = 5 * 60 * 000, -- Delay in ms before shutting down the server when last instance closes (default: 5 minutes) use_bundled_binary = false, -- Use local `mcp-hub` binary (set this to true when using build = "bundled_build.lua") mcp_request_timeout = 60000, --Max time allowed for a MCP tool or resource to execute in milliseconds, set longer for long running tasks global_env = {}, -- Global environment variables available to all MCP servers (can be a table or a function returning a table) workspace = { enabled = true, -- Enable project-local configuration files look_for = { ".mcphub/servers.json", ".vscode/mcp.json", ".cursor/mcp.json" }, -- Files to look for when detecting project boundaries (VS Code format supported) reload_on_dir_changed = true, -- Automatically switch hubs on DirChanged event port_range = { min = 40000, max = 41000 }, -- Port range for generating unique workspace ports get_port = nil, -- Optional function returning custom port number. Called when generating ports to allow custom port assignment logic }, ---Chat-plugin related options----------------- auto_approve = false, -- Auto approve mcp tool calls auto_toggle_mcp_servers = true, -- Let LLMs start and stop MCP servers automatically extensions = { avante = { make_slash_commands = true, -- make /slash commands from MCP server prompts } }, --- Plugin specific options------------------- native_servers = {}, -- add your custom lua native servers here builtin_tools = { edit_file = { parser = { track_issues = true, extract_inline_content = true, }, locator = { fuzzy_threshold = 0.8, enable_fuzzy_matching = true, }, ui = { go_to_origin_on_complete = true, keybindings = { accept = ".", reject = ",", next = "n", prev = "p", accept_all = "ga", reject_all = "gr", }, }, }, }, ui = { window = { width = 0.8, -- 0-1 (ratio); "50%" (percentage); 50 (raw number) height = 0.8, -- 0-1 (ratio); "50%" (percentage); 50 (raw number) align = "center", -- "center", "top-left", "top-right", "bottom-left", "bottom-right", "top", "bottom", "left", "right" relative = "editor", zindex = 50, border = "rounded", -- "none", "single", "double", "rounded", "solid", "shadow" }, wo = { -- window-scoped options (vim.wo) winhl = "Normal:MCPHubNormal,FloatBorder:MCPHubBorder", }, }, json_decode = nil, -- Custom JSON parser function (e.g., require('json5').parse for JSON5 support) on_ready = function(hub) -- Called when hub is ready end, on_error = function(err) -- Called on errors end, log = { level = vim.log.levels.WARN, to_file = false, file_path = nil, prefix = "MCPHub", }, }) end } ``` -------------------------------- ### Minimal MCPResourceTemplate Example Source: https://github.com/ravitemer/mcphub.nvim/blob/main/lua/mcphub/native/README.md Defines a resource template using a URI template with parameters. The handler function receives request parameters and can generate dynamic responses. ```lua ---@class MCPResourceTemplate ---@field uriTemplate string URI template with {params} (required) ---@field handler fun(req: ResourceRequest, res: ResourceResponse): table|nil Template implementation (required) ---@field name? string Template name ---@field description? string Template description ---@field mimeType? string Default MIME type -- Example minimal template: local template = { uriTemplate = "users://{id}", handler = function(req, res) return res:text("User " .. req.params.id):send() end } ``` -------------------------------- ### Get Prompts Source: https://github.com/ravitemer/mcphub.nvim/wiki/API-Reference Retrieves system prompt components, including lists of active servers and instructions for tool usage and resource access. ```APIDOC ## Get Prompts ### Description Get system prompt components. ### Method ```lua local prompts = hub:get_prompts() -- prompts.active_servers: Lists active servers -- prompts.use_mcp_tool: Tool usage instructions -- prompts.access_mcp_resource: Resource access instructions ``` ``` -------------------------------- ### NixOS Flake Installation Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Add mcphub.nvim to your NixOS flake.nix or home-manager configuration. This snippet shows how to include the plugin as an input. ```nix inputs = { mcphub-nvim.url = "github:ravitemer/mcphub.nvim"; ... } ``` -------------------------------- ### MCPHub Server Configuration Example Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcp/servers_json.md This JSON structure shows the default fields automatically added by the MCPHub UI for each server, including disabled tools/resources and custom instructions. ```json { "mcpServers": { "example": { "disabled": false, "disabled_tools": ["expensive-tool"], "disabled_resources": ["resource://large-data"], "disabled_resourceTemplates": ["resource://{type}/{id}"], "autoApprove": ["safe-tool", "read-only-tool"], "custom_instructions": { "disabled": false, "text": "Custom instructions for this server" } } } } ``` -------------------------------- ### Define Native MCP Server with Static Configuration Source: https://github.com/ravitemer/mcphub.nvim/wiki/Creating-Server Use this snippet to define a complete native MCP server, including its name, capabilities, tools, resources, and resource templates, directly within the `setup()` configuration. ```lua require("mcphub").setup({ native_servers = { weather = { name = "weather", capabilities = { tools = { { name = "get_weather", description = "Get current weather information", inputSchema = { type = "object", properties = { city = { type = "string", description = "City name", examples = ["London", "New York"] } } }, handler = function(req, res) local weather_data = { London = { temp = 22, condition = "☀️" }, ["New York"] = { temp = 25, condition = "⛅" } } local city_data = weather_data[req.params.city] if city_data then res:text(string.format( "Weather in %s: %s %d°C", req.params.city, city_data.condition, city_data.temp )):send() else res:error("City not found") end end } }, resources = { { name = "london_weather", uri = "weather://current/london", description = "Current London weather", handler = function(req, res) res:text("London: ☀️ 22°C"):send() end } }, resourceTemplates = { { name = "city_weather", uriTemplate = "weather://current/{city}", description = "Get weather for any city", handler = function(req, res) res:text(req.params.city .. ": ⛅ 20°C"):send() end } }, promtps = { } } } } }) ``` -------------------------------- ### NixOS/Home Manager Plugin Integration Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Integrate mcphub.nvim into your NixOS or Home Manager Neovim configuration. This involves adding the plugin to `nvim.plugins` and including the setup function in Lua code. ```nix inputs.mcphub-nvim.packages."${system}".default ``` -------------------------------- ### Lualine Integration with Dynamic Icon and Static Text Coloring Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Example demonstrating how to dynamically color the icon while statically coloring the status text in Lualine. ```lua {require('mcphub.extensions.lualine'), color = {fg = '#eeeeee'}} ``` -------------------------------- ### Add Prompt: Example Chat Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Defines a simple chat prompt that takes a 'topic' argument and generates a conversational response. ```APIDOC ## Add Prompt: Example Chat ### Description This function registers a prompt named "example" that initiates a friendly chat. It requires a "topic" argument to guide the conversation. ### Method mcphub.add_prompt ### Parameters - `name` (string): The name of the prompt, "example". - `options` (table): - `name` (string): Display name for the prompt, "chat". - `description` (string): A description of the prompt, "Start a friendly chat". - `arguments` (table): A list of arguments the prompt accepts. - `name` (string): The name of the argument, "topic". - `description` (string): Description of the argument. - `required` (boolean): Whether the argument is required (true). - `handler` (function): The function that generates the prompt response. ### Handler Logic The handler function uses the provided "topic" argument to construct a system message and an example user-LLM interaction. It then sends this structured prompt. ### Request Example ```lua mcphub.add_prompt("example", { name = "chat", description = "Start a friendly chat", arguments = { { name = "topic", description = "What to chat about", required = true } }, handler = function(req, res) return res :system() :text("You are a friendly chat assistant.\n" .. "Topic: " .. req.params.topic) :user() :text("Tell me about " .. req.params.topic) :llm() :text("I'd love to discuss " .. req.params.topic) :send() end }) ``` ``` -------------------------------- ### Placeholder Syntax Examples Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcp/servers_json.md Demonstrates the universal `${}` placeholder syntax for resolving environment variables, executing commands, and using VS Code predefined variables. Empty strings and null values fall back to environment variables. ```json "API_KEY": "" ``` ```json "API_KEY": null ``` ```json "AUTH": "Bearer ${API_KEY}" ``` ```json "AUTH": "Bearer ${env:API_KEY}" ``` ```json "PATH": "${workspaceFolder}/bin" ``` ```json "TOKEN": "${cmd: op read op://vault/token}" ``` ```json "HOME": "/home/ubuntu" ``` -------------------------------- ### Tool Response Examples Source: https://github.com/ravitemer/mcphub.nvim/blob/main/lua/mcphub/native/README.md Demonstrates how to use the ToolResponse object to send text, image, resource, or error responses. Always end with send(). ```lua -- Examples: res:text("Hello world") res:image(image_data, "image/png") res:resource({ uri = "example://file.txt", text = "File content", mimeType = "text/plain" }) res:error("Something went wrong") res:send() -- Always end with send() ``` -------------------------------- ### Resource Response Examples Source: https://github.com/ravitemer/mcphub.nvim/blob/main/lua/mcphub/native/README.md Illustrates using the ResourceResponse object for sending text, binary blobs, images, or errors. MIME types have defaults. ```lua -- Examples: res:text("Content", "text/plain") -- mime defaults to text/plain res:blob(binary_data) -- mime defaults to application/octet-stream res:image(image_data, "image/png") -- Helper for image blobs res:error("Resource not found") res:send() -- Always end with send() ``` -------------------------------- ### Configure mcphub.nvim for Local Development Source: https://github.com/ravitemer/mcphub.nvim/blob/main/CONTRIBUTING.md Configure mcphub.nvim to use a local mcp-hub instance. This involves setting the command and arguments to point to your local mcp-hub installation and enabling debug logging. ```lua local mcphub = require("mcphub") -- First clear the log file local file = io.open(vim.fn.expand("~/mcphub.log"), "w") if file then file:write("") file:close() end mcphub.setup({ -- Use local mcp-hub during development cmd = "node", cmdArgs = { "/path/to/mcp-hub/src/utils/cli.js", -- Point to local mcp-hub }, shutdown_delay = 0, -- During development, stop immediately when neovim exits -- Enhanced logging for development log = { to_file = true, file_path = vim.fn.expand("~/mcphub.log"), level = vim.log.levels.DEBUG, }, }) ``` -------------------------------- ### Lualine Setup with MCPHub Status Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/extensions/lualine.md Configure lualine to display MCPHub's status, server count, and execution indicator. This snippet uses global variables provided by MCPHub. ```lua require('lualine').setup { sections = { lualine_x = { { function() -- Check if MCPHub is loaded if not vim.g.loaded_mcphub then return "󰐻 -" end local count = vim.g.mcphub_servers_count or 0 local status = vim.g.mcphub_status or "stopped" local executing = vim.g.mcphub_executing -- Show "-" when stopped if status == "stopped" then return "󰐻 -" end -- Show spinner when executing, starting, or restarting if executing or status == "starting" or status == "restarting" then local frames = { "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" } local frame = math.floor(vim.loop.now() / 100) % #frames + 1 return "󰐻 " .. frames[frame] end return "󰐻 " .. count end, color = function() if not vim.g.loaded_mcphub then return { fg = "#6c7086" } -- Gray for not loaded end local status = vim.g.mcphub_status or "stopped" if status == "ready" or status == "restarted" then return { fg = "#50fa7b" } -- Green for connected elseif status == "starting" or status == "restarting" then return { fg = "#ffb86c" } -- Orange for connecting else return { fg = "#ff5555" } -- Red for error/stopped end end, }, }, }, } ``` -------------------------------- ### Configuring mcp-hub Command and Arguments in Lua Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Use this configuration to specify the command and arguments for starting the mcp-hub server, particularly when using a bundled binary or a custom path. ```lua require("mcphub").setup({ cmd = "node", cmdArgs = {"/path/to/mcp-hub/src/utils/cli.js"}, }) ``` -------------------------------- ### Auto-Approval Configuration Examples Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcp/servers_json.md Illustrates different ways to configure the 'autoApprove' field for tools on a server. This controls whether tools require user confirmation before execution. ```json "autoApprove": true ``` ```json "autoApprove": ["read_file", "list_files"] ``` ```json "autoApprove": [] ``` -------------------------------- ### VS Code MCP Configuration with JSON5 Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcp/servers_json.md A complete example of a VS Code .vscode/mcp.json file using JSON5 syntax. It demonstrates configuring server URLs, headers, and filesystem access with VS Code environment variables. ```json5 { // VS Code MCP configuration with JSON5 support "servers": { "github": { "url": "https://api.githubcopilot.com/mcp/", "headers": { "Authorization": "Bearer ${env:GITHUB_TOKEN}" } }, "filesystem": { "command": "npx", "args": ["-y", "mcp-server-filesystem", "${workspaceFolder}"], "env": { "WORKSPACE_PATH": "${workspaceFolder}", "USER_HOME": "${userHome}" } }, // Trailing comma is supported with JSON5 } } ``` -------------------------------- ### Get Prompt Helpers Source: https://github.com/ravitemer/mcphub.nvim/wiki/API-Reference Retrieve system prompt components, such as lists of active servers, tool usage instructions, and resource access instructions. These are useful for constructing prompts for language models. ```lua local prompts = hub:get_prompts() -- prompts.active_servers: Lists active servers -- prompts.use_mcp_tool: Tool usage instructions -- prompts.access_mcp_resource: Resource access instructions ``` -------------------------------- ### Error Handling for Prerequisites in Lua Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Implements error handling for tool prerequisites, checking if Git is installed and if the current directory is a Git repository. ```lua mcphub.add_tool("git", { handler = function(req, res) -- Check environment if not vim.fn.executable("git") then return res:error("Git not installed", { install = "https://git-scm.com" }) end -- Check repository if not is_git_repo() then return res:error("Not a git repository", { cwd = vim.fn.getcwd(), action = "Initialize with 'git init'" }) end end }) ``` -------------------------------- ### Setting Global Environment Variables Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/workspace.md Configure global environment variables for MCP Hub using the `global_env` option in the setup function. This example captures the DBUS session bus address. ```lua require("mcphub").setup({ global_env = function(context) return { DBUS_SESSION_BUS_ADDRESS = os.getenv("DBUS_SESSION_BUS_ADDRESS") or "", } end }) ``` -------------------------------- ### Mcphub.nvim Setup with Custom Auto-Approval Function Source: https://github.com/ravitemer/mcphub.nvim/blob/main/doc/mcphub.txt Configure mcphub.nvim with a custom auto_approve function to define specific conditions for automatically approving or denying MCP tool calls. This function receives parameters like server name, tool name, and arguments to make decisions. ```lua require("mcphub").setup({ auto_approve = function(params) -- Auto-approve GitHub issue reading if params.server_name == "github" and params.tool_name == "get_issue" then return true -- Auto approve end -- Block access to private repos if params.arguments.repo == "private" then return "You can\'t access my private repo" -- Error message end -- Auto-approve safe file operations in current project if params.tool_name == "read_file" then local path = params.arguments.path or "" if path:match("^" .. vim.fn.getcwd()) then return true -- Auto approve end end -- Check if tool is configured for auto-approval in servers.json if params.is_auto_approved_in_server then return true -- Respect servers.json configuration end return false -- Show confirmation prompt end, }) ```