Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add cmd and cmdArgs config options #32

Merged

Conversation

omarcresp
Copy link

@omarcresp omarcresp commented Mar 21, 2025

Add to config new optionals cmd and cmdArgs to change how the mcp-hub server instantiates

This will be needed for the nix compat because when installing mcp-hub with nix it will end in the nix store at /nix/store/uuid-mcphub/...
Also it can solve #31 by providing a way to clone the repo and run it from the clone repo avoiding to depend on a globally install/available mcp-hub

ravitemer and others added 7 commits March 19, 2025 10:46
This release adds support for custom instructions per MCP server allowing users to configure and manage server-specific instructions through the UI.
Add "Most Downloads" sort option to marketplace view to sort packages by
their download count.

Co-authored-by: Lin Zhenyun <linzhenyun@ft.tech>
@omarcresp omarcresp force-pushed the feat/CMD-option-in-config branch from c6fd0e0 to 030b2ea Compare March 21, 2025 18:02
@omarcresp
Copy link
Author

@ravitemer not sure if the cmdArgs being pass as null in the plenary will be an issue, pls validate it still works as expected when cmd and cmdArgs are not passed (i cannot run it normally with the mcp-hub installed with npm i -g)

@ravitemer
Copy link
Owner

Thank you @omarcresp for your thoughtful PR. Grateful for your time.
Will review and come back to you.

Can you check the nightly branch and see if it works on nixos?

{
    "ravitemer/mcphub.nvim",
    dependencies = {
        "nvim-lua/plenary.nvim",  -- Required for Job and HTTP requests
    },
    branch = "nightly",
    -- cmd = "MCPHub", -- lazily start the hub when `MCPHub` is called
    build = "build.lua", -- Installs required mcp-hub npm module
    config = function()
        require("mcphub").setup({
            -- Required options
            port = 3000,  -- Port for MCP Hub server
            config = vim.fn.expand("~/.config/lvim/lvim-mcp-servers.json"),  -- Absolute path to config file
        })
    end
}

@ravitemer
Copy link
Owner

With update in nightly branch, I feel users don't have to git clone or struggle with npm i -g etc.

Keen to hear your thoughts. Don't you think that will be a easier and fool-proof setup?

@omarcresp
Copy link
Author

Havent got it to build in nix with nightly branch

for context this is how mcp-hub is declare, not using lazy but nix to package the plugin

pkgs.vimUtils.buildVimPlugin {
  name = "mcphub.nvim";
  src = inputs.mcphub;
  nativeBuildInputs = [pkgs.lua];
  buildPhase = ''
    lua build.lua
  '';
  nvimSkipModule = [
    "mcphub.hub"
    "mcphub.extensions.codecompanion"
    "mcphub"
    "build"
  ];
};

once i got it stable in my machine i'll prepare PRs to include this plugin and the server in https://github.com/NixOS/nixpkgs so other people could use from pkgs.vimPlugins.mcphub and pkgs.mcphub-server instead of having to package it (like in my previous snippet)


In my opinion, previous approach was fine, just needed to give more options to the users to control how to invoke the server. I won't recommend to put the burden of installing/making the mcp-hub server available on the plugin side. Require to have it available in the user path + recommend doing npm i -g is a great solution for 80% of users... probably more. For the rest of them just give them the tools to modify how to invoke the server feels like the best approach for me

@ravitemer
Copy link
Owner

Agree on everything. I am happy to add these options.

My only dilemma is that as mcp-hub and mcphub.nvim are tightly coupled, if the user updates the plugin and is using cmd, cmdArgs options he has to manually update the mcp-hub where-ever that is setup. In that case he might have to have a custom build step that auto updates mcp-hub. Can we make this autoupdating work with nixos setup?

As you rightly said most of the users can use the default build step, I thought if we have build.lua users don't have to worry about building as I assume this will work almost always. Except that "lua build" with nixos is not working if I understood you correctly. We can also have a build.sh or makefile in that case.

I guess we can add a separate section in readme for these special cases and that shows a build step that auto updates the mcp-hub.

Thank you. Will merge this in the morning.

@omarcresp
Copy link
Author

omarcresp commented Mar 21, 2025

I'll answer in parts

  • lua build.lua not working
    I advanced on it but finally it will not work because nix doesnt allow network access during building for security and reproducibility reasons. changing it to be .sh or any other wont fix it because trying to use npm install will fail due to network restriction. Is possible to write an equivalent of that build.lua using the nix language and using secure data fetchers

  • How vim plugins works in nix
    In nix every vim plugin is package inside a derivation, they are then store in /nix/store which is a readonly directory with a name like {uuid}-{pluginname}-{version}. This steps are meant to be reproducible so running (pseudocode alert) nix install mcphub.nvim@1.0.0 will result ALWAYS in the same {uuid}-{pluginname}-{version} folder with the same content (it is ensure by hashing)

  • Reproducibility
    The build.lua current approach is not reproducible, since it relies on installing mcp-hub@latest running this command in different points of time will yield different results which is not ideal because shadow locks the user to always use the newer version

Solutions

  • Install mcp-hub: package the mcp-hub server inside nixpkgs so users will be abble to install mcp-hub in their system and have that available in the PATH and that will be version sync with mcphub.nvim just by design of how nixpkgs works. you point to a version of nixpkgs and that contain the versions that are compatible (mantainers take care of it) then you wont update plugin version you would update nixpkgs version and that may include newer mcphub plugin and server versions
  • Write build.lua in nix: instead of having mcp-hub and mcphub.nvim and asking users to install mcp-hub in their system (extra step) we can just have mcphub.nvim and rewrite that build.lua using the nix language so we only package one thing instead of two. This approach is better for the nix users because plugin will automagically work out of the box. But Im not sure about the get_bundled_mcp_path forcing mcp-hub to be inside the plugin local directory, maybe make that optional? so server could still be spawm by just mcp-hub.
  • Using it without installing: Alternative nixos allows to put things in /nix/store and use them on demand without having to install them in PATH. people could simple pass the nix/store/mcp-hub/ binary path to the cmd option (there are built in ways in nix to do that reliably)

additional

  • Flakes: previous solutions depends on nixpkgs mantainers to release newer versions on nixpkgs repository, an alternative to have latest versions always is to create a flake.nix file in the repo and that flake.nix contains the steps to package the plugin so people could point to mcphub.nvim github instead of nixpkgs to get latest versions

ravitemer and others added 3 commits March 22, 2025 05:30
…tallation

This update significantly improves the plugin's configuration and installation
flexibility, with an emphasis on zero-config usage.

Zero Configuration Support:

Default port to 37373
Default config path to ~/.config/mcphub/servers.json
Auto-create config file with empty mcpServers object
Works out of the box with just require("mcphub").setup({})
Installation Improvements:

Default Installation (Global npm):

Continues to work with npm install -g mcp-hub
No additional configuration needed

Bundled Installation (No global npm access):

Add bundled_build.lua for local mcp-hub installation
Auto-updates with plugin updates
Enable with use_bundled_binary = true
No global npm permissions required

Custom Installation Support:

Flexible cmd and cmdArgs configuration
Supports NixOS and other custom environments
Example configurations provided in docs

Documentation:
Updated README with all installation methods
Added zero-config setup examples
Improved configuration documentation
Clear guidance for different use cases
Breaking Changes: None. Enhances existing functionality while
maintaining backward compatibility.
…tallation

This update significantly improves the plugin's configuration and installation
flexibility, with an emphasis on zero-config usage.

Zero Configuration Support:

Default port to 37373
Default config path to ~/.config/mcphub/servers.json
Auto-create config file with empty mcpServers object
Works out of the box with just require("mcphub").setup({})
Installation Improvements:

Default Installation (Global npm):

Continues to work with npm install -g mcp-hub
No additional configuration needed

Bundled Installation (No global npm access):

Add bundled_build.lua for local mcp-hub installation
Auto-updates with plugin updates
Enable with use_bundled_binary = true
No global npm permissions required

Custom Installation Support:

Flexible cmd and cmdArgs configuration
Supports NixOS and other custom environments
Example configurations provided in docs

Documentation:
Updated README with all installation methods
Added zero-config setup examples
Improved configuration documentation
Clear guidance for different use cases
Breaking Changes: None. Enhances existing functionality while
maintaining backward compatibility.
@ravitemer
Copy link
Owner

First, thank you for taking the time to review and provide such detailed feedback! Your insights about NixOS and build process limitations really helped clarify things.

Let me explain my thinking behind these recent changes:

I completely agree that for most users (80%+), the global npm installation is the perfect solution. It's simple, standard, and just works. That's why we're keeping it as the default and recommended approach.

My main concern was about version synchronization between mcphub.nvim and mcp-hub. When users update the plugin but forget to update mcp-hub (or vice versa), it could lead to compatibility issues. That's what led me to add bundled_build.lua - it was an attempt to ensure both components stay in sync.

However, you've helped me understand that:

  1. This approach breaks in NixOS due to build-time network restrictions
  2. The reproducibility aspects of Nix's packaging system actually solve the version sync problem better
  3. For NixOS users, having mcp-hub packaged separately in nixpkgs is cleaner

I now see that we should:

  1. Keep emphasizing global npm install as the primary method
  2. Keep the cmd/cmdArgs flexibility for custom setups
  3. Document proper NixOS integration (once available in nixpkgs)
  4. Consider the bundled approach as just another option, not a primary solution

For NixOS specifically, I'm excited about your plan to submit PRs for both mcphub and mcp-hub to nixpkgs. That will provide a much better solution than trying to bundle everything together.

Would you be open to:

  1. Keeping the bundled_build.lua option
  2. Adding documentation about proper NixOS setup once the packages are available
  3. Maybe adding a flake.nix in the future for latest versions

Thank you again for helping me understand the NixOS perspective better. Let me know if this direction makes sense to you.

@omarcresp
Copy link
Author

Love it, i'll work on the nix documentation, the nixpkgs and nixvim (a framework to configure neovim using the nix language) PRs this weekend and keep you updated on that things

Let me know if you want me to review changes once this PR is done

@ravitemer
Copy link
Owner

I don't know if these changes require a major release, but I am almost done with my native mcp server implementation and want to include these config changes along with that in v4.

Until then, let's keep the PR open 😄

@craigdallimore
Copy link

Another neovim+nixos+mcphub user here. It would be brilliant to get this into nixpkgs.

At the moment I've got it sort-of working using this nix derivation (to get mcp-hub into the PATH):

mcp-hub/default.nix
{ lib
, buildNpmPackage
, fetchFromGitHub
, nodejs
, uv
}:

buildNpmPackage rec {
  pname = "mcp-hub";
  version = "1.7.3";

  src = fetchFromGitHub {
    owner = "ravitemer";
    repo = "mcp-hub";
    rev = "010581b9d9d2b689df71dd8b65aef024a1a61eec";
    hash = "sha256-tGfUsETzFpPHTT++XRlhpjYwUDThJJNigQVmfcZeh28=";
  };

  npmDepsHash = "sha256-hC5QxKxHAtV94DwT5m0zR+VAA8Jn4SuB36fdAhVT73g=";

  # Make sure node binaries and global npm packages are available
  makeWrapperArgs = [
    "--prefix" "PATH" ":" "${lib.makeBinPath [ nodejs uv ]}"
    "--suffix" "NODE_PATH" ":" "${placeholder "out"}/lib/node_modules"
  ];

  # Runtime dependencies - include both nodejs and uv (which provides uvx)
  nativeBuildInputs = [ nodejs uv ];

  # Build dependencies
  buildInputs = [];

  meta = with lib; {
    description = "MCP (Model Context Protocol) Hub for neovim integration";
    homepage = "https://github.com/ravitemer/mcp-hub";
    license = licenses.mit;
    maintainers = with maintainers; [ ];  # Add maintainers if desired
  };
}

... and for the neovim plugin:

mcphub-nvim
# nightly

    mcphub-nvim = pkgs.vimUtils.buildVimPlugin {
      name = "mcphub-nvim";
      src = pkgs.fetchFromGitHub {
        owner = "ravitemer";
        repo = "mcphub.nvim";
        rev = "030b2ea17daf6c46f34376e455faa4e608acaf8b";
        hash = "sha256-17PR8gjB0jBAKXo2L9VeMjaTVJZFLHV5fwTAmubpOec=";
      };
    };

And this config:

require('mcphub').setup({
  port = 3000,
  config = vim.fn.expand("~/.config/mcpservers.json"),
  cmd = "mcp-hub",
  cmdArgs = "--port 3000 --config ~/.config/mcpservers.json",

  -- Optional options
  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"
  },
})

This works (for me at least!) but it takes a long time for the UI to connect to the server. And it isn't the slickest config - but I'm sharing in case it might be helpful.

Screenshot From 2025-03-23 10-27-33

@ravitemer
Copy link
Owner

Thank you for sharing.

Is there anything I can do to make this easier and let the hub start faster in nixos? (assuming you meant slow to start in nixos)

I am try to do any kind of changes to mcp-hub and mcphub.nvim that helps nixos with this pain point.

@craigdallimore
Copy link

I'm not sure why it is slow to start on my Thinkpad - I'd need to figure out how to measure the various operations to see where the time goes. I also tried it on a MacBook that uses nix, and it was nearly instant. I sense this might be something on my end, unless it reproduces for others.

@omarcresp
Copy link
Author

Hi @craigdallimore im packaging everything to the nixpkgs for the next avante release 😄 (its easier to get eyes on things when you update an existing largely used nvim plugin and I'm one of the avante mantainers in nixpkgs)

This works (for me at least!) but it takes a long time for the UI to connect to the server. And it isn't the slickest config - but I'm sharing in case it might be helpful.

How much time are we talking? I have an HP very low spec and it loads there like in 2-3 seconds spins up the mcphub server and connects to all mcp servers (i have 3 currently)

If you're on flakes. This branches have a working implementation of flakes for usage (im my case in with nixvim)

    mcphub-nvim.url = "github:omarcresp/mcphub.nvim/nix-cmd";
    mcphub-nvim.inputs.nixpkgs.follows = "nixpkgs";
    mcphub-nvim.inputs.flake-parts.follows = "flake-parts";

    mcphub.url = "github:omarcresp/mcp-hub/feat/nix-compatibility";
    mcphub.inputs.nixpkgs.follows = "nixpkgs";
    mcphub.inputs.flake-parts.follows = "flake-parts";

......

          mcphub-nvim = inputs.mcphub-nvim.packages.${system}.default;
          mcphub = inputs.mcphub.packages.${system}.default;

And on nixvim (I'll also prepare a PR to make mcphub a config option here) using it like this:

{ mcphub-nvim, mcphub, ... }:
{
  extraPlugins = [mcphub-nvim];
  extraConfigLua = ''
    require("mcphub").setup({
        port = 3000,
        config = vim.fn.expand("~/mcp-hub/mcp-servers.json"),
        cmd = "${mcphub}/bin/mcp-hub"
    })
  '';
}

you could also put mcphub (the server) in your system/home-manager packages and avoid doing the cmd = part

@ravitemer if you agree, i can create an issue in the repo for nix support where we could track the progress of all the things that must happen to have a full implementation of this plugin in nixpkgs and nixvim so if other nix/nixvim users have questions they could go there in the meantime :)

@ravitemer
Copy link
Owner

I can create an issue in the repo for nix support where we could track the progress of all the things that must happen to have a full implementation of this plugin in nixpkgs and nixvim so if other nix/nixvim users have questions they could go there in the meantime :)

Absolutely!

@craigdallimore
Copy link

How much time are we talking? I have an HP very low spec and it loads there like in 2-3 seconds spins up the mcphub server and connects to all mcp servers (i have 3 currently)

2m 12s, lenovo x280 i7. Bizarre. If I get time I'll try your flake

@ravitemer
Copy link
Owner

2m 12s, lenovo x280 i7. Bizarre. If I get time I'll try your flake

Whoa! 2m? Can you try running mcp-hub -p 3000 -c ~/mcp-hub/mcp-servers.json in the terminal? This might tell if it is a nixos thing or related to the system.

@ravitemer
Copy link
Owner

ravitemer commented Mar 23, 2025

Can you first try with a simple server like fetch and disable any other servers

      "fetch": { 
        "args": [  
          "mcp-server-fetch"  
        ],  
        "command": "uvx"  
      }

@craigdallimore
Copy link

craigdallimore commented Mar 23, 2025

Doing that, it started my three servers in 0.19s

@ravitemer
Copy link
Owner

Doing that, it started my three servers in 0.19s

if mcp-hub command can start them that fast, mcphub.nvim should also start them that fast as it just uses the command internally. Although I don't know much about nixos, It feels like the issue might be with how we configure the plugin in nix. @omarcresp can you think of any reason why this is happening?

@omarcresp
Copy link
Author

Not sure, @craigdallimore 19s is still high for just the fetch server. I just built your derivation and it took 2s

maybe can you mount the server from the /nix/store result and share the logs to investigate?

@craigdallimore
Copy link

0.19 of a second 🙂, not 19

@omarcresp
Copy link
Author

wow, thats fast. TDAH got in the middle sorry 😅 so it only takes long when spawn by nvim?

@ravitemer ravitemer changed the base branch from main to feat/custom_instructions March 25, 2025 19:14
@ravitemer ravitemer merged commit feb9bfe into ravitemer:feat/custom_instructions Mar 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants