[文档]defprocess_parameter(name:str,param:inspect.Parameter)->inspect.Parameter:""" Processes a function parameter: - Converts jsonargparse.typing.ClosedUnitInterval to a local equivalent annotation. """ClosedUnitInterval=Annotated[float,Field(ge=0.0,le=1.0,description="float restricted to be ≥0 and ≤1")]ifparam.annotation==getattr(sys.modules.get("jsonargparse.typing"),"ClosedUnitInterval",None):returnparam.replace(annotation=ClosedUnitInterval)returnparam
[文档]defcreate_operator_function(op,mcp):"""Creates a callable function for a Data-Juicer operator class. This function dynamically creates a function that can be registered as an MCP tool, with proper signature and documentation based on the operator's __init__ method. """sig=op["signature"]docstring=op["description"]param_docstring=op["param_desc"]# Create new function signature with dataset_path as first parameter# Consider adding other common parameters later, such as export_psthnew_parameters=[inspect.Parameter("dataset_path",inspect.Parameter.POSITIONAL_OR_KEYWORD,annotation=str),inspect.Parameter("export_path",inspect.Parameter.POSITIONAL_OR_KEYWORD,annotation=Optional[str],default=None,),inspect.Parameter("np",inspect.Parameter.POSITIONAL_OR_KEYWORD,annotation=Optional[int],default=None,),]+[process_parameter(name,param)forname,paraminsig.parameters.items()ifnamenotin("args","kwargs","self")]new_signature=sig.replace(parameters=new_parameters,return_annotation=str)deffunc(*args,**kwargs):args_dict={}bound_arguments=new_signature.bind(*args,**kwargs)bound_arguments.apply_defaults()export_path=bound_arguments.arguments.pop("export_path")dataset_path=bound_arguments.arguments.pop("dataset_path")np=bound_arguments.arguments.pop("np")args_dict={k:vfork,vinbound_arguments.arguments.items()ifv}dj_cfg={"dataset_path":dataset_path,"export_path":export_path,"process":[{op["name"]:args_dict}],"np":np,}returnexecute_op(dj_cfg)func.__signature__=new_signaturefunc.__doc__=f"""{docstring}\n\n{param_docstring}\n"""func.__name__=op["name"]decorated_func=mcp.tool()(func)returndecorated_func
[文档]defcreate_mcp_server(port:str="8000"):""" Creates the FastMCP server and registers the tools. Args: port (str, optional): Port number. Defaults to "8000". """mcp=FastMCP("Data-Juicer Server",port=port)# Operator Managementops_list_path=os.getenv("DJ_OPS_LIST_PATH",None)ifops_list_path:withopen(ops_list_path,"r",encoding="utf-8")asfile:ops_list=[line.strip()forlineinfileifline.strip()]else:ops_list=Nonesearcher=OPSearcher(ops_list)op_results=searcher.search()# Register all operators as MCP toolsforopinop_results:_=create_operator_function(op,mcp)returnmcp
if__name__=="__main__":parser=argparse.ArgumentParser(description="Data-Juicer MCP Server")parser.add_argument("--port",type=str,default="8000",help="Port number for the MCP server")# changed to str for consistencyargs=parser.parse_args()# Server configurationmcp=create_mcp_server(port=args.port)mcp.run(transport=os.getenv("SERVER_TRANSPORT","sse"))