From a2b1ca4c9c79fde0efdad47b6102ae0e92b7eb7b Mon Sep 17 00:00:00 2001 From: aivibe <93047788+axisrow@users.noreply.github.com> Date: Mon, 2 Mar 2026 11:51:25 +0700 Subject: [PATCH] feat: unify version management with --version/-V flag Replace hardcoded version strings with dynamic version from importlib.metadata. Add --version/-V CLI flag to mcp-cli. - __init__.py: read __version__ from package metadata instead of "1.0.0" - apps/host.py: use APP_VERSION from config instead of hardcoded "0.13" - main.py: add _version_callback and --version/-V option to Typer app Co-Authored-By: Claude Opus 4.6 --- src/mcp_cli/__init__.py | 6 +++++- src/mcp_cli/apps/host.py | 7 +++---- src/mcp_cli/main.py | 17 ++++++++++++++++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/mcp_cli/__init__.py b/src/mcp_cli/__init__.py index e23c3141..61411132 100644 --- a/src/mcp_cli/__init__.py +++ b/src/mcp_cli/__init__.py @@ -38,5 +38,9 @@ os.environ.setdefault("CHUK_LLM_OPENAI_TOOL_COMPATIBILITY", "true") os.environ.setdefault("CHUK_LLM_UNIVERSAL_TOOLS", "true") -__version__ = "1.0.0" +from importlib.metadata import version as _pkg_version, PackageNotFoundError +try: + __version__ = _pkg_version("mcp-cli") +except PackageNotFoundError: + __version__ = "0.0.0-dev" __all__ = ["__version__"] diff --git a/src/mcp_cli/apps/host.py b/src/mcp_cli/apps/host.py index c1ff9d8d..7406cc1a 100644 --- a/src/mcp_cli/apps/host.py +++ b/src/mcp_cli/apps/host.py @@ -39,14 +39,13 @@ DEFAULT_HTTP_REQUEST_TIMEOUT, ) +from mcp_cli.config import APP_VERSION + if TYPE_CHECKING: from mcp_cli.tools.manager import ToolManager logger = logging.getLogger(__name__) -# Version injected into the host page -_MCP_CLI_VERSION = "0.13" - # Strict regex for CSP source values — reject anything that could break out # of an HTML attribute or inject additional directives. _SAFE_CSP_SOURCE = re.compile(r"^[a-zA-Z0-9\-.:/*]+$") @@ -288,7 +287,7 @@ async def _start_server( tool_name=safe_tool_name, port=app_info.port, csp_attr=csp_attr, - mcp_cli_version=_MCP_CLI_VERSION, + mcp_cli_version=APP_VERSION, init_timeout=DEFAULT_APP_INIT_TIMEOUT, ) host_page_bytes = host_page.encode("utf-8") diff --git a/src/mcp_cli/main.py b/src/mcp_cli/main.py index ccb353a5..3808adf9 100644 --- a/src/mcp_cli/main.py +++ b/src/mcp_cli/main.py @@ -30,7 +30,7 @@ restore_terminal, ) from chuk_term.ui.theme import set_theme -from mcp_cli.config import process_options +from mcp_cli.config import process_options, APP_VERSION from mcp_cli.context import initialize_context # ────────────────────────────────────────────────────────────────────────────── @@ -55,12 +55,27 @@ app = typer.Typer(add_completion=False) +# ────────────────────────────────────────────────────────────────────────────── +# Version callback +# ────────────────────────────────────────────────────────────────────────────── +def _version_callback(value: bool) -> None: + if value: + typer.echo(f"mcp-cli {APP_VERSION}") + raise typer.Exit() + + # ────────────────────────────────────────────────────────────────────────────── # Default callback that handles no-subcommand case # ────────────────────────────────────────────────────────────────────────────── @app.callback(invoke_without_command=True) def main_callback( ctx: typer.Context, + version: bool = typer.Option( + None, "--version", "-V", + callback=_version_callback, + is_eager=True, + help="Show version and exit.", + ), config_file: str = typer.Option( "server_config.json", help="Configuration file path" ),