Skip to main content
Glama
FoundryNet

forge-sandbox

by FoundryNet

Forge Sandbox

Datos simulados, esquema real.

Una simulación local y sin claves del núcleo de telemetría industrial Forge. Ejecútala en tu portátil, desarrolla la integración de tu agente contra ella y luego apunta el mismo código a Forge en producción para hablar con equipos reales.

Sin clave de API. Sin cuenta. Sin registro. No se guarda nada. La aplicación no realiza llamadas salientes.

docker run -p 8000:8000 ghcr.io/foundrynet/forge-sandbox

Multiarquitectura: linux/amd64 y linux/arm64. Fija una versión con ghcr.io/foundrynet/forge-sandbox:1.0.0 si prefieres no seguir latest.

¿El puerto 8000 ya está ocupado? docker run -p 8099:8000 ..., o con compose: FORGE_SANDBOX_PORT=8099 docker compose up.

curl -X POST http://localhost:8000/v1/normalize \
  -H "Content-Type: application/json" \
  -d '{"oem": "haas", "data": {"S SPEED (RPM)": 8500, "SP_LOAD_PCT (%)": 84.7, "COOL_TEMP [°F]": 161.8}}'
{
  "normalized": {
    "spindle_speed_rpm": 8500,
    "spindle_load_pct": 84.7,
    "sensor_readings.coolant_temp": 72.1111
  },
  "coverage_pct": 100.0,
  "fields_total": 3,
  "fields_distinct_canonical": 3,
  "unit_conversions": [
    {"raw_field": "COOL_TEMP [°F]", "canonical_field": "sensor_readings.coolant_temp",
     "from": "f", "to": "c", "conversion": "fahrenheit_to_celsius",
     "raw_value": 161.8, "converted_value": 72.1111}
  ],
  "oem": "haas",
  "vertical": "cnc",
  "simulated": true
}

Para qué sirve

Los equipos industriales de N fabricantes producen telemetría en N formatos incompatibles. La velocidad del husillo es S SPEED (RPM) en un Haas, Nist_Spindle (RPM) en un SINUMERIK y ACT_SP_SPEED_1/min en un FANUC. Tu agente no debería tener que aprender los tres.

Forge traduce cualquiera de ellos a un vocabulario canónico. El sandbox te permite desarrollar contra ese vocabulario antes de tener equipos, credenciales o presupuesto.

Sandbox

Producción

Datos

simulados

tus máquinas reales

Esquema canónico

real

real

Mapeos de etiquetas de fabricante

1,515 (fuentes públicas)

16,908 seleccionados

Etiquetas sin resolver

clasificador de señales

+ embeddings, + investigación con LLM, + autocuración

Predicción

mínimos cuadrados

TimesFM (200M parámetros)

Autenticación

ninguna

clave de API

Persistencia

ninguna

historial, identidad, disparadores, salvaguardas

Coste

gratuita

ver precios

Las estructuras de las respuestas son idénticas. Ese es el contrato. Desarrolla contra el sandbox, cambia la URL base, añade una cabecera Authorization: Bearer y tu código de cliente no cambia.


Related MCP server: operational-data-mcp

Cinco minutos

El sandbox incluye cinco máquinas simuladas. Cada una emite sus nombres reales de etiquetas de fabricante: las grafías reales que te encuentras en la transmisión.

# 1. See what's here
curl -s localhost:8000/v1/machines | jq '.machines[].description'

# 2. Pull a raw reading — vendor tags, unnormalized
curl -s localhost:8000/v1/simulate/siemens | jq .data
{
  "Betriebszustand": "AUTOMATIK",
  "PROGRAMM": "WELLE_STUFE3.MPF",
  "Nist_Spindle (RPM)": 1203,
  "SPINDEL_AUSLASTUNG (%)": 62.4,
  "Kuehlmittel Temp (C)": 30.6,
  "STUECKZAHL (pcs)": 842,
  "Betriebsstunden": 14203.5
}

Tu agente no puede adivinar que STUECKZAHL es un recuento de piezas y que Betriebsstunden son horas de funcionamiento. No tiene por qué hacerlo:

# 3. Normalize it
curl -s localhost:8000/v1/simulate/siemens \
  | jq '{oem, data}' \
  | curl -s -X POST localhost:8000/v1/normalize -H 'Content-Type: application/json' -d @- \
  | jq .normalized
{
  "execution_state": "AUTOMATIK",
  "program_name": "WELLE_STUFE3.MPF",
  "spindle_speed_rpm": 1203,
  "spindle_load_pct": 62.4,
  "sensor_readings.coolant_temp": 30.6,
  "part_count": 842,
  "operating_hours": 14203.5
}
# 4. Forecast — grab a series, ask whether it breaches
curl -s 'localhost:8000/v1/simulate/fanuc/series?field=MOTOR_TEMP&points=48' > /tmp/s.json

jq '{time_series: .values, threshold: 75.0, canonical_field: .canonical_field}' /tmp/s.json \
  | curl -s -X POST localhost:8000/v1/predict_breach -H 'Content-Type: application/json' -d @- \
  | jq '{will_breach, estimated_steps_to_breach, confidence, breach_window}'

Las cinco máquinas

Clave

Equipo

Protocolo

Estilo de etiqueta

haas

Centro de mecanizado Haas VF-2SS

MTConnect

S SPEED (RPM), SP_LOAD_PCT (%)

fanuc

Robot de 6 ejes FANUC R-30iB

FOCAS

TCPVEL (mm/s), PAYLOADKG(kg)

siemens

SINUMERIK 840D sl / S7-1500

PROFINET

SPINDEL_AUSLASTUNG (%), STUECKZAHL (pcs)

prusa

Impresora 3D Prusa MK3S+

Marlin serial

hotend_temp, heater_power, pinda_temp

carrier

Carrier 48TC HVAC de cubierta

BACnet/IP

SupplyTemp, DamperPosition, CO2

Añade ?seed=N a cualquier llamada simulate para que sea repetible.


Endpoints

Endpoint

Qué hace

POST /v1/normalize

telemetría bruta del fabricante → campos canónicos (JSON o text/csv)

POST /v1/predict_breach

si una serie cruzará un umbral, y cuándo

POST /v1/fleet_health

resumen de flota, distribución de riesgo, cola de mantenimiento

POST /v1/predict_batch

predicciones por máquina, sin resumen

GET /v1/coverage

qué se puede normalizar; pasa ?oem= para consultar uno

GET /v1/canonical-fields

el diccionario canónico: nombre, tipo, unidad, vertical

GET /v1/machines

las cinco máquinas simuladas

GET /v1/simulate/{machine}

una lectura bruta

GET /v1/simulate/{machine}/series?field=

un historial de una etiqueta bruta

GET /health

comprobación de vida (GET y HEAD)

ANY /mcp

servidor MCP, Streamable HTTP

GET /docs

navegador OpenAPI

Los endpoints que existen en producción pero necesitan estado persistente — /v1/history, /v1/identify, /v1/guardrails, /v1/triggers, /v1/attest, /v1/billing/usage — devuelven 501 con el motivo, no un 404 simple, para que puedas distinguir "no está en el sandbox" de "lo escribiste mal".


MCP

El sandbox también es un servidor MCP. Apunta Claude Desktop, Claude Code o cualquier cliente MCP a http://localhost:8000/mcp.

{
  "mcpServers": {
    "forge-sandbox": {
      "type": "http",
      "url": "http://localhost:8000/mcp"
    }
  }
}

Claude Code:

claude mcp add --scope user --transport http forge-sandbox http://localhost:8000/mcp

--scope user importa. Sin él, claude mcp add registra el servidor local al directorio actual, por lo que se resuelve allí y en ningún otro sitio — ejecuta claude mcp get forge-sandbox desde el proyecto en el que realmente quieras usarlo y obtendrás "No MCP server named forge-sandbox". El ámbito de usuario lo hace disponible en todas partes. Para quitarlo:

claude mcp remove forge-sandbox -s user

Ocho herramientas. Las cinco que existen en producción llevan las descripciones de herramientas de producción textualmente, porque la descripción es la interfaz sobre la que razona tu agente: si aquí se lee de forma distinta, el comportamiento del prompt que ajustas contra el sandbox no se trasladará.

Tool

normalize_telemetry

producción

get_coverage

producción

predict_breach

producción

fleet_health

producción

predict_batch

producción

list_sandbox_machines

solo sandbox

get_sandbox_reading

solo sandbox

get_sandbox_series

solo sandbox

La descripción de cada herramienta termina con una nota SANDBOX:, de modo que un agente que lea la lista de herramientas sepa que los datos son simulados antes de actuar sobre nada.

Forge en producción expone 32 herramientas en https://mcp.foundrynet.io/mcp. Las otras 24 necesitan identidad persistente, historial, salvaguardas, disparadores, facturación o atestación en cadena.


Cómo funciona realmente la resolución aquí

Producción resuelve una etiqueta a través de cinco capas. El sandbox incluye las tres que no necesitan pesos de modelos, ni red, ni datos propietarios.

Capa

Tipo de coincidencia

Confianza

Qué es

1

corpus

1.00

etiqueta de fabricante exacta en un paquete de mapeos

1b

corpus_normalized

0.95

misma fila, una vez que se normalizan mayúsculas/puntuación/sufijo de unidad

1c

cross_oem

0.60

el paquete de otro fabricante lo conocía — informado, no oculto

2

identity

1.00

la etiqueta ya ES un nombre de campo canónico

3

signal

0.55–0.72

clasificador determinista de sujeto+cantidad

unknown

0.00

fallo honesto

Una etiqueta que no se resuelve a nada conserva su nombre y valor brutos en la salida. Nada se descarta silenciosamente y no cuenta para la cobertura.

coverage_pct es campos canónicos distintos ÷ total de etiquetas. Diez grafías de una misma cantidad son un campo cubierto, no diez. (Producción tuvo exactamente este bug y reportó una cobertura del 100% en un corpus sin sembrar.)

El sandbox nunca inventa un nombre canónico. Cada nombre que emite sale del diccionario incluido, y los objetivos del clasificador se validan contra ese diccionario al arrancar: un error tipográfico hace fallar el contenedor, no envía un campo incorrecto con apariencia plausible.


Lo que NO está en esta imagen

De forma deliberada, y dicho claramente para que nada de aquí se confunda con la versión real:

  • El corpus de mapeos de producción. 16,908 mapeos seleccionados con puntuaciones de confianza y procedencia. El sandbox incluye 1,515 mapeos ensamblados solo a partir de fuentes ya públicas: el esquema canónico con licencia MIT (haas, fanuc, siemens, octoprint), el paquete vertical BACnet/IP incluido más los nombres de objetos Carrier i-Vu, y los nombres de campos Marlin M105/M114 que cualquier Prusa emite por el puerto serie. tools/build_packs.py muestra exactamente de dónde procede cada fila.

  • La capa de embeddings. Producción genera embeddings de las etiquetas no reconocidas y las empareja por similitud. Aquí no hay pesos de modelos.

  • Investigación de campos con LLM. Producción envía etiquetas realmente novedosas a un modelo, guarda la respuesta en caché, la confirma a los 5 usos y la empaqueta a los 10. Aquí no.

  • Validadores físicos y validadores de lectura. Tasa de cambio, sensor atascado, caída de señal, modo de funcionamiento, correlación, decaimiento de confianza. Aquí no.

  • TimesFM. Producción pronostica con un modelo fundacional de series temporales de 200M de parámetros. El sandbox usa mínimos cuadrados con una banda de cuantiles escalada por residuos. Cada predicción lleva el sello "model": "sandbox-ols-v1" y "simulated": true.

  • Persistencia, identidad, historial, disparadores, salvaguardas, facturación, atestación. Todo con estado, todo del lado del servidor.

  • Cualquier conexión con producción. La aplicación no importa ningún cliente HTTP ni ninguna API de socket, por lo que no hace llamadas salientes — grep -rE "httpx|requests|urllib|socket" app/ no devuelve nada. docker-compose.yml además la ejecuta read_only con todas las capacidades eliminadas. Ten en cuenta que esto refuerza el sistema de archivos, no la red: el puente por defecto de Docker sigue permitiendo la salida, así que si necesitas que eso se aplique de verdad y no solo sea cierto, ejecútala en una red internal.

Cada respuesta lleva "simulated": true y una cabecera X-Forge-Sandbox: true. Si alguna vez ves eso en un endpoint real, algo está mal enrutado.


Dos cosas que el sandbox hace mejor que producción

Ambas son problemas conocidos de producción, corregidos aquí porque un sandbox que te enseña la forma equivocada es peor que ningún sandbox.

  1. La escala PWM está declarada. El campo de calentador @: de Marlin es un byte de ciclo de trabajo de 0–127, no un porcentaje. El corpus de producción emite unit: null para él, por lo que una lectura de 95 se interpreta como "95%, cerca del máximo" cuando en realidad es alrededor del 75%. El sandbox declara unit: "pwm_0_127".

  2. Las unidades nulas se rellenan a partir de los nombres de campo. El corpus publicado declara una unidad para solo 58 de 366 campos. Cuando el nombre del campo indica la unidad (_temperature_c, _pressure_bar, _rpm), el sandbox la rellena y la marca con unit_source: "sandbox_inferred_from_name".


Desarrollo local

docker compose up --build          # build and run your local changes
docker build --target test .       # run the suite inside the shipping image

Sin Docker:

python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
python -m pytest tests/ -q
uvicorn app.main:app --reload --port 8000

Regenera los paquetes de mapeos desde el código fuente (necesita el repositorio canonical-schema clonado):

python3 tools/build_packs.py
forge-sandbox/
  app/
    main.py        FastAPI surface — the production response envelopes
    corpus.py      tag → canonical resolution, unit conversion, collisions
    simulate.py    the five machines
    predict.py     deterministic forecasting, production's response contract
    mcp_tools.py   MCP server, production tool descriptions
    packs/         generated mapping packs + the canonical dictionary
  tools/
    build_packs.py regenerates packs from the public sources
  tests/
    test_sandbox.py

Migración a producción

Dos cambios:

- BASE_URL = "http://localhost:8000"
- headers = {}
+ BASE_URL = "https://forge.foundrynet.io"
+ headers = {"Authorization": f"Bearer {FORGE_API_KEY}"}

Para MCP, sustituye http://localhost:8000/mcp por https://mcp.foundrynet.io/mcp.

Qué cambia por debajo:

  • Las etiquetas que el sandbox informó como unknown se resuelven mediante la capa de embeddings, la vía de investigación con LLM o los paquetes verticales.

  • Las predicciones provienen de TimesFM en lugar de una línea recta.

  • Las lecturas persisten, por lo que el historial, los disparadores y las salvaguardas empiezan a funcionar.

  • /v1/identify emite una identidad de máquina duradera.

  • Las predicciones pueden atestiguarse.

Consigue una clave: foundrynet.io


Sandbox:     fake data, real schema
Production:  real data, real schema, real predictions

Upgrade:     foundrynet.io

Licencia

MIT. Los paquetes de mapeo se derivan del esquema canónico de FoundryNet con licencia MIT; tools/build_packs.py documenta la procedencia de cada paquete.


Forge de Foundry Labs · forge@foundrynet.io

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    A local MCP server that breaks on demand, allowing you to test your client against auth failures, disappearing tools, flaky responses, and token expiry from a web UI.
    42
    10
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Exposes live industrial IoT telemetry to any MCP client, streaming simulated sensor data from a fleet of machines and detecting anomalies, with the ability to inject faults on demand.
    4
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Enables bounded, deterministic triage verdicts for server health, fleet status, and timeline investigation through a simulated execution-boundary MCP server.
    3
    5
    MIT

View all related MCP servers

Related MCP Connectors

  • Hosted MCP endpoint with realistic fake data for prototyping agents. 12 tools, no setup.

  • Self-hosted MCP gateway: turn any API, database or MCP server into AI connectors — no code.

  • MCP server exposing Kettle Logic insight articles & industry guidance as tools + resources.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/FoundryNet/forge-sandbox'

If you have feedback or need assistance with the MCP directory API, please join our Discord server