Coding Agents¶
OpenFlowsheet is built to be driven by coding agents as well as by people. Agents and humans use the same contract: the same operations, the same documents, the same refusals. Nothing an agent does bypasses validation, and nothing it reports needs to be taken on trust — every result points at a certificate and a replay bundle.
Three ways in¶
| Door | Best for | Start with |
|---|---|---|
| Python | an agent that writes and runs code in a notebook or script | LocalApplication (API) |
| CLI | an agent with a shell | openflowsheet api --project <dir> <operation> --json … (tutorial) |
| MCP | an assistant that calls tools | openflowsheet serve-mcp (needs the server extra) |
HTTP (openflowsheet serve-http) serves the same operations under /v1 for a client of your own.
MCP¶
The MCP server speaks over standard input and output, and serves one tool per operation that is
offered on MCP (validate_revision, commit_change, preview_change, submit_job, wait_job,
get_job_result, list_models, get_artifact, inspect_structure and the other inspection
tools). Each tool's description is reviewed text that ships with the package, and each result
carries its JSON schema. Solves run as jobs (submit_job, then wait_job).
Grant the agent a capability with only the rights it needs, and point the client at the server:
openflowsheet project init plant
openflowsheet project grant --project plant --principal agent --rights read,draft,execute > token.txt
# Claude Code, for example:
claude mcp add openflowsheet -- openflowsheet serve-mcp --project "$PWD/plant" --token-file "$PWD/token.txt"
grant prints the token once; keep the file private. Authority comes from the credential only:
the server never trusts an identity a request claims, and every call — refused ones included — is
in the project's audit log (list_audit).
Asking an agent to work with OpenFlowsheet¶
A good request names the process, the property basis, the specifications and what must come back as evidence. For example:
Using OpenFlowsheet's MCP tools, build a Rankine cycle on IAPWS-95 water: 1 mol/s, pump to 3 MPa (efficiency 0.75), boiler to 673.15 K, turbine to 10 kPa (efficiency 0.85), condenser to saturated liquid. Validate it, solve it, and report the thermal efficiency with the run id, the verification status and any certificate check that did not pass.
Rules worth giving an agent, because they are how the software is meant to be read:
- Check the verdict, not just the outcome.
CONVERGEDis the solver's view; only aVERIFIEDcertificate says that every residual, balance and specification check passed at its registered tolerance. ReportRELAXED,UNVERIFIEDandFAILEDas such. - Treat a refusal as an answer.
model_unsupported(...),revision_not_readyorINITIALIZATION_FAILEDmean the request is outside what is supported; they are not obstacles to work around by loosening a tolerance or swapping a model silently. Read its explanation'skindandactionfirst (below). - Keep the claims apart. A verified solve is numerical verification of the stated equations
at the stated state. It is not empirical validation of the property model, and not an optimality
claim. The certificate's
statementssay so in words an agent can quote. - Use
list_modelsandinspect_structurebefore guessing. They state every model's ports, parameters and accepted specifications, and the degrees of freedom of a revision. - Commit against the head you read.
commit_changetakes the expected head revision and an idempotency key; a conflict is reported, never overwritten.
Reading what went wrong¶
Every refusal and every failed solve explains itself, in the same document on every transport (Messages):
- A refusal is an
ApiErrorwhosedetail.explanationholds the explanation:summary,cause,why(with the numbers),action,kind, theelementsinvolved, thenumbers, thechainof codes and thedocslink to the code's section. The machinecode,messageand the otherdetailmembers are unchanged. - A solve that did not converge returns normally; its
RunResult.failure(onget_job_result) holds the outcome, the stored failure message, the implicated elements, the suggested actions, the failure bundle's artifact id and the sameexplanation.failureisnullfor a converged run. kindsays whose move it is:input(change the flowsheet or the request),not_supported(a limitation; change the approach, not the numbers),numerical(the flowsheet may be right; try another start or policy),bug(report it),notice(not a failure).gap, on anot_supportedexplanation, names the limitation (its support-matrix row) and the missing capability. It is the answer to "can OpenFlowsheet do this?", and the reason not to retry.explain(openflowsheet explain <code>, theexplaintool,GET /v1/explain/{code}) returns any code's catalogue entry: what it means, the rule, what to do and an example. An unknown code is refusednot_foundwithdetail.suggestions.
For agents working on OpenFlowsheet itself¶
The repository's CLAUDE.md holds the working rules for agents that change the code: the design
authorities, the two-lane protocol, branch and evidence discipline and the scientific conduct the
project holds itself to.
What has been measured about agents
The agent evidence so far is limited: one pinned model and configuration, over MCP only, on registered tasks (see Limitations and support).