@mcp.tool()
def get_phase_diagram(
elements: list[str],
) -> str:
"""
Get phase diagram data for a chemical system.
Args:
elements: List of elements defining the system (e.g., ["Li", "Fe", "O"] for Li-Fe-O system)
Returns:
JSON with phase diagram entries including stable phases, formation energies, and decomposition products
"""
has_key, key_or_error = check_api_key()
if not has_key:
return json.dumps({"error": key_or_error})
try:
from mp_api.client import MPRester
from pymatgen.analysis.phase_diagram import PhaseDiagram
with MPRester(key_or_error) as mpr:
# Get all entries in the chemical system
chemsys = "-".join(sorted(elements))
entries = mpr.get_entries_in_chemsys(elements)
if not entries:
return json.dumps({
"error": f"No entries found for chemical system: {chemsys}",
"chemical_system": chemsys,
})
# Build phase diagram
pd = PhaseDiagram(entries)
# Get stable entries
stable_entries = []
for entry in pd.stable_entries:
stable_entries.append({
"material_id": str(entry.entry_id) if hasattr(entry, 'entry_id') else None,
"formula": entry.composition.reduced_formula,
"energy_per_atom_eV": entry.energy_per_atom,
"formation_energy_per_atom_eV": pd.get_form_energy_per_atom(entry),
})
# Get unstable entries with decomposition info
unstable_entries = []
for entry in pd.unstable_entries:
decomp, e_above_hull = pd.get_decomp_and_e_above_hull(entry)
decomp_products = [p.composition.reduced_formula for p in decomp.keys()]
unstable_entries.append({
"material_id": str(entry.entry_id) if hasattr(entry, 'entry_id') else None,
"formula": entry.composition.reduced_formula,
"energy_above_hull_eV": e_above_hull,
"decomposes_to": decomp_products,
})
return json.dumps({
"chemical_system": chemsys,
"num_elements": len(elements),
"total_entries": len(entries),
"stable_phases": {
"count": len(stable_entries),
"entries": stable_entries,
},
"unstable_phases": {
"count": len(unstable_entries),
"entries": unstable_entries[:20], # Limit to first 20
},
}, indent=2)
except ImportError:
return json.dumps({"error": "mp-api or pymatgen not installed"})
except Exception as e:
return json.dumps({"error": str(e)})