Skip to main content
Glama
XD3an
by XD3an

install_local_mcp_server

Install an MCP server from a local directory by specifying the path, arguments, and environment variables for configuration.

Instructions

Install an MCP server from a local directory.

Args:
    path: The path to the MCP server code cloned on your computer
    args: The arguments to pass along
    env: The environment variables to set, delimited by =

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathYes
argsNo
envNo

Implementation Reference

  • The @mcp.tool()-decorated handler function that implements the 'install_local_mcp_server' tool. It installs a local MCP server by checking if it's a Node.js or Python project, determining the entry point, and adding the configuration to Claude Desktop's config file using the helper install_to_claude_desktop.
    @mcp.tool()
    def install_local_mcp_server(
        path: str, 
        args: Optional[List[str]] = None,
        env: Optional[List[str]] = None,
    ) -> str:
        """
        Install an MCP server from a local directory.
        
        Args:
            path: The path to the MCP server code cloned on your computer
            args: The arguments to pass along
            env: The environment variables to set, delimited by =
        """
        if args is None:
            args = []
            
        if not os.path.exists(path):
            return f"Path '{path}' does not exist."
            
        # Check if it's a Node.js or Python project
        has_package_json = os.path.exists(os.path.join(path, "package.json"))
        has_pyproject_toml = os.path.exists(os.path.join(path, "pyproject.toml"))
        has_setup_py = os.path.exists(os.path.join(path, "setup.py"))
        
        # Determine server name from directory name
        server_name = os.path.basename(path)
        
        # Check if Node.js is installed (for npm packages)
        has_node = check_command_exists("node")
        has_npm = check_command_exists("npm")
        has_pip = check_command_exists("pip")
        has_python = check_command_exists("python")
        
        # Handle Node.js projects
        if has_package_json and has_node and has_npm:
            # For Node.js projects, use node directly to run the local script
            # Find the main entry point from package.json
            try:
                with open(os.path.join(path, "package.json"), "r") as f:
                    package_json = json.load(f)
                    
                # Try to find the main entry point
                main_file = package_json.get("main", "index.js")
                
                # Install to Claude Desktop
                install_to_claude_desktop(
                    server_name,
                    "node",
                    [os.path.join(path, main_file)] + args,
                    env,
                )
                
                return f"Successfully installed local Node.js MCP server '{server_name}'! Please tell the user to restart the application."
            except Exception as e:
                return f"Error installing Node.js MCP server: {str(e)}"
                
        # Handle Python projects
        elif (has_pyproject_toml or has_setup_py) and has_python:
            # For Python projects, use python -m to run the module
            # Try to determine the module name from directory structure
            module_name = server_name.replace("-", "_")
            
            # Check if there's a directory with the same name
            if os.path.isdir(os.path.join(path, module_name)):
                # Install to Claude Desktop
                install_to_claude_desktop(
                    server_name,
                    "python",
                    ["-m", module_name] + args,
                    env,
                    cwd=path,
                )
                
                return f"Successfully installed local Python MCP server '{server_name}'! Please tell the user to restart the application."
            else:
                # Try to find any Python files in the root directory
                py_files = [f for f in os.listdir(path) if f.endswith(".py") and f != "setup.py"]
                
                if py_files:
                    main_file = py_files[0].replace(".py", "")
                    
                    # Install to Claude Desktop
                    install_to_claude_desktop(
                        server_name,
                        "python",
                        [os.path.join(path, main_file + ".py")] + args,
                        env,
                    )
                    
                    return f"Successfully installed local Python MCP server '{server_name}'! Please tell the user to restart the application."
        
        return f"Could not determine how to install MCP server from '{path}'. Make sure it's a valid Node.js or Python project."
  • Core helper function install_to_claude_desktop used by install_local_mcp_server to write the MCP server configuration (command, args, env, cwd) to the Claude Desktop JSON config file under mcpServers.
    def install_to_claude_desktop(
        server_name: str,
        command: str,
        args: List[str],
        env: Optional[List[str]] = None,
        cwd: Optional[str] = None,
    ) -> None:
        """
        Install an MCP server to Claude Desktop.
        
        Args:
            server_name: The name of the MCP server
            command: The command to run the MCP server
            args: The arguments to pass to the command
            env: The environment variables to set, delimited by =
            cwd: The working directory for the command
        """
        # Normalize server name to be a valid identifier
        # For npm packages, make sure we use a simple name without @ or /
        if server_name.startswith("@"):
            # For @scope/package, use just "package" as the server name
            if "/" in server_name:
                server_name = server_name.split("/")[1]
        
        # Remove any invalid characters from server name
        server_name = re.sub(r'[^a-zA-Z0-9_-]', '-', server_name)
        
        # Get the Claude Desktop config file path
        config_path = get_claude_desktop_config_path()
        
        if not config_path:
            raise ValueError("Could not find Claude Desktop config file")
            
        # Read the existing config
        try:
            with open(config_path, "r", encoding="utf-8") as f:
                config = json.load(f)
        except (FileNotFoundError, json.JSONDecodeError):
            config = {}
            
        # Initialize mcpServers if it doesn't exist
        if "mcpServers" not in config:
            config["mcpServers"] = {}
            
        # Prepare the server config
        server_config = {
            "command": command,
            "args": args,
        }
        
        # Add environment variables if provided
        if env and len(env) > 0:
            server_config["env"] = parse_env_vars(env)
                    
        # Add working directory if provided
        if cwd:
            server_config["cwd"] = cwd
            
        # Add the server to the config
        config["mcpServers"][server_name] = server_config
        
        # Write the config back to the file
        with open(config_path, "w", encoding="utf-8") as f:
            json.dump(config, f, indent=2)
  • Helper function check_command_exists to verify if required commands like node, npm, pip are available.
    def check_command_exists(command: str) -> bool:
        """Check if a command exists in the system PATH."""
        return shutil.which(command) is not None
  • Helper function parse_env_vars to parse list of KEY=VALUE strings into a dict for env config.
    def parse_env_vars(env_vars: Optional[List[str]]) -> Optional[Dict[str, str]]:
        """Parse environment variables from a list of KEY=VALUE strings."""
        if not env_vars:
            return None
            
        env_obj = {}
        for env_var in env_vars:
            if "=" in env_var:
                key, value = env_var.split("=", 1)
                env_obj[key] = value
                
        return env_obj if env_obj else None
  • The @mcp.tool() decorator registers the install_local_mcp_server function as an MCP tool.
    @mcp.tool()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/XD3an/mcp-builder'

If you have feedback or need assistance with the MCP directory API, please join our Discord server