Skip to main content
Glama
carban
by carban

MiniZinc MCP Server

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.


Demo

Related MCP server: Google OR-Tools server

Install it

1. Prerequisites

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

  • uvcurl -LsSf https://astral.sh/uv/install.sh | sh

  • MiniZinc 2.6+ with the minizinc executable on PATH (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.

2. Install the server (pick one)

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

3. Wire it into your MCP client

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"]
    }
  }
}

4. Verify it works

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.


What it does

Tool

Description

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.

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.

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 which params 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.

solve_model arguments

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.

The tool descriptions also instruct the client agent to present solving results and model info to you as Markdown tables instead of raw JSON, so solve_model answers read like a table of output variables even though the tool itself always returns structured JSON.


Developing locally

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())
"

Running the tests

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).

Notes and limitations

  • 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 with max_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). Use list_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.

Available Tools

4 tools
list_solversB

List MiniZinc solvers

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior2/5

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

The only annotation is openWorldHint=false, which does not address safety or side effects. The description merely states 'List MiniZinc solvers' without disclosing any behavioral traits beyond the operation itself, such as return format or whether it's read-only. With minimal annotation coverage, the description fails to add needed context.

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 a single sentence with no filler, which is appropriately sized for a parameterless list tool. It is concise and front-loaded with the core action.

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

Completeness4/5

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

Given that an output schema exists (which handles return value details) and there are no parameters, the description adequately communicates the tool's purpose. It could be more explicit about scope (e.g., 'all available solvers'), but it is reasonably complete for a simple list operation.

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

Parameters4/5

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

The tool has zero parameters, so there is nothing to explain. Per the rubric, 0 parameters warrants a baseline score of 4, and the description appropriately adds no parameter information since none is required.

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 uses a clear verb ('List') and resource ('MiniZinc solvers'), making the operation specific. It doesn't explicitly distinguish from sibling tools like validate_model or solve_model, but the resource is unique enough that an agent can tell them apart.

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

Usage Guidelines2/5

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

No guidance is provided on when to use this tool versus the sibling tools. While the name is self-explanatory, the description doesn't state any context, prerequisites, or alternatives, leaving the agent to infer usage.

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

solve_modelC

Solve a MiniZinc model

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsNo
solverNogecode
model_codeYes
all_solutionsNo
max_solutionsNo
timeout_secondsNo

TDQS

C2.4/5.0
Behavior2/5

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

The annotations only provide openWorldHint=false, which is minimal. The description does not disclose what happens when the model is unsatisfiable, how solutions are returned, whether the solver selection affects behavior, or what side effects (if any) occur. For a tool that executes a model, the absence of behavioral context is a significant gap.

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

Conciseness3/5

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

The description is extremely short, which is concise, but it is under-specified rather than efficiently informative. It front-loads the core action but does not earn its place by adding any detail beyond the tool name.

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

Completeness2/5

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

With 6 parameters, 0% schema description coverage, no output schema, and minimal annotations, the description is far from complete. An agent would not know how to construct a valid call, what the result format is, or how to choose between this and solve_model_by_path. The presence of sibling tools makes the missing differentiation especially costly.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate, but it does not explain any parameter. The description does not clarify that model_code is the inline MiniZinc source, what params contains, how solver values map to available solvers, or what all_solutions and max_solutions do. The schema provides names and types only, and the description adds no meaning.

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

Purpose3/5

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

The description 'Solve a MiniZinc model' states a clear verb and resource, but it is generic and does not distinguish this tool from its sibling solve_model_by_path, which also solves a MiniZinc model. The name and description are nearly redundant, and the agent cannot tell which tool to use without inspecting the schema.

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

Usage Guidelines2/5

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

No guidance is given about when to use this tool versus solve_model_by_path or validate_model. The description does not mention that this tool takes inline model code, while solve_model_by_path presumably takes a file path. The agent is left to infer usage from the schema.

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

solve_model_by_pathB

Solve a MiniZinc model given by file paths

ParametersJSON Schema
NameRequiredDescriptionDefault
solverNogecode
data_pathNo
model_pathYes
all_solutionsNo
max_solutionsNo
timeout_secondsNo

TDQS

B3/5.0
Behavior2/5

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

The description provides minimal behavioral context beyond 'solve'. It doesn't mention what the tool returns (solutions, status, etc.), whether it triggers side effects, or if it requires specific environment conditions. The annotations only include 'openWorldHint: false', which is not informative for behavior, so the description carries the burden and falls short.

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

Conciseness3/5

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

The description is very short and front-loaded with the core purpose, which is good for conciseness. However, it omits crucial details about parameter semantics and behavior that could have been added without bloating the description. It earns a moderate score because it is concise but under-specified.

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

Completeness2/5

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

Given six parameters, no output schema, and a description that only states the core action, the description is incomplete. It lacks information on parameter usage (e.g., what data_path is for), return format, and error handling. An agent would need to infer a lot, especially since the tool likely has complex behavior (solving constraints, producing multiple solutions).

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

Parameters3/5

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

Schema description coverage is 0%, meaning the schema provides no descriptions for any of the six parameters. The tool description itself does not elaborate on the parameters either. However, many parameter names are self-explanatory (e.g., model_path, solver, timeout_seconds), providing some implicit meaning. The description adds no extra semantics but the defaults are present in the schema, so baseline 3 is appropriate given the self-evident names.

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 'Solve a MiniZinc model given by file paths' clearly states the verb 'solve' and the resource 'MiniZinc model', and distinguishes it from siblings like 'solve_model' by the 'given by file paths' qualifier which implies the model is a file path rather than inline content. However, it could be more explicit about what makes it different from 'solve_model'.

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 is for solving models from file paths, which hints at a distinction from siblings like 'solve_model', but it does not explicitly state when to use this tool versus alternatives. It doesn't mention scenarios where this is preferred over 'solve_model' or when to use 'validate_model' first.

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

validate_modelC

Validate a MiniZinc model

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsNo
model_codeYes

TDQS

C2.3/5.0
Behavior2/5

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

Annotations only provide openWorldHint=false, which does not clarify operational behavior. The description says 'Validate a MiniZinc model' but does not disclose whether it has side effects, what it returns, or whether it requires permissions. With no readOnly/destructive hints, the description carries the full burden and falls short.

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

Conciseness2/5

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

The description is a single short sentence, which is concise, but it is under-specified rather than efficiently informative. It omits crucial context without any structured layout to compensate. The brevity does not add value because it leaves too many unanswered questions.

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

Completeness1/5

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

The tool has two parameters, no output schema, and no description of return values or error behavior. Given the tool's function (validation), an agent would need to know what is returned (e.g., a success/failure message, list of errors) and what inputs are expected. The description is grossly incomplete for correct invocation.

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

Parameters1/5

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

The input schema has two parameters (model_code and params) with zero description coverage. The description does not mention either parameter, their purpose, format, or how they relate. Agents receive no help understanding what model_code should contain or what params is for, making this a severe gap.

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 states a specific verb (validate) and resource (MiniZinc model), making it clear what the tool does. It is not a tautology and is distinguishable from the solve-related siblings. However, it lacks specificity about what validation entails (e.g., syntax checking, type checking, constraint checking), preventing a 5.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus the sibling tools (list_solvers, solve_model, solve_model_by_path). There is no mention of validation being a prerequisite before solving, or any scenarios where this tool is preferred. Usage context is entirely absent.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedlist_solvers
    • First observedsolve_model
    • First observedsolve_model_by_path
    • First observedvalidate_model

TDQS

B3/5.0

Scored across 4 tools

Disambiguation3/5

list_solvers and validate_model are clearly distinct, but solve_model and solve_model_by_path overlap heavily in purpose. The descriptions distinguish file-based solving from a generic solve action, but an agent may be uncertain which to use for an inline model versus a file path.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern: list_solvers, validate_model, solve_model, solve_model_by_path. The by_path suffix is a clear modifier rather than a convention break.

Tool Count4/5

Four tools is a reasonable scope for a specialized MiniZinc server. Each tool addresses a core workflow need, though the set is slightly minimal.

Completeness4/5

The server covers the main MiniZinc operations: enumerate solvers, validate a model, and solve a model. Minor gaps exist such as solver-specific configuration or more granular result controls, but the core workflow is not blocked.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    A Model Context Protocol (MCP) server that exposes MiniZinc constraint solving capabilities to Large Language Models.
    184
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP-ORTools integrates Google's OR-Tools constraint programming solver with Large Language Models through the MCP, enabling AI models to: Submit and validate constraint models Set model parameters Solve constraint satisfaction and optimization problems Retrieve and analyze solution
    21
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Provides constraint satisfaction and optimization capabilities to LLMs and AI agents for scheduling, resource allocation, routing, budget optimization, and configuration problems using Google OR-Tools CP-SAT solver.
    5
    5
    Apache 2.0
  • A
    license
    Not graded
    quality
    Not graded
    maintenance
    An MCP server that enables Large Language Models to interactively create, edit, and solve constraint models using backends like MiniZinc, Z3, PySAT, and Clingo. It bridges natural language with symbolic reasoning for solving complex logical, SAT, SMT, and optimization problems.
    MIT