Skip to content

Sync tool functions fail with Windows COM (CoInitialize not called) due to thread pool execution #4003

@miloira

Description

@miloira

Enhancement

Title: Sync tool functions fail with Windows COM (CoInitialize not called) due to thread pool execution

Description:

When a sync (non-async) tool function uses Windows COM-based libraries (e.g. uiautomation, comtypes, pywinauto), it fails with:

[WinError -2147221008] CoInitialize has not been called.

Root Cause:

FastMCP dispatches sync tool functions to a worker thread (likely via anyio.to_thread.run_sync or loop.run_in_executor). These worker threads don't have COM initialized, which breaks any tool that relies on Windows COM APIs.

In contrast, the official mcp SDK (mcp.server.fastmcp) calls sync functions directly in the event loop thread (return fn(**args)), so COM state is inherited from the main thread and everything works fine.

Minimal Reproduction:

from fastmcp import FastMCP
import uiautomation as auto

mcp = FastMCP("test")

@mcp.tool()
def list_windows() -> str:
    """List desktop windows via UI Automation (COM-based)."""
    desktop = auto.GetRootControl()
    return str([w.Name for w in desktop.GetChildren()[:5]])

if __name__ == "__main__":
    mcp.run(transport="stdio")

Calling list_windows produces:

[WinError -2147221008] CoInitialize has not been called.

Current Workaround:

Manually call ctypes.windll.ole32.CoInitialize(None) at the start of every sync tool function.

Proposed Solution (any of):

  1. Call CoInitialize/CoUninitialize automatically on worker threads (Windows only).
  2. Provide an option to run sync tools on the main thread (like the official mcp SDK does), e.g.:
    @mcp.tool(run_in_thread=False)
    def my_com_tool(): ...
  3. Provide a server-level setting:
    mcp = FastMCP("test", sync_tool_runner="main_thread")  # or "thread_pool"

Environment:

  • OS: Windows 10/11
  • Python: 3.12+
  • fastmcp: 3.x
  • Affected libraries: uiautomation, comtypes, or any COM-dependent library

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementImprovement to existing functionality. For issues and smaller PR improvements.serverRelated to FastMCP server implementation or server-side functionality.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions