Skip to main content
Glama
ispacex
by ispacex
README.md
# boinc-central-mcp

An MCP server (stdio) that lets agents see batch status and fetch batch output on
[BOINC Central](https://boinc.berkeley.edu/central/) without a browser. It works with
BUDA (Docker) batches and other remote-submission apps, and with any BOINC project
that runs the standard job-submission code.

The server only calls the API BOINC already has, so the server side needs no changes:

| What | BOINC endpoint | Auth |
|---|---|---|
| batches, jobs, abort, retire | `submit_rpc_handler.php` (XML RPC: `query_batches`, `query_batch`, `query_job`, `query_completed_job`, `abort_batch`, `retire_batch`) | `<authenticator>` in the request |
| batch output tar | `get_output3.php?action=get_batch_tar` (the "Get tarred output files" button) | web cookie `auth`, whose value is the same authenticator |

## Tools

| Tool | What it returns |
|---|---|
| `list_batches(state?)` | Your batches, newest first. `state` is one of `init`, `in_progress`, `complete`, `aborted`. The server leaves retired batches out. `app_name` is `buda` for BUDA batches. |
| `batch_status(batch_id, runtime_sample=0)` | State, fraction done, job counts (`done`, `in_progress`, `unsent`, `failed`), submit and finish times, batch turnaround, credit and the web URL. With `runtime_sample=N`, also the median elapsed and CPU time of N completed jobs. |
| `batch_jobs(batch_id, status?, limit=200, offset=0)` | One row per job: id, name, status, canonical instance, CPU time. Failed jobs also carry exit codes and error flags. |
| `job_details(job_id, job_name?, stderr_tail=3000)` | A job's instances and their states. With `job_name`, also the exit status, elapsed and CPU time, and the tail of stderr. |
| `download_batch_output(batch_id, dest_dir, extract=false)` | Writes `dest_dir/batch_<id>.tar` and returns the path, byte count and file count, never the contents. With `extract=true` it also unpacks the tar safely into `dest_dir/batch_<id>/`. |
| `abort_batch(batch_id, confirm)` | **Destructive.** Aborts the batch. You must pass `confirm=true`. |
| `retire_batch(batch_id, confirm)` | **Destructive.** The server deletes the batch's collected output at once. You must pass `confirm=true`. |

The read-only tools carry `readOnlyHint`, and the two destructive ones carry
`destructiveHint`.

### About "median turnaround"

The RPC API does not give per-job sent or received times, so these figures come from
what the API does give:

- `batch_turnaround_s` is the finish time minus the submit time. For a running batch,
  it is the time elapsed so far.
- `median_turnaround_s` is the batch field the web page labels "Median turnaround
  time" (`expire_time`). BUDA leaves it unset, so for BUDA batches it is usually
  `null`.
- `runtime_sample` gives median run times of completed jobs.
- `median_job_turnaround_s` is the median of received time minus sent time over the
  canonical instances. It appears only when the server reports those times, which
  needs the proposed BOINC change on the
  [`remote-batch-output-auth`](https://github.com/ispacex/boinc/tree/remote-batch-output-auth)
  branch.

## Setup

1. **Get your account key, the authenticator.** Log in to BOINC Central and open
   *Your account → Account keys*
   (<https://boinc.berkeley.edu/central/weak_auth.php>). Copy the value shown under
   "Your account key is:". Do not copy the *weak* account key below it, because the
   RPC API does not accept the weak key.
2. **Put the key in the key file and lock it down.**

   ```sh
   mkdir -p ~/.config/boinc-central
   ( umask 077; pbpaste > ~/.config/boinc-central/authenticator )   # or use an editor
   chmod 600 ~/.config/boinc-central/authenticator
   ```

   The server refuses to read the file if group or others can read it.
   `BOINC_CENTRAL_AUTH_FILE=/path/to/file` points the server at another file. Only a
   path is accepted: the key itself is never taken from a tool argument or an
   environment variable value. The server also removes the key from any error text
   before an agent can see it.
3. **Register the server with Claude Code.**

   ```sh
   claude mcp add boinc-central -s user -- \
     uvx --from git+https://github.com/ispacex/boinc-central-mcp boinc-central-mcp
   ```

   To run from a local checkout instead:

   ```sh
   claude mcp add boinc-central -s user -- \
     uv run --directory ~/work/math/boinc-central-mcp boinc-central-mcp
   ```

   `BOINC_CENTRAL_URL` (default `https://boinc.berkeley.edu/central/`) points the
   server at another BOINC project.

Your account needs remote-submission access (a `user_submit` record), which every
account that can submit BUDA jobs has.

## Development

```sh
uv run pytest
```

The tests use recorded-format XML fixtures (`tests/fixtures/`) and an
`httpx.MockTransport`, so they need neither network access nor a key. They pass with
`mcp` 1.x (`FastMCP`) and 2.x (`MCPServer`, the renamed FastMCP).

## TODO: submitting BUDA batches

There is no RPC for submitting BUDA batches. `buda_submit.php` is a web form that
authenticates by cookie. It submits in two steps:

1. Upload the batch `.zip` to your sandbox (`sandbox.php`, `action=upload_file`,
   multipart).
2. Request `buda_submit.php?action=submit&app=…&batch_file=…&max_runtime_days=…&exp_runtime_days=…&cmdline=…`.
   This runs `create_work` with BUDA's `sub_appname` and templates.

The generic `submit_batch` RPC does not set those up. A `submit_buda_batch` tool could
drive the two web steps with the same `auth` cookie. A cleaner route is a
`submit_buda_batch` RPC upstream in BOINC.

## License

MIT, see [LICENSE](LICENSE).