ls-dyna-mcp
Drives LS-DYNA analyses through Ansys Workbench/Mechanical using PyMechanical, supporting analysis settings, loads and conditions, results, binout trackers, keyword snippets, deck export, and background solves.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ls-dyna-mcp Submit crash.k with 8 cores and check the run progress"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ls-dyna-mcp
MCP server for LS-DYNA (Ansys 2026 R1, LS-DYNA 16.1). It works in two ways, separately or together:
With Ansys Workbench / Mechanical: an AI client drives the LS-DYNA analysis through PyMechanical (analysis settings, loads, results, binout trackers, keyword snippets, deck export and a background solve).
Standalone, without Workbench: it submits and monitors solver runs on your own keyword decks (
.kfiles), as LS-Run does (SMP and MPP, queue, dependencies, restarts,sw1stop), and reads, audits and compares the files LS-DYNA writes. No Mechanical connection is needed.
Both modes share run monitoring (progress, ETA, energy-balance checks, termination read from the
solver's banner), readers for glstat, binout, d3plot and the ASCII histories, a deck audit and
comparison, and an optional keyword builder based on PyDYNA. Replies are redacted and file access is
limited to allowed folders; see doc/security.md.
Tool surface
53 tools, grouped by purpose. One-line descriptions are in doc/tools.md.
Purpose | Needs Mechanical | Tools |
Connection | yes |
|
Discovery | yes |
|
Discovery (user guide) | no |
|
Model building | yes |
|
Keyword builder | only to add a card to the analysis |
|
Solve | yes |
|
Standalone runs | no |
|
Run monitoring and results | no |
|
Decks and reference | no |
|
Gates around a solve |
|
|
Experimental (off by default) | no |
|
Related MCP server: Ansys MCP Server
Installation
For users:
pip install . # the server, with the ls-dyna-mcp console script
pip install ".[binout]" # optional: read_binout and read_d3plot (lasso-python)
pip install ".[pydyna]" # optional: describe_keyword and build_keyword (ansys-dyna-core)For developers:
pip install -e ".[dev]" # core tests; tests that need lasso or PyDYNA are skipped
pip install -e ".[binout,pydyna,dev]" # the full test suite, as CI runs itlasso-python pins an older psutil than PyMechanical needs; see
doc/getting-started.md for the --no-deps workaround.
Usage
Register the ls-dyna-mcp command with your MCP client (Claude Code, Claude Desktop or VS Code).
For the Mechanical-side tools, start Mechanical with a gRPC port first; the file readers and the
job runner work without it. Client configuration is in
doc/getting-started.md and a short walk-through is in
examples/example_workflow.md.
Configuration
The most important environment variables (the full list is in doc/configuration.md):
Variable | Effect |
| Folders the file-side tools may use (default: the working directory) |
| Standalone jobs run at once (default 1) |
| Upper bound on |
|
|
|
|
|
|
| Where the job table and the remembered Mechanical port are kept |
|
|
Safety
File tools only touch allowed folders; network paths, links and alternate data streams are refused.
Only Ansys-installed
lsdyna*.exesolvers can run, with allow-listed arguments; scripts and LS-PrePost are off by default.Replies are redacted for computer, user and licence identifiers. Details: doc/security.md.
Known limits
Windows and Ansys 2026 R1 only.
Workbench scripting cannot set the selection (drop-down) settings; use keyword snippets.
A long Workbench solve through the MCP has not been tested; see doc/known-limits.md and doc/workbench-notes.md.
License
MIT, see LICENSE. ANSYS and LS-DYNA are trademarks of their owners. This project is independent and ships no vendor software.
Resources
Available Tools
53 toolsadd_binout_trackerA
Add a Binout Tracker (SolutionInformation.AddLSDYNAGeneralTracker). branch is a binout branch: abstat, bndout, dbfsi, defgeo, deforc, elout, glstat, jntforc, matsum, nodout, rbdout, rcforc, rwforc, secforc, sleout, spcforc, trhist, randles, isoPot. Add trackers BEFORE solving. Branch, then sub-branch, then component are set in that order; a failure removes the tracker again unless keep_partial=true (list_binout_tracker_options shows the valid names). Args: branch, component (e.g. kinetic_energy), subbranch, named_selection, analysis_index, keep_partial
Inputs: branch (required), component (required), subbranch, keep_partial, +2 more. Returns: result
add_keyword_commandsA
Add a Keyword Snippet (Commands object) holding raw LS-DYNA keyword text, for cards Mechanical has no native object for (e.g. *CONTROL_ENERGY, *DEFINE_CURVE). Leading/trailing blank lines are stripped: trailing blanks are read as empty mandatory cards and break the solve. INCLUDE cards in the text may only name files inside the allowed folders (the solver itself would otherwise open them, e.g. a network path). Args: keywords (must start with a '' card such as *CONTROL_ENERGY; do NOT add *KEYWORD, the snippet goes inside the deck Mechanical writes); analysis_index; scope_path: where to insert it, as a dotted path from the Model, e.g. "Geometry.Children[0].Children[0]" for a body (*MAT, *EOS, *HOURGLASS) or "Connections" (contact types the system lacks). Empty = under the analysis (any keyword).
Inputs: keywords (required), scope_path, analysis_index. Returns: result
add_load_or_conditionA
Add a load / boundary / initial condition to the LS-DYNA analysis and scope it. kind (case and spaces ignored): Velocity, InitialVelocity, Acceleration, EarthGravity, FixedSupport, Displacement, RemoteDisplacement, Force, RemoteForce, Moment, Pressure, HydrostaticPressure, LinePressure, RotationalVelocity, RotationalAcceleration, DetonationPoint, ImpedanceBoundary, BoltPretension, ElementBirthAndDeath, NodalForce, NodalDisplacement, FrictionlessSupport, SimplySupported, FixedRotation. properties_json sets properties by name, e.g. {"DefineBy": "Components", "XComponent": "5000 [mm s^-1]"}; each is reported, and unknown names say so (use inspect_object on the new object's path to see what exists). Properties are applied in the order given (put "DefineBy" first). If a property or the scope fails the new object is removed again, so a retry cannot create duplicates (keep_partial=true keeps it). Without a named_selection the object is created unscoped. A Velocity/Displacement overrides Fixed Support on the same body (Users Guide 8). Args: kind, named_selection, properties_json, analysis_index, keep_partial
Inputs: kind (required), keep_partial, analysis_index, named_selection, +1 more. Returns: result
add_resultA
Add a result object under Solution. kind: TotalDeformation, DirectionalDeformation, EquivalentStress, EquivalentPlasticStrain, MaximumPrincipalStress, MinimumPrincipalStress, ShearStress, NormalStress, TotalVelocity, DirectionalVelocity, TotalAcceleration, ForceReaction, Position, UserDefinedResult, EnergyProbe, DeformationProbe, VelocityProbe, ReactionProbe, StressProbe, StrainProbe. For d3max/d3part see set_analysis_settings (Capture Maximum Stress Over Time, Selective Output). Properties are applied in order; a failed property or scope removes the new object again unless keep_partial=true. Args: kind, named_selection, properties_json, analysis_index, keep_partial
Inputs: kind (required), keep_partial, analysis_index, named_selection, +1 more. Returns: result
audit_deckA
Read-only audit of an LS-DYNA keyword deck before it is solved (plain text parsing, nothing
is executed). Reports the cards present by family, duplicate ids (MID, PID, SECID, EOSID, HGID,
LCID/TBID), references to ids that do not exist (PART to SECID/MID/EOSID/HGID, curves), first-card
format problems, whether MAT/PART cards look Workbench-written or snippet-written, a guess of the
unit system, the end time against the output intervals, and a table of known Workbench defaults
(for example *MAT_JOHNSON_COOK SPALL 0, which LS-DYNA treats as 2) each with the place in the
LS-DYNA keyword manual it was read at, or marked unverified. Follows *INCLUDE only inside the
allowed folders. Returns findings (severity info/warning/error, card, field, message) and a
compact summary. Args: deck_path, include_children (follow *INCLUDE files)
Inputs: deck_path (required), include_children. Returns: result
build_keywordA
Write one keyword card as LS-DYNA text, laid out by PyDYNA's own definition of the keyword
(nothing here is typed from memory). Unknown field names and wrong value types are refused.
Fields you leave out are written with the manual default (PyDYNA writes it explicitly, for
example SPALL 2.0): the reply's defaults_written lists them. After writing, the text is read
back and every value you gave must come out unchanged, else ok is false and the field is named
(value too wide for its column, a float that would lose digits, a field of an inactive
conditional card). A field name that occurs in several cards must be addressed as
"card3.name" (card numbers as in describe_keyword). title adds the _TITLE option (printable
ASCII only, no control characters). Cannot do: keywords with repeating-row (table or point)
cards such as DEFINE_CURVE or *PART with a table, and keywords with file or path fields; use
add_keyword_commands with explicit text for those. The same safety checks as
add_keyword_commands apply. With add_to_analysis=true the card is added as a Keyword Snippet
(scope_path as in add_keyword_commands); otherwise the text is only returned.
Args: name (e.g. MAT_JOHNSON_COOK), values (field name -> value, see describe_keyword),
add_to_analysis, analysis_index, scope_path, title
Inputs: name (required), values (required), title, scope_path, +2 more. Returns: result
check_restart_setupA
Validate a Simple / Small / Full restart before solving: the documented rules (e.g. a
small restart is impossible for a serial single-precision solution; a small restart needs a
later end time) and, if directory (the earlier run's folder) is given, whether the restart
files it needs are really there (d3dump for simple/small, d3full for full). Times of 0 are
treated as unknown. Args: restart_type, solver_precision (single|double),
processing_type (SMP|MPP), number_of_cores, previous_end_time, new_end_time, directory
Inputs: restart_type (required), directory, new_end_time, number_of_cores, +3 more. Returns: result
check_run_healthA
Judge a run from glstat (or binout) and d3hsp. Checks termination, energy balance,
hourglass energy and negative sliding energy at their worst point in the run and, for
quasi-static runs, kinetic energy. The reply has a verdict: 'running' (a job of this server
is still active in the folder), 'no_results' (nothing to judge), 'truncated' (normal termination
before the requested end time), 'failed' (error termination),
'suspect' (energy problems, or the energy file looks left over from an earlier run),
'incomplete' (no termination banner yet: still running or killed), 'unverified' (finished but
no energy data) or 'ok'. ok: true only means the files were read, not that the run is
good. Staleness is judged by file times: run each job in a clean folder.
Args: directory, hourglass_limit (max hourglass/internal, default 0.10),
balance_tol (allowed deviation of the energy ratio from 1),
quasi_static (also flag kinetic energy above 5% of total, a rule of thumb)
Inputs: directory (required), balance_tol, quasi_static, hourglass_limit. Returns: result
compare_decksA
Read-only field-by-field comparison of two keyword decks, for example a standalone reference
against the deck Workbench wrote. Cards are matched by keyword and id (MID, PID...), not order;
card name case, comma versus fixed format, number formatting (1.0e3 equals 1000) and *PARAMETER
values are normalised. Fields of the common cards carry the manual's field names (MAT_JOHNSON_COOK,
MAT_ELASTIC, MAT_PLASTIC_KINEMATIC, EOS_GRUNEISEN, SECTION_SOLID/SPH/SHELL, CONTROL_TERMINATION/
SPH/HOURGLASS/TIMESTEP/CONTACT/ENERGY, DATABASE_BINARY_D3PLOT, INITIAL_VELOCITY, HOURGLASS); other
cards use "field N". Status per row: equal, differs, only-in-reference, only-in-candidate,
default-vs-explicit (one side blank and the other the manual default); known_workbench_default
marks a candidate value that is a known Workbench default (see audit_deck). At most 300 rows
(differences first); truncated says if more existed.
Args: reference_path, candidate_path, cards (keyword prefixes such as ["MAT_JOHNSON_COOK",
"CONTROL_"]; default all), candidate_unit_scale ({"length": 1000.0, "mass": 0.001, "time": 1.0}:
how many candidate units one reference unit is, per base quantity; converts density, stress,
velocity, energy and time of the reference before comparing; absent = compare raw values)
Inputs: candidate_path (required), reference_path (required), cards, candidate_unit_scale. Returns: result
compare_early_resultsA
Early-time gate: compare a scalar history of a short run with a reference CSV (time,value) before committing to the long run. quantity: 'glstat:kinetic_energy' (glstat, or the binout glstat) or '::' for matsum, rcforc, sleout, spcforc, rwforc, nodout (for example 'matsum:1:kinen', 'nodout:5:x_vel'). The reference is interpolated at the simulation's output times inside [t_min, t_max] and multiplied by reference_scale (unit conversion; times must already be in the model's unit). Returns points compared, max and RMS relative error (%), the worst point, the first time the error exceeds tolerance_pct and a verdict within_tolerance / exceeds. A mismatch means diagnose the model (audit_deck, compare_decks): never tune parameters to match an experiment. No solver is run. Args: working_dir, reference_csv, quantity, t_min, t_max, tolerance_pct, reference_scale
Inputs: quantity (required), working_dir (required), reference_csv (required), t_max, +3 more. Returns: result
connect_to_mechanicalB
Connect to the Mechanical session that holds your LS-DYNA system. Args: port: gRPC port of the Mechanical session (changes every session)
Inputs: port (required). Returns: result
create_lsdyna_analysisA
Add an LS-DYNA analysis (restart=True: an LS-DYNA Restart analysis) to the Mechanical model via Model.AddLSDynaAnalysis / AddLSDynaRestartAnalysis. The Workbench system itself has template ids LSDYNA and RestartLSDYNA (see create_lsdyna_system_snippet). The new analysis is detected as LS-DYNA. It cannot be deleted through the scripting API (null-reference error), so remove it in the GUI if unwanted. Args: restart
Inputs: restart. Returns: result
create_lsdyna_system_snippetB
Workbench journal lines that create an LS-DYNA (or LS-DYNA Restart) system, for execute_workbench_script in the Workbench MCP. Template ids come from the installed LSDYNA ACT extension. Args: restart
Inputs: restart. Returns: result
delete_objectA
Delete one object this server (or the user) added to the analysis: a load, support, result, tracker or keyword snippet. Only these paths are accepted: "Children[n]" (loads, supports, snippets), "Solution.Children[n]" (results) and "Solution.SolutionInformation.Children[n]" (trackers). The object's current name must equal expected_name, so a stale index (indexes shift when objects are added or removed) deletes nothing. Analyses, Analysis Settings, Solution, Solution Information, Initial Conditions and anything outside the analysis (named selections, mesh, contacts) are refused. Look first with list_scoping_targets or inspect_object. Args: path, expected_name, analysis_index
Inputs: path (required), expected_name (required), analysis_index. Returns: result
describe_keywordA
List the cards and fields of an LS-DYNA keyword (field name, type, column, width,
default), read from the installed PyDYNA package (pip install ansys-dyna-core; it holds
Ansys-generated definitions of about 3,100 keywords). The name is matched exactly, hyphens
included (MAT_SAMP-1 and MAT_SAMP_1 are different keywords). default is what build_keyword
writes for a field you leave out (PyDYNA writes the manual default explicitly, e.g. SPALL 2.0).
builder_supported is false for keywords with repeating-row (table or point) cards such as
DEFINE_CURVE, and for keywords with file or path fields: use add_keyword_commands for those.
Args: name (e.g. MAT_JOHNSON_COOK, with or without the leading *)
Inputs: name (required). Returns: result
describe_workbench_materialA
Which *MAT/*EOS cards Workbench can write, and how each field maps to Engineering Data (from the installed LSDYNASolverRepresentation.xml). query is matched against the card name, e.g. "JOHNSON_COOK" or "*MAT_ELASTIC". An xml_path must be inside an allowed folder. Args: query, xml_path (optional)
Inputs: query (required), xml_path. Returns: result
disconnect_from_mechanicalA
Disconnect, leaving Mechanical running. Args: shutdown (True sends Mechanical a forced exit request whoever started it, so unsaved work is lost; a session Workbench owns may restart or linger, so normally close it from Workbench instead), confirm (shutdown=True is refused unless confirm is exactly "SHUT DOWN MECHANICAL")
Inputs: confirm, shutdown. Returns: result
get_analysis_settingsB
Read the Analysis Settings. Each row has the property name ("Step Controls/Endtime"), the Details-panel caption ("End Time"), the raw value, its type, and whether it is read-only/visible. Enum settings (solver precision, processing type...) come back as integers; -1 is the Program Controlled default. Values are in the model's solver units (End Time here is seconds). Args: analysis_index; group (name prefix, e.g. "Output Controls"); visible_only
Inputs: group, visible_only, analysis_index. Returns: result
get_lsdyna_jobC
One job plus the tail of its lsrun.stdout.txt. Args: job_id, tail_lines
Inputs: job_id (required), tail_lines. Returns: result
get_run_progressA
Progress of a running or finished solve, read-only (never touches or kills a process). From
messag / mes0nnnn (MPP), restart messag01 / mes010000, d3hsp and lsrun.stdout.txt: latest time,
cycle and time step, percent of the end time, the solver's own estimate lines when it printed
them (estimated total / to-complete cpu and clock time, percent complete), our own rate and ETA
from successive calls (observations are kept in the per-user state folder, not in the run
folder, so call it again a minute or more later), hang hints (no solver process, newest output
file older than stale_minutes, d3plot not advancing, simulation time unchanged between calls)
and the solver's error block (Error nnnnn, termination due to energy, forrtl) from the tail.
state: running, finished, failed, stalled or unknown. The ETA assumes a constant rate.
Args: working_dir, stale_minutes
Inputs: working_dir (required), stale_minutes. Returns: result
get_solution_informationC
Members of the Solution Information object (solver output, time step / energy histories) to find what this release exposes. Args: analysis_index
Inputs: analysis_index. Returns: result
get_solve_statusA
Solution status, Mechanical messages and the solver working directory. While a solve started by solve_analysis is running, answers 'Solving' without touching Mechanical (which is busy), then returns that solve's result once. Args: analysis_index
Inputs: analysis_index. Returns: result
inspect_objectA
List the public properties of an object in the LS-DYNA analysis tree. Use it to discover real property names before calling set_analysis_settings. Args: path: dotted path below the analysis, e.g. "" (the analysis itself), "AnalysisSettings", "Children[0]"; analysis_index; max_items
Inputs: path, max_items, analysis_index. Returns: result
list_addable_objectsA
The Add* methods the analysis (loads, supports, conditions), its Solution (results, probes)
or its Solution Information (Binout trackers: AddLSDYNAGeneralTracker...) offers in this
release, so a kind can be found without guessing. host "solution" also lists the Solution
Information methods (in solution_information_methods), because trackers live there; host
"solution_information" lists only those.
By default the acoustic, frequency-response, PSD/response-spectrum, electromagnetic and
optimisation items, which do not apply to LS-DYNA, are left out (all_physics=true lists them).
Args: host ("analysis", "solution" or "solution_information"), filter (case-insensitive text),
analysis_index, all_physics
Inputs: host, filter, all_physics, analysis_index. Returns: result
list_binout_tracker_optionsA
Which binout branches and components a Binout Tracker accepts in this release (queried from the solver extension, not hard-coded). With no branch: the branches (e.g. glstat, matsum, rcforc, spcforc...). With a branch: that branch's components. A throwaway tracker is created and deleted. Args: branch, analysis_index
Inputs: branch, analysis_index. Returns: result
list_lsdyna_analysesA
List every analysis in the Mechanical model, flagging which are LS-DYNA (solver target LSDYNA@LSDYNA, or RestartLSDYNA@LSDYNA for an LS-DYNA Restart system).
Inputs: no named parameters. Returns: result
list_lsdyna_jobsA
All jobs submitted in this server session with status (pending, running, done, failed, stopped, cancelled) and termination (normal/error/unknown from d3hsp).
Inputs: no named parameters. Returns: result
list_restart_filesB
Restart files a run left in its folder: d3dump* (simple/small restart), d3full* (full restart) and dynain / dynain.lsda (initial state for a follow-on analysis), with sizes and times. Args: directory
Inputs: directory (required). Returns: result
list_scoping_targetsB
What loads and results can be scoped to: the named selections (name, kind, entity count), the parts and bodies of the geometry (name and geometry id, to use with the location options of add_load_or_condition), and the objects already in the analysis. Args: analysis_index, max_items
Inputs: max_items, analysis_index. Returns: result
list_solver_filesA
List LS-DYNA output files (d3plot, d3hsp, glstat, binout...) in a solver directory. Args: directory (the working_dir from get_solve_status)
Inputs: directory (required). Returns: result
list_solver_versionsA
List the LS-DYNA executables Workbench knows about (lsdyna_solvers.xml: version, SMP/MPP, MPI type, precision, path). Default location is %APPDATA%/Ansys//ACTLSDYNA/lsdyna_solvers.xml. An xml_path must be inside an allowed folder. Args: xml_path (optional)
Inputs: xml_path. Returns: result
prepare_dynainA
Explicit-to-implicit sequential solution, step 2: copy the solver's ASCII dynain file to
dynain.k so the External Model system can import it. Get an ASCII dynain with
set_dynain_output(psid, fmt="ascii") in the explicit run, and leave Workbench's own Output
Controls > Stress File for flexible parts OFF: that setting cannot choose ASCII through
scripting (the Workbench default is the binary dynain.lsda, which this tool cannot use;
multi-system transfers use the .lsda file directly, no conversion needed), and turning it on
as well gives the deck two springback cards. Rigid-body displacements are not saved. An
existing dynain.k is kept unless overwrite=True; a dynain larger than
LSDYNA_MCP_MAX_DYNAIN_MB (default 2048) is refused.
Args: directory (the explicit run's working_dir), overwrite
Inputs: directory (required), overwrite. Returns: result
presolve_checkA
Check before a solve, read-only (nothing is deleted or started). Reports free RAM and free
disk, a memory estimate (the solver's own 'Memory required' report in a previous d3hsp of the
folder when there is one; otherwise a rough heuristic from the node and element counts of the
deck, uncertain by a factor of about 3 either way), the LS-DYNA result files in the folder that
a new run would overwrite (names only), ncpu against the physical and logical cores, and the
unit-system hint and error findings of audit_deck. verdict: ok, warn or stop, with reasons.
Give working_dir (the newest .k in it is used) and/or deck_path.
Args: working_dir, deck_path, ncpu (0 = not given), memory (words as for the solver, e.g. 200m)
Inputs: ncpu, memory, deck_path, working_dir. Returns: result
read_binoutA
Browse and read binout (LSDA) results, where Workbench keeps glstat, matsum, rcforc, spcforc, sleout, nodout... Call with no branch to list branches, then branch to list sub-branches/variables, then branch+subbranch+variable for the data (thinned to max_points). Needs: pip install "ls-dyna-mcp[binout]". Args: directory, branch, subbranch, variable, max_points
Inputs: directory (required), branch, variable, subbranch, +1 more. Returns: result
read_d3plotA
Field results from the d3plot: where and when a quantity peaks. With no field it lists the
fields stored. With a field (node_displacement, node_velocity, element_solid_stress,
element_solid_effective_plastic_strain, element_shell_stress...) it returns, for up to
max_states evenly spread states (or the single state), the min / max / mean, the id of the
node or element holding the max, and a count of non-finite values (a blown-up run). Vectors
give their magnitude and stresses von Mises (worst integration point). Needs lasso-python.
Args: directory, field, state (-1 = spread), max_states (at most 20)
Inputs: directory (required), field, state, max_states. Returns: result
read_glstatB
Energy history from glstat, thinned to at most max_states evenly spaced states. Args: directory, max_states
Inputs: directory (required), max_states. Returns: result
read_history_fileA
Read an ASCII time-history file (matsum, rcforc, sleout, spcforc, rwforc, nodout). Returns
the record count, a min/max/last summary per part/interface/node/wall from ALL records, and
records thinned to max_records (at most 500). NaN/Inf values come back as null and are
counted in the summary as nonfinite_values. Use this when the run wrote ASCII files instead
of (or besides) a binout.
Args: directory, kind (one of the six), entity (optional id to keep), name (file name if not
the default, e.g. matsum), max_records
Inputs: kind (required), directory (required), name, entity, +1 more. Returns: result
read_implicit_progressA
Implicit (statics / dynamics) solver progress from messag: per time step the iterations to
converge, stiffness reformations, the last residual norms and whether the step converged, plus
totals, the count of recoverable DIVERGENCE warnings and any lines about non-convergence or
step-size cuts. Use it to judge a Workbench Transient/Static LS-DYNA run that is slow or stuck.
Args: directory, name (default: the newest messag[nn], else mes0000; or the captured screen log
lsrun.stdout.txt), max_steps (the last N steps are returned in steps)
Inputs: directory (required), name, max_steps. Returns: result
run_lsprepostA
DISABLED unless the server is started with LSDYNA_MCP_ENABLE_LSPREPOST=1. Run an LS-PrePost command file (post-processing automation) in working_dir (must be an allowed folder). headless=True uses 'runc=' (no graphics: only non-graphical commands work); False uses 'c= -nographics'. The call runs on a worker thread with a hard timeout (at most 900 s) that kills the whole process tree. Files created are listed. Args: commands (cfile text, at most 20000 characters), working_dir, headless, timeout_s
Inputs: commands (required), working_dir (required), headless, timeout_s. Returns: result
run_mechanical_scriptA
DISABLED unless the server is started with LSDYNA_MCP_ENABLE_SCRIPT=1. Run a custom IronPython script inside Mechanical (full ACT API) with stock IronPython semantics. Args: script
Inputs: script (required). Returns: result
scan_keyword_fileA
Summarise a .k/.key file: keyword counts and missing essentials (termination, d3plot output, timestep control). Follows *INCLUDE, so a Split Input File deck (input.k pulling in database.k, control.k, mesh.k, component.k, contact.k) is scanned as a whole. Args: path, follow_includes
Inputs: path (required), follow_includes. Returns: result
scan_solver_messagesA
Count errors, warnings and implicit step retries in d3hsp, messag or mes0* files:
'*** Error nnnnn', 'FATAL ERROR', 'Nonlinear solver failed to find equilibrium',
'automatic time step size DECREASE, RETRY step'. The default name (empty, or the bare d3hsp /
messag) picks the newest d3hsp[nn] / messag[nn]; file in the reply says which was read.
Args: directory, name
Inputs: directory (required), name. Returns: result
search_lsdyna_helpA
Search the LS-DYNA user guide (HTML help) that Ansys installs, for example to find the options of a setting such as Hourglass Type. Only that installed help is read, nothing is written. A page matches when its text contains every word of the query (case-insensitive); hits are ranked by the number of matches and by words in the page title. Each hit has the file name, the page title and a short excerpt. The help gives option names and descriptions, not the integer values behind a setting; after setting a value, call get_analysis_settings to see what is stored. The help is an optional Ansys install component. Args: query, max_results (1-20), help_dir (optional folder with the .html pages; must be inside an allowed folder; default: the help of the installed release, or LSDYNA_MCP_HELP_DIR)
Inputs: query (required), help_dir, max_results. Returns: result
send_sense_switchA
Steer a running LS-DYNA job by writing a sense-switch file (d3kil) in its run directory. sw1 stops and writes d3dump (continue later with a simple restart); sw3 writes restart files and keeps running; sw4 writes a plot state; swb/swc/swd write dynain (swd also terminates); sw2 prints status; swa flushes buffers. For implicit runs: conv (force the step to converge, troubleshooting only), ttrm (retry the step with a smaller increment), rtrm (stop at the end of the step), lpri / nlpr / iter (toggle solver output). LS-DYNA reads and deletes d3kil while running; a switch sent to a run that already finished is refused. A reply of ok means the file was written, not that the solver has acted on it yet. Args: directory (the solver working_dir), switch
Inputs: switch (required), directory (required). Returns: result
set_analysis_settingsA
Set Analysis Settings; each value is read back and compared. Each key is attempted independently and reported. A key matches the full property name ("Step Controls/Endtime"), the caption ("End Time") or the last name segment, ignoring case and punctuation; if a caption is ambiguous (e.g. "Time Step Size" exists under Step Controls and EM Step Controls) the reply lists the full names to use instead. Values are set raw, in the model's solver units (End Time is seconds); numeric text such as "5e-4" is parsed (text with a unit in brackets is refused, never silently converted), true/false become 1/0, and plain integer settings take their integer value (read the current one with get_analysis_settings; -1 is Program Controlled). Non-finite values and values outside a sensible range (End Time in (0, 1e6) s, cycle counts > 0, time-step factors in (0, 1]) are rejected before anything is sent. Each value is read back and compared (NaN and Infinity never compare equal): a setting that keeps its old value is reported as 'not applied'. Selection (drop-down) settings such as Hourglass Type, Output Format, Stress File Type or Automatic Mass Scaling were seen to accept only -1 through this interface; set those with keyword snippets (add_keyword_commands, set_dynain_output) or in the GUI. Args: settings_json: JSON object, e.g. {"End Time": 0.0005, "Output Controls/Stress": 1}; analysis_index
Inputs: settings_json (required), analysis_index. Returns: result
set_dynain_outputA
Make the run write a dynain (final deformed shape and stress state) in the format you can use, by adding a *INTERFACE_SPRINGBACK_LSDYNA keyword snippet. Checked on the real solver: FTYPE 0 writes an ASCII dynain (which prepare_dynain can turn into an initial-state deck), 1 writes dynain.bin, 2 both, 3 dynain.lsda (the Workbench default, not convertible here). The Workbench setting 'Stress File for flexible parts' cannot choose ASCII through scripting, so leave it off (0) or the deck gets two springback cards. Args: psid (the part set to write; must exist unless part_ids_json is given), fmt (ascii | binary | both | lsda), part_ids_json (JSON list of part ids: a *SET_PART_LIST with this psid is added), analysis_index
Inputs: psid (required), fmt, part_ids_json, analysis_index. Returns: result
solve_analysisA
Solve the LS-DYNA analysis. Mechanical's local solve only runs blocking (it refuses to run in the background), so with wait=False (the default) this server runs the blocking solve on a background thread and returns at once with the solver working_dir: watch the run with check_run_health / tail_solver_file on that folder, and get_solve_status says 'Solving' until it ends. While a solve runs, other Mechanical tools report 'busy'; the file and job tools stay responsive. With wait=True the call itself blocks until the solve ends. Args: analysis_index, wait
Inputs: wait, analysis_index. Returns: result
stop_lsdyna_jobA
Cancel a pending job. For a running one, send sw1 (it stops and writes d3dump, so it can be restarted) or, with force=True, terminate the process. Args: job_id, force
Inputs: job_id (required), force. Returns: result
submit_lsdyna_jobA
Run LS-DYNA on a .k file outside Workbench (what LS-Run does). Only the solvers listed in Workbench's lsdyna_solvers.xml can be run, and the input must be inside an allowed folder. Jobs queue (max concurrent: env LSDYNA_MCP_MAX_JOBS, default 1; one job per folder); output goes to lsrun.stdout.txt in the input's folder. SMP: lsdyna_*.exe i=... ncpu=...; a NEGATIVE ncpu gives reproducible results at up to 15% more CPU time. MPP: mpiexec -np N (IntelMPI uses -localonly). Needs the Ansys LS-DYNA license (LSTC_LICENSE=ANSYS) and, beyond one core, HPC licenses. Args: input_file; ncpu (non-zero, at most 512 in magnitude); process (SMP|MPP); precision (single|double); mpi (IntelMPI|MSMPI); memory (words, e.g. 200m; empty = solver default); depends_on (job id to wait on for normal termination, -1 = last submitted); version; extra_args_json (JSON list of key=value strings; only case, memory2, jobid are accepted, e.g. ["case=1"]); dry_run (build the command, don't run); restart_file (name of a restart file such as d3dump01 or d3full01 in the input's folder: the run is started with r=; check_restart_setup says whether a restart is possible and what the input must contain)
Inputs: input_file (required), mpi, ncpu, memory, +7 more. Returns: result
summarize_d3plotA
EXPERIMENTAL and DISABLED unless LSDYNA_MCP_ENABLE_LSPREPOST=1. Have LS-PrePost load a d3plot and write its lspost.msg summary (s=). In testing LS-PrePost 4.13 crashed (0xC0000005) loading a d3plot without a GUI, and the reply then says so. Prefer read_binout / check_run_health. Args: d3plot_path, timeout_s
Inputs: d3plot_path (required), timeout_s. Returns: result
tail_solver_fileA
Last lines of a solver text file plus termination status. The default name (empty, or the
bare d3hsp / messag) picks the NEWEST d3hsp[nn] / messag[nn], i.e. the file the latest run or
restart is writing; the reply's file says which one was read. Any other name (d3hsp01,
mes0000, lsrun.stdout.txt...) is read as given. Text is redacted (see README, Privacy).
Args: directory, name, lines
Inputs: directory (required), name, lines. Returns: result
write_and_audit_deckA
Write the deck Workbench would solve (the same Analysis.WriteInputFile path as
write_solver_input, no solve) into an allowed folder, audit it (audit_deck) and, with
reference_path, compare it with the reference deck (compare_decks). safe_to_solve is false on
any error-severity finding (from the audit or the comparison, for example a Workbench default such as
*MAT_JOHNSON_COOK SPALL 0 against the reference's 3) and when the reference has cards the
written deck lacks (end time, initial velocity, contacts, materials lost by an External Model
import). True only means nothing blocking was found: read reasons and diff.
The file goes next to the reference (else into the first allowed folder) under output_name
(a plain .k name; default wb_written_.k); an existing file is never replaced.
Args: analysis_index, reference_path (the standalone deck to compare with), output_name
Inputs: output_name, analysis_index, reference_path. Returns: result
write_solver_inputA
Write the LS-DYNA keyword deck Mechanical would solve to output_path, without solving (Analysis.WriteInputFile). If this release lacks it, falls back to a generate-input-only solve and copies input.k. With Split Input File = Yes, the deck includes control.k, mesh.k etc. that stay in the solver working directory. output_path must be a .k/.key/.dyn file inside an allowed folder and must not exist unless overwrite=True. Args: output_path, analysis_index, overwrite
Inputs: output_path (required), overwrite, analysis_index. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 53 tools
Tool descriptions are unusually detailed and draw real boundaries, but several clusters overlap heavily: get_solve_status / get_run_progress / check_run_health / read_implicit_progress all answer 'how is my run doing', and read_glstat / read_binout / read_history_file / read_d3plot all read results. Likewise deck tools (scan_keyword_file, audit_deck, compare_decks, write_solver_input, write_and_audit_deck) require careful reading to pick correctly. An agent can usually choose well, but only by parsing long descriptions rather than from names alone.
The dominant pattern is verb_noun in snake_case (list_lsdyna_analyses, get_analysis_settings, add_result, delete_object, submit_lsdyna_job), applied consistently to prefixes like list_/get_/set_/add_/read_. A handful deviate into noun-ish or adjective forms (audit_deck, presolve_check, build_keyword, describe_keyword, tail_solver_file), but these remain readable and unambiguous in style.
53 tools is well above the 'heavy' threshold, even for a broad domain spanning mechanical connection, settings, loads, results, keyword authoring, deck auditing, solving, job control and post-processing. Several tools could be merged (multiple run-status/progress readers, two deck-writing entry points, four separate result-file readers), so the surface feels accumulated rather than scoped.
The lifecycle is covered end to end: connect/disconnect, create analyses and systems, inspect and set analysis settings, add loads/results/trackers, author and audit keyword decks, write and submit decks, watch and steer running jobs, restart, and read back every major result format. Even edge paths (restart validation, dynain conversion, sense switches, version discovery) have dedicated tools, with disabled features documented rather than silently absent.
Related MCP Connectors
Structural FEM for AI agents: frames, plates, buckling, seismic and Eurocode checks, solved locally.
Run FDS, OpenFOAM, CalculiX and other engineering simulations on cloudHPC from your AI assistant.
Governed data discovery, exact queries, decisions, simulations, and runtime utilities over MCP.
Manage SysML2 projects; check, evaluate, verify, query, document and diagram models.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables automated control of Ansys Workbench, Mechanical, and MAPDL through scripted journals and batch processing for simulation workflows.107MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Ansys simulation software (Fluent, MAPDL, Mechanical, Geometry) through the Model Context Protocol.71MIT
- FlicenseNot gradedqualityCmaintenanceEnables an AI assistant to drive Abaqus/CAE through file IPC—sending Python commands, querying model info, submiting jobs, and capturing viewport screenshots—so finite element models can be built and solved without manual GUI interaction.2-
- AlicenseCqualityBmaintenanceEnables AI assistants to control and automate Abaqus/CAE simulations via MCP, including model query, job management, ODB inspection, KPI extraction, capsule tracking, physics contract validation, report generation, and viewport capture. It also supports noGUI batch mode, dual transport, and integration with Codex/Claude clients.1108MIT