Skip to content
Three-quarter view of a flying-wing drone coloured by pressure coefficient, with streamwise vorticity cores trailing behind it on three wake planes.

mcopenfoam

OpenFOAM jobs that tell you what they are doing. Submit a case, get a job id in under a second, and follow it through meshing, solving and an early stop once the forces settle.

A fine CFD case runs for an hour or more. Started from a shell or from inside one long tool call, it says nothing until it ends, and a mesh that leaked or a solver that diverged at iteration 80 is found out at the end. mcopenfoam turns each case into a durable job that a client polls in seconds:

job_status · flight-a6.7-b0-coarseone line per poll
  1. 00:00queuedqueued on cfd-host behind keelcmp-B (simpleFoam 47/1000 eta 54m)
  2. 54:12meshsnappyHexMesh (4/7) castellating 0.43M cells
  3. 58:40meshsnappyHexMesh (4/7) snapping 3.94M cells
  4. 61:05meshsnappyHexMesh (4/7) layers 3.94M cells
  5. 66:31solvesimpleFoam 111/1000 Cd 0.05108 Cl 0.3852 drift 8.88% eta 86m
  6. 97:18solvesimpleFoam 400/1000 Cd 0.05102 Cl 0.3817 drift 0.31% eta 51m
  7. 104:02convergedsimpleFoam 420/1000 Cd 0.05101 Cl 0.3816 drift 0.06% eta 6m converged, ends at 620
  8. 118:40renderfigures A A2 A3 B C D E rendered
  9. 118:44finishedfinished after 620 iterations in 1.9h

Durable jobs

Each job is a directory with its state, an event log and its own copy of the case. Tool calls only read it, so nothing is lost when a client disconnects.

Progress you can read

Mesh phases and cell counts, solver iteration, residuals, force coefficients with their drift, and an ETA, every few seconds.

Stops when it has converged

The watcher lowers endTime once Cd, Cl and CmPitch hold steady over a window, and keeps the samplers covering the last 200 iterations.

Sweeps on one mesh

Several angles of attack or sideslip on the identical mesh, each starting from the last point’s fields. Add points to a finished sweep later.

Figures without a desktop

Headless ParaView renders separation maps, Cp, wake vorticity and a three-quarter view, each marked with the side it is seen from.

Survives restarts

Steps run detached and write their exit code into the case. Restart the worker mid-mesh and it picks the job back up.

MCP clientClaude Code, or any client: submit, poll, read results. Tool calls return in seconds.
stdio on this machine, or HTTP to a remote host
ServerTools and resources. Writes a job once at submit, then only reads it.
QueueProcrastinate: in memory locally, Postgres on a host. One job per host at a time.
WorkerRuns the step loop and the watcher. In the server process locally, its own container on a host.
docker exec -d into a container per job
Job containerOpenFOAM, the case mounted at /case, MPI ranks pinned. Steps write their own log and exit code.
ParaView containerHeadless pvpython, run once per figure set: separation maps, Cp, wake planes, a three-quarter view.
everything durable lands in one directory per job
Jobs directoryjob.json, events.jsonl, the case copy with its logs and postProcessing, figures/. Survives any process.

The hosted server is the HTTP form, behind OAuth from auth.supported.systems: connect to it. The same code also runs over stdio on your own machine with an in-memory queue. Why it is built this way.

Top view of the drone's upper surface coloured by skin friction along the free stream, orange where the flow is attached and blue where it reverses, with black friction lines.
View A at alpha 8: skin friction along the free stream with surface friction lines. Orange is attached flow moving aft. Over the aft half of the outer wing the friction falls to near zero and the lines turn spanwise, and small swirls sit just aft of the pod junctions: the flow there is close to separating. Rendered by mcopenfoam from a coarse TerraHawk flight case.