- tools/physics-sanity/ — JS library of cross-node balance helpers
(mass / hydraulic / hydraulic-power / oxygen-transfer / energy) with
7 unit tests + a CLI demo. Designed for `require()` from per-node
integration tests where shape-based unit tests miss physically-
impossible plant states.
- tools/docker-compose.yml + tools/mcp/{node-red-admin,influxdb,browser}
scaffolding — placeholder Dockerfiles + a ROADMAP.md for the Node-RED
admin MCP. Compose file is the target shape for the Q3-2026 migration
to the central MCP server; the per-service Dockerfile stays in this
repo as the canonical definition either way. Implementations are TODO.
- tools/README.md — top-level tooling index; documents the CI order for
running every tool on a PR.
- .gitignore: ignore tools/.env (developer-specific MCP endpoints).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
EVOLV MCP services — Docker stack
Three MCP services Claude Code uses to close real loops during EVOLV work:
| Service | What it does | Tools exposed |
|---|---|---|
mcp-node-red-admin |
Wraps the Node-RED HTTP admin API | getFlows, postFlow, getFlow, inject, listNodes, restartFlow |
mcp-influxdb |
Queries the telemetry bucket | query, assertSeriesExists, assertRecentWrite, listMeasurements |
mcp-browser |
Headless Playwright against the FlowFuse dashboard | loadDashboard, screenshot, consoleLogs, waitForChart, getChartData |
Why these
Each closes a verification loop Claude currently cannot close:
- Node-RED admin — today Claude pushes flows via raw
curl; the MCP lets Claude deploy + fire injects + read live state in one conversational turn. - InfluxDB — today Claude cannot verify "did the telemetry land?" beyond reading source. The MCP closes the loop after a deploy.
- Browser — today Claude cannot see the rendered dashboard. The MCP catches the failure mode behind the η-null crash + the blank-ui-chart bug + the editor pile-up bug at the only layer where they're visible.
Migration plan
These run locally now (we're in the middle of an infra migration).
Once the central MCP server is provisioned (target Q3 2026), each
service moves to shared infra by lifting the entry from this
docker-compose.yml plus the matching tools/mcp/<name>/Dockerfile
and pointing every developer's Claude Code at the central endpoint
instead of localhost. The compose file stays here as the canonical
definition.
Usage
# build the three images (one-off, ~3 min)
cd tools
docker compose --profile mcp build
# start them
docker compose --profile mcp up -d
# wire Claude Code to them — add to your user-level .mcp.json
{
"mcpServers": {
"evolv-node-red-admin": { "type": "stdio", "command": "docker", "args": ["exec", "-i", "evolv-mcp-node-red-admin", "node", "server.mjs"] },
"evolv-influxdb": { "type": "stdio", "command": "docker", "args": ["exec", "-i", "evolv-mcp-influxdb", "node", "server.mjs"] },
"evolv-browser": { "type": "stdio", "command": "docker", "args": ["exec", "-i", "evolv-mcp-browser", "node", "server.mjs"] }
}
}
The repo-level .mcp.json is deliberately not committed (each
developer has different host endpoints / tokens). Use a user-level
config or ~/.claude.json.
Required environment
tools/.env (gitignored) with:
NODE_RED_HOST=http://host.docker.internal:1880
NODE_RED_TOKEN=… # optional, only if Node-RED has admin auth on
INFLUX_URL=http://host.docker.internal:8086
INFLUX_TOKEN=…
INFLUX_ORG=wbd
INFLUX_BUCKET=telemetry
DASHBOARD_URL=http://host.docker.internal:1880/dashboard
Status
| Service | Dockerfile | Server impl | Status |
|---|---|---|---|
mcp-node-red-admin |
placeholder | TODO — see mcp/node-red-admin/ROADMAP.md |
not runnable yet |
mcp-influxdb |
placeholder | TODO | not runnable yet |
mcp-browser |
placeholder | TODO — wrap @playwright/test |
not runnable yet |
The compose file is the target shape. The Dockerfile + server
implementation per service is a follow-up (each is ~200–400 LOC of MCP
protocol + the wrapped client). When a service lands, flip its row
above to runnable and remove the placeholder.
When to use these — required reading
CLAUDE.md § "Tooling (Docker-first, local now, central later)" lists
the operating doctrine: always prefer these tools over ad-hoc
curl/grep/manual checks. Each tool exists because of a specific bug
class we've already paid for. Skipping them re-opens those bugs.
Future: OPC-UA / PLC MCP
Out of scope for this round; will be revisited later. When added it
follows the same pattern: tools/mcp/opcua/ with its own Dockerfile
and a row in this README.