Skip to content

Commit 76362c3

Browse files
author
g97iulio1609
committed
fix: configure only mcp namespace logger instead of root logger
FastMCP.__init__() calls configure_logging() which previously called logging.basicConfig(), configuring the root logger with handlers and level. This violates Python logging best practices: library code should never configure the root logger, as that is the prerogative of the application developer. Replace logging.basicConfig() with targeted configuration of the 'mcp' namespace logger only. This ensures: - MCP SDK logs still work out of the box for quickstart scripts - Application-level logging configuration is not overridden - No duplicate handlers on repeated FastMCP instantiations References: - https://docs.python.org/3/howto/logging.html#configuring-logging-for-a-library Fixes #1656
1 parent b46ebd6 commit 76362c3

1 file changed

Lines changed: 23 additions & 7 deletions

File tree

src/mcp/server/mcpserver/utilities/logging.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
import logging
44
from typing import Literal
55

6+
# Namespace logger for all MCP SDK logging.
7+
# Per Python logging best practices, library code should only configure
8+
# its own namespace logger, never the root logger.
9+
_MCP_LOGGER_NAME = "mcp"
10+
611

712
def get_logger(name: str) -> logging.Logger:
813
"""Get a logger nested under MCP namespace.
@@ -21,19 +26,30 @@ def configure_logging(
2126
) -> None:
2227
"""Configure logging for MCP.
2328
29+
Configures only the ``mcp`` namespace logger so that application-level
30+
logging configuration is not overridden. Per the Python logging docs,
31+
library code should never call ``logging.basicConfig()`` or add handlers
32+
to the root logger.
33+
2434
Args:
2535
level: The log level to use.
2636
"""
27-
handlers: list[logging.Handler] = []
37+
mcp_logger = logging.getLogger(_MCP_LOGGER_NAME)
38+
mcp_logger.setLevel(level)
39+
40+
# Avoid adding duplicate handlers on repeated calls.
41+
if mcp_logger.handlers:
42+
return
43+
2844
try:
2945
from rich.console import Console
3046
from rich.logging import RichHandler
3147

32-
handlers.append(RichHandler(console=Console(stderr=True), rich_tracebacks=True))
48+
handler: logging.Handler = RichHandler(
49+
console=Console(stderr=True), rich_tracebacks=True
50+
)
3351
except ImportError: # pragma: no cover
34-
pass
35-
36-
if not handlers: # pragma: no cover
37-
handlers.append(logging.StreamHandler())
52+
handler = logging.StreamHandler()
53+
handler.setFormatter(logging.Formatter("%(message)s"))
3854

39-
logging.basicConfig(level=level, format="%(message)s", handlers=handlers)
55+
mcp_logger.addHandler(handler)

0 commit comments

Comments
 (0)