Skip to content

fix: configure only mcp namespace logger instead of root logger#2162

Open
giulio-leone wants to merge 2 commits intomodelcontextprotocol:mainfrom
giulio-leone:fix/fastmcp-logging-init
Open

fix: configure only mcp namespace logger instead of root logger#2162
giulio-leone wants to merge 2 commits intomodelcontextprotocol:mainfrom
giulio-leone:fix/fastmcp-logging-init

Conversation

@giulio-leone
Copy link

Summary

Fixes #1656

FastMCP.__init__() calls configure_logging() which previously called logging.basicConfig(), configuring the root logger with handlers and level. This violates Python logging best practices:

It is strongly advised that you do not add any handlers other than NullHandler to your library's loggers. This is because the configuration of handlers is the prerogative of the application developer.
Python Logging HOWTO

Problem

Any application using the MCP SDK that calls FastMCP() gets its logging configuration silently overridden:

  • Custom log formats are replaced
  • Log levels are changed
  • Handlers (e.g., file handlers, structured JSON logging) are affected
  • Unit test log capture can break

Fix

Replace logging.basicConfig() with targeted configuration of the mcp namespace logger only:

  • logging.getLogger('mcp') is configured with handlers and level
  • The root logger is left untouched
  • Duplicate handler guards prevent stacking on repeated FastMCP() calls
  • MCP SDK logs still work out of the box for quickstart scripts

Test Results

475 server tests pass (2 consecutive clean runs).

giulio-leone and others added 2 commits February 28, 2026 04:37
When using transport='stdio', the server wraps sys.stdin.buffer and
sys.stdout.buffer in TextIOWrapper and anyio.AsyncFile. When these
wrappers are garbage collected after the server exits, they close
the underlying sys.stdin/sys.stdout, causing subsequent I/O
operations to fail with ValueError.

Use os.dup() to duplicate the file descriptors before wrapping them,
so closing the wrapped streams only closes the duplicates, leaving
the original stdin/stdout intact.

Fixes modelcontextprotocol#1933

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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 modelcontextprotocol#1656

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FastMCP configures logging on init, which messes up application-level logging

1 participant