16
16
17
17
logger = getLogger (__name__ )
18
18
19
- FULL_TOOL_NAME_MAX_LENGTH = 55
20
-
21
19
22
20
class FastApiMCP :
23
21
def __init__ (
@@ -33,6 +31,7 @@ def __init__(
33
31
exclude_operations : Optional [List [str ]] = None ,
34
32
include_tags : Optional [List [str ]] = None ,
35
33
exclude_tags : Optional [List [str ]] = None ,
34
+ max_tool_name_length : Optional [int ] = None ,
36
35
):
37
36
"""
38
37
Create an MCP server from a FastAPI app.
@@ -52,6 +51,8 @@ def __init__(
52
51
exclude_operations: List of operation IDs to exclude from MCP tools. Cannot be used with include_operations.
53
52
include_tags: List of tags to include as MCP tools. Cannot be used with exclude_tags.
54
53
exclude_tags: List of tags to exclude from MCP tools. Cannot be used with include_tags.
54
+ max_tool_name_length: Maximum length allowed for tools (some vendors prohibit long names).
55
+ Tools breaching this restriction will be filtered out.
55
56
"""
56
57
# Validate operation and tag filtering options
57
58
if include_operations is not None and exclude_operations is not None :
@@ -75,6 +76,7 @@ def __init__(
75
76
self ._exclude_operations = exclude_operations
76
77
self ._include_tags = include_tags
77
78
self ._exclude_tags = exclude_tags
79
+ self ._max_tool_name_length = max_tool_name_length
78
80
79
81
self ._http_client = http_client or httpx .AsyncClient ()
80
82
@@ -323,6 +325,7 @@ def _filter_tools(self, tools: List[types.Tool], openapi_schema: Dict[str, Any])
323
325
and self ._exclude_operations is None
324
326
and self ._include_tags is None
325
327
and self ._exclude_tags is None
328
+ and self ._max_tool_name_length is None
326
329
):
327
330
return tools
328
331
@@ -340,23 +343,6 @@ def _filter_tools(self, tools: List[types.Tool], openapi_schema: Dict[str, Any])
340
343
)
341
344
continue
342
345
343
- operation_full_name = self .get_tool_full_name (operation_id )
344
- if len (operation_full_name ) > FULL_TOOL_NAME_MAX_LENGTH :
345
- logger .warning (f"Skipping operation with exceedingly long operationId: { operation_full_name } " )
346
- continue
347
-
348
- """
349
- if method not in ["get", "post", "put", "delete", "patch"]:
350
- logger.warning(f"Skipping non-HTTP method: {method.upper()} {path}")
351
- continue
352
-
353
- # Get operation metadata
354
- operation_id = operation.get("operationId")
355
- if not operation_id:
356
- logger.warning(f"Skipping operation with no operationId: {method.upper()} {path}, details: {operation}")
357
- continue
358
- """
359
-
360
346
tags = operation .get ("tags" , [])
361
347
for tag in tags :
362
348
if tag not in operations_by_tag :
@@ -365,11 +351,14 @@ def _filter_tools(self, tools: List[types.Tool], openapi_schema: Dict[str, Any])
365
351
366
352
operations_to_include = set ()
367
353
354
+ all_operations = {tool .name for tool in tools }
355
+
368
356
if self ._include_operations is not None :
369
357
operations_to_include .update (self ._include_operations )
370
358
elif self ._exclude_operations is not None :
371
- all_operations = {tool .name for tool in tools }
372
359
operations_to_include .update (all_operations - set (self ._exclude_operations ))
360
+ elif self ._max_tool_name_length is not None :
361
+ operations_to_include .update (all_operations ) # all_operations
373
362
374
363
if self ._include_tags is not None :
375
364
for tag in self ._include_tags :
@@ -379,9 +368,14 @@ def _filter_tools(self, tools: List[types.Tool], openapi_schema: Dict[str, Any])
379
368
for tag in self ._exclude_tags :
380
369
excluded_operations .update (operations_by_tag .get (tag , []))
381
370
382
- all_operations = {tool .name for tool in tools }
383
371
operations_to_include .update (all_operations - excluded_operations )
384
372
373
+ if self ._max_tool_name_length is not None :
374
+ long_operations = {
375
+ tool .name for tool in tools if len (self .get_combined_full_name (tool .name )) > self ._max_tool_name_length
376
+ }
377
+ operations_to_include = operations_to_include - long_operations
378
+
385
379
filtered_tools = [tool for tool in tools if tool .name in operations_to_include ]
386
380
387
381
if filtered_tools :
@@ -392,5 +386,17 @@ def _filter_tools(self, tools: List[types.Tool], openapi_schema: Dict[str, Any])
392
386
393
387
return filtered_tools
394
388
395
- def get_tool_full_name (self , operation_id : str ) -> str :
389
+ def get_combined_full_name (self , operation_id : str ) -> str :
390
+ """
391
+ Combined name consists of server name + operation_id
392
+
393
+ Args:
394
+ operation_id: As defined during creation
395
+
396
+ Returns:
397
+ concatenated string of server name + operation_id
398
+ """
399
+ if not self .name :
400
+ return operation_id
401
+
396
402
return f"{ self .name } \\ { operation_id } "
0 commit comments