Skip to main content
Glama

nodered-mcp

Ein MCP-Server, der eine Node-RED-flows.json liest, abfragt und bearbeitet.

License CI Python

Über

Node-RED speichert jeden Flow, jeden Knoten, jede Verbindung und jede Gruppenbox in einer einzigen großen JSON-Datei. Wenn man sie von Hand bearbeitet – oder mit jq und sed – endet man mit verwaisten Verbindungen, Gruppen, deren Boxen ihre eigenen Knoten nicht mehr abdecken, und neuen Knoten, die auf bestehenden gestapelt sind.

Dieser Server stellt diese Datei einem MCP-Client als eine kleine Sammlung von Werkzeugen bereit, die das Format verstehen. Er kennt den Unterschied zwischen einem Flow-Knoten und einem Konfigurationsknoten, kann einen Verbindungsweg nachverfolgen und reproduziert die eigene Geometrie des Node-RED-Editors, sodass eine gezeichnete Gruppenbox genau die Box ist, die der Editor gezeichnet hätte.

Es ist ein Port des Paars flows_util.py / layout_util.py, das verwendet wurde, um Node-RED-Änderungen in einem Home-Automation-Repository zu skripten, verallgemeinert, sodass Dateipfad, Containername und Neustartbefehl vollständig konfigurierbar sind.

Related MCP server: nr-mcp

Funktionen

  • Abfragen – Tabs, Gruppen, verwaiste Knoten, Subflows, referenzierte Entitäten von Home Assistant und Verbindungsverläufe durch einen Flow.

  • Bearbeiten – Knoten erstellen, aktualisieren, löschen, umbenennen und duplizieren; sie verbinden und trennen; Gruppen erstellen, befüllen und neu gestalten; Knotensätze importieren und exportieren.

  • Platzieren – leere Canvasfläche beanspruchen, bevor Knoten erstellt werden, statt Koordinaten zu raten; die Canvas auf Kollisionen prüfen und Überlappungen reparieren.

  • Bewusst committen – Bearbeitungen sammeln sich im Speicher an und erreichen die Festplatte nur, wenn du darum bittest, sodass ein Multi-Knoten-Build als eine Einheit landet.

  • Zwei Schutzmechanismen, die die zugrunde liegenden Skripte nie brauchten: ein Layout-Gate, das Schreibvorgänge verweigert, die neue Kollisionen einführen, und eine Veraltetheitsprüfung, die das Überschreiben einer flows.json verweigert, die jemand aus dem Browser bereitgestellt hat.

Voraussetzungen

  • Python 3.11+

  • Eine flows.json im lokalen Dateisystem

  • Docker im PATH – nur für das deploy-Werkzeug, das die Datei in einen Container kopiert und ihn neu startet

Installation

git clone https://github.com/ljmerza/nodered-mcp
cd nodered-mcp
uv sync

Verwendung

Der Pfad zur flows.json ist die einzige erforderliche Einstellung. Es gibt keinen sinnvollen Standardwert, daher weigert sich der Server, ohne einen solchen zu starten.

uv run nodered-mcp --flows-path /path/to/nodered/data/flows.json

Bei einem MCP-Client registrieren

{
  "mcpServers": {
    "nodered": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--directory", "/path/to/nodered-mcp", "nodered-mcp"],
      "env": {
        "NODERED_FLOWS_PATH": "/path/to/nodered/data/flows.json"
      }
    }
  }
}

Ein vollständigeres Beispiel findest du in .mcp.json.example.

Konfiguration

Jede Einstellung wird nach CLI-Flag > Umgebungsvariable > Standardwert aufgelöst.

Flag

Umgebungsvariable

Standardwert

Zweck

--flows-path

NODERED_FLOWS_PATH

(erforderlich)

Pfad zur flows.json auf dem Host

--container

NODERED_CONTAINER

nodered

Containername, der von deploy verwendet wird

--container-flows-path

NODERED_CONTAINER_FLOWS_PATH

/data/flows.json

Pfad zur flows.json im Container

--restart-cmd

NODERED_RESTART_CMD

docker restart <container>

Neustartbefehl; {container} wird ersetzt

--transport

NODERED_MCP_TRANSPORT

stdio

stdio, http oder sse

--host / --port

NODERED_MCP_HOST / NODERED_MCP_PORT

127.0.0.1 / 8080

Bindeadresse für http und sse

Wenn Node-RED nicht mit einfachem Docker verwaltet wird, richte --restart-cmd darauf aus:

NODERED_RESTART_CMD="docker compose restart {container}"

Werkzeuge

Sieben Werkzeuge, die jeweils anhand eines op-Arguments dispatchieren.

Werkzeug

Operationen

nodered_query

summary, tabs, groups, tab, group, search, ungrouped, orphans, subflows, styles, entities, inspect, connections, trace

nodered_find_nodes

Strukturierte Suche nach Tab, Typ oder Namens-Teilstring

nodered_get_node

Das rohe JSON eines Knotens plus sein Verbindungskontext

nodered_edit

create_node, update_node, delete_node, rename_node, duplicate_node, wire, unwire, import_nodes, export_group

nodered_group

create, add, move_node, rename, set_style, normalize_styles, refit, shift, bounds

nodered_layout

check, free_region, occupied, fix

nodered_session

status, save, deploy, reload

Ein typischer Build

nodered_query(op="tabs")                                   -> tab ids
nodered_layout(op="free_region", tab_id=TAB, w=800, h=200) -> {"x": 100, "y": 3240}
nodered_edit(op="create_node", tab_id=TAB, node_type="inject",
             name="tick", x=100, y=3240)                   -> node id
nodered_edit(op="create_node", tab_id=TAB, node_type="switch",
             name="gate", x=300, y=3240)                   -> node id
nodered_edit(op="wire", source_id=..., target_id=...)
nodered_group(op="create", name="My Flow", tab_id=TAB, node_ids=[...])
nodered_session(op="save")

Nichts von dem oben Genannten berührt flows.json bis zum abschließenden save.

Wie es die Datei schützt

Das Layout-Gate

save und deploy prüfen die Canvas vor und nach deiner Bearbeitung und verweigern das Schreiben, wenn die Bearbeitung einen neuen Befund auf Fehlerebene einführt:

Befund

Schweregrad

Bedeutung

group-overlap

Fehler

Eine Gruppenbox ist auf einer anderen Gruppenbox gelandet

group-escape

Fehler

Eine Gruppenbox bedeckt ihre eigenen Knoten nicht mehr

stray-in-group

Warnung

Ein Knoten sitzt in einer Gruppenbox, deren Mitglied er nicht ist

node-overlap

Warnung

Zwei Knoten belegen denselben Raum

Probleme, die bereits auf der Festplatte existierten, blockieren nie – nur solche, die deine Bearbeitung erzeugt hat. Wenn das Gate auslöst, ist die Lösung normalerweise eine der folgenden:

  • nodered_layout(op="free_region"), um freie Canvasfläche zu beanspruchen, und dann dort platzieren

  • nodered_group(op="refit", group_id=...), um eine Gruppe um ihre Knoten herum anzupassen

  • nodered_session(op="save", allow_overlap=true), wenn die Überlappung beabsichtigt ist

Die Gruppengeometrie ist exakt: Die Größenregeln wurden aus dem Node-RED-Editor übernommen, sodass eine berechnete Box dem entspricht, was der Editor zeichnet. Die Knotengeometrie ist exakt, abgesehen von der Breite des Beschriftungstexts, die anhand der Helvetica-Metriken angenähert wird – deshalb sind Befunde auf Knotenebene immer nur Warnungen.

Die Veraltetheitsprüfung

Node-RED schreibt flows.json neu, sobald jemand im Browser auf Deploy klickt. Die Sitzung zeichnet (mtime_ns, size) auf, wenn sie die Datei lädt, und prüft vor jedem Schreibvorgang erneut. Wenn sich die Datei unter dir verändert hat, wird der Commit verweigert, anstatt diese Arbeit stillschweigend rückgängig zu machen. Entweder reload ausführen und deine Bearbeitungen wiederholen oder force=true übergeben.

Nanosekunden statt os.path.getmtime: Ein Gleitkomma-Epoch-Wert löst nur auf etwa eine Mikrosekunde auf, sodass ein Schreibvorgang, der im selben Takt wie das Laden erfolgt, als gleich verglichen wird und an der Prüfung vorbeischlüpft.

Eigenständige Verwendung

Beide Engine-Module funktionieren als Bibliotheken und CLIs, unabhängig von MCP.

uv run python -m nodered_mcp.flows summary --flows-path /path/to/flows.json
uv run python -m nodered_mcp.layout --path /path/to/flows.json --fix boxes,move
from nodered_mcp.flows import Flows

f = Flows("/path/to/flows.json")
ox, oy = f.free_region(tab_id, w=1600, h=300)
f.create_node(tab_id, "inject", "tick", x=ox, y=oy)
f.save()

--fix boxes allein macht die Sache schlimmer: Durch das Neuanpassen wachsen einige Boxen, sodass sie benachbarte Nicht-Mitgliedsknoten verschlucken. Führe boxes,move zusammen aus und lies den Probelauf, bevor du --apply übergibst.

Projektstruktur

src/nodered_mcp/
├── server.py       FastMCP server: the seven tools
├── session.py      in-memory session, stdout capture, staleness guard
├── config.py       CLI flags and environment resolution
├── flows.py        the Flows class, composed from the mixins below
├── constants.py    defaults, the group style, LayoutError
├── reports.py      ReadMixin      — summary, tab, group, search, trace
├── nodes.py        NodeEditMixin  — create/update/delete/wire nodes
├── groups.py       GroupMixin     — create and populate group boxes
├── placement.py    LayoutMixin    — claim free canvas, measure and refit boxes
├── transfer.py     TransferMixin  — import and export node sets
├── persist.py      PersistMixin   — save, deploy, and the layout gate
└── layout.py       canvas geometry and linter, ported from the NR editor

Flows setzt die Mixins zusammen, sodass die öffentliche API flach bleibt: f.summary(), f.create_node(), f.free_region(), f.save().

Entwicklung

uv sync --group dev
uv run pytest                    # 49 tests
uv run ruff check .
uv run ruff format --check .

Die Tests laufen gegen eine synthetische Fixture in tests/fixtures/, niemals gegen eine echte Flows-Datei. Sie decken ab: Konfigurationspriorität, die Lese-Werkzeuge, In-Memory-bis-zum-Speichern-Semantik, das Layout-Gate sowohl blockierend als auch außer Kraft gesetzt, die Veraltetheitsprüfung, die deploy-Befehlssequenz und dass kein Werkzeug nach stdout schreibt – ein versehentliches print würde das Stdio-Framing von MCP beschädigen.

CI führt dieselben Prüfungen über ljmerza/misc-actions aus.

Mitwirken

Issues und Pull-Requests sind willkommen. Bitte halte ruff check, ruff format und pytest grün.

Danksagungen

  • Node-RED – die Canvas-Geometrie hier ist aus dessen Editor-Client portiert, sodass Gruppenboxen dem entsprechen, was der Editor zeichnet.

  • FastMCP – das MCP-Server-Framework.

Lizenz

MIT. Siehe LICENSE.

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
0dRelease cycle
3Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    Minimal MCP server wrapping the Node-RED admin API, enabling flow management, node installation, and context retrieval via natural language.

View all related MCP servers

Related MCP Connectors

  • Create, browse, remix, collaborate on, and run durable AI workflow nodes from MCP hosts.

  • MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.

  • JSON tools MCP.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ljmerza/nodered-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server