Skip to main content

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

License: BSD-3-Clause Python 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_fdmnes zip — 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):

  1. fdmnes_list_examples → see Cu
  2. fdmnes_run_example(example_name="Cu", np=4) → get a job_id
  3. fdmnes_status(job_id) until status == "completed"
  4. fdmnes_fetch_result(job_id) → returns output paths
  5. fdmnes_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):

  1. Bump version in pyproject.toml.
  2. Commit, tag (git tag v0.x.y), push the tag (git push --tags).
  3. The Publish to PyPI GitHub 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fdmnes_mcp-0.1.0.tar.gz (79.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fdmnes_mcp-0.1.0-py3-none-any.whl (86.1 kB view details)

Uploaded Python 3

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

Hashes for fdmnes_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c6aef14d7e5c3cdbf5ea77342fc3d57995a2fb27ee65d709c5a98399387aa9f0
MD5 3340274470855db1976361f3d6d17849
BLAKE2b-256 090c561aad5040550ffe8ac5f55031d569199b525ab89fd543942db78d9304f3

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for fdmnes_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b37872805d42708d8b87f63cce9d454c94371ba838e0d8f6967001ecf95f9042
MD5 bbb7fb704545f8d8ffbe66c02dca8d18
BLAKE2b-256 1ce65c439c777754179afe596d7721819ea0bb224be9b0312d90d2d5242e505b

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page