Mcp Cesm Runner — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Mcp Cesm Runner (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
MCP server for driving CESM case lifecycle: setup → build → submit → monitor.
Complements the CrocoDash MCP, which handles grid creation and forcing. This server picks up where that one leaves off — once a case directory exists, this server drives the CIME build/run pipeline.
| Tool | Purpose |
|---|---|
list_cases(search_root) | Find all CESM cases under a directory |
get_case_status(case_dir) | Read CaseStatus log + key XML config |
check_input_data(case_dir) | Verify all required input files are staged |
All three accept an optional container=<session_name> arg to run inside a crocontainer session instead of on the host, but only for cases made for the container's CIME machine, ubuntu-latest (e.g. /workspace/case after run_case_in_container). A host case (machine=derecho) is refused: bundle it with bundle_case (CrocoDash MCP) and use run_case_in_container.
| Tool | Purpose |
|---|---|
case_setup(case_dir, [container]) | Run ./case.setup |
case_build(case_dir, [container]) | Compile the model (./case.build) |
case_submit(case_dir, no_batch, [container]) | Submit to PBS/slurm or run interactively |
| Tool | Purpose |
|---|---|
xmlquery(case_dir, variable) | Query any CESM XML variable |
xmlchange(case_dir, variable, value) | Set a CESM XML variable |
preview_run(case_dir) | Show PE layout and batch script without submitting |
| Tool | Purpose |
|---|---|
tail_log(case_dir, component, lines) | Read recent run log output |
get_job_status(case_dir) | Check PBS/slurm queue for this case's job |
list_compsets(cesmroot, filter) | List available compsets in a CESM install |
| Tool | Purpose |
|---|---|
build_sandbox([sandbox_dir, rebuild, queue, account, dry_run]) | One-time: qsub a PBS job (~1hr) that builds the Apptainer sandbox; returns the job id and log path. rebuild=True moves an existing sandbox to <path>.old-<timestamp> first; dry_run=True shows the script and command only |
start_container(scratch_dir, [sandbox_or_image, inputdata_dir, name, runtime]) | Start a persistent container session |
run_case_in_container(container, bundle_dir) | Copy a crocodash bundle into the session and run run_case.sh (fork → build → run) |
container_exec(name, case_dir, command) | Run any command inside a running session |
stop_container(name) | Stop and clean up the session |
list_containers() | Show running sessions |
| URI | Content |
|---|---|
cesm://case/{case_dir*}/env | All XML config variables (same as xmlquery(case_dir, "--listall")) |
cesm://case/{case_dir*}/status | CaseStatus log + key config (same as get_case_status) |
cesm://case/{case_dir*}/logs | Log files in the case dir, its RUNDIR and DOUT_S_ROOT/logs |
{case_dir*} takes the case path as-is, slashes included, e.g. cesm://case//glade/u/home/<user>/croc_cases/my_case/status.
pip install -e .
# or in the CrocoDash conda env:
conda run -n CrocoDash pip install -e .cesm-runner-mcp
# or
python server.pyWire up to Claude Code by adding to .mcp.json:
{
"mcpServers": {
"cesm-runner": {
"command": "python",
"args": ["/path/to/MCP_cesm_runner/server.py"]
}
}
}Instead of waiting in the PBS queue, run CESM interactively inside a container. On Derecho, the full GLADE filesystem is mounted transparently so all host paths work inside.
Call build_sandbox() via the MCP: it qsubs the build (Derecho develop queue, 3 h) and returns the job id and log path. build_sandbox(rebuild=True) replaces a stale sandbox, keeping the old one as <path>.old-<timestamp>. Or build it by hand:
# Build the writable sandbox (~1 hr on a compute node)
qcmd -l walltime=03:00:00 -- apptainer build --sandbox \
/glade/derecho/scratch/$USER/crocontainer_sandbox \
docker://ghcr.io/crocodile-cesm/crocontainer:latest-amd64The container only builds and runs cases for its own CIME machine (ubuntu-latest), so a case made on Derecho goes in as a bundle, which run_case.sh forks for ubuntu-latest:
bundle_case("~/croc_cases/mycase", "~/scratch/croc_bundles") # CrocoDash MCP
start_container(scratch_dir="~/scratch/croc_scratch")
→ Apptainer instance starts; /glade mounted; inputdata at /glade/campaign/cesm/cesmdata/inputdata
run_case_in_container("croc_session", "~/scratch/croc_bundles/mycase_case_bundle")
→ forks the case to /workspace/case, builds and runs it; no queue
# Debugger MCP finds an error → fix → resubmit inside the container:
container_exec("croc_session", "/workspace/case", "./xmlchange STOP_N=3")
case_submit("/workspace/case", no_batch=True, container="croc_session")
stop_container("croc_session")CESM inputdata is mounted directly from GLADE — no downloading required: /glade/campaign/cesm/cesmdata/inputdata → /root/cesm/inputdata inside container
start_container(
scratch_dir="./scratch",
sandbox_or_image="ghcr.io/crocodile-cesm/crocontainer:latest",
inputdata_dir="./cesm_nyf_inputdata", # pre-downloaded NYF data
runtime="podman"
)./xmlquery, ./case.setup, etc. directly — version-safe and matches what users run manuallycontainer= to route via apptainer exec instance:// or podman exec instead of running on the hostDefault reference install: ~/work/installs/CESM_crocodash (CESM branch crocodash)
Cases live in: ~/croc_cases/
CESM inputdata: /glade/campaign/cesm/cesmdata/inputdata
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.