Skip to content

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

Description

@pfaion

Initial Checks

Description

Hi everyone, thanks for maintaining the Python SDK for MCP!

I've noticed that the FastMCP class configures the logging ecosystem on __init__(), both by adding custom handlers and calling logging.basicConfig(...). This will conflict with any logging setup that any application using the MCP SDK will use.

Please note that the best practice for logging is:

  • library code should never configure logging behavior
  • application entrypoints should configure logging behavior

Please refer to the official logging HowTo, section "Configuring Logging for a Library":

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 who uses your library. The application developer knows their target audience and what handlers are most appropriate for their application: if you add handlers ‘under the hood’, you might well interfere with their ability to carry out unit tests and deliver logs which suit their requirements.

For the sake of easy quickstarts, I'd advice to create some module specifically meant for quickstarts that runs a FastMCP server, taking care of setting up the rich logging as well before. But keep it separated from the main library usage of FastMCP server, so applications using it don't get their logging config messed up.

Example Code

Python & MCP Python SDK

1.22.0

Activity

  1. added
    bugSomething isn't working
    ready for workEnough information for someone to start working on
    P2Moderate issues affecting some users, edge cases, potentially valuable feature
    on Dec 2, 2025
  2. omar-y-abdi commented on Mar 12, 2026

    @omar-y-abdi

    I have a fix for this — PR incoming. The change moves configure_logging() from MCPServer.__init__() to MCPServer.run(), so instantiation no longer touches the root logger. Only the run() entrypoint configures logging.

  3. pfaion commented on Mar 16, 2026

    @pfaion
    Author

    Please note that no parts of the library should run configure_logging(). The MCPServer class is part of the library, so none of it's methods should configure the logging.

    If you want people to be able to quickly start an MCP server for exploring/learning, add a project script to the library that calls configure_logging(). This is the right approach to do this.

    E.g. add a module cli.py with a def run() function, where you:

    1. configure_logging()
    2. create a server
    3. run the server

    That way people can call this to experiment, or copy it for quickstart, but no library user instantiating and running an MCPServer object would be forced to use this logging config.

  4. lacebal commented on Apr 24, 2026

    @lacebal

    We are facing the same problem and I have seen many open issues reported but no solution (that's ok, this is Open Source so a best effort), but the worst of all is that there seems to not be any plan or roadmap to tackle this basic usage hinderance on library from an official "Open" protocol. This looks ridiculous.

    Is there any plan to work on that or would you just accept any vibe coded changing logging initialization to follow best practices as pointed out?

  5. pfaion commented on Apr 27, 2026

    @pfaion
    Author

    For anyone coming across this, you can work around these types of issue by using logging.basicConfig(..., force=True) in your application entrypoint after creating the FastMCP server. This will remove and close any existing handlers attached to the root logger.

    If you are using a more elaborate manual logging config you will have to manually remove all existing handlers before setting up your own logging pipeline.

  6. pfaion commented on Apr 27, 2026

    @pfaion
    Author

    For people willing to engage with the maintainers to try and fix this: If I'd be maintaining this library, I'd want to make sure that all of the examples referenced in the README still have reasonable logs when running them in a CLI. You might have to specifically call logging.basicConfig() for these types of entrypoints. I don't think just removing the call from FastMCP.__init__ is necessarily a good fix.

  7. Hackerchen716 commented on May 29, 2026

    @Hackerchen716

    I initially considered working on this, but after re-checking the issue I noticed active linked PRs already cover this area. I will not open a duplicate PR here.

  8. m-u-xyz commented on Jun 16, 2026

    @m-u-xyz

    While PR #2532 waits for whatever it is it's waiting for, here's a monkey-patchy workaround:

    import logging
    from typing import cast
    
    ... # configure your own logging here -- before importing, well, anything else really
    
    def _no_config(*_a: Any, **_k: Any) -> None:
        import warnings  # noqa: PLC0415
    
        warnings.warn("Call to logging config ignored", stacklevel=2)
    
    logging.basicConfig = cast(Any, _no_config)
    logging.config.dictConfig = cast(Any, _no_config)
    logging.config.fileConfig = cast(Any, _no_config)
    
  9. m-u-xyz commented on Oct 5, 2026

    @m-u-xyz

    Sigh PR #2532 was closed without resolving it.

    Dear authors: please don't do that. IMHO, calling logging.basicConfig unconditionally, when you're not __main__, is disruptive and anti-social. I'm setting up my logging before importing things, because that's how I can catch import errors and whatnot. You're forcing me to do it all over again, possibly losing important information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Moderate issues affecting some users, edge cases, potentially valuable featurebugSomething isn't workingready for workEnough information for someone to start working on

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions