Skip to main content
Glama
kskwon02

node-red-mcp

by kskwon02

npm version Node.js TypeScript License PRs Welcome

A production-ready MCP server that connects AI assistants (Claude, Copilot, etc.) to the Node-RED Admin API.

Inspect flows, manage nodes, analyze graph topology, capture debug output, apply JSON patches, and rollback changes — all through natural language.


Architecture

graph TB
    subgraph "AI Client"
        A[Claude Desktop]
        B[VS Code MCP]
        C[Custom Client]
    end

    subgraph "MCP Server @mysterysd/node-red-mcp"
        direction LR
        T[Transport Layer<br/>stdio / SSE / streamableHttp]
        S[Server Factory<br/>McpServer]
        T --> S
        S --> Tools[38 Tools<br/>flows / nodes / graph / auth / runtime]
        S --> Res[7 Resources<br/>settings / flows / graph / registry]
        S --> Prompts[3 Prompts<br/>analyze / repair / refactor]
        Tools --> GE[Graph Engine<br/>DAG analysis / cycles / search]
        Tools --> NR[Node Registry<br/>persistent name-to-ID lookup]
        Tools --> Snap[Snapshots<br/>20-deep ring buffer per flow]
        Tools --> Debug[Debug Capture<br/>WebSocket /comms]
    end

    subgraph "Node-RED Instance"
        NR_API[Admin REST API<br/>:1880]
        NR_WS[WebSocket<br/>:1880/comms]
    end

    A & B & C -->|MCP Protocol| T
    S -->|axios| NR_API
    Debug -->|ws| NR_WS

Related MCP server: n8n Workflow Builder

Data Flow

sequenceDiagram
    participant AI as AI Assistant
    participant MCP as node-red-mcp
    participant NR as Node-RED

    AI->>MCP: flows-create(label, nodes)
    MCP->>MCP: auto-generate node IDs
    MCP->>MCP: auto-layout positions
    MCP->>NR: POST /flow
    NR-->>MCP: { id, rev }
    MCP->>MCP: refresh NodeRegistry
    MCP-->>AI: { status, flowId }

    AI->>MCP: flows-add-node(flowId, node)
    MCP->>NR: GET /flow/:id
    MCP->>MCP: snapshot current state
    MCP->>MCP: append node, validate wires
    MCP->>NR: PUT /flow/:id
    MCP->>MCP: refresh NodeRegistry
    MCP-->>AI: { status, nodeId }

    AI->>MCP: nodes-resolve(query)
    MCP->>MCP: lookup in NodeRegistry
    MCP-->>AI: { matches: [...] }

Features

  • šŸš€ 3 Transport Modes — stdio (default), SSE, streamable HTTP

  • šŸ”Œ 38 MCP Tools — full coverage of flows, nodes, runtime, auth, inject, graph analysis, and debug capture

  • 🧩 5 Node-Level Mutation Tools — add, remove, update, rewire, and move individual nodes without rewriting entire flows

  • šŸ“Š Graph Engine — auto-builds directed acyclic graph (DAG) from flow topology, detects cycles, sources, sinks, and computes node categories

  • šŸ—ƒļø Node Registry — persistent, auto-synced hot DB for looking up node IDs by name, type, label, and flow

  • šŸ” Semantic Search — query flows by node name, type, topic, URL, or any metadata

  • šŸ› Live Debug Capture — WebSocket-based capture of Node-RED debug output, combined with inject or standalone

  • šŸ”§ JSON Patch — RFC 6902 compliant patch engine for incremental flow edits

  • šŸ“ø Snapshots — in-memory 20-entry ring buffer per flow for rollback

  • šŸ”— 7 Resources + 3 Prompts — inspect runtime settings, diagnostics, flows, graph, registry, and get AI-assisted analysis


Table of Contents


Installation

npm install -g @mysterysd/node-red-mcp

Or run directly without installing:

npx @mysterysd/node-red-mcp

Prerequisites

  • Node.js >= 18

  • Node-RED instance running with the Admin API enabled (default: http://localhost:1880)

Quick Start

# 1. Set your Node-RED URL (default: http://localhost:1880)
export NODE_RED_URL=http://my-nodered:1880

# 2. Start the MCP server in stdio mode
npx @mysterysd/node-red-mcp

Then configure your MCP client:

TIP

The server auto-refreshes the Node Registry on startup, so all your nodes are immediately searchable by name.

Claude Desktop / VS Code

{
  "mcpServers": {
    "node-red": {
      "command": "npx",
      "args": ["@mysterysd/node-red-mcp"],
      "env": {
        "NODE_RED_URL": "http://localhost:1880",
        "NODE_RED_ACCESS_TOKEN": "your-token"
      }
    }
  }
}

opencode

{
  "mcpServers": {
    "node-red": {
      "command": "node",
      "args": ["path/to/dist/index.js", "stdio"],
      "env": {
        "NODE_RED_URL": "http://localhost:1880"
      }
    }
  }
}

Configuration

All configuration is via environment variables:

Variable

Default

Description

NODE_RED_URL

http://localhost:1880

Base URL of the Node-RED Admin API

NODE_RED_TOKEN

—

Bearer token for API auth (takes precedence over NODE_RED_ACCESS_TOKEN)

NODE_RED_ACCESS_TOKEN

—

Alternative name for the bearer token

NODE_RED_USERNAME

—

Username for password-based auth

NODE_RED_PASSWORD

—

Password for password-based auth

MCP_SERVER_PORT

3001 (SSE), 3002 (streamable HTTP)

HTTP server port for HTTP transports

PORT

3001 (SSE), 3002 (streamable HTTP)

Fallback port (overridden by MCP_SERVER_PORT)

NODE_REGISTRY_PATH

./node-registry.json

File path for persistent Node Registry

NOTE

Copy.env.example to .env as a reference for all available environment variables.

Authentication

The server supports two auth methods:

  1. Token-based (recommended):

    export NODE_RED_TOKEN="your-bearer-token"
  2. Password-based (auto-login on first request):

    export NODE_RED_USERNAME="admin"
    export NODE_RED_PASSWORD="your-password"

If neither is set, the server will attempt unauthenticated requests (Node-RED's default for local-only deployments).

WARNING

Avoid usingNODE_RED_TOKEN in shared or version-controlled config files. Use environment-specific secrets whenever possible.

Usage

# stdio mode (default — for Claude Desktop, VS Code, etc.)
node-red-mcp
node-red-mcp stdio

# SSE mode (HTTP server on :3001)
node-red-mcp sse

# Streamable HTTP mode (HTTP server on :3002)
node-red-mcp streamableHttp

Transport Modes

Mode

Protocol

Best For

stdio

stdin/stdout JSON-RPC

Claude Desktop, VS Code MCP extensions

sse

Server-Sent Events

Remote or containerized setups

streamableHttp

HTTP POST + DELETE

Stateless proxies, load-balanced deployments

Debug Capture

Two tools provide real-time debug output capture via Node-RED WebSocket (/comms):

Tool

Description

node-red-inject (with waitForDebug)

Inject + capture — fires inject, listens, returns both result and debug messages in one call

node-red-debug-listen

Standalone listener — connects, subscribes to debug, captures messages for N seconds with optional node/flow filtering

Example (one-call inject + verify):

// node-red-inject({ nodeId: "my-inject", waitForDebug: 5 })
→ { status: "injected", debug: [...], debugCount: 3 }

Both tools handle Node-RED's array-batched WebSocket format automatically.


Tools Reference

All 38 tools are registered with the MCP server. Each returns JSON output.

Auth

Tool

Description

node-red-auth-get-scheme

Inspect the active Node-RED admin auth scheme

node-red-auth-login

Exchange credentials for a bearer token

node-red-auth-revoke

Revoke an existing bearer token

Runtime

Tool

Description

node-red-runtime-get-settings

Read runtime settings

node-red-runtime-get-diagnostics

Read runtime diagnostics

node-red-runtime-get-flow-state

Read runtime flow state

node-red-runtime-set-flow-state

Update runtime flow state

node-red-debug-listen

Capture debug messages via WebSocket for a duration (optionally filtered by node/flow)

Flows

Tool

Description

node-red-flows-list

List active flow tabs and metadata

node-red-flows-get

Get a single flow by id or label

node-red-flows-create

Create a new flow tab with nodes (auto-generates IDs, auto-layouts positions, remaps wires)

node-red-flows-update

Replace an existing flow tab (auto-layouts positions)

node-red-flows-patch

Apply JSON Patch (RFC 6902) operations to a flow

node-red-flows-delete

Delete a flow tab

node-red-flows-clone

Clone an existing flow tab

node-red-flows-rollback

Rollback a flow to a previous snapshot

node-red-inject

Trigger an inject node by its ID (optionally waitForDebug to capture debug output in one call)

Node-Level Mutations

Tool

Description

node-red-flows-add-node

Add a single node to an existing flow tab. Auto-generates ID if omitted, validates wire targets, positions intelligently.

node-red-flows-remove-node

Remove a single node from a flow tab. Cleans up wire references from all remaining nodes.

node-red-flows-update-node

Update specific properties of a single node by ID. Deep-merges the provided properties onto the existing node. Reports which keys changed.

node-red-flows-rewire-node

Replace all wire connections for a specific node. Validates all target IDs exist in the flow.

node-red-flows-move-node

Move a single node to a specific visual position (x, y) within a flow tab.

Graph

Tool

Description

node-red-graph-analyze

Analyze topology, dependencies, and graph health

node-red-graph-summary

Summary statistics and risk assessment

node-red-graph-visualize

Generate a human-readable graph view

node-red-graph-dependencies

Resolve upstream and downstream dependencies for a node

node-red-graph-query

Search nodes by semantic query

node-red-graph-pack

Context pack for semantic search with neighbor expansion

node-red-graph-export

Export the full flow graph in serializable format

Nodes

Tool

Description

node-red-nodes-list

List installed node modules and node sets

node-red-nodes-install

Install a node module from npm

node-red-nodes-get-module

Inspect a specific node module

node-red-nodes-toggle-module

Enable or disable a node module

node-red-nodes-remove-module

Remove a node module

node-red-nodes-get-set

Inspect a specific node set within a module

node-red-nodes-toggle-set

Enable or disable a node set

node-red-nodes-resolve

Look up node IDs by name, type, description, or flow label using the Node Registry


Resources

URI

Description

node-red://runtime/settings

Current runtime settings (JSON)

node-red://runtime/diagnostics

Runtime diagnostics (JSON)

node-red://flows

All active flows (raw JSON)

node-red://nodes

All installed nodes (JSON)

node-red://graph

Full graph snapshot (serializable format)

node-red://flow/{id}

Single flow by ID (template)

node-red://registry

Node Registry snapshot — all indexed nodes with names, types, flow labels, and categories

Prompts

Prompt

Description

analyze-flow

Analyze a flow for risks, dependencies, and graph structure

repair-flow

Draft a repair plan for invalid or broken flow wiring

refactor-flow

Suggest a graph-aware refactor plan for a flow


Node Registry

The Node Registry is a persistent, auto-synced hot database that indexes every node across all flows.

graph LR
    subgraph "Node Registry"
        NR[(registry.json)]
        L[lookupInRegistry]
        GF[getRegistryForFlow]
        GS[getRegistrySnapshot]
    end

    MC[flows-create] -->|refresh| NR
    MU[5 Mutation Tools] -->|refresh| NR
    FU[flows-update] -->|refresh| NR
    ST[Server Start] -->|initial load| NR
    NR -->|query| RS[nodes-resolve tool]
    NR -->|expose| RES[node-red://registry resource]

How it works

  1. Startup: refreshRegistry(client) fetches all flows via Admin API and builds an index

  2. Persistence: Index saved to NODE_REGISTRY_PATH (default: ./node-registry.json) as JSON

  3. Auto-sync: Every mutation tool (add, remove, update, rewire, move) and flows-create/update triggers a refresh

  4. Lookup: Search by name, type, ID, or flow label with fuzzy matching and result ranking

  5. Categories: Each node is categorized as source, debug, transform, network, messaging, storage, template, dashboard, config, or other

Example query:

// nodes-resolve({ query: "Temperature", flowLabel: "Factory Floor" })
→ {
  "matches": [
    { "id": "abc123", "type": "inject", "name": "Temperature Sensor",
      "flowId": "...", "flowLabel": "Factory Floor", "category": "source" }
  ]
}

Client Library

The client library (src/client/index.ts) provides a standalone NodeRedClient class you can use programmatically:

import { NodeRedClient } from "@mysterysd/node-red-mcp/client";

const client = new NodeRedClient({
  baseUrl: "http://localhost:1880",
  accessToken: process.env.NODE_RED_ACCESS_TOKEN,
});

// List all flows
const flows = await client.getFlows();

// Get a specific flow
const flow = await client.getFlow("flow-id");

// Install a node
await client.installNode({ module: "node-red-contrib-something" });

API

class NodeRedClient {
  baseUrl: string;                         // Public getter (for WebSocket URL construction)
  constructor(options: ClientOptions);

  // Auth
  getAuthScheme(): Promise<AuthScheme>;
  login(credentials?: AuthCredentials): Promise<TokenResponse>;
  revoke(token?: string): Promise<unknown>;

  // Runtime
  getSettings(): Promise<Record<string, unknown>>;
  getDiagnostics(): Promise<Record<string, unknown>>;
  getFlowState(): Promise<unknown>;
  setFlowState(state: unknown): Promise<unknown>;

  // Flows
  getFlows(): Promise<FlowsResponse>;
  getFlow(id: string): Promise<FlowDocument>;
  createFlow(flow: FlowDocument): Promise<FlowDocument>;
  updateFlow(id: string, flow: FlowDocument): Promise<FlowDocument>;
  deleteFlow(id: string): Promise<unknown>;

  // Nodes
  listNodes(): Promise<unknown>;
  installNode(payload: Record<string, unknown>): Promise<unknown>;
  getNodeModule(module: string): Promise<unknown>;
  toggleNodeModule(module: string, enabled: boolean): Promise<unknown>;
  removeNodeModule(module: string): Promise<unknown>;
  getNodeSet(module: string, set: string): Promise<unknown>;
  toggleNodeSet(module: string, set: string, enabled: boolean): Promise<unknown>;

  // Inject
  inject(nodeId: string): Promise<unknown>;
}

Graph Engine

The graph engine (src/graph/) is a standalone library for building and analyzing Node-RED flow topologies:

import { buildGraph, formatGraph } from "@mysterysd/node-red-mcp/graph/engine";
import { queryGraph } from "@mysterysd/node-red-mcp/graph/search";
import { applyPatch } from "@mysterysd/node-red-mcp/graph/patch";
graph TD
    RAW[Raw Flows<br/>from Admin API] --> BG[buildGraph]
    BG --> FG[FlowGraph]
    FG --> VA[graph-analyze]
    FG --> VS[graph-visualize]
    FG --> DP[graph-dependencies]
    FG --> QY[queryGraph<br/>semantic search]
    FG --> PK[graph-pack<br/>context pack]
    FG --> SM[summarizeGraph]
    FG --> EX[graph-export]

Graph Types

interface FlowGraph {
  rev: string;
  tabs: FlowTab[];
  nodes: FlowNode[];
  nodeById: Map<string, FlowNode>;
  adjacency: Map<string, string[]>;            // forward edges
  reverseAdjacency: Map<string, Set<string>>;  // backward edges
  edges: GraphEdge[];
  sources: string[];       // nodes with 0 in-degree
  sinks: string[];         // nodes with 0 out-degree
  cycles: string[][];      // detected cycles
  categories: Map<string, NodeCategory>;
}

Functions

Function

Description

buildGraph(flowsResponse)

Build a FlowGraph from raw Node-RED API response

categorizeNode(node)

Classify node as source, debug, transform, subflow, config, dashboard, or other

isConfigNode(node)

Check if a node is a config node (no position, no wires)

collectClosure(map, start)

BFS/DFS from a start node to collect all reachable nodes

graphToSerializable(graph)

Convert graph to plain JSON-safe format

formatGraph(graph, focusId?)

Produce a human-readable topology view

findCycles(adjacency)

Detect all cycles in a directed graph

buildSemanticIndex(graph)

Build a searchable text index over all nodes

queryGraph(graph, query, flowId?)

Search nodes by semantic query (returns scored results)

collectRelevantSubgraph(graph, index, query, opts)

Find matching nodes + expand to neighbors

summarizeGraph(graph)

Generate a summary with counts, categories, risky nodes

applyPatch(document, operations)

Apply RFC 6902 JSON Patch operations


Development

# Clone and install
git clone https://github.com/mysterysd/node-red-mcp.git
cd node-red-mcp
npm install

# Build
npm run build

# Watch mode
npm run watch

# Test (with coverage)
npm test

# Lint
npm run prettier:check
npm run prettier:fix

Project Structure

src/
ā”œā”€ā”€ config.ts          # Centralized env var config
ā”œā”€ā”€ client/            # NodeRedClient — Admin API wrapper
ā”œā”€ā”€ graph/             # Graph engine (types, engine, search, patch, registry)
│   └── registry.ts    # NodeRegistry — persistent name-to-ID hot DB
ā”œā”€ā”€ tools/
│   ā”œā”€ā”€ auth/          # 3 tools: get-scheme, login, revoke
│   ā”œā”€ā”€ runtime/       # 5 tools: settings, diagnostics, flow-state, debug-listen
│   ā”œā”€ā”€ flows/         # 14 tools: list, get, create, update, patch, delete, clone,
│   │                  #   rollback, inject, add-node, remove-node, update-node,
│   │                  #   rewire-node, move-node
│   │   └── mutation-utils.ts  # Shared mutateFlow() utility
│   ā”œā”€ā”€ graph/         # 7 tools: analyze, summary, visualize, dependencies,
│   │                  #   query, pack, export
│   └── nodes/         # 8 tools: list, install, get-module, toggle-module,
│                       #   remove-module, get-set, toggle-set, resolve
ā”œā”€ā”€ resources/         # 7 MCP resource handlers (incl. registry)
ā”œā”€ā”€ prompts/           # 3 MCP prompt templates
ā”œā”€ā”€ server/            # McpServer factory
ā”œā”€ā”€ transports/        # stdio, SSE, streamableHttp
ā”œā”€ā”€ __tests__/         # 171 unit tests (17 files)
└── index.ts           # CLI entry point

Test Stats

  • 171 unit tests across 17 test files

  • ~77% overall coverage (core modules at 100%)

  • 25 integration tests against live Node-RED

  • Coverage includes: all 5 mutation tools (94–100%), registry (90%), resolve (100%)


Docker

FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine AS production
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/package*.json ./
RUN npm ci --omit=dev
EXPOSE 3002
ENV NODE_RED_URL=http://nodered:1880
CMD ["node", "dist/index.js", "streamableHttp"]

Build and run:

docker build -t node-red-mcp .
docker run -e NODE_RED_URL=http://host.docker.internal:1880 -p 3002:3002 node-red-mcp

License

MIT Ā© Mystery SD

Install Server
A
license - permissive license
B
quality
B
maintenance

Maintenance

–Maintainers
–Response time
–Release cycle
–Releases (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.

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/kskwon02/node-red-ai-mcp'

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