Skip to main content
Glama

simple_cvxpy_solver

Solve convex optimization problems using CVXPY with a simplified interface that accepts variables, objectives, and constraints directly.

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
variablesYes
objective_typeYes
objective_exprYes
constraintsYes
parametersNo
descriptionNo

Implementation Reference

  • Handler function for the 'simple_cvxpy_solver' tool. Constructs CVXPYProblem from simple inputs and delegates to solve_cvxpy_problem 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}")]
  • Pydantic models defining input schema (CVXPYProblem, variables, objective, constraints) and output (CVXPYSolution) used internally by the tool.
    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 logic: parses string expressions into CVXPY objects using safe eval, builds and solves the optimization problem with cvxpy, extracts primal/dual solutions.
    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}")
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It mentions the tool 'solves' problems and returns 'the solution or an error message,' which covers basic behavior. However, it lacks details on performance characteristics, error handling, computational limits, or any side effects, which are crucial for a solver tool. The description adds minimal behavioral context beyond the implied solving action.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded, starting with the core purpose and then detailing parameters and returns. Every sentence earns its place by explaining functionality or inputs/outputs. It could be slightly more concise by integrating the 'Args' and 'Returns' labels more seamlessly, but overall it's well-structured and efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a solver tool with 6 parameters, no annotations, and no output schema, the description provides a solid foundation with purpose and parameter details. However, it lacks information on output format (beyond 'list of TextContent'), error specifics, or usage examples, which would enhance completeness for such a tool. It's adequate but has gaps in behavioral and output context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description compensates fully by detailing all 6 parameters in the 'Args' section, providing clear semantics for each (e.g., 'variables: List of variable definitions, each with 'name' and 'shape''). This adds significant value beyond the bare schema, making the parameters understandable and actionable for the agent.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'A simpler interface for solving CVXPY optimization problems' and distinguishes it from 'the full CVXPYProblem model structure.' It specifies the verb 'solving' and resource 'CVXPY optimization problems,' making it clear what it does. However, it doesn't explicitly differentiate from sibling tools like 'solve_cvxpy_problem,' which slightly reduces clarity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by stating it's 'simpler' and 'without requiring the full CVXPYProblem model structure,' suggesting it should be used for straightforward CVXPY problems. However, it doesn't provide explicit guidance on when to use this tool versus alternatives like 'solve_cvxpy_problem' or other solver siblings, leaving the agent to infer based on the 'simpler' qualifier.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other 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