Skip to main content
Glama

ado_package_install

Install Stata ado packages from SSC, GitHub, or net sources to access third-party commands.

Instructions

Install a Stata ado package from SSC, GitHub, or net sources. Use before running commands that require third-party packages.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
packageYes
sourceNossc
is_replaceNo
package_source_fromNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Primary handler: Installs ado packages from SSC, net, or GitHub. On Unix uses installer classes (SSC_Install, NET_Install, GITHUB_Install); on Windows writes a dofile and executes via stata_do. Supports replace, timeout, and config_file parameters.
    def ado_package_install(
        package: str,
        source: str = "ssc",
        is_replace: bool = True,
        package_source_from: str = None,
        config_file: str | Path | None = None,
        timeout: int = 300,
    ) -> str:
        """Install an ado package from SSC, net, or GitHub."""
        runtime = create_runtime_context(config_file=config_file, require_stata=True)
        source = source.lower()
    
        if runtime.is_unix:
            installer_cls = SOURCE_MAPPING.get(source, SSC_Install)
            install_args = [package, package_source_from] if source == "net" else [package]
            install_message = installer_cls(runtime.stata_cli, is_replace, timeout=timeout).install(*install_args)
    
            if not installer_cls.check_installed_from_msg(install_message):
                error_summary = installer_cls.extract_error_summary(install_message)
                install_message += (
                    f"\nError: Failed to install package '{package}' from source '{source}'. "
                    f"Details: {error_summary}"
                )
                if source == "github":
                    install_message += (
                        "\nPlease check the GitHub repository URL, verify case sensitivity, "
                        "and ensure the github command is installed in Stata."
                    )
            else:
                try:
                    from ..mcp_servers import _load_help_cls
    
                    _load_help_cls().help(package, replace=True)
                except Exception:
                    pass
            return install_message
    
        from_message = f"from({package_source_from})" if (package_source_from and source == "net") else ""
        replace_flag = "replace" if is_replace else ""
        command = f"{source} install {package}, {replace_flag} {from_message}".strip()
        dofile_path = write_dofile(command, config_file=config_file)
        return str(stata_do(dofile_path, read_log_when_error=False, config_file=config_file).get("log_content", {}))
  • Legacy handler in mcp_servers.py (used before API refactor). Duplicates logic: on Unix uses installer classes with direct config, on Windows writes dofile. Wraps the old config singleton instead of runtime context.
    def ado_package_install(
            package: str,
            source: str = "ssc",
            is_replace: bool = True,
            package_source_from: str = None
    ) -> str:
        """
        Install a Stata package from SSC, GitHub, or net.
    
        Args:
            package (str): Package name. For GitHub, use "user/repo" format.
            source (str): "ssc" (default), "github", or "net".
            is_replace (bool): Force reinstallation if already present.
            package_source_from (str): Directory or URL (required only for source="net").
    
        Returns:
            str: Stata installation log as a string.
    
        Examples:
            >>> ado_package_install(package="outreg2")
            >>> ado_package_install(package="SepineTam/TexIV", source="github")
    
        Notes:
            SSC installs can be slow; skip if the package is likely already installed.
        """
        source = source.lower()
    
        if config.IS_UNIX:
            from .stata import GITHUB_Install, NET_Install, SSC_Install
    
            SOURCE_MAPPING: Dict = {
                "github": GITHUB_Install,
                "net": NET_Install,
                "ssc": SSC_Install
            }
            installer = SOURCE_MAPPING.get(source, SSC_Install)
    
            logging.info(f"Try to use {installer.__name__} to install {package}.")
    
            # set the args for the special cases
            args = [package, package_source_from] if source == "net" else [package]
            install_msg = installer(config.STATA_CLI, is_replace, timeout=300).install(*args)
    
            if installer.check_installed_from_msg(install_msg):
                logging.info(f"{package} is installed successfully.")
            else:
                error_summary = installer.extract_error_summary(install_msg)
                install_msg += (
                    f"\nError: Failed to install package '{package}' from source '{source}'. "
                    f"Details: {error_summary}"
                )
                if source == "github":
                    install_msg += (
                        "\nPlease check the GitHub repo URL, verify case sensitivity, "
                        "and ensure the GitHub command is installed in Stata"
                    )
                logging.error(f"{package} installation failed.")
                logging.debug(f"Full installation message: {install_msg}")
    
            return install_msg
        else:
            from_message = f"from({package_source_from})" if (package_source_from and source == "net") else ""
            replace_str = "replace" if is_replace else ""
            tmp_file = write_dofile(f"{source} install {package}, {replace_str} {from_message}")
            return stata_do(tmp_file, read_log_when_error=False).get("log_content")
  • Tool registration entry in _TOOL_REGISTRY dict mapping 'ado_package_install' to its description and function reference (with 'all' profile).
    "ado_package_install": {
        "description": (
            "Install a Stata ado package from SSC, GitHub, or net sources. "
            "Use before running commands that require third-party packages."
        ),
        "func": ado_package_install,
        "profiles": {"all"},
    },
  • register_tools function that iterates _TOOL_REGISTRY and calls server.tool() to register each tool with FastMCP.
    def register_tools(server: FastMCP, profile: str = "all") -> None:
        """Register tools and resources based on a selected profile."""
        global _registered_profile
    
        if profile not in {"core", "all"}:
            raise ValueError(f"Unsupported profile: {profile}")
    
        if _registered_profile == profile:
            return
        if _registered_profile is not None and _registered_profile != profile:
            raise RuntimeError(
                "Tools are already registered with a different profile. "
                "Create a new process to switch profile."
            )
    
        for name, meta in _TOOL_REGISTRY.items():
            if meta.get("unix_only") and not config.IS_UNIX:
                continue
            if meta.get("deprecated") and not config.ENABLE_WRITE_DOFILE:
                continue
            if profile not in meta["profiles"]:
                continue
    
            tool_func: ToolFunc | None = meta.get("func")
            if tool_func is None:
                logging.warning("Skipping tool '%s' because its registry entry has no callable func.", name)
                continue
            server.tool(name=name, description=meta["description"])(tool_func)
  • CLI handler for 'ado-install' action that invokes ado_package_install from the API module with parsed CLI arguments.
    def handle_tool(args: Namespace) -> int:
        """Handle the tool subcommand."""
        from ..api import ado_package_install, get_data_info, read_log, stata_do, stata_help
    
        try:
            if args.tool_action == "ado-install":
                result = ado_package_install(
                    package=args.package_name,
                    source=args.source,
                    is_replace=args.is_replace,
                    package_source_from=args.package_source_from,
                )
            elif args.tool_action == "do":
                result = stata_do(
                    dofile_path=args.dofile_path,
                    log_file_name=args.log_file_name,
                    read_log_when_error=args.is_read_log,
                    is_replace_log=args.is_replace_log,
                    enable_smcl=args.enable_smcl,
                )
            elif args.tool_action == "help":
                result = stata_help(
                    cmd=args.stata_command,
                    enable_smcl=args.enable_smcl,
                )
            elif args.tool_action == "data-info":
                result = get_data_info(
                    data_path=args.data_path,
                    vars_list=args.vars_list,
                    encoding=args.encoding,
                )
            elif args.tool_action == "read-log":
                result = read_log(
                    file_path=args.file_path,
                    encoding=args.encoding,
                    output_format=args.output_format,
                )
            else:
                return 2
        except Exception as error:
            print(error, file=sys.stderr)
            return 1
    
        print_cli_result(result)
        return 0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description confirms the tool modifies the system by installing packages and lists sources (SSC, GitHub, net). However, without annotations, it lacks details such as potential side effects, authentication needs, or whether it can overwrite existing packages. This is moderate transparency for a modification tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences with no redundant information. The purpose and usage hint are front-loaded, making it quick to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 4 parameters, no schema descriptions, and no annotations, the description is too brief. It does not explain parameter roles or the output schema (which exists). A user would need external documentation to use all parameters correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has four parameters with zero description coverage. The description only vaguely hints at the 'source' parameter but does not explain 'is_replace' or 'package_source_from'. It fails to add meaning beyond the schema's property names, which are insufficient for correct use.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool installs a Stata ado package from specific sources (SSC, GitHub, or net). It uses a specific verb ('install') and resource ('ado package'), distinguishing it from sibling tools like help or read_log.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description advises using the tool 'before running commands that require third-party packages,' providing clear when-to-use context. It does not mention when not to use or alternatives, but no comparable sibling tools exist, so this is adequate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/SepineTam/stata-mcp'

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