From af0b2fa52880a0be48eb2f1e709386b91f1363ec Mon Sep 17 00:00:00 2001 From: Jeremiah Lowin <153965+jlowin@users.noreply.github.com> Date: Sat, 27 Sep 2025 12:04:19 -0400 Subject: [PATCH 1/3] Default rich tracebacks to False --- src/fastmcp/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fastmcp/settings.py b/src/fastmcp/settings.py index 95e9f6290..744b7302d 100644 --- a/src/fastmcp/settings.py +++ b/src/fastmcp/settings.py @@ -170,7 +170,7 @@ def normalize_log_level(cls, v): """ ) ), - ] = True + ] = False deprecation_warnings: Annotated[ bool, From 411518e017fe78f98cc0dea68e6e14ed022c26df Mon Sep 17 00:00:00 2001 From: William Easton Date: Fri, 10 Oct 2025 16:39:14 -0400 Subject: [PATCH 2/3] Improve traceback handling for narrow terminals --- src/fastmcp/settings.py | 2 +- src/fastmcp/utilities/logging.py | 36 ++++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/fastmcp/settings.py b/src/fastmcp/settings.py index 744b7302d..95e9f6290 100644 --- a/src/fastmcp/settings.py +++ b/src/fastmcp/settings.py @@ -170,7 +170,7 @@ def normalize_log_level(cls, v): """ ) ), - ] = False + ] = True deprecation_warnings: Annotated[ bool, diff --git a/src/fastmcp/utilities/logging.py b/src/fastmcp/utilities/logging.py index 4d06418df..cc872bf9f 100644 --- a/src/fastmcp/utilities/logging.py +++ b/src/fastmcp/utilities/logging.py @@ -47,25 +47,49 @@ def configure_logging( if logger is None: logger = logging.getLogger("fastmcp") - # Only configure the FastMCP logger namespace + formatter = logging.Formatter("%(message)s") + + # Don't propagate to the root logger + logger.propagate = False + logger.setLevel(level) + + # Configure the handler for normal logs handler = RichHandler( console=Console(stderr=True), rich_tracebacks=enable_rich_tracebacks, **rich_kwargs, ) - formatter = logging.Formatter("%(message)s") handler.setFormatter(formatter) - logger.setLevel(level) + # filter to exclude tracebacks + handler.addFilter(lambda record: record.exc_info is None) + + # Configure the handler for tracebacks, for tracebacks we use a compressed format: + # no path or level name to maximize width available for the traceback + # suppress framework frames and limit the number of frames to 3 + + import mcp + import pydantic + + traceback_handler = RichHandler( + console=Console(stderr=True), + show_path=False, + show_level=False, + rich_tracebacks=enable_rich_tracebacks, + tracebacks_max_frames=3, + tracebacks_suppress=[fastmcp, mcp, pydantic], + **rich_kwargs, + ) + traceback_handler.setFormatter(formatter) + + traceback_handler.addFilter(lambda record: record.exc_info is not None) # Remove any existing handlers to avoid duplicates on reconfiguration for hdlr in logger.handlers[:]: logger.removeHandler(hdlr) logger.addHandler(handler) - - # Don't propagate to the root logger - logger.propagate = False + logger.addHandler(traceback_handler) @contextlib.contextmanager From 710a7632e1b7cd085517357af57458caef33faf7 Mon Sep 17 00:00:00 2001 From: William Easton Date: Fri, 10 Oct 2025 16:48:26 -0400 Subject: [PATCH 3/3] Small pr clean-up --- src/fastmcp/utilities/logging.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fastmcp/utilities/logging.py b/src/fastmcp/utilities/logging.py index cc872bf9f..ec7f47023 100644 --- a/src/fastmcp/utilities/logging.py +++ b/src/fastmcp/utilities/logging.py @@ -56,7 +56,6 @@ def configure_logging( # Configure the handler for normal logs handler = RichHandler( console=Console(stderr=True), - rich_tracebacks=enable_rich_tracebacks, **rich_kwargs, ) handler.setFormatter(formatter)