一键导入
nodered-fundamentals
Core vocabulary of Node-RED: nodes, flows (tabs), wires, messages, context, config nodes, design principles, and basic error handling concepts.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Core vocabulary of Node-RED: nodes, flows (tabs), wires, messages, context, config nodes, design principles, and basic error handling concepts.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Step-by-step operational guide for building, editing, testing, and debugging Node-RED flows using MCP tools.
Comprehensive rules for positioning and arranging nodes in Node-RED flows. Covers debug node placement, vertical centering around branch points, horizontal spacing standards, comment placement, group spacing, and bounding-box calculations. Use whenever creating or rearranging multi-node flows to ensure visual clarity and avoid overlapping elements.
Reference for @flowfuse/node-red-dashboard (Dashboard 2.0) v1.30.2, the officially recommended Node-RED dashboard. Covers widget catalog with properties, config nodes (ui-base, ui-page, ui-group, ui-theme), wiring patterns, and common dashboard recipes. Docs: https://dashboard.flowfuse.com/
Comprehensive reference for the JSONata expression language (v2.2.0). Covers syntax, path navigation, predicates, operators, all built-in function categories (string, numeric, aggregation, boolean, array, object, date/time, higher-order), programming constructs (variables, functions, recursion), the processing model (sequences, flattening), and the JavaScript embedding API. Includes Node-RED-specific usage notes for change, switch, and inject nodes.
Comprehensive reference for the Mustache templating language (v1.3.0). Covers all tag types: variables (escaped and unescaped), sections, inverted sections, comments, partials, blocks, parents, and set delimiters. Documents dotted-name resolution, implicit iterator, lambdas, and the inheritance extension (blocks/parents). Includes Node-RED-specific usage notes for the template node.
Categorized reference of Node-RED built-in core node types, key properties, and a deep-dive into the function node's APIs, return semantics, and async patterns.
| name | nodered-fundamentals |
| description | Core vocabulary of Node-RED: nodes, flows (tabs), wires, messages, context, config nodes, design principles, and basic error handling concepts. |
| tools | ["get-flows","get-flow-nodes","get-flow-diagram","get-config-nodes","get-node-detail","get-palette-nodes","get-node-type-detail","create-flow","update-flow","delete-flow","create-node","update-node","delete-node","connect-nodes","disconnect-nodes","get-context","delete-context","inject-message","search-nodes","export-flow","import-flow","read-debug-messages","install-node","uninstall-node","refresh-staging","deploy","get-staging-status"] |
Core vocabulary, design principles, and basic error handling for working with Node-RED via the MCP tools. Read this BEFORE building any flows.
Node-RED is a flow-based, event-driven visual programming platform. You wire together "nodes" on a canvas to process messages. Each message flows through a chain of nodes, each node performing a specific operation (transform, filter, route, store, etc.).
payload property.A node is the fundamental building block. Each node has a type that determines what it does.
Key fields on every node:
| Field | Description |
|---|---|
id | Unique UUID (generated by the runtime or MCP tools) |
type | Palette type (e.g., "inject", "function", "debug", "http in") |
name | User-visible label (set via name property in create-node/update-node) |
z | The flow (tab) ID this node belongs to |
x, y | Canvas position (pixels, not meaningful for behavior) |
wires | Array of output connections (see Wire section below) |
MCP tools for nodes:
create-node — add a new node to a flowupdate-node — merge properties onto an existing node (never wires)delete-node — remove a node and clean up its wiresget-flow-nodes — list nodes in a flow with their current stateget-node-detail — get the full node object including large text fields (func code, template markup)search-nodes — find nodes across all flows by name, type, or property value"Flow" has two meanings in Node-RED — always disambiguate:
z field).🚨 CRITICAL CONCEPT — Edits are NOT live until you deploy.
The MCP tools use a staging workspace model, identical to the Node-RED editor:
create-node, connect-nodes, update-node, delete-node, etc. modify an in-memory copy of the flows. Nothing is sent to the Node-RED runtime until you explicitly deploy.get-flows, get-flow-nodes, get-flow-diagram, etc. return data from the staged copy, reflecting all pending changes.deploy to send all staged changes to Node-RED. Three deploy types:
"nodes" (default) — restart only modified nodes (least disruptive)"flows" — restart only modified flow tabs"full" — restart everythingget-staging-status to see what's pending before deploying.inject-message refuses to inject if there are undeployed changes — deploy first, then test.deploy once. Don't deploy after every single operation — batch your edits.Rule: After ANY write operation, check the staging.deployed field in the response. If false, you have pending changes. Call deploy before testing with inject-message.
Workflow: Edit → Read (verify with diagram) → Deploy → Test (inject + debug)
In MCP contexts, "flow" typically means the tab. Use flowId to specify which tab to operate on.
MCP tools for flows:
get-flows — list all tabs/subflows with their node counts and typescreate-flow — create a new empty tabupdate-flow — change tab label, disabled state, info, or env varsdelete-flow — remove a tab and all its nodesexport-flow — export a tab's JSON for backup or migrationimport-flow — import flow JSON into the instanceA wire connects one node's output port to another node's input. Wires are stored in the wires array on the source node.
wires array structure:
"wires": [["targetNodeId1", "targetNodeId2"], []]
Ports are 0-indexed. The first output port is index 0.
MCP tools for wires:
connect-nodes — add a wire from one node to another (single or batch)disconnect-nodes — remove a wire (single, clear-port, or batch)wires in update-node properties — wiring is managed exclusively through connect-nodes/disconnect-nodesA message (often called msg) is the JavaScript object that flows between nodes. Every message has at minimum:
| Property | Description |
|---|---|
payload | The primary data — can be any type (string, number, object, Buffer) |
topic | Optional routing/metadata string |
_msgid | Auto-generated unique message identifier |
| (custom) | Nodes can attach any additional properties (e.g., msg.headers, msg.statusCode) |
MCP tools:
inject-message — trigger an inject node (starts a message through the flow)read-debug-messages — read output from debug nodes (requires comms WebSocket)Context is Node-RED's key-value storage system with three scopes:
| Scope | Lifetime | Access |
|---|---|---|
| Node | Tied to a single node | context.get(key) / context.set(key, val) in function nodes |
| Flow | All nodes in one flow tab | flow.get(key) / flow.set(key, val) in function nodes |
| Global | Entire Node-RED instance | global.get(key) / global.set(key, val) in function nodes |
⚠️ IMPORTANT: The Admin API does NOT support writing context values. The MCP tools can only read (get-context) and delete (delete-context) context. To write context, you must use a function node with context.set(), flow.set(), or global.set().
MCP tools:
get-context — read a context variable from any scopedelete-context — delete a context variable from any scopeWarning: Default in-memory context is lost when Node-RED restarts. For persistence, users must configure file-based context storage (not controllable via MCP).
A config node (configuration node) is a shared resource node that holds reusable settings. Unlike regular nodes, config nodes are not wired into a flow — they are referenced by regular nodes via a property (e.g., an MQTT node references an mqtt-broker config node).
Key characteristics:
z field is "" (global, available to all flows) or a specific flowId (scoped to one tab)create-node or update-node⚠️ CREDENTIAL PRIVACY — critical to understand:
Node-RED never exposes real credential values (passwords, API keys, tokens, certificates) through its REST API. When you call get-flow-nodes or get-config-nodes:
credentials field (e.g., { username: "xxx", password: "yyy" }) will be absent — never included.credentials field does NOT mean the node has no credentials configured. It means the values are hidden for security.How to work with credentials despite this limitation:
get-node-detail on a config node. It returns a _credentials field like { user: "test67", has_password: true }. Password values are NEVER shown — only has_<field>: true/false.update-node with a credentials object. You only need to send the fields you want to change — unspecified credential fields are preserved. Example: properties: { credentials: { password: "newpass" } } changes only the password.create-node with credentials inside properties. Example: properties: { broker: "localhost", port: 1883, credentials: { user: "test67", password: "mypass" } }.credentials sub-object.MCP tools:
get-config-nodes — list all config nodes, filter by type (credentials hidden)get-node-detail — get full details of a specific config node (credentials hidden)A subflow is a reusable group of nodes packaged as a single node. You define inputs/outputs as "subflow instance properties" and reuse the subflow like any palette node. Subflows appear in get-flows with type: "subflow".
Note: Full subflow creation/editing is not yet supported via MCP tools. You can view existing subflows with get-flows and get-flow-nodes, but creating or modifying subflow internals requires the Node-RED editor.
The palette is the registry of all installed node types. Each type has a module, version, category, and configurable properties.
MCP tools:
get-palette-nodes — list all available node types (paginated, alphabetical)get-node-type-detail — get detailed info about a specific type including its configurable parametersinstall-node — install a new node module from npm (may require Node-RED restart)uninstall-node — remove a node module (⚠️ destroys all nodes of that type)create-flow or update-flow to set meaningful labels like "Weather API Ingest" not "Flow 1".info property on flows to document purpose, inputs/outputs, and dependencies. This is visible in the editor and helps anyone (including future you) understand the flow.name on every node you create. Use create-node's properties.name or update-node."function 3", "debug 2"). These are meaningless in get-flow-nodes output.search-nodes to find unnamed nodes: search for "name":"".info property on flow tabs via create-flow or update-flow.type: "comment") to annotate sections of a flow. They display as text labels on the canvas.export-flow to share a documented flow as JSON for review.Node-RED provides a Catch node (type: "catch") for error handling. It catches errors thrown by nodes on the same flow tab.
Catch node scope:
scope property to an array of node IDs.Error object structure:
{
message: "Error description",
source: { id: "nodeId", type: "nodeType", name: "nodeName", count: 1 },
error: <original error object>
}
Best practices:
node.error("message", msg) to throw catchable errors.read-debug-messages to observe caught errors during development.Link nodes enable message passing across flow tabs without using global context or subflows.
| Type | Purpose |
|---|---|
link in | Receives messages from link out/call nodes (any tab) |
link out | Sends messages to all link in nodes with matching link name |
link call | Sends a message and waits for a response (request-reply pattern) |
Key behaviors:
link call is the only built-in way to do synchronous request-reply across tabs.MCP tools: Standard create-node, update-node, delete-node, connect-nodes apply to link nodes as well.
Flows can define environment variables scoped to a single tab.
How to set them:
create-flow or update-flow with the env array:
"env": [
{ "name": "API_KEY", "value": "sk-xxx", "type": "str" },
{ "name": "TIMEOUT", "value": "30", "type": "num" },
{ "name": "DEBUG", "value": "true", "type": "bool" }
]
"str", "num", "bool" (controls how the value is parsed)How to use them:
const apiKey = env.get("API_KEY");{{env.API_KEY}}${API_KEY}A simple inject → function → debug flow:
┌──────────┐ msg ┌──────────────┐ msg ┌──────────┐
│ inject │──────────▶│ function │──────────▶│ debug │
│ (start) │ │ msg.payload │ │ (output) │
└──────────┘ │ = x * 2 │ └──────────┘
└──────────────┘
1. inject node triggers → sends msg { payload: <timestamp> }
2. function node receives msg → sets msg.payload = msg.payload * 2
3. debug node receives msg → prints to debug sidebar (read via read-debug-messages)
Each node processes the message and passes it to the next node in the chain. This is the fundamental pattern: trigger → transform → output.