@@ -180,6 +180,34 @@ def _generate_mcp_server_code(self, _code, params, name=None, description=None,
180180 # 如果某个参数没有默认值,需要添加 None 占位
181181 defaults .append (ast .Constant (value = None ))
182182 node .args .defaults = defaults
183+ # 将不支持 JSON Schema 的参数类型注解替换为 Any,
184+ # 避免 FastMCP/Pydantic 生成 schema 时崩溃(如 requests.Response)
185+ _safe_annotation_names = {
186+ 'str' , 'int' , 'float' , 'bool' , 'dict' , 'list' , 'tuple' ,
187+ 'set' , 'bytes' , 'Any' , 'Optional' , 'Union' , 'List' ,
188+ 'Dict' , 'Tuple' , 'Set' , 'Sequence' , 'None' , 'NoneType' ,
189+ }
190+
191+ def _is_safe_annotation (node_ann ):
192+ if node_ann is None :
193+ return True
194+ if isinstance (node_ann , ast .Constant ):
195+ return True
196+ if isinstance (node_ann , ast .Name ):
197+ return node_ann .id in _safe_annotation_names
198+ if isinstance (node_ann , ast .Attribute ):
199+ # e.g. requests.Response, typing.Optional — treat none as safe
200+ return False
201+ if isinstance (node_ann , (ast .Subscript , ast .BinOp )):
202+ # e.g. Optional[str], str | None — recurse
203+ if isinstance (node_ann , ast .Subscript ):
204+ return _is_safe_annotation (node_ann .value ) and _is_safe_annotation (node_ann .slice )
205+ return _is_safe_annotation (node_ann .left ) and _is_safe_annotation (node_ann .right )
206+ return False
207+
208+ for arg in node .args .args :
209+ if not _is_safe_annotation (arg .annotation ):
210+ arg .annotation = ast .Name (id = 'Any' , ctx = ast .Load ())
183211 # 修改返回类型注解为 Result
184212 node .returns = ast .Name (id = 'Result' , ctx = ast .Load ())
185213 # 修改 return 语句为 return Result(result=..., tool_id=...)
0 commit comments