|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
3 | | -import functools |
4 | | -import inspect |
5 | 3 | from collections.abc import Callable |
6 | 4 | from functools import cached_property |
7 | 5 | from typing import TYPE_CHECKING, Any |
|
11 | 9 | from mcp.server.mcpserver.exceptions import ToolError |
12 | 10 | from mcp.server.mcpserver.utilities.context_injection import find_context_parameter |
13 | 11 | from mcp.server.mcpserver.utilities.func_metadata import FuncMetadata, func_metadata |
| 12 | +from mcp.shared._callable_inspection import is_async_callable |
14 | 13 | from mcp.shared.exceptions import UrlElicitationRequiredError |
15 | 14 | from mcp.shared.tool_name_validation import validate_and_warn_tool_name |
16 | 15 | from mcp.types import Icon, ToolAnnotations |
@@ -63,7 +62,7 @@ def from_function( |
63 | 62 | raise ValueError("You must provide a name for lambda functions") |
64 | 63 |
|
65 | 64 | func_doc = description or fn.__doc__ or "" |
66 | | - is_async = _is_async_callable(fn) |
| 65 | + is_async = is_async_callable(fn) |
67 | 66 |
|
68 | 67 | if context_kwarg is None: # pragma: no branch |
69 | 68 | context_kwarg = find_context_parameter(fn) |
@@ -118,12 +117,3 @@ async def run( |
118 | 117 | raise |
119 | 118 | except Exception as e: |
120 | 119 | raise ToolError(f"Error executing tool {self.name}: {e}") from e |
121 | | - |
122 | | - |
123 | | -def _is_async_callable(obj: Any) -> bool: |
124 | | - while isinstance(obj, functools.partial): # pragma: lax no cover |
125 | | - obj = obj.func |
126 | | - |
127 | | - return inspect.iscoroutinefunction(obj) or ( |
128 | | - callable(obj) and inspect.iscoroutinefunction(getattr(obj, "__call__", None)) |
129 | | - ) |
0 commit comments