Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
UV_INDEXYesMust include https://pypi.ampl.com for resolution to succeed.
AMPLKEY_UUIDNoAMPL licence UUID. Optional; without it a size-limited demo licence is used.
AMPL_MCP_ALLOW_SHELLNoSet to '1' to permit AMPL's shell and cd statements.
AMPL_MCP_LICENCE_DIRNoOverride the durable licence directory.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
ampl_versionA

Report server build, AMPL versions, licence tier and installed solvers.

Requires no session. Call this first when anything is unexplained: a demo licence solves small models happily and fails only on larger ones, with an error that reads like a modelling problem.

amplpy_version is always reported. ampl_version is the AMPL engine's own version banner, which only a live engine can be asked for: it is None when no session is running (the key is still present, so the result shape does not change depending on whether a session happens to exist). Call ampl_init_session first if you need it.

ampl_init_sessionA

Start an AMPL engine. No engine exists until this is called.

workdir defaults to a per-session temporary directory; pass a path to work against a real project. Every path ARGUMENT to a tool is resolved inside it and an escape is refused - but this is not a sandbox: AMPL expression text is not path-guarded (ampl_display("1 > 'C:/elsewhere.txt'") writes outside it via AMPL's own redirection), and an include with an absolute path reads from outside it.

ampl_list_sessionsA

List live sessions and which one is current.

ampl_use_sessionC

Make name the current session.

ampl_restart_sessionB

Restart the engine, discarding all model state. The recovery path.

ampl_close_sessionB

Dispose the engine, removing the workdir if the server created it.

ampl_evalA

Run AMPL statements in order, returning per-statement output and errors.

Model-mode set literals need braces: set S = {1,2,3}; and set S := {1,2,3}; both work. Omitting the braces, e.g. set S := 1 2 3;, is a syntax error in model mode. A failing statement stops the batch but never kills the session.

statements must be a non-empty list of strings that contains at least one actual statement: an empty list, or input that is only comments and whitespace, is reported as an argument_error rather than as a successful call over nothing.

A warnings list appears on the result when a statement loads a file (include, commands, model, data) or a shared library (load). Loading is permitted on purpose, but the loaded file's contents are executed WITHOUT being guard-checked - read the warning and tell the user rather than assuming the guard covered it.

ampl_read_filesA

Load .mod/.dat/.run files by path, resolved inside the session workdir.

Each file's contents are guard-checked exactly like a statement passed to ampl_eval before AMPL is asked to load it: a shell statement hidden inside a .run/.mod/.dat file is refused, not silently executed, subject to the same AMPL_MCP_ALLOW_SHELL escape hatch.

That check stops at the file it is given. If the file itself loads another file (include, commands, model, data) or a shared library (load), AMPL executes THAT file's contents unchecked - a shell there will run. Such statements are permitted deliberately and reported in a top-level warnings list; read it and tell the user.

On a load failure, message is a human-readable string and the full per-statement record is under detail.

ampl_set_dataA

Assign a parameter from JSON, avoiding hand-written .dat syntax.

values may be a scalar, a mapping of index to value, or a list of [index..., value] records for multi-dimensional entities. The parameter must already be declared. This tool handles parameters only; to declare or assign a set, use ampl_eval with a statement such as set S = {1,2,3};.

name must be a bare AMPL entity name; it is interpolated into an AMPL statement, so anything else is an argument_error.

ampl_list_entitiesA

List declared entities with their shape. The map of what has been built.

Call this when unsure what exists rather than guessing at names.

ampl_get_dataA

Read an entity's values as records.

suffix selects val, dual, rc, slack, lb or ub, so this one tool covers primal values, duals, reduced costs and bounds. At most one suffix may be requested per call: results.entity_rows tells an indexed (index, value) pair apart from a scalar value by checking for a 2-tuple, so passing multiple suffixes to get_values() on a scalar entity would be silently misread as an index/value pair.

Reading a PARAMETER can have a side effect: an indexed default that has never been referenced is computed and cached by AMPL only when read (documented AMPL laziness, not an amplpy quirk), and this tool forces that computation, but ONLY when a plain read comes back empty or short - never unconditionally - so a data-dependent default already read here keeps the value it had when read rather than tracking later changes to what it depends on; avoid reading such a parameter until you are done changing the data it depends on. If some instances of a PARAMETER (or VARIABLE) still have no value afterwards (a parameter with no default that was only partially assigned), that is reported via notes with ok: false, never silently reported as a complete, successful read. This completeness check does not apply to sets, constraints or objectives: num_instances() counts something other than "rows returned" for those (e.g. 1 for a whole set regardless of how many members it has), so comparing the two would misreport a perfectly normal empty set as a failed read.

name must be a bare AMPL entity name; it is interpolated into an AMPL statement, so anything else is an argument_error. limit is the page size and must be at least 1 - a limit of 0 or less is an argument_error, not an empty page reported as a successful read.

ampl_displayA

Evaluate an arbitrary AMPL display expression. The reach-anything tool.

A warnings list appears on the result when expr carries a file-loading statement (include, commands, model, data, load). Loading is permitted on purpose, but the loaded file's contents are executed WITHOUT being guard-checked.

This tool evaluates AMPL, so AMPL's own output redirection (display 1 > 'somewhere.txt';) applies and is NOT confined to the session working directory. The path guard covers this server's own path ARGUMENTS, not AMPL expression text.

ampl_solveA

Solve the current model and summarise the outcome.

Returns a bounded tail of solver output, not the whole log. Read duals and reduced costs afterwards with ampl_get_data(name, suffix="dual"|"rc").

ok is only true when solve_result is exactly "solved", no error or warning was captured, no output-stream failure marker was seen, AND at least one objective was declared: AMPL happily reports solve_result "solved" for a session with no model at all, or for a model with no objective, even though no solver was ever reached.

ampl_sweepA

Set a scalar parameter to each value, re-solve, and collect results.

Server-side so a twenty-point study is one call rather than forty round trips; AMPL re-presolves only what changed. Each run goes through the same shared core as ampl_solve (_solve_once), so it gets the same output-failure-marker scan, the same "solved AND has an objective" requirement for ok, and the same stable objective_name/objective_value shape - not a re-implementation that would silently reopen the holes Task 8 closed. objective, if given, is activated with an objective <name>; statement before the first solve (exactly like ampl_solve's own objective=) so every run actually optimizes that objective, not merely reports its value computed at some other objective's optimum; a bogus name is caught before any solve runs, the same way ampl_solve catches it. Omit objective to use whichever objective AMPL reports first, which on a model with more than one declared objective may not be the one actually active.

A value that fails to assign (wrong parameter name, wrong type, a value outside a declared domain) is recorded as its own failed run (ok False, with a message) and the sweep continues through the remaining values rather than aborting. collect names extra AMPL expressions evaluated with ampl.get_value after each solve; each is guard-checked exactly like a statement passed to ampl_eval, so collect cannot become another route to shell, and none may reuse a name this tool already uses for a run's own fields (value, ok, solve_result, ...) - doing so would silently overwrite that field instead of adding a new one. The overall ok is false if any run failed.

The parameter is left at whatever the LAST swept value was; this tool never restores the value it had before the call. A later ampl_solve() on the same session solves against that last value, not the model's original state - re-set the parameter first (e.g. via ampl_set_data) if that is not what is wanted.

ampl_optionA

Get an AMPL option, or set it when value is given.

An option name AMPL does not have is an argument_error, on both the get and the set: AMPL creates an option on first assignment, so a typo like ampl_option("solvre", "cbc") would otherwise report success while creating an inert option and leaving the real solver untouched. The one exception is the <solver>_options directive convention (highs_options, gurobi_options, ...), which by design does not exist until you create it.

value must be a string when given.

ampl_diagnoseA

Explain the last solve: status, message, and violated constraints.

Call this after an infeasible or unbounded result rather than guessing at the model.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

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/worc4021/ampl-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server