[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M73H938RFACWDAKP4HW8N8P1":3,"skill-same:01M73H938RFACWDAKP4HW8N8P1":53},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":29,"commitSha":30,"skillDirectory":31,"forksCount":32,"repositoryHtmlUrl":33,"repositoryHomepageUrl":34,"ownerHtmlUrl":35,"ownerBlogUrl":36,"ownerDescription":37,"updatedAt":38,"install":39,"resources":52},"01M73H938RFACWDAKP4HW8N8P1","molecular-dynamics",null,"Runs and analyzes molecular dynamics simulations with OpenMM and MDAnalysis. Sets up protein\u002Fsmall molecule systems, defines force fields, runs energy minimization and production MD, and analyzes trajectories (RMSD, RMSF, contact maps, free energy surfaces). For structural biology, drug binding, and biophysics.","bg-szy\u002FTOP-SKILLS","bg-szy","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F106576190?v=4","01M73A4E8KPV67SFXRY8XZGNBX","ShuZhiyong","01M73A4E96MQ294MHM74TZBVQD",6,"MIT","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fawesome-skills\u002Fmolecular-dynamics\u002FSKILL.md",[],[],"2026-11-11 15:11:14",false,"---\nname: molecular-dynamics\ndescription: Runs and analyzes molecular dynamics simulations with OpenMM and MDAnalysis. Sets up protein\u002Fsmall molecule systems, defines force fields, runs energy minimization and production MD, and analyzes trajectories (RMSD, RMSF, contact maps, free energy surfaces). For structural biology, drug binding, and biophysics.\nlicense: MIT\ncompatibility: Requires Python 3.11+ with OpenMM and MDAnalysis; matplotlib for plots. Optional PDBFixer and OpenFF need separate installation. Network access for installation; local simulation and analysis run offline.\nmetadata:\n  version: \"1.3\"\n  last-reviewed: \"2026-10-01\"\n  skill-author: Kuan-lin Huang\n---\n\n# Molecular Dynamics\n\n## Overview\n\nMolecular dynamics (MD) simulation computationally models the time evolution of molecular systems by integrating Newton's equations of motion. This skill covers two complementary tools:\n\n- **OpenMM** (https:\u002F\u002Fopenmm.org\u002F): High-performance MD simulation engine with GPU support, Python API, and flexible force field support\n- **MDAnalysis** (https:\u002F\u002Fmdanalysis.org\u002F): Python library for reading, writing, and analyzing MD trajectories from all major simulation packages\n\n**Reviewed versions:** OpenMM 8.6.1 and MDAnalysis 2.10.0. Reference-platform\nsmoke checks use small synthetic systems; GPU performance and scientific convergence\nare not established by them. OpenMM latest API pages identify a development build,\nso the installed 8.6.1 API is the executable reference.\n\n**Installation into a dedicated environment:**\n```bash\nuv venv --python 3.12 .venv-md\nuv pip install --python .venv-md\u002Fbin\u002Fpython \"openmm==8.6.1\" \"MDAnalysis==2.10.0\" matplotlib pandas\n# Windows: use .venv-md\u002FScripts\u002Fpython.exe instead\n```\n\n## When to Use This Skill\n\nUse molecular dynamics when:\n\n- **Protein stability analysis**: How does a mutation affect protein dynamics?\n- **Drug binding simulations**: Characterize binding mode and residence time of a ligand\n- **Conformational sampling**: Explore protein flexibility and conformational changes\n- **Protein-protein interaction**: Model interface dynamics and binding energetics\n- **RMSD\u002FRMSF analysis**: Quantify structural fluctuations from a reference structure\n- **Free energy estimation**: Compute binding free energy or conformational free energy\n- **Membrane simulations**: Model proteins in lipid bilayers\n- **Intrinsically disordered proteins**: Study IDR conformational ensembles\n\n## Core Workflow: OpenMM Simulation\n\nExamples require system-specific preparation and validation. Review biological\nassembly, alternate locations, missing loops, termini, protonation, disulfides,\nligands and cofactors before parameterization. An MD trajectory alone does not\nestablish binding free energy or residence time.\n\nThe functions below form one Python module: execute their import blocks together.\nUse a new output prefix for every stage to avoid overwriting earlier results.\n\n### 1. System Preparation\n\n```python\nfrom openmm.app import *\nfrom openmm import *\nfrom openmm.unit import *\n\ndef prepare_system_from_pdb(pdb_file, forcefield_name=\"amber14-all.xml\",\n                              water_model=\"amber14\u002Ftip3pfb.xml\", ph=7.0):\n    \"\"\"\n    Prepare an OpenMM system from a PDB file.\n\n    Args:\n        pdb_file: Path to cleaned PDB file (use PDBFixer for raw PDB files)\n        forcefield_name: Force field XML file\n        water_model: Water model XML file\n\n    Returns:\n        modeller, system\n    \"\"\"\n    # Load PDB\n    pdb = PDBFile(pdb_file)\n\n    # Load force field\n    forcefield = ForceField(forcefield_name, water_model)\n\n    # Add hydrogens and solvate\n    modeller = Modeller(pdb.topology, pdb.positions)\n    modeller.addHydrogens(forcefield, pH=ph)\n\n    # TIP3P geometry also serves TIP3P-FB; XML supplies the parameters.\n    # 10 Å padding; added salt excludes neutralizing counterions.\n    modeller.addSolvent(\n        forcefield,\n        model='tip3p',\n        padding=10*angstroms,\n        ionicStrength=0.15*molar, neutralize=True\n    )\n\n    print(f\"System: {modeller.topology.getNumAtoms()} atoms, \"\n          f\"{modeller.topology.getNumResidues()} residues\")\n\n    # Create system\n    system = forcefield.createSystem(\n        modeller.topology,\n        nonbondedMethod=PME,         # Particle Mesh Ewald for long-range electrostatics\n        nonbondedCutoff=1.0*nanometer,\n        constraints=HBonds,           # Constrain bonds involving H (not intermolecular H-bonds)\n        rigidWater=True,\n        ewaldErrorTolerance=0.0005\n    )\n\n    return modeller, system\n```\n\n### 2. Energy Minimization\n\n```python\nfrom openmm.app import *\nfrom openmm import *\nfrom openmm.unit import *\n\ndef minimize_energy(modeller, system, output_pdb=\"minimized.pdb\",\n                     max_iterations=1000, tolerance=10.0, platform_name=None):\n    \"\"\"\n    Energy minimize the system to remove steric clashes.\n\n    Args:\n        modeller: Modeller object with topology and positions\n        system: OpenMM System\n        output_pdb: Path to save minimized structure\n        max_iterations: Maximum minimization steps\n        tolerance: Convergence criterion in kJ\u002Fmol\u002Fnm\n\n    Returns:\n        simulation object with minimized positions\n    \"\"\"\n    # Keep the integrator at 2 fs for the subsequent NVT\u002FNPT examples.\n    integrator = LangevinMiddleIntegrator(300*kelvin, 1\u002Fpicosecond, 0.002*picoseconds)\n\n    # Automatic platform selection, or an explicit tested platform (e.g. CPU).\n    # A registered GPU plugin does not prove a working device or driver.\n    platform = Platform.getPlatformByName(platform_name) if platform_name else None\n    simulation = Simulation(modeller.topology, system, integrator, platform)\n    simulation.context.setPositions(modeller.positions)\n\n    # Check initial energy\n    state = simulation.context.getState(getEnergy=True)\n    print(f\"Initial energy: {state.getPotentialEnergy()}\")\n\n    # Minimize\n    simulation.minimizeEnergy(\n        tolerance=tolerance*kilojoules_per_mole\u002Fnanometer,\n        maxIterations=max_iterations\n    )\n\n    state = simulation.context.getState(getEnergy=True, getPositions=True)\n    print(f\"Minimized energy: {state.getPotentialEnergy()}\")\n\n    # Save minimized structure\n    with open(output_pdb, 'w') as f:\n        PDBFile.writeFile(simulation.topology, state.getPositions(), f)\n\n    return simulation\n```\n\n### 3. NVT Equilibration\n\n```python\nfrom openmm.app import *\nfrom openmm import *\nfrom openmm.unit import *\n\ndef run_nvt_equilibration(simulation, n_steps=50000, temperature=300,\n                            report_interval=1000, output_prefix=\"nvt\"):\n    \"\"\"\n    NVT equilibration: constant N, V, T.\n    Equilibrate velocities to target temperature.\n\n    Args:\n        simulation: OpenMM Simulation (after minimization)\n        n_steps: Number of MD steps (50000 × 2fs = 100 ps)\n        temperature: Temperature in Kelvin\n        report_interval: Steps between data reports\n        output_prefix: File prefix for trajectory and log\n    \"\"\"\n    # This example is unrestrained; add validated restraints before Context creation.\n    if any(\"Barostat\" in type(f).__name__ and f.getFrequency() > 0\n           for f in simulation.system.getForces()):\n        raise ValueError(\"NVT requires all barostats disabled or absent\")\n\n    # Set both the thermostat target and initial velocities.\n    simulation.integrator.setTemperature(temperature*kelvin)\n    simulation.context.setVelocitiesToTemperature(temperature*kelvin)\n\n    # Add reporters\n    simulation.reporters = []\n\n    # Log file\n    simulation.reporters.append(\n        StateDataReporter(\n            f\"{output_prefix}_log.txt\",\n            report_interval,\n            step=True,\n            potentialEnergy=True,\n            kineticEnergy=True,\n            temperature=True,\n            volume=True,\n            speed=True\n        )\n    )\n\n    # DCD trajectory (compact binary format)\n    simulation.reporters.append(\n        DCDReporter(f\"{output_prefix}_traj.dcd\", report_interval)\n    )\n\n    duration = (n_steps * simulation.integrator.getStepSize()).value_in_unit(picoseconds)\n    print(f\"Running NVT equilibration: {n_steps} steps ({duration:.1f} ps)\")\n    simulation.step(n_steps)\n    print(\"NVT equilibration complete\")\n\n    return simulation\n```\n\n### 4. NPT Equilibration and Production\n\nCall this function first with a dedicated NPT equilibration prefix. Inspect density,\nenergy, structure and replicate stability before a separate production call; the\ndefault duration is an example, not an equilibration or convergence criterion.\n\n```python\ndef run_npt_production(simulation, n_steps=500000, temperature=300, pressure=1.0,\n                        report_interval=5000, output_prefix=\"npt\"):\n    \"\"\"\n    NPT production run: constant N, P, T.\n\n    Args:\n        n_steps: Production steps (500000 × 2fs = 1 ns)\n        temperature: Temperature in Kelvin\n        pressure: Pressure in bar\n        report_interval: Steps between reports\n    \"\"\"\n    # Keep the Langevin thermostat and barostat at the same temperature.\n    simulation.integrator.setTemperature(temperature*kelvin)\n    system = simulation.system\n    barostats = [f for f in system.getForces() if \"Barostat\" in type(f).__name__]\n    if not system.usesPeriodicBoundaryConditions():\n        raise ValueError(\"NPT requires a periodic system\")\n    if not barostats:\n        system.addForce(MonteCarloBarostat(pressure*bar, temperature*kelvin, 25))\n        simulation.context.reinitialize(preserveState=True)\n    elif len(barostats) != 1 or not isinstance(barostats[0], MonteCarloBarostat):\n        raise ValueError(\"This example supports one isotropic MonteCarloBarostat\")\n    else:\n        barostats[0].setDefaultPressure(pressure*bar)\n        barostats[0].setDefaultTemperature(temperature*kelvin)\n        barostats[0].setFrequency(25)\n    # Existing Context parameters must also be updated on repeated calls.\n    simulation.context.setParameter(MonteCarloBarostat.Pressure(), pressure)\n    simulation.context.setParameter(MonteCarloBarostat.Temperature(), temperature)\n\n    # Update reporters\n    simulation.reporters = []\n    simulation.reporters.append(\n        StateDataReporter(\n            f\"{output_prefix}_log.txt\",\n            report_interval,\n            step=True,\n            potentialEnergy=True,\n            temperature=True,\n            density=True,\n            speed=True\n        )\n    )\n    simulation.reporters.append(\n        DCDReporter(f\"{output_prefix}_traj.dcd\", report_interval)\n    )\n\n    # Save checkpoints\n    simulation.reporters.append(\n        CheckpointReporter(f\"{output_prefix}_checkpoint.chk\", 50000)\n    )\n\n    duration = (n_steps * simulation.integrator.getStepSize()).value_in_unit(nanoseconds)\n    print(f\"Running NPT stage: {n_steps} steps ({duration:.3f} ns)\")\n    simulation.step(n_steps)\n    simulation.saveCheckpoint(f\"{output_prefix}_checkpoint.chk\")\n    simulation.saveState(f\"{output_prefix}_state.xml\")\n    print(\"NPT stage complete\")\n    return simulation\n```\n\n## Trajectory Analysis with MDAnalysis\n\n### 1. Load Trajectory\n\nUse the solvated topology with exactly the DCD atom count and order (e.g. the\n`minimized.pdb` above), not the original unsolvated input. MDAnalysis converts\nlengths to Å and time to ps by default; OpenMM bare coordinates use nm. Preserve\nframe box vectors and actual timestamps; do not infer time from frame number.\n\n```python\nimport MDAnalysis as mda\nfrom MDAnalysis.analysis import rms, align, contacts\nimport numpy as np\nimport matplotlib.pyplot as plt\n\ndef load_trajectory(topology_file, trajectory_file):\n    \"\"\"\n    Load an MD trajectory with MDAnalysis.\n\n    Args:\n        topology_file: PDB, PSF, or other topology file\n        trajectory_file: DCD, XTC, TRR, or other trajectory\n    \"\"\"\n    u = mda.Universe(topology_file, trajectory_file)\n    print(f\"Universe: {u.atoms.n_atoms} atoms, {u.trajectory.n_frames} frames\")\n    first, last = u.trajectory[0].time, u.trajectory[-1].time\n    print(f\"Time range: {first:g} to {last:g} ps\")\n    u.trajectory[0]\n    return u\n```\n\n### 2. RMSD Analysis\n\n```python\ndef compute_rmsd(u, selection=\"backbone\", reference_frame=0):\n    \"\"\"\n    Compute RMSD of selected atoms relative to reference frame.\n\n    Args:\n        u: MDAnalysis Universe\n        selection: Atom selection string (MDAnalysis syntax)\n        reference_frame: Frame index for reference structure\n\n    Returns:\n        numpy array with columns [frame index, time in ps, RMSD in Angstroms]\n    \"\"\"\n    # RMSD performs its own fit; avoid rotating the stored trajectory here.\n    # Make the selected molecule whole before analysis of periodic trajectories.\n    R = rms.RMSD(u, select=selection, ref_frame=reference_frame)\n    R.run()\n\n    rmsd_data = R.results.rmsd  # columns: frame, time, RMSD\n    return rmsd_data\n\ndef plot_rmsd(rmsd_data, title=\"RMSD over time\", output_file=\"rmsd.png\"):\n    \"\"\"Plot RMSD over simulation time.\"\"\"\n    fig, ax = plt.subplots(figsize=(10, 4))\n    ax.plot(rmsd_data[:, 1] \u002F 1000, rmsd_data[:, 2], 'b-', linewidth=0.5)\n    ax.set_xlabel(\"Time (ns)\")\n    ax.set_ylabel(\"RMSD (Å)\")\n    ax.set_title(title)\n    ax.axhline(rmsd_data[:, 2].mean(), color='r', linestyle='--',\n               label=f'Mean: {rmsd_data[:, 2].mean():.2f} Å')\n    ax.legend()\n    plt.tight_layout()\n    plt.savefig(output_file, dpi=150)\n    return fig\n```\n\n### 3. RMSF Analysis (Per-Residue Flexibility)\n\nMake molecules whole and align a separate structural-analysis copy before RMSF;\nRMSF does not align. Do not run periodic contacts on a rotated trajectory whose\nbox was not rotated. See [analysis reference](references\u002Fmdanalysis_analysis.md)\nfor alignment, PCA, DSSP, hydrogen bonds and population-derived free energy.\n\n```python\ndef compute_rmsf(u, selection=\"protein and name CA\", start_frame=0):\n    \"\"\"\n    Compute per-residue RMSF (flexibility).\n\n    Returns:\n        residue_keys, rmsf_values; keys are (resindex, segid, resid, resname)\n    \"\"\"\n    # Select atoms\n    atoms = u.select_atoms(selection)\n\n    if not len(atoms):\n        raise ValueError(\"RMSF selection is empty\")\n    # A multi-atom selection returns mean atomic RMSF, not COM RMSF.\n    R = rms.RMSF(atoms)\n    R.run(start=start_frame)\n\n    # Average by residue\n    resids = []\n    rmsf_per_res = []\n    for res in u.select_atoms(selection).residues:\n        res_atoms = res.atoms.intersection(atoms)\n        if len(res_atoms) > 0:\n            resids.append((res.ix, res.segid, res.resid, res.resname))\n            # RMSF is indexed within the selected AtomGroup, not the Universe.\n            rmsf_per_res.append(R.results.rmsf[atoms.resindices == res.ix].mean())\n\n    return resids, np.array(rmsf_per_res)\n```\n\n### 4. Protein-Ligand Contacts\n\n```python\ndef analyze_contacts(u, protein_sel=\"protein\", ligand_sel=\"resname LIG\",\n                      radius=4.5, start_frame=0, periodic=True):\n    \"\"\"\n    Track protein-ligand contacts over trajectory.\n\n    Args:\n        radius: Atom-pair cutoff in Angstroms; any pair defines a residue contact.\n        periodic: Require box data and use minimum-image distances.\n    Returns sets of (resindex, segid, resid, resname), one per analyzed frame.\n    \"\"\"\n    from MDAnalysis.lib.distances import distance_array\n\n    protein = u.select_atoms(protein_sel)\n    ligand = u.select_atoms(ligand_sel)\n\n    if not len(protein) or not len(ligand):\n        raise ValueError(\"Protein and ligand selections must both be nonempty\")\n    if not np.isfinite(radius) or radius \u003C= 0:\n        raise ValueError(\"radius must be finite and positive\")\n    contact_frames = []\n    for ts in u.trajectory[start_frame:]:\n        if periodic and (ts.dimensions is None or not np.all(np.isfinite(ts.dimensions))\n                         or np.any(ts.dimensions[:3] \u003C= 0)):\n            raise ValueError(\"Periodic contacts require valid frame box dimensions\")\n        # This includes hydrogen atoms unless the caller selects heavy atoms.\n        distances = contacts.contact_matrix(\n            distance_array(protein.positions, ligand.positions, box=ts.dimensions if periodic else None),\n            radius,\n        )\n        contact_residues = set()\n        for i in range(distances.shape[0]):\n            if distances[i].any():\n                res = protein[i].residue\n                contact_residues.add((res.ix, res.segid, res.resid, res.resname))\n        contact_frames.append(contact_residues)\n\n    return contact_frames\n```\n\n## Force Fields and Preparation\n\nChoose a validated protein\u002Fligand\u002Fwater\u002Fion combination for the scientific system.\nThe working example retains AMBER14\u002FTIP3P-FB; it is not a universal recommendation.\nCurrent OpenMM also bundles `amber19-all.xml` (ff19SB, DNA OL21, RNA OL3, lipid21),\nand `charmm36_2024.xml` with its own `charmm36_2024\u002Fwater.xml`. Generic TIP3P and\nCHARMM-modified TIP3P are not interchangeable. IDP ensembles are especially\nsensitive to protein-water balance. Four-site waters need extra particles and a\nmatching Modeller geometry, unlike the three-site example above.\n\nAMBER protein XML does not parameterize arbitrary ligands. Use a reviewed GAFF2\nor OpenFF route with explicit stereochemistry, protonation, bond orders, atom\nmapping and charge method. A ligand-only Interchange is not a protein-ligand system.\nSee [preparation reference](references\u002Fsystem_preparation.md) for conservative\nPDBFixer and OpenFF examples, installation requirements and current release details.\n\n## Validation and Provenance\n\n- Start with minimization; finite energy does not establish a valid structure.\n- Use staged NVT → NPT equilibration → production. This example has no restraints.\n- A 2 fs step with constrained H-containing bonds is a starting choice. Larger\n  steps\u002FHMR require integrator, stability and observable validation for that system.\n- Use per-frame boxes for periodic distances. Make molecules whole for structural\n  observables using trusted bond topology; unwrapping cannot infer missing bonds.\n- Assess burn-in, autocorrelation, effective samples, replicas and uncertainties.\n  Short stable temperature\u002Fdensity traces do not establish conformational sampling.\n- Save topology\u002Fatom order, System\u002FIntegrator XML, force-field files\u002Fversions,\n  seeds, platform\u002Fprecision, parameters and analysis selections. Checkpoints are\n  platform\u002Fhardware\u002Fversion specific; XML states are more portable but do not\n  retain all internal random-generator state. Test restarting the actual setup.\n\n## Additional Resources\n\n- **OpenMM documentation**: https:\u002F\u002Fopenmm.org\u002Fdocumentation.html\n- **MDAnalysis user guide**: https:\u002F\u002Fdocs.mdanalysis.org\u002F\n- **GROMACS** (alternative MD engine): https:\u002F\u002Fmanual.gromacs.org\u002F\n- **NAMD** (alternative): https:\u002F\u002Fwww.ks.uiuc.edu\u002FResearch\u002Fnamd\u002F\n- **CHARMM-GUI** (web-based system builder): https:\u002F\u002Fcharmm-gui.org\u002F\n- **AmberTools** (free Amber tools): https:\u002F\u002Fambermd.org\u002FAmberTools.php\n- **OpenMM paper**: Eastman P et al. (2017) PLOS Computational Biology. PMID: 28278240\n- **MDAnalysis paper**: Michaud-Agrawal N et al. (2011) J Computational Chemistry. PMID: 21500218\n","# Molecular Dynamics\n\n## Overview\n\nMolecular dynamics (MD) simulation computationally models the time evolution of molecular systems by integrating Newton's equations of motion. This skill covers two complementary tools:\n\n- **OpenMM** (https:\u002F\u002Fopenmm.org\u002F): High-performance MD simulation engine with GPU support, Python API, and flexible force field support\n- **MDAnalysis** (https:\u002F\u002Fmdanalysis.org\u002F): Python library for reading, writing, and analyzing MD trajectories from all major simulation packages\n\n**Reviewed versions:** OpenMM 8.6.1 and MDAnalysis 2.10.0. Reference-platform\nsmoke checks use small synthetic systems; GPU performance and scientific convergence\nare not established by them. OpenMM latest API pages identify a development build,\nso the installed 8.6.1 API is the executable reference.\n\n**Installation into a dedicated environment:**\n```bash\nuv venv --python 3.12 .venv-md\nuv pip install --python .venv-md\u002Fbin\u002Fpython \"openmm==8.6.1\" \"MDAnalysis==2.10.0\" matplotlib pandas\n# Windows: use .venv-md\u002FScripts\u002Fpython.exe instead\n```\n\n## When to Use This Skill\n\nUse molecular dynamics when:\n\n- **Protein stability analysis**: How does a mutation affect protein dynamics?\n- **Drug binding simulations**: Characterize binding mode and residence time of a ligand\n- **Conformational sampling**: Explore protein flexibility and conformational changes\n- **Protein-protein interaction**: Model interface dynamics and binding energetics\n- **RMSD\u002FRMSF analysis**: Quantify structural fluctuations from a reference structure\n- **Free energy estimation**: Compute binding free energy or conformational free energy\n- **Membrane simulations**: Model proteins in lipid bilayers\n- **Intrinsically disordered proteins**: Study IDR conformational ensembles\n\n## Core Workflow: OpenMM Simulation\n\nExamples require system-specific preparation and validation. Review biological\nassembly, alternate locations, missing loops, termini, protonation, disulfides,\nligands and cofactors before parameterization. An MD trajectory alone does not\nestablish binding free energy or residence time.\n\nThe functions below form one Python module: execute their import blocks together.\nUse a new output prefix for every stage to avoid overwriting earlier results.\n\n### 1. System Preparation\n\n```python\nfrom openmm.app import *\nfrom openmm import *\nfrom openmm.unit import *\n\ndef prepare_system_from_pdb(pdb_file, forcefield_name=\"amber14-all.xml\",\n                              water_model=\"amber14\u002Ftip3pfb.xml\", ph=7.0):\n    \"\"\"\n    Prepare an OpenMM system from a PDB file.\n\n    Args:\n        pdb_file: Path to cleaned PDB file (use PDBFixer for raw PDB files)\n        forcefield_name: Force field XML file\n        water_model: Water model XML file\n\n    Returns:\n        modeller, system\n    \"\"\"\n    # Load PDB\n    pdb = PDBFile(pdb_file)\n\n    # Load force field\n    forcefield = ForceField(forcefield_name, water_model)\n\n    # Add hydrogens and solvate\n    modeller = Modeller(pdb.topology, pdb.positions)\n    modeller.addHydrogens(forcefield, pH=ph)\n\n    # TIP3P geometry also serves TIP3P-FB; XML supplies the parameters.\n    # 10 Å padding; added salt excludes neutralizing counterions.\n    modeller.addSolvent(\n        forcefield,\n        model='tip3p',\n        padding=10*angstroms,\n        ionicStrength=0.15*molar, neutralize=True\n    )\n\n    print(f\"System: {modeller.topology.getNumAtoms()} atoms, \"\n          f\"{modeller.topology.getNumResidues()} residues\")\n\n    # Create system\n    system = forcefield.createSystem(\n        modeller.topology,\n        nonbondedMethod=PME,         # Particle Mesh Ewald for long-range electrostatics\n        nonbondedCutoff=1.0*nanometer,\n        constraints=HBonds,           # Constrain bonds involving H (not intermolecular H-bonds)\n        rigidWater=True,\n        ewaldErrorTolerance=0.0005\n    )\n\n    return modeller, system\n```\n\n### 2. Energy Minimization\n\n```python\nfrom openmm.app import *\nfrom openmm import *\nfrom openmm.unit import *\n\ndef minimize_energy(modeller, system, output_pdb=\"minimized.pdb\",\n                     max_iterations=1000, tolerance=10.0, platform_name=None):\n    \"\"\"\n    Energy minimize the system to remove steric clashes.\n\n    Args:\n        modeller: Modeller object with topology and positions\n        system: OpenMM System\n        output_pdb: Path to save minimized structure\n        max_iterations: Maximum minimization steps\n        tolerance: Convergence criterion in kJ\u002Fmol\u002Fnm\n\n    Returns:\n        simulation object with minimized positions\n    \"\"\"\n    # Keep the integrator at 2 fs for the subsequent NVT\u002FNPT examples.\n    integrator = LangevinMiddleIntegrator(300*kelvin, 1\u002Fpicosecond, 0.002*picoseconds)\n\n    # Automatic platform selection, or an explicit tested platform (e.g. CPU).\n    # A registered GPU plugin does not prove a working device or driver.\n    platform = Platform.getPlatformByName(platform_name) if platform_name else None\n    simulation = Simulation(modeller.topology, system, integrator, platform)\n    simulation.context.setPositions(modeller.positions)\n\n    # Check initial energy\n    state = simulation.context.getState(getEnergy=True)\n    print(f\"Initial energy: {state.getPotentialEnergy()}\")\n\n    # Minimize\n    simulation.minimizeEnergy(\n        tolerance=tolerance*kilojoules_per_mole\u002Fnanometer,\n        maxIterations=max_iterations\n    )\n\n    state = simulation.context.getState(getEnergy=True, getPositions=True)\n    print(f\"Minimized energy: {state.getPotentialEnergy()}\")\n\n    # Save minimized structure\n    with open(output_pdb, 'w') as f:\n        PDBFile.writeFile(simulation.topology, state.getPositions(), f)\n\n    return simulation\n```\n\n### 3. NVT Equilibration\n\n```python\nfrom openmm.app import *\nfrom openmm import *\nfrom openmm.unit import *\n\ndef run_nvt_equilibration(simulation, n_steps=50000, temperature=300,\n                            report_interval=1000, output_prefix=\"nvt\"):\n    \"\"\"\n    NVT equilibration: constant N, V, T.\n    Equilibrate velocities to target temperature.\n\n    Args:\n        simulation: OpenMM Simulation (after minimization)\n        n_steps: Number of MD steps (50000 × 2fs = 100 ps)\n        temperature: Temperature in Kelvin\n        report_interval: Steps between data reports\n        output_prefix: File prefix for trajectory and log\n    \"\"\"\n    # This example is unrestrained; add validated restraints before Context creation.\n    if any(\"Barostat\" in type(f).__name__ and f.getFrequency() > 0\n           for f in simulation.system.getForces()):\n        raise ValueError(\"NVT requires all barostats disabled or absent\")\n\n    # Set both the thermostat target and initial velocities.\n    simulation.integrator.setTemperature(temperature*kelvin)\n    simulation.context.setVelocitiesToTemperature(temperature*kelvin)\n\n    # Add reporters\n    simulation.reporters = []\n\n    # Log file\n    simulation.reporters.append(\n        StateDataReporter(\n            f\"{output_prefix}_log.txt\",\n            report_interval,\n            step=True,\n            potentialEnergy=True,\n            kineticEnergy=True,\n            temperature=True,\n            volume=True,\n            speed=True\n        )\n    )\n\n    # DCD trajectory (compact binary format)\n    simulation.reporters.append(\n        DCDReporter(f\"{output_prefix}_traj.dcd\", report_interval)\n    )\n\n    duration = (n_steps * simulation.integrator.getStepSize()).value_in_unit(picoseconds)\n    print(f\"Running NVT equilibration: {n_steps} steps ({duration:.1f} ps)\")\n    simulation.step(n_steps)\n    print(\"NVT equilibration complete\")\n\n    return simulation\n```\n\n### 4. NPT Equilibration and Production\n\nCall this function first with a dedicated NPT equilibration prefix. Inspect density,\nenergy, structure and replicate stability before a separate production call; the\ndefault duration is an example, not an equilibration or convergence criterion.\n\n```python\ndef run_npt_production(simulation, n_steps=500000, temperature=300, pressure=1.0,\n                        report_interval=5000, output_prefix=\"npt\"):\n    \"\"\"\n    NPT production run: constant N, P, T.\n\n    Args:\n        n_steps: Production steps (500000 × 2fs = 1 ns)\n        temperature: Temperature in Kelvin\n        pressure: Pressure in bar\n        report_interval: Steps between reports\n    \"\"\"\n    # Keep the Langevin thermostat and barostat at the same temperature.\n    simulation.integrator.setTemperature(temperature*kelvin)\n    system = simulation.system\n    barostats = [f for f in system.getForces() if \"Barostat\" in type(f).__name__]\n    if not system.usesPeriodicBoundaryConditions():\n        raise ValueError(\"NPT requires a periodic system\")\n    if not barostats:\n        system.addForce(MonteCarloBarostat(pressure*bar, temperature*kelvin, 25))\n        simulation.context.reinitialize(preserveState=True)\n    elif len(barostats) != 1 or not isinstance(barostats[0], MonteCarloBarostat):\n        raise ValueError(\"This example supports one isotropic MonteCarloBarostat\")\n    else:\n        barostats[0].setDefaultPressure(pressure*bar)\n        barostats[0].setDefaultTemperature(temperature*kelvin)\n        barostats[0].setFrequency(25)\n    # Existing Context parameters must also be updated on repeated calls.\n    simulation.context.setParameter(MonteCarloBarostat.Pressure(), pressure)\n    simulation.context.setParameter(MonteCarloBarostat.Temperature(), temperature)\n\n    # Update reporters\n    simulation.reporters = []\n    simulation.reporters.append(\n        StateDataReporter(\n            f\"{output_prefix}_log.txt\",\n            report_interval,\n            step=True,\n            potentialEnergy=True,\n            temperature=True,\n            density=True,\n            speed=True\n        )\n    )\n    simulation.reporters.append(\n        DCDReporter(f\"{output_prefix}_traj.dcd\", report_interval)\n    )\n\n    # Save checkpoints\n    simulation.reporters.append(\n        CheckpointReporter(f\"{output_prefix}_checkpoint.chk\", 50000)\n    )\n\n    duration = (n_steps * simulation.integrator.getStepSize()).value_in_unit(nanoseconds)\n    print(f\"Running NPT stage: {n_steps} steps ({duration:.3f} ns)\")\n    simulation.step(n_steps)\n    simulation.saveCheckpoint(f\"{output_prefix}_checkpoint.chk\")\n    simulation.saveState(f\"{output_prefix}_state.xml\")\n    print(\"NPT stage complete\")\n    return simulation\n```\n\n## Trajectory Analysis with MDAnalysis\n\n### 1. Load Trajectory\n\nUse the solvated topology with exactly the DCD atom count and order (e.g. the\n`minimized.pdb` above), not the original unsolvated input. MDAnalysis converts\nlengths to Å and time to ps by default; OpenMM bare coordinates use nm. Preserve\nframe box vectors and actual timestamps; do not infer time from frame number.\n\n```python\nimport MDAnalysis as mda\nfrom MDAnalysis.analysis import rms, align, contacts\nimport numpy as np\nimport matplotlib.pyplot as plt\n\ndef load_trajectory(topology_file, trajectory_file):\n    \"\"\"\n    Load an MD trajectory with MDAnalysis.\n\n    Args:\n        topology_file: PDB, PSF, or other topology file\n        trajectory_file: DCD, XTC, TRR, or other trajectory\n    \"\"\"\n    u = mda.Universe(topology_file, trajectory_file)\n    print(f\"Universe: {u.atoms.n_atoms} atoms, {u.trajectory.n_frames} frames\")\n    first, last = u.trajectory[0].time, u.trajectory[-1].time\n    print(f\"Time range: {first:g} to {last:g} ps\")\n    u.trajectory[0]\n    return u\n```\n\n### 2. RMSD Analysis\n\n```python\ndef compute_rmsd(u, selection=\"backbone\", reference_frame=0):\n    \"\"\"\n    Compute RMSD of selected atoms relative to reference frame.\n\n    Args:\n        u: MDAnalysis Universe\n        selection: Atom selection string (MDAnalysis syntax)\n        reference_frame: Frame index for reference structure\n\n    Returns:\n        numpy array with columns [frame index, time in ps, RMSD in Angstroms]\n    \"\"\"\n    # RMSD performs its own fit; avoid rotating the stored trajectory here.\n    # Make the selected molecule whole before analysis of periodic trajectories.\n    R = rms.RMSD(u, select=selection, ref_frame=reference_frame)\n    R.run()\n\n    rmsd_data = R.results.rmsd  # columns: frame, time, RMSD\n    return rmsd_data\n\ndef plot_rmsd(rmsd_data, title=\"RMSD over time\", output_file=\"rmsd.png\"):\n    \"\"\"Plot RMSD over simulation time.\"\"\"\n    fig, ax = plt.subplots(figsize=(10, 4))\n    ax.plot(rmsd_data[:, 1] \u002F 1000, rmsd_data[:, 2], 'b-', linewidth=0.5)\n    ax.set_xlabel(\"Time (ns)\")\n    ax.set_ylabel(\"RMSD (Å)\")\n    ax.set_title(title)\n    ax.axhline(rmsd_data[:, 2].mean(), color='r', linestyle='--',\n               label=f'Mean: {rmsd_data[:, 2].mean():.2f} Å')\n    ax.legend()\n    plt.tight_layout()\n    plt.savefig(output_file, dpi=150)\n    return fig\n```\n\n### 3. RMSF Analysis (Per-Residue Flexibility)\n\nMake molecules whole and align a separate structural-analysis copy before RMSF;\nRMSF does not align. Do not run periodic contacts on a rotated trajectory whose\nbox was not rotated. See [analysis reference](references\u002Fmdanalysis_analysis.md)\nfor alignment, PCA, DSSP, hydrogen bonds and population-derived free energy.\n\n```python\ndef compute_rmsf(u, selection=\"protein and name CA\", start_frame=0):\n    \"\"\"\n    Compute per-residue RMSF (flexibility).\n\n    Returns:\n        residue_keys, rmsf_values; keys are (resindex, segid, resid, resname)\n    \"\"\"\n    # Select atoms\n    atoms = u.select_atoms(selection)\n\n    if not len(atoms):\n        raise ValueError(\"RMSF selection is empty\")\n    # A multi-atom selection returns mean atomic RMSF, not COM RMSF.\n    R = rms.RMSF(atoms)\n    R.run(start=start_frame)\n\n    # Average by residue\n    resids = []\n    rmsf_per_res = []\n    for res in u.select_atoms(selection).residues:\n        res_atoms = res.atoms.intersection(atoms)\n        if len(res_atoms) > 0:\n            resids.append((res.ix, res.segid, res.resid, res.resname))\n            # RMSF is indexed within the selected AtomGroup, not the Universe.\n            rmsf_per_res.append(R.results.rmsf[atoms.resindices == res.ix].mean())\n\n    return resids, np.array(rmsf_per_res)\n```\n\n### 4. Protein-Ligand Contacts\n\n```python\ndef analyze_contacts(u, protein_sel=\"protein\", ligand_sel=\"resname LIG\",\n                      radius=4.5, start_frame=0, periodic=True):\n    \"\"\"\n    Track protein-ligand contacts over trajectory.\n\n    Args:\n        radius: Atom-pair cutoff in Angstroms; any pair defines a residue contact.\n        periodic: Require box data and use minimum-image distances.\n    Returns sets of (resindex, segid, resid, resname), one per analyzed frame.\n    \"\"\"\n    from MDAnalysis.lib.distances import distance_array\n\n    protein = u.select_atoms(protein_sel)\n    ligand = u.select_atoms(ligand_sel)\n\n    if not len(protein) or not len(ligand):\n        raise ValueError(\"Protein and ligand selections must both be nonempty\")\n    if not np.isfinite(radius) or radius \u003C= 0:\n        raise ValueError(\"radius must be finite and positive\")\n    contact_frames = []\n    for ts in u.trajectory[start_frame:]:\n        if periodic and (ts.dimensions is None or not np.all(np.isfinite(ts.dimensions))\n                         or np.any(ts.dimensions[:3] \u003C= 0)):\n            raise ValueError(\"Periodic contacts require valid frame box dimensions\")\n        # This includes hydrogen atoms unless the caller selects heavy atoms.\n        distances = contacts.contact_matrix(\n            distance_array(protein.positions, ligand.positions, box=ts.dimensions if periodic else None),\n            radius,\n        )\n        contact_residues = set()\n        for i in range(distances.shape[0]):\n            if distances[i].any():\n                res = protein[i].residue\n                contact_residues.add((res.ix, res.segid, res.resid, res.resname))\n        contact_frames.append(contact_residues)\n\n    return contact_frames\n```\n\n## Force Fields and Preparation\n\nChoose a validated protein\u002Fligand\u002Fwater\u002Fion combination for the scientific system.\nThe working example retains AMBER14\u002FTIP3P-FB; it is not a universal recommendation.\nCurrent OpenMM also bundles `amber19-all.xml` (ff19SB, DNA OL21, RNA OL3, lipid21),\nand `charmm36_2024.xml` with its own `charmm36_2024\u002Fwater.xml`. Generic TIP3P and\nCHARMM-modified TIP3P are not interchangeable. IDP ensembles are especially\nsensitive to protein-water balance. Four-site waters need extra particles and a\nmatching Modeller geometry, unlike the three-site example above.\n\nAMBER protein XML does not parameterize arbitrary ligands. Use a reviewed GAFF2\nor OpenFF route with explicit stereochemistry, protonation, bond orders, atom\nmapping and charge method. A ligand-only Interchange is not a protein-ligand system.\nSee [preparation reference](references\u002Fsystem_preparation.md) for conservative\nPDBFixer and OpenFF examples, installation requirements and current release details.\n\n## Validation and Provenance\n\n- Start with minimization; finite energy does not establish a valid structure.\n- Use staged NVT → NPT equilibration → production. This example has no restraints.\n- A 2 fs step with constrained H-containing bonds is a starting choice. Larger\n  steps\u002FHMR require integrator, stability and observable validation for that system.\n- Use per-frame boxes for periodic distances. Make molecules whole for structural\n  observables using trusted bond topology; unwrapping cannot infer missing bonds.\n- Assess burn-in, autocorrelation, effective samples, replicas and uncertainties.\n  Short stable temperature\u002Fdensity traces do not establish conformational sampling.\n- Save topology\u002Fatom order, System\u002FIntegrator XML, force-field files\u002Fversions,\n  seeds, platform\u002Fprecision, parameters and analysis selections. Checkpoints are\n  platform\u002Fhardware\u002Fversion specific; XML states are more portable but do not\n  retain all internal random-generator state. Test restarting the actual setup.\n\n## Additional Resources\n\n- **OpenMM documentation**: https:\u002F\u002Fopenmm.org\u002Fdocumentation.html\n- **MDAnalysis user guide**: https:\u002F\u002Fdocs.mdanalysis.org\u002F\n- **GROMACS** (alternative MD engine): https:\u002F\u002Fmanual.gromacs.org\u002F\n- **NAMD** (alternative): https:\u002F\u002Fwww.ks.uiuc.edu\u002FResearch\u002Fnamd\u002F\n- **CHARMM-GUI** (web-based system builder): https:\u002F\u002Fcharmm-gui.org\u002F\n- **AmberTools** (free Amber tools): https:\u002F\u002Fambermd.org\u002FAmberTools.php\n- **OpenMM paper**: Eastman P et al. (2017) PLOS Computational Biology. PMID: 28278240\n- **MDAnalysis paper**: Michaud-Agrawal N et al. (2011) J Computational Chemistry. PMID: 21500218\n",{"name":5,"license":15,"metadata":24,"description":7,"compatibility":28},{"version":25,"skill-author":26,"last-reviewed":27},"1.3","Kuan-lin Huang","2026-10-01","Requires Python 3.11+ with OpenMM and MDAnalysis; matplotlib for plots. Optional PDBFixer and OpenFF need separate installation. Network access for installation; local simulation and analysis run offline.","master","fd76f882a04e445e899d5cfb2732f2105ea054ee","skills\u002Fawesome-skills\u002Fmolecular-dynamics",0,"https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS","https:\u002F\u002Fbg-szy.github.io\u002FTOP-SKILLS\u002F","https:\u002F\u002Fgithub.com\u002Fbg-szy","https:\u002F\u002Fwww.ecust.edu.cn\u002F","a student of East China University of Science and Technology","2026-11-13 06:26:27",{"source":8,"skillName":5,"commands":40,"prompt":50,"zipAvailable":51},[41,44,47],{"tool":42,"command":43},"npx","npx skills add bg-szy\u002FTOP-SKILLS --skill molecular-dynamics",{"tool":45,"command":46},"bunx","bunx skills add bg-szy\u002FTOP-SKILLS --skill molecular-dynamics",{"tool":48,"command":49},"pnpm","pnpm dlx skills add bg-szy\u002FTOP-SKILLS --skill molecular-dynamics","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fawesome-skills\u002Fmolecular-dynamics\u002FSKILL.md",true,[],[54,63,70,77,86,94],{"skillNo":55,"name":56,"nameZh":6,"description":57,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":58,"sourceHtmlUrl":59,"categories":60,"keywords":61,"publishedAt":62},"01M76KTXGSTXVVDC7YSBM41ZZS","wxpusher-integration","Use when（适用场景）：用户明确询问、指定或上下文已选定 WxPusher，需要了解、接入或排查通知（含微信 ClawBot\u002FiLink、appToken、UID、Topic、SPT）；仅说“微信通知”、未选服务商，或只出现通用 UID\u002FTopic 时不触发。","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fmarketplace\u002Fwxpusher-integration\u002FLICENSE.md","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fmarketplace\u002Fwxpusher-integration\u002FSKILL.md",[],[],"2026-11-12 13:55:43",{"skillNo":64,"name":65,"nameZh":6,"description":66,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":67,"categories":68,"keywords":69,"publishedAt":19},"01M748C5DS5BQBVBMG22FCGG34","branding","When the user wants to define, audit, or apply brand strategy—purpose, values, positioning, storytelling, voice, narrative (not only visuals). Also use when the user mentions \"brand strategy\", \"brand story\", \"brand storytelling\" or \"brand voice\". For typography, colors, design tokens, and frontend visuals, use brand-visual-generator.","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fsuperskills\u002Fbranding\u002FSKILL.md",[],[],{"skillNo":71,"name":72,"nameZh":6,"description":73,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":76,"publishedAt":19},"01M748C1GXJ9WRKP18X45DKP6G","brand-visual-generator","When the user wants to define, audit, or apply visual identity (typography, colors, spacing, design tokens, frontend aesthetics). Also use when the user mentions \"brand style guide\", \"visual identity\", \"design system\" or \"typography\". For brand story, positioning, and voice, use branding.","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fsuperskills\u002Fbrand-visual-generator\u002FSKILL.md",[],[],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":81,"licenseFileUrl":82,"sourceHtmlUrl":83,"categories":84,"keywords":85,"publishedAt":19},"01M747T565TFEP3RAVWM0Y899Y","mcp-builder","Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node\u002FTypeScript (MCP SDK).","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fskills\u002Fmcp-builder\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fskills\u002Fmcp-builder\u002FSKILL.md",[],[],{"skillNo":87,"name":88,"nameZh":6,"description":89,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":81,"licenseFileUrl":90,"sourceHtmlUrl":91,"categories":92,"keywords":93,"publishedAt":19},"01M747RAJGMBZ2QN4563STB5SH","frontend-design","Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fskills\u002Ffrontend-design\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fskills\u002Ffrontend-design\u002FSKILL.md",[],[],{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":81,"licenseFileUrl":98,"sourceHtmlUrl":99,"categories":100,"keywords":101,"publishedAt":19},"01M747NHAY5BE9GXEB31H255R1","claude-api","Reference for the Claude API \u002F Anthropic SDK — model ids, pricing, params, streaming, tool use, MCP, agents, caching, token counting, model migration.\nTRIGGER — read BEFORE opening the target file; don't skip because it \"looks like a one-liner\" — whenever: the prompt names Claude\u002FAnthropic in any form (Claude, Anthropic, Fable, Opus, Sonnet, Haiku, `anthropic`, `@anthropic-ai`, `claude-*`, `us.anthropic.*`, `[1m]`); the user asks about an LLM (pricing\u002Fmodel choice\u002Flimits\u002Fcaching) — never answer from memory; OR the task is LLM-shaped with provider unstated (agent\u002FMCP\u002Ftool-definition\u002Fmulti-agent\u002FRAG\u002FLLM-judge\u002Fcomputer-use; generate\u002Fsummarize\u002Fextract\u002Fclassify\u002Frewrite\u002Fconverse over NL; debugging refusals\u002Fcutoffs\u002Fstreaming\u002Ftool-calls\u002Ftokens).\nSKIP only when another provider is being worked on (overrides all triggers): OpenAI\u002FGPT\u002FGemini\u002FLlama\u002FMistral\u002FCohere\u002FOllama named in the query; OR `grep -rE 'openai|langchain_openai|google.generativeai|genai|mistralai|cohere|ollama'` over the project hits (run this grep FIRST if no provider named — don't Read the file).","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fskills\u002Fclaude-api\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fbg-szy\u002FTOP-SKILLS\u002Fblob\u002Fmaster\u002Fskills\u002Fskills\u002Fclaude-api\u002FSKILL.md",[],[]]