Skip to content

Index

Functionality for interaction with the CLI.

The cli package contains all of the functionality required for user interaction with the command line interface (CLI). It sets up an argument parser for the main mada-tools command and subparsers for the various subcommands found in the commands subpackage.

Subpackages

commands: Sets up subcommands for the mada-tools command.

Modules:

Name Description
ascii_art

A file to store ASCII art that can be used in the CLI output.

__getattr__(name)

Lazily expose CLI objects that import command implementations.

Importing an individual command module first executes this package initializer. Keep the command registry lazy so lightweight commands such as export-docs can be imported without loading every MCP server-management command and its runtime dependencies.

Source code in mada_tools/cli/__init__.py
def __getattr__(name):
    """Lazily expose CLI objects that import command implementations.

    Importing an individual command module first executes this package
    initializer. Keep the command registry lazy so lightweight commands such as
    ``export-docs`` can be imported without loading every MCP server-management
    command and its runtime dependencies.
    """
    if name == "ALL_COMMANDS":
        from mada_tools.cli.commands import ALL_COMMANDS

        return ALL_COMMANDS

    if name == "BANNER":
        from mada_tools.cli.ascii_art import BANNER

        return BANNER

    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

setup_logging(level='INFO', log_to_stdout=True, log_file=None)

Configure root logger for the entire application.

Called once when argparse is loaded up. Other modules should just use logging.getLogger(name).

Parameters:

Name Type Description Default
level str

Log level name, for example: "DEBUG", "INFO", "WARNING".

'INFO'
log_to_stdout bool

If True, log to stdout.

True
log_file str | None

If given, also log to this file.

None
Source code in mada_tools/logging_config.py
def setup_logging(
    level: str = "INFO",
    log_to_stdout: bool = True,
    log_file: str | None = None,
):
    """
    Configure root logger for the entire application.

    Called once when argparse is loaded up. Other modules
    should just use logging.getLogger(__name__).

    Args:
        level (str): Log level name, for example: "DEBUG",
            "INFO", "WARNING".
        log_to_stdout (bool): If True, log to stdout.
        log_file (str | None): If given, also log to this file.
    """
    # Convert level string to numeric value
    level_upper = level.upper()
    numeric_level = LEVEL_MAP.get(level_upper, logging.INFO)

    # Remove any existing handlers if reconfiguring
    root_logger = logging.getLogger()
    root_logger.handlers.clear()
    root_logger.setLevel(numeric_level)

    formatter = logging.Formatter(
        fmt="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S",
    )

    if log_to_stdout:
        stream_handler = logging.StreamHandler(sys.stdout)
        stream_handler.setLevel(numeric_level)
        stream_handler.setFormatter(formatter)
        root_logger.addHandler(stream_handler)

    if log_file:
        file_handler = logging.FileHandler(log_file)
        file_handler.setLevel(numeric_level)
        file_handler.setFormatter(formatter)
        root_logger.addHandler(file_handler)