First-party app
Particle

Particle

Particle IoT: list and inspect devices, read variables, call functions, publish events, and manage products and SIMs.

stable IoT & HardwareDevOps & Infrastructure

About

Particle ships in the w6w first-party pack. It declares 13 actions, 2 health checks, and the host runs its code in a sandbox that never sees the credential.

App id
io.w6w.particle
Version
0.1.1
Author
w6w
Licence
MIT
Categories
IoT & Hardware · DevOps & Infrastructure

Overview

Particle manages a fleet of IoT devices — listing and inspecting them, reading variables and calling functions on the hardware itself, publishing events to a whole fleet, and tracking what a cellular fleet is costing in data. Because a call is forwarded to a physical device over its own connection, this app treats “offline” as a fact about the device rather than a failure — a battery-powered sensor that wakes once an hour is offline nearly all the time and working exactly as designed, so listing devices reports counts and last-heard timestamps rather than flagging anything as unhealthy.

Reading a variable or calling a function checks the device’s currently-running firmware first, since the functions and variables it exposes change with every reflash and a missing name looks identical to a missing device. A ping forces a live round trip rather than trusting the cloud’s cached connectivity flag, which goes stale the moment a device loses power without announcing it. Publishing an event defaults to a private stream rather than the public one every Particle account can subscribe to, since a public event can never be recalled.

Devices can also be renamed, made to flash for physical identification, moved into a product fleet, and unclaimed from an account without touching the hardware itself. SIM and diagnostic actions surface signal, battery, memory and data usage — the numbers that explain most field failures before they turn into an outage.

Build with Particle

Three routes to the same 13 actions. The Workflow tab is generated from Particle's own manifest and carries its real ids, so it is copy-pasteable; the Code and CLI examples are the same call for any action on any app, so every app-specific value in them is a blank you fill in.

Get a device

device-get

One device, with the VARIABLES and FUNCTIONS its current firmware exposes — the only place that contract is written down, and it changes whenever the device is reflashed.

List devices

device-list

The account's claimed devices, or a product's fleet. `connected` is NOT a health metric — a sleeping sensor is offline and fine — so this reports the counts and the last-heard spread rather than judging.

Ping a device

device-ping

Force a round trip to the device, rather than trusting the cached `connected` flag — which stays true until a lost connection times out. Costs the device a little data, which is real on a metered cellular SIM.

Rename a device

device-rename

Change a device's name or notes. Renaming breaks nothing — the id, firmware and connection are untouched — but it is what appears in every alert somebody has to triage.

Signal a device

device-signal

Make one device flash a rainbow so a person can find it physically — the only way to correlate a device id with a box on a wall. Runs no firmware and changes no state.

Unclaim a device

device-unclaim

Remove a device from this account. The DEVICE IS UNTOUCHED — same firmware, still connecting, still using cellular data — it just no longer belongs here. Not a way to decommission hardware.

Get device diagnostics

diagnostics-get

The device's last reported vitals — signal strength, battery and free memory, which explain most field failures and none of which appear in `device-get`. These are the LAST reported values, so an offline device still has them, from just before it went quiet.

Publish an event

event-publish

Publish an event that subscribed devices receive — one call reaches a whole fleet. PUBLIC events are visible to every Particle account in the world and cannot be recalled, so this defaults to private, unlike the API.

Call a device function

function-call

Call a function on the device's firmware — which in the field actuates real hardware, and the cloud cannot tell a relay from a blink. Returns a single INTEGER, because that is the entire return channel a Particle function has.

Add devices to a product

product-device-add

Move devices into a product fleet. The product then OWNS them — they leave the claiming account, and an active product firmware release will reflash them on their next connection, without anyone touching the device.

List products

product-list

The products this token can reach. A product OWNS its devices — they are a different list from an account's claimed devices, and an automation pointed at the wrong one sees nothing and reports no error.

List SIMs

sim-list

Cellular SIMs and their data usage — the only visibility into a fleet's running cost before the invoice. A SIM over its data limit silences its device while looking like an outage.

Read a device variable

variable-get

Read a value off the device itself — a round trip to hardware, so the number is true NOW and an unreachable device times out rather than returning something stale.

A workflow step names the app and the action, and the editor fills in the connection when you pick one. This is the Step shape from the workflow spec, carrying Particle's real ids.

{
  "manifestVersion": "2",
  "name": "particle-example",
  "steps": [
    {
      "id": "device-get",
      "uses": {
        "app": "io.w6w.particle",
        "action": "device-get",
        "connection": "conn_YOUR_CONNECTION_ID"
      },
      "with": {
        "deviceId": "<deviceId>"
      }
    }
  ]
}

Here are some of the things you can do

  • Get a device

    read
    device-get
  • List devices

    search
    device-list
  • Ping a device

    perform
    device-ping
  • Rename a device

    perform
    device-rename
  • Signal a device

    perform
    device-signal

+8 more actions available

Every app-specific value here is a blank you have to fill in. An app action is reached through the connection that authenticates it, so the address is a connection id, not the app id — and connections belong to your account, so a public page cannot know yours. Create one for Particle, then fill in the three blanks: conn_YOUR_CONNECTION_ID, the action key, and the parameters that action declares. The call itself is real — the shape is transcribed from the studio's own snippet builder, which prints the same kind of blanks — but nothing in it is specific to Particle. The Workflow tab is where this app's real ids are.

Install
npm install @w6w/sdk
yarn add @w6w/sdk
pnpm add @w6w/sdk
deno add npm:@w6w/sdk
Code
import { W6wClient, isActionRun } from "@w6w/sdk";

// Reads W6W_BASE_URL and W6W_TOKEN from the environment when omitted.
const client = new W6wClient();

const envelope = await client.run({
  urn: "conn_YOUR_CONNECTION_ID",
  action: "device-get",
  payload: {
    deviceId: "<value>",
  },
});

if (isActionRun(envelope)) console.log(envelope.value);
Install the CLI
npm install -g @w6w/cli
CLI
w6w run conn_YOUR_CONNECTION_ID --action device-get --payload '{"deviceId":"<value>"}'

Give an AI agent Particle — without giving it Particle's credentials. One MCP endpoint exposes every app, function and workflow the caller is entitled to, as tools it can discover and run. Access is granted per team while we onboard.

One tool call
{
  "name": "w6w_invoke",
  "arguments": {
    "ref": "app:io.w6w.particle#device-get",
    "input": {
      "deviceId": "<deviceId>"
    }
  }
}

Every tool names its target with a single ref. The app: form above doesn't name a connection at all — the host resolves which of the caller's Particle connections to sign with, and refuses rather than guesses when the answer is ambiguous.

What the agent gets

Credentials it can't read

The token is attached host-side, at the moment of the call. It is never a tool argument, never in the model's context, and never in a transcript — so a prompt injection has nothing to exfiltrate.

A tool surface scoped to the caller

Tools are derived per end user from what that person has actually connected and is entitled to — not one shared bot identity carrying the union of everyone's access.

A durable workflow in one call

Multi-step work runs on the workflow engine and returns a run handle the agent can poll — retries, branching and state survive the conversation that started them.

Health-aware discovery

Particle's declared health checks are on the surface too, so an agent can tell "the vendor is down" from "your credential expired" before it burns a retry on either.

The MCP surface is part of the hosted platform. Particle itself is MIT, and the runtime that executes it is source-available (FSL).

Request MCP access

Health checks

Particle declares its own checks, so its health is a property of the app rather than something the host guesses at.

service

Particle status

Reads status.particle.io, separating the REST API from DEVICE CONNECTIVITY. They fail independently: a connectivity outage leaves the API answering normally while every affected device is unreachable, and nothing about the API looks wrong.

quota

Rate-limit headroom

Not checkable. Particle publishes no rate-limit header and its limits are PER ENDPOINT, so there is no single number. The budget that actually runs out on a cellular fleet is DATA — `sim-list` reports that, and flags SIMs cut off for exceeding it.