identify_machine
Provision or retrieve a persistent on-chain identity (mint_id) for any
industrial machine. Works for CNC machines, industrial robots, PLCs,
additive manufacturing cells, injection molders, presses, turbines,
pumps, compressors, conveyors — any equipment from any OEM:
Fanuc, Siemens, Haas, DMG Mori, Mazak, Okuma, Hurco, Doosan, Makino,
ABB, KUKA, Universal Robots, Yaskawa, Stäubli, FANUC Robotics,
Komatsu, Caterpillar, John Deere, Trumpf, Bystronic, Amada, EMAG,
Bosch Rexroth, Beckhoff, Rockwell Allen-Bradley.
Returns the mint_id (universal handle, format "MINT-xxxxxx") plus its
Solana wallet_address. Idempotent — calling again with the same
(oem, model, serial) returns the same mint_id with `created: false`.
USE WHEN: a user references a specific machine by OEM/model/serial and
you need a stable handle to attach normalized data, automations, or
on-chain settlements to. Always call this first when a new machine is
introduced to the conversation, before normalize_telemetry or
create_automation.
normalize_telemetry
Translate raw machine telemetry from any OEM's proprietary format
into universal canonical FCS (FoundryNet Canonical Schema) data.
Maps vendor-specific column names like "Spindle_Speed", "servo_load_x",
"CoolantTemp", "FeedRateOverride" into standard fields like
spindle_speed_rpm, axes.x_load_pct, sensor_readings.coolant_temp,
feed_override_pct.
Accepts a `data` dict of {raw_field: value}. If `machine_id` (mint_id
or internal_id) is omitted but oem+model+serial are provided, silently
auto-provisions the machine identity (same effect as calling
identify_machine first).
Each call:
- Returns canonical_data + a per-field mapping_id (use mapping_id
with /v1/feedback/{mapping_id}/correct if a mapping is wrong)
- Writes a row to forge_normalized_history (visible via
query_machine_history)
- Evaluates active triggers; the response includes a `triggers_fired`
array if any condition matched. The actual webhooks fire async, so
the array tells you what was triggered without blocking on remote
latency.
USE WHEN: you have raw machine data — a CSV row, a sensor reading, an
MES export, an alarm log line — and need to either (a) understand it
semantically using canonical field names, (b) feed an automation that
watches canonical fields, or (c) build up history for the machine.
query_machine_history
Retrieve operational history for an identified machine. Each row is
one /v1/normalize call's canonical output (FCS field → value).
Query options:
from_dt, to_dt ISO-8601 timestamps to bound the time range
fields comma-separated FCS field names to project; omit for
full canonical_data
limit max rows (1–1000, default 100)
summary true → returns aggregate stats only (row_count,
time range, avg coverage_pct, fields_covered set)
without the raw rows. Always cheap.
USE WHEN: a user asks how a machine has been running, wants utilization
or throughput or health trends, looks for patterns in alarms or
operational state, compares periods ("how was today vs yesterday"), or
wants to know what data is even available for a machine. Prefer
`summary=true` first to orient on volume + which fields are present,
then drill in with field projection on a smaller time window.
create_automation
Set up automated monitoring + actions for an industrial machine
using natural language. Connect machine telemetry to any business
system — ERP, CMMS, MES, Slack, Teams, email, Zapier, n8n — via
webhooks already registered as tools on the Forge service.
Examples of `instruction`:
"Alert maintenance Slack when spindle load exceeds 90 percent."
"Create a Fiix work order when coolant temperature stays above 35°C
for five minutes."
"Notify the supervisor when part_count hits 500."
"When the maintenance_type changes to CORRECTIVE, post to the ops
channel."
Returns a `parsed_trigger` JSON for HUMAN review — DOES NOT
auto-activate. The caller (you, with user confirmation) must
explicitly POST the parsed_trigger to /v1/triggers on the Forge API
to actually create it. The response includes
`confirmation_required: true` and may include `notes` if the parser
had to make a fuzzy match (e.g. resolved an ambiguous field name to
its closest canonical match).
USE WHEN: a user wants to set up monitoring, alerts, or automations
for machine state transitions. Always show the parsed_trigger to the
user verbatim and ask "Confirm to activate?" before they activate it.
activate_automation
Activate a parsed automation trigger on a machine. Call this AFTER
create_automation returns a parsed_trigger and the user explicitly
confirms they want to arm it.
Creates a live trigger that monitors the machine's normalized telemetry
and fires the listed actions when the condition matches. Each action
references a registered tool by tool_id; on fire, the tool's webhook
is POSTed with {{variable}} interpolation against the canonical data
context (mint_id, oem, model, serial, site, field, value, threshold,
plus every canonical field on the matched record).
Inputs:
machine_id mint_id ("MINT-…") or internal_id; resolved to canonical mint_id
name short human label, ≤ 80 chars (e.g. "high spindle load")
condition simple {field, op, value|threshold} OR compound {all: [...]}
ops: >, <, >=, <=, ==, !=
actions list of {tool_id, payload_overrides?, headers_overrides?}
enabled defaults to true; pass false to create the trigger paused
Returns the persisted trigger row including `id` (use it later to
pause/edit/delete via the Forge API). Once active, the trigger fires
on every subsequent normalize_telemetry call where the condition
matches — no further activation needed.
USE WHEN: the user has reviewed the parsed_trigger from
create_automation and said something like "yes, activate it" /
"go ahead" / "arm it." Never call this tool without explicit
confirmation — it changes machine behavior in a way the user can
feel (real Slack messages, real ERP work orders).
list_automations
List all active automations / triggers configured for one machine.
Returns each trigger with: id, name, condition (field/op/value or
compound `all`), actions (each resolved to its tool name + url +
method), enabled state, fire_count, last_fired_at, last_error.
USE WHEN: the user asks "what automations do I have on this machine"
/ "show me my triggers" / "what alerts am I getting" / "what's
monitoring this machine right now". Always pass the machine's
mint_id (or internal_id — both resolve).