Prototyp · Vorschau: alle Server aus der offiziellen Registry, alle 30 Minuten synchronisiert. Bewertungen und Benutzerkonten folgen in einem späteren Schritt.
PopNx MCPMCP-Server für alle, die KI nutzen · in einfachen Worten erklärt

FERS — structural FEM

von Jeroen124Version 2.83.0i★ –iComputer oder Cloud
Name in der Registrycom.ferscloud/fers

Installieren

Überblick

Beschreibung vom Entwickler (englisches Original)

Structural FEM for AI agents: frames, plates, buckling, seismic and Eurocode checks, solved locally.

Die drei Säulen von PopNx MCP

Diese drei werden nie zu einer Punktzahl zusammengefasst: Meinungen, Messungen und Beliebtheit sind verschiedene Dinge.

Was du damit machen kannst

Für diesen Server haben wir noch keine Zusammenfassung in einfacher Sprache geschrieben. Unten stehen die Fakten, die wir aus der Registry gelesen haben.

  • Verbindung: Computer oder Cloud
  • Transport: stdio, Streamable HTTP
  • Kategorie: Sonstiges
  • Das musst du eintragen: FERS_API_KEY

Installation

Wähle die KI-App, die du nutzt, und kopiere die Einstellungen.

Bevor du installierst

  • Basischecks: 2 von 3 bestanden
  • Läuft auf dem Server des Entwicklers: Was du fragst, läuft über dessen Server.
  • Das trägst du selbst ein: FERS_API_KEY

Als geheim markierte Werte sind Schlüssel zu deinem Konto. Gib sie nie weiter und füge sie nie in einen Chat ein.

Du brauchst

  • Läuft in der CloudNichts zu installieren; die Verbindung läuft übers Internet
  • npmNode.js installiert (für den Befehl npx)

Welche App nutzt du?

Wähle oben deine App. Wir merken sie uns, damit der Button beim nächsten Mal „In … installieren“ anzeigt.

Funktioniert in Claude im Web, auf dem Desktop und auf dem Handy:

  1. Öffne Settings → Connectors
  2. Tippe auf Add custom connector
  3. Füge die Adresse unten ein und tippe auf Add
  4. Wenn eine Anmeldung verlangt wird, melde dich beim Dienst des Entwicklers an
SettingsConnectors1+ Add2https://…3
https://ferscloud.com/api/mcp

Oder führ ihn auf deinem Computer aus

Öffne Claude Desktop → Settings → Developer → Edit Config und füge dies in claude_desktop_config.json ein

{
  "mcpServers": {
    "fers": {
      "command": "npx",
      "args": [
        "-y",
        "@ferscloud/fers-mcp"
      ],
      "env": {
        "FERS_API_KEY": "your-value"
      }
    }
  }
}

Führe das in deinem Terminal aus

claude mcp add --transport http fers https://ferscloud.com/api/mcp

Oder führ ihn auf deinem Computer aus

claude mcp add fers --env FERS_API_KEY=your-value -- npx -y @ferscloud/fers-mcp

Trag die leeren Werte ein, bevor du ihn startest.

In Cursor öffnen

Oder kopier die Einstellungen selbst

In .cursor/mcp.json in deinem Projekt oder in ~/.cursor/mcp.json einfügen

{
  "mcpServers": {
    "fers": {
      "url": "https://ferscloud.com/api/mcp"
    }
  }
}

Oder führ ihn auf deinem Computer aus

In Cursor öffnen

Oder kopier die Einstellungen selbst

In .cursor/mcp.json in deinem Projekt oder in ~/.cursor/mcp.json einfügen

{
  "mcpServers": {
    "fers": {
      "command": "npx",
      "args": [
        "-y",
        "@ferscloud/fers-mcp"
      ],
      "env": {
        "FERS_API_KEY": "your-value"
      }
    }
  }
}

Dein Browser fragt, ob er die App öffnen darf, dann zeigt die App die Einstellungen und bittet dich um Bestätigung. Schlüsselwerte bleiben leer, damit du sie selbst einträgst.

In VS Code öffnen

Oder kopier die Einstellungen selbst

In .vscode/mcp.json in deinem Projekt einfügen

{
  "servers": {
    "fers": {
      "type": "http",
      "url": "https://ferscloud.com/api/mcp"
    }
  }
}

Oder führ ihn auf deinem Computer aus

In VS Code öffnen

Oder kopier die Einstellungen selbst

In .vscode/mcp.json in deinem Projekt einfügen

{
  "servers": {
    "fers": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@ferscloud/fers-mcp"
      ],
      "env": {
        "FERS_API_KEY": "your-value"
      }
    }
  }
}

Dein Browser fragt, ob er die App öffnen darf, dann zeigt die App die Einstellungen und bittet dich um Bestätigung. Schlüsselwerte bleiben leer, damit du sie selbst einträgst.

ChatGPT verbindet sich nur mit Servern im Internet:

  1. Öffne ChatGPT im Web → Settings → Connectors (Apps)
  2. Tippe auf Create oder Add (bei manchen Tarifen musst du zuerst Developer mode unter Advanced einschalten)
  3. Füge die Adresse unten ein, gib ihr einen Namen und speichere
  4. Wenn eine Anmeldung verlangt wird, melde dich beim Dienst des Entwicklers an
SettingsConnectors1+ Create2https://…3
https://ferscloud.com/api/mcp

Menünamen können sich je nach Tarif und mit der Zeit leicht unterscheiden.

Deine Auswahl bleibt in einem Cookie auf diesem Gerät; kein Konto nötig.

Werte, die du selbst einträgst

  • FERS_API_KEY geheim env
    Optional FersCloud API key. Without it every solve runs on the Free tier: non-commercial use only, up to 100 members. A Pro account covers commercial use and raises the limit to 10,000.

Diese Einstellungen werden aus dem Registry-Eintrag des Entwicklers erzeugt. Wenn in der README etwas anderes steht, folge der README.

Was er kann

Der Server verlangt eine Anmeldung, bevor er seine Tools auflistet.

Basischecksi

Wir prüfen Informationen, die jeder sehen kann; den Code haben wir nicht gelesen. Checks, die nicht zutreffen, werden nicht mitgezählt. · Geprüft am 7. Nov. 2026

  • ! Vorsicht

    Entwickler passt zum Repo

    Der Herausgeber (ferscloud.com) ist nicht der Repo-Inhaber (Jeroen124); vielleicht hat jemand anderes ihn eingetragen

  • … Noch nicht geprüft

    Wird noch gepflegt

    Dieses Repo haben wir noch nicht von GitHub gelesen

  • … Noch nicht geprüft

    Hat eine Lizenz

    Dieses Repo haben wir noch nicht von GitHub gelesen

  • ✓ Bestanden

    Endpunkt antwortet

    Antwort in 51 ms (HTTP 401)

  • ✓ Bestanden

    Anmeldung mit OAuth

    Gibt OAuth-Anmeldung an, damit deine KI-App dich zum Einloggen weiterleiten kann

  • … Noch nicht geprüft

    Keine versteckten Anweisungen in Tool-Beschreibungen

    Noch nicht geprüft; wir lesen die Tool-Liste, wenn wir den Endpunkt prüfen

Im Vergleich mit anderen in Sonstigesi

  • Mehr Sterne als 0 % der anderen 32558 Server in dieser Kategorie
  • Neuer in der Registry veröffentlicht als 92 % der anderen 32558 Server in dieser Kategorie
  • Basischecks gleich gut wie oder besser als bei 37 % der anderen 32558 Server in dieser Kategorie

Verglichen mit allen aktiven Servern dieser Kategorie in der Registry. Sterne zählen nur, wenn dem Herausgeber das Repo gehört.

Häufige Fragen

Ist FERS — structural FEM sicher?

Er hat 2 von 3 zutreffenden Basischecks bestanden. Den Code haben wir nicht gelesen. Bevor du einen Schlüssel oder Token hinzufügst, sieh nach, welche Zugriffe der Server verlangt, und nutze einen Schlüssel, der nur die Berechtigungen hat, die du brauchst.

Welche Schlüssel oder Codes braucht er?

Das musst du eintragen: FERS_API_KEY

Läuft er auf meinem Computer oder in der Cloud?

Beides geht: Installiere ihn auf deinem Computer oder verbinde dich mit der Cloud-Version.

Wird er noch gepflegt?

Das GitHub-Repo wurde zuletzt – geändert, und die neueste Version (2.83.0) kam vorgestern in die Registry.

Welche Apps können ihn nutzen?

Apps, die MCP unterstützen, etwa Claude Desktop, Claude Code, Cursor und VS Code. Er verbindet sich per URL, also funktionieren auch Apps, die Remote-MCP-Server akzeptieren, zum Beispiel ChatGPT im Entwicklermodus.

Was kann ich stattdessen nutzen?

In derselben Kategorie: Spec Driven Development, Remote Desktop Commander, FactLot

Alternativen

Server derselben Kategorie von anderen Entwicklern, sortiert nach Sternen.

So liest du eine Karte:★ GitHub-SterneiDrei Säulen: Bewertungen · Checks · NutzungiAktualisiert = neueste Version in der Registry veröffentlichti

Spec Driven Development

von formulahendry

MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.

Läuft auf deinem Computer★ 440MITAktualisiert vor 14 Monaten
Installieren

Remote Desktop Commander

von desktop-commander

Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.

Läuft in der Cloud★ 211Aktualisiert gestern
Installieren

FactLot

von 9mp96ygnbk-alt

Cited CRE facts and deterministic calculators for agents: rent, CAM, debt sizing, IRR, parcel IDs.

Computer oder CloudAktualisiert heute
Installieren

README vom Entwickler

README öffnen

Unverändert aus dem Repo des Entwicklers übernommen. PopNx MCP hat den Inhalt weder geprüft noch empfiehlt es ihn. HTML, Bilder und Skripte wurden entfernt. Links führen von dieser Website weg.

FERS: structural analysis in Python

FERS: structural finite-element analysis (3D frames, trusses, plates, Eurocode 3 checks) for engineers and AI agents. This is its Python SDK and the fers command. The solver is a compiled engine that runs on your machine, with no account and no network call: free for non-commercial use up to 100 members. This SDK is open source (BSD-3-Clause) at github.com/Jeroen124/FERS_core; the engine's licence is under Licence.

It computes linear and second-order (P-Delta) static analysis, natural frequencies, elastic buckling load factors (α_cr), response-spectrum seismic analysis, and EN 1993-1-1 steel member checks, flexural and lateral-torsional buckling included. A model is JSON in and JSON out, written from Python, by the fers command, or by an AI agent through the FERS MCP server, the Claude Code plugin or the agent skill.

pip install FERS
from fers_core import check_beam

IPE200 in S235, simply supported over 6 m, 10 kN/m. SI units: m, N, Pa.

check_beam adds an EN 1993-1-1 member check on a ULS combination of 1.35 x the load.

model = check_beam(6.0, "IPE200", udl=10_000.0) model.settings.analysis_options.include_member_deflected_shape = True model.run_analysis()

beam = model.resultsbundle.loadcases["Q"].member_results["1"] x_frac, (_, dy, _) = beam.member_displacement_peak ec3 = model.unity_check_results()[0] print(f"M {beam.local_minimums.mz / 1e3:.1f} kNm, sag {dy * 1e3:.1f} mm at x/L {x_frac:.2f}") print(f"EC3 utilization {ec3['max_utilization']:.2f}")

M -45.0 kNm, sag -41.8 mm at x/L 0.50

EC3 utilization 2.85

The sag is 41.3 mm of bending (5wL⁴/384EI) plus 0.4 mm of shear deformation, which the engine includes. The beam fails: the ULS moment of 60.75 kNm exceeds its bending resistance of 51.9 kNm, and with nothing restraining its compression flange, lateral-torsional buckling takes the utilization to 2.85.

  • Agents and scripts: fers solve, fers check and fers validate take a model JSON file, print one line (or --json) and say in their exit code whether the numbers can be used; see From the terminal and from coding agents. fers skill --install . gives a coding agent the FERS skill, and MCP clients can use the FERS MCP server. In Claude Code, both come as one plugin: /plugin install fers --marketplace Jeroen124/FERS_core.
  • Extras: plots (pip install "FERS[plot]"), section properties meshed from your own dimensions ("FERS[sections]") and DXF import ("FERS[dxf]"); "FERS[all]" installs everything 0.1.x did. Catalogue sections (IPE200, HEB300, UB 457x191x67, W14X30, ...) need no extra.
  • Licence: the SDK is BSD-3-Clause; the engine it installs is free for non-commercial use (Licence).

Solving a model

Building a model by hand, create the FERS object first, then its nodes, members and loads. Creating a FERS restarts the id counters, so a node made before it would share an id with one made after it, and the solver refuses node ids that do not run from 1 without gaps.

Reading results

run_analysis() puts the results on model.resultsbundle. Load cases and load combinations are keyed by name. Within each, nodes and members are keyed by their id as a string, because results round-trip through JSON.

case = model.resultsbundle.loadcases["Load"]    # or .loadcombinations["ULS 1"]

case.displacement_nodes["5"].dy # dx dy dz rx ry rz warp case.reaction_nodes["1"].nodal_forces.fy # fx fy fz mx my mz bw beam = case.member_results["4"] beam.local_maximums.mz, beam.local_minimums.mz # envelope along the member beam.local_start_forces.fy # end forces, member axes

start_node_forces, end_node_forces, maximums and minimums are in the global frame; the local_* forces, section_forces and internal_force_series are in the member's own axes, with mz the strong-axis moment. Read a frame's moments from the local ones: outside the XY plane the global mz is not the bending moment, and in a frame in the YZ plane it reads 0.

Since 0.1.98, member_results and displacement_nodes are read-only tables rather than dicts of objects. That is what keeps a large result small in memory. They read like dicts: [], get, in, len, .items(), and iteration in the solver's order. Each lookup builds a fresh object, and nothing in it can be changed:

beam.local_maximums.mz = 0.0                     # AttributeError: read-only

editable = case.member_results.copy() # a plain dict of editable objects editable["4"].local_maximums.mz = 0.0 # fine

section_forces, internal_force_series and member_displacements come back as tuples. To test for a table, use isinstance(x, collections.abc.Mapping), not dict. reaction_nodes and plate_results are plain dicts, as before.

Saving and loading
from fers_core import FERS

model.save_to_json("beam.json") # the model and its results model = FERS.from_json("beam.json")

FERS.from_json reads any file the solver or the SDK wrote, one entry at a time. A typical result needs less memory than its file to load, and at most about twice the file's size; before 0.1.98 it needed 15 to 20 times. For a large model, let the solver write the file itself. The result then never passes through Python as one string:

model.run_analysis_to_file("beam_results.json")

solved = FERS.from_json("beam_results.json")

fers_core/examples/809_Reading_Results.py runs all of this end to end.

Saving a loaded model writes back everything the solver reads, with the same ids. That includes what the file defines but nothing uses yet, such as a section an editor keeps in its library. Nodes, members and the rest created after loading get ids the loaded model does not use, so saving never lets a new object replace a loaded one.

Only the results you read (engine 0.2.68)

AnalysisOptions(result_filter=[...]) keeps or drops whole result blocks. result_requests goes further. Each ResultRequest names a block and narrows it to chosen members or nodes, load combinations, components and one member end:

from fers_core import ResultBlock, ResultRequest

from fers_core.builders import check_beam from fers_core.result_requests import nodes_of from fers_core.unity_checks import classification

model = check_beam(5.0, "IPE300", udl=10000.0) # one "Beam", one ULS combination beams = classification("Beam") model.settings.analysis_options.result_requests = [ ResultRequest(ResultBlock.LOCAL_ENVELOPES, members=[beams], limit_state="ULS", components=["fx", "my", "mz"]), ResultRequest(ResultBlock.NODE_DISPLACEMENTS, nodes=nodes_of(beams), limit_state="ULS", components=["dy"]), ResultRequest(ResultBlock.REACTIONS, limit_state="ULS"), ] model.run_analysis()

The values load into the same member_results, displacement_nodes and reaction_nodes, so code that reads them keeps working. Anything that was not requested reads as `None`, not zero. A check that reads a value nobody asked for therefore fails instead of passing on a zero.

  • members takes the unity checks' selectors: classification(...), members([...]), member_sets([...]) and all_members(). Several selectors form a union.
  • nodes takes nodes([...]), or nodes_of(*selectors) for the end nodes of the selected members.
  • Load combinations are matched on their limit_state, as unity checks match them, or by load_combination_ids. To select by limit state, set limit_state on each LoadCombination; the solver does not read situation.
  • A request with neither limit_state nor load_combination_ids also covers the load cases.
  • end="start" or end="end" keeps one end of the end-force and end-displacement blocks.
  • The solver refuses a request it cannot meet, before it starts. That includes section_forces, internal_force_series, a component the block does not have, a limit state no combination carries, and result_filter set as well.

The values themselves are on model.resultsbundle.selections, one entry per request and group of result sets. Each entry's values is a read-only numpy array shaped (result_sets, ids, fields, components), with each axis listed beside it:

sel = model.resultsbundle.selections[0]

sel["group"] # "loadcombinations" or "loadcases" sel["result_sets"], sel["ids"] # combination names, member or node ids sel["fields"], sel["components"] # e.g. ["local_maximums", "local_minimums"], ["fx", "my", "mz"] my = sel"values".index("my")] # every set, member and field

save_to_json writes the selections back as the solver wrote them, so a saved result reloads unchanged. fers_core/examples/810_Result_Requests.py runs this end to end.

Scissor hinges: a continuous beam that turns on what it crosses (engine 0.2.68)

A rail running over beams and resting on each one is continuous along its length, but free to turn on every beam. A MemberHinge releases one member end, so releasing both rail ends at a beam splits the rail into two spans. Put the rail's members in a member set of their own and give the set a ScissorHinge instead. No link member or extra node is needed:

from fers_core import FERS, DistributedLoad, Material, Member, MemberSet, NodalSupport, Node, ScissorHinge, Section

from fers_core.supports.supportcondition import SupportCondition as C

model = FERS() steel = Material(name="S355", e_mod=210e9, g_mod=81e9, density=7850.0, yield_stress=355e6) rail_section = Section(name="rail", material=steel, i_y=1e-6, i_z=1e-6, j=1e-7, area=1e-3) beam_section = Section(name="beam", material=steel, i_y=1e-4, i_z=1e-4, j=1e-4, area=5e-3)

turns = {"X": C.fixed(), "Y": C.free(), "Z": C.free()} a, m, b = Node(0.0, 0.0, 0.0), Node(1.0, 0.0, 0.0), Node(2.0, 0.0, 0.0) a.nodal_support = NodalSupport(rotation_conditions=turns) b.nodal_support = NodalSupport( displacement_conditions={"X": C.free(), "Y": C.fixed(), "Z": C.fixed()}, rotation_conditions=turns ) beam_start, beam_end = Node(1.0, 0.0, -0.5), Node(1.0, 0.0, 0.5) beam_start.nodal_support = beam_end.nodal_support = NodalSupport() # clamped

rail_1 = Member(start_node=a, end_node=m, section=rail_section) rail_2 = Member(start_node=m, end_node=b, section=rail_section) model.add_member_set(MemberSet( members=[rail_1, rail_2], scissor_hinge=ScissorHinge(rotational_release_y=0.0, rotational_release_z=0.0), )) model.add_member_set(MemberSet(members=[ Member(start_node=beam_start, end_node=m, section=beam_section), Member(start_node=m, end_node=beam_end, section=beam_section), ]))

span = model.create_load_case(name="span") DistributedLoad(member=rail_1, load_case=span, magnitude=1000.0, end_magnitude=1000.0, direction=(0, -1, 0)) model.run_analysis() mz = model.resultsbundle.loadcases["span"].member_results[str(rail_1.id)].local_end_forces.mz print(f"{abs(mz):.1f} Nm") # 62.4; a knife edge gives qL²/16 = 62.5, a rigid joint 122.6

  • Where it applies: at every node where a member of the set meets a member outside the set, or a plate. There the set's members stay joined to each other and move relative to the node along and about the released axes. Nothing is released where the set meets only itself or a support. So the continuous beam's members belong in a set of their own; a set holding every member meets nothing, and the solver refuses it.
  • Only some of those nodes: MemberSet(scissor_hinge_nodes=[...]) lists where the hinge applies, for a beam that turns on some of the members it meets and is joined to the rest.
  • Each value works as a MemberHinge release doe

Nur der Anfang wird gezeigt; den Rest findest du im Repo

PopNx fragen