def tools(self) -> List[Callable[..., Dict[str, Any]]]:
        """Initialize tool-specific methods based on available tools."""
        tools_response = self.list_tools()



        tools = tools_response.get("available_tools", {}).get("tools", [])

        functions: List[Callable[..., Dict[str, Any]]] = []

        def get_python_type(schema_type: str, format: Optional[str] = None) -> type:
            """Convert JSON schema type to Python type."""
            type_mapping = {
                "string": str,
                "integer": int,
                "boolean": bool,
                "number": float,
                "array": list,
                "object": dict,
            }
            return type_mapping.get(schema_type, Any)

        for tool in tools:
            tool_name: str = tool["name"]
            tool_desc: str = tool.get("description", "")
            input_schema: Dict[str, Any] = tool.get("inputSchema", {})
            properties: Dict[str, Dict[str, Any]] = input_schema.get("properties", {})
            required: List[str] = input_schema.get("required", [])

            def create_tool_function(
                tool_name: str,
                properties: Dict[str, Dict[str, Any]],
                required: List[str],
            ) -> Callable[..., Dict[str, Any]]:
                annotations = {}
                defaults = {}
                parameters = []

                # Build parameters for both required and optional arguments
                for param_name in required:
                    param_info = properties[param_name]
                    param_type = get_python_type(param_info.get("type", "any"))
                    annotations[param_name] = param_type
                    parameters.append(
                        inspect.Parameter(
                            param_name,
                            inspect.Parameter.POSITIONAL_OR_KEYWORD,
                            annotation=param_type
                        )
                    )

                for param_name, param_info in properties.items():
                    if param_name not in required:
                        param_type = get_python_type(param_info.get("type", "any"))
                        annotations[param_name] = param_type
                        default_value = param_info.get("default", None)
                        defaults[param_name] = default_value
                        parameters.append(
                            inspect.Parameter(
                                param_name,
                                inspect.Parameter.POSITIONAL_OR_KEYWORD,
                                default=default_value,
                                annotation=param_type
                            )
                        )

                def tool_function(*args: Any, **kwargs: Any) -> Dict[str, Any]:
                    all_kwargs = kwargs.copy()
                    for i, arg in enumerate(args):
                        if i < len(required):
                            all_kwargs[required[i]] = arg

                    for param, default in defaults.items():
                        if param not in all_kwargs:
                            all_kwargs[param] = default

                    return self.call_tool(tool_name, all_kwargs)

                # Create a signature object and apply it to the function
                sig = inspect.Signature(parameters=parameters, return_annotation=Dict[str, Any])
                tool_function.__signature__ = sig
                tool_function.__name__ = tool_name
                tool_function.__annotations__ = {
                    **annotations,
                    "return": Dict[str, Any],
                }
                tool_function.__doc__ = f"{tool_desc}\n\nReturns:\n    Tool execution results"

                return tool_function


            func = create_tool_function(tool_name, properties, required)
            functions.append(func)

        return functions
Initialize tool-specific methods based on available tools.
src/upsonic/tools_server/function_client.py