@@ -239,6 +239,10 @@ def test_request_body_handling(complex_fastapi_app: FastAPI):
239239 routes = complex_fastapi_app .routes ,
240240 )
241241
242+ create_order_route = openapi_schema ["paths" ]["/orders" ]["post" ]
243+ original_request_body = create_order_route ["requestBody" ]["content" ]["application/json" ]["schema" ]
244+ original_properties = original_request_body .get ("properties" , {})
245+
242246 tools , operation_map = convert_openapi_to_mcp_tools (openapi_schema )
243247
244248 create_order_tool = next (tool for tool in tools if tool .name == "create_order" )
@@ -251,6 +255,19 @@ def test_request_body_handling(complex_fastapi_app: FastAPI):
251255 assert "payment_method" in properties
252256 assert "notes" in properties
253257
258+ for param_name in ["customer_id" , "items" , "shipping_address_id" , "payment_method" , "notes" ]:
259+ if "description" in original_properties .get (param_name , {}):
260+ assert "description" in properties [param_name ]
261+ assert properties [param_name ]["description" ] == original_properties [param_name ]["description" ]
262+
263+ for param_name in ["customer_id" , "items" , "shipping_address_id" , "payment_method" , "notes" ]:
264+ assert properties [param_name ]["title" ] == param_name
265+
266+ for param_name in ["customer_id" , "items" , "shipping_address_id" , "payment_method" , "notes" ]:
267+ if "default" in original_properties .get (param_name , {}):
268+ assert "default" in properties [param_name ]
269+ assert properties [param_name ]["default" ] == original_properties [param_name ]["default" ]
270+
254271 required = create_order_tool .inputSchema .get ("required" , [])
255272 assert "customer_id" in required
256273 assert "items" in required
@@ -268,6 +285,18 @@ def test_request_body_handling(complex_fastapi_app: FastAPI):
268285 assert "unit_price" in item_props ["properties" ]
269286 assert "total" in item_props ["properties" ]
270287
288+ for nested_param in ["product_id" , "quantity" , "unit_price" , "total" ]:
289+ assert "title" in item_props ["properties" ][nested_param ]
290+
291+ # Check if the original nested schema had descriptions
292+ original_item_schema = original_properties .get ("items" , {}).get ("items" , {}).get ("properties" , {})
293+ if "description" in original_item_schema .get (nested_param , {}):
294+ assert "description" in item_props ["properties" ][nested_param ]
295+ assert (
296+ item_props ["properties" ][nested_param ]["description" ]
297+ == original_item_schema [nested_param ]["description" ]
298+ )
299+
271300 assert "create_order" in operation_map
272301 assert operation_map ["create_order" ]["path" ] == "/orders"
273302 assert operation_map ["create_order" ]["method" ] == "post"
@@ -296,3 +325,100 @@ def test_missing_type_handling(complex_fastapi_app: FastAPI):
296325
297326 assert "product_id" in get_product_props
298327 assert get_product_props ["product_id" ].get ("type" ) == "string" # Default type applied
328+
329+
330+ def test_body_params_descriptions_and_defaults (complex_fastapi_app : FastAPI ):
331+ """
332+ Test that descriptions and defaults from request body parameters
333+ are properly transferred to the MCP tool schema properties.
334+ """
335+ openapi_schema = get_openapi (
336+ title = complex_fastapi_app .title ,
337+ version = complex_fastapi_app .version ,
338+ openapi_version = complex_fastapi_app .openapi_version ,
339+ description = complex_fastapi_app .description ,
340+ routes = complex_fastapi_app .routes ,
341+ )
342+
343+ order_request_schema = openapi_schema ["components" ]["schemas" ]["OrderRequest" ]
344+
345+ order_request_schema ["properties" ]["customer_id" ]["description" ] = "Test customer ID description"
346+ order_request_schema ["properties" ]["payment_method" ]["description" ] = "Test payment method description"
347+ order_request_schema ["properties" ]["notes" ]["default" ] = "Default order notes"
348+
349+ item_schema = openapi_schema ["components" ]["schemas" ]["OrderItem" ]
350+ item_schema ["properties" ]["product_id" ]["description" ] = "Test product ID description"
351+ item_schema ["properties" ]["quantity" ]["default" ] = 1
352+
353+ tools , _ = convert_openapi_to_mcp_tools (openapi_schema )
354+
355+ create_order_tool = next (tool for tool in tools if tool .name == "create_order" )
356+ properties = create_order_tool .inputSchema ["properties" ]
357+
358+ assert "description" in properties ["customer_id" ]
359+ assert properties ["customer_id" ]["description" ] == "Test customer ID description"
360+
361+ assert "description" in properties ["payment_method" ]
362+ assert properties ["payment_method" ]["description" ] == "Test payment method description"
363+
364+ assert "default" in properties ["notes" ]
365+ assert properties ["notes" ]["default" ] == "Default order notes"
366+
367+ if "items" in properties :
368+ assert properties ["items" ]["type" ] == "array"
369+ assert "items" in properties ["items" ]
370+
371+ item_props = properties ["items" ]["items" ]["properties" ]
372+
373+ assert "description" in item_props ["product_id" ]
374+ assert item_props ["product_id" ]["description" ] == "Test product ID description"
375+
376+ assert "default" in item_props ["quantity" ]
377+ assert item_props ["quantity" ]["default" ] == 1
378+
379+
380+ def test_body_params_edge_cases (complex_fastapi_app : FastAPI ):
381+ """
382+ Test handling of edge cases for body parameters, such as:
383+ - Empty or missing descriptions
384+ - Missing type information
385+ - Empty properties object
386+ - Schema without properties
387+ """
388+ openapi_schema = get_openapi (
389+ title = complex_fastapi_app .title ,
390+ version = complex_fastapi_app .version ,
391+ openapi_version = complex_fastapi_app .openapi_version ,
392+ description = complex_fastapi_app .description ,
393+ routes = complex_fastapi_app .routes ,
394+ )
395+
396+ order_request_schema = openapi_schema ["components" ]["schemas" ]["OrderRequest" ]
397+
398+ if "description" in order_request_schema ["properties" ]["customer_id" ]:
399+ del order_request_schema ["properties" ]["customer_id" ]["description" ]
400+
401+ if "type" in order_request_schema ["properties" ]["notes" ]:
402+ del order_request_schema ["properties" ]["notes" ]["type" ]
403+
404+ item_schema = openapi_schema ["components" ]["schemas" ]["OrderItem" ]
405+
406+ if "properties" in item_schema ["properties" ]["total" ]:
407+ del item_schema ["properties" ]["total" ]["properties" ]
408+
409+ tools , _ = convert_openapi_to_mcp_tools (openapi_schema )
410+
411+ create_order_tool = next (tool for tool in tools if tool .name == "create_order" )
412+ properties = create_order_tool .inputSchema ["properties" ]
413+
414+ assert "customer_id" in properties
415+ assert "title" in properties ["customer_id" ]
416+ assert properties ["customer_id" ]["title" ] == "customer_id"
417+
418+ assert "notes" in properties
419+ assert "type" in properties ["notes" ]
420+ assert properties ["notes" ]["type" ] in ["string" , "object" ] # Default should be either string or object
421+
422+ if "items" in properties :
423+ item_props = properties ["items" ]["items" ]["properties" ]
424+ assert "total" in item_props
0 commit comments