Define the future of scientific computing together
AI4S-Agent Co-building Initiative | Local Setup and Contribution Cases of ABACUS-agent-tools
Posted onInABACUSWord count in article: 1.9kReading time ≈7 mins.
This document describes how to install ABACUS agent and Google ADK in a local Linux environment (including WSL) as of June 12, 2025, and how to run a simple ABACUS calculation after startup.
Requirements: conda and ABACUS (recommended to install v3.10 LTS version) are installed locally.
Tutorial for Experiencing ABACUS-agent-tools in Local Environment
Set environment variables required by ABACUS agent tools
Before starting abacusagent, some environment variables need to be set in the configuration file. This file is located at .abacusagent/env.json. If the file does not exist, you can create it directly.
When running ABACUS agent and Google ADK locally for ABACUS calculations, it is recommended to set at least the following environment variables: ABACUSAGENT_WORK_PATH, ABACUS_COMMAND, ABACUS_PP_PATH, ABACUS_ORB_PATH. Environment variables can be added by inserting them into env.json.
It is recommended to use the efficiency orbitals and pseudopotentials in APNS-v1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
{ "_comments": { "ABACUS_WORK_PATH": "The working directory for AbacusAgent, where all temporary files will be stored.", "ABACUS_SUBMIT_TYPE": "The type of submission for ABACUS, can be local or bohrium.", "ABACUSAGENT_HOST": "The host address for the AbacusAgent server.", "ABACUSAGENT_PORT": "The port number for the AbacusAgent server.", "ABACUSAGENT_MODEL": "The model to use for AbacusAgent, can be 'fastmcp', 'test', or 'dp'.", "BOHRIUM_USERNAME": "The username for Bohrium.", "BOHRIUM_PASSWORD": "The password for Bohrium.", "BOHRIUM_PROJECT_ID": "The project ID for Bohrium.", "BOHRIUM_ABACUS_IMAGE": "The image for Abacus on Bohrium.", "BOHRIUM_ABACUS_MACHINE": "The machine type for Abacus on Bohrium.", "BOHRIUM_ABACUS_COMMAND": "The command to run Abacus on Bohrium", "ABACUS_COMMAND": "The command to execute Abacus on local machine.", "ABACUS_PP_PATH": "The path to the pseudopotential library for Abacus.", "ABACUS_ORB_PATH": "The path to the orbital library for Abacus.", "_comments": "This dictionary contains the default environment variables for AbacusAgent." } }
Start abacusagent (or start in the background)
1 2 3 4 5
# Foreground startup abacusagent
# Background startup nohup abacusagent &
The default port used is 50001, and the MCP server address is localhost. Use abacusagent -h to see how to change the MCP backend, the IP address, and port of the running MCP server.
If the previous step was not started in the background, open a new terminal next and load the Python environment of the previous terminal.
Prepare agent.py for use by Google ADK
1 2
mkdir my_agents && cd my_agents mkdir abacus_agent && cd abacus_agent
Create agent.py and fill in the following content:
import os from google.adk.agents import Agent from google.adk.models.lite_llm import LiteLlm from google.adk.tools.mcp_tool import MCPToolset from google.adk.tools.mcp_tool.mcp_toolset import SseServerParams from dp.agent.adapter.adk import CalculationMCPToolset
# Set the environment variables required for the LLM you are using and your own API key here os.environ['DEEPSEEK_API_KEY'] = "" model = LiteLlm(model='deepseek/deepseek-chat')
instruction = """You are an expert in materials science and computational chemistry. " "Help users perform ABACUS including single point calculation, structure optimization, molecular dynamics and property calculations. " "The website of ABACUS documentation is at https://abacus.deepmodeling.com/en/latest/, please read it if necessary." "Use default parameters if the users do not mention, but let users confirm them before submission. " "Always verify the input parameters to users and provide clear explanations of results." "The LCAO basis is prefered." """
# Modify the url here according to the port used when starting abacusagent toolset = CalculationMCPToolset( connection_params=SseServerParams( url="http://localhost:50001/sse", ) )
1.An LLM API key is required and imported into the environment variable. The example shows the method of using Deepseek's API; fill in the API key on line 9. For using other LLMs, please query the environment variables that need to be imported and modify line 14.
2.Line 12 gives the prompt for the LLM, which can be appropriately modified to make the LLM perform better.
3.The port of the URL in line 23 needs to be the same as the port used when starting abacusagent.
Start Google ADK
After writing agent.py, start Google ADK locally:
1 2
cd .. adk web
If the port is occupied, you can modify the port: adk web --port 8001
1 2 3 4 5 6
Started server process [3260] INFO: INFO: Waiting for application startup. ADK Web Server started For local testing, access at http://localhost:8001. INFO: INFO: Application startup complete. Uvicorn running on http://127.0.0.1:8001 (Press CTRL+C to quit)
Access the given URL in a browser to start the conversation. You can use Chinese or English for the conversation.
Below is an example of performing a relax calculation on a water molecule and giving the bond length of the O-H bond and the bond angle of H-O-H after optimization.
1 2 3 4 5 6 7 8 9 10 11
H2O 1.0 10.000000000.000000000.00000000 0.0000000010.000000000.00000000 0.000000000.0000000010.00000000 O H 12 Cartesian 4.890252674.765105524.31745869 5.797585215.078556924.30766611 4.342835245.351774893.79043572
Add your own written tool functions
Currently, you can add your own written functions in src/abacusagent/modules and use the decorator @mcp.tool() .It is necessary to restart abacusagent and adk.
Contribution Cases
Calculation Function Case - Bader Charge Calculation
To implement Bader charge calculation, the following tool functions need to be built:
1.Calculate the charge density based on the given ABACUS input file.
2.Merge the charge densities of different spin components into one file.
3.Perform Bader charge analysis using the merged file and output the results.
Therefore, create the file bader.py and place it in the src/abacusagent/modules/ directory. Construct the following functions in the file:
from abacusagent.init_mcp import mcp from typing importOptional, List
@mcp.tool() # important! to make this function visible to Agent defcalculate_charge_densities_with_abacus( abacus: str, jobdir: str ) -> Optional[List[str]]: """ calculate the charge densities (of different spin channels, if calculation is polarized) within given prepared ABACUS job directory Parameters: abacus (str): Path to the abacus executable. jobdir (str): Directory where the job files are located. Returns: list: List of file names for the charge density cube files. """
@mcp.tool() # important! to make this function visible to Agent defmerge_charge_densities_of_different_spin( cube_manipulator: str, fcube: List[str] ) -> str: """ merge the charge densities of different spin channels into one file Parameters: cube_manipulator (str): Path to the cube manipulator executable. fcube (list): List of file names for the cube files to be manipulated. Returns: str: Output cube file path. """
@mcp.tool() # important! to make this function visible to Agent defcalculate_bader_charges( bader: str, fcube: str ) -> List[str]: """ Calculate Bader charges using the bader executable. Parameters: bader (str): Path to the bader executable. fcube (str): Path to the cube file containing charge density. Returns: list: A list of file names generated by the Bader analysis. """
In addition, several tool functions are implemented for automatically identifying whether it is a spin-polarized calculation and reading input/output files. Decorate the above main functions expected to be called by the Agent with the mcp_tool() decorator to enable Agent calls.
Calculation Example Contribution Case - Band Gap of NiO
To automatically select examples from the database for the requested material calculation, a tool function in ABACUS-agent-tools is written and stored in src/abacusagent/modules/abacus.py:
from abacusagent.init_mcp import mcp from typing importLiteral, TypedDict from pathlib import Path import json import time import os import shutil from abacusagent.preprocess import PrepInput from abacusagent.utils import WriteInput
@mcp.tool() defabacus_prepare_example_material( chemical_formula: Literal['NiO'] = 'NiO' ) -> TypedDict("results", {"job_path": str, 'description': str}): """ Prepare input files for ABACUS from given examples. Should only be used if the completely same material are requested to calculate. Currently examples are listed here: - NiO: A typical antiferromagnetic material. The provided example calculate the band gap of NiO with PBE+U and the U for Ni 3d is 5 eV. Args: chemical_formula: The chemical formula of the material. Should be among provided examples. Returns: A dictionary contains the job path, with input files generated according to provided examples and original description in the example. """ example_database_path = Path(__file__).resolve().parent / "example_data" withopen(example_database_path / f"{chemical_formula}.json") as fin: job_info = json.load(fin) input, stru = job_info['input'], job_info['stru'] current_time = time.strftime("%Y%m%d%H%M%S") job_work_dir = Path(f"{os.environ['ABACUSAGENT_WORK_PATH']}") / f"{chemical_formula}-{current_time}" temp_stru_file_path = f'/tmp/{chemical_formula}-{current_time}' withopen(temp_stru_file_path, "w") as fout: for lines in stru: fout.write(lines + "\n") fout.close() _, job_path = PrepInput( files=temp_stru_file_path, filetype="abacus/stru", jobtype='scf', lcao=True ).run() job_path = Path(job_path[0]) WriteInput(input, job_path / "INPUT") os.remove(temp_stru_file_path) shutil.move(job_path, job_work_dir) return {'job_path': str(job_work_dir.absolute()), 'description': job_info['description']}
For example, after preparing the following NiO band gap calculation case (stored in src/abacusagent/modules/example_data/NiO.json), the Agent can find that the NiO band gap case has been saved in the database and automatically read the database to prepare ABACUS calculation files.
{ "description": "This example is calculating the band gap of NiO using APNS-v1 pseudopotential and orbital bundle. This material is a typical magnetic material. The magnetic moment of Ni atoms are in antiferromangetics form. The band gap are calculated using PBE+U with Ueff= 7 eV for Ni 3d orbital.", "input": { "suffix": "NiO", "ntype": 2, "calculation": "scf", "ecutwfc": 100, "scf_thr": 1e-07, "scf_nmax": 200, "smearing_method": "gaussian", "smearing_sigma": 0.01, "mixing_type": "broyden", "mixing_beta": 0.2, "mixing_gg0": 1.5, "ks_solver": "genelpa", "basis_type": "lcao", "gamma_only": 0, "symmetry": 1, "nspin": 2, "dft_plus_u": 1, "orbital_corr": "2 -1", "hubbard_u": "7.0 0.0", "out_mul": 1, "out_bandgap": 1, "kspacing": 0.1 }, "stru": [ "ATOMIC_SPECIES", "Ni 58.6934 Ni_ONCV_PBE-1.2.upf upf201", "O 15.9994 O.upf upf201", "NUMERICAL_ORBITAL", "Ni_gga_8au_100Ry_4s2p2d1f.orb", "O_gga_6au_100Ry_2s2p1d.orb", "LATTICE_CONSTANT", "1.8897260000", "LATTICE_VECTORS", "4.1632639461 2.0729584133 2.0729584133", "2.0729584133 4.1632639461 2.0729584133", "2.0729584133 2.0729584133 4.1632639461", "ATOMIC_POSITIONS", "Direct", "Ni #label", "0.0000 #magnetism", "2 #number of atoms", "0.0000000000 0.0000000000 0.0000000000 m 1 1 1 mag 1.3047", "0.5000000000 0.5000000000 0.5000000000 m 1 1 1 mag -1.3047", "O #label", "0.0000 #magnetism", "2 #number of atoms", "0.2500000000 0.2500000000 0.2500000000 m 1 1 1 mag -0.0000", "0.7500000000 0.7500000000 0.7500000000 m 1 1 1 mag -0.0000" ], "pp": "APNS-v1", "orb": "APNS-v1" }
For subsequent further development, it is hoped to achieve fuzzy matching, select the case closest to the desired calculation from the database, and automatically prepare the input file.
Bader Charge Calculation Case Demonstration
A workflow driver function named calculate is also created in bader.py:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
@mcp.tool() defcalculate( jobdir: str, abacus: str, cube_manipulator: str, bader: str ) -> List[float]: """ Calculate Bader charges for a given job directory, with ABACUS as the dft software to calculate the charge density, and then postprocess the charge density with the cube manipulator and Bader analysis. Parameters: jobdir (str): Directory where the job files are located. abacus (str): Path to the abacus executable. cube_manipulator (str): Path to the cube manipulator executable. bader (str): Path to the bader executable. Returns: list: A list of Bader charges. """
Therefore, if the prompt is written correctly, the numerical values of Bader charges can be directly obtained, and the Agent will automatically perform ABACUS calculation, cube file processing, and Bader post-processing operations: