The universal industrial agent.

Plain English in. Autonomous action out.

16 OEM familiesΒ·Measured coverageΒ·Natural languageΒ·Tamper-evident work history

See it fire & settle Β· in minutes, no card Get a free API key

Self-serve signup

By continuing, you agree to the Terms of Service and Privacy Policy.

"Connect the DMG Mori on Line 6"
Machine ID MINT-4b20e2 created β€” work history attestation enabled
"Alert me when coolant exceeds 30Β°C"
Automation armed β€” monitoring sensor_readings.coolant_temp
"When inventory drops below 50 units, notify purchasing"
Automation armed β€” monitoring inventory_count
"New reading: coolant at 31.2Β°C"
Alert fired β†’ Slack #machine-alerts (186ms)

See it fire & settle. In minutes, no card.

The fire_sandbox MCP tool runs the full watch β†’ fire β†’ settle loop against a built-in echo endpoint and anchors a real Solana mainnet transaction. Ten fires per key, lifetime. No production data needed.

  1. 01

    Get a free key

    50 normalize calls + 10 sandbox fires. Email only, no card.

    Get free API key β†’
  2. 02

    Paste the MCP config

    Drop the snippet from Connect in 30 seconds into your Claude Desktop or Cursor config and restart the client.

  3. 03

    Ask Claude to fire the sandbox

    Then say: "Use fire_sandbox to fire a test alert with condition 'demo from foundrynet.io'." You get back a real tx_signature with a Solscan link.

    {
      "sandbox_echo": 200,
      "payload_hash": "53c5bf65…",
      "tx_signature": "2FdHy2Gv…hVjVg16",
      "verify_url": "https://solscan.io/tx/2FdHy2Gv…hVjVg16"
    }

Sandbox uses a built-in echo endpoint β€” no production webhooks fire and no machine is touched. The Solana settlement is real (mainnet) so the audit trail you'd get in production is the audit trail you get here.

Three steps. No code.

01Connect

Identify any machine by OEM, model, and serial. Or connect any business system via webhook. The agent works with machines and software.

02Talk

Send telemetry in any format or trigger evaluations from any source. Set up automations in one sentence. "Alert when coolant exceeds 30" or "notify purchasing when inventory drops below 50."

03Act

Triggers fire to any system. Slack, ERP, CMMS, MES, email. Every action logged, auditable, and anchored as a tamper-evident work record.

Claude Code for your operations.

The same AI that writes code from natural language can run your business operations. Update your ERP. Create work orders. Trigger purchase orders. Send shift reports. All from one sentence.

Machines

Connect any CNC, robot, or industrial equipment. The agent normalizes telemetry from any OEM, monitors health continuously, and takes action when conditions change. Every reading attested in a tamper-evident work record.

"Connect the Haas VF-2SS on Line 4"
"Alert when spindle load exceeds 85%"
"How's this machine trending?"

Operations

Connect any business system with a webhook. The agent triggers actions across ERP, CMMS, MES, quality, scheduling, email, and any HTTP endpoint. No integration code. No middleware. One sentence.

"When inventory drops below 50, notify purchasing"
"Every Friday at 5pm, send the production summary"
"Create a work order for coolant system maintenance"

Same agent. Same billing. Same audit trail. Machines and software, unified through natural language.

Works with everything you already have.

OEMs FanucSiemens HaasDMG Mori KomatsuMazak ABBKUKA Universal Robots
Systems SlackSAP EpicorOracle FiixUpKeep MaintainXPlex IgnitionAny webhook

Works with Claude Desktop, Cursor, GPT, or any MCP-compatible client. Complements AWS IoT, Azure IoT, Siemens MindSphere, PTC ThingWorx.

Measured coverage, per OEM.

Sixteen OEM families ship with normalized field-mapping coverage today. Status reflects test depth, not marketing tier: Production = field-validated against real telemetry; Beta = mapped from OEM docs, awaiting field signal; Early = partial mappings, expanding. We publish what we cover.

FanucProduction
SiemensProduction
HaasProduction
DMG MoriProduction
MazakProduction
OkumaBeta
MitsubishiBeta
Mori SeikiBeta
DoosanBeta
Hyundai-WIAEarly
HardingeEarly
KomatsuEarly
ABBBeta
KUKABeta
Universal RobotsBeta
YaskawaBeta

Don't see your OEM? Get a free API key and send us one normalize call β€” we'll quote a coverage timeline. Live machine-level coverage reported per request as coverage_pct in every /v1/normalize response.

One price per active machine.

A machine is the unit you care about. We charge per machine, not per packet. Each one gets a persistent Machine ID, a tamper-evident work history, and unlimited automations. Sampling cadence is included β€” the bill doesn't move when you sample more often.

Free explore
$0 forever
  • 50 normalize calls (lifetime)
  • 10 fire_sandbox demos (lifetime)
  • 1 machine, identity included
  • API + MCP + Claude Desktop access
Get free API key

Email only. No card.

Per active machine recommended
$49 /active machine/month
  • Persistent Machine ID + tamper-evident work history
  • Unlimited automations included
  • Unlimited normalize at any sampling cadence
  • Certified, signed history export premium
  • Billed only for machines that submit β‰₯1 normalize call that month

Email opens a draft to our team. We reply within 1 business day.

Volume / Enterprise 10+ machines
Custom contact
  • Volume discount per machine
  • Dedicated MCP endpoint + SLA
  • Certified history export included
  • SSO, on-prem ingestion options
Talk to us

Reply within 1 business day.

Certified Work History Export Β· $50 per report Audit-grade, signed machine work record with full normalized history, attestation hashes, and Solana provenance chain. Built for equipment lenders, insurers, and compliance auditors. Included with Fleet plan. Available as one-time purchase on any tier. GET /v1/history/{machine_id}/certified
Low volume? Use pay-as-you-go. normalize 1Β’/call Β· trigger 5Β’/fire Β· settle 2Β’/batch Β· history 1Β’/query Same key, same API. Auto-switches to per-machine billing once you connect a second active machine β€” no migration step. Volume discount auto-applies above 100K calls/month.

Identity: free. Automation setup: free. Trigger evaluation: free. Feedback: free.
"Active machine" = a machine that submitted β‰₯1 normalize call in the billing period.

One API. Every deployment.

Add FoundryNet to your integration toolkit. Every machine you connect gets cross-manufacturer normalization, natural-language automations, and a tamper-evident work record for every machine. Your customers get smarter machines. You get recurring revenue from every API call.

Become an integrator partner

Integrator revenue share program coming soon. Earn on every machine you connect.

Connect in 30 seconds.

Drop this into your Claude Desktop config:

{
  "mcpServers": {
    "foundrynet": {
      "command": "npx",
      "args": ["-y", "mcp-remote",
        "https://foundrynet-mcp-production.up.railway.app/sse",
        "--header", "Authorization:Bearer ${FNET_KEY}"],
      "env": { "FNET_KEY": "fnet_…  (free key at foundrynet.io/signup)" }
    }
  }
}

12 tools. SSE transport. Works with any MCP client.


API Reference

All /v1/* requests need Authorization: Bearer fnet_… and (where applicable) Content-Type: application/json. Base URL: https://forge.foundrynet.io.

Quick start

  1. Get your API key: self-serve via POST /v1/keys/checkout β†’ Stripe Checkout β†’ POST /v1/keys/activate (or use the form at the top of this page)
  2. Identify a machine: POST /v1/identify
  3. Send data: POST /v1/normalize
  4. Connect a tool: POST /v1/tools
  5. Set up automation: POST /v1/triggers/natural
  6. Query history: GET /v1/history/{mint_id}
  7. Verify on-chain: POST /v1/settle

Endpoints

POST /v1/identify

Provision or look up a persistent on-chain identity (mint_id) for one machine. Idempotent on (oem, model, serial).

{
  "oem":    "fanuc",
  "model":  "Robodrill Ξ±-D21MiB5",
  "serial": "R30iB-12345",
  "site":   "Line 3"
}
{
  "mint_id":     "MINT-4de03b",
  "internal_id": "fanuc:robodrill-a-d21mib5:r30ib-12345",
  "created":     true,
  "machine":     { "status": "active" },
  "first_seen":  "2026-05-04T01:00:00Z"
}
POST /v1/normalize

Translate raw OEM telemetry to canonical FCS data. Auto-provisions identity from oem/model/serial when no machine_id is given. Returns triggers_fired[] when any active trigger matches. Optional idempotency_key dedups retries within 24h. Optional observed_at (ISO 8601 controller clock) is stored alongside the server ingested_at.

{
  "data":   { "Spindle_Speed": 2200, "spindle_load": 92 },
  "oem":    "fanuc",
  "model":  "Robodrill Ξ±-D21MiB5",
  "serial": "R30iB-12345",
  "observed_at":     "2026-05-05T09:30:15Z",
  "idempotency_key": "optional-caller-supplied-key"
}
{
  "normalized":      { "spindle_speed_rpm": 2200, "spindle_load_pct": 92 },
  "field_mappings":  { "spindle_load": { "mapping_id": "6c34…", "canonical": "spindle_load_pct", "confidence": 0.93 } },
  "fields_total":    2, "fields_renamed":  2, "fields_identity": 0, "fields_unknown":  0,
  "coverage_pct":    100,
  "machine_id":      "MINT-4de03b",
  "history_id":      "c419…",
  "triggers_fired":  [{ "trigger_id": "7f0c…", "trigger_name": "high spindle load", "actual_value": 92 }]
}
POST /v1/tools

Register a webhook endpoint as a tool. Triggers reference these by tool_id. auth_secret returned ONCE on create; never read back via GET.

{
  "name": "slack-maintenance",
  "url":  "https://hooks.slack.com/services/T…/B…/xxx",
  "method": "POST",
  "payload_template": { "text": "Alert: {{oem}} {{model}} β€” {{field}} at {{value}}" },
  "auth_type": "none"
}
{ "id": "add2…", "name": "slack-maintenance", "auth_type": "none", "enabled": true }
POST /v1/triggers/natural

Parse a natural-language instruction into a structured trigger. NEVER auto-activates; returns parsed_trigger for review and explicit POST to /v1/triggers.

{ "machine_id": "MINT-4de03b", "instruction": "Alert maintenance Slack when spindle load exceeds 90." }
{
  "parsed_trigger": {
    "machine_id": "MINT-4de03b",
    "name": "Spindle Load Alert",
    "condition": { "field": "spindle_load_pct", "op": ">", "value": 90 },
    "actions":   [{ "tool_id": "add2…" }]
  },
  "confirmation_required": true
}
GET /v1/history/{mint_id}

Per-machine canonical history. Query params: from, to (ISO-8601), fields (csv), limit (≀1000), summary (bool).

GET /v1/history/MINT-4de03b?limit=5&summary=true
{
  "mint_id":  "MINT-4de03b",
  "machine":  { "oem": "fanuc", "model": "Robodrill Ξ±-D21MiB5", "site": "Line 3" },
  "row_count": 2,
  "avg_coverage": 100,
  "fields_covered": ["spindle_load_pct", "spindle_speed_rpm", "sensor_readings.coolant_temp"]
}
POST /v1/settle

Anchor data on Solana mainnet via the MINT relay. Add ?batch=true with body {"mint_id": "…"} to Merkle-root all unsettled events for that machine into one transaction.

POST /v1/settle?batch=true
{ "mint_id": "MINT-4de03b" }
{
  "mint_id":      "MINT-4de03b",
  "merkle_root":  "413d5ec…",
  "event_count":  4,
  "tx_signature": "2yiyp…",
  "verify_url":   "https://solscan.io/tx/2yiyp…"
}

MCP server

SSE endpoint: https://foundrynet-mcp-production.up.railway.app/sse

12 tools

Reliability + provenance

Soft delete

DELETE /v1/triggers/{id} defaults to soft delete β€” sets deleted_at, hides from list/eval, restorable for 30 days via PATCH /v1/triggers/{id}/restore. Add ?permanent=true for irrecoverable hard delete.

Idempotency

/v1/normalize accepts an optional idempotency_key. If absent, server synthesizes sha256(mint_id + canonical(data))[:32]. Repeats within 24h return the original response with deduplicated: true and skip trigger evaluation.

Coverage metric

Every /v1/normalize response carries three counters: fields_renamed (source != canonical), fields_identity (source == canonical), fields_unknown (no mapping). coverage_pct = (renamed + identity) / total.

Provenance timestamps

observed_at (ISO 8601 from the controller clock) is optional on /v1/normalize. Stored alongside ingested_at (server). When the difference exceeds 60s, response includes clock_skew_warning. Sustained-condition windows reference observed_at when present.

Structured errors

{
  "error":  true,
  "status": 422,
  "field":  "body.oem",
  "reason": "Field required",
  "received_value": {},
  "suggestion":     "e.g. 'fanuc'",
  "additional_errors": [ { "field": "body.model", "reason": "Field required" } ]
}

Pricing

Metered billing via Stripe. Counts roll up to your subscription's current billing period and settle on Stripe's normal cycle. Query GET /v1/usage for live counts and an estimated bill.

Get an API key via the self-serve flow: POST /v1/keys/checkout with {email} returns a Stripe Checkout URL; after the user adds a card, POST /v1/keys/activate with {session_id} returns the fnet_… key (shown once).

Who's behind this. How we protect your data.

About

FoundryNet Labs builds developer infrastructure for natural-language machine automation. We're a small team based in Reno, Nevada. Backed by operators and integrators across the CNC, robotics, and discrete-manufacturing stack.

Contact: hello@foundrynet.io

Security

  • Fernet symmetric encryption on webhook auth secrets at rest.
  • HMAC-SHA256 signing on every outbound webhook delivery.
  • Supabase Row Level Security isolates accounts at the database level.
  • API keys hashed (SHA-256) β€” we store the hash, not the key.
  • Idempotency by content hash on /v1/normalize prevents duplicate processing.

Full detail in the Privacy Policy.