Otter puts a Claude Code agent in the accelerator control room: an operator asks in plain language, the agent mines the Badger run archive and the live machine, drafts a validated tuning routine and runs it through Badger, behind a hook-enforced approval chain. I am its sole author. On an LCLS shift in June 2026 one campaign, launched on the operator's approval and then left to run, took the FEL pulse energy from 0.47 to 1.82 mJ in 88 evaluations.
- 0.47 → 1.82 mJLCLS HXR pulse energy, one campaign
- 88 · 19 min · 0evaluations · wall time · beam-loss violations
- 44validated routines drafted, 2.5–3 min from ask to beam
Why
Badger made advanced optimizers a one-click routine, but someone still has to write the routine: knobs, ranges, generator, hyperparameters, constraints. That knowledge is spread across past runs, operators' heads and documentation. Otter asks whether an agent can assemble it from evidence fast enough to matter on shift, without ever being the thing that writes to the machine.
How
Otter is built on LBNL's open-source Osprey harness (Claude Code as the runtime, MCP servers as tools, safety enforced by the runtime rather than the prompt). On top of it I wrote two MCP servers, 35 tools, and four skills:
- Evidence, in order. Tools mine the Badger archive, read live PVs with their limits, and fall back to an offline knowledge pack (no embeddings, no network). A live read outranks an archived recipe, which outranks a document; every hyperparameter in a saved routine is traceable to one of the three.
- Three skills, three rungs.
/propose-routinedrafts one routine for the operator to launch./auto-tuneranks knobs by historical impact, plans stages and runs them back to back in one Badger window, through a small file-based remote-control surface I added to Badger./auto-tune-facet-yamlcomposes a multi-phase injector bring-up as YAML and runs it through a check, run, verify, retry engine that restores the machine on failure. - Approval chain. Every hardware-affecting tool passes three PreToolUse gates: a writes kill switch that fails closed, a channel-limits database, then a human approval prompt. In the control room the controls server cannot write PVs at all; the only path to the machine is a routine run through Badger, with its own operator confirmation.

Results
I ran all of the LCLS and FACET-II testing, with the operator on duty holding the trigger.
/auto-tune campaign on LCLS, from the Badger archive: HXR pulse intensity (80th percentile) at every evaluation. Stage 1, UCB on four LTUH matching quads; stage 2, EI on eight LI26 quads, in the same Badger window. The agent skipped a planned third stage when stage 2 added only 0.5%.- LCLS campaign. 0.47 to 1.82 mJ in 88 evaluations and about 19 minutes, zero beam-loss violations, knob ranking drawn from 529 archived runs. The start was a real beam sag, so part of the gain is recovery; 1.82 mJ was still the evening's peak, above the operator's manual simplex baseline of 1.75 mJ.
- LCLS routines. 44 validated routine YAMLs across the LCLS sessions (20 on the 26 June shift), 2.5–3 minutes from request to beam. Two sessions ended in an operator veto at the launch prompt: the path working as designed.
- FACET-II injector, 1 July 2026. Five complete six-phase campaigns (BAX laser steering, BOED Schottky timing, extremum-seeking orbit, energy spread, emittance, TCAV phasing) at 1600, 2000 and 2200 pC, 15–23 minutes each; the one hard failure, a klystron timeout, was retried autonomously and passed. An end-to-end pipeline validation: pre-checks that night found disconnected PVs, so no emittance numbers are quoted until beam provenance is confirmed.
What I did. Sole author of Otter: the two MCP servers, four skills, knowledge pack, deployment to two control-room hosts without internet access, and all of the experiments. The per-phase FACET-II physics routines (BAX, BOED, the BO stages) come from SLAC's autonomous-control package; mine is the MCP wrapper, worker, verifier and workflow engine around them. Osprey itself: #2 code contributor (249 commits, November 2025 to March 2026: terminal UI, typed event streaming, provider adapters).
Numbers are from Badger archive runs and agent transcripts on both control-room hosts, June to July 2026.