Skip to content

Feature Request: Custom Tool Registration via Lua Plugin #47

@linw1995

Description

@linw1995

Feature Request: Custom Tool Registration via Lua Plugin

Summary

Allow users to register custom MCP tools through Lua functions defined in the Neovim plugin configuration, extending the server's capabilities beyond the built-in tools.

Status: ⚠️ Experimental Implementation Available

Current Progress: Feature has been implemented as an experimental dynamic tool system on the feat/dynamic_tools branch.

Implementation Summary

The dynamic tool system is now available with the following key components:

HybridToolRouter Architecture

  • Dual Tool Support: Combines static tools (from #[tool_router] macro) with dynamic tools
  • Connection-Scoped Tools: Tools automatically registered/unregistered with connection lifecycle
  • Performance Optimized: Lock-free concurrent access using Arc<DashMap>
  • Conflict Resolution: Prevents naming conflicts between static and dynamic tools

Lua Tool Integration

  • User-Extensible Registration: Custom tools through Neovim configuration
  • JSON Schema Validation: Robust parameter validation using jsonschema crate
  • MCP Helper Functions: MCP.success(), MCP.error(), MCP.text(), MCP.json() for responses
  • Automatic Discovery: Tools discovered and registered during connection setup
  • Connection Isolation: Tools scoped to specific connections with automatic cleanup

Example Usage

require("nvim-mcp").setup({
    custom_tools = {
        save_buffer = {
            description = "Save a specific buffer by ID",
            parameters = {
                type = "object",
                properties = {
                    buffer_id = {
                        type = "integer", 
                        description = "The buffer ID to save",
                        minimum = 1,
                    },
                },
                required = { "buffer_id" },
            },
            handler = function(params)
                vim.api.nvim_buf_call(params.buffer_id, function()
                    vim.cmd("write")
                end)
                return MCP.success({
                    buffer_id = params.buffer_id,
                    message = "Buffer saved successfully",
                })
            end,
        },
    },
})

Changes Made

Files Changed (19 files, +3738/-41 lines):

  • Core Infrastructure: src/server/hybrid_router.rs (571 lines) - HybridToolRouter implementation
  • Lua Integration: src/server/lua_tools.rs (563 lines) - Lua tool discovery and validation
  • Plugin Enhancement: lua/nvim-mcp/init.lua (+84 lines) - Custom tool registration support
  • Documentation: Enhanced CLAUDE.md with dynamic tool architecture details
  • Testing: Comprehensive integration tests for dynamic tool lifecycle
  • Resource System: Extended resources to show tool-connection mappings

Key Commits:

  • 4744345: Refactor dynamic tool conversion with From trait and comprehensive tests
  • 5f3707f: Fix dynamic tool schema to include connection_id parameter
  • 6ef7bd6: Initialize Lua tools after auto-connection
  • 142480c: Add Lua dynamic tools system with trait-based architecture
  • 01d030d: Add HybridToolRouter for Dynamic Tool Registration

⚠️ Experimental Status Warning

Important: This implementation is marked as experimental and may change significantly or be removed in future versions. Key considerations:

  • API stability not guaranteed
  • May require breaking changes based on user feedback
  • Comprehensive testing needed before production use
  • Documentation may lag behind implementation

Benefits Achieved

  • ✅ Extensible architecture allowing user-defined workflows
  • ✅ Maintains separation between core tools and user customizations
  • ✅ Leverages existing Neovim Lua ecosystem and user expertise
  • ✅ Keeps MCP protocol compliance while adding flexibility
  • ✅ Connection-scoped tool isolation prevents interference
  • ✅ Automatic tool lifecycle management with connection cleanup
  • ✅ Performance-optimized with lock-free concurrent data structures

Next Steps

  1. User Testing: Gather feedback from early adopters
  2. API Stabilization: Refine interfaces based on real-world usage
  3. Documentation: Complete user guide and examples
  4. Integration Testing: Expanded test coverage for edge cases
  5. Performance Analysis: Benchmarking under load

The experimental implementation provides a solid foundation for the requested feature while maintaining system reliability and performance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions