From 1ca882e57a83fe7bdd904d7b4fb7bf6f997acf55 Mon Sep 17 00:00:00 2001 From: Andrey Barchenkov Date: Mon, 27 Apr 2026 20:06:44 -0400 Subject: [PATCH] fix: move logging configuration from MCPServer.__init__ to run() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MCPServer.__init__() called configure_logging() which invokes logging.basicConfig(), adding handlers and setting the level on the root logger. This violates the Python logging best practice that library code should never configure the root logger — only application entrypoints should do that. Applications embedding MCPServer as a library had their logging config silently overwritten at import/construction time. Move configure_logging() to run(), which is the application entrypoint for standalone server processes. Library consumers who instantiate MCPServer directly now keep full control of their logging setup. Fixes #1656 --- src/mcp/server/mcpserver/server.py | 5 ++--- tests/server/mcpserver/test_server.py | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/mcp/server/mcpserver/server.py b/src/mcp/server/mcpserver/server.py index be77705da..32c53489f 100644 --- a/src/mcp/server/mcpserver/server.py +++ b/src/mcp/server/mcpserver/server.py @@ -203,9 +203,6 @@ def __init__( self._token_verifier = ProviderTokenVerifier(auth_server_provider) self._custom_starlette_routes: list[Route] = [] - # Configure logging - configure_logging(self.settings.log_level) - @property def name(self) -> str: return self._lowlevel_server.name @@ -291,6 +288,8 @@ def run( if transport not in TRANSPORTS.__args__: # type: ignore # pragma: no cover raise ValueError(f"Unknown transport: {transport}") + configure_logging(self.settings.log_level) + match transport: case "stdio": anyio.run(self.run_stdio_async) diff --git a/tests/server/mcpserver/test_server.py b/tests/server/mcpserver/test_server.py index 3457ec944..40f16292b 100644 --- a/tests/server/mcpserver/test_server.py +++ b/tests/server/mcpserver/test_server.py @@ -1516,3 +1516,22 @@ async def test_report_progress_passes_related_request_id(): message="halfway", related_request_id="req-abc-123", ) + + +def test_mcpserver_init_does_not_configure_logging() -> None: + """MCPServer.__init__ must not call logging.basicConfig or add handlers. + + Regression test for https://github.com/modelcontextprotocol/python-sdk/issues/1656. + Library code should never configure the root logger — that is the + application's responsibility. + """ + import logging + + root = logging.getLogger() + handlers_before = list(root.handlers) + level_before = root.level + + MCPServer("test-logging") + + assert root.handlers == handlers_before + assert root.level == level_before