From c164d2c72646a91de1c76d97b8f4184602fddf13 Mon Sep 17 00:00:00 2001 From: Teagan Glenn Date: Mon, 13 Oct 2025 16:27:41 -0600 Subject: [PATCH] refactor(project): centralize log level configuration --- docker/pyproject.deps.toml | 2 +- mcp_plex/server/cli.py | 21 +++++++++++++++++++++ pyproject.toml | 2 +- tests/test_server_cli.py | 16 ++++++++++++++++ uv.lock | 2 +- 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/docker/pyproject.deps.toml b/docker/pyproject.deps.toml index 34cbd3e..e752fa2 100644 --- a/docker/pyproject.deps.toml +++ b/docker/pyproject.deps.toml @@ -1,6 +1,6 @@ [project] name = "mcp-plex" -version = "2.0.16" +version = "2.0.17" requires-python = ">=3.11,<3.13" dependencies = [ "fastmcp>=2.11.2", diff --git a/mcp_plex/server/cli.py b/mcp_plex/server/cli.py index d543982..71357c6 100644 --- a/mcp_plex/server/cli.py +++ b/mcp_plex/server/cli.py @@ -3,6 +3,7 @@ from __future__ import annotations import argparse +import logging import os from dataclasses import dataclass @@ -33,6 +34,17 @@ def to_kwargs(self) -> dict[str, object]: return kwargs +def _resolve_log_level(cli_value: str | None) -> str: + """Return the desired log level name based on CLI or environment input.""" + + env_value = os.getenv("LOG_LEVEL") + if cli_value: + return cli_value + if env_value: + return env_value.lower() + return "info" + + def main(argv: list[str] | None = None) -> None: """CLI entrypoint for running the MCP server.""" @@ -61,6 +73,12 @@ def main(argv: list[str] | None = None) -> None: default=settings.reranker_model, help="Cross-encoder reranker model name (env: RERANKER_MODEL)", ) + parser.add_argument( + "--log-level", + type=str.lower, + choices=["critical", "error", "warning", "info", "debug", "notset"], + help="Logging verbosity (env: LOG_LEVEL)", + ) args = parser.parse_args(argv) env_transport = os.getenv("MCP_TRANSPORT") @@ -112,6 +130,9 @@ def main(argv: list[str] | None = None) -> None: settings.sparse_model = args.sparse_model settings.reranker_model = args.reranker_model + log_level_name = _resolve_log_level(args.log_level) + logging.basicConfig(level=getattr(logging, log_level_name.upper(), logging.INFO)) + plex_server.run(transport=transport, **run_config.to_kwargs()) diff --git a/pyproject.toml b/pyproject.toml index ae3614d..feaad47 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "mcp-plex" -version = "2.0.16" +version = "2.0.17" description = "Plex-Oriented Model Context Protocol Server" requires-python = ">=3.11,<3.13" diff --git a/tests/test_server_cli.py b/tests/test_server_cli.py index 54f369d..211bba6 100644 --- a/tests/test_server_cli.py +++ b/tests/test_server_cli.py @@ -1,5 +1,6 @@ from unittest.mock import patch +import logging import asyncio import importlib import pytest @@ -125,3 +126,18 @@ def test_run_config_reexport(): from mcp_plex.server import RunConfig as ExportedRunConfig assert ExportedRunConfig is server.RunConfig + + +def test_main_configures_log_level(monkeypatch): + configured: dict[str, object] = {} + + def fake_basic_config(**kwargs): + configured["level"] = kwargs.get("level") + + monkeypatch.setattr("logging.basicConfig", fake_basic_config) + + with patch.object(server.server, "run") as mock_run: + server.main(["--log-level", "debug"]) + + assert configured["level"] == logging.DEBUG + mock_run.assert_called_once_with(transport="stdio") diff --git a/uv.lock b/uv.lock index 9a50aa1..1edf433 100644 --- a/uv.lock +++ b/uv.lock @@ -730,7 +730,7 @@ wheels = [ [[package]] name = "mcp-plex" -version = "2.0.16" +version = "2.0.17" source = { editable = "." } dependencies = [ { name = "fastapi" },