MCP server (crystod-mcp)#

The CrystOD analyses as tools for an AI assistant. crystod-mcp is a Model Context Protocol server, shipped as a separate package in the crystod-mcp/ directory of the repository, that lets Claude Desktop, Claude Code, or any MCP client call CrystOD directly: ask “which space groups can the R-point instability of SrTiO3 condense into?” and the assistant runs crystod_isotropy_subgroups (or the full phonon workflow) and answers with the table.

I want to …

tool

list the isotropy subgroups of an irrep

crystod_isotropy_subgroups

decompose a product of irreps

crystod_irrep_product

reduce a representation from its characters

crystod_decompose_representation

see how an orbital shell splits in a ligand field

crystod_ligand_field

read a character table (point group, or little group of k)

crystod_character_table

label the phonon modes with irreps

crystod_phonon_irreps

find the subgroups the imaginary modes lead to

crystod_imaginary_mode_subgroups

get the irreps of the crystal orbitals of an element

crystod_crystal_orbital_irreps

list the special k points of a space group

crystod_special_kpoints

get the point group and SALCs of a molecule

crystod_molecular_symmetry

Every tool takes text and returns Markdown, so nothing needs to be on the assistant’s disk: space groups as symbols or numbers, irreps in ISO-IR notation (R4+, GM5-), crystal structures as the full text of a POSCAR, molecules as the full text of an XYZ file, phonon forces as the full text of a phonopy FORCE_SETS. The text of a structure is written to a temporary directory for the duration of one call and removed afterwards.

Installation#

crystod-mcp is a separate package so that CrystOD itself carries no MCP dependency. From a checkout of the repository:

pip install ./crystod-mcp

This installs CrystOD (>= 0.4.0) and the MCP Python SDK (2.x) as dependencies; Python 3.10 or later. Publication on PyPI as crystod-mcp is planned, after which pip install crystod-mcp and the uvx form below work without a checkout. crystod-mcp --version checks the installation; the server itself is started by the MCP client over standard input/output, not by hand.

Client configuration#

Claude Desktop reads claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json; Windows: %APPDATA%\Claude\claude_desktop_config.json). python must be the interpreter in which crystod-mcp is installed – give its full path when it lives in a conda environment or a venv:

{
  "mcpServers": {
    "crystod": {
      "command": "python",
      "args": ["-m", "crystod_mcp"],
      "env": {
        "CRYSTOD_MCP_TIMEOUT": "60"
      }
    }
  }
}

Claude Code registers the server from the command line:

claude mcp add crystod -- crystod-mcp

(or claude mcp add crystod -- /path/to/env/bin/python -m crystod_mcp to name the interpreter). With uv installed, once the package is on PyPI:

{
  "mcpServers": {
    "crystod": {
      "command": "uvx",
      "args": ["crystod-mcp"]
    }
  }
}

crystod-mcp/mcp_config.json holds both forms.

The tools#

Tool

Command it wraps

Inputs

crystod_isotropy_subgroups

crystod-group --parent

parent (Pm-3m or 221), irrep (R4+; two labels for a coupled order parameter), order_parameter (optional, "0 0 a")

crystod_irrep_product

crystod-group --product

space_group (a point-group symbol such as m-3m selects the point-group product), irreps (list)

crystod_decompose_representation

crystod-group --decompose

point_group, characters (one per class, E first)

crystod_ligand_field

crystod-group --ligand-field

point_group, orbital (s/p/d/f)

crystod_character_table

crystod-group --table

group (point group, or space group), kpoint (optional label or coordinates; Gamma by default for a space group)

crystod_phonon_irreps

crystod-phonon --irreps

poscar, dim ([4, 4, 4]), force_sets, qpoint (optional; every special point otherwise)

crystod_imaginary_mode_subgroups

crystod-phonon --subgroup

poscar, dim, force_sets, threshold (THz, default -0.1)

crystod_crystal_orbital_irreps

crystod

poscar, element, orbital, kpoint (optional)

crystod_special_kpoints

crystod-bz --show-kpoint

space_group or poscar

crystod_molecular_symmetry

crystod-mol

xyz, element and orbital (optional, together)

The tools are built on the Python API (crystod.group.isotropy_subgroups, crystod.phonon.label_phonon_modes, crystod.phonon.scan_imaginary_modes, crystod.bz.get_special_kpoints, …); the three whose printed report is the natural answer (crystod, the little-group character table and crystod-mol) return the report of the command itself. crystod_isotropy_subgroups always returns the whole table: the API has no maximum-index cut-off (there is no max_index argument).

A tool call with a bad input returns one sentence naming the problem and the remedy – the tabulated irreps of the space group, the class order of the character table, the special k points of the space group – instead of a traceback, so the assistant can correct itself and call again. For example crystod_isotropy_subgroups("Pm-3m", "R9+") answers

irrep "R9+" is not tabulated for space group Pm-3m (No. 221). Available irreps:
GM1+, GM2+, GM3+, GM4+, GM5+, GM1-, ..., M5-

Example#

crystod_isotropy_subgroups("Pm-3m", "R4+") returns

## Isotropy subgroups of R4+ in Pm-3m (No. 221)

| Direction | Subgroup | No. | Size | Index | Free parameters |
|---|---|---|---|---|---|
| (0,0,a) | I4/mcm | 140 | 2 | 6 | 1 |
| (a,a,a) | R-3c | 167 | 2 | 8 | 1 |
| (0,a,a) | Imma | 74 | 2 | 12 | 1 |
| (0,a,b) | C2/m | 12 | 2 | 24 | 2 |
| (a,a,b) | C2/c | 15 | 2 | 24 | 2 |
| (a,b,c) | P-1 | 2 | 2 | 48 | 3 |

6 isotropy subgroup(s). Size: primitive-cell multiplication relative to the
parent; index: index of the subgroup in the parent; free parameters:
independent order-parameter components (1 = a single amplitude fixes the
structure).

Irrep labels follow ISO-IR (H. T. Stokes, B. J. Campbell and R. Cordes,
Acta Cryst. A69, 388 (2013), https://iso.byu.edu). CrystOD: H. Koiso and
Y. Mochizuki et al., Phys. Rev. B 110, 064104 (2024).

– the same six subgroups as crystod-group --parent Pm-3m --irrep R4+ and the Python API, with the citation footer every result carries.

Citation#

The irrep labels come from the ISO-IR tables of the ISOTROPY Software Suite that CrystOD bundles, and the analyses are CrystOD’s, so every tool result ends with the two citations (ISO-IR: H. T. Stokes, B. J. Campbell and R. Cordes, Acta Cryst. A69, 388 (2013); CrystOD: H. Koiso and Y. Mochizuki et al., Phys. Rev. B 110, 064104 (2024)). Please keep both when results obtained through the server are published; see Citation. The server returns computed results (labels, decompositions, subgroups), never the tables themselves.

Time limits and resources#

Every call runs under a time limit of 60 s by default; the CRYSTOD_MCP_TIMEOUT environment variable of the server process (seconds, set in the client configuration as above) raises or lowers it, and a call that exceeds it returns an error naming the limit and the variable instead of hanging the client. The limit bounds the wait, not the computation: the tools that return a CrystOD report run it in a subprocess that is killed at the limit, while the group-theory, k-point, molecular and phonon tools run in a worker thread that finishes in the background after the error has been returned (retrying a long scan with a larger limit while the first one is still running costs a second scan). The group-theory, k-point and molecular tools answer in well under a second. The phonon tools rebuild the force constants from FORCE_SETS with phonopy – a few seconds for the 4x4x4 SrTiO3 example, more for large supercells – and crystod_imaginary_mode_subgroups scans every q point the supercell resolves. The server runs one calculation per call in a worker thread (a subprocess for the tools that return a CrystOD report), needs no network access and keeps no state between calls.

Tests#

pip install -e "./crystod-mcp[test]"
python -m pytest -q crystod-mcp/tests

The tests call every tool on the inputs bundled with CrystOD (crystod.examples: ScF3, SrTiO3 with its 4x4x4 FORCE_SETS, CH4, NH3), check the results the CrystOD testsuite expects (Pm-3m R4+ -> I4/mcm, R-3c, Imma, C2/m, C2/c, P-1; the imaginary R5- mode of SrTiO3 at -1.09 THz; Sc 3d of ScF3 -> GM3+ + GM5+ at Gamma; CH4 -> Td with A1 + T2 for the H 1s SALCs), confirm the citation footer on every result and the one-sentence errors, and connect to the server in-process and over stdio to list the ten tools and make a call.

License#

MIT, as CrystOD. The MCP Python SDK the server is built on is MIT licensed (Copyright (c) 2024 Anthropic, PBC); its notice is reproduced in crystod-mcp/LICENSE.