cd /news/ai-agents/show-hn-constraint-programming-in-yo… · home topics ai-agents article
[ARTICLE · art-130489] src=github.com ↗ pub= topic=ai-agents verified=true sentiment=↑ positive

Show HN: Constraint Programming in Your AI Agent

A developer released minizinc-mcp, an MCP server that exposes MiniZinc constraint solving and optimization to LLM clients including opencode, Claude Desktop, and Cursor, letting agents parse, type-check, and solve MiniZinc models directly from a chat session. Built with the MCP Python SDK v2 and the MiniZinc Python binding, the server requires only uv and MiniZinc 2.6+ with the minizinc executable on PATH, and installs via `uv tool install --from git+https://github.com/carban/minizinc-mcp minizinc-mcp` or runs on demand with uvx. It exposes six tools prefixed with minizinc_ — minizinc_list_solvers, minizinc_validate_model, minizinc_solve_model, minizinc_solve_model_by_path, minizinc_get_model_info, and minizinc_get_flatzinc — and runs over stdio.

read5 min views1 publishedSep 15, 2026
Show HN: Constraint Programming in Your AI Agent
Image: Michielbdejong (auto-discovered)

An MCP server that exposes MiniZinc constraint solving and optimization to LLM clients such as opencode, Claude Desktop, and Cursor. It lets an agent parse, type-check, and solve MiniZinc models directly from a chat session.

Built with the MCP Python SDK v2 and the MiniZinc Python binding.

Only two things need to be installed, once per machine:

  • uvcurl -LsSf https://astral.sh/uv/install.sh | sh
  • MiniZinc 2.6+ with theminizinc executable onPATH (includes a default solver, Gecode)

Everything else is fetched automatically by uv — there is no clone, no venv setup, and no manual pip install on your side.

Install it globally (best if you use it in several projects):

uv tool install --from git+https://github.com/carban/minizinc-mcp minizinc-mcp

Or run it on demand each time, with nothing installed:

uvx --from git+https://github.com/carban/minizinc-mcp minizinc-mcp

The server runs over stdio. Tell your MCP client to launch it:

opencode — project level (add this to opencode.jsonc in your project):

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "minizinc": {
      "type": "local",
      "command": ["uvx", "--from", "git+https://github.com/carban/minizinc-mcp", "minizinc-mcp"]
    }
  }
}

opencode — global (add the same mcp.minizinc block to ~/.config/opencode/opencode.json):

{
  "mcp": {
    "minizinc": {
      "type": "local",
      "command": ["uvx", "--from", "git+https://github.com/carban/minizinc-mcp", "minizinc-mcp"]
    }
  }
}

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "minizinc": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/carban/minizinc-mcp", "minizinc-mcp"]
    }
  }
}

Restart your client. Six tools should now be available, prefixed with minizinc_:

  • minizinc_list_solvers
  • minizinc_validate_model
  • minizinc_solve_model
  • minizinc_solve_model_by_path
  • minizinc_get_model_info
  • minizinc_get_flatzinc

Quick sanity check — ask your client: "list the available MiniZinc solvers". You should see gecode, chuffed, highs, and anything else installed on the machine.

Tool Description
list_solvers Lists every MiniZinc solver installed on the machine. The returned tag names (e.g. gecode ,chuffed ,highs ) can be passed tosolve_model .
validate_model Parses and type-checks MiniZinc model code without solving it . Useful for checking model syntax up front. ReturnsVALID orINVALID with an error message.
solve_model Solves a MiniZinc model given as source code: once, exhaustively ( all_solutions ), or with a solution / time limit. Returns the status, solution(s), objective value (for optimization problems), and solver statistics.
solve_model_by_path Same as solve_model but loads the model and its optional data (.dzn ) file from paths instead of source code.
get_model_info Inspects a model without solving it : returns its solve method (satisfy/minimize/maximize) and the declared input parameters and output variables with their types. Useful for an agent to know exactly whichparams a model expects.
get_flatzinc Compiles a model (and optional data) to FlatZinc text without solving it. Returns the .fzn model, the.ozn output model, and flattening statistics. Useful for debugging and low-level inspection.
Argument Type Default Description
model_code str (required) The MiniZinc source code ( .mzn ) of the model.
params dict | str None Parameter assignments like a .dzn file: a JSON object mapping names to values (a JSON string encoding such an object is also accepted).
solver str "gecode" Which solver to use (see list_solvers ).
all_solutions bool False Compute all solutions of a solve satisfy problem.
max_solutions int | None None Stop after at most this many solutions.
timeout_seconds int | None None Solver time limit in seconds.

The result is a JSON object like:

{
  "status": "OPTIMAL_SOLUTION",
  "objective": 9,
  "solution": { "objective": 9, "x": 9, "y": 1 },
  "statistics": { "time": 0.204, "nodes": 3, ... }
}

status is one of SATISFIED, OPTIMAL_SOLUTION, ALL_SOLUTIONS, UNSATISFIABLE, UNKNOWN, or ERROR. validate_model and solve_model never raise in normal operation — errors are returned inside the result dict.

Clone the repo, then:

uv sync          # create the environment and install mcp + minizinc

The server speaks the MCP stdio transport, so it is launched as a subprocess by an MCP client. Run it with the SDK inspector:

uv run mcp dev server.py

that opens the MCP Inspector in the browser where every tool can be called interactively. A minimal programmatic smoke test:

uv run python -c "
import asyncio
from mcp import Client
from mcp.client.stdio import StdioServerParameters

async def main():
    params = StdioServerParameters(command='uv', args=['run', 'python', 'server.py'], cwd='.')
    async with Client(params) as client:
        result = await client.call_tool('solve_model', {
            'model_code': 'var 1..10: x; var 1..10: y; constraint x + y = 10; solve maximize x;'
        })
        print(result.content[0].text)

asyncio.run(main())
"

Install the test dependencies, then run the suite:

uv sync --group dev
uv run pytest -q

The tests in tests/ launch the server end-to-end over stdio and call every tool through the MCP protocol, solving the example model in example/. They need a working MiniZinc install (the same prerequisite as for developers).

  • params follows JSON representation: JSON arrays map to MiniZinc arrays; numbers, strings, and booleans map to their native MiniZinc types. Exotic types like sets and enums are not fully expressible this way.
  • Do not combine all_solutions withmax_solutions ; the MiniZinc driver rejects the combination.
  • MiniZinc requires a solver that supports the model (e.g. chuffed /gecode for CP,highs /cbc for MIP models). Uselist_solvers to see what is installed.
  • Solutions are returned inline in the tool result; read_only_hint is set on all tools, so they do not modify your files or system.
── more in #ai-agents 4 stories · sorted by recency
── more on @minizinc-mcp 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/show-hn-constraint-p…] indexed:0 read:5min 2026-09-15 ·