Skip to main content

casino-mcp

An MCP control plane over the Fortran CASINO quantum Monte Carlo code: start runs, know what is running, stop them, and read an out file as structured data instead of shipping 4000 lines of text into a model's context.

Alpha (0.1.0). The four control tools and the out parser are done and tested; the tool that returns physics to the model is not shipped yet. Interfaces may still move.

What it is, and what it is not

CASINO already has the primitives — opt_plan, runqmc --auto-continue, multirun, envmc, make_E_v_dt. What it has no place for is the layer between them: machine-readable results, a memory of what was run, and the judgement calls that sit between the steps ("has the variance plateaued?", "is this timestep still in the linear regime?"). That layer is what this package is, and three rules keep it honest:

  1. No number is produced by the model. Every value a tool returns is read from a file and carries the line it came from. What CASINO did not print comes back as null with a reason, never a guess.
  2. Every result is reproducible from its record. A job record freezes the command, the process count, and the path, size and mtime of the casino binary that ran.
  3. Nothing destructive is implicit. A run refuses to start in a directory that already holds results, and refuses harder when that out is committed reference data.

There is deliberately no execute_shell(command) tool. Every tool is a named CASINO operation with typed arguments.

Install

pip install casino-mcp          # needs Python 3.11+ and a working CASINO installation

From a checkout:

pip install -e '.[dev]'

The package does not bundle, build or replace CASINO. It drives runqmc, which stays the runtime: arch detection, MPI variants, batch-queue submission and the lock file are its job, not ours.

Register it with Claude Code

.mcp.json, project scope:

{
  "mcpServers": {
    "casino": {
      "command": "casino-mcp",
      "args": ["serve"],
      "env": {
        "CASINO_HOME": "/home/you/bin/CASINO",
        "CASINO_ARCH": "linuxpc-gcc-parallel.openblas"
      }
    }
  }
}

Tools

tool returns
casino_run(workdir, nproc, version, overwrite, unlock) job_id, pid, workdir, command, binary stamp
casino_status(job_id) running / finished / failed / stopped / unknown, pid, runtime, exit code
casino_stop(job_id, timeout) what was signalled, final status
casino_list_jobs(limit) every known job, newest first

The runtype (vmc, vmc_opt, vmc_dmc, …) comes from the input file in workdir; there is no tool per runtype, because that multiplies the surface without adding a capability.

Command line

The same runtime without a model in the loop — which is also how you debug the server:

casino-mcp config                  # the resolved configuration, and the files it came from
casino-mcp run ./calc -p 4         # start a calculation
casino-mcp status 20260823-164511-qobn
casino-mcp stop   20260823-164511-qobn
casino-mcp jobs                    # the registry, newest first
casino-mcp parse ./calc            # the `out` file as JSON
casino-mcp serve                   # the MCP server on stdio

Every subcommand prints JSON and exits non-zero when that JSON carries an error.

Configuration

There is no configuration file. An MCP server is configured where it is registered — the env block of the .mcp.json above — and CASINO's own variables keep their names, so setting them once configures both layers:

variable
CASINO_HOME root of the CASINO installation (default ~/bin/CASINO)
CASINO_ARCH build target, the directory under bin_qmc; used to stamp which binary a job ran
CASINO_RUNQMC explicit path to runqmc; otherwise PATH, then $CASINO_HOME/bin_qmc/runqmc
CASINO_MCP_STATE_DIR the job registry; otherwise $XDG_STATE_HOME/casino-mcp
CASINO_MCP_FORBID directories no run may ever touch, :-separated like PATH

Everything else — one MPI process, the opt binary, twenty seconds between SIGTERM and SIGKILL, two hundred job records kept — is a constant in settings.py. casino-mcp config prints what the server would use right now and which variable said so; run it first when a tool call refuses.

CASINO_MCP_FORBID is the one guard with no per-call override. overwrite=true and unlock=true unlock the other two; a directory listed here cannot be run in at all, which is what makes it the right place for a tree of committed reference calculations.

How it works

Claude Code ──stdio──> server.py ──spawn──> launcher.py ──> runqmc ──> mpirun ──> casino
                          │                     │
                          │                     └─ writes status.json (exit code, end time)
                          └─ reads/writes jobs.json + one directory per job

State lives outside the calculation, under $XDG_STATE_HOME/casino-mcp/:

jobs.json                    index: job_id -> record
jobs/<job_id>/meta.json      what was launched, frozen at spawn
jobs/<job_id>/status.json    written by the launcher when the run ends
jobs/<job_id>/runqmc.log     runqmc's own output (not CASINO's `out`)

The calculation directory only ever gets what CASINO puts there.

Why a launcher process. runqmc is a bash script that execs mpirun -np N casino; signalling its pid orphans the tree. The launcher runs in its own session, so killpg reaches everything, its exit code survives the MCP server being restarted, and runqmc's output goes to a log instead of the JSON-RPC stream. A recycled pid cannot pass for a live job: /proc/<pid> start time is compared, and a zombie does not count as running.

The out parser

parse_out is a plain function with no MCP and no dependencies. An out file is a sequence of phases, not one result — vmc_opt writes a VMC and an OPTIMIZATION phase per cycle, vmc_dmc writes VMC, DMC equilibration and DMC statistics accumulation — so it returns phases, and result points at the last phase that carries an energy.

from casino_mcp.parse_out import parse_out

parsed = parse_out('./calc')
parsed['result']['energy']  # {'value': -2.861829862553, 'error': 0.000659077167, 'line': 237}

The one derived number in it is the sample-variance error of a single-block run, which CASINO does not print; it is taken from the one block exactly as envmc does, and labelled derived. Nothing shells out to envmc or endmc at runtime — endmc misparses numbers under a non-C locale.

Tests

pytest                      # 102 tests, ~2 s, no CASINO needed

The unit suite runs anywhere: the parser is checked against five real out files committed under tests/data/, and the launcher, the process group and the guardrails are exercised against a fake runqmc shell script.

pytest -m integration --examples-dir ~/PycharmProjects/PyCasino/examples

The integration suite needs a real CASINO. It checks parse_out against CASINO's own envmc over an entire examples tree (526 files, ~50 s), and drives the server over real stdio MCP, running and stopping actual VMC calculations.

tools/protocol_dump.py speaks the JSON-RPC by hand with no SDK and prints every line in both directions. Read it before adding a tool.

Licence

MIT.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

casino_mcp-0.1.0.tar.gz (62.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

casino_mcp-0.1.0-py3-none-any.whl (22.2 kB view details)

Uploaded Python 3

File details

Details for the file casino_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: casino_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 62.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for casino_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c375cc275b2a12155c7a53d0fffd109c6142692154bc3ff3ff1b818e4b323cb7
MD5 d3383f6f0b58691b75ce1f2cc8e97e01
BLAKE2b-256 4b8c18ec87e7f3634703776a8dab08000cc218a02242977458b56cf2ef4aa804

See more details on using hashes here.

File details

Details for the file casino_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: casino_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 22.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.12.3

File hashes

Hashes for casino_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8b72e2d4a77f7dd5b604f0e5f1fb00bb1109a09789bc41903d993fddc30f23e2
MD5 9cc9eef0b18ea49a1ac16f084ed64887
BLAKE2b-256 712b1d5d6c94e8af0e4264a5f1aaf3f7a190fc1b344ce389f9e1a0873edb8653

See more details on using hashes here.

Release history Release notifications | RSS feed

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page