fdmnes-mcp
Enables running FDMNES X-ray spectroscopy simulations via natural language, supporting input file creation, job execution, output analysis, and keyword lookup through MCP-aware clients.
README
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.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.