From 33bfe60fb0ca7a96b17de2d96de2f17f1305acb2 Mon Sep 17 00:00:00 2001 From: Rifa Ferzana <78103780+Rifa-111@users.noreply.github.com> Date: Sat, 27 Jun 2026 18:06:09 +0100 Subject: [PATCH] Offload sync function calls to a thread Offload synchronous function calls to a thread to prevent blocking the event loop. This change ensures that context is correctly propagated using anyio's run_sync. --- src/mcp/server/fastmcp/utilities/func_metadata.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mcp/server/fastmcp/utilities/func_metadata.py b/src/mcp/server/fastmcp/utilities/func_metadata.py index 241100d317..7352b7fe52 100644 --- a/src/mcp/server/fastmcp/utilities/func_metadata.py +++ b/src/mcp/server/fastmcp/utilities/func_metadata.py @@ -93,7 +93,11 @@ async def call_fn_with_arg_validation( if fn_is_async: return await fn(**arguments_parsed_dict) else: - return fn(**arguments_parsed_dict) + return await anyio.to_thread.run_sync(lambda: fn(**arguments_parsed_dict)) + # Sync functions are offloaded to a thread to avoid blocking the event loop. + # anyio.to_thread.run_sync() uses copy_context() internally, so contextvars + # propagate correctly. Context is passed explicitly via arguments_parsed_dict, + # not through contextvars, so it is unaffected. def convert_result(self, result: Any) -> Any: """