Mechanical MCP Server
Connects an MCP-compatible AI client to a local ANSYS Mechanical 2026 R1 session over gRPC so you can inspect, modify, mesh, load, solve, and read simulation data with tool calls.
Connect to, check, and disconnect from one local Mechanical gRPC session; optional shutdown requires confirmation.
Inspect model info, bodies, named selections, analyses, materials, mesh statistics, boundary conditions, contacts, results, and point masses.
Assign existing materials, suppress/unsuppress bodies, set 2D behavior, set mesh element/body sizes, and generate meshes.
Add supports and loads: fixed, frictionless, displacement, remote displacement, force, remote force, pressure, moment, and standard gravity; list boundary conditions.
Add/change contacts and contact types; configure nonlinear analysis settings.
Solve analyses in blocking or background mode and poll solve status.
Add/read results: total and directional deformation, equivalent/normal/principal stress, stress intensity, stress tool, reaction force, and modal frequencies.
Export nodal results and linearize stress paths, with optional
postprocdependencies.Create, list, and delete named selections; convert parts or name-prefix body groups to point masses; list point masses.
Generate TXT reports, or DOCX with the optional
reportdependency.Run arbitrary Mechanical Python scripts only when explicitly enabled; it is off by default.
Enforce security/config controls: file allow-lists, redaction, explicit analysis selection, lock/timeout/wait limits, and no outbound network calls.
Integrates with ANSYS Mechanical via PyMechanical gRPC, providing tools for geometry, meshing, boundary conditions, solving, results, and reporting.
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., "@Mechanical MCP Server Connect to Mechanical on port 10000"
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.
ANSYS Mechanical & ACP MCP Servers
A Model Context Protocol (MCP) server that connects any MCP-compatible AI client to ANSYS Mechanical via PyMechanical gRPC. Talk to your simulation in plain English.
The repo also ships a second server, ansys-acp-mcp, for building composite layups in ANSYS Composite PrepPost (ACP) through PyACP. See ACP server.
https://github.com/user-attachments/assets/309952dc-dce0-4aa6-9b06-e8047f32c2de
Compatible clients
Works with any MCP-compatible client, including:
VS Code (with Copilot MCP support)
Related MCP server: Ansys MCP Server
What it does
Category | Tools |
Connection |
|
Model |
|
Mesh |
|
Connections |
|
Loads and supports |
|
Analysis settings |
|
Solve |
|
Results |
|
Post-processing |
|
Point mass |
|
Named selections |
|
Reports |
|
Scripting |
|
Every tool that changes the model names the analysis it used (analysis: index, name, type). With
several analyses in the model, analysis_index or analysis_name must be given (index 0 is often
not the one meant); expect_analysis_type refuses a mismatch. Set
MECHANICAL_MCP_REQUIRE_EXPLICIT_ANALYSIS=0 to restore the old default of index 0.
What ok: true means
Every tool answers with a JSON object that has an ok key. For tools that create something in the
model, ok: true means the object was created, scoped and read back - it does not mean the
result is valid. A result added before the analysis is solved comes back with max: null,
min: null, solved: false and a note (Mechanical itself would report 0). If anything fails after
an object was created, the object is deleted again and the response says rolled_back: true.
Requirements
ANSYS Mechanical 2026 R1 on Windows. Only 2026 R1 (v261) has been exercised; older releases may lack API members used here (the gravity and reaction-force calls differ between releases) and are untested.
Python 3.10+,
ansys-mechanical-core,mcp[cli]>=1,<2
Installation
git clone https://github.com/codersag/mechanical-mcp.git
cd mechanical-mcp
pip install -e .Optional extras:
pip install -e ".[report]" # python-docx: generate_report(fmt="docx")
pip install -e ".[postproc]" # numpy + scipy: linearize_pathMCP Client Configuration
Add the following to your MCP client's config file. The config file location varies by client:
Client | Config file location |
Claude Desktop (Windows) |
|
Claude Desktop (Mac) |
|
Cursor |
|
Windsurf |
|
{
"mcpServers": {
"mechanical-mcp": {
"command": "ansys-mechanical-mcp"
}
}
}Or if running from source:
{
"mcpServers": {
"mechanical-mcp": {
"command": "python",
"args": ["C:/path/to/mechanical-mcp/mechanical_mcp_server.py"]
}
}
}Restart your client after editing the config.
Finding the Mechanical gRPC port
Mechanical exposes a gRPC server whose port you pass to connect_to_mechanical.
In Workbench (Tools → Scripting → Run Script):
port = GetSystem("SYS").GetContainer(ComponentName="Model").StartGrpcServer()
print(port)If you have multiple Mechanical systems open (e.g. Modal + Static Structural), run the script for each system by replacing "SYS" with the system name (e.g. "SYS 1", "SYS 2").
Usage
Open ANSYS Mechanical 2026 R1 and start its gRPC server (see above)
Find the port using one of the methods above
Connect to your Mechanical instance:
"Connect to Mechanical on port 10000"
Then interact naturally:
"Assign Structural Steel to the body called Plate"
"Generate a mesh with 50mm element size"
"Add a fixed support to the named selection called Base"
"Solve the analysis and get the maximum von Mises stress"
"Convert part Equipment1 to a point mass"
One session at a time
The server holds one connection. Calling connect_to_mechanical with another port replaces it,
but only once the new session answers (a dead or wrong port leaves the working connection alone).
Only sessions on this machine are supported: the port is probed on 127.0.0.1 first so a dead port
fails fast, and a port that accepts connections but never speaks gRPC is detected by a short
protocol probe instead of hanging the handshake. The last port is remembered in a per-user folder
(%LOCALAPPDATA%\mechanical-mcp, override with MECHANICAL_MCP_STATE_DIR) so a restarted server can
reconnect; only the port, a hash of the project folder and the folder's NAME are stored, never a path. A call that fails in transit (timeout, dropped channel) is never re-sent: Mechanical may
or may not have run it, so the response says so and you should look at the model before retrying.
Security and configuration
Tool arguments come from an AI agent that may have read untrusted text, so the server is restrictive by default.
Variable | Meaning |
| Folders (separated by |
| Same for the ACP server; falls back to |
|
|
|
|
| Set to |
| Where the remembered port is stored. |
| How long a call waits for Mechanical while another call (a solve) is running, default 60. |
| How many calls may queue for the Mechanical lock before the next gets |
| Size and time budget of |
| How long status tools ( |
| Bound on the gRPC handshake and first script when connecting, default 20. |
| How long |
| Size and time limits for |
Files: network/UNC paths and : (alternate data streams) are refused from the text, only .json
(export, linearize) or .docx/.txt (report) are accepted, and an existing file is never replaced
unless you pass overwrite=true. export_nodal_results enforces this inside the Mechanical script
as well: it writes a uniquely named exclusive temporary file, checks again right before the final
rename and refuses (leaving the file) if one appeared meanwhile, and removes only the temporary file
it created. Reserved Windows device names (aux.json, COM1.txt, nul, ...) are refused. disconnect_from_mechanical(shutdown=True) force-exits the
Mechanical session whoever started it (unsaved work is lost), so it also needs
confirm="SHUT DOWN MECHANICAL"; the normal disconnect_from_mechanical() only drops the connection.
Example with an allow-list and scripting enabled:
{
"mcpServers": {
"mechanical-mcp": {
"command": "ansys-mechanical-mcp",
"env": { "MECHANICAL_MCP_ROOTS": "C:\\Work\\fea", "MECHANICAL_MCP_ENABLE_SCRIPT": "0" }
}
}
}Privacy
The server is meant to be usable on a work machine without telling the AI model, its logs or this repository who you are.
Replies are redacted (on by default,
MECHANICAL_MCP_REDACT=0switches it off): the user-profile prefix of a path becomes%USERPROFILE%, and your Windows user name, computer name, licence server (port@host), customer / checkout / session / host ids and e-mail addresses are replaced in every tool reply and error. This is pattern-based: a project that has your name in its own file or folder names, or text Mechanical returns in a form the patterns do not know, can still carry it. Use a neutral project folder name if that matters.Stored state is minimal. The remembered-session file holds the port, a 16-character hash of the project folder and the folder's name; no path, no user name.
File access is confined to the folders in
MECHANICAL_MCP_ROOTS/ACP_MCP_ROOTS; error messages report how many folders are allowed, never which.Nothing leaves the machine. The server talks to Mechanical on
127.0.0.1and makes no network requests; it does not log tool arguments to a file. Temporary script and output files are removed after each call and stale ones (older than a day) at start-up.The repository's
.gitignoreexcludes project files (*.mechdb,*.wbpj), caches, logs and local configuration;tests/test_privacy.pychecks the published files for profile paths, e-mail addresses and licence ids.
Geometry selection, nonlinear setup and post-processing
Load and support tools (add_fixed_support, add_frictionless_support, add_displacement, add_force, add_pressure) take a named selection, or "" plus either:
entity_ids: comma-separated geometry ids, orbox_mm:"xmin,xmax,ymin,ymax,zmin,zmax"in mm (blank = open side), withentity_type(face,edge,vertex) and optionalbody_name.
Box coordinates are compared in mm whatever unit the geometry uses (read from GeoData.Unit).
A missing or empty named selection, ids that do not exist, or a box that matches nothing is an error
and nothing is created. entity_ids may name faces, edges or vertices.
Inspecting the model: list_boundary_conditions (loads and supports with scope and key values),
list_contact_regions, list_results and get_result_values (Max/Min with unit once solved),
list_named_selections, create_named_selection (from body names or prefix, geometry ids or a box;
refuses empty results and duplicate names unless replace=true).
Other model and result tools: set_2d_behavior, set_body_mesh_size, set_nonlinear_settings
(changes only the settings you pass), set_contact_type (overwrites every contact region unless
limited with region_names / only_if_currently; the response lists each region's previous type),
add_contact (two or more bodies), add_normal_stress, add_stress_intensity,
export_nodal_results and linearize_path.
Stress linearization flow
add_normal_stress(a signed component; linearizing von Mises or stress intensity is refused).solve_analysis(usewait=false+get_solve_statusfor long solves).export_nodal_results("Normal Stress", "C:/Work/fea/n.json")- writes node ids,xyz_mm(millimetres),values,value_unit, and whether the quantity is signed. Refuses an unsolved model.linearize_path("C:/Work/fea/n.json", "0,0,0", "0,0,12")- a 3D section line, or two numbers in aplane(then the data must lie in one plane, or giveslice_mm). Returns membrane, bending (at the start point; the end point has the opposite sign) and peak = total - (membrane + bending), withsection_length_mm.
Not verified against a real solved model: steps 3-4 depend on Result.PlotData, which only exists
after a solve, and the server's tests never solve. The export script, units and file format are
covered by unit tests with a fake object model; the numerical linearization is tested against
analytic profiles (pure membrane, pure bending, linear + peak). Treat the first real run with care.
Known limits
Sign convention of
add_pressureis not verified here. The magnitude is passed to Mechanical as given; which way a positive value acts was not checked (it needs a solve and a look at the result), so confirm it in Mechanical before relying on the direction.set_contact_typesnapshots the type AND the friction coefficient of every region it changes and restores both if any region fails; the response lists the real before/after of both.A client-side timeout on
solve_analysismarks the solve as possibly still running: the next solve request is refused until you check and passconfirm_not_running=true.A finished background solve's result is kept until read (up to five, one hour) and attached to the poll for the same analysis.
Verified live (Mechanical 2026 R1, an unsolved copy of a project, nothing solved or saved): gravity, loads and supports (named selection / ids / box scopes), remote displacement, reaction-force probe creation, results created before a solve, modal/static checks, mesh size, body sizing, nonlinear settings, contact type changes, material and suppression changes, point-mass conversion (it reproduces the previous implementation's centre of gravity and attachment faces, which shows agreement, not that the inertia is right - see the next point), reports (TXT), non-ASCII names including an emoji, list_point_masses in StandardMKS / CGS / NMM / BIN / UMKS, named-selection creation and dependents, the reuse of identical results and contacts, a connection to a silent socket (refused after about 2 s by the protocol probe, the existing connection untouched), a load scoped to a body-type named selection (refused and rolled back; Mechanical leaves such a load without a scope), the analysis-selection checks (explicit analysis, name, expected type) on a model with three analyses, deleting a named selection by object id, the reparse-point link test (
System.IO.File.GetAttributes) on a junction, a regular file and a folder, redaction of paths in replies, and recovery after a transport failure (exit code 0 in a subprocess).generate_meshwas only run on a model that already had a mesh (it returned the existing counts at once); meshing a fresh model and the failure path were not exercised live.Never run live (needs a solve, which these tests forbid): values read from solved results (
max/min, reaction force x/y/z/total, modal frequencies),export_nodal_resultson real data, the background solve with a real solver,generate_report(fmt="docx")with real python-docx (tested with a fakedocxmodule),set_2d_behavioron a truly 2D model, andconvert_*_to_point_masson a model whose loads are scoped to the converted bodies (covered by unit tests with the fake model only).Standard Earth Gravity only supports +-X, +-Y, +-Z (always 1 g). Any other direction is an error.
Mechanical 2026 R1 exposes no solve cancel, so a running solve cannot be stopped from here.
solve_analysis(wait=false)runs the blocking solve on a background thread; other Mechanical tools report "busy" until it ends, andget_solve_statusanswersSolvingwithout touching Mechanical.Materials are created in Workbench Engineering Data, not by this server;
assign_materialonly accepts names that already exist there.Numeric limits (the code enforces exactly these): element sizes 0.001 to 100000 mm, proximity multiplier 0.1 to 100, friction 0 to 10, forces and moments at most 1e12 in magnitude, pressure 1e15 Pa, displacements 1e9 mm, rotations 36000 deg,
samples2 to 5000.Point-mass inertia is only exact when the principal axes are the global axes. Mechanical gives a body only its three PRINCIPAL moments of inertia (
MomentOfInertiaIp1-3; no tensor, no axes, no products of inertia). They are used as Ixx, Iyy, Izz and the response saysinertia_basis: "principal"with warnings: always one, one more when several bodies are combined (their products of inertia are dropped because a point mass cannot take them), and one when planar faces are not aligned with the global axes. A body rotated against the global axes gets wrong Ixx/Iyy; check or set the inertia by hand in that case. Mass, centre of gravity and the attachment faces are unaffected.A box selects by centroid.
box_mmpicks the faces/edges/vertices whose CENTROID lies inside the box, not the entities that lie entirely inside; the response counts the selected entities that stick out inwarnings, andfully_inside=truerequires the whole entity (face and edge bounding boxes) to be inside.Names are not unique in Mechanical (two contact regions can both be "Contact Region").
set_contact_type(region_names=...)matches every region of that name and says so;list_contact_regionsshowsindexandduplicate_names.delete_named_selectiondeletes every selection of that name.Idempotency. The result tools and
add_contactreturn an identical existing object (already_exists: true,created: false, andsuppressed- a reused object may be suppressed) instead of adding "Equivalent Stress 2"; passreuse_existing=falseto force a duplicate. A contact region counts as the same when it joins exactly the same entities with the same type and (frictional) friction coefficient. If a region joins them but differs,add_contactrefuses and lists the differences;update_existing=truechanges the type/friction (restored on failure) and reportsupdated. Behaviour and formulation are not set by the call; they are only reported inexisting_properties. Point-mass conversion refuses to run twice for the same EXACT prefix/part (the mass would count twice) unlessallow_duplicate=true: the selection it makes is namedNearestFace_<start of prefix>_<hash of the whole prefix>, soSYS\\BandSYS\\Backingnever collide and are both allowed. Two different prefixes that match the same body are not recognised as duplicates.delete_named_selectionrefuses while loads, results, contacts, point masses or mesh controls are scoped to the selection (it lists them) unlessforce=true. Only objects scoped through aLocation,GeometryLocation,SourceLocationorTargetLocationare recognised: Force-reaction probes (their scope is a copy of the entities), joints, springs, remote points, coordinate systems and anything else that references a selection some other way are NOT detected.Transport failures. If a call fails in transit (timeout, dropped channel) the script is not re-sent and the response says it may or may not have run. The connection object is dropped outside the exception handler and finalized before its channel is closed: doing it inside the handler made the whole server process crash (exit 139) because the failing frames kept the object alive. The handshake with a port that is not Mechanical is bounded (
MECHANICAL_MCP_CONNECT_TIMEOUT_S, default 20 s) and does not hold the Mechanical lock; a late connection that arrives after the timeout is dropped the same way.Honest status while Mechanical is busy. During a blocking solve
check_mechanical_connectionanswersconnected: true, busy: true,get_solve_statusanswersstatus: "Busy"anddisconnect_from_mechanicalanswers busy, each withinMECHANICAL_MCP_PROBE_WAIT_S(1 s) plus scheduling. The guarantee is precise: these three tools run on their own small thread pool and never queue for the lock, so other waiting calls cannot starve them. Every other Mechanical tool waits for the lock up toMECHANICAL_MCP_LOCK_WAIT_S(60 s), but at mostMECHANICAL_MCP_MAX_WAITERS(4) calls wait at a time; the next ones getbusy: trueimmediately. A connection attempt to a port that never answers takes at mostMECHANICAL_MCP_CONNECT_TIMEOUT_Sand at most two such attempts may be pending.Reconnecting. The remembered port is stored with a hash of the project folder (and its name). The identity is read when you connect: if the project in the session is later saved under another name or a different project is opened in the same session, the remembered identity is stale until you connect again. A silent re-attach is only made while the port still serves that project (otherwise the call fails and tells you to connect deliberately), is reported once as
reconnected_toin the tool output, and the port is forgotten when it refuses connections or after three bad answers in a row (tested), not after one; a busy or slow session (handshake timeout) is neither a refusal nor counted. A remembered session with no project identity (an unsaved project) is never re-attached silently: callconnect_to_mechanical.linearize_path merges coincident nodes (interface nodes of touching bodies; their values are averaged) and triangulates only the nodes near the line (a k-d tree), so 216k nodes take seconds. A line that crosses a hole or notch is a
gaperror carryinggap_diagnostics(largest span and where it is);allow_gaps=trueaccepts it and reportsinterpolated_across_gap. The criterion is local and relative: the simplex a sample falls in is a gap only when its longest edge is more than 3 times the median of the simplices around it AND fewer than 20 % of those neighbours are of similar size. Graded, polar and long-element meshes (10:1, line along the long side or across it) and an abrupt step in element size (a fine region next to a coarse one) are therefore not flagged, but a void smaller than about three element sizes is not detected either. A section line shorter than 0.1 % of the model or than one element is refused. A line end that lies outside the triangulation by less thansnap_fraction(default 0.25) of an element - on a curved boundary or a hair outside a flat face - is extrapolated from the nearest simplex and listed inendpoint_adjustments; farther out the line is refused.MECHANICAL_MCP_MAX_NODES(default 1,000,000) andMECHANICAL_MCP_LINEARIZE_TIMEOUT_S(default 60) bound the work; a timed-out run is told to stop (it checks a cancel flag between stages) and only one linearization may run at a time; a second call getsbusyuntil the stopped one has ended. Only the single exported scalar is linearized: the file records itsorientation;expect_componentmakes a mismatch an error (and is reported ascomponent_unverifiedwhen the file has none); a line running along another axis than the component is refused unlessaccept_direction_mismatch=true; components are never combined.Export step and time.
export_nodal_resultsexports the result at the step it is currently set to; an analysis with several load steps needs an explicitload_step, and the file records the step, substep and time (step). Time-history results are exported one step per file.Exported units.
PlotDatadoes not declare its unit. The export compares its largest value with the result's ownMaximumand recordsvalue_unit_verified; when it is false the unit label is unconfirmed. This has only been unit-tested (a solve is needed to run it for real).Explicit Dynamics analyses keep displacement as a time table; the value you set is the last entry (the first is 0 at t=0).
set_nonlinear_settingson an analysis without those settings returns a clear error.get_solve_statusmessages come from Mechanical's global Messages pane (all analyses); the response says so.One Mechanical session per server process; sessions on other machines are not supported.
Generated scripts run in a private copy of Mechanical's globals, so nothing leaks between tools;
run_mechanical_script(when enabled) shares Mechanical's persistent globals as before.
ACP server (ansys-acp-mcp)
A second MCP server, acp_mcp_server.py, lets an AI assistant build ANSYS Composite PrepPost (ACP) layups and solid models through PyACP (ansys-acp-core), then convert the exported solid mesh into a clean per-fibre-angle external model for a Mechanical coupled-field analysis (for example thermal-electric lightning studies). Every tool returns JSON with ok and a short, specific error on failure.
Tested with ACP 2026 R1, ansys-acp-core 0.3.2, mcp 1.30, Windows, Python 3.10.
Install
pip install -e ".[acp]"ACP must be installed (the server uses acp_grpcserver.exe from %AWP_ROOT261%\ACP). Set AWP_ROOT261 (or the equivalent for your release) if ANSYS is not in the default location.
{
"mcpServers": {
"ansys-acp": {
"command": "ansys-acp-mcp",
"env": { "AWP_ROOT261": "C:\\Program Files\\ANSYS Inc\\v261" }
}
}
}Tools
Group | Tool | What it does |
Session |
| start / inspect / stop the PyACP-managed ACP server |
Model I/O |
| import CDB/H5/DAT/ |
Definition |
| materials, fabrics, rosettes, oriented selection sets |
Layup |
| modeling group with one ply per angle (+ optional bulk ply) |
Solid |
| extrude, recompute, export CDB/H5 |
CDB (no ACP needed) |
| summarise a CDB; convert an ACP solid CDB into a per-angle external model (normalised through MAPDL) |
Workbench ACP |
| generate the script that builds the layup inside Workbench's own ACP, the Workbench commands that run and link it, and the Mechanical snippet that splits plies |
Typical flow: acp_launch → acp_import_model (shell mesh) → acp_create_material → acp_create_fabric → acp_create_rosette → acp_create_oriented_selection_set → acp_create_layup → acp_create_solid_model → acp_update → acp_export_solid_model → acp_prepare_external_model. See examples/build_plate_layup.py.
Notes
The laminate is extruded toward
orientation_point; a shell at z = 0 withorientation_point = (0, 0, -1)puts the plies below the surface.acp_create_layupnames pliesply03_-45etc.;acp_prepare_external_modelreads the fibre angle from that name.ACP solid CDBs are structural (layered SOLID185). The converter gives each angle its own material and coordinate system so a coupled-field solve can use them, and runs the result through MAPDL so Workbench's External Model reader accepts it.
Hexahedral solid models only; composite shell layups, sub-laminates, draping and taper are not wrapped yet.
Development
python run_acp_unit_tests.py # CDB / Workbench-script tests, no ANSYS needed
python examples/stdio_smoke_test.py # start the server over stdio and list toolsIntegration tests need ACP: set ACP_MCP_INTEGRATION=1 and ACP_MCP_SHELL_CDB to a shell CDB, then run pytest tests/test_integration.py.
License
Apache License 2.0 — see LICENSE
Available Tools
37 toolsadd_directional_deformationC
Add Directional Deformation result. Args: axis (X/Y/Z), named_selection, analysis_index
Inputs: axis, analysis_index, named_selection. Returns: result
add_displacementC
Add Displacement BC. Pass None for a DOF to leave it free. Args: named_selection, x_mm, y_mm, z_mm (None=free), analysis_index
Inputs: named_selection (required), x_mm, y_mm, z_mm, +1 more. Returns: result
add_equivalent_stressC
Add Equivalent (von Mises) Stress result, optionally scoped to a named selection. Args: named_selection (empty = whole model), analysis_index
Inputs: analysis_index, named_selection. Returns: result
add_fixed_supportC
Add Fixed Support to a named selection. Args: named_selection, analysis_index
Inputs: named_selection (required), analysis_index. Returns: result
add_forceC
Add Force load in Newtons. Args: named_selection, fx_n, fy_n, fz_n, analysis_index
Inputs: named_selection (required), fx_n, fy_n, fz_n, +1 more. Returns: result
add_frictionless_supportC
Add Frictionless Support. Args: named_selection, analysis_index
Inputs: named_selection (required), analysis_index. Returns: result
add_momentC
Add Moment load in N·m. Args: named_selection, mx_nm, my_nm, mz_nm, analysis_index
Inputs: named_selection (required), mx_nm, my_nm, mz_nm, +1 more. Returns: result
add_pressureC
Add Pressure load in Pascals. Args: named_selection, magnitude_pa, analysis_index
Inputs: magnitude_pa (required), named_selection (required), analysis_index. Returns: result
add_principal_stressC
Add Principal Stress result. Args: which (max/mid/min), analysis_index
Inputs: which, analysis_index. Returns: result
add_reaction_forceC
Add Force Reaction probe at a named selection. Args: named_selection, analysis_index
Inputs: named_selection (required), analysis_index. Returns: result
add_remote_displacementC
Add Remote Displacement BC. Pass None for a DOF to leave it free. Args: named_selection, x_mm, y_mm, z_mm, rot_x_deg, rot_y_deg, rot_z_deg, analysis_index
Inputs: named_selection (required), x_mm, y_mm, z_mm, +4 more. Returns: result
add_remote_forceC
Add Remote Force load. Args: named_selection, fx_n, fy_n, fz_n, analysis_index
Inputs: named_selection (required), fx_n, fy_n, fz_n, +1 more. Returns: result
add_standard_gravityC
Add Standard Earth Gravity. Direction vector defaults to -Y (down). Args: analysis_index, x_component, y_component, z_component (unit vector)
Inputs: x_component, y_component, z_component, analysis_index. Returns: result
add_stress_toolC
Add Stress Tool (safety factor, stress ratio) using material limits. Args: analysis_index
Inputs: analysis_index. Returns: result
add_total_deformationC
Add Total Deformation result. Args: mode (0=not modal), analysis_index
Inputs: mode, analysis_index. Returns: result
add_total_deformation_all_modesC
Add Total Deformation for all modal modes. Args: num_modes, analysis_index
Inputs: num_modes, analysis_index. Returns: result
assign_materialC
Assign material to a body. Args: body_name, material_name
Inputs: body_name (required), material_name (required). Returns: result
check_mechanical_connectionB
Check connection status.
Inputs: no named parameters. Returns: result
connect_to_mechanicalB
Connect to ANSYS Mechanical via gRPC. Args: port: gRPC port reported by Workbench (changes every session)
Inputs: port (required). Returns: result
convert_part_to_point_massB
Convert all unsuppressed bodies inside a named Part to a combined Point Mass, then create a Named Selection of all coplanar attachment faces on the nearest structural surface. No ACT extensions required. Args: part_name, proximity_multiplier (default 3.0)
Inputs: part_name (required), proximity_multiplier. Returns: result
convert_prefix_to_point_massB
Convert all unsuppressed bodies whose name starts with body_name_prefix to a combined Point Mass, then create a Named Selection of all coplanar attachment faces on the nearest structural surface. No ACT extensions required. Args: body_name_prefix, proximity_multiplier (default 3.0)
Inputs: body_name_prefix (required), proximity_multiplier. Returns: result
delete_named_selectionC
Delete a named selection by name. Args: name
Inputs: name (required). Returns: result
disconnect_from_mechanicalA
Disconnect from Mechanical, leaving the session running. Args: shutdown (True also closes Mechanical itself - unsaved work is lost)
Inputs: shutdown. Returns: result
generate_meshB
Generate mesh. Visible live in Mechanical GUI.
Inputs: no named parameters. Returns: result
generate_reportC
Generate simulation report. Args: output_path, analysis_index, fmt (docx or txt)
Inputs: output_path (required), fmt, analysis_index. Returns: result
get_mesh_statisticsB
Get mesh node and element counts.
Inputs: no named parameters. Returns: result
get_modal_frequenciesA
Get natural frequencies from a modal analysis.
Frequencies are only readable through result objects. When none exist the tool used to return an empty list with ok:true, which reads as "this model has no modes" rather than "nobody asked for the results yet". Args: analysis_index, add_results_if_missing (add Total Deformation results and evaluate them when the solution has none)
Inputs: analysis_index, add_results_if_missing. Returns: result
get_model_infoB
Get model info: bodies, named selections, analyses.
Inputs: no named parameters. Returns: result
get_solve_statusC
Get solve status. Args: analysis_index
Inputs: analysis_index. Returns: result
list_boundary_conditionsC
List all boundary conditions. Args: analysis_index
Inputs: analysis_index. Returns: result
list_materialsB
List all materials in Engineering Data.
Inputs: no named parameters. Returns: result
list_named_selectionsB
List all named selections with face/body counts.
Inputs: no named parameters. Returns: result
list_point_massesA
List all Point Masses with CG, mass, pinball and scoped named selection.
Inputs: no named parameters. Returns: result
run_mechanical_scriptC
Run custom Python script inside Mechanical ACT API. Args: script
Inputs: script (required). Returns: result
set_mesh_element_sizeC
Set global mesh element size in mm. Args: element_size_mm
Inputs: element_size_mm (required). Returns: result
solve_analysisA
Solve the analysis. Progress visible in GUI. Returns solver messages. Args: analysis_index, wait (False submits and returns at once - then poll get_solve_status; use it for solves longer than the client call timeout)
Inputs: wait, analysis_index. Returns: result
suppress_bodiesA
Suppress or unsuppress bodies by name prefix (empty = all bodies). Args: name_prefix, suppress (True=suppress, False=unsuppress)
Inputs: suppress, name_prefix. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 37 tools
Most tools target distinct resources and actions across connection, modeling, boundary conditions, solving, and results. A few result-probe tools are conceptually close (e.g. add_total_deformation vs add_total_deformation_all_modes, add_stress_tool vs add_equivalent_stress), but descriptions generally make the intended use clear.
All tools use snake_case and nearly all follow a verb_noun pattern (add_force, get_model_info, list_materials, generate_mesh). The few deviations, such as run_mechanical_script or solve_analysis, remain readable and consistent with the overall convention.
37 tools is a heavy surface for an MCP server and exceeds the rubric's 25+ threshold for being too many. While ANSYS Mechanical is broad, several result and BC tools could be consolidated or handled through the existing script escape hatch.
The server covers the main simulation lifecycle: connect, inspect model, assign materials, mesh, add loads/BCs, solve, add results, and generate reports. Notable gaps remain in generic create/update/delete for named selections and boundary conditions, but run_mechanical_script provides a workaround for many missing operations.
Maintenance
Related MCP Connectors
MCP server enabling AI agents to manage Bitrix24 features via standardized protocol
MCP server unifying ERPs, CRMs, APIs and knowledge base for Claude, ChatGPT and Gemini.
Build and run AI workflows, agents, data tables and 1000+ API integrations from any MCP client.
Related MCP Servers
- AlicenseBqualityFmaintenanceEnables natural language-driven ANSYS simulations (Fluent, Mechanical, Geometry) with automatic TUI script generation for reproducibility.415MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Ansys simulation software (Fluent, MAPDL, Mechanical, Geometry) through the Model Context Protocol.71MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with ANSYS Icepak through natural language commands, supporting geometry import, material assignment, thermal loads, meshing, solving, and result retrieval.-

Ansys CFX-MCPofficial
AlicenseAqualityBmaintenanceAn MCP server that enables AI assistants to interact with Ansys CFX through PyCFX, supporting natural-language-assisted CFX-Pre, CFX Solver, and CFD-Post workflows for setup, execution, and postprocessing.7661 PyPI4Apache 2.0