MCP server

Constraint problems, in your own words

Connect openconstraint-mcp to a coding agent that speaks the Model Context Protocol (MCP), such as Claude Code, Codex, or OpenCode, then describe your problem in any human language — English, Spanish, French, Chinese — not in modeling code. The agent writes a CP-SAT or MiniZinc model, and can keep your instance beside it as data the model reads rather than constants baked in. The server validates the model, runs the solver on your machine, and reports the run verbatim. Ask the agent for a checker as well, and that checker verifies the answer against your data.

v0.3.0

Install and verify

Needs Python 3.12+ (opens in a new tab) and uv (opens in a new tab). A CP-SAT model is a Python script, which suits problems that are easier to state in code. MiniZinc (opens in a new tab) is a declarative model on a managed runtime, and that runtime is one extra step.

  1. Install the package

    				uv tool install openconstraint-mcp
    			

    Installs from PyPI (opens in a new tab). CP-SAT ships inside the package, so it works as soon as this finishes. Stop here if CP-SAT is all you need.

  2. Add the MiniZinc runtime

    				openconstraint-mcp install-runtime
    			

    The download is roughly 200 MB. Nothing else in the package touches the network. The bundle installs on Linux x86_64, macOS arm64, and Windows x86_64 — those three builds, not those three systems. Anywhere else, or when you already have MiniZinc, use configure-runtime --runtime-dir <path> instead and point it at the directory holding bin/minizinc.

  3. Verify

    				openconstraint-mcp check-runtime
    openconstraint-mcp list-solvers
    			

    The first reports whether the MiniZinc runtime is installed; the second lists the solvers it exposes.

Connect and solve

Wire the server into your client, confirm which solvers it found, then state a problem in words rather than code. Any client that speaks MCP (opens in a new tab) will do.

  1. Add the server to your client

    Choose your MCP client
    				{
      "mcpServers": {
        "openconstraint": {
          "type": "stdio",
          "command": "openconstraint-mcp",
          "args": ["stdio", "--toolset", "full"]
        }
      }
    }
    			

    Claude Code (opens in a new tab) reads .mcp.json in your project.

    				[mcp_servers.openconstraint]
    command = "openconstraint-mcp"
    args = ["stdio", "--toolset", "full"]
    tool_timeout_sec = 3600
    			

    Codex (opens in a new tab) reads .codex/config.toml in your project, or ~/.codex/config.toml for every project. Raise the per-tool timeout as this block does: a checked CP-SAT call runs two capped child processes, so a client that gives up sooner returns a timeout while the solver is still running.

    				{
      "$schema": "https://opencode.ai/config.json",
      "mcp": {
        "openconstraint": {
          "type": "local",
          "command": ["openconstraint-mcp", "stdio", "--toolset", "full"],
          "enabled": true
        }
      }
    }
    			

    OpenCode (opens in a new tab) reads opencode.json in your project, or ~/.config/opencode/opencode.json for every project.

    Restart the client after saving the configuration.

  2. Ask which solvers it has

    				Use the openconstraint MCP server to list all solvers.
    			

    The server has five solvers: CP-SAT (the default MiniZinc backend), Gecode, Chuffed, COIN-BC, and HiGHS. It also has findMUS, which diagnoses rather than solves. It lists CPLEX, Gurobi, SCIP, and Xpress without a version. You license and install those yourself.

  3. Describe the problem, not the constraint model

    				Use the openconstraint MCP server for this.
    Three jobs, three machines.
    Job A: 3 minutes on M1, then 2 on M2, then 2 on M3.
    Job B: 2 on M1, then 1 on M3, then 4 on M2.
    Job C: 4 on M2, then 3 on M3.
    A machine runs one task at a time, start to finish.
    Finish all three jobs as early as possible.
    			

    This is Google's OR-Tools job shop tutorial (opens in a new tab) in plain words instead of the arrays of numbers it ships as. The agent writes the model and usually keeps the jobs beside it as data. The prompt names neither MiniZinc nor CP-SAT, so the agent chooses.

    For more problems and models, see the job shop example (opens in a new tab).

  4. Keep the files, not just the answer

    				Use the openconstraint MCP server for this.
    Three jobs, three machines.
    Job A: 3 minutes on M1, then 2 on M2, then 2 on M3.
    Job B: 2 on M1, then 1 on M3, then 4 on M2.
    Job C: 4 on M2, then 3 on M3.
    A machine runs one task at a time, start to finish.
    Finish all three jobs as early as possible.
    
    Solve it with MiniZinc.
    Write a checker and verify the solution with it.
    Save the model, the data file and the checker
    to /tmp/jobshop/minizinc.
    Show me the schedule as a table.
    			

    The path must be absolute; /tmp/jobshop/minizinc is an example. Saving needs the full toolset. That is why the configuration above passes --toolset full.

  5. Turn the answer into a spreadsheet

    				Use the openconstraint MCP server for this.
    Take the solution you just saved and write the
    schedule to schedule.xlsx in the same folder:
    a row per operation with job, machine, start
    and finish, and a Gantt sheet by machine.
    			

    Step 4 saves the solution as JSON. The server also reads and writes Excel and CSV files, for either backend. Ask for a table, a Gantt sheet, or both. Both are grids of cells, not charts.

    Download the example workbook (schedule.xlsx, 6 KB)

  6. When there is no answer

    				Use the openconstraint MCP server for this.
    Three jobs, three machines.
    Job A: 3 minutes on M1, then 2 on M2, then 2 on M3.
    Job B: 2 on M1, then 1 on M3, then 4 on M2.
    Job C: 4 on M2, then 3 on M3.
    A machine runs one task at a time, start to finish.
    Finish all three jobs as early as possible.
    
    Every job must also finish within 6 minutes.
    Solve it with MiniZinc. If this model has no
    schedule, find the constraints that conflict and
    tell me which one to relax.
    			

    When the server reports the model unsatisfiable, ask the agent to run find_unsat_core. This only works for MiniZinc.

  7. Search for a better formulation

    				Use the openconstraint MCP server for this.
    We have an OR-Tools CP-SAT job shop model at
    /tmp/jobshop/cp-sat/model.py, with checker.py
    and tasks_ft10.json beside it. The model takes
    the data path as its first argument.
    
    If the baseline already proves optimality in a
    few seconds, stop: the instance is too easy to
    compare on. Otherwise race it against a few
    alternative formulations, on the same data and
    checker and with identical solver settings.
    Tell me which one won and how long each took.
    			

    This needs a working CP-SAT model, its independent checker, and representative data of your own.

  8. When one solver is too slow

    				Use the openconstraint MCP server for this.
    The MiniZinc model saved in /tmp/jobshop/minizinc
    is slow on this instance. Write a couple of
    variants of it, one with a restart annotation,
    and race them against CP-SAT, Gecode and Chuffed
    in the background, with a few seeds each.
    Take whichever answer lands first.
    			

    The server runs several attempts at once. Each one uses a different model, solver, or seed. The first answer stops the rest.

Questions about the MCP server?

Ask on the issue tracker. It covers installation problems, solver behavior, and models of your own.