Skip to content

Commit c483055

Browse files
committed
Don't block the event loop on non-async functions
1 parent dcc9b4f commit c483055

File tree

1 file changed

+6
-12
lines changed

1 file changed

+6
-12
lines changed

src/mcp/server/fastmcp/utilities/func_metadata.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
1+
import functools
12
import inspect
23
import json
34
from collections.abc import Awaitable, Callable, Sequence
45
from itertools import chain
56
from types import GenericAlias
67
from typing import Annotated, Any, cast, get_args, get_origin, get_type_hints
78

9+
import anyio
10+
import anyio.to_thread
811
import pydantic_core
9-
from pydantic import (
10-
BaseModel,
11-
ConfigDict,
12-
Field,
13-
RootModel,
14-
WithJsonSchema,
15-
create_model,
16-
)
12+
from pydantic import BaseModel, ConfigDict, Field, RootModel, WithJsonSchema, create_model
1713
from pydantic.fields import FieldInfo
1814
from pydantic.json_schema import GenerateJsonSchema, JsonSchemaWarningKind
1915
from typing_extensions import is_typeddict
@@ -60,9 +56,7 @@ def model_dump_one_level(self) -> dict[str, Any]:
6056
kwargs[output_name] = value
6157
return kwargs
6258

63-
model_config = ConfigDict(
64-
arbitrary_types_allowed=True,
65-
)
59+
model_config = ConfigDict(arbitrary_types_allowed=True)
6660

6761

6862
class FuncMetadata(BaseModel):
@@ -92,7 +86,7 @@ async def call_fn_with_arg_validation(
9286
if fn_is_async:
9387
return await fn(**arguments_parsed_dict)
9488
else:
95-
return fn(**arguments_parsed_dict)
89+
return await anyio.to_thread.run_sync(functools.partial(fn, **arguments_parsed_dict))
9690

9791
def convert_result(self, result: Any) -> Any:
9892
"""Convert the result of a function call to the appropriate format for

0 commit comments

Comments
 (0)