Skip to main content
Glama

solve_cvxpy_problem

Solve convex optimization problems defined with variables, objectives, and constraints using CVXPY. Returns solutions for mathematical programming tasks.

Instructions

Solve a CVXPY optimization problem.

This tool takes a CVXPY optimization problem defined with variables, objective,
and constraints, and returns a solution if one exists.

Example:

Solve the following problem:

    minimize ||Ax - b||₂²
    subject to:
    0 ≤ x ≤ 1
    where A = [1.0, -0.5; 0.5, 2.0; 0.0, 1.0] and b = [2.0, 1.0, -1.0]

Should be this tool call:

    simple_cvxpy_solver(
        variables=[{"name": "x", "shape": 2}],
        objective_type="minimize",
        objective_expr="cp.sum_squares(np.array(A) @ x - np.array(b))",
        constraints=["x >= 0", "x <= 1"],
        parameters={"A": [[1.0, -0.5], [0.5, 2.0], [0.0, 1.0]],
                    "b": [2.0, 1.0, -1.0]}
    )

Args:
    problem: The problem definition with variables, objective, and constraints

Returns:
    A list of TextContent containing the solution or an error message

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
problemYes

Implementation Reference

  • Core handler function that implements the CVXPY problem solving logic: creates variables, parses expressions for objective and constraints, solves the problem, extracts values and duals.
    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}")
  • MCP tool handler registered with @app.tool('solve_cvxpy_problem'). Calls the core solve_cvxpy_problem function and formats the result as TextContent for MCP response.
    @app.tool("solve_cvxpy_problem")
    async def solve_cvxpy_problem_tool(problem: CVXPYProblem) -> list[TextContent]:
        """Solve a CVXPY optimization problem.
    
        This tool takes a CVXPY optimization problem defined with variables, objective,
        and constraints, and returns a solution if one exists.
    
        Example:
    
        Solve the following problem:
    
            minimize ||Ax - b||₂²
            subject to:
            0 ≤ x ≤ 1
            where A = [1.0, -0.5; 0.5, 2.0; 0.0, 1.0] and b = [2.0, 1.0, -1.0]
    
        Should be this tool call:
    
            simple_cvxpy_solver(
                variables=[{"name": "x", "shape": 2}],
                objective_type="minimize",
                objective_expr="cp.sum_squares(np.array(A) @ x - np.array(b))",
                constraints=["x >= 0", "x <= 1"],
                parameters={"A": [[1.0, -0.5], [0.5, 2.0], [0.0, 1.0]],
                            "b": [2.0, 1.0, -1.0]}
            )
    
        Args:
            problem: The problem definition with variables, objective, and constraints
    
        Returns:
            A list of TextContent containing the solution or an error message
        """
        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 solve_cvxpy_problem_tool",
                    )
                ]
  • Registration of the 'solve_cvxpy_problem' tool using FastMCP's @app.tool decorator.
    @app.tool("solve_cvxpy_problem")
  • Pydantic models defining the input schema (CVXPYProblem, CVXPYVariable, etc.) and output (CVXPYSolution) for the CVXPY solver.
    from enum import Enum
    from typing import Any
    
    from pydantic import BaseModel
    
    
    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
  • Helper function to parse string expressions into CVXPY expressions using safe eval with 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)

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