femm
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| FEMM_DIR | No | FEMM 5 bin folder (holding `femm_headless`). Default: auto-detected from `C:\femm-qt\bin`, `/Applications/femm_gui.app/Contents/MacOS`, `~/.local/opt/femm-qt/bin`, `/opt/femm-qt/bin`, or `femm_headless` on PATH. | |
| FEMM_AGENT_WORK | No | Root of the per-session work dirs (models, arrays, plots, reports). | ~/femm-agent-work |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| femm_statusA | Where FEMM 5 is installed, its version, open sessions, work dir, catalog/material counts. Call this first. If |
| femm_session_openA | Start (or reuse) a named FEMM engine. Every other tool takes headless=True spawns femm_headlessw (no window, fastest). headless=False opens the
femm_gui window: needed for femm_save_bitmap (screenshots are not written headless).
attach=True connects to an engine already listening on |
| femm_session_closeA | Quit the FEMM engine of session |
| femm_session_listB | All open sessions: port, pid, physics, document, solved flag, call/error counts. |
| femm_selftestA | End-to-end check of the install with a known answer (~1-2 s). In a separate session "selftest" it builds an axisymmetric thick solenoid (a=10 mm, b=12 mm, L=100 mm, 500 turns, 1 A), solves, and compares |B| at the centre with the analytic formula B0 = mu0Jl*ln[(b+sqrt(b^2+l^2))/(a+sqrt(a^2+l^2))] (expect < 1 % error). Also checks library material loading, the error path for a FEMM 4.2 name, current-density units, bulk getters, circuit results and timing. Returns pass/fail per check. |
| femm_new_documentA | Create a new empty model: physics = magnetics | electrostatics | heatflow | currentflow. This defines the mi_/ei_/hi_/ci_ commands. Next: femm_problem_define (units, planar/axi, depth, frequency), then geometry, materials, labels, boundaries, femm_solve. |
| femm_openB | Open a FEMM model (.fem/.fee/.feh/.fec) or a solution (.ans/.res/.anh/.anc). Relative paths resolve against the session work dir; use forward slashes. Opening a solution makes the post-processor tools (femm_point_values, ...) available directly. |
| femm_saveA | Save the current model (xi_saveas). |
| femm_close_documentA | Close the current pre-processor document and its post-processor (if any). The engine keeps running; call femm_new_document or femm_open next. |
| femm_problem_defineA | Define the problem for the current physics (wraps xi_probdef with the right argument order). units: millimeters|centimeters|meters|inches|mils|micrometers (aliases mm, cm, m, in, um).
problem_type: planar | axi (axisymmetric: x is r >= 0, y is z, depth ignored).
depth: out-of-plane length for planar models, in |
| femm_problem_infoB | Problem definition as FEMM reports it (xi_getprobleminfo, and xo_getprobleminfo after a solve: note the post-processor reports depth in metres), the geometry bounding box, and node/element counts when solved. |
| femm_set_commentC | Store a free-text comment/description in the model file (xi_setcomment). Single line. |
| femm_add_nodesA | Add nodes at [[x, y], ...] (problem units; axi: x is r >= 0). Existing nodes at the same place are reused by FEMM. Usually you want femm_draw_polygon / femm_add_segments instead. |
| femm_add_segmentsB | Add straight segments [[[x1,y1],[x2,y2]], ...] (or [x1,y1,x2,y2] each). End nodes are created as needed. Segments that cross are split by FEMM at the intersection. |
| femm_add_arcsA | Add arcs [[x1, y1, x2, y2, angle_deg, maxseg_deg], ...]: from (x1,y1) counter-clockwise to
(x2,y2) sweeping |
| femm_draw_rectangleA | Axis-aligned rectangle with opposite corners (x1,y1), (x2,y2): 4 nodes + 4 segments. Add a block label inside it afterwards (femm_add_block_label). |
| femm_draw_circleA | Full circle of radius r around (cx, cy) as four 90-degree arcs (nodes at 0/90/180/270 deg). maxseg = arc discretisation in degrees. For a half circle in axi models, use femm_add_arcs. |
| femm_draw_polygonB | Polygon through [[x, y], ...]: nodes + segments, closed back to the first point by default. Returns the vertex centroid (a block-label candidate only if the polygon is convex). |
| femm_draw_polylineB | Open chain of segments through [[x, y], ...] (not closed). Same as femm_draw_polygon(closed=False). |
| femm_selectA | Select objects for a following edit (femm_move_selected, femm_delete_selected,
femm_set_group ...). kind:
nodes | segments | arcs | labels -> nearest object to each of |
| femm_clear_selectedC | Deselect everything in the pre-processor. |
| femm_delete_selectedB | Delete the current selection. kind: all | nodes | segments | arcs | labels (deleting nodes also deletes segments/arcs attached to them). |
| femm_move_selectedA | Move the selection: translate by (dx, dy), or rotate by |
| femm_copy_selectedA | Copy the selection |
| femm_mirror_selectedA | Mirror-copy the selection about the line through (x1,y1)-(x2,y2) (the original stays). |
| femm_scale_selectedC | Scale the selection by |
| femm_set_groupB | Put the selected objects into group number |
| femm_import_dxfA | Import a DXF drawing into the current model (xi_readdxf). |
| femm_export_dxfC | Write the current geometry to a DXF file (xi_savedxf). |
| femm_geometry_summaryA | Counts of nodes, segments, arcs, block labels and the defined materials, boundaries, circuits/conductors, plus the bounding box. FEMM 5 has no pre-processor count getters, so this saves the model (to its current path, or <work_dir>/model.) and reads the counts from the saved file. Use it to sanity-check a model before meshing. |
| femm_add_block_labelA | Add a block label at (x, y) inside a closed region and assign its properties in one call. material: a name already loaded/defined (femm_material_load / femm_material_add), or "" for a hole. mesh_size: max element size in problem units, None = automatic. Magnetics only: circuit (name from femm_add_circuit, "" for none), magdir (magnetisation direction in degrees for magnets), turns (number of turns of this block in the circuit; negative = opposite direction). group: integer group for selection/integrals. Each closed region needs exactly one label; a label in the wrong region is a common bug (check with femm_geometry_summary). |
| femm_set_block_propB | Change the properties of the existing block label nearest (x, y) (same arguments as femm_add_block_label). Use to swap materials or currents between solves. |
| femm_add_boundaryA | Define a boundary condition for the current physics and (optionally) assign it. Magnetics bc_type (mi_addboundprop, 12 args): prescribed_a (A = a0 + a1x + a2y, phase phi; A=0 is the usual outer boundary), small_skin_depth (mu = relative permeability, sigma MS/m), mixed (c0, c1 complex OK), strategic_dual_image, periodic, antiperiodic, periodic_air_gap / antiperiodic_air_gap (sliding band: inner_angle/outer_angle = rotor/stator shift in degrees). Assign it to BOTH concentric arcs of the gap annulus and put a "" block label inside the annulus (verified: without it the solver stops with "a region has no material assigned"). Electrostatics: fixed_voltage (value = V), mixed (c0, c1), surface_charge (flux = C/m^2), periodic, antiperiodic. Currentflow: fixed_voltage (value), mixed, surface_current (flux), periodic, antiperiodic. Heatflow: fixed_temperature (value = K), heat_flux (flux W/m^2), convection (h W/m^2K, t_inf K), radiation (beta emissivity, t_inf_rad K), periodic, antiperiodic. segments / arcs: [[x, y], ...] points ON the segments/arcs (e.g. midpoints) to assign this boundary to (each picks the nearest). Periodic pairs need one boundary per pair, assigned to both sides. For an unbounded open boundary see femm_call('mi_makeABC'). |
| femm_set_segment_propB | Select the segments nearest each of |
| femm_set_arc_propB | Select the arcs nearest each of |
| femm_set_node_propB | Select the nodes nearest each of |
| femm_add_circuitA | Magnetics: define a circuit carrying |
| femm_modify_circuitB | Change a circuit: current (A, real; for complex use femm_call('mi_modifycircprop', ...)), series/parallel, or rename (mi_modifycircprop propnum 1 / 2 / 0). Re-solve afterwards. |
| femm_add_conductorA | Electrostatics / heat flow / current flow: define a conductor property. fixed: electrostatics 'voltage' (value V) or 'charge' (value C/m); heatflow 'temperature' (value K) or 'flux' (value W/m, total heat); currentflow 'voltage' (V) or 'current' (A; complex OK at AC). Assign it to segments/arcs/nodes with femm_set_segment_prop(conductor=name) etc. Results after solving: femm_circuit_results(name). |
| femm_add_point_propB | Define a nodal point property and optionally assign it to the nodes nearest |
| femm_material_searchA | Fuzzy search of the FEMM 5 material library (no engine needed). Matches names and folders: 'M-19', 'silicon iron', 'N42', 'NdFeB', 'AWG 18', 'stainless', 'pure iron'. FEMM 4.2 names ('M-19 Steel', 'NdFeB 32 MGOe') are mapped to their FEMM 5 equivalents and ranked first. physics: magnetics|electrostatics|heatflow|currentflow. Returns name, folder and key properties (mu_r, Hc, sigma, nonlinear?). Empty query + folder lists a folder; empty query alone returns the family index. |
| femm_material_getA | Full library record of one material (all keys of the .dat block: Mu_x, H_c, Sigma in MS/m, d_lam in mm, LamFill, LamType, WireD, ...). include_curve=True adds the B-H (or T-k) points. On a miss, returns suggestions (and the FEMM 4.2 -> 5 rename if known). |
| femm_material_loadA | Copy materials from the FEMM 5 library into the current model (xi_getmaterial), for the session's physics. Names must match FEMM 5 exactly ('M-19 14 mil', 'N42', 'Copper', 'Air', '18 AWG'). On a miss the result lists suggestions; with fallback_to_suggestion=True the best suggestion (e.g. FEMM 4.2 'M-19 Steel' -> 'M-19 14 mil') is loaded instead and reported in 'renamed' (use those names in femm_add_block_label). |
| femm_material_addA | Define a custom material for the session's physics (xi_addmaterial). Only the arguments of that physics are used; *_y defaults to *_x. magnetics: mu_x, mu_y (relative), h_c (A/m, magnets), j (source current density MA/m^2, complex OK), sigma (MS/m), lam_d (lamination thickness mm), phi_hmax (hysteresis angle deg), lam_fill (0..1), lam_type (0 none, 1 laminated x, 2 laminated y, 3 magnet wire, 4 stranded, 5 litz, 6 square wire), phi_hx, phi_hy, n_strands, wire_d (mm); bh_points [[B_T, H_A/m], ...] makes it nonlinear (mu ignored). electrostatics: eps_x, eps_y (relative), qv (C/m^3). heatflow: k_x, k_y (W/m/K), qv (W/m^3), kt (volumetric heat capacity MJ/m^3/K). currentflow: sigma_x, sigma_y (S/m), eps_x, eps_y, ltx, lty (loss tangents). |
| femm_material_add_bhA | Give material |
| femm_material_modifyA | Change properties of a material already in the model (xi_modifymaterial), e.g. {"mu_x": 2000, "sigma": 0} or {"name": "M19-hot"}. Keys per physics: magnetics name mu_x mu_y h_c j sigma lam_d phi_hmax lam_fill lam_type phi_hx phi_hy n_strands wire_d; electrostatics name eps_x eps_y qv; heatflow name k_x k_y qv kt; currentflow name sigma_x sigma_y eps_x eps_y ltx lty. Re-solve afterwards. |
| femm_create_meshA | Mesh the model without solving (xi_createmesh) to check that meshing succeeds. FEMM requires a saved file, so the model is saved first. FEMM 5 returns no element count from createmesh; the count is reported by femm_solve (fast: a 10k-element static solve takes well under a second). Meshing errors usually mean open regions or overlapping lines. |
| femm_solveA | Save, solve and load the solution in one call (xi_saveas + xi_analyze + xi_loadsolution). path: where to save (default: current file or <work_dir>/model.). timeout in seconds for the solver (AC/nonlinear models with >100k elements can take minutes). Returns solve time, node and element counts and the solution file. After this the post-processing tools (femm_point_values, femm_block_integral, femm_circuit_results, ...) work. Re-run after every geometry/material/current change: the loaded solution does not update itself. |
| femm_load_solutionB | Load the existing solution of the current (already solved) model into the post-processor (xi_loadsolution) without re-solving. Fails if the model was never solved. |
| femm_smartmeshA | Smart meshing (automatic refinement near small features). state: on | off | default. scope: document (xi_smartmesh, saved with the model) or global (smartmesh(), whole engine; 'default' defers to each file). Turn off for very large models to cut element count, then set mesh sizes explicitly on block labels. |
| femm_point_valuesA | Field values at [[x, y], ...] (problem units), labelled for the physics, plus the magnitude (|B|, |E|, |F| or |J|). Components are x/y for planar and r/z for axisymmetric models. Magnetics keys: A, Bx/By (T), sigma (MS/m), energy_density (J/m^3), Hx/Hy (A/m), J_eddy, J_source (MA/m^2, verified), mux/muy (relative), P_ohmic, P_hyst (W/m^3), fill_factor. Complex (AC) values come back as {"re", "im"} (peak). A point outside the model gives outside=true. Up to a few hundred points per call is fine (~1 ms each). |
| femm_block_integralA | Integrate over blocks: select the blocks containing |
| femm_line_integralB | Line integrals along a contour of straight pieces through [[x, y], ...] (use many points to follow a curve). Magnetics codes: 0 B.n (flux; total, average), 1 H.t (MMF), 2 length (and surface area), 3 stress tensor force, 4 stress tensor torque, 5 (B.n)^2. Electrostatics: 0 E.t, 1 D.n (charge), 2 length, 3 force, 4 torque. Heat: 0 G.t (dT), 1 F.n (heat flow), 2 length, 3 average T. Current: 0 E.t, 1 J.n (current), 2 length, ... Defaults: the first three/four. |
| femm_circuit_resultsA | Magnetics: current (A), voltage drop (V) and flux linkage (Wb) of circuit |
| femm_select_blockB | Post-processor block selection for femm_call('mo_blockintegral', [code]) workflows.
action=select clears, then selects the blocks containing |
| femm_mesh_arraysA | Dump the solution mesh and fields to a file in the session work dir and return the path, shape and min/max/mean per column (never the raw arrays). which: all, or a comma list of nodes, elements, and per physics: magnetics b (B1,B2 per element), a (A per element); electrostatics v (per node), d; heatflow t (per node), f; currentflow v (per node), j. Element rows are n1,n2,n3 (node indices), cx, cy, area, group. fmt: npz (numpy) or csv. Load with numpy.load(path). |
| femm_field_statsA | Area-weighted statistics of the main field over the mesh, from the bulk arrays (fast, no file). Magnetics: |B| min/max/mean/rms/p95, saturated area fraction (|B| >= threshold, default 1.6 T) and number of elements above 2 T. Other physics: |D|, |F| or |J| per element and V/T at nodes. region: 'all' or 'group:N[,M]' (give the blocks of one material a group number with femm_add_block_label(group=N) to get per-material stats). |
| femm_gap_resultsA | Air-gap (sliding band) results for a periodic/antiperiodic air-gap boundary |
| femm_save_bitmapA | Screenshot of the current view to an image file (xo_savebitmap / xi_savebitmap), .png or .bmp. VERIFIED: works only in a session opened with femm_session_open(headless=False) (a GUI window); the headless engine accepts the command but writes nothing. view: post (solution plot) or pre (geometry). density: show a density plot of plot_type (magnetics 'bmag','breal','bimag','hmag','jmag',...; electrostatics 0 V,1 |D|,2 |E|; heatflow 0 T,1 |F|,2 |G|; currentflow 0..8, 3 = |J|). Leave plot_type, lower and upper unset for FEMM's default auto-scaled plot (|B|, V, T or |J|); an explicit plot_type needs lower/upper limits. view='pre' after a solve switches focus back to the geometry window. contours: number of flux/equipotential lines. zoom: [x1, y1, x2, y2] or None = natural. For data plots that work headless use femm_make_plot or femm_mesh_arrays. |
| femm_make_plotA | Sample a quantity along a contour (straight pieces through [[x, y], ...]) to a text file (xo_makeplot with a filename; works headless). Magnetics plot_type: 0 A, 1 |B|, 2 B.n, 3 B.t, 4 |H|, 5 H.n, 6 H.t, 7 J eddy, 8 J source+eddy. Electrostatics: 0 V, 1 |D|, 2 D.n, 3 D.t, 4 |E|, 5 E.n, 6 E.t. Heat: 0 T, 1 |F|, 2 F.n, 3 F.t, 4 |G|, 5 G.n, 6 G.t. Current: 0 V, 1 |J|, 2 J.n, 3 J.t, 4 |E|, ... Returns the file path, column header and min/max/mean of the sampled values (position is distance along the contour). |
| femm_callA | Call any FEMM 5 scripting command by name with positional |
| femm_evalA | Evaluate ONE LINE of MicroPython inside FEMM and return its value (tab-separated reply parsed to numbers/lists). Statements return null; expressions return their value. A newline is rejected: for multi-line code use femm_run_script. Examples: 'mo_getpointvalues(0,0)[1]', 'mi_getboundingbox()', '[mo_getgapb("AGE",a)[0] for a in range(0,90,10)]'. Variables persist between calls in the same session. |
| femm_run_scriptA | Run a multi-line MicroPython script with FEMM's commands as globals (mi_addnode(...) etc.,
no |
| femm_run_luaA | Run a legacy FEMM 4.2 Lua script unchanged with FEMM 5's bundled Lua 4 interpreter
(bin/femm-lua.bat on Windows: |
| femm_journalA | The raw command lines this session sent to FEMM (most recent |
| femm_export_pyfemm_scriptB | Write the session journal as a standalone pyFEMM script (import femm; femm.openfemm(1); femm.mi_...(); femm.closefemm()) so the user can re-run the whole model without the agent. Default path: <work_dir>/scripts/_pyfemm.py. femm_eval expressions that are not plain calls are kept as comments. |
| femm_api_searchA | Search the catalog of every FEMM 5 scripting command (name, signature, description). physics: magnetics|electrostatics|heatflow|currentflow (common commands always included); phase: pre (mi_/ei_/hi_/ci_) or post (mo_/eo_/ho_/co_). Examples: 'block integral', 'air gap', 'boundary', 'bitmap', 'mi_addmaterial'. Then femm_api_get(name) for full args. |
| femm_api_getB | Full catalog entry of one command: args (name, type, optional, description), return value, integer code tables (enums), read_only flag, notes (e.g. pyFEMM-only helpers the engine does not define), and where it is documented in the manual. |
| femm_manual_sectionB | Read the installed FEMM 5 manual (manual.pdf, extracted to text once and cached). query: a section number ('3.7.1'), a heading ('Data Extraction Commands', 'Boundary Conditions', 'Air Gap'), or a keyword ('mo_gapintegral', 'Kelvin'): headings return the section text, keywords return snippets with their section names. |
| femm_examples_listA | Example models and scripts shipped with FEMM 5 (examples/ and pyfemm/examples/): name,
path, size, and for models the header (problem type, units, frequency, depth). Filter by
substring |
| femm_factsB | Verified FEMM 5 behaviour collected by this project (docs/femm5-facts.md): command
quirks, units, what works headless, renamed materials. |
| femm_experiment_force_vs_positionA | Force vs position: move the parts in Use for actuators, plungers, coilguns (axisymmetric: dy moves along z). The moving parts must be surrounded by air and carry their own group number (femm_set_group). Geometry is moved back at the end and the model is left solved at the start position. Example: femm_experiment_force_vs_position(groups=[1], dy=0.25, steps=9). Returns rows [position, Fx, Fy, F_along_motion, F_virtual_work, coenergy, psi_*] and csv/json/png paths. |
| femm_experiment_torque_vs_angleA | Rotor torque vs mechanical angle (degrees, end point included). method='rotate': rotates |
| femm_experiment_coggingA | Cogging torque: all circuit currents set to 0, torque over |
| femm_experiment_backemfB | Open-circuit back-EMF: flux linkage of each circuit (default all) over one electrical period
(360/pole_pairs mech deg, |
| femm_experiment_inductanceB | Inductance from flux linkage. Default: self/mutual matrix L_jk = (psi_j(I_k=current) - psi_j(0)) / current
for |
| femm_experiment_ac_sweepA | Time-harmonic frequency sweep (Hz): per frequency, circuit phasors (peak amplitudes) ->
Z = V/I, R(f), L(f) = Im Z / omega, and losses (total / resistive / hysteresis) over all blocks.
Check: 1/2 Re(V conj I) equals total losses. Other probdef settings are kept and the original
frequency restored. |
| femm_experiment_parametricA | Generic parametric study. Every case re-opens the same saved base model, applies its setup, solves and collects outputs. case: {"name": "Hc=900k", "params": {"hc": 9e5}, "commands": [{"command": "mi_modifymaterial", "args": ["N42", 3, 9e5]}]} (preprocessor commands only: mi_/ei_/hi_/ci_). template: optional multi-line MicroPython run inside FEMM per case, formatted with params, e.g. "mi_selectgroup(1)\nmi_movetranslate({dx}, 0)". outputs: {"name", "kind": "point", "x", "y", "quantity": "B|Bx|By|A|H|mu|J"} | {"kind": "block", "code": 22, "groups": [1]} | {"kind": "circuit", "circuit": "A", "quantity": "flux|current|voltage|L|R"} | {"kind": "gap", "boundary": "AGE", "code": 0} | {"kind": "line", "points": [[x,y],...], "code": 3} | {"kind": "expr", "expression": "..."}. |
| femm_experiment_bh_checkA | Permanent-magnet operating points: solves, then per magnet block label the mean and minimum flux density along its magnetisation direction (B_m), H_m, permeance coefficient Pc and B_m/Br. Flags demagnetisation risk when min B_m < min_fraction * Br. Labels with a magdir formula are skipped. |
| femm_build_benchmarkA | Build a validated benchmark model from scratch (new magnetics document, saved to |
| femm_estimateA | Analytic sanity references in SI units (m, A, T, H, N, N*m). Call with no name to list the formulas and their arguments. Examples: femm_estimate("ccore_gap_b", {"turns": 200, "current": 2, "gap": 0.002, "iron_path": 0.18, "mu_r": 2000}); femm_estimate("dq_torque", {"pole_pairs": 2, "psi_d": 0.05, "psi_q": 0, "i_d": 0, "i_q": 10}); femm_estimate("skin_depth", {"freq": 1000, "sigma": 58e6}). Others: solenoid / loop / thick- solenoid fields, inductances, Maxwell force B^2 A/2mu0, Carter coefficient, PM load line, SPM gap flux and flux linkage, cogging period, capacitances, resistance, round-wire AC impedance. Compare FEMM results to these within the idealisation error (fringing, leakage, saturation). |
| femm_units_convertA | Unit conversions used with FEMM. conversion='length' needs from_unit/to_unit among inches, millimeters, centimeters, mils, meters, micrometers (aliases mm, in, um ...). Others (value in, result out): deg2rad, rad2deg, rpm_to_rad_s, awg_diameter_mm (AWG gauge -> mm, pyFEMM AWG()), iec_diameter_mm, tesla_to_gauss, gauss_to_tesla, oersted_to_a_per_m, a_per_m_to_oersted, hc_from_br (T -> A/m, needs mu_r, default 1.05), br_from_hc, br_from_mgoe / hc_from_mgoe (grade -> Br or Hc for mi_addmaterial), mgoe_from_br, mgoe_to_j_per_m3. |
| femm_check_ruleA | Run one pure physics rule on numbers you already have (no FEMM call). Call with rule='list' to see them. Examples: femm_check_rule("energy_consistency", {"energy": 0.0149, "flux_linkages": [0.0149], "currents": [2]}); femm_check_rule("power_balance", {"p_input": 1.2, "p_losses": 1.19}); femm_check_rule("force_consistency", {"f_a": -9.7, "f_b": -9.2, "tolerance": 0.1}). Returns {name, ok, value, expected, tolerance, message}. |
| femm_health_checkA | Judge whether the loaded magnetics solution is physically sane. Needs femm_solve first.
Runs (subset via |
| femm_reportB | Write report.md + report.json (+ figures/) to <work_dir>/reports//.
include (default all): "model" (parsed model summary), "health" (femm_health_check on the
loaded solution), "field" (|B| map PNG from the bulk mesh arrays, |
| femm_compare_resultsA | A/B comparison of two experiment results (paths to the experiment .json files, or JSON
text): every numeric summary value and every common numeric column (rows matched on the first
column, e.g. angle). Use it to compare mesh refinements, the rotate vs air-gap-element
methods, or two designs. Differences beyond |
| femm_file_summaryA | Parse a FEMM text file offline (no engine): .fem/.fee/.feh/.fec models or .ans/.res/.anh/.anc solutions. Returns problem definition, materials (with use counts, nonlinear/magnet flags), boundaries (type names, segment counts), circuits (net turns), groups, counts, bounding box, magnets. arrays=True on a solution also writes _mesh.npz (nodes, elements) next to it. |
| femm_plot_fieldA | |B| colour map of the loaded magnetics solution rendered from the bulk mesh arrays (works
headless, no GUI screenshot). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 88 tools
Despite 88 tools, most have clearly distinct purposes and detailed descriptions that clarify scope. However, several overlapping families exist—plotting (make_plot, plot_field, save_bitmap), field extraction (point_values, block_integral, line_integral, mesh_arrays, field_stats), and reference (api_get, api_search, manual_section, facts)—where an agent could misselect without careful reading.
All tools use the femm_ prefix and snake_case with consistent verb_noun patterns (e.g., femm_add_nodes, femm_solve, femm_experiment_torque_vs_angle). A few noun-only names like femm_status are still predictable and readable.
88 tools is far beyond the recommended 3–15 and exceeds even the 25+ 'too many' threshold, representing an extreme mismatch for a single MCP server. Many tools could be consolidated or exposed through a more compact workflow layer.
The surface covers the full FEMM lifecycle: document creation, geometry, materials, boundaries, meshing, solving, extensive post-processing, parametric experiments, reporting, and a generic femm_call/femm_eval escape hatch for any missing command. No obvious dead ends for the domain.