FEA (finite element analysis)
RemoteAbout FEA (finite element analysis)
An MCP server for running finite element studies on single-solid STEP parts, using CalculiX for static stress and modal analysis. It targets engineering workflows that need validated setups, numerical results, and visual reports.
Key features
- 01Inspect STEP geometry
- 02Built-in material library
- 03Static stress and safety analysis
- 04Natural frequencies and mode shapes
- 05Setup validation before solving
- 06Stress plots and 3D viewer
Use cases
- 01Assess a part under specified loads
- 02Check natural frequencies of a constrained part
- 03Inspect stress and safety results visually
MCP support
Exposes synchronous geometry, material, and report tools plus asynchronous FEA study tasks to MCP clients. It also implements the MCP tasks extension and an MCP Apps 3D viewer.
Configuration
Remote servers need no local install. Pick your client, then copy the config or install in one click.
https://therobomaster123--mcp-fea-mcp-endpoint.modal.run/mcpclaude mcp add --transport http therobomaster123-mcp-fea https://therobomaster123--mcp-fea-mcp-endpoint.modal.run/mcp{"mcpServers":{"therobomaster123-mcp-fea":{"type":"http","url":"https://therobomaster123--mcp-fea-mcp-endpoint.modal.run/mcp"}}}Open in Cursor{"servers":{"therobomaster123-mcp-fea":{"type":"http","url":"https://therobomaster123--mcp-fea-mcp-endpoint.modal.run/mcp"}}}Open in VS Code{"mcpServers":{"therobomaster123-mcp-fea":{"type":"http","url":"https://therobomaster123--mcp-fea-mcp-endpoint.modal.run/mcp"}}}{"mcpServers":{"therobomaster123-mcp-fea":{"serverUrl":"https://therobomaster123--mcp-fea-mcp-endpoint.modal.run/mcp"}}}Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.
https://therobomaster123--mcp-fea-mcp-endpoint.modal.run/mcpAuth requiredTools
Details
From the project READMEmcp-fea
Real finite element analysis from a conversation. An AI assistant sends a STEP file and a plain-English question ("does this arm survive a 6 g maneuver with a 400 g motor?"); this MCP server maps the words onto geometry, rejects bad setups deterministically before any compute is spent, meshes and solves with CalculiX on Modal as an async MCP task, and returns a verdict backed by numbers — peak von Mises stress, factor of safety, deflection, natural frequencies — plus rendered stress plots and an interactive 3D viewer. Every study ends with a non-skippable reaction-balance check; every benchmark on the validation page is regenerated by CI on every commit.

Measured on the live deployment (2026-07-31): cold start 3.8 s · cantilever study submit→completed 9.3 s warm / 12.9 s with a cold solver container · ~$0.002 per study at Modal's posted rates.
| Benchmark | Reference | Computed | Error |
|---|---|---|---|
| Cantilever tip deflection (PL³/3EI) | 0.58055 mm | 0.58046 mm | 0.02% |
| NAFEMS LE10 σ_yy @ D | −5.38 MPa | −5.456 MPa | 1.41% |
| Plate-with-hole peak (Heywood Kt) | 62.8 MPa | 61.92 MPa | 1.40% |
| Cantilever f₁ (Euler–Bernoulli) | 816.0 Hz | 815.4 Hz | 0.08% |
Full table, mesh stats, and an explicit limitations section: docs/validation.md — regenerated by CI, never hand-edited.
Protocol: MCP 2026-07-28 (stateless core) with the
io.modelcontextprotocol/tasks extension implemented per SEP-2663 (the
official Python SDK v2 shipped without it — this repo also contains the
client-side extension that teaches the official
SDK to consume task-augmented servers) and an MCP Apps (SEP-1865) 3D
viewer. See docs/decisions.md for every engineering
call and why.
Deploy (3 commands)
uv sync
uv run modal secret create mcp-fea-token MCP_FEA_TOKEN=$(openssl rand -hex 24)
uv run modal deploy -m src.server.modal_app
Modal prints the endpoint URL (https://<workspace>--mcp-fea-mcp-endpoint.modal.run).
Connect any 2026-07-28 MCP client with Authorization: Bearer <your token>.
First-time Modal users: uv run modal token new once. Then verify the live
deployment end to end:
MCP_FEA_LIVE_URL=https://... MCP_FEA_TOKEN=... make verify-live
Tools
| Tool | Sync/async | What it does |
|---|---|---|
inspect_geometry | sync | STEP → face table (face_id, type, centroid, normal/axis, area, bbox) + part bbox/volume. Call first: it's how English maps to face ids. |
list_materials | sync | Built-in library: Al 6061-T6, Al 7075-T6, Steel 4140, Stainless 304, Ti-6Al-4V, ABS, PLA, Nylon 12, PC (E, ν, yield, density). |
submit_fea_study | task | Linear static: validate → mesh (C3D10, curvature-adaptive, local thin-wall refine) → CalculiX → verdict/stress/FoS + 3 stress PNGs. |
submit_modal_study | task | Natural frequencies + mode shapes (*FREQUENCY), first N modes (default 6), one exaggerated-deformation PNG per mode. Requires constraints and density. |
get_report | sync | Full payload for a completed task; include_mesh_data: true adds the surface-mesh payload the 3D viewer app fetches. |
Task lifecycle: working (statusMessage walks validating → meshing → solving → postprocessing) → completed | failed | cancelled;
tasks/cancel kills the running container. Tasks are retained 24 h.
Units policy
One conversion boundary, at ingest. Internally everything is consistent
mm–N–MPa(–tonne): lengths mm, forces N, stress/moduli MPa, density tonne/mm³
(kg/m³ × 1e-12 — done once, in Material.density_tonne_mm3), which makes
modal frequencies come out directly in Hz. STEP coordinates are interpreted
in the declared units (mm|m|in); gmsh's own unit conversion is disabled
so the declared unit is authoritative — and sanity-checked (a 100 mm part
declared "m" gets flagged).
Validation codes
Every rejection returns {code, message, suggested_fix}.
| Code | Meaning | Stage |
|---|---|---|
GEOMETRY_REF_INVALID | STEP missing/unreadable/over 25 MB, bad units field | parse |
GEOMETRY_KERNEL_CRASH / GEOMETRY_TIMEOUT | CAD kernel crashed / hung on the file (isolated subprocess; endpoint unaffected) | inspect |
MATERIAL_UNKNOWN / MATERIAL_UNPHYSICAL | Not in library / E ∉ [0.01, 1500] GPa, ν ∉ (0, 0.5), yield ≤ 0, density ∉ [10, 25000] kg/m³, missing density for modal | parse |
CONSTRAINT_INVALID / CONSTRAINT_CONFLICT | Bad type; node pinned in two local frames | parse/deck |
LOAD_INVALID / LOAD_MISSING / MODAL_INVALID | Bad type/units/direction; zero loads; bad n_modes | parse |
GEOM_NO_SOLID / GEOM_MULTIPLE_SOLIDS | Not a single solid body (assemblies = v2) | pre-mesh |
FACE_ID_INVALID | Face id not on this part | pre-mesh |
RIGID_BODY_MOTION | Constraints leave free motion (named, e.g. "rotation about the hole axis") — SVD rank check | pre-mesh |
LOAD_ON_FIXED_FACE | Load applied to a fully fixed face | pre-mesh |
UNITS_SUSPECT (warning) | Part > 5 m or < 0.5 mm — declared units probably wrong | pre-mesh |
LOAD_MAGNITUDE_EXTREME / _NEGLIGIBLE (warnings) | σ ≈ F/A > 10× yield or < 1e-6× yield | pre-mesh |
MESH_ELEMENT_CAP | > 400k elements even after coarsening / local refine | mesh |
MESH_QUALITY_JACOBIAN / MESH_QUALITY_ASPECT / MESH_THIN_WALLS | Quality gates; thin walls get one local auto-refine first | mesh |
MESH_TIMEOUT | Meshing exceeded its wall budget (near-tangent slivers, helical threads) — the worker is killed from outside | mesh |
SOLVER_SINGULAR / SOLVER_MESH_DEGENERATE / SOLVER_TIMEOUT / SOLVER_FAILED | Mapped ccx failures (>150k elements auto-switch to the iterative solver) | solve |
EQUILIBRIUM_FAIL (warning, untrusted result) | ΣRF vs free-node applied loads off by > 0.5% | post |
LOAD_INTO_SUPPORT (warning) | > 5% of the load lands on constrained nodes (loaded face touches a fixed face) and is carried directly by the support | post |
BEYOND_YIELD / LARGE_DEFLECTION (warnings) | FoS < 1 (post-yield numbers flagged non-physical) / u > 5% of min dimension | post |
Abuse limits (all env-tunable)
25 MB STEP cap · 40 MB request cap (413) · per-token rate limit
(MCP_FEA_RATE_LIMIT/_WINDOW_S, 429) · concurrent-solve cap
(MCP_FEA_MAX_CONCURRENT) · daily budget (MCP_FEA_MAX_SPAWNS_PER_DAY) ·
kill switch (MCP_FEA_DISABLE_SPAWN=1). CAD parsing never runs in the
endpoint process (see SECURITY.md).
Local development
uv sync
curl -Ls https://micro.mamba.pm/api/micromamba/osx-arm64/latest | tar -xj bin/micromamba
./bin/micromamba create -y -p .tools/ccx-env -c conda-forge calculix=2.23
make test # fast suite (protocol, benchmarks, validation, hardening)
make torture # 21 real-world STEP files through the endpoint
make validation-page
uv run uvicorn --factory src.server.app:create_local_app --port 8000 # local server
Repo map
src/pipeline/ geometry, meshing, deck, solver, validation, post, render ·
src/materials/ library · src/server/ protocol, tools, tasks, limits,
worker host, Modal app, Apps UI · src/client/ SDK tasks extension ·
tests/ (incl. torture/) · demo/ · docs/ decisions, validation, upstream notes. License: Apache-2.0.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.