@gmag11/nodered-mcp-server 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +162 -0
  3. package/index.js +133 -0
  4. package/package.json +58 -0
  5. package/resources/skills/nodered-flow-builder/SKILL.md +659 -0
  6. package/resources/skills/nodered-flow-layout/SKILL.md +395 -0
  7. package/resources/skills/nodered-flowfuse-dashboard/SKILL.md +941 -0
  8. package/resources/skills/nodered-fundamentals/SKILL.md +323 -0
  9. package/resources/skills/nodered-jsonata/SKILL.md +1039 -0
  10. package/resources/skills/nodered-mustache/SKILL.md +588 -0
  11. package/resources/skills/nodered-node-reference/SKILL.md +1020 -0
  12. package/resources/skills/nodered-node-reference/examples/common.json +113 -0
  13. package/resources/skills/nodered-node-reference/examples/network.json +107 -0
  14. package/resources/skills/nodered-node-reference/examples/parser.json +147 -0
  15. package/resources/skills/nodered-node-reference/examples/sequence.json +141 -0
  16. package/resources/skills/nodered-node-reference/examples/storage.json +104 -0
  17. package/resources/skills/nodered-patterns/SKILL.md +414 -0
  18. package/resources/skills/nodered-patterns/examples/error-handler.json +72 -0
  19. package/resources/skills/nodered-patterns/examples/http-endpoint.json +42 -0
  20. package/resources/skills/nodered-patterns/examples/mqtt-subscriber.json +47 -0
  21. package/resources/skills/nodered-patterns/examples/timer-flow.json +50 -0
  22. package/resources/skills/nodered-subflows/SKILL.md +261 -0
  23. package/resources/skills/nodered-uibuilder/SKILL.md +500 -0
  24. package/src/auth/api-key-verifier.js +36 -0
  25. package/src/auth/composite-verifier.js +59 -0
  26. package/src/auth/config.js +106 -0
  27. package/src/auth/oauth-clients-store.js +107 -0
  28. package/src/auth/oauth-provider.js +149 -0
  29. package/src/auth/oauth-token-store.js +312 -0
  30. package/src/nodered/auth.js +158 -0
  31. package/src/nodered/client.js +199 -0
  32. package/src/nodered/comms-client.js +500 -0
  33. package/src/renderer/colors.js +161 -0
  34. package/src/renderer/geometry.js +115 -0
  35. package/src/renderer/html-builder.js +571 -0
  36. package/src/renderer/index.js +51 -0
  37. package/src/renderer/ir-builder.js +161 -0
  38. package/src/renderer/layout.js +126 -0
  39. package/src/renderer/mermaid-builder.js +109 -0
  40. package/src/renderer/svg-builder.js +228 -0
  41. package/src/schemas/responses.js +283 -0
  42. package/src/server.js +844 -0
  43. package/src/skills/loader.js +84 -0
  44. package/src/staging-store.js +258 -0
  45. package/src/tools/add-nodes-to-group.js +216 -0
  46. package/src/tools/connect-nodes.js +115 -0
  47. package/src/tools/constants.js +45 -0
  48. package/src/tools/create-flow.js +87 -0
  49. package/src/tools/create-node.js +126 -0
  50. package/src/tools/create-subflow-instance.js +123 -0
  51. package/src/tools/create-subflow.js +101 -0
  52. package/src/tools/delete-context.js +60 -0
  53. package/src/tools/delete-flow.js +81 -0
  54. package/src/tools/delete-group.js +116 -0
  55. package/src/tools/delete-node.js +73 -0
  56. package/src/tools/delete-subflow.js +103 -0
  57. package/src/tools/deploy.js +94 -0
  58. package/src/tools/disconnect-nodes.js +158 -0
  59. package/src/tools/export-flow.js +161 -0
  60. package/src/tools/export-subflow.js +78 -0
  61. package/src/tools/flow-utils.js +376 -0
  62. package/src/tools/get-config-nodes.js +86 -0
  63. package/src/tools/get-context.js +76 -0
  64. package/src/tools/get-flow-diagram.js +99 -0
  65. package/src/tools/get-flow-nodes.js +116 -0
  66. package/src/tools/get-flows.js +74 -0
  67. package/src/tools/get-node-detail.js +77 -0
  68. package/src/tools/get-node-type-detail.js +92 -0
  69. package/src/tools/get-palette-nodes.js +63 -0
  70. package/src/tools/get-staging-status.js +34 -0
  71. package/src/tools/get-subflow-detail.js +110 -0
  72. package/src/tools/get-subflows.js +105 -0
  73. package/src/tools/import-flow.js +310 -0
  74. package/src/tools/inject-message.js +117 -0
  75. package/src/tools/install-node.js +31 -0
  76. package/src/tools/read-debug-messages.js +155 -0
  77. package/src/tools/refresh-staging.js +62 -0
  78. package/src/tools/remove-nodes-from-group.js +162 -0
  79. package/src/tools/render-staging.js +69 -0
  80. package/src/tools/response-utils.js +42 -0
  81. package/src/tools/search-nodes.js +134 -0
  82. package/src/tools/uninstall-node.js +31 -0
  83. package/src/tools/update-flow.js +95 -0
  84. package/src/tools/update-group.js +77 -0
  85. package/src/tools/update-node.js +132 -0
  86. package/src/tools/update-subflow.js +84 -0
  87. package/src/transport/http.js +252 -0
  88. package/src/transport/stdio.js +16 -0
  89. package/src/transport/ws-server.js +223 -0
@@ -0,0 +1,588 @@
1
+ ---
2
+ name: nodered-mustache
3
+ description: >-
4
+ Comprehensive reference for the Mustache templating language (v1.3.0).
5
+ Covers all tag types: variables (escaped and unescaped), sections, inverted sections,
6
+ comments, partials, blocks, parents, and set delimiters. Documents dotted-name resolution,
7
+ implicit iterator, lambdas, and the inheritance extension (blocks/parents).
8
+ Includes Node-RED-specific usage notes for the template node.
9
+ ---
10
+
11
+ # Mustache Templating Language Reference
12
+
13
+ Comprehensive reference for Mustache — a **logic-less templating language** that works by expanding tags in a template using values provided in a hash or object. Mustache is one of the supported formats in Node-RED's "template" node.
14
+
15
+ Mustache can be used for HTML, config files, source code — anything. It is called "logic-less" because there are no if statements, else clauses, or for loops. Instead there are only **tags**. Some tags are replaced with a value, some nothing, and others a series of values.
16
+
17
+ > **Version:** Mustache spec v1.3.0 (including optional extensions for lambdas and inheritance)
18
+ > **Try it:** [mustache.github.io](http://mustache.github.io/)
19
+ > **Docs:** [mustache(5) man page](https://mustache.github.io/mustache.5.html)
20
+
21
+ ---
22
+
23
+ ## Quick Example
24
+
25
+ A typical Mustache template:
26
+
27
+ ```mustache
28
+ Hello {{name}}
29
+ You have just won {{value}} dollars!
30
+ {{#in_ca}}
31
+ Well, {{taxed_value}} dollars, after taxes.
32
+ {{/in_ca}}
33
+ ```
34
+
35
+ Given the following hash:
36
+
37
+ ```json
38
+ {
39
+ "name": "Chris",
40
+ "value": 10000,
41
+ "taxed_value": 6000,
42
+ "in_ca": true
43
+ }
44
+ ```
45
+
46
+ Will produce:
47
+
48
+ ```
49
+ Hello Chris
50
+ You have just won 10000 dollars!
51
+ Well, 6000 dollars, after taxes.
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Tag Types
57
+
58
+ Tags are indicated by double mustaches. `{{person}}` is a tag, as is `{{#person}}`. In both examples, `person` is the key or tag key.
59
+
60
+ ### Variables
61
+
62
+ The most basic tag type. A `{{name}}` tag will try to find the `name` key in the current context. If there is no `name` key, parent contexts are checked recursively. If the top context is reached and the key is still not found, nothing is rendered (empty string).
63
+
64
+ **HTML Escaping:** All variables are HTML escaped by default. Use triple mustache `{{{name}}}` or ampersand syntax `{{&name}}` for raw unescaped output.
65
+
66
+ ```mustache
67
+ * {{name}}
68
+ * {{age}}
69
+ * {{company}}
70
+ * {{{company}}}
71
+ ```
72
+
73
+ ```json
74
+ {
75
+ "name": "Chris",
76
+ "company": "<b>GitHub</b>"
77
+ }
78
+ ```
79
+
80
+ Output:
81
+ ```
82
+ * Chris
83
+ *
84
+ * &lt;b&gt;GitHub&lt;/b&gt;
85
+ * <b>GitHub</b>
86
+ ```
87
+
88
+ > **Note:** The `age` key is missing, so nothing is rendered for `{{age}}`.
89
+
90
+ #### Dotted Names
91
+
92
+ If the key contains dots, it is split on the dots to obtain multiple keys. Each key is looked up in sequence through nested contexts. If any intermediate key is not found, nothing is rendered.
93
+
94
+ ```mustache
95
+ * {{client.name}}
96
+ * {{age}}
97
+ * {{client.company.name}}
98
+ * {{{company.name}}}
99
+ ```
100
+
101
+ ```json
102
+ {
103
+ "client": {
104
+ "name": "Chris & Friends",
105
+ "age": 50
106
+ },
107
+ "company": {
108
+ "name": "<b>GitHub</b>"
109
+ }
110
+ }
111
+ ```
112
+
113
+ Output:
114
+ ```
115
+ * Chris &amp; Friends
116
+ *
117
+ *
118
+ * <b>GitHub</b>
119
+ ```
120
+
121
+ #### Implicit Iterator (`{{.}}`)
122
+
123
+ If the name consists of only a dot (`.`), the current context value is interpolated as a whole. This is especially useful inside sections iterating over lists of scalars (see Sections below).
124
+
125
+ ```mustache
126
+ * {{.}}
127
+ ```
128
+
129
+ Current context:
130
+ ```
131
+ "Hello!"
132
+ ```
133
+
134
+ Output:
135
+ ```
136
+ * Hello!
137
+ ```
138
+
139
+ #### Variable Lambdas
140
+
141
+ If any value found during lookup is a callable object (function/lambda), it is invoked with zero arguments. If the lambda returns a string, that string is rendered as a Mustache template before interpolation (using default delimiters against the current context).
142
+
143
+ ```mustache
144
+ * {{time.hour}}
145
+ * {{today}}
146
+ ```
147
+
148
+ ```json
149
+ {
150
+ "time": {
151
+ "hour": 0,
152
+ "minute": 0,
153
+ "second": 0
154
+ },
155
+ "today": "{{year}}-{{month}}-{{day}}",
156
+ "year": 1970,
157
+ "month": 1,
158
+ "day": 1
159
+ }
160
+ ```
161
+
162
+ Output:
163
+ ```
164
+ * 0
165
+ * 1970-1-1
166
+ ```
167
+
168
+ ---
169
+
170
+ ### Sections
171
+
172
+ Sections render blocks of text zero or more times, depending on the value of the key in the current context. A section begins with a pound (`#`) and ends with a slash (`/`): `{{#person}}...{{/person}}`.
173
+
174
+ The behavior is determined by the value of the key lookup:
175
+
176
+ #### False Values or Empty Lists
177
+
178
+ If the key exists and has a value of `false` or an empty list, the content between the tags is **not displayed**.
179
+
180
+ ```mustache
181
+ Shown.
182
+ {{#person}}
183
+ Never shown!
184
+ {{/person}}
185
+ ```
186
+
187
+ ```json
188
+ { "person": false }
189
+ ```
190
+
191
+ Output:
192
+ ```
193
+ Shown.
194
+ ```
195
+
196
+ #### Non-Empty Lists
197
+
198
+ If the key value is a non-empty list, the block is rendered **once for each item**. The context inside the block is set to the current item. This is how you loop over collections.
199
+
200
+ ```mustache
201
+ {{#repo}}
202
+ <b>{{name}}</b>
203
+ {{/repo}}
204
+ ```
205
+
206
+ ```json
207
+ {
208
+ "repo": [
209
+ { "name": "resque" },
210
+ { "name": "hub" },
211
+ { "name": "rip" }
212
+ ]
213
+ }
214
+ ```
215
+
216
+ Output:
217
+ ```
218
+ <b>resque</b>
219
+ <b>hub</b>
220
+ <b>rip</b>
221
+ ```
222
+
223
+ Using the implicit iterator with a list of scalars:
224
+
225
+ ```mustache
226
+ {{#repo}}
227
+ <b>{{.}}</b>
228
+ {{/repo}}
229
+ ```
230
+
231
+ ```json
232
+ { "repo": ["resque", "hub", "rip"] }
233
+ ```
234
+
235
+ Output:
236
+ ```
237
+ <b>resque</b>
238
+ <b>hub</b>
239
+ <b>rip</b>
240
+ ```
241
+
242
+ #### Non-False Values (Not a List)
243
+
244
+ When the value is non-false but not a list, the block is rendered **once** with the value used as the context.
245
+
246
+ ```mustache
247
+ {{#person?}}
248
+ Hi {{name}}!
249
+ {{/person?}}
250
+ ```
251
+
252
+ ```json
253
+ { "person?": { "name": "Jon" } }
254
+ ```
255
+
256
+ Output:
257
+ ```
258
+ Hi Jon!
259
+ ```
260
+
261
+ #### Section Lambdas
262
+
263
+ When the key value is a callable object (function/lambda), the function is invoked and passed the **literal block text** (unrendered — `{{tags}}` are not expanded). The return value replaces the section content. If the lambda returns a string, it is rendered using the same delimiters as the original section.
264
+
265
+ ```mustache
266
+ {{#wrapped}}{{name}} is awesome.{{/wrapped}}
267
+ ```
268
+
269
+ ```json
270
+ {
271
+ "name": "Willy",
272
+ "wrapped": "&lt;b&gt;{{name}} is awesome.&lt;/b&gt;"
273
+ }
274
+ ```
275
+
276
+ Output:
277
+ ```
278
+ <b>Willy is awesome.</b>
279
+ ```
280
+
281
+ ---
282
+
283
+ ### Inverted Sections
284
+
285
+ An inverted section begins with a caret (`^`) and ends with a slash (`/`): `{{^person}}...{{/person}}`. Inverted sections render their content **once** when the key doesn't exist, is `false`, or is an empty list — the inverse of regular sections.
286
+
287
+ ```mustache
288
+ {{#repo}}
289
+ <b>{{name}}</b>
290
+ {{/repo}}
291
+ {{^repo}}
292
+ No repos :(
293
+ {{/repo}}
294
+ ```
295
+
296
+ ```json
297
+ { "repo": [] }
298
+ ```
299
+
300
+ Output:
301
+ ```
302
+ No repos :(
303
+ ```
304
+
305
+ ---
306
+
307
+ ### Comments
308
+
309
+ Comments begin with a bang (`!`) and are **ignored** in output. Comments may contain newlines.
310
+
311
+ ```mustache
312
+ <h1>Today{{! ignore me }}.</h1>
313
+ ```
314
+
315
+ Output:
316
+ ```
317
+ <h1>Today.</h1>
318
+ ```
319
+
320
+ ---
321
+
322
+ ### Partials
323
+
324
+ Partials begin with a greater than sign (`>`): `{{> box}}`. Partials are rendered at **runtime** (not compile time), so recursive partials are possible (just avoid infinite loops).
325
+
326
+ Partials **inherit the calling context**. You don't need to pass data explicitly — any key available in the parent template is also available inside the partial.
327
+
328
+ ```
329
+ base.mustache:
330
+ <h2>Names</h2>
331
+ {{#names}}
332
+ {{> user}}
333
+ {{/names}}
334
+
335
+ user.mustache:
336
+ <strong>{{name}}</strong>
337
+ ```
338
+
339
+ This can be thought of as a single, expanded template:
340
+
341
+ ```mustache
342
+ <h2>Names</h2>
343
+ {{#names}}
344
+ <strong>{{name}}</strong>
345
+ {{/names}}
346
+ ```
347
+
348
+ #### Dynamic Names
349
+
350
+ Partials can be loaded dynamically at runtime using an asterisk followed by a dotted name: `{{>*dynamic}}`. The dotted name resolves to a string that names the partial to include.
351
+
352
+ ```
353
+ main.mustache:
354
+ Hello {{>*dynamic}}
355
+
356
+ world.template:
357
+ everyone!
358
+ ```
359
+
360
+ ```json
361
+ { "dynamic": "world" }
362
+ ```
363
+
364
+ Output:
365
+ ```
366
+ Hello everyone!
367
+ ```
368
+
369
+ ---
370
+
371
+ ### Blocks and Parents (Template Inheritance)
372
+
373
+ Blocks and parents are part of the **optional inheritance extension**. They enable template inheritance patterns where a base template defines overridable sections.
374
+
375
+ #### Blocks
376
+
377
+ A block begins with a dollar sign (`$`) and ends with a slash: `{{$title}}...{{/title}}`. Blocks mark parts of a template that may be overridden by a parent template. If not overridden, the block's default content is rendered.
378
+
379
+ ```
380
+ article.mustache:
381
+ <h1>{{$title}}The News of Today{{/title}}</h1>
382
+ {{$body}}
383
+ <p>Nothing special happened.</p>
384
+ {{/body}}
385
+ ```
386
+
387
+ Rendered directly:
388
+ ```
389
+ <h1>The News of Today</h1>
390
+ <p>Nothing special happened.</p>
391
+ ```
392
+
393
+ #### Parents
394
+
395
+ A parent begins with a less than sign (`<`) and ends with a slash: `{{<article}}...{{/article}}`. Like a partial, a parent lets you include another template. **Unlike** a partial, a parent also lets you **override blocks** from the included template.
396
+
397
+ Content inside a parent that is not within a block override is ignored (acts like a comment).
398
+
399
+ ```mustache
400
+ {{<article}}
401
+ Never shown
402
+ {{$body}}
403
+ {{#headlines}}
404
+ <p>{{.}}</p>
405
+ {{/headlines}}
406
+ {{/body}}
407
+ {{/article}}
408
+ ```
409
+
410
+ ```json
411
+ {
412
+ "headlines": [
413
+ "A pug's handler grew mustaches.",
414
+ "What an exciting day!"
415
+ ]
416
+ }
417
+ ```
418
+
419
+ Output (using article.mustache from above):
420
+ ```
421
+ <h1>The News of Today</h1>
422
+ <p>A pug's handler grew mustaches.</p>
423
+ <p>What an exciting day!</p>
424
+ ```
425
+
426
+ #### Dynamic Names in Parents
427
+
428
+ Parent templates can also use dynamic names with `{{<*dynamic}}...{{/*dynamic}}`:
429
+
430
+ ```
431
+ {{!normal.mustache}}
432
+ {{$text}}Here goes nothing.{{/text}}
433
+
434
+ {{!bold.mustache}}
435
+ <b>{{$text}}Here also goes nothing but it's bold.{{/text}}</b>
436
+
437
+ {{!dynamic.mustache}}
438
+ {{<*dynamic}}
439
+ {{$text}}Hello World!{{/text}}
440
+ {{/*dynamic}}
441
+ ```
442
+
443
+ ```json
444
+ { "dynamic": "bold" }
445
+ ```
446
+
447
+ Output:
448
+ ```
449
+ <b>Hello World!</b>
450
+ ```
451
+
452
+ ---
453
+
454
+ ### Set Delimiter
455
+
456
+ Set Delimiter tags start with an equals sign and change the tag delimiters from `{{` and `}}` to custom strings. Custom delimiters **may not contain whitespace or the equals sign**.
457
+
458
+ This is useful for languages like TeX where double-braces may occur in the text and are awkward to use for markup.
459
+
460
+ ```mustache
461
+ * {{default_tags}}
462
+ {{=<% %>=}}
463
+ * <% erb_style_tags %>
464
+ <%={{ }}=%>
465
+ * {{ default_tags_again }}
466
+ ```
467
+
468
+ Output:
469
+ ```
470
+ * default_tags_value
471
+ * erb_style_tags_value
472
+ * default_tags_again_value
473
+ ```
474
+
475
+ ---
476
+
477
+ ## Lambda Functions Deep Dive
478
+
479
+ Lambdas (callable objects) are an optional extension in the Mustache spec v1.3.0. They behave differently depending on context:
480
+
481
+ | Context | Lambda behavior |
482
+ |---------|----------------|
483
+ | **Variable** `{{lambda}}` | Invoked with zero args. If it returns a string, that string is rendered as a Mustache template (with default delimiters) against the current context. |
484
+ | **Section** `{{#lambda}}...{{/lambda}}` | Invoked with the **literal block text** (unrendered). Return value replaces the section. If a string, rendered with the same delimiters as the section. |
485
+
486
+ **Variable lambda example** — template-generating function:
487
+
488
+ ```mustache
489
+ {{#items}}
490
+ <li>{{name}}: {{display}}</li>
491
+ {{/items}}
492
+ ```
493
+
494
+ ```json
495
+ {
496
+ "items": [
497
+ { "name": "Alice", "value": 5 },
498
+ { "name": "Bob", "value": 0 }
499
+ ],
500
+ "display": "{{#value}}{{.}}{{/value}}{{^value}}N/A{{/value}}"
501
+ }
502
+ ```
503
+
504
+ **Section lambda example** — wrapping/filtering:
505
+
506
+ If `wrapped` is a function that takes text and returns `<b>${text}</b>`, then `{{#wrapped}}{{name}}{{/wrapped}}` effectively wraps the name in bold tags.
507
+
508
+ ---
509
+
510
+ ## Summary: Tag Reference Table
511
+
512
+ | Tag | Syntax | Purpose |
513
+ |-----|--------|---------|
514
+ | Variable (escaped) | `{{name}}` | Interpolate with HTML escaping |
515
+ | Variable (unescaped) | `{{{name}}}` or `{{&name}}` | Interpolate raw, no escaping |
516
+ | Dotted name | `{{a.b.c}}` | Traverse nested objects |
517
+ | Implicit iterator | `{{.}}` | Interpolate current context |
518
+ | Section | `{{#key}}...{{/key}}` | Loop / conditional / context switch |
519
+ | Inverted section | `{{^key}}...{{/key}}` | Render when false/empty/missing |
520
+ | Comment | `{{! text }}` | Ignored, may span lines |
521
+ | Partial | `{{> name}}` | Include another template |
522
+ | Dynamic partial | `{{>*name}}` | Include template by name resolution |
523
+ | Block | `{{$key}}...{{/key}}` | Overridable default content |
524
+ | Parent | `{{<name}}...{{/name}}` | Include template with block overrides |
525
+ | Dynamic parent | `{{<*name}}...{{/*name}}` | Parent by name resolution |
526
+ | Set delimiter | `{{=...=}}` | Change tag delimiters |
527
+
528
+ ---
529
+
530
+ ## Node-RED Template Node Usage
531
+
532
+ In Node-RED, the **template** node supports Mustache as one of its output formats. When the template node's **Format** is set to **Mustache template**, the template is evaluated against the `msg` object as the context hash.
533
+
534
+ ### Accessing Message Properties
535
+
536
+ | Mustache expression | Accesses |
537
+ |---------------------|----------|
538
+ | `{{payload}}` | `msg.payload` |
539
+ | `{{topic}}` | `msg.topic` |
540
+ | `{{payload.temperature}}` | `msg.payload.temperature` (nested) |
541
+ | `{{payload.sensor.name}}` | `msg.payload.sensor.name` (deeply nested) |
542
+ | `{{{payload}}}` | `msg.payload` (raw, unescaped) |
543
+
544
+ ### Common Patterns
545
+
546
+ **Conditional rendering with sections:**
547
+ ```mustache
548
+ {{#payload.active}}
549
+ Sensor is active.
550
+ {{/payload.active}}
551
+ ```
552
+
553
+ **Iterating over an array in payload:**
554
+ ```mustache
555
+ {{#payload}}
556
+ <li>{{name}}: {{value}}</li>
557
+ {{/payload}}
558
+ ```
559
+
560
+ **Fallback with inverted sections:**
561
+ ```mustache
562
+ {{#payload}}
563
+ Data: {{.}}
564
+ {{/payload}}
565
+ {{^payload}}
566
+ No data received.
567
+ {{/payload}}
568
+ ```
569
+
570
+ **Comments for template documentation:**
571
+ ```mustache
572
+ {{! This template formats sensor readings as HTML }}
573
+ <h2>Sensor: {{topic}}</h2>
574
+ ```
575
+
576
+ ### Relationship to Other Template Formats
577
+
578
+ Node-RED's template node supports multiple formats:
579
+
580
+ | Format | Behavior |
581
+ |--------|----------|
582
+ | **Mustache template** | Evaluated against `msg` as Mustache (this skill) |
583
+ | **Plain text** | Literal text, no substitution |
584
+ | **JSONata** | Evaluated as a JSONata expression against `msg` |
585
+
586
+ When using Mustache format, the entire template is processed by the Mustache engine before being assigned to `msg.payload`. Use Mustache when you need simple variable substitution with HTML escaping and section-based iteration, without the complexity of a full expression language.
587
+
588
+ > **Note:** Mustache is logic-less. For complex data transformations, filtering, or calculations, use the **change** node with JSONata expressions instead.