MCP server wrapping FDMNES (X-ray spectroscopy ab-initio code) for natural-language driven workflows in Claude Code, Claude Desktop, and other MCP clients.
Project description
fdmnes-mcp
MCP (Model Context Protocol) server that wraps FDMNES — the ab-initio Fortran code for X-ray spectroscopy by Yves Joly at Institut Néel CNRS, Grenoble. Drive FDMNES through Claude Desktop, Claude Code, Codex CLI, Cline, or any other MCP-aware client with natural-language tool calls.
Build and validate input files, launch parallel mpirun fdmnes_mpi jobs asynchronously, poll status, fetch outputs, plot spectra, and look up any of FDMNES's ~350 input keywords from a source-grounded catalog — without ever leaving the chat.
About FDMNES. FDMNES (Finite Difference Method Near Edge Structure) computes XANES, EXAFS (via the FDMX extension), XMCD, RXS/DAFS, RIXS, NRIXS / X-Raman, optic, and emission spectra. Two solver engines: a 3D real-space finite-difference solver (full-potential) and a multiple-scattering Green's function (muffin-tin). Free download at https://fdmnes.neel.cnrs.fr/. This wrapper does NOT redistribute FDMNES itself — you install FDMNES separately.
Install
1. Install FDMNES
If you haven't already, grab FDMNES from https://fdmnes.neel.cnrs.fr/download/. You want either:
- the parallel Linux executable (
parallel_fdmneszip — recommended), or - the Fortran source + the MUMPS / ScaLAPACK / OpenMPI toolchain (build it yourself).
Make sure your FDMNES binary is executable (chmod +x <binary>) and ideally on $PATH. The MCP server autodetects it from $PATH, then from common install directories (~/fdmnes, ~/FDMNES, /opt/fdmnes, /usr/local/fdmnes); override with the FDMNES_BIN env var if needed.
2. Install fdmnes-mcp
From PyPI (recommended once a release is published):
pip install fdmnes-mcp
From GitHub main (bleeding edge):
pip install git+https://github.com/Joint-Photon-Sciences-Institute/fdmnes-mcp.git
From a local checkout (for development):
git clone https://github.com/Joint-Photon-Sciences-Institute/fdmnes-mcp.git
cd fdmnes-mcp
python3 -m venv .venv
.venv/bin/pip install -e .
After install, the fdmnes-mcp console script is on your $PATH and equivalent to python -m fdmnes_mcp.
3. Verify the wiring
fdmnes-mcp --info # or: python -m fdmnes_mcp --info
Prints the resolved paths and flags anything missing. Example output:
fdmnes-mcp configuration
========================
FDMNES binary : /usr/local/bin/fdmnes_mpi
exists / x-bit : True / True
Bundle directory : /opt/fdmnes/linux_bundle/fdmnes_Linux
exists : True
Examples directory : /opt/fdmnes/linux_bundle/fdmnes_Linux/Sim/Test_stand/in
exists : True
Docs directory : /.../site-packages/fdmnes_mcp/data/docs (packaged)
exists : True
Work directory : /home/you/fdmnes-jobs
mpirun default -np : 4
All paths resolved.
Register with your MCP client
Claude Code
claude mcp add fdmnes -- fdmnes-mcp
(If fdmnes-mcp isn't on your $PATH, use the absolute path returned by which fdmnes-mcp.)
Claude Desktop
Edit claude_desktop_config.json (location varies by OS: ~/Library/Application Support/Claude/ on macOS, %APPDATA%\Claude\ on Windows, ~/.config/Claude/ on Linux):
{
"mcpServers": {
"fdmnes": {
"command": "fdmnes-mcp"
}
}
}
To override defaults via environment variables:
{
"mcpServers": {
"fdmnes": {
"command": "fdmnes-mcp",
"env": {
"FDMNES_BIN": "/opt/fdmnes/fdmnes_mpi",
"FDMNES_MPI_DEFAULT_NP": "8"
}
}
}
}
Codex CLI
In your ~/.codex/config.toml:
[mcp_servers.fdmnes]
command = "fdmnes-mcp"
Cline (VS Code)
Edit cline_mcp_settings.json (Cline → MCP Servers → Configure):
{
"mcpServers": {
"fdmnes": {
"command": "fdmnes-mcp",
"transport": "stdio"
}
}
}
Any generic MCP client
Run the binary as a stdio server:
fdmnes-mcp
Quick start (Claude)
After registering, try:
List the bundled FDMNES examples, then run the Cu K-edge one on 4 ranks and plot the convolved spectrum when it finishes.
Claude will call (roughly):
fdmnes_list_examples→ seeCufdmnes_run_example(example_name="Cu", np=4)→ get ajob_idfdmnes_status(job_id)untilstatus == "completed"fdmnes_fetch_result(job_id)→ returns output pathsfdmnes_plot_spectrum(path=".../Cu_conv.txt")→ renders the spectrum
Or for a new material:
Scaffold an SCF XANES job for Fe₂O₃ at the Fe K-edge with Hubbard U = 5 eV under
~/jobs/fe2o3/, then run it on 8 ranks.
Configuration
All paths are auto-detected with sensible fallbacks. Override any of them via environment variables:
| Variable | Default | Purpose |
|---|---|---|
FDMNES_BIN |
autodetect from $PATH and common installs |
FDMNES binary (parallel or serial) |
FDMNES_BUNDLE_DIR |
autodetect | Directory with fdmfile.txt + Sim/Test_stand/ |
FDMNES_EXAMPLES_DIR |
$FDMNES_BUNDLE_DIR/Sim/Test_stand/in |
Bundled _inp.txt examples |
FDMNES_DOCS_DIR |
packaged docs | Override path to docs (keyword DB source) |
FDMNES_WORK_DIR |
~/fdmnes-jobs |
Default cwd for new jobs |
FDMNES_MPI_DEFAULT_NP |
4 |
Default -np for mpirun |
Call fdmnes_get_config inside a Claude session at any time to see what's currently active.
Tool reference
27 tools across 6 categories (+ 8 resources). See src/fdmnes_mcp/tools/ for implementations.
I/O & inspection
| Tool | Purpose |
|---|---|
fdmnes_get_config |
Show MCP paths + binary status |
fdmnes_list_examples |
List bundled _inp.txt examples |
fdmnes_read_input |
Parse an _inp.txt into structured blocks |
fdmnes_read_spectrum |
Read X.txt / X_conv.txt into arrays (auto-downsampled) |
fdmnes_summarise_spectrum |
Compact metadata-only view (no arrays) |
fdmnes_read_bav |
Extract release / point group / Symsite / SCF trace / Fermi level / parallel banner from a _bav.txt |
fdmnes_list_outputs |
List FDMNES output files under a prefix or directory |
Authoring
| Tool | Purpose |
|---|---|
fdmnes_keyword_lookup |
Look up a keyword (name or alias) → args, default, effect, source ref |
fdmnes_keyword_search |
Substring search across name / alias / effect text |
fdmnes_list_keyword_categories |
List the ~16 categories in the keyword DB |
fdmnes_validate_input |
Lint an _inp.txt against the keyword catalog |
fdmnes_build_input |
Build an _inp.txt from structured params |
Execution (async)
| Tool | Purpose |
|---|---|
fdmnes_run |
Launch mpirun fdmnes in the background → returns a job_id |
fdmnes_run_example |
One-shot: select a bundled example by name and launch |
fdmnes_status |
Poll job status + stdout/stderr tails |
fdmnes_list_jobs |
List all jobs launched in this session |
fdmnes_cancel_job |
Terminate a running job |
fdmnes_fetch_result |
Once a job completes, list its output files |
fdmnes_reconvolve |
Generate + run a convolution-only job that re-broadens an existing output |
Plotting
| Tool | Purpose |
|---|---|
fdmnes_plot_spectrum |
Render an FDMNES output to PNG (base64 + optional save path) |
fdmnes_compare_spectra |
Overlay multiple spectra with optional normalisation |
Workflow templates
| Tool | Purpose |
|---|---|
fdmnes_template_xanes |
Scaffold a basic XANES job (FDM or MS) |
fdmnes_template_scf_xanes |
XANES with SCF (and optional Hubbard U) |
fdmnes_template_fdmx_exafs |
EXAFS via FDMX (K-edge) |
fdmnes_template_rxs |
Resonant diffraction with one or more reflections |
fdmnes_template_xmcd |
Magnetic / XMCD with circular polarisation |
Escape hatch
| Tool | Purpose |
|---|---|
fdmnes_run_shell |
Run any shell command in the FDMNES workspace (sparingly) |
Resources
Read-only docs available at:
| URI | Content |
|---|---|
fdmnes://config |
Server config snapshot |
fdmnes://docs/methods |
FDM vs MST, DFT/TDDFT, defaults |
fdmnes://docs/io |
Input / output file structure |
fdmnes://docs/keywords |
Full keyword reference (large) |
fdmnes://docs/pipelines |
16 workflow recipes |
fdmnes://docs/examples |
Annotated catalog of bundled inputs |
fdmnes://docs/keyword/{name} |
Reference card for a single keyword |
Architecture
src/fdmnes_mcp/
├── __main__.py # entry point with --info / --help / --version
├── server.py # FastMCP setup + tool/resource registration
├── config.py # autodetection + env-var-driven paths
├── session.py # JobManager (asyncio subprocess registry)
├── parsers/
│ ├── input_parser.py # _inp.txt → structured blocks
│ ├── spectrum_parser.py # X.txt / X_conv.txt → numpy arrays
│ ├── bav_parser.py # _bav.txt → highlights
│ └── keyword_db.py # ~770-entry keyword DB (mined from packaged docs)
├── tools/
│ ├── io_tools.py
│ ├── authoring_tools.py
│ ├── execution_tools.py # async run / status / fetch
│ ├── plot_tools.py
│ ├── template_tools.py # workflow one-shots
│ └── shell_tools.py
├── resources/docs.py # fdmnes:// resource URIs
└── data/docs/ # packaged reference docs (markdown)
The keyword DB is mined from the shipped data/docs/keyword-reference.md at server startup. Override with FDMNES_DOCS_DIR to point at a different docs tree (e.g. a forked / extended catalog).
Citing FDMNES
If you publish results obtained with FDMNES (with or without this wrapper), the FDMNES author asks that you cite the following, as listed in the FDMNES User's Guide:
- Main FDMNES paper: O. Bunau and Y. Joly, J. Phys.: Condens. Matter 21, 345501 (2009).
- MUMPS-accelerated FDM: S. A. Guda et al., J. Chem. Theory Comput. 11, 4512-4521 (2015).
- FDMX EXAFS extension: J. D. Bourke, C. T. Chantler, Y. Joly, J. Synchrotron Rad. 23, 551-559 (2016).
- Surface RXD: Y. Joly et al., J. Chem. Theory Comput. 14, 973-980 (2018).
- X-Raman / NRIXS: Y. Joly, C. Cavallari, S. A. Guda, C. J. Sahle, J. Chem. Theory Comput. 13, 2172-2177 (2017).
- International Tables for Crystallography, Volume I (2021, 2022).
This wrapper does not need a separate citation, but a link or acknowledgement is appreciated:
FDMNES jobs were driven through the fdmnes-mcp wrapper (Joint Photon Sciences Institute, https://github.com/Joint-Photon-Sciences-Institute/fdmnes-mcp).
Contributing & releases
Issues and pull requests welcome at https://github.com/Joint-Photon-Sciences-Institute/fdmnes-mcp.
Release process (for maintainers):
- Bump
versioninpyproject.toml. - Commit, tag (
git tag v0.x.y), push the tag (git push --tags). - The
Publish to PyPIGitHub Actions workflow builds and publishes via PyPI Trusted Publishing. No API tokens needed in the repo — the project's PyPI page must be configured to trust this repo + workflow on first release (one-time setup).
License
This wrapper is released under the BSD 3-Clause License. FDMNES itself is independent software with its own distribution terms; see https://fdmnes.neel.cnrs.fr/ for FDMNES licensing questions.
Acknowledgements
Built in the style of xraylarch-mcp. Thanks to Yves Joly and the FDMNES developers for making the code freely available, and to the MCP / FastMCP authors for the protocol that makes wrappers like this trivial.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fdmnes_mcp-0.1.0.tar.gz.
File metadata
- Download URL: fdmnes_mcp-0.1.0.tar.gz
- Upload date:
- Size: 79.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c6aef14d7e5c3cdbf5ea77342fc3d57995a2fb27ee65d709c5a98399387aa9f0
|
|
| MD5 |
3340274470855db1976361f3d6d17849
|
|
| BLAKE2b-256 |
090c561aad5040550ffe8ac5f55031d569199b525ab89fd543942db78d9304f3
|
Provenance
The following attestation bundles were made for fdmnes_mcp-0.1.0.tar.gz:
Publisher:
publish.yml on Joint-Photon-Sciences-Institute/fdmnes-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fdmnes_mcp-0.1.0.tar.gz -
Subject digest:
c6aef14d7e5c3cdbf5ea77342fc3d57995a2fb27ee65d709c5a98399387aa9f0 - Sigstore transparency entry: 1583201818
- Sigstore integration time:
-
Permalink:
Joint-Photon-Sciences-Institute/fdmnes-mcp@c10966c3f87549c87434a4c4702a86d7360739c3 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Joint-Photon-Sciences-Institute
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c10966c3f87549c87434a4c4702a86d7360739c3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file fdmnes_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: fdmnes_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 86.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b37872805d42708d8b87f63cce9d454c94371ba838e0d8f6967001ecf95f9042
|
|
| MD5 |
bbb7fb704545f8d8ffbe66c02dca8d18
|
|
| BLAKE2b-256 |
1ce65c439c777754179afe596d7721819ea0bb224be9b0312d90d2d5242e505b
|
Provenance
The following attestation bundles were made for fdmnes_mcp-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on Joint-Photon-Sciences-Institute/fdmnes-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
fdmnes_mcp-0.1.0-py3-none-any.whl -
Subject digest:
b37872805d42708d8b87f63cce9d454c94371ba838e0d8f6967001ecf95f9042 - Sigstore transparency entry: 1583201980
- Sigstore integration time:
-
Permalink:
Joint-Photon-Sciences-Institute/fdmnes-mcp@c10966c3f87549c87434a4c4702a86d7360739c3 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Joint-Photon-Sciences-Institute
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c10966c3f87549c87434a4c4702a86d7360739c3 -
Trigger Event:
push
-
Statement type: