nodered-mcp
nodered-mcp
Ein MCP-Server, der eine Node-RED-flows.json liest, abfragt und bearbeitet.
Ü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.jsonverweigert, die jemand aus dem Browser bereitgestellt hat.
Voraussetzungen
Python 3.11+
Eine
flows.jsonim lokalen DateisystemDocker im
PATH– nur für dasdeploy-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 syncVerwendung
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.jsonBei 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 |
|
| (erforderlich) | Pfad zur |
|
|
| Containername, der von |
|
|
| Pfad zur |
|
|
| Neustartbefehl; |
|
|
|
|
|
|
| Bindeadresse für |
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 |
|
|
| Strukturierte Suche nach Tab, Typ oder Namens-Teilstring |
| Das rohe JSON eines Knotens plus sein Verbindungskontext |
|
|
|
|
|
|
|
|
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 |
| Fehler | Eine Gruppenbox ist auf einer anderen Gruppenbox gelandet |
| Fehler | Eine Gruppenbox bedeckt ihre eigenen Knoten nicht mehr |
| Warnung | Ein Knoten sitzt in einer Gruppenbox, deren Mitglied er nicht ist |
| 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 platzierennodered_group(op="refit", group_id=...), um eine Gruppe um ihre Knoten herum anzupassennodered_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,movefrom 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 boxesallein macht die Sache schlimmer: Durch das Neuanpassen wachsen einige Boxen, sodass sie benachbarte Nicht-Mitgliedsknoten verschlucken. Führeboxes,movezusammen 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 editorFlows 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.
This server cannot be installed
Maintenance
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
- AlicenseNot gradedqualityDmaintenanceEnables management of multiple N8N workflow automation instances through MCP. Supports listing, creating, updating, deleting, executing workflows and monitoring their executions across different N8N environments.63MIT
- AlicenseAqualityDmaintenanceLets AI assistants interact with Node-RED to read flows, search nodes, edit function code, deploy changes safely, and manage modules.131MIT
- AlicenseNot gradedqualityBmaintenanceExposes Node-RED flows as MCP tools for AI assistants, with OAuth protection and optional admin tools for flow management.2081ISC
- FlicenseNot gradedqualityBmaintenanceMinimal MCP server wrapping the Node-RED admin API, enabling flow management, node installation, and context retrieval via natural language.
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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