Abstract
On Tuesday, 6 October 2026, UCR Research Computing built and released nrp-mcp, an open-source Model Context Protocol (MCP) server that lets a researcher use the National Research Platform's Nautilus cluster from the AI assistant they already use. The researcher describes what they want in plain language; nrp-mcp reads the project, writes the Kubernetes manifests, checks them against NRP policy, explains the plan, and runs nothing until the person says yes. It went from a written plan to version 0.3.0 by late morning and to 0.6.4, public and tested on Windows, macOS and Linux, by late afternoon. That evening five independent adversarial reviews judged the idea sound and the tool not yet safe for unsupervised students. This note covers what was built, how it was tested, and what the reviews found.
As with earlier field notes, the work was directed by me and carried out mostly by an AI agent (Hermes) under a written spec, live tests and explicit approval steps.
The Problem
Nautilus is a large, shared Kubernetes cluster run by the National Research Platform and open to researchers at member institutions. It has GPUs, storage and hosted language models, at no charge to the researcher. The barrier is the interface. A researcher whose work lives in a Slurm batch script has to learn containers, Jobs, Indexed Jobs, persistent volumes, Ingress and NRP's own usage rules before the first result comes back. Most of them have papers to write instead, and the ones who do learn it can still break NRP policy without meaning to.
The Tool
nrp-mcp is a single Go binary that runs on the researcher's own computer, uses their own kubeconfig and NRP sign-in, and offers nine tools named for intent rather than for Kubernetes objects:
| Tool | Changes things? | What it does |
|---|---|---|
nrp_setup |
only when asked to fix | Laptop readiness: kubectl version, the sign-in plugin, the NRP config file, sign-in; installs or updates with a yes |
nrp_status |
no | Namespaces, GPU quotas, running work, volumes, public URLs, policy warnings |
nrp_plan |
no | Reads a project and a goal (job, sweep, web, session, llm-batch, volume, pull), applies every rule, and returns the plan, the refusals, the manifests and a confirm token |
nrp_run |
yes, with a token | Runs an approved plan; anything public also needs an explicit acknowledgement |
nrp_watch |
no | Progress, logs, a plain-language diagnosis with a fix |
nrp_cleanup |
yes, two steps | Lists your runs, deletes one after a second confirm |
nrp_session |
no | A private Jupyter or VS Code session via port-forward |
nrp_data |
uploads only | Small uploads and result downloads on a volume |
nrp_build |
no | Suggests a Dockerfile and an NRP GitLab CI file to build an image |
In practice a researcher says things like "run this script on a
GPU", "run it 200 times with different seeds", "move my Slurm job
here" or "put my lab's tool on the web". A Slurm script's
#SBATCH lines are translated, and anything with no
equivalent is named rather than silently dropped.
The Day, Release by Release
- Morning: plan. A written plan named the server, fixed the tool prefix, and added web hosting to version 1 with a guard that refuses to publish until the person types the URL back.
- 0.3.0 (10:52 EDT). Eight tools, a rules engine, and the plan, confirm, run sequence.
- 0.4.0 and 0.4.1 (11:04 to 11:13). Data and session tools tested live; a live parameter sweep as an Indexed Job; a first public web publish of a small leaf-area example app, live over HTTPS in about a minute and then taken down and cleaned up.
-
0.5.0 (12:06).
nrp_setup, because the real first step is the laptop, not the cluster. - 0.6.0 (12:47). Public release preparation: per-person cleanup, one namespace resolution path, a release workflow, an install script, community files and a rewritten README. The repository went public.
- Cross-platform CI (13:15). A setup test on fresh Windows, macOS and Linux runners, with a no-sign-in mode for CI.
- 0.6.2 (13:50). Tool schemas made single-typed after one assistant rejected a schema the others accepted. Three assistants tested end to end: Hermes Agent, Gemini CLI and OpenCode.
-
0.6.3 (15:05). Each Slurm array task now gets its
own
SLURM_ARRAY_TASK_ID, with a bootstrap example and a live array check. - 0.6.4 (16:49). Pod and GPU caps now count what runs at once, not a sweep's total.
The largest live run of the day was a 60-task sweep that ran 20 at a time under the default limit. No GPUs were used for testing, and the namespace was left empty at the end of the day.
The Guides Behind It
The tool leans on documentation that went live the same morning: an eight-part researcher guide to Nautilus on the Research Computing website (KB023 to KB030) covering access, notebooks, batch and GPU work, storage, the hosted language models, hosting a lab web tool, and teaching a class. nrp-mcp serves those guides as resources, so the assistant can point a person to the page that explains what it just did. A set of 20 worked research examples, from seismic waveform processing to econometrics Monte Carlo studies, was written and reviewed alongside it.
Five Adversarial Reviews
Anything handed to students has to be read by people looking for its faults. Five independent reviewers each took one area. None of them touched the live cluster; bugs were reproduced on local test clusters, in containers and in unit tests.
| Area | Critical | High | Medium | Low |
|---|---|---|---|---|
| Security | 0 | 2 | 7 | 7 |
| Correctness and fuzzing | 0 | 12 | 15 | 14 |
| Cross-platform installs | 2 | 3 | 7 | 8 |
| Robustness on Kubernetes | 1 | 10 | 10 | 6 |
| Design and value | 1 | 8 | 5 | 3 |
Many findings overlap; together they make about 30 distinct issues. The headline answers:
- Is it a good idea? Yes. Nothing else the reviewers found takes a researcher from a Slurm script or a folder of code to a policy-compliant sweep on Nautilus. The Go code was called clean and portable, the confirm tokens well built, the downloads properly verified.
- Is it secure? Mostly by design: no local shell, argument-only kubectl calls, cryptographic tokens, checksummed downloads. But it has two real holes. The project packer could include credential files, and two people in one shared namespace choosing the same volume name could end with one deleting the other's data. The "nothing runs without your yes" promise is also not enforced, because the model can see the token.
-
Is it stable? The happy paths work. Just off
them, common inputs break: projects over 256 KB, file names with
spaces, static sites, a volume used for over an hour, and
real-world Slurm time strings. A request for
--time=0-06:00was being read as one hour. - Is it cross-platform? The binary is. The install story is not yet: some macOS and fresh Linux setups leave it off the PATH, and Windows lacks a student-ready installer.
The reviewers' recommendation: a supervised, CPU-only workshop exercise is fine once the priority list is fixed; other labs get a supervised pilot in their own namespace; wider promotion waits.
What Went Wrong
- Released before it was reviewed. The repository went public at midday and the adversarial reviews came back that evening. The order should have been the other way round for anything a student might run unsupervised. Nothing was harmed, but the README briefly claimed shared namespaces were safe, and they are not yet.
- A schema only one client rejected. A tool schema that most assistants accepted was refused by one. Testing against a single client would have shipped it broken for that client's users.
- One reviewer was stopped by a content filter. The first security review was blocked partway through by the model provider's filter and had to be rerun with a narrower, defensive brief.
- The large-project path is untested. Small projects are copied straight into a stock container. Bigger ones need an image built on NRP GitLab, and that path has generated its files correctly but has never been driven end to end.
Patterns Worth Keeping
- Plan, confirm, run. Every change returns a plan and a token first; nothing changes on the cluster without the second step.
- Start at the laptop. Most first-day failures are local: wrong kubectl, no sign-in plugin, no config file.
- Name intents, not objects. "sweep" and "web" are what people want; Indexed Jobs and Ingress are how.
- Test against several assistants. MCP clients differ in what they accept.
- Publish the reviews. The five reports, a summary and a combined fix list are kept with the project, so the gap between what the tool claims and what it does is on the record.
What Is Next
- Fix the two security holes and the issues that would break a supervised workshop exercise, before next Monday's lab workshop.
- Drive the GitLab image-build path end to end with a project shaped like a real lab web application, before recommending it to labs with larger tools.
Repositories
The review reports, the research examples and the workshop materials live in a private planning repository. Figures in this note come from the git history, the review summary and the live test runs recorded during the day.