Run your own server
This guide is for running mcopenfoam yourself from a checkout of its source; most people use the hosted server instead.
On your own machine
Section titled “On your own machine”With docker, uv and the source in ~/mcopenfoam-src:
docker pull opencfd/openfoam-default:2406claude mcp add mcopenfoam -- uv run --directory ~/mcopenfoam-src mcopenfoamThe server runs over stdio with an in-memory queue and the worker in the same process. Jobs live under ~/mcopenfoam/jobs/, and case_path can be any directory on your machine. On a machine with fewer physical cores than a case’s ranks, set MCOPENFOAM_MPI_ARGS='["--use-hwthread-cpus"]'.
On a CFD host
Section titled “On a CFD host”On a shared machine the same code runs as three containers: the MCP server over HTTP, a worker that launches the job containers, and Postgres for the queue and the instrumentation.
-
Put the source on the host and make the env file.
Terminal window cd ~/mcopenfoam-src/deploy && cp .env.example .env -
Edit
.env. The values that matter:Variable Set it to MCOPENFOAM_HOSTthe host’s name; it is the queue name and appears in every event BIND_ADDR127.0.0.1or a LAN address; never a public oneJOBS_HOST_DIRa directory on a large volume: a fine sweep is about 18 GB CASES_HOST_DIRwhere staged cases live; the server mounts it read-write HOST_UID,HOST_GID,DOCKER_GIDyour user and the dockergroup, so files stay yoursRANK_BUDGETthe most ranks one job may take MPI_ARGSe.g. ["--bind-to","core","--map-by","ppr:10:socket"]on a two-socket, 20-core hostPOSTGRES_PASSWORDanything long EMBEDDINGS_URL,EMBEDDINGS_API_KEYoptional; turns on similar failures -
Build the ParaView image and start the stack.
Terminal window make paraviewmake upmake upbuilds the server image and the Postgres image (Alpine Postgres 17 with pgvector), starts all three, and prints their logs. The worker’s first log line names the host, the jobs directory and its host path. -
Reach it from your client. The server has no authentication of its own, so it stays off the public network. Tunnel to it:
Terminal window ssh -f -N -L 8372:<host-lan-address>:8372 <host>claude mcp add --transport http mcopenfoam-remote http://127.0.0.1:8372/mcp -
Check it.
server_infoon the remote server reports the host, the image and whether it is present, the rank budget, the jobs directory as the host sees it, free disk,cases_writable, and the instrumentation backend.
A public endpoint with OAuth
Section titled “A public endpoint with OAuth”deploy/compose.public.yml adds a second server container on the same queue, worker and jobs, with OAuth, published through caddy-docker-proxy at https://$PUBLIC_DOMAIN/mcp. The private server keeps serving trusted clients over the tunnel.
-
Create an OAuth application at your OIDC identity provider: a confidential client with the redirect URI
https://<your-domain>/auth/callbackand the scopesopenid,profile,emailandoffline_access. Bind it to the group of people who may use the server. -
Write
deploy/.env.oauth, which stays out of git:Terminal window MCOPENFOAM_OIDC_CONFIG_URL=https://<idp>/application/o/<slug>/.well-known/openid-configurationMCOPENFOAM_OIDC_CLIENT_ID=<client id>MCOPENFOAM_OIDC_CLIENT_SECRET=<client secret> -
Turn it on in
.envwithPUBLIC=1andPUBLIC_DOMAIN=<your-domain>, thenmake up.
Caddy sends /mcp, the OAuth endpoints and the job-files route to the public server, and everything else on that hostname to whatever else serves it, such as these docs. The sign-in state lives in Postgres, so restarts keep clients signed in.
Updating the code
Section titled “Updating the code”cd ~/mcopenfoam-src && git pullmake -C deploy buildmake -C deploy restartA restart is safe while a job runs: its step keeps running in its container and the new worker re-attaches. Surviving restarts explains how.
Pinning ranks
Section titled “Pinning ranks”Unpinned ranks migrate between cores and share hyperthread siblings with whatever else runs on the host. On one 20-core, two-socket machine this cost about 10% per iteration. --bind-to core --map-by ppr:10:socket puts ten ranks on each socket, one per physical core.