Skip to main content
Glama

simple_cvxpy_solver

Solve CVXPY optimization problems by defining variables, objectives, and constraints in a simplified interface, eliminating the need for complex CVXPYProblem structures.

Instructions

A simpler interface for solving CVXPY optimization problems.

This tool provides a more straightforward interface for CVXPY problems, without requiring the full CVXPYProblem model structure. Args: variables: List of variable definitions, each with 'name' and 'shape' objective_type: Either 'minimize' or 'maximize' objective_expr: The objective function expression as a string constraints: List of constraint expressions as strings parameters: Dictionary of parameter values (e.g., matrices A, b) description: Optional description of the problem Returns: A list of TextContent containing the solution or an error message

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
constraintsYes
descriptionNo
objective_exprYes
objective_typeYes
parametersNo
variablesYes

Implementation Reference

  • The main handler function for the 'simple_cvxpy_solver' MCP tool. It parses the simple input parameters into a CVXPYProblem model and calls the underlying solver.
    @app.tool("simple_cvxpy_solver") async def simple_cvxpy_solver( variables: list[dict[str, Any]], objective_type: str, objective_expr: str, constraints: list[str], parameters: dict[str, Any] | None = None, description: str = "", ) -> list[TextContent]: """A simpler interface for solving CVXPY optimization problems. This tool provides a more straightforward interface for CVXPY problems, without requiring the full CVXPYProblem model structure. Args: variables: List of variable definitions, each with 'name' and 'shape' objective_type: Either 'minimize' or 'maximize' objective_expr: The objective function expression as a string constraints: List of constraint expressions as strings parameters: Dictionary of parameter values (e.g., matrices A, b) description: Optional description of the problem Returns: A list of TextContent containing the solution or an error message """ try: # Convert to Problem model problem_variables = [] for var in variables: if "name" not in var or "shape" not in var: return [ TextContent( type="text", text="Each variable must have 'name' and 'shape' fields", ) ] problem_variables.append(CVXPYVariable(**var)) try: obj_type = ObjectiveType(objective_type) except ValueError: return [ TextContent( type="text", text=( f"Invalid objective type: {objective_type}. " f"Must be one of: {', '.join([t.value for t in ObjectiveType])}" ), ) ] objective = CVXPYObjective(type=obj_type, expression=objective_expr) problem_constraints = [CVXPYConstraint(expression=expr) for expr in constraints] problem = CVXPYProblem( variables=problem_variables, objective=objective, constraints=problem_constraints, parameters=parameters or {}, description=description, ) # Solve the problem result = solve_cvxpy_problem(problem) match result: case Success(solution): return [ TextContent( type="text", text=json.dumps( { "values": { k: v.tolist() if hasattr(v, "tolist") else v for k, v in solution.values.items() }, "objective_value": solution.objective_value, "status": solution.status, "dual_values": { k: v.tolist() if hasattr(v, "tolist") else v for k, v in (solution.dual_values or {}).items() }, } ), ) ] case Failure(error): return [ TextContent(type="text", text=f"Error solving problem: {error}") ] case _: return [ TextContent( type="text", text="Unexpected error in simple_cvxpy_solver", ) ] except Exception as e: return [TextContent(type="text", text=f"Error in simple_cvxpy_solver: {e!s}")]
  • FastMCP tool registration decorator for 'simple_cvxpy_solver'.
    @app.tool("simple_cvxpy_solver")
  • Pydantic schemas defining the CVXPY problem structure used internally by the simple_cvxpy_solver handler.
    class ObjectiveType(str, Enum): """Enum for objective types in CVXPY.""" MINIMIZE = "minimize" MAXIMIZE = "maximize" class CVXPYVariable(BaseModel): """Model representing a CVXPY variable.""" name: str shape: int | tuple[int, ...] # Can be scalar (int) or vector/matrix (tuple) class CVXPYConstraint(BaseModel): """Model representing a CVXPY constraint.""" expression: str # String representation of the constraint description: str = "" class CVXPYObjective(BaseModel): """Model representing a CVXPY objective.""" type: ObjectiveType expression: str # String representation of the objective function class CVXPYProblem(BaseModel): """Model representing a complete CVXPY optimization problem.""" variables: list[CVXPYVariable] objective: CVXPYObjective constraints: list[CVXPYConstraint] parameters: dict[str, Any] = {} # For A, b, etc. description: str = "" class CVXPYSolution(BaseModel): """Model representing a solution to a CVXPY problem.""" values: dict[str, Any] # Variable values objective_value: float | None status: str dual_values: dict[int, Any] | None = None # Constraint index to dual value
  • Core solver function that constructs the CVXPY problem from the model, parses expressions, solves it, and extracts the solution.
    def solve_cvxpy_problem(problem: CVXPYProblem) -> Result[CVXPYSolution, str]: """Solve a CVXPY optimization problem. Args: problem: The problem definition Returns: Result containing a CVXPYSolution or an error message """ try: # Create variables variables: dict[str, cp.Variable] = {} for var in problem.variables: variables[var.name] = create_variable(var.name, var.shape) # Parse objective objective_expr = parse_expression( problem.objective.expression, variables, problem.parameters ) objective = ( cp.Minimize(objective_expr) if problem.objective.type == ObjectiveType.MINIMIZE else cp.Maximize(objective_expr) ) # Parse constraints constraints = [] for _i, constraint in enumerate(problem.constraints): constraint_expr = parse_expression( constraint.expression, variables, problem.parameters ) constraints.append(constraint_expr) # Create and solve the problem prob = cp.Problem(objective, constraints) result = prob.solve() # Extract solution values = {name: var.value for name, var in variables.items()} dual_values = { i: constraint.dual_value for i, constraint in enumerate(constraints) if hasattr(constraint, "dual_value") and constraint.dual_value is not None } return Success( CVXPYSolution( values=values, objective_value=float(result) if result is not None else None, status=prob.status, dual_values=dual_values if dual_values else None, ) ) except Exception as e: return Failure(f"Error solving CVXPY problem: {e!s}")
  • Helper function to create CVXPY variables from model specs.
    def create_variable(name: str, shape: int | tuple[int, ...]) -> cp.Variable: """Create a CVXPY variable with the given shape. Args: name: Name of the variable shape: Shape of the variable (int for scalar, tuple for vector/matrix) Returns: CVXPY variable """ return cp.Variable(shape, name=name)
  • Helper function to safely evaluate string expressions for objectives and constraints using available variables and parameters.
    def parse_expression( expr_str: str, variables: dict[str, cp.Variable], params: dict[str, Any] ) -> CVXPYExpr: """Parse a CVXPY expression string. Args: expr_str: String representation of the expression variables: Dictionary of variable names to CVXPY variables params: Dictionary of parameter names to values Returns: Parsed CVXPY expression """ # Create a local dictionary with variables and parameters local_dict = { **variables, **params, "cp": cp, "np": np, } # Evaluate the expression in the context of the local dictionary return eval(expr_str, {"__builtins__": {}}, local_dict)

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sdiehl/usolver'

If you have feedback or need assistance with the MCP directory API, please join our Discord server