Files
EVOLV/tools/mcp/README.md

98 lines
3.8 KiB
Markdown
Raw Permalink Normal View History

# 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
```bash
# 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:
```dotenv
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 ~200400 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.