CCPP-TOOLS-MCP · ENGINEERING CALCULATION MCP SERVERSHT 1/8 · REV 0

Deterministic · standards-traceable · stdlib-only core

The agent orchestrates.
Tested code computes.
Every answer carries its evidence.

LLM agents are excellent at driving an engineering workflow in natural language — and terrible at arithmetic. ccpp-tools-mcp splits the work: any MCP client (Claude Desktop, mobile, Claude Code, Cursor) holds the conversation, while every number comes from a pure Python function that returns the governing standard, the equation it evaluated, the assumptions you must own, and the warnings you must not ignore.

11
MCP tools · v1
524
tests green
~1,800
cross-oracle assertions
0
runtime deps in core
1e-8
IF-97 golden tolerance
VIEW SOURCE ON GITHUB →
01 · LIVE TOOL CHAIN — FUEL-OIL TRANSFER CASESHT 2/8

Interactive · real server responses

One real design task, end to end, tool call by tool call

A diesel transfer system — storage tank to elevated day tank — verified through eight tool calls. Every JSON below is an actual response from the server, not a mock. Step through with the buttons or Space. The full Claude conversation is in the repo transcript.


      

02 · THE RESPONSE ENVELOPESHT 3/8

Design principle

A number you can defend, not just a number

Every tool returns the same contract: result with unit-suffixed fields, method naming the standard and the exact equation, assumptions the engineer must own, and warnings that degrade validity.

Warnings are load-bearing. An undersized line answers with the number and a velocity flag. A deep-turndown case flags the laminar–turbulent transition. A near-saturation valve sizing reports choked flow. The orchestrating agent is expected to surface every warning — the case transcript shows that happening.

Refusal over extrapolation. Out-of-range states (IF-97 region 3/5) raise a typed error instead of returning a plausible-looking number. Half of a tool's trustworthiness is what it declines to do.

{
 "result": { "npsha_m": 12.99, "margin_m": 8.99 },
 "method": {
  "standard": "Hydraulic Institute (HI 9.6.1)",
  "equation": "NPSHa = (P_abs - Pv)/(rho g)
               + z_static - h_f,suction"
 },
 "assumptions": [
  "atmospheric pressure 101.325 kPa(a)",
  "vapor pressure 0.5 kPa(a) at pumping temp"
 ],
 "warnings": [],
 "validity": "ok"
}
03 · VERIFICATION — TWO INDEPENDENT LEGSSHT 4/8

Why trust the numbers

Golden tests from the documents, sweeps against independent code

The runtime core is stdlib-only. fluids and iapws are test-only dependencies — so agreement with them is a consensus of two independent implementations, never a circular check.

DomainGolden sourceCross oraclePointsTolerance
IF-97 regions 1/2 (v·h·s·cp)R7-97 Tables 5, 15iapws.IAPWS97~540 gridrel 1e-8
IF-97 saturation lineR7-97 Tables 35, 36_PSat_T / _TSat_P~590rel 1e-8
Water viscosityR12-08 Table 4_Viscosity324 gridrel 1e-8
Colebrook frictionimplicit-equation residual = 0fluids.Colebrook264rel 1e-6
ASME B36.10M tablespot valuesnearest_pipe (every row)89 rows±0.03 mm
Crane K structureTP-410 C·fT formK_*_Crane ratioexactrel 1e-9
ISA 75.01 Cvdefinition identity (1 gpm / 1 psi / water = 1)analyticrel 2e-3
04 · WHAT THE HARNESS CAUGHTSHT 5/8

Kept as evidence, on purpose

The strongest proof of a test harness is a real catch

Both incidents below are preserved in docs/verification.md rather than silently fixed — a verification system you can trust is one that has demonstrably fired.

Catch #1 — five golden values written from memory, rejected by the document

The R12-08 viscosity verification table was first transcribed from memory: 5 of 11 expectations failed. The official release PDF was downloaded and Table 4 re-transcribed — the implementation matched all 11 points unchanged. The memory was wrong, not the code. Rule enforced since: goldens come from documents, never from recall.

Catch #2 — a wall-thickness transcription error in 89 rows

The embedded B36.10M table carried NPS 18 SCH 80 as 23.88 mm. The all-rows sweep against fluids flagged it on its first run; the standard value is 23.83 mm. One wrong digit in 89 rows, caught without human eyes.

05 · IAPWS-IF97 — OWN IMPLEMENTATIONSHT 6/8

Technical highlight

Steam tables from the release document, no library

Regions 1 (compressed liquid), 2 (superheated steam), 4 (saturation), the B23 boundary, and the R12-08 industrial viscosity formulation — implemented in pure stdlib Python directly from the IAPWS releases.

Whether ~130 transcribed coefficients are all correct is decided by the releases' own computer-program verification tables: a single wrong digit breaks 8–9 significant-figure agreement. A ~1,100-point sweep against the independent iapws package seals it.

  • Table 5 (region 1): 3 states × v·h·u·s·cp — rel 1e-8
  • Table 15 (region 2): 3 states × 5 properties — rel 1e-8
  • Tables 35/36 (saturation): 6 points — rel 1e-8
  • R12-08 Table 4 (viscosity): 11 points — print precision
// refusal over extrapolation
water_state(pressure_mpa=30, temperature_k=650)
IF97RangeError: state falls in IF-97 region 3
(near-critical), which is not implemented

// verification anchors (release values)
T=300 K, p=3 MPa   → v = 0.100215168e-2 m³/kg
T=700 K, p=30 MPa  → h = 2631.49474 kJ/kg
psat(600 K)        → 12.3443146 MPa
μ(298.15 K, 998)   → 889.735100 μPa·s
06 · TOOL SURFACE & HONEST LIMITSSHT 7/8

v1 surface

Eleven tools — and a list of what they refuse to pretend

ToolComputesStandard basis
fluid_props_liquidρ · ν/μ · Pv · SG (preset or 2-point fit)API gravity · ASTM D341
fluid_props_steamwater/steam v·h·s·cp·μ, saturation statesIAPWS-IF97 · R12-08 (own)
tank_capacityworking/nominal volume, residence timevolume balance (ahead of API 650)
pipe_size_selectsmallest NPS/SCH meeting a velocity limitASME B36.10M + continuity
pipe_wall_thicknesspressure-design wall vs selected scheduleASME B31.1 §104.1.2
dp_segment_liquidfriction + fitting losses, Re/velocity flagsCrane TP-410 · Colebrook
list_crane_fittingsaccepted fitting keys and K basisCrane TP-410
pump_tdh · pump_npsha · pump_powerhead balance · NPSH margin · powerHydraulic Institute
valve_cv_liquidrequired Cv/Kv + choked-flow checkISA 75.01 / IEC 60534-2-1
  • Decision support, not engineering of record — criterion selection, margins, and code compliance stay with the responsible engineer; every response says so through its assumptions
  • v1 is liquid-service only; compressible dP, heat-exchanger rating, and parallel-flow distribution arrive in v1.1 each with its own validated case
  • The bundled diesel preset is a representative ASTM D975 sample, not project fuel data — stated in every response
  • Crane printed fT vs recomputed fT differ by up to ~9 % — documented in the cross tests, not hidden
07 · GET STARTEDSHT 8/8

Five minutes to a running chain

Point any MCP client at it and paste the case prompt

Claude Desktop (claude_desktop_config.json)

{
 "mcpServers": {
  "ccpp-tools": {
   "command": "uvx",
   "args": ["ccpp-tools-mcp"]
  }
 }
}

Claude Code

claude mcp add ccpp-tools -- uvx ccpp-tools-mcp

Claude mobile / web (HTTP transport)

uv run ccpp-tools-mcp \
  --transport streamable-http --port 8899
cloudflared tunnel --url http://localhost:8899
# add https://<tunnel>/mcp as a custom connector

Links