4444 AssistantQueryInput , AssistantPostInput , InputType , EmbeddingsInput , \
4545 semantic_search_system_prompt , \
4646 SemanticSearchInput , EmbeddingsStoreOutput
47- from .mcp import MCPToolTrigger , _TYPE_MAPPING
47+ from .mcp import MCPToolTrigger , _TYPE_MAPPING , check_property_type , check_is_array , check_is_required
4848from .retry_policy import RetryPolicy
4949from .function_name import FunctionName
5050from .warmup import WarmUpTrigger
5555 MySqlTrigger
5656
5757
58+ logger = logging .getLogger ('azure.functions.WsgiMiddleware' )
59+
5860class Function (object ):
5961 """
6062 The function object represents a function in Function App. It
@@ -1588,6 +1590,11 @@ def mcp_tool(self):
15881590 def decorator (fb : FunctionBuilder ) -> FunctionBuilder :
15891591 target_func = fb ._function .get_user_function ()
15901592 sig = inspect .signature (target_func )
1593+
1594+ # Pull any explicitly declared MCP tool properties
1595+ explicit_properties = getattr (target_func , "__mcp_tool_properties__" , {})
1596+ logger .info (f"Explicit MCP tool properties: { explicit_properties } " )
1597+
15911598 # Parse tool name and description from function signature
15921599 tool_name = target_func .__name__
15931600 description = (target_func .__doc__ or "" ).strip ().split ("\n " )[0 ]
@@ -1602,15 +1609,29 @@ def decorator(fb: FunctionBuilder) -> FunctionBuilder:
16021609 if param_name in skip_param_names :
16031610 continue
16041611 param_type_hint = param .annotation if param .annotation != inspect .Parameter .empty else str # noqa
1605- # Parse type and description from type hint
1606- actual_type = param_type_hint
1607- if actual_type is MCPToolContext :
1612+
1613+ if param_type_hint is MCPToolContext :
16081614 continue
1609- property_type = _TYPE_MAPPING .get (actual_type , "string" )
1615+
1616+ # Check if explicit metadata exists for this param
1617+ if param_name in explicit_properties :
1618+ logger .info (f"Using explicit MCP tool property for param: { param_name } " ) # noqa
1619+ prop = explicit_properties [param_name ].copy ()
1620+ prop ["propertyName" ] = param_name
1621+ tool_properties .append (prop )
1622+ continue
1623+
1624+ # Otherwise infer it
1625+ is_required = check_is_required (param , param_type_hint )
1626+ is_array = check_is_array (param_type_hint )
1627+ property_type = check_property_type (param_type_hint , is_array )
1628+
16101629 tool_properties .append ({
16111630 "propertyName" : param_name ,
16121631 "propertyType" : property_type ,
16131632 "description" : "" ,
1633+ "isArray" : is_array ,
1634+ "isRequired" : is_required
16141635 })
16151636
16161637 tool_properties_json = json .dumps (tool_properties )
@@ -1660,6 +1681,40 @@ async def wrapper(context: str, *args, **kwargs):
16601681
16611682 return decorator
16621683
1684+ def mcp_tool_property (self , arg_name : str ,
1685+ description : Optional [str ] = "" ,
1686+ property_type : Optional [str ] = None ,
1687+ is_required : Optional [bool ] = True ,
1688+ is_array : Optional [bool ] = False ):
1689+ """
1690+ Decorator for defining explicit MCP tool property metadata for a specific argument.
1691+
1692+ Example:
1693+ @app.mcp_tool_property(
1694+ arg_name="snippetname",
1695+ description="The name of the snippet.",
1696+ property_type="string",
1697+ is_required=True,
1698+ is_array=False
1699+ )
1700+ """
1701+ def decorator (func ):
1702+ # If this function is already wrapped by FunctionBuilder or similar, unwrap it
1703+ target_func = getattr (func , "_function" , func )
1704+ target_func = getattr (target_func , "_func" , target_func )
1705+
1706+ existing = getattr (target_func , "__mcp_tool_properties__" , {})
1707+ existing [arg_name ] = {
1708+ "description" : description or "" ,
1709+ "propertyType" : property_type or "string" ,
1710+ "isRequired" : is_required ,
1711+ "isArray" : is_array ,
1712+ }
1713+ setattr (target_func , "__mcp_tool_properties__" , existing )
1714+ return func
1715+ return decorator
1716+
1717+
16631718 def dapr_service_invocation_trigger (self ,
16641719 arg_name : str ,
16651720 method_name : str ,
0 commit comments