kratos-mcp-server 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. kratos_mcp_server-0.1.1/.github/workflows/ci.yml +53 -0
  2. kratos_mcp_server-0.1.1/.github/workflows/docs.yml +45 -0
  3. kratos_mcp_server-0.1.1/.github/workflows/release.yml +51 -0
  4. kratos_mcp_server-0.1.1/.gitignore +10 -0
  5. kratos_mcp_server-0.1.1/CLAUDE.md +115 -0
  6. kratos_mcp_server-0.1.1/LICENSE +21 -0
  7. kratos_mcp_server-0.1.1/PKG-INFO +99 -0
  8. kratos_mcp_server-0.1.1/README.md +86 -0
  9. kratos_mcp_server-0.1.1/docs/.vitepress/config.ts +59 -0
  10. kratos_mcp_server-0.1.1/docs/guide/architecture.md +117 -0
  11. kratos_mcp_server-0.1.1/docs/guide/connecting.md +87 -0
  12. kratos_mcp_server-0.1.1/docs/guide/getting-started.md +75 -0
  13. kratos_mcp_server-0.1.1/docs/guide/installation.md +88 -0
  14. kratos_mcp_server-0.1.1/docs/guide/mdpa-format.md +123 -0
  15. kratos_mcp_server-0.1.1/docs/guide/troubleshooting.md +95 -0
  16. kratos_mcp_server-0.1.1/docs/index.md +56 -0
  17. kratos_mcp_server-0.1.1/docs/tools/environment.md +152 -0
  18. kratos_mcp_server-0.1.1/docs/tools/index.md +37 -0
  19. kratos_mcp_server-0.1.1/docs/tools/mesh.md +79 -0
  20. kratos_mcp_server-0.1.1/docs/tools/postprocessing.md +70 -0
  21. kratos_mcp_server-0.1.1/docs/tools/prompts.md +43 -0
  22. kratos_mcp_server-0.1.1/docs/tools/resources.md +25 -0
  23. kratos_mcp_server-0.1.1/docs/tools/scaffolding.md +124 -0
  24. kratos_mcp_server-0.1.1/docs/tools/simulation.md +71 -0
  25. kratos_mcp_server-0.1.1/docs/tutorials/cantilever-beam.md +123 -0
  26. kratos_mcp_server-0.1.1/docs/tutorials/thermal-bar.md +90 -0
  27. kratos_mcp_server-0.1.1/package-lock.json +2346 -0
  28. kratos_mcp_server-0.1.1/package.json +14 -0
  29. kratos_mcp_server-0.1.1/pyproject.toml +37 -0
  30. kratos_mcp_server-0.1.1/src/kratos_mcp/__init__.py +0 -0
  31. kratos_mcp_server-0.1.1/src/kratos_mcp/bridge.py +144 -0
  32. kratos_mcp_server-0.1.1/src/kratos_mcp/jobs.py +232 -0
  33. kratos_mcp_server-0.1.1/src/kratos_mcp/kratos_env.py +178 -0
  34. kratos_mcp_server-0.1.1/src/kratos_mcp/logparse.py +88 -0
  35. kratos_mcp_server-0.1.1/src/kratos_mcp/mdpa.py +435 -0
  36. kratos_mcp_server-0.1.1/src/kratos_mcp/runner.py +115 -0
  37. kratos_mcp_server-0.1.1/src/kratos_mcp/server.py +43 -0
  38. kratos_mcp_server-0.1.1/src/kratos_mcp/source_catalog.py +141 -0
  39. kratos_mcp_server-0.1.1/src/kratos_mcp/templates/fluid_transient/Materials.json.tpl +16 -0
  40. kratos_mcp_server-0.1.1/src/kratos_mcp/templates/fluid_transient/ProjectParameters.json.tpl +95 -0
  41. kratos_mcp_server-0.1.1/src/kratos_mcp/templates/registry.json +211 -0
  42. kratos_mcp_server-0.1.1/src/kratos_mcp/templates/structural_dynamic/Materials.json.tpl +17 -0
  43. kratos_mcp_server-0.1.1/src/kratos_mcp/templates/structural_dynamic/ProjectParameters.json.tpl +75 -0
  44. kratos_mcp_server-0.1.1/src/kratos_mcp/templates/structural_modal/Materials.json.tpl +17 -0
  45. kratos_mcp_server-0.1.1/src/kratos_mcp/templates/structural_modal/ProjectParameters.json.tpl +55 -0
  46. kratos_mcp_server-0.1.1/src/kratos_mcp/templates/structural_static/Materials.json.tpl +17 -0
  47. kratos_mcp_server-0.1.1/src/kratos_mcp/templates/structural_static/ProjectParameters.json.tpl +69 -0
  48. kratos_mcp_server-0.1.1/src/kratos_mcp/templates/thermal_stationary/Materials.json.tpl +14 -0
  49. kratos_mcp_server-0.1.1/src/kratos_mcp/templates/thermal_stationary/ProjectParameters.json.tpl +88 -0
  50. kratos_mcp_server-0.1.1/src/kratos_mcp/templates/thermal_transient/Materials.json.tpl +14 -0
  51. kratos_mcp_server-0.1.1/src/kratos_mcp/templates/thermal_transient/ProjectParameters.json.tpl +85 -0
  52. kratos_mcp_server-0.1.1/src/kratos_mcp/tools/__init__.py +10 -0
  53. kratos_mcp_server-0.1.1/src/kratos_mcp/tools/environment.py +253 -0
  54. kratos_mcp_server-0.1.1/src/kratos_mcp/tools/mesh.py +130 -0
  55. kratos_mcp_server-0.1.1/src/kratos_mcp/tools/postprocess.py +166 -0
  56. kratos_mcp_server-0.1.1/src/kratos_mcp/tools/prompts.py +86 -0
  57. kratos_mcp_server-0.1.1/src/kratos_mcp/tools/resources.py +231 -0
  58. kratos_mcp_server-0.1.1/src/kratos_mcp/tools/scaffold.py +545 -0
  59. kratos_mcp_server-0.1.1/src/kratos_mcp/tools/simulation.py +97 -0
  60. kratos_mcp_server-0.1.1/src/kratos_mcp/worker.py +237 -0
  61. kratos_mcp_server-0.1.1/tests/conftest.py +23 -0
  62. kratos_mcp_server-0.1.1/tests/smoke_client.py +50 -0
  63. kratos_mcp_server-0.1.1/tests/test_bridge_integration.py +63 -0
  64. kratos_mcp_server-0.1.1/tests/test_jobs.py +92 -0
  65. kratos_mcp_server-0.1.1/tests/test_kratos_env.py +62 -0
  66. kratos_mcp_server-0.1.1/tests/test_logparse.py +45 -0
  67. kratos_mcp_server-0.1.1/tests/test_mdpa.py +110 -0
  68. kratos_mcp_server-0.1.1/tests/test_run_integration.py +121 -0
  69. kratos_mcp_server-0.1.1/tests/test_source_catalog.py +52 -0
  70. kratos_mcp_server-0.1.1/tests/test_templates.py +80 -0
  71. kratos_mcp_server-0.1.1/uv.lock +1326 -0
@@ -0,0 +1,53 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ name: Unit tests (Python ${{ matrix.python-version }})
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.12"]
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: astral-sh/setup-uv@v5
18
+ with:
19
+ python-version: ${{ matrix.python-version }}
20
+ - name: Install dependencies
21
+ run: uv sync
22
+ - name: Run unit tests (Kratos integration tests are skipped without a build)
23
+ run: uv run pytest -m "not kratos" -q
24
+
25
+ build-package:
26
+ name: Build Python package
27
+ runs-on: ubuntu-latest
28
+ needs: test
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+ - uses: astral-sh/setup-uv@v5
32
+ - name: Build sdist and wheel
33
+ run: uv build
34
+ - uses: actions/upload-artifact@v4
35
+ with:
36
+ name: python-package
37
+ path: dist/*
38
+
39
+ build-docs:
40
+ name: Build documentation
41
+ runs-on: ubuntu-latest
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+ - uses: actions/setup-node@v4
45
+ with:
46
+ node-version: 20
47
+ cache: npm
48
+ - run: npm ci
49
+ - run: npm run docs:build
50
+ - uses: actions/upload-artifact@v4
51
+ with:
52
+ name: docs-site
53
+ path: docs/.vitepress/dist
@@ -0,0 +1,45 @@
1
+ name: Deploy docs
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+ pages: write
11
+ id-token: write
12
+
13
+ concurrency:
14
+ group: pages
15
+ cancel-in-progress: false
16
+
17
+ jobs:
18
+ build:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ - uses: actions/setup-node@v4
23
+ with:
24
+ node-version: 20
25
+ cache: npm
26
+ - run: npm ci
27
+ - name: Build with VitePress
28
+ run: npm run docs:build
29
+ env:
30
+ # Serve from https://<user>.github.io/<repo>/
31
+ DOCS_BASE: /${{ github.event.repository.name }}/
32
+ - uses: actions/configure-pages@v5
33
+ - uses: actions/upload-pages-artifact@v3
34
+ with:
35
+ path: docs/.vitepress/dist
36
+
37
+ deploy:
38
+ needs: build
39
+ runs-on: ubuntu-latest
40
+ environment:
41
+ name: github-pages
42
+ url: ${{ steps.deployment.outputs.page_url }}
43
+ steps:
44
+ - id: deployment
45
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,51 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - uses: astral-sh/setup-uv@v5
13
+ - name: Run unit tests
14
+ run: uv sync && uv run pytest -m "not kratos" -q
15
+ - name: Build sdist and wheel
16
+ run: uv build
17
+ - uses: actions/upload-artifact@v4
18
+ with:
19
+ name: dist
20
+ path: dist/*
21
+
22
+ github-release:
23
+ needs: build
24
+ runs-on: ubuntu-latest
25
+ permissions:
26
+ contents: write
27
+ steps:
28
+ - uses: actions/download-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist
32
+ - name: Create GitHub release with artifacts
33
+ uses: softprops/action-gh-release@v2
34
+ with:
35
+ files: dist/*
36
+ generate_release_notes: true
37
+
38
+ publish-pypi:
39
+ # Publishes via PyPI trusted publishing; configure the 'pypi' environment
40
+ # and a trusted publisher on pypi.org before the first release.
41
+ needs: build
42
+ runs-on: ubuntu-latest
43
+ environment: pypi
44
+ permissions:
45
+ id-token: write
46
+ steps:
47
+ - uses: actions/download-artifact@v4
48
+ with:
49
+ name: dist
50
+ path: dist
51
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,10 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ dist/
5
+ *.egg-info/
6
+ .pytest_cache/
7
+ node_modules/
8
+ docs/.vitepress/dist/
9
+ docs/.vitepress/cache/
10
+ .cache/
@@ -0,0 +1,115 @@
1
+ # Kratos MCP Server
2
+
3
+ MCP (Model Context Protocol) server exposing Kratos Multiphysics to AI
4
+ assistants: installation introspection, case scaffolding (ProjectParameters /
5
+ Materials / MDPA meshes), simulation execution as background jobs, and VTK
6
+ post-processing. Python, `mcp` SDK (FastMCP), stdio transport.
7
+
8
+ ## Environment
9
+
10
+ A local compiled build is optional: `src/kratos_mcp/kratos_env.py` resolves
11
+ Kratos from, in order, an explicit `KRATOS_PYTHONPATH`/`KRATOS_LIBS`, a
12
+ `KRATOS_ROOT` build tree, or a pip-installed `KratosMultiphysics` importable
13
+ by the server's own interpreter.
14
+
15
+ - `KRATOS_ROOT` (default `/home/vicente/src/Kratos`) → uses
16
+ `$KRATOS_ROOT/bin/Release` as `PYTHONPATH` and `$KRATOS_ROOT/bin/Release/libs`
17
+ as `LD_LIBRARY_PATH`.
18
+ - Overrides: `KRATOS_PYTHONPATH`, `KRATOS_LIBS`, `KRATOS_SOURCE` (source tree
19
+ for macro parsing), `KRATOS_EXTRA_LIBS` (extra lib dirs; MKL under
20
+ `/opt/intel/oneapi/mkl/latest/lib` is auto-detected — LinearSolversApplication
21
+ needs `libmkl_rt.so.2`).
22
+ - **Pip fallback**: if no build tree resolves, `kratos_env.resolve()` probes
23
+ `python -c "import KratosMultiphysics"` in a subprocess. The `kratos_install`
24
+ tool (`tools/environment.py`) populates this by running `pip install` —
25
+ official wheels are `KratosMultiphysics` (core), `Kratos<AppName>` per
26
+ application (e.g. `KratosStructuralMechanicsApplication`), or
27
+ `KratosMultiphysics-all` (everything) — Linux/Windows x86_64 only, no macOS
28
+ wheels. `kratos_env.pip_install()`/`pypi_package_name()` do the mapping and
29
+ subprocess call; running pip itself is fine in the server process (it never
30
+ imports Kratos), unlike everything else Kratos-related.
31
+ - Manual incantation for ad-hoc Kratos scripts against a build tree:
32
+ `PYTHONPATH=$KRATOS_ROOT/bin/Release LD_LIBRARY_PATH=$KRATOS_ROOT/bin/Release/libs:/opt/intel/oneapi/mkl/latest/lib python3 ...`
33
+ - Server state (jobs, bridge cache) lives in `~/.kratos-mcp/`
34
+ (`KRATOS_MCP_HOME` overrides; tests set it to a tmp dir).
35
+
36
+ ## The one hard rule
37
+
38
+ **Never import KratosMultiphysics in the server process.** It prints an ASCII
39
+ banner on import (corrupts the stdio JSON-RPC stream) and its C++ core can
40
+ abort the process. All Kratos access goes through subprocesses:
41
+
42
+ - `bridge.py` → spawns `worker.py` for short ops (introspection, validation,
43
+ deep mdpa read). Results travel via a `--result-file` JSON file, never
44
+ stdout. Cacheable ops are cached on disk keyed by build fingerprint.
45
+ - `jobs.py` → spawns `runner.py` detached for simulations. Job state persists
46
+ in `~/.kratos-mcp/jobs/<id>/` (`meta.json` + `stdout.log`) and survives
47
+ server restarts; orphaned jobs are re-evaluated from pid liveness + log tail.
48
+
49
+ `worker.py` and `runner.py` are the ONLY modules that import Kratos, and they
50
+ only run inside subprocesses with the env vars injected.
51
+
52
+ ## Commands
53
+
54
+ - `uv sync` — install deps (`mcp`, `meshio`, `numpy`; dev: pytest)
55
+ - `uv run kratos-mcp` — run the server (stdio)
56
+ - `uv run pytest -m "not kratos"` — unit tests, no Kratos needed
57
+ - `uv run pytest -m kratos` — integration tests against the real build
58
+ (cantilever + thermal bar end-to-end with physics assertions)
59
+ - `uv run python tests/smoke_client.py` — scripted stdio MCP client smoke test
60
+ - `npm run docs:dev` / `npm run docs:build` — VitePress docs
61
+
62
+ ## Layout
63
+
64
+ - `src/kratos_mcp/server.py` — FastMCP instance + main()
65
+ - `src/kratos_mcp/tools/` — one module per tool category (`environment`,
66
+ `scaffold`, `mesh`, `simulation`, `postprocess`, `resources`, `prompts`),
67
+ each exposing `register(mcp)`; `register_all` in `__init__.py`
68
+ - `src/kratos_mcp/mdpa.py` — pure-Python MDPA parse/write/inspect/validate +
69
+ structured mesh generators (line/rectangle/box with named boundary parts)
70
+ - `src/kratos_mcp/source_catalog.py` — parses `KRATOS_REGISTER_ELEMENT/
71
+ CONDITION/CONSTITUTIVE_LAW` macros from the Kratos C++ sources (there is no
72
+ runtime registry for these)
73
+ - `src/kratos_mcp/templates/` — case templates as data: `registry.json`
74
+ (metadata + placeholder defaults) + `<name>/ProjectParameters.json.tpl` +
75
+ `Materials.json.tpl`. Substitution: quoted `"{{key}}"` → JSON-typed value,
76
+ bare `{{key}}` → text.
77
+ - `src/kratos_mcp/logparse.py` — step/convergence extraction from job logs
78
+
79
+ ## Kratos gotchas learned the hard way
80
+
81
+ - Load-bearing conditions must be the `*LoadCondition*` types
82
+ (`LineLoadCondition2D2N`, `SurfaceLoadCondition3D4N`); the generic
83
+ `LineCondition2D2N`/`SurfaceCondition3D4N` are geometric dummies that
84
+ silently contribute nothing (zero RHS, zero displacement).
85
+ - The convection-diffusion solver REPLACES mesh elements at import
86
+ (`element_replace_settings`); thermal meshes use generic `Element2D3N` +
87
+ `ThermalFace2D2N`. It must be a simplex mesh (triangles/tets) — its
88
+ `TetrahedralMeshOrientationCheck` fails on quads with "condition without
89
+ any corresponding element".
90
+ - `solver_type: stationary` still defaults to the transient EulerianConvDiff
91
+ element; true steady state needs `element_replace_settings: {"element_name":
92
+ "LaplacianElement", ...}` (our `thermal_stationary` template does this).
93
+ - Static analyses run exactly one step via `time_step: 1.1 > end_time: 1.0`
94
+ (standard Kratos test convention).
95
+ - `Kernel.Get*VariableNames()` return one newline-separated string, not lists.
96
+ - `KM.Parameters` tolerates `//` comments; plain `json.loads` on Kratos test
97
+ files may fail.
98
+ - Kratos resolves mdpa/materials paths relative to the CWD → `runner.py`
99
+ chdirs into the case directory.
100
+
101
+ ## Conventions
102
+
103
+ - All server logging to stderr (stdout is the MCP transport).
104
+ - Tools return plain dicts; errors as `{"error": ...}` rather than raising
105
+ (bridge failures include worker stdout/stderr tails for diagnosis).
106
+ - Blocking work inside async tools goes through `anyio.to_thread.run_sync`.
107
+ - Tool inputs/outputs use absolute paths.
108
+ - Reference cases used for templates/tests:
109
+ `applications/StructuralMechanicsApplication/tests/LinearTruss2D/2D2N/` and
110
+ `applications/ConvectionDiffusionApplication/tests/basic_conv_diffusion_test/`
111
+ in the Kratos tree.
112
+
113
+ ## Keep docs in sync
114
+
115
+ Every time you change code in this repo, check whether doc/, README.md, and this file need updating too — and update them if they do. Treat doc drift as part of the change, not a follow-up.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vicente Mataix Ferrándiz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,99 @@
1
+ Metadata-Version: 2.4
2
+ Name: kratos-mcp-server
3
+ Version: 0.1.1
4
+ Summary: MCP server for Kratos Multiphysics: scaffold, run and post-process finite element simulations
5
+ Author: Vicente Mataix Ferrándiz
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.10
9
+ Requires-Dist: mcp>=1.2
10
+ Requires-Dist: meshio>=5.3
11
+ Requires-Dist: numpy>=1.26
12
+ Description-Content-Type: text/markdown
13
+
14
+ # Kratos MCP Server
15
+
16
+ [![CI](https://github.com/loumalouomega/Kratos-MCP-Server/actions/workflows/ci.yml/badge.svg)](https://github.com/loumalouomega/Kratos-MCP-Server/actions/workflows/ci.yml)
17
+ [![Deploy docs](https://github.com/loumalouomega/Kratos-MCP-Server/actions/workflows/docs.yml/badge.svg)](https://loumalouomega.github.io/Kratos-MCP-Server/)
18
+ [![Release](https://github.com/loumalouomega/Kratos-MCP-Server/actions/workflows/release.yml/badge.svg)](https://github.com/loumalouomega/Kratos-MCP-Server/releases)
19
+ [![PyPI](https://img.shields.io/pypi/v/kratos-mcp-server.svg)](https://pypi.org/project/kratos-mcp-server/)
20
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
21
+ [![License: MIT](https://img.shields.io/github/license/loumalouomega/Kratos-MCP-Server)](LICENSE)
22
+
23
+ An [MCP](https://modelcontextprotocol.io) server that lets AI assistants drive
24
+ [Kratos Multiphysics](https://github.com/KratosMultiphysics/Kratos) finite
25
+ element simulations end to end:
26
+
27
+ - **Introspect** the installation: applications, elements, conditions,
28
+ constitutive laws, variables, solvers and their default parameters.
29
+ - **Scaffold** simulation cases from templates: structural
30
+ (static/dynamic/modal), thermal (transient/stationary) and fluid
31
+ (transient incompressible) — ProjectParameters.json, Materials.json and
32
+ structured MDPA meshes with named boundary regions.
33
+ - **Run** simulations as managed background jobs (status, live logs,
34
+ progress, cancel) that survive server restarts.
35
+ - **Post-process** VTK results: summaries, point probes, convergence
36
+ analysis.
37
+
38
+ 31 tools, 7 resources and 4 guided prompts. See the full documentation in
39
+ [`docs/`](docs/) (VitePress).
40
+
41
+ ## Quick start
42
+
43
+ A local Kratos build is **not required** — the server can pip-install
44
+ Kratos itself on first use.
45
+
46
+ **Once published to PyPI**, no clone needed — `uvx` fetches and runs it:
47
+
48
+ ```bash
49
+ claude mcp add kratos -- uvx kratos-mcp-server
50
+ ```
51
+
52
+ **From a local checkout** (current state, before the first PyPI release):
53
+
54
+ ```bash
55
+ git clone https://github.com/loumalouomega/Kratos-MCP-Server
56
+ cd Kratos-MCP-Server
57
+ uv sync
58
+ claude mcp add kratos -- uv --directory "$PWD" run kratos-mcp
59
+ ```
60
+
61
+ Then ask your assistant something like:
62
+
63
+ > Check the Kratos installation — install it if it's missing — then set up
64
+ > a cantilever plate 1 m × 0.2 m fixed on the left with a 1 MN/m downward
65
+ > load on the right edge, run it, and report the tip deflection.
66
+
67
+ The assistant calls `kratos_install` the first time and reuses it afterwards.
68
+ If you already have a compiled Kratos checkout, skip that and point
69
+ `KRATOS_ROOT` at it instead (`-e KRATOS_ROOT=/path/to/Kratos` on the `claude
70
+ mcp add` line) — see [Installation](docs/guide/installation.md).
71
+
72
+ ## Requirements
73
+
74
+ - Python ≥ 3.10, [uv](https://docs.astral.sh/uv/)
75
+ - Kratos Multiphysics, either pip-installed via `kratos_install`
76
+ (Linux/Windows x86_64 only — no macOS wheels) or a compiled build (tested
77
+ with 10.4, StructuralMechanics / ConvectionDiffusion / FluidDynamics /
78
+ LinearSolvers applications)
79
+
80
+ ## Architecture in one paragraph
81
+
82
+ Kratos is never imported in the server process — it prints a banner on import
83
+ (which would corrupt the stdio JSON-RPC stream) and can abort the process on
84
+ solver errors. Short operations run in a **worker** subprocess that returns
85
+ JSON through a result file; simulations run **detached** with per-job
86
+ directories under `~/.kratos-mcp/jobs/`. See
87
+ [docs/guide/architecture.md](docs/guide/architecture.md).
88
+
89
+ ## Development
90
+
91
+ ```bash
92
+ uv run pytest -m "not kratos" # unit tests (no Kratos needed)
93
+ uv run pytest -m kratos # integration tests against the real build
94
+ npm install && npm run docs:dev # documentation site
95
+ ```
96
+
97
+ ## License
98
+
99
+ [MIT](LICENSE)
@@ -0,0 +1,86 @@
1
+ # Kratos MCP Server
2
+
3
+ [![CI](https://github.com/loumalouomega/Kratos-MCP-Server/actions/workflows/ci.yml/badge.svg)](https://github.com/loumalouomega/Kratos-MCP-Server/actions/workflows/ci.yml)
4
+ [![Deploy docs](https://github.com/loumalouomega/Kratos-MCP-Server/actions/workflows/docs.yml/badge.svg)](https://loumalouomega.github.io/Kratos-MCP-Server/)
5
+ [![Release](https://github.com/loumalouomega/Kratos-MCP-Server/actions/workflows/release.yml/badge.svg)](https://github.com/loumalouomega/Kratos-MCP-Server/releases)
6
+ [![PyPI](https://img.shields.io/pypi/v/kratos-mcp-server.svg)](https://pypi.org/project/kratos-mcp-server/)
7
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
8
+ [![License: MIT](https://img.shields.io/github/license/loumalouomega/Kratos-MCP-Server)](LICENSE)
9
+
10
+ An [MCP](https://modelcontextprotocol.io) server that lets AI assistants drive
11
+ [Kratos Multiphysics](https://github.com/KratosMultiphysics/Kratos) finite
12
+ element simulations end to end:
13
+
14
+ - **Introspect** the installation: applications, elements, conditions,
15
+ constitutive laws, variables, solvers and their default parameters.
16
+ - **Scaffold** simulation cases from templates: structural
17
+ (static/dynamic/modal), thermal (transient/stationary) and fluid
18
+ (transient incompressible) — ProjectParameters.json, Materials.json and
19
+ structured MDPA meshes with named boundary regions.
20
+ - **Run** simulations as managed background jobs (status, live logs,
21
+ progress, cancel) that survive server restarts.
22
+ - **Post-process** VTK results: summaries, point probes, convergence
23
+ analysis.
24
+
25
+ 31 tools, 7 resources and 4 guided prompts. See the full documentation in
26
+ [`docs/`](docs/) (VitePress).
27
+
28
+ ## Quick start
29
+
30
+ A local Kratos build is **not required** — the server can pip-install
31
+ Kratos itself on first use.
32
+
33
+ **Once published to PyPI**, no clone needed — `uvx` fetches and runs it:
34
+
35
+ ```bash
36
+ claude mcp add kratos -- uvx kratos-mcp-server
37
+ ```
38
+
39
+ **From a local checkout** (current state, before the first PyPI release):
40
+
41
+ ```bash
42
+ git clone https://github.com/loumalouomega/Kratos-MCP-Server
43
+ cd Kratos-MCP-Server
44
+ uv sync
45
+ claude mcp add kratos -- uv --directory "$PWD" run kratos-mcp
46
+ ```
47
+
48
+ Then ask your assistant something like:
49
+
50
+ > Check the Kratos installation — install it if it's missing — then set up
51
+ > a cantilever plate 1 m × 0.2 m fixed on the left with a 1 MN/m downward
52
+ > load on the right edge, run it, and report the tip deflection.
53
+
54
+ The assistant calls `kratos_install` the first time and reuses it afterwards.
55
+ If you already have a compiled Kratos checkout, skip that and point
56
+ `KRATOS_ROOT` at it instead (`-e KRATOS_ROOT=/path/to/Kratos` on the `claude
57
+ mcp add` line) — see [Installation](docs/guide/installation.md).
58
+
59
+ ## Requirements
60
+
61
+ - Python ≥ 3.10, [uv](https://docs.astral.sh/uv/)
62
+ - Kratos Multiphysics, either pip-installed via `kratos_install`
63
+ (Linux/Windows x86_64 only — no macOS wheels) or a compiled build (tested
64
+ with 10.4, StructuralMechanics / ConvectionDiffusion / FluidDynamics /
65
+ LinearSolvers applications)
66
+
67
+ ## Architecture in one paragraph
68
+
69
+ Kratos is never imported in the server process — it prints a banner on import
70
+ (which would corrupt the stdio JSON-RPC stream) and can abort the process on
71
+ solver errors. Short operations run in a **worker** subprocess that returns
72
+ JSON through a result file; simulations run **detached** with per-job
73
+ directories under `~/.kratos-mcp/jobs/`. See
74
+ [docs/guide/architecture.md](docs/guide/architecture.md).
75
+
76
+ ## Development
77
+
78
+ ```bash
79
+ uv run pytest -m "not kratos" # unit tests (no Kratos needed)
80
+ uv run pytest -m kratos # integration tests against the real build
81
+ npm install && npm run docs:dev # documentation site
82
+ ```
83
+
84
+ ## License
85
+
86
+ [MIT](LICENSE)
@@ -0,0 +1,59 @@
1
+ import { defineConfig } from 'vitepress'
2
+
3
+ export default defineConfig({
4
+ title: 'Kratos MCP Server',
5
+ description:
6
+ 'MCP server for Kratos Multiphysics: scaffold, run and post-process finite element simulations from AI assistants',
7
+ base: process.env.DOCS_BASE ?? '/',
8
+ themeConfig: {
9
+ nav: [
10
+ { text: 'Guide', link: '/guide/getting-started' },
11
+ { text: 'Tools', link: '/tools/' },
12
+ { text: 'Tutorials', link: '/tutorials/cantilever-beam' },
13
+ ],
14
+ sidebar: {
15
+ '/guide/': [
16
+ {
17
+ text: 'Guide',
18
+ items: [
19
+ { text: 'Getting started', link: '/guide/getting-started' },
20
+ { text: 'Installation', link: '/guide/installation' },
21
+ { text: 'Connecting a client', link: '/guide/connecting' },
22
+ { text: 'Architecture', link: '/guide/architecture' },
23
+ { text: 'The MDPA mesh format', link: '/guide/mdpa-format' },
24
+ { text: 'Troubleshooting', link: '/guide/troubleshooting' },
25
+ ],
26
+ },
27
+ ],
28
+ '/tools/': [
29
+ {
30
+ text: 'Tool reference',
31
+ items: [
32
+ { text: 'Overview', link: '/tools/' },
33
+ { text: 'Environment & introspection', link: '/tools/environment' },
34
+ { text: 'Project scaffolding', link: '/tools/scaffolding' },
35
+ { text: 'Meshes (MDPA)', link: '/tools/mesh' },
36
+ { text: 'Simulation & jobs', link: '/tools/simulation' },
37
+ { text: 'Post-processing', link: '/tools/postprocessing' },
38
+ { text: 'Resources', link: '/tools/resources' },
39
+ { text: 'Prompts', link: '/tools/prompts' },
40
+ ],
41
+ },
42
+ ],
43
+ '/tutorials/': [
44
+ {
45
+ text: 'Tutorials',
46
+ items: [
47
+ { text: 'Cantilever beam', link: '/tutorials/cantilever-beam' },
48
+ { text: 'Thermal bar', link: '/tutorials/thermal-bar' },
49
+ ],
50
+ },
51
+ ],
52
+ },
53
+ socialLinks: [
54
+ { icon: 'github', link: 'https://github.com/KratosMultiphysics/Kratos' },
55
+ ],
56
+ search: { provider: 'local' },
57
+ outline: [2, 3],
58
+ },
59
+ })
@@ -0,0 +1,117 @@
1
+ # Architecture
2
+
3
+ ## The core constraint
4
+
5
+ Kratos cannot run inside the MCP server process, for three reasons:
6
+
7
+ 1. **stdout is sacred.** MCP over stdio uses stdout for JSON-RPC framing, and
8
+ `import KratosMultiphysics` prints a multi-line ASCII banner to stdout.
9
+ One import would corrupt the protocol stream.
10
+ 2. **Crashes.** Kratos is a C++ core; a solver bug or bad input can abort the
11
+ whole process (segfault). The server must survive that.
12
+ 3. **Environment.** A build-tree Kratos needs `PYTHONPATH` and
13
+ `LD_LIBRARY_PATH` set *before* the interpreter starts — too late for a
14
+ process that is already running.
15
+
16
+ So the server process never imports Kratos. Two subprocess mechanisms cover
17
+ all Kratos access:
18
+
19
+ ```
20
+ ┌──────────────────────────────┐
21
+ │ MCP client (Claude, ...) │
22
+ └──────────────┬───────────────┘
23
+ │ stdio JSON-RPC
24
+ ┌──────────────▼───────────────┐
25
+ │ kratos-mcp server (FastMCP) │ never imports Kratos
26
+ │ tools/ · mdpa.py · jobs.py │
27
+ └─────┬───────────────────┬────┘
28
+ │ bridge.run_op() │ jobs.start()
29
+ │ (sync, seconds) │ (detached, minutes-hours)
30
+ ┌─────▼─────────┐ ┌─────▼─────────┐
31
+ │ worker.py │ │ runner.py │ both import Kratos,
32
+ │ introspection│ │ AnalysisStage│ env vars injected
33
+ │ validation │ │ .Run() │
34
+ └───────────────┘ └───────────────┘
35
+ ```
36
+
37
+ ## Getting Kratos itself
38
+
39
+ `kratos_env.resolve()` finds Kratos in one of three ways, in order: an
40
+ explicit `KRATOS_PYTHONPATH`/`KRATOS_LIBS` override, a `KRATOS_ROOT`
41
+ checkout with a compiled `bin/Release`, or a **pip-installed**
42
+ `KratosMultiphysics` importable by the server's own interpreter — probed in
43
+ a subprocess so a missing package fails safely instead of raising in the
44
+ server process. That third path is what `kratos_env.pip_install()` and the
45
+ `kratos_install` tool populate: they run `pip install` (never Kratos itself)
46
+ directly in the server process — safe, since pip does not import
47
+ Kratos — installing the official `KratosMultiphysics` / `Kratos<AppName>` /
48
+ `KratosMultiphysics-all` wheels (Linux/Windows x86_64 only). Once installed,
49
+ the very next `resolve()` call picks it up automatically; no restart needed.
50
+ A local build always takes priority when both are present.
51
+
52
+ ## The bridge (short operations)
53
+
54
+ `bridge.run_op(op, args)` spawns `python -m kratos_mcp.worker` with the Kratos
55
+ environment injected and a JSON request file. The worker writes its result to
56
+ a **result file** — never stdout — so banners and solver chatter cannot
57
+ corrupt it; stdout/stderr are captured and attached to error messages.
58
+
59
+ Ops: `check`, `list_applications`, `list_variables`, `has_constitutive_laws`,
60
+ `get_solver_defaults`, `validate_parameters`, `read_mdpa_deep`.
61
+
62
+ Because each spawn costs one to a few seconds, results of build-dependent ops
63
+ are cached in `~/.kratos-mcp/cache/`, keyed by `(op, args, build
64
+ fingerprint)` — editing or rebuilding Kratos invalidates the cache
65
+ automatically.
66
+
67
+ ## Jobs (simulations)
68
+
69
+ `jobs.start()` launches `python -m kratos_mcp.runner --case-dir ...` fully
70
+ detached (own session), with everything persisted under
71
+ `~/.kratos-mcp/jobs/<job_id>/`:
72
+
73
+ ```
74
+ 20260712-101530-a1b2c3/
75
+ ├── meta.json # state machine: queued → running → succeeded|failed|cancelled
76
+ └── stdout.log # combined solver output
77
+ ```
78
+
79
+ - **Status** is recomputed from the process return code, or — after a server
80
+ restart, when the child handle is gone — from pid liveness plus the
81
+ AnalysisStage end banner in the log.
82
+ - **Progress** (`current_step`, `current_time`) is parsed from the
83
+ `STEP:`/`TIME:` lines AnalysisStage prints each step.
84
+ - **Cancel** sends SIGTERM to the job's process group and escalates to
85
+ SIGKILL after a grace period.
86
+
87
+ The runner picks the analysis class from the `analysis_stage` key in
88
+ ProjectParameters.json (the convention used by Kratos itself and by all our
89
+ templates), from an explicit `analysis_type`/`analysis_class` argument, or by
90
+ inferring it from `solver_type`.
91
+
92
+ ## Hybrid introspection
93
+
94
+ What the tools report comes from two sources:
95
+
96
+ - **Runtime** (authoritative for *your build*): version, compiled
97
+ applications, variables, constitutive-law existence, solver default
98
+ parameters — via the bridge.
99
+ - **Source parsing**: element/condition/constitutive-law catalogs are parsed
100
+ from `KRATOS_REGISTER_*` macros in the C++ sources, because Kratos has no
101
+ runtime listing for them. Entries are flagged `compiled: true/false` by
102
+ cross-referencing the compiled application list.
103
+
104
+ ## Pure-Python MDPA layer
105
+
106
+ `mdpa.py` parses, writes, validates and generates `.mdpa` meshes without
107
+ Kratos, so mesh tools work even where no build is available and unit tests
108
+ run anywhere. `mdpa_validate(deep=true)` additionally round-trips the file
109
+ through the real `ModelPartIO` in a worker.
110
+
111
+ ## Templates as data
112
+
113
+ Case templates live in `src/kratos_mcp/templates/` as JSON files with
114
+ `{{placeholder}}` markers plus a `registry.json` describing defaults,
115
+ required applications and solver modules. Substitution is typed: a quoted
116
+ `"{{key}}"` becomes the JSON encoding of the value (numbers stay numbers,
117
+ arrays stay arrays); a bare `{{key}}` inside a longer string is textual.