FERS desde la terminal y desde agentes de código

El paquete de Python pone el solver en su máquina y, desde 0.1.100, el comando fers con él. Una shell, un script, un trabajo de CI o un agente de código valida un modelo, lo resuelve en un archivo y lee solo los números que necesita — en tiempo de motor, sin ida y vuelta al servidor y sin nada que conectar.

1. Instalar y comprobar qué tiene

Un solo paquete contiene los objetos de modelado, el motor compilado y el comando. fers doctor imprime las versiones y dónde están los ejemplos; con una clave, pregunta además al servidor de licencias si la clave se acepta.

pip install FERS
fers doctor --offline      # versions and where the examples live
fers version

Sin clave de API el motor trabaja en el plan gratuito, para uso no comercial hasta 100 barras, y no hace ninguna llamada de red. Ponga una clave en FERS_API_KEY (o pase --api-key) para Pro, que cubre el uso comercial; el motor la verifica entonces con ferscloud.com una vez por cálculo.

2. El ciclo: modelar, validar, resolver, leer

El modelado sigue en Python, donde están los objetos y los ejemplos numerados. El comando toma el relevo en el archivo: valida el JSON contra el esquema de entrada del motor, se lo entrega sin cambios e informa en una línea.

  1. Modelar en Python — Constrúyalo con fers_core en unidades SI y guárdelo con model.save_to_json("model.json"). fers examples list y fers examples show 001 son la referencia más rápida de la API de objetos.
  2. Validar el archivo — fers validate model.json lo comprueba contra el esquema de entrada y nombra el campo que falla. fers schema --list y fers schema Member imprimen el esquema cuando un nombre de campo ofrece dudas.
  3. Resolver en un archivo — fers solve model.json --out results.json escribe los resultados directamente en el archivo. La salida estándar es una línea de resumen, o un objeto JSON con --json.
  4. Leer una selección — Cargue el archivo resuelto con FERS.from_json y lea el caso de carga o la combinación que necesite, o pida menos de antemano al motor con un ResultRequest.
python build_model.py                     # authors with fers_core and saves model.json
fers validate model.json                  # the input schema, naming the field that fails
fers solve model.json --out results.json  # the engine streams the results to the file
# solved: 3 load cases, 8 combinations in 0.4 s -> results.json (2.1 MB)

3. Los resultados se quedan en archivos

fers solve nunca analiza los resultados: el motor los escribe y el comando lee de vuelta solo lo justo para el resumen. Un modelo que escribe cientos de megabytes no cuesta nada al proceso ni al contexto de un agente. El código de salida dice qué ocurrió, de modo que un script o un agente puede ramificar sin leer prosa.

  • 0 resuelto. 4 resuelto, pero el motor registró fallos (solve_failures, load_case_failures): léalos antes de usar cualquier número.
  • 1 el motor rechazó el cálculo o este falló, con su mensaje en stderr. 2 entrada incorrecta: archivo ausente, JSON inválido, un modelo que no cumple el esquema.
  • 3 licencia: sin clave donde hace falta una, clave rechazada, o la comprobación de licencia agotó el tiempo.
  • La línea de resumen cuenta casos de carga, combinaciones, fallos registrados, conjuntos de resultados que no convergieron, y los errores y avisos del motor.
from fers_core import FERS, ResultBlock, ResultRequest

# Before solving: ask the engine for only the blocks you will read.
model.settings.analysis_options.result_requests = [
    ResultRequest(ResultBlock.REACTIONS, limit_state="ULS"),
    ResultRequest(ResultBlock.NODE_DISPLACEMENTS, components=["dy"]),
]
model.save_to_json("model.json")

# After "fers solve model.json --out results.json":
solved = FERS.from_json("results.json")
case = solved.resultsbundle.loadcombinations["ULS 1"]
print(case.reaction_nodes["1"].nodal_forces.fy)

4. Comprobaciones normativas e informes

Un modelo con definiciones de comprobación — check_beam en fers_core.builders construye uno en una línea — recibe su veredicto EN 1993-1-1 de fers check: estado, aprovechamiento y barra determinante por comprobación. fers report genera el informe HTML con cálculo manual a partir de un documento ya resuelto, sin volver a calcular.

fers check beam.json --out beam_solved.json
# ec3: Green, utilization 0.778, governing 1 in combination 1
fers report beam_solved.json --out report.html

5. Catálogos y el esquema

Las tablas de perfiles (EN, British Steel, AISC) y los materiales predefinidos son los mismos que resuelven los objetos de Python, impresos en SI para que un valor pueda cotejarse con un prontuario antes de entrar en un modelo.

fers sections list --series HEB
fers sections get IPE200          # h, b, i_y, i_z, j, area, wel, wpl ... in m, m2, m4
fers materials list
fers materials get S355 --json
fers schema --list                # the schema's definitions, one line each
fers schema Member                # one definition in full

6. Agentes de código y el archivo skill

Un agente con shell — Claude Code, Codex, el agente de Cursor, un runner de CI — no necesita servidor ni conector: el paquete es el solver. Lo que necesita es el ciclo anterior en una forma que lea antes de empezar, y eso es el archivo skill: una página en formato skill con el paso de instalación, el ciclo, cómo leer resultados y cuándo usar en su lugar el servidor MCP.

El archivo va dentro del paquete, y fers skill --install . lo escribe en .claude/skills/fers/SKILL.md, donde lo busca Claude Code; fers skill --path da su ruta para cualquier otro agente. También vive en el repositorio FERS_core. Los agentes que leen en vez de llamar siguen teniendo llms.txt y la versión Markdown de esta página en /docs/command-line.md.

fers skill --install .     # writes .claude/skills/fers/SKILL.md, where Claude Code looks
fers skill --path          # the file's path, for any other agent
fers skill                 # or read it

7. ¿CLI o MCP?

Lo decide dónde se ejecuta el agente, no qué protocolo es mejor en abstracto. Ambas vías ejecutan el mismo motor y devuelven los mismos números.

  • Un agente de terminal (Claude Code, Codex, un trabajo de CI) instala el paquete: el cálculo corre en su propia máquina en tiempo de motor, no hay límites de peticiones ni tiempos de espera, los resultados se quedan en archivos y modela en Python a partir de los ejemplos.
  • Un cliente de escritorio o de editor (Claude Desktop, Cursor, VS Code, ChatGPT de escritorio) usa el servidor MCP local: calcula en la misma máquina, y una sola llamada a una herramienta devuelve los números comprobados. Un agente de terminal también puede usarlo; para una comprobación llave en mano necesita menos turnos que el comando.
  • Una app de chat en el navegador o en un teléfono usa el servidor MCP alojado: construye y valida el modelo y devuelve un enlace que lo calcula en su navegador.
  • Ambos pueden compartir una cuenta: la clave de API que eleva los límites del comando es la clave que acepta el servidor MCP.

Páginas relacionadas

Véase también

Preguntas frecuentes

¿`fers solve` calcula en mi máquina o en la nube?

En su máquina. El motor está compilado dentro del paquete; la única llamada de red es la comprobación de licencia cuando hay una clave de API, una vez por cálculo. Sin clave no hay ningún acceso a la red.

¿Necesito una clave de API?

Para el uso comercial, con cualquier tamaño de modelo, y para modelos por encima del límite gratuito de 100 barras (Pro llega a 10,000). Ponga la clave en FERS_API_KEY o pase --api-key; fers doctor le dice si se acepta.

¿Por qué `fers solve` no imprime los resultados?

Porque pertenecen a un archivo. Un documento resuelto puede llegar a cientos de megabytes, y un agente que lo pega en su contexto ha perdido el hilo. El comando imprime una línea de resumen, y FERS.from_json o un ResultRequest lee la parte que necesita.

¿Puedo usar el comando en CI?

Sí. Es un script de consola normal con códigos de salida significativos y salida --json, y el motor no necesita pantalla ni GPU. Fije la versión del paquete, defina FERS_API_KEY como secreto si los modelos superan el límite gratuito y guarde el wheel en caché.