---
title: Agent interface (MCP)
summary: Gyre exposes its capabilities to AI agents through the Model Context Protocol. An agent can discover cases, upload meshes, run analyses, let the solver choose the polynomial degree for a target accuracy, obtain exact gradients and error estimates, and read this documentation — through tools designed to be self-correcting.
section: guide
order: 6
level: 2
audience: [AI agents, agent builders]
keywords: [MCP, Model Context Protocol, agents, tools, Claude, upload_mesh, order selection]
---
<!-- gyre docs: expanded Markdown of guide/agents.md (generated tables, verification numbers and chart data are written out). Base level of this page: L2 Practice; passages at another level are bracketed by 'begin level N' / 'end level N' comments and start with [LN Name]. Built from revision ceb1f4b0be. -->

## Connect

The service mounts an MCP endpoint (streamable HTTP, stateless) at `/mcp`:

```bash
claude mcp add --transport http gyre http://HOST:8600/mcp
```

For clients that speak stdio only, a proxy forwards to a deployment:

```bash
claude mcp add gyre -- python -m gyre.agent --service http://HOST:8600
```

If the deployment sets `GYRE_API_TOKEN`, pass it as a bearer token (HTTP) or `--token` (proxy).

<!-- begin level 2 (Practice) -->
**[L2 Practice] Options of the stdio proxy**

`python -m gyre.agent` is a second entry point, separate from the `gyre` program (it is not in
the [command-line reference](../reference/cli.md)).

| Option | Default | Meaning |
|---|---|---|
| `--service URL` | the environment variable `GYRE_SERVICE_URL`, else `http://127.0.0.1:8600` | the deployment the proxy forwards to |
| `--token TOKEN` | the environment variable `GYRE_API_TOKEN`, else none | bearer token sent with every request to the deployment |
| `--transport stdio\|streamable-http` | `stdio` | how the proxy itself talks to its MCP client. `stdio` is what a client that starts the proxy as a subprocess expects; `streamable-http` makes the proxy an HTTP MCP server of its own, on the MCP SDK's default address |

The proxy holds no state and no solver: every tool call becomes a request to the deployment's
REST API, with a timeout of 900 seconds per request.

<!-- end level 2 -->

## Tools

| tool | purpose |
|---|---|
| `gyre_info` | Identify this Gyre deployment: version, source commit, device, endpoints, uptime. |
| `list_presets` | List built-in cases (name, description, size estimate) under `presets`. Start here. |
| `get_case_schema` | JSON Schema of a case specification (mesh, flow, discretization, solver). |
| `validate_case` | Dry-run a case without solving: resolved spec, element/DOF estimate, chosen device. |
| `submit_job` | Queue a steady flow analysis and return the job record. |
| `get_job` | Job state (queued/running/succeeded/failed/cancelled), progress and result summary. |
| `get_job_result` | Result of a finished job. |
| `get_job_events` | Progress events of a job (nonlinear iterations etc.) starting at sequence `since`. |
| `list_jobs` | Recent jobs under `jobs`, newest first; optionally filter by state. |
| `cancel_job` | Cancel a queued or running job. |
| `get_job_artifact` | Read a file a job produced. |
| `open_session` | Open a warm analysis session (a dedicated solver process) for repeated evaluations. |
| `session_evaluate` | Set inputs (e.g. {"alpha_deg": 3.0, "mach": 0.55}), converge the flow, return outputs. |
| `session_gradients` | Exact total derivatives d(of)/d(wrt) at the session's current converged state. |
| `session_error_estimate` | Adjoint-weighted-residual discretization-error estimate for outputs `of`. |
| `session_adjoint` | Reverse (adjoint) total product at the session's converged state: the coupled-adjoint building block. |
| `session_surface` | Surface nodes of the session's case: `coordinates` (one row per node, the nodes that the input `x_surface` displaces and on which `f_surface` acts), the current `displacement` and `nodes`. Arrays are summarised unless `full_arrays`. |
| `session_state` | Current inputs of a session, whether a flow state exists (`solved`), whether the last evaluation converged (`converged`) and the residual norm of the kept state. |
| `get_session` | A session's case, device, counters and `interface` (inputs with shapes and current values, outputs); `commands` lists what `session_command` accepts when the solver process reports it. |
| `session_command` | Run any command of the session's solver process (generic pass-through). |
| `list_sessions` | Open sessions (under `sessions`) with their case, device, call counts and idle time. |
| `close_session` | Close a session and free its solver process. |
| `list_meshes` | Meshes in this deployment's mesh store, under `meshes`: name, size, element count, geometry order, boundary groups (faces per group), bounding box, sha256. |
| `upload_mesh` | Store a mesh file so that cases can use it; returns its summary. |
| `inspect_mesh` | Summary of a stored mesh: bytes, sha256, dim, elements, geometry_order, nodes, boundaries (faces per group), bounding_box and quality numbers. |
| `delete_mesh` | Remove a mesh from the store (jobs still queued on it will fail). |
| `list_pipelines` | Declarative pipelines of this deployment, under `pipelines`. |
| `run_pipeline` | Start a pipeline run (a DAG of cached stages: solves, sweeps, gates, reports). |
| `get_pipeline_run` | Status and progress of a pipeline run. |
| `list_pipeline_runs` | Recent pipeline runs under `runs`, newest first (id, pipeline, status, times). |
| `cancel_pipeline_run` | Cancel an active pipeline run (the engine and the stage it is running are terminated); returns the run's status, `cancelled` once its processes have ended. Stages that had completed stay in the stage cache. A finished run is returned as is. |
| `get_pipeline_artifact` | Files a stage of a pipeline run produced. |
| `search_docs` | Full-text search of the Gyre documentation served with this deployment. |
| `read_doc` | Read a documentation page as Markdown (math in LaTeX). `path` comes from `search_docs` (or use "llms.txt" for the site index). Long pages are paged with `offset`. |

<!-- begin level 2 (Practice) -->
**[L2 Practice] Workflows an agent should follow**

**Explore.** `list_presets` → `validate_case` (size, device, warnings) → `get_case_schema` when a
field name is needed.

**One-shot analysis.** `submit_job` with `wait_seconds` (short jobs finish within the call) →
otherwise `get_job` with `wait_seconds` until `state` is `succeeded` → `get_job_result`.

**Design loop or sweep.** `open_session` once → repeat `session_evaluate` and
`session_gradients` → `close_session`. Sessions keep compiled kernels and warm-start each
solve.

**Your own geometry.** `upload_mesh` (a Gmsh `.msh` file of quadrilaterals or hexahedra with a
named physical group on every boundary, or a Gyre `.npz` file) → read `boundaries` in the
returned summary → `validate_case` with `mesh: {generator: "file", params: {path: <name>}}`
and one condition per group in `discretization.boundaries` → `submit_job` or `open_session`.
`list_meshes`, `inspect_mesh` and `delete_mesh` manage the store. See
[Mesh files](meshes.md).

**Accuracy on demand.** `submit_job` with `adapt_output` and `adapt_tolerance` (and optionally
`adapt_max_order`, default 5) raises the polynomial degree from the case's
`discretization.order` until the estimated error of that output meets the tolerance.
`get_job_result` returns the `adaptation` section by default; read `met` before relying on the
value.

**Trust but verify.** `session_error_estimate` for the discretization error of an output;
`search_docs` / `read_doc` for methods, limits and verification evidence.

<!-- end level 2 -->

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] Design rules of the tool surface**

* **One code path.** Every tool calls the REST API; an agent gets exactly the behaviour a
  program gets.
* **Structured, stable results.** JSON with fixed keys. Arrays longer than a couple of dozen
  entries are replaced by `{"_array": true, "shape", "min", "max", "l2_norm", "head"}` unless
  `full_arrays` is set — shape sensitivities and histories would otherwise flood the context.
* **Errors that teach.** A failure relayed from the REST API returns
  `{"ok": false, "status", "error": {"type", "message", "hint"}}`; the hint names the valid
  alternatives or the next call to make. The documentation tools report their own failures in
  the same form without `status` (`read_doc` omits the hint for an invalid path).
* **Refusals before a request.** A mesh name that is not a bare file name ending in `.msh` or
  `.npz` returns `{"ok": false, "status": 422, "error": {"type": "InvalidMeshName", …}}`
  without a request to the service. `upload_mesh` takes `content` as text (`encoding="text"`,
  the default) or base64 (`encoding="base64"`, needed for `.npz`); invalid base64 or another
  encoding returns `InvalidEncoding`. `adapt_output` and `adapt_tolerance` must be given
  together; one without the other returns a `ValidationError`.
* **Bounded waits.** Long work is asynchronous; waits are capped at 300 seconds per call, so an
  agent stays responsive and can report progress with `get_job_events`.
* **Self-description.** The server's instructions summarise conventions (non-dimensional units,
  radians, input and output names); `validate_case` and the session interface report sizes,
  shapes and current values.

<!-- end level 3 -->

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] A session transcript**

```text
→ open_session(case="naca0012_euler")
← {"id": "ses-…", "interface": {"inputs": {"mach": …, "alpha": …, "x_surface": {"shape": [128, 2]}},
                                 "outputs": {"cl": …, "cd": …, "f_surface": {"shape": [128, 2]}}}}
→ session_evaluate(session_id, inputs={"alpha_deg": 2.0})
← {"converged": true, "reason": "residual tolerance reached", "nonlinear_iterations": 16,
   "outputs": {"cl": 0.278767, "cd": 0.000949, …}, …}
→ session_gradients(session_id, of=["cl"], wrt=["alpha_deg", "x_surface"])
← {"derivatives": {"cl": {"alpha_deg": 0.135059,
                          "x_surface": {"_array": true, "shape": [128, 2], "l2_norm": 61.73, …}}},
   "info": {"mode": "adjoint", "linear_solves": [{"output": "cl", "iterations": 51, …}], …}}
→ session_evaluate(session_id, inputs={"alpha_deg": 2.5})        # warm start
← {"converged": true, "nonlinear_iterations": 6, "outputs": {"cl": 0.345916, "cd": 0.001074, …}, …}
→ close_session(session_id)
← {"id": "ses-…", "closed": true}
```

Recorded from a service running revision `5ee1cdc` on the CPU; numbers are shortened and `…`
marks omitted keys. `alpha_deg` derivatives are per degree: 0.135059 per degree is the 7.7383
per radian that a job with `wrt: ["alpha"]` returns for the same case. The warm-started
second evaluation needed 6 nonlinear iterations instead of 16. The recording is not kept in
the repository: the coefficients and gradients were reproduced by an independent command-line
run of the same case, the iteration counts were not
([what stands behind the replies](../examples/agent-session.md)).
The [agent example](../examples/agent-session.md) shows a complete exchange.

<!-- end level 3 -->

<!-- begin level 3 (Mechanics) -->
**[L3 Mechanics] Resources and prompts**

Resources: `gyre://presets` and `gyre://schema/case`. Prompts: `analyze_case` (run, check
convergence, report outputs with error estimates and provenance) and `gradient_check` (verify
an adjoint gradient against finite differences in a session).

<!-- end level 3 -->

<!-- begin level 4 (Theory) -->
**[L4 Theory] Documentation for machines**

The site publishes `llms.txt` (an index of pages with summaries), the Markdown source of every
page next to its HTML, and a search index. `search_docs` ranks pages by term matches in title,
headings, summary and body; `read_doc` returns Markdown with LaTeX math, paged by character
offset. An agent can therefore ground a statement about, say, adjoint consistency in the page
that defines it and in the verification study that tests it.

<!-- end level 4 -->
