My AI Experience with the SUEWS-agent 3: Why and how we built the SUEWS-agent

SUEWS is the urban climate model I help develop.
It simulates how cities exchange heat and water with the atmosphere, and researchers around the world use it for questions ranging from neighbourhood-scale heat to city-scale climate adaptation.
It is the work of many people over many years, with the science to show for it.

It also has an honest problem: the cost of entry.
Before you can ask SUEWS anything, you have to describe your city to it, the surfaces, vegetation, buildings and people, all in a long and exacting configuration.
The format is well documented, and recent releases have made it far cleaner, but a serious model still asks a lot up front, and new users can spend their first weeks on setup rather than science.
Over the years I have watched that cost quietly keep out some of the people we most want to reach: practitioners, planners, students, researchers from neighbouring fields.

There is a quieter version of the same problem on our side of the fence.
SUEWS keeps evolving, and every time it does, the documentation, the examples, the schema, the release notes and the user guidance all have to move with it.
We are a small team, we try hard, and we have made real progress, yet some drift between the code and everything written about it is almost unavoidable.
With open-source software the code is the final source of truth, but reading the code is not something most users can or should have to do.
So when the docs and the code fall out of step, that gap quietly becomes a barrier, for users trying to get started and for us trying to keep it all aligned.

I should be candid about how I got here.
I have used ChatGPT since more or less the day it appeared, and it felt revolutionary straight away, genuinely useful in my own work.
At first the gains were on the developer side: it helped me write code, from quick research scripts to the harder internals of the model.
Over the last two years that help has let SUEWS and its Python wrapper SuPy move faster, with steadier releases and some bigger structural work, including retiring the old f2py bridge layer between the Fortran core and Python in favour of cleaner, Rust-based internals.
But all of that was felt by us, the developers, not by an ordinary SUEWS user staring at a configuration file.
That is the gap the SUEWS-agent tries to close.

The piece that made it feel possible was MCP, the Model Context Protocol.
When Anthropic released it, a protocol that lets an AI agent call structured tools rather than only chat, I watched closely, because it looked like the right bridge between an AI and a piece of scientific software.
I tried several ways to wire it into SUEWS before the current design finally became concrete.

So alongside the latest SUEWS release we built the SUEWS-agent.
Rather than let an AI chat loosely with the documentation, we expose SUEWS as the SUEWS-specific part of the agent’s harness: a small set of structured tools, each doing one well-defined job.
It can create a starter configuration for a site from a plain-language description.
It can inspect that configuration and tell you which site-defining values are still just sample defaults.
It can validate a setup by running SUEWS’s own checks, rather than trusting the model’s prose that it looks fine.
It can run the simulation once the setup is genuinely ready.
And it can diagnose and summarise the output, explaining what came back or flagging why a run cannot yet be trusted.
The SUEWS-agent is not the whole agent; it is the SUEWS-specific harness layer.
The brain and the back-and-forth come from a host like Claude Code or Codex, while SUEWS itself stays the physics model underneath.
Plain language in, physically grounded simulation out, the science in the middle untouched, and all of it open to inspect.

What took the real care was not the tools but the guardrails around them, because an agent that is confidently wrong about a city’s climate is worse than no agent at all.
The clearest way to see what that means is to put each guardrail next to the failure mode it is meant to prevent.

Figure: observed SUEWS MCP outputs from 19 June 2026. The same Day 1 configuration passes structural validation but fails readiness, while an intentionally broken configuration is caught by validate_config. Valid is not the same as ready.

Three guardrails do most of that work.

First, readiness, which stops a legal file from being mistaken for a ready one.
This is a small distinction in wording, but a large one in practice.
Validation asks whether the file is structurally acceptable to SUEWS; readiness asks whether it is specific enough to trust as your site.
Structural validation alone will happily pass a configuration that is well-formed but still describes the bundled sample.

validate_config   ->  status: success · is_valid: true · error_count: 0   (the file is legal)
assess_readiness  ->  status: success · ready: false
                      2 site-defining values still sample defaults:
                        - location: bundled KCL/London
                        - forcing:  Kc_2012_data_60.txt

Same file, two verdicts: legal, but not yet yours.

Second, validation that comes from the model, not from the agent’s say-so.
When the agent calls a configuration valid, that verdict is SUEWS’s own schema speaking, not a sentence the agent wrote to sound confident.

with (observed):        validate_config -> is_valid: false · error_count: 22
                        first errors: invalid tstep; required physics choices missing
without (illustrative): you would be trusting the agent's prose, e.g. "looks fine to me"

Third, provenance, so a result can always be traced back to what produced it.
Every result the agent returns carries the versions and commit it came from.

with (observed):        schema_version: 2026.5 · suews_version: 2026.6.5 · git_commit: 9dae7a8
without (illustrative): a number with no record of how it was made, and no way to defend it

None of this was designed in the abstract.
I built the first version, then took it to Professor Sue Grimmond (@Sue.Grimmond) and asked her to test it as hard as she could.
She is the right person to ask: much of SUEWS grew out of her work, and she carries the judgement about urban climate that the model itself was built on.
She went at the hard cases deliberately, pressing the agent with the tough, probing questions that only that depth of experience can pose.
The agent and I worked through them, wrote down where it fell short, and went round again several times before this version saw daylight.
Most of what I would call the design is really the residue of those failures.

If there is one belief underneath all of it, it is that for science the guardrails matter more than the cleverness.
It would have been easier, and flashier in a demo, to let the agent improvise freely.
We chose the opposite, to make it hard for the agent to produce something that looks right but is not, because a tool a planner or a student can trust is worth more than one that dazzles and confidently gets it wrong.

You saw it work on day one of this series: a London neighbourhood described in a sentence, configured, validated and run.
On 24 June 2026 we hand all of this to a roomful of people at the first SUEWS Community Hackathon, many of whom will never have run a climate model before, and find out what happens.

In the next post, I’ll move from running a model to doing research, and how to ask better questions.

1 Like