@@ -239,6 +239,10 @@ def test_request_body_handling(complex_fastapi_app: FastAPI):
239
239
routes = complex_fastapi_app .routes ,
240
240
)
241
241
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
+
242
246
tools , operation_map = convert_openapi_to_mcp_tools (openapi_schema )
243
247
244
248
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):
251
255
assert "payment_method" in properties
252
256
assert "notes" in properties
253
257
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
+
254
271
required = create_order_tool .inputSchema .get ("required" , [])
255
272
assert "customer_id" in required
256
273
assert "items" in required
@@ -268,6 +285,18 @@ def test_request_body_handling(complex_fastapi_app: FastAPI):
268
285
assert "unit_price" in item_props ["properties" ]
269
286
assert "total" in item_props ["properties" ]
270
287
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
+
271
300
assert "create_order" in operation_map
272
301
assert operation_map ["create_order" ]["path" ] == "/orders"
273
302
assert operation_map ["create_order" ]["method" ] == "post"
@@ -296,3 +325,100 @@ def test_missing_type_handling(complex_fastapi_app: FastAPI):
296
325
297
326
assert "product_id" in get_product_props
298
327
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