inspire-mcp
# inspire-mcp
A small [Model Context Protocol](https://modelcontextprotocol.io) (stdio) server that lets an AI agent
(Cursor, Codex, Claude Desktop, ...) drive **Altair Inspire** on Windows through Inspire's
official **headless batch mode** and its Python API (`hwx.inspire`).
> Unofficial. Not affiliated with or endorsed by Altair. You need your own licensed Inspire install.
**Tested with:** Altair Inspire **2026.0** (release file `2026`, embedded Python 3.10.18) on Windows 11,
`mcp` 1.30 (Python 3.13 venv), Cursor CLI and its MCP client.
## How it works
Each tool call writes a small Python script into a fresh run folder and launches
```
<Inspire>\hwx\bin\win64\ExecWinEnvInsp.exe -cfg -b -p Inspire -ex hwx.exe -f <run>\task.py
```
The script runs inside Inspire's own interpreter with `from hwx import inspire` available, writes
`result.json`, and Inspire exits. Consequences:
- No GUI is opened and an Inspire window you already have open is **never touched**.
- No state is kept between calls (each call is a new process, ~2-15 s startup, longer for big models).
Save to a `.stmod` if you need to continue in a later call.
- On timeout, only the batch process tree started by that call is terminated.
- Calls are serialized (one Inspire batch process at a time per server).
- Each run folder keeps `user_code.py`, `args.json`, `result.json`, `stdout.log`, `stderr.log`.
## Tools
| Tool | What it does |
|---|---|
| `inspire_status` | Is Inspire found, install root, release/version, batch executor path, running Inspire processes, free RAM. Does not start Inspire. |
| `inspire_run_python(code, timeout_s=300)` | Run arbitrary Python inside a fresh headless Inspire. Names provided: `inspire`, `RUN_DIR`. Assign `result = ...` to return JSON-able data; `print()` output is returned as `stdout`; exceptions come back with a traceback. |
| `inspire_model_info(path, units="MKS")` | Open a model read-only (`.stmod`, `.fem`, other importable formats) and list parts (min bounding box, mass, volume, material, sheet thickness), load cases, loads, contact count. |
| `inspire_h3d_summary(path, fields=None, units="MKS")` | Open an OptiStruct `.h3d` result and return, per run, all available result types and min/max with positions for the requested fields (default `Displacement`, `von Mises Stress`). |
| `inspire_export_optistruct(model_path, output_fem, element_size_m=None, load_cases=None, run_name=None, timeout_s=900)` | Export an OptiStruct input deck (`.fem`) via `inspire.OptiStructAnalysis.export`. Refuses to overwrite. Does not run the solver. |
Example for `inspire_run_python`:
```python
m = inspire.newModel()
m.createSolidBlock(x=0.02, y=0.01, z=0.005)
b = inspire.geometry.minBoundingBox(m.parts)
result = {"parts": len(m.parts), "bbox_m": [b.x, b.y, b.z]}
```
API reference: <https://help.altair.com/inspire/inspireapi/index.html>
## Install
Requires Windows, Altair Inspire with a working license, and Python 3.10+ for the server itself
(the server does **not** need Inspire's Python; it just launches Inspire).
```powershell
git clone https://github.com/zchenjun88-hash/inspire-mcp.git
cd inspire-mcp
python -m venv venv
.\venv\Scripts\python.exe -m pip install -r requirements.txt
# quick check: prints status and runs a tiny script inside Inspire
.\venv\Scripts\python.exe inspire_mcp_server.py --self-test
```
### Finding Inspire
In this order:
1. `--inspire-root <path>` command-line argument
2. `INSPIRE_ROOT` environment variable
3. Auto-detect on all drives: `X:\Altair Inspire*\Inspire*\`, `X:\Program Files\Altair\*\Inspire*\`,
`X:\Program Files\Altair\*\`, `X:\Altair\*\Inspire*\`
The path may be the install root (e.g. `C:\Program Files\Altair\2026`), the `Inspire2026` folder,
or `ExecWinEnvInsp.exe` itself.
Run folders go to `--runs-dir`, else `INSPIRE_MCP_RUNS`, else `./runs` next to the script.
Keep this path ASCII-only (see Known issues).
### Cursor
`%USERPROFILE%\.cursor\mcp.json`:
```json
{
"mcpServers": {
"inspire": {
"command": "C:\\path\\to\\inspire-mcp\\venv\\Scripts\\python.exe",
"args": ["-u", "C:\\path\\to\\inspire-mcp\\inspire_mcp_server.py",
"--inspire-root", "C:\\Program Files\\Altair\\2026"]
}
}
}
```
For the Cursor CLI (`agent`), you can pre-approve the tools by adding `"Mcp(inspire:*)"` to
`permissions.allow` in `%USERPROFILE%\.cursor\cli-config.json`, then check with `agent mcp list`.
### Codex
`%USERPROFILE%\.codex\config.toml`:
```toml
[mcp_servers.inspire]
command = 'C:\path\to\inspire-mcp\venv\Scripts\python.exe'
args = ['-u', 'C:\path\to\inspire-mcp\inspire_mcp_server.py']
env = { INSPIRE_ROOT = 'C:\Program Files\Altair\2026' }
startup_timeout_sec = 30
tool_timeout_sec = 900 # exports of large models can take minutes
```
### Other clients
Any MCP client that can launch a stdio server works: command = the venv `python.exe`,
args = `inspire_mcp_server.py` plus optional `--inspire-root`.
## Known issues / limits
- **Non-ASCII output paths hang OptiStruct export** (observed on Inspire 2026: the batch process
idles forever when the `.fem` target folder contains e.g. Chinese characters). The export tool
therefore exports into an ASCII-only staging folder (inside the runs dir, or `%SystemDrive%\inspire_mcp_stage`)
and copies the deck to your requested path. Opening models from non-ASCII paths worked fine.
If you write your own export code with `inspire_run_python`, use ASCII paths.
- Not a live-GUI bridge: it cannot see or change the model currently open in your Inspire window.
- `inspire_h3d_summary` reads the first subcase/step; field names must match the names listed
in `available` (shell models, for instance, may not expose `von Mises Stress`).
- `inspire_run_python` executes arbitrary code with your user's permissions. Only connect it to
agents you trust and review what they run.
- Some MCP clients have short default tool timeouts (Codex: 60 s). Raise them for exports.
## 中文说明
这是一个让 AI 助手(Cursor、Codex 等)通过 MCP 操作 **Altair Inspire** 的小服务。原理是调用 Inspire 官方的
无界面批处理(`ExecWinEnvInsp.exe -cfg -b -p Inspire -ex hwx.exe -f 脚本.py`),在 Inspire 自带的 Python 里执行
`hwx.inspire` 接口。每次调用都是一个全新的后台 Inspire 进程,不会打开界面,也不会碰你已经开着的 Inspire 窗口;
调用之间不保留状态,需要接着做的请先保存成 `.stmod`。
已测试版本:Altair Inspire 2026.0(Windows 11)。工具:`inspire_status`(安装/版本状态)、
`inspire_run_python`(在 Inspire 里跑任意 Python,给 `result` 赋值即可返回)、`inspire_model_info`(读取模型的零件、
材料、载荷工况)、`inspire_h3d_summary`(读取 .h3d 结果的最大/最小值)、`inspire_export_optistruct`(导出 OptiStruct .fem)。
安装:`python -m venv venv`,`venv\Scripts\python.exe -m pip install -r requirements.txt`,然后按上面的
Cursor / Codex 配置登记。Inspire 安装路径可用 `--inspire-root` 参数或 `INSPIRE_ROOT` 环境变量指定,不指定会自动搜索。
注意:导出路径含中文时 Inspire 2026 的 OptiStruct 导出会卡死,本工具已自动先导出到纯英文临时目录再复制过去;
自己写导出脚本时请用纯英文路径。需要有效的 Inspire 许可证。
## License
MIT, see [LICENSE](LICENSE).
TDQS
Scored across 5 tools
Each tool targets a distinct stage of the headless Inspire workflow: status check, Python execution, model inspection, result reading, and OptiStruct export. The main overlap is that inspire_run_python is a generic escape hatch that could technically replicate model_info, h3d_summary, or export, but the dedicated tools' descriptions make their intended scope clear.
All five tools share the inspire_ prefix and snake_case, giving a predictable namespace. Minor deviation: three names are noun-style (status, model_info, h3d_summary) while two are verb_noun (run_python, export_optistruct), so the verb convention isn't fully uniform.
Five tools is well within the ideal 3-15 range and each covers a distinct workflow need without redundancy. The generic run_python handles arbitrary scripting, so no bloat of convenience wrappers is needed.
The surface covers discovery, execution, model inspection, results extraction, and export — a coherent lifecycle for headless Inspire automation. Gaps remain: there is no dedicated tool to run the solver (export explicitly does not solve) and no model save/conversion flow, though inspire_run_python can bridge most of these.