npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

n8n-nodes-arduino-cloud

v0.1.1

Published

n8n community nodes for Arduino Cloud — read and write Thing Properties, react to variable updates over MQTT, and expose properties as AI Agent tools with safety rails.

Readme

n8n-nodes-arduino-cloud

Give your AI agent persistent memory of what your hardware did. This package wires Arduino Cloud into n8n so an AI Agent — through the standard Tools Agent connector — can read, write, and query historic values on any Arduino Cloud-connected board (Nano 33 IoT, MKR WiFi 1010, Portenta, UNO R4 WiFi, Nano ESP32, …) with safety rails for the LLM. The same nodes work for non-agent workflows too: react to a property update, write a value back, or pull last-hour history into a dashboard.

This package is independent of n8n-nodes-uno-q. Install both side by side if you have a UNO Q and Cloud-connected boards — the two address different semantics (LAN-local RPC vs. cloud pub/sub) and don't share state.

Built on the two official Arduino JS SDKs:

Requirements

  • n8n 1.x with community nodes enabled
  • An Arduino Cloud API key (Client ID + Client Secret). The default scope iot:devices,iot:things,iot:properties covers everything the package does.
  • Node ≥ 20 in the n8n container (the official n8nio/n8n image already meets this)

Install

From n8n: Settings → Community Nodes → Install → type n8n-nodes-arduino-cloud → Install.

To use the Arduino Cloud node as an AI Agent tool, also set N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true on the n8n process. The sample docker-compose already sets it.

Credential — Arduino Cloud OAuth2 API

One credential covers both nodes. Create it under Settings → Credentials → New → Arduino Cloud OAuth2 API:

| Field | Meaning | |---|---| | Client ID | The client_id from your Arduino Cloud API key. | | Client Secret | The client_secret. n8n stores it encrypted. | | Organization ID | Optional X-Organization header for multi-org accounts. Leave blank otherwise. |

Test Connection mints a token via OAuth2 client_credentials and lists Things — succeeds with Connected — N Thing(s) visible or surfaces the exact failure (bad credentials, network, etc.).

The same credential drives REST calls and the MQTT-over-WS subscriptions; you don't need a second one for the trigger.

Nodes

Arduino Cloud (action)

Reads and writes Thing Properties. Marked usableAsTool: true — drops into a Tools Agent's tool connector without a separate wrapper node. Three operations on the Property resource:

| Operation | What it does | LLM-friendly use | |---|---|---| | Get | Read the current value of a property. | "What is the temperature?" | | Set | Publish a new value. | "Turn the heater on." | | Get History | Time-series values for a window. | "Was the temperature unusual at 3 am yesterday?" |

Thing and Property dropdowns are populated live via the REST API once the credential is set; you don't paste UUIDs by hand.

Value coercion — the Value field accepts an n8n expression. By default the node parses literal strings (true/false, 42, 3.14, JSON object/array) into the corresponding native types; you can force a specific type with the Value Type dropdown if Auto guesses wrong (e.g. a digit-only string that must stay a string). For Location and Color variables, pass an object via expression — {{ { lat: 45.5, lon: 9.2 } }} for LOCATION, {{ { hue: 270, sat: 80, bri: 128 } }} for COLOR_HSB.

GetHistory defaults: leave From and To blank to query "last hour up to now". Both fields accept any value n8n's expression editor produces (ISO-8601 string, JS Date, Unix epoch).

Arduino Cloud Trigger

Fires a workflow on each property update. Backed by arduino-iot-js's MQTT-over-WebSocket subscription to the Arduino Cloud broker — no polling, no webhook proxy.

Two fields: Thing (UUID via dropdown) and Property Variable Name (the variable_name from the sketch — e.g. temperaturenot the property UUID). The picker shows both for clarity and writes the variable name to the parameter.

The emitted JSON shape downstream nodes see is:

{
  "thingId": "<uuid>",
  "variableName": "temperature",
  "value": 21.5,
  "receivedAt": "2026-04-25T15:00:00.000Z"
}

value matches the property's declared type — boolean for STATUS, number for INT/FLOAT, object for COLOR_HSB / LOCATION.

Connection sharing. Multiple triggers in the same workflow that point at the same credential collapse to a single MQTT connection (see §13.7 in the master plan for the architecture). You don't need to worry about exhausting MQTT slots if you have a dozen triggers.

AI tool use — Property Guard and Rate Limit

The point of usableAsTool: true is that an LLM picks parameters at runtime. That's powerful and dangerous — the LLM might pick a thermostat setpoint of 99°C, or call the same actuator a hundred times in a tight reasoning loop. Two affordances mitigate that.

Property Guard

A small JavaScript predicate that runs at invocation time. Variables in scope:

| Name | Type | Meaning | |---|---|---| | operation | string | "get", "set", or "getHistory". | | thingId | string | | | propertyId | string | | | value | any | The parsed Value (Set only; undefined for Get/GetHistory). | | budget | object | budget.used("minute"\|"hour"\|"day"), budget.remaining, budget.resetsInMs. See Rate Limit below. |

Return:

  • true / undefined / null — allow the call through.
  • a string — reject with that exact message. The string is fed back to the LLM as the tool output, so the agent can read it and self-correct (e.g. "Refused: setpoint must be 15-26 degrees").
  • false — generic rejection.
  • throw — hard error (the workflow fails with that error).
// Clamp a thermostat setpoint.
if (operation === "set" && (value < 15 || value > 26)) {
  return "Refused: setpoint must be between 15 and 26 degrees.";
}
// Block writes after 11pm local.
if (operation === "set" && new Date().getHours() >= 23) {
  return "Refused: no writes after 23:00.";
}
return true;

The guard runs without a sandbox — same trust model as the n8n Code node. Only the Property Guard's return value is passed back to the LLM; rate-limit short-circuits and "refused" outputs flow through the same channel, so the agent sees a uniform "this didn't go through, here's why" signal regardless of which gate caught it.

Rate Limit

Sliding-window cap: Max Calls within a Per window (Minute / Hour / Day). Excess calls short-circuit with a Refused: rate limit of N per X exceeded. Retry in ~Ys. string the LLM reads.

Counters are in-memory per n8n process, keyed per (node, thingId, propertyId, operation). Two consequences:

  • Get and Set on the same property have independent budgets. A user reading the value to verify a write doesn't burn the write budget — and vice versa.
  • Restarting n8n (or docker compose restart) resets every counter. Counters are not shared across queue-mode workers.

For finer policies (priority reservation, soft caps without hard enforcement, "warn the LLM at 80% of the limit"), read budget.remaining / budget.used(window) from the Property Guard.

Gate ordering: Rate Limit → Property Guard → REST call. A Rate Limit rejection short-circuits the guard. A guard rejection does not consume rate-limit budget (otherwise a guard like "no writes after 23:00" would burn through the cap on every refusal).

$fromAI expressions

Any node parameter can be filled by the LLM at call time using $fromAI('name', 'description', 'type'). Typical pattern:

| Field | Value | |---|---| | Thing | static dropdown choice | | Property | static dropdown choice | | Value | ={{ $fromAI('value', 'Setpoint in degrees Celsius. Range 15-26.', 'number') }} |

The LLM sees the description and produces a value at invocation. Pair it with a Property Guard that validates the same range — descriptions guide the agent, guards enforce.

Tool description

The text in the node's Description field (Settings → bottom of the node) is what the LLM reads when deciding whether to invoke the tool. 90% of agent-ergonomics bugs are prose, not code. Start with a verb, state units and ranges, include an example invocation. "Set the kitchen thermostat to a setpoint between 15 and 26°C. Example: 21." beats "Sets a property".

Limits and caveats

  • Arduino Cloud REST budget: 10 requests/sec per OAuth2 client. The package automatically queues requests against a per-credential token bucket so a workflow with many parallel nodes won't 429 — they serialise transparently. A side effect: bursts above 10 calls/sec see ~100 ms added latency per excess call.
  • Property Guard runs without a sandbox — same trust model as n8n's Code node. Don't paste guards from untrusted sources.
  • Rate Limit counters are in-memory per process — they reset on container restart and are not shared across queue-mode workers.
  • Trigger connection sharing happens per credential id. If the same Arduino Cloud account is wired up via two separate n8n credentials (e.g. for tagging purposes), you get two MQTT connections and double the broker load. Use one credential.
  • Set is asynchronous to the device: propertiesV2Publish returns when the cloud accepts the value; whether the device receives and applies it depends on the device being online. The Trigger node delivers the value back as soon as the broker fans it out, which is your best signal that the round-trip completed.

Disjoint from the UNO Q stack

This package does not depend on n8n-nodes-uno-q and does not replace it. The two address different semantics:

| Need | Cloud package | UNO Q package | |---|---|---| | Telemetry: device → workflow on a value change | ✅ native (MQTT trigger) | ✅ via Arduino UNO Q Trigger | | State: shared variable between workflow and device | ✅ native (Properties) | works, not the native idiom | | RPC: typed args, return value, sub-10 ms LAN-local round-trip | ❌ not the model | ✅ native (Arduino UNO Q Call / Method) | | Works offline | ❌ requires internet | ✅ |

Install both if you have both kinds of hardware. They run side by side with no coupling.

See also

  • n8n-nodes-uno-q — companion package for Arduino UNO Q workflows. Sub-10 ms LAN-local RPC to the on-board MCU via arduino-router: read sensors, drive GPIO, react to MCU events, and call MCU methods from an AI Agent (with Method Guard + Rate Limit safety rails matching this package's affordances). Disjoint runtime — install both side by side if you have UNO Q hardware and other Arduino Cloud-connected boards.
  • @raasimpact/arduino-uno-q-bridge — the pure-Node.js MessagePack-RPC client behind n8n-nodes-uno-q. Useful on its own for Node.js apps on the UNO Q.
  • Project repo and master plan — including the wedge analysis behind this package's narrow v1 scope: docs/master-plan/13-arduino-cloud.md.

License

MIT.