Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
FEMM_DIRNoFEMM 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_WORKNoRoot 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

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
femm_statusA

Where FEMM 5 is installed, its version, open sessions, work dir, catalog/material counts.

Call this first. If install.found is false, nothing else can run: install FEMM 5 (https://www.femm.info) or set FEMM_DIR to the folder holding femm_headless. check_version runs femm_headless --version once (cached, ~0.3 s).

femm_session_openA

Start (or reuse) a named FEMM engine. Every other tool takes session (default "main") and opens it lazily, so call this only to choose options.

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 port (e.g. a GUI the user started) instead of spawning one. work_dir is the engine's current directory; relative paths in other tools resolve there (default ~/femm-agent-work/, env FEMM_AGENT_WORK).

femm_session_closeA

Quit the FEMM engine of session name (unsaved work is lost: call femm_save first).

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). path absolute or relative to the work dir; the extension is added if missing. Without path: re-save the current file, or <work_dir>/model. for a new model. femm_solve saves automatically.

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 units (defaults to 1 unit with a warning: set it! e.g. stack length). frequency (Hz): magnetics (0 = magnetostatic) and currentflow only. precision: solver tolerance (1e-8 typical). min_angle: mesh quality, 30 deg default. ac_solver: magnetics only, 0 or 1 (successive approximation / Newton; see manual 2.2.6). prev_solution, time_step: heatflow transient only (previous .anh file, seconds). Orders used: mi(freq,units,type,prec,depth,minang,acsolver); ei(units,type,prec,depth,minang); hi(units,type,prec,depth,minang,prevsoln,dt); ci(units,type,freq,prec,depth,minang).

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 angle_deg (0 < angle <= 180); maxseg_deg is the arc discretisation (1 deg fine, 5-10 coarse; air gaps want <= 1). End nodes are created as needed.

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 points [[x, y], ...] group -> every object in group rectangle -> objects inside rectangle=[x1, y1, x2, y2] circle -> objects inside circle=[cx, cy, R] entities (rectangle/circle only): nodes|segments|labels|arcs|all. Returns what FEMM reports for each pick (the coordinates of the selected object).

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 rotate_deg (counter-clockwise) about about=[x, y] (default origin). entities: nodes|segments|labels|arcs|group restricts what moves (default: FEMM's current edit mode; use 'group' after femm_select(kind='group')).

femm_copy_selectedA

Copy the selection copies times, each shifted by a further (dx, dy) or rotated by a further rotate_deg about about (default origin). Typical: one slot drawn, then femm_select(kind='group') + femm_copy_selected(rotate_deg=360/Q, copies=Q-1, entities='group').

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 factor about about=[x, y] (default origin).

femm_set_groupB

Put the selected objects into group number group (used for moving rotors, for femm_block_integral(group=...) and femm_field_stats(region='group:N')).

femm_import_dxfA

Import a DXF drawing into the current model (xi_readdxf). tolerance merges nodes closer than this (problem units); leave None for FEMM's default. Check the result with femm_geometry_summary, then add block labels.

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 points (e.g. midpoints) and set boundary name ("" = none), mesh_size (max element size along the segment; None = automatic), hide-in-postprocessor flag, group, and (non-magnetics) conductor name.

femm_set_arc_propB

Select the arcs nearest each of points and set discretisation (max_seg_deg, degrees per straight piece; air gaps want <= 1), boundary name, hide flag, group, (non-magnetics) conductor.

femm_set_node_propB

Select the nodes nearest each of points and set a point property (from femm_add_point_prop, "" = none), group and (non-magnetics) conductor.

femm_add_circuitA

Magnetics: define a circuit carrying current amps (peak for AC; [re, im] or "1+2j" for phase). series=True: every block in it carries current per turn (set turns on the block labels; stranded coils). series=False (parallel): current is the total, split between blocks by impedance (solid conductors). Results: femm_circuit_results.

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 points. magnetics: value = prescribed A (Wb/m), source = point current (A). electrostatics: value = V, source = point charge (C/m). heatflow: value = T (K), source = point heat (W/m). currentflow: value = V, source = point current (A/m).

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 name a nonlinear curve. Magnetics: points = [[B (T), H (A/m)], ...] starting at [0, 0], B and H strictly increasing (mi_addbhpoint). Heat flow: points = [[T (K), k (W/m/K)], ...] (hi_addtkpoint). clear_first removes the existing curve. The material must already exist in the model (femm_material_add or femm_material_load).

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 points and/or every block in group (list of group numbers), then evaluate xo_blockintegral for each code. Magnetics codes (manual 3.7.1): 0 A.J, 1 A, 2 field energy (J), 3 hysteresis/lamination loss, 4 resistive loss (W), 5 area, 6 total loss, 7 total current, 8/9 integral of Bx/By, 10 volume, 11/12 Lorentz force x/y, 15 Lorentz torque, 17 coenergy, 18/19 weighted stress tensor force x/y (N, select the moving part surrounded by air), 22 stress tensor torque (N m), 24 R^2... Other physics: see femm_api_get('eo_blockintegral') etc. Defaults: magnetics [2,17,5,10,7]; electrostatics [0,1,2]; heatflow [0,1,2]; currentflow [0,1,4,5]. Planar results are per the problem depth (total, not per metre).

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 name (mo_getcircuitproperties), with derived inductance L = flux/current (for a circuit alone in the model; mutual effects included), resistance (DC) or impedance V/I (AC). Electrostatics/heat/current: conductor results (xo_getconductorproperties): voltage & charge, temperature & heat flux, or voltage & current.

femm_select_blockB

Post-processor block selection for femm_call('mo_blockintegral', [code]) workflows. action=select clears, then selects the blocks containing points and/or groups; action=clear clears the selection. (femm_block_integral does select+integrate+clear itself.)

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 boundary (femm_add_boundary bc_type='periodic_air_gap'): torque (mo_gapintegral 0), force (1), stored energy (2) [include_ac adds 2x torque/force and interaction terms]; Br/Bt at angle (deg); the Br/Bt distribution at npts angles saved to CSV with stats; and the harmonics largest Br harmonics (mo_getallgapharmonics). Magnetics only. Warning: FEMM returns zeros (not an error) for an unknown boundary name.

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 args, e.g. femm_call('mi_makeABC', [7, 50, 0, 0, 0]) or femm_call('mo_getgapb', ['AGE', 15]). The call is checked against the command catalog first; warnings (wrong arity or types, unknown name, pyFEMM-only helpers such as mo_getb that the engine lacks) are returned in warnings, and the call is still sent unless the name is unknown to both the catalog and the engine. Strings are quoted for you; complex values: [re, im] is NOT converted here, pass a string expression via femm_eval instead. Use femm_api_search to find commands.

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. prefix). Give code or path (.py). mode=inprocess (default): written to <work_dir>/scripts and executed inside this session's engine with exec(open(p).read()) (VERIFIED on FEMM 5): it sees and changes the session's model; set a global result (or result_var) to return a value; print() output is NOT captured (the engine's stdout is discarded). mode=batch: runs femm_headless --port <free> -run script.py args... as a separate engine (fresh state, exits at the end); returns stdout, stderr and exit code (1 on a script error, with the message in stderr). Use for long independent jobs or sys.argv-driven scripts.

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-lua -h -p <free port> script.lua args). It spawns its own engine (not a session) and exits when done. VERIFIED on Windows with a small newdocument/mi_probdef/mi_addnode/print script. Returns stdout/stderr/exit code. To port a Lua script permanently, rewrite it with femm_run_script (MicroPython) instead.

femm_journalA

The raw command lines this session sent to FEMM (most recent limit), i.e. exactly what the engine executed; commands FEMM refused are prefixed '#! ' with the error. save=True also writes the full journal as a replayable in-process script (<work_dir>/scripts/journal.py: run it with femm_run_script(path=...)). Internal pings are filtered out. Use femm_export_pyfemm_script for a standalone file.

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 query and/or extension ('.fem', '.py', '.lua', ...). Open one with femm_open.

femm_factsB

Verified FEMM 5 behaviour collected by this project (docs/femm5-facts.md): command quirks, units, what works headless, renamed materials. query returns only the sections that mention it. Read this before trusting FEMM 4.2 habits.

femm_experiment_force_vs_positionA

Force vs position: move the parts in groups by (dx, dy) PROBLEM UNITS per step, re-solve, and record the weighted-stress-tensor force on force_groups (default groups), the total coenergy and every circuit's flux linkage. Health check: WST force vs virtual work dW'/ds.

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 rotate_groups about center (default [0, 0]) each step and re-meshes; torque = WST block integral on torque_groups (default rotate_groups; exclude a rotor-side air layer from torque_groups). Needs an air layer split by a circle in the gap so the rotor can turn. method='age': the model has a FEMM 5 'Periodic Air Gap' boundary (BdryFormat 6) named gap_boundary; its inner angle is stepped and torque = mo_gapintegral (mesh never changes). drive = {"circuits": ["A","B","C"], "pole_pairs": p, "id": 0, "iq": 10, "theta0_deg": 0} makes the phase currents follow the rotor (amplitude-invariant dq; theta_e = p*angle + theta0) and adds a mean-torque check against 3/2 p (psi_d iq - psi_q id).

femm_experiment_coggingA

Cogging torque: all circuit currents set to 0, torque over periods cogging periods (360/lcm(slots, poles) mech deg, steps samples incl. end point) and its harmonics. poles is the number of poles (2p). Same rotor options as femm_experiment_torque_vs_angle. Checks: zero mean, periodic end points, WST vs virtual work. Currents are restored.

femm_experiment_backemfB

Open-circuit back-EMF: flux linkage of each circuit (default all) over one electrical period (360/pole_pairs mech deg, steps samples), EMF = omega * dpsi/dtheta (spectral derivative), fundamental / THD / harmonics / line-line EMF / Ke. Currents are zeroed and restored. psi_estimate (Wb, peak) adds an analytic comparison (femm_estimate spm_flux_linkage_fundamental).

femm_experiment_inductanceB

Inductance from flux linkage. Default: self/mutual matrix L_jk = (psi_j(I_k=current) - psi_j(0)) / current for circuits (default all) - subtracting the zero-current solve removes magnet flux. Linear models get an energy check (W = 1/2 L I^2). dq mode: dq = {"circuits": ["A","B","C"], "pole_pairs": p, "theta0_deg": 0, "id": 5, "iq": 5} at the present rotor position (theta0 = electrical angle of the d-axis from phase A) gives psi_pm, Ld, Lq, saliency and the dq torque, checked against the FEM torque on torque_groups (WST) or gap_boundary (air-gap element).

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. current overrides every swept circuit's current. Conductors must have conductivity and the mesh must resolve the skin depth (femm_estimate skin_depth).

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 path, default <work_dir>/.fem) and return its groups, circuits and analytic estimates: 'ccore' (planar U-core + armature, groups armature=1 core=2 coil=3, circuit 'coil'), 'coilgun' (axisymmetric coil + iron slug group 1), 'spm' (12-slot 4-pole surface PM machine, params rotor_method='rotate'|'age', rotor groups [1,10] or AGE boundary 'AGE', circuits A/B/C), 'round_wire' (copper wire in an A=0 circle for AC sweeps). params are the builder keyword arguments (e.g. {"gap": 0.5, "turns": 100}); see femm_agent.benchmarks.

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 checks): mesh (element count, worst triangle angle), precision, energy (W = W' and W = 1/2 sum I psi for linear models without magnets), saturation (share of steel above b_limit T; linear iron over 2.2 T), boundary (|B| at the outer boundary vs peak), torque (WST on rotor_groups vs -stator_groups; air-gap element torque if present), force (force_groups vs -reaction_groups), ac (1/2 Re(V conj I) = losses), flux (two cuts [[p1,p2],[p3,p4]] must carry the same flux), pm (magnet operating points). Returns {checks: [{name, ok, value, expected, tolerance, message}], summary, facts}.

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, zoom = [xmin, xmax, ymin, ymax] in problem units), "experiments" (this session's experiment results, or the result .json paths in experiment_files). Returns the paths; open report.md to read it.

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 rtol are flagged.

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). zoom = [xmin, xmax, ymin, ymax] in problem units; default file <work_dir>/field_B.png; save_arrays also writes the nodes/elements/B arrays as .npz.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A3.5/5.0

Scored across 88 tools

Disambiguation4/5

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.

Naming Consistency5/5

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.

Tool Count1/5

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.

Completeness5/5

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.

Maintenance

ActivityMaintained
ResponsivenessNo issues