{"slug": "show-hn-constraint-programming-in-your-ai-agent", "title": "Show HN: Constraint Programming in Your AI Agent", "summary": "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.", "body_md": "An [MCP](https://modelcontextprotocol.io) server that exposes [MiniZinc](https://www.minizinc.org/) 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.\n\nBuilt with the [MCP Python SDK v2](https://py.sdk.modelcontextprotocol.io/) and the [MiniZinc Python binding](https://pypi.org/project/minizinc/).\n\nOnly two things need to be installed, **once per machine**:\n\n- **[uv](https://docs.astral.sh/uv/)** —`curl -LsSf https://astral.sh/uv/install.sh | sh`\n- **[MiniZinc](https://www.minizinc.org/)** 2.6+ with the`minizinc` executable on`PATH` (includes a default solver, Gecode)\n\nEverything else is fetched automatically by `uv` — there is **no clone, no venv setup, and no manual `pip install`** on your side.\n\nInstall it globally (best if you use it in several projects):\n\n```\nuv tool install --from git+https://github.com/carban/minizinc-mcp minizinc-mcp\n```\n\nOr run it on demand each time, with nothing installed:\n\n```\nuvx --from git+https://github.com/carban/minizinc-mcp minizinc-mcp\n```\n\nThe server runs over stdio. Tell your MCP client to launch it:\n\n**opencode — project level** (add this to `opencode.jsonc` in your project):\n\n```\n{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"mcp\": {\n    \"minizinc\": {\n      \"type\": \"local\",\n      \"command\": [\"uvx\", \"--from\", \"git+https://github.com/carban/minizinc-mcp\", \"minizinc-mcp\"]\n    }\n  }\n}\n```\n\n**opencode — global** (add the same `mcp.minizinc` block to `~/.config/opencode/opencode.json`):\n\n```\n{\n  \"mcp\": {\n    \"minizinc\": {\n      \"type\": \"local\",\n      \"command\": [\"uvx\", \"--from\", \"git+https://github.com/carban/minizinc-mcp\", \"minizinc-mcp\"]\n    }\n  }\n}\n```\n\n**Claude Desktop** (`claude_desktop_config.json`):\n\n```\n{\n  \"mcpServers\": {\n    \"minizinc\": {\n      \"command\": \"uvx\",\n      \"args\": [\"--from\", \"git+https://github.com/carban/minizinc-mcp\", \"minizinc-mcp\"]\n    }\n  }\n}\n```\n\nRestart your client. Six tools should now be available, prefixed with `minizinc_`:\n\n- `minizinc_list_solvers`\n- `minizinc_validate_model`\n- `minizinc_solve_model`\n- `minizinc_solve_model_by_path`\n- `minizinc_get_model_info`\n- `minizinc_get_flatzinc`\n\nQuick sanity check — ask your client: *\"list the available MiniZinc solvers\"*. You should see `gecode`, `chuffed`, `highs`, and anything else installed on the machine.\n\n| Tool | Description | \n|---|---|\n| `list_solvers` | Lists every MiniZinc solver installed on the machine. The returned tag names (e.g. `gecode` ,`chuffed` ,`highs` ) can be passed to`solve_model` . | \n| `validate_model` | Parses and type-checks MiniZinc model code **without solving it** . Useful for checking model syntax up front. Returns`VALID` or`INVALID` with an error message. | \n| `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. | \n| `solve_model_by_path` | Same as `solve_model` but loads the model and its optional data (`.dzn` ) file from paths instead of source code. | \n| `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 which`params` a model expects. | \n| `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. | \n\n| Argument | Type | Default | Description | \n|---|---|---|---|\n| `model_code` | `str` | (required) | The MiniZinc source code ( `.mzn` ) of the model. | \n| `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). | \n| `solver` | `str` | `\"gecode\"` | Which solver to use (see `list_solvers` ). | \n| `all_solutions` | `bool` | `False` | Compute all solutions of a `solve satisfy` problem. | \n| `max_solutions` | `int \\| None` | `None` | Stop after at most this many solutions. | \n| `timeout_seconds` | `int \\| None` | `None` | Solver time limit in seconds. | \n\nThe result is a JSON object like:\n\n```\n{\n  \"status\": \"OPTIMAL_SOLUTION\",\n  \"objective\": 9,\n  \"solution\": { \"objective\": 9, \"x\": 9, \"y\": 1 },\n  \"statistics\": { \"time\": 0.204, \"nodes\": 3, ... }\n}\n```\n\n`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.\n\nClone the repo, then:\n\n```\nuv sync          # create the environment and install mcp + minizinc\n```\n\nThe server speaks the MCP **stdio** transport, so it is launched as a subprocess by an MCP client. Run it with the SDK inspector:\n\n```\nuv run mcp dev server.py\n```\n\nthat opens the MCP Inspector in the browser where every tool can be called interactively. A minimal programmatic smoke test:\n\n``` python\nuv run python -c \"\nimport asyncio\nfrom mcp import Client\nfrom mcp.client.stdio import StdioServerParameters\n\nasync def main():\n    params = StdioServerParameters(command='uv', args=['run', 'python', 'server.py'], cwd='.')\n    async with Client(params) as client:\n        result = await client.call_tool('solve_model', {\n            'model_code': 'var 1..10: x; var 1..10: y; constraint x + y = 10; solve maximize x;'\n        })\n        print(result.content[0].text)\n\nasyncio.run(main())\n\"\n```\n\nInstall the test dependencies, then run the suite:\n\n```\nuv sync --group dev\nuv run pytest -q\n```\n\nThe 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](https://www.minizinc.org/) install (the same prerequisite as for developers).\n\n- `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.\n- Do not combine `all_solutions` with`max_solutions` ; the MiniZinc driver rejects the combination.\n- MiniZinc requires a solver that supports the model (e.g. `chuffed` /`gecode` for CP,`highs` /`cbc` for MIP models). Use`list_solvers` to see what is installed.\n- 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.", "url": "https://wpnews.pro/news/show-hn-constraint-programming-in-your-ai-agent", "canonical_source": "https://github.com/carban/minizinc-mcp", "published_at": "2026-09-15 16:42:24+00:00", "updated_at": "2026-09-15 16:51:05.173682+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "ai-products"], "entities": ["minizinc-mcp", "MiniZinc", "Model Context Protocol", "opencode", "Claude Desktop", "Cursor", "uv", "Gecode"], "alternates": {"html": "https://wpnews.pro/news/show-hn-constraint-programming-in-your-ai-agent", "markdown": "https://wpnews.pro/news/show-hn-constraint-programming-in-your-ai-agent.md", "text": "https://wpnews.pro/news/show-hn-constraint-programming-in-your-ai-agent.txt", "jsonld": "https://wpnews.pro/news/show-hn-constraint-programming-in-your-ai-agent.jsonld"}}