DiffDock Molecular Docking
K-Dense-AI/scientific-agent-skills
Predicts how small molecules bind to a protein with DiffDock, covering batch docking, pose ranking by confidence and checks on the results; not for binding affinity.
Read, write, and edit ChemDraw CDX/CDXML files with RDKit's rdkit.Chem.rdChemDraw plus direct XML editing, always paired with a rendered PNG.
$ npx skills add jaechang-hits/SciAgent-Skills --skill rdkit-chemdraw-cdxml -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install jaechang-hits/SciAgent-Skills rdkit-chemdraw-cdxml --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/jaechang-hits/SciAgent-Skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml .claude/skills/rdkit-chemdraw-cdxml && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "rdkit-chemdraw-cdxml" agent skill from https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml into .claude/skills/rdkit-chemdraw-cdxml/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rdkit-chemdraw-cdxml", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxmlType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add jaechang-hits/SciAgent-Skills --skill rdkit-chemdraw-cdxml -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install jaechang-hits/SciAgent-Skills rdkit-chemdraw-cdxml --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jaechang-hits/SciAgent-Skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml .agents/skills/rdkit-chemdraw-cdxml && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "rdkit-chemdraw-cdxml" agent skill from https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml into .agents/skills/rdkit-chemdraw-cdxml/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rdkit-chemdraw-cdxml", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jaechang-hits/SciAgent-Skills --skill rdkit-chemdraw-cdxml -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install jaechang-hits/SciAgent-Skills rdkit-chemdraw-cdxml --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jaechang-hits/SciAgent-Skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml .cursor/skills/rdkit-chemdraw-cdxml && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "rdkit-chemdraw-cdxml" agent skill from https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml into .cursor/skills/rdkit-chemdraw-cdxml/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rdkit-chemdraw-cdxml", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/jaechang-hits/SciAgent-Skills.git --path skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add jaechang-hits/SciAgent-Skills --skill rdkit-chemdraw-cdxml -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install jaechang-hits/SciAgent-Skills rdkit-chemdraw-cdxml --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jaechang-hits/SciAgent-Skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml .gemini/skills/rdkit-chemdraw-cdxml && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "rdkit-chemdraw-cdxml" agent skill from https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml into .gemini/skills/rdkit-chemdraw-cdxml/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rdkit-chemdraw-cdxml", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install jaechang-hits/SciAgent-Skills rdkit-chemdraw-cdxmlInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add jaechang-hits/SciAgent-Skills --skill rdkit-chemdraw-cdxml -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/jaechang-hits/SciAgent-Skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml .github/skills/rdkit-chemdraw-cdxml && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "rdkit-chemdraw-cdxml" agent skill from https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml into .github/skills/rdkit-chemdraw-cdxml/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rdkit-chemdraw-cdxml", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jaechang-hits/SciAgent-Skills --skill rdkit-chemdraw-cdxml -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install jaechang-hits/SciAgent-Skills rdkit-chemdraw-cdxml --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jaechang-hits/SciAgent-Skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml .opencode/skills/rdkit-chemdraw-cdxml && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "rdkit-chemdraw-cdxml" agent skill from https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml into .opencode/skills/rdkit-chemdraw-cdxml/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "rdkit-chemdraw-cdxml", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
rdkit-chemdraw-cdxmlRead, write, and edit ChemDraw CDX/CDXML files with RDKit's rdkit.Chem.rdChemDraw plus direct XML editing, always paired with a rendered PNG.
Rdkit Chemdraw Cdxml is an agent skill from jaechang-hits/SciAgent-Skills. Read, write, and edit ChemDraw CDX/CDXML files with RDKit's rdkit.Chem.rdChemDraw plus direct XML editing, always paired with a rendered PNG. Parse molecules and reactions from .cdxml/.cdx, write structures with good 2D depiction, and hand-build or modify the parts RDKit cannot write: reaction arrows, plus signs, schemes/steps, and text/labels. Use for reaction schemes, synthesis routes, mechanisms, retrosynthesis, or SI figures. Critical: RDKit writes structures only — round-tripping a reaction through a Mol…
Its SKILL.md is about 6.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 5 other files, including scripts and reference files (for example `references/cdxml-schema-reference.md`, `scripts/build_reaction_scheme.py` and `scripts/check_scheme.py`).
It sits in Research & Science, covering Drug discovery and cheminformatics. It works with RDKit. The repository describes itself as: 197 bioinformatics & life science skills for Claude Code and AI agents — BixBench 92.0% accuracy. RNA-seq, single-cell, drug discovery, proteomics, and more. Powers OmicsHorizon. The licence is BSD-3-Clause.
2 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 82c862c. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Ships 2 files in scripts/ (Python), which the agent can run.
Shell commands in SKILL.md call:
pythonpipFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
lifescience.opensource.epam.comrdkit.orgchemapps.stolaf.edugithub.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Rdkit Chemdraw Cdxml loads about 6.9k tokens when it runs, and up to ~9k if it reads all its reference files. Until then it costs about 189 tokens; SKILL.md has 2,056 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.
The full file from jaechang-hits/SciAgent-Skills at commit 82c862c, republished under its BSD-3-Clause licence (© jaechang-hits). 2,056 words, ~6,914 tokens.
.claude/skills/rdkit-chemdraw-cdxml/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.CDXML is an XML serialization of ChemDraw's object tree (CDX is its binary form). RDKit 2022.09+ exposes an optional Revvity ChemDraw parser at rdkit.Chem.rdChemDraw that reads molecules and reactions and writes molecule structures. RDKit cannot write arrows, plus signs, schemes, or text — those are built or edited at the XML level. This skill covers the full read → depict → annotate → write → modify → render loop.
A .cdxml is not viewable without ChemDraw, and you cannot run ChemDraw here — so the rendered PNG is the only evidence the file is correct. Therefore:
<name>.cdxml and <name>.png together, matching basenames — never the CDXML alone. build_scheme() and Module 9 write both; the helper raises if the PNG cannot be produced.scripts/check_scheme.py (rebuilds each molecule from the drawing, sanitizes, checks mass balance across arrows, and critiques layout). Drive it to zero problems..cdxml files that open cleanly in ChemDraw.cdxml or .cdx+ separators + conditions textrdkit-cheminformatics instead for descriptors/fingerprints/SMARTS with no ChemDraw I/Oopenbabel; this toolkit is 2D ChemDraw-specificrdkit (2023.03+, built with ChemDraw support), epam.indigo (renders CDXML→PNG); xml.etree.ElementTree (stdlib) handles all XML editing..cdxml (UTF-8 text) or .cdx (binary) for reading.python -c "import rdkit" first; inside pixi use pixi run python ....epam.indigo into the interpreter that runs your code. A bare pip install can land in a different Python than the kernel (e.g. system /usr/local vs the pixi env that has rdkit), so import indigo still fails even though the install "succeeded" — and no single interpreter then has both rdkit and indigo. In a Jupyter/IPython kernel use %pip install epam.indigo; otherwise python -m pip install epam.indigo (the running interpreter), or add it to the project env (pixi add epam.indigo). For the same reason, do not run the build/render in a fresh subprocess (["python", …] may resolve yet another interpreter) — import the helper and run it in the current process.python -m pip install epam.indigo # the running interpreter; or %pip install epam.indigo in Jupyter
python -c "from rdkit import Chem; print('ChemDraw write support:', Chem.HasChemDrawCDXSupport())"from rdkit import Chem
from rdkit.Chem import rdChemDraw, rdDepictor
mol = Chem.MolFromSmiles("CC(=O)Oc1ccccc1C(=O)O") # aspirin
rdDepictor.SetPreferCoordGen(True)
rdDepictor.Compute2DCoords(mol) # coordinates are REQUIRED before writing
cdxml = rdChemDraw.MolToChemDrawBlock(mol, rdChemDraw.CDXFormat.CDXML) # -> str
open("aspirin.cdxml", "w", encoding="utf-8").write(cdxml)MolsFromChemDrawFile / MolsFromChemDrawBlock handle both .cdx and .cdxml, returning a tuple of Mol (one per fragment).
from rdkit import Chem
from rdkit.Chem import rdChemDraw
mols = rdChemDraw.MolsFromChemDrawFile("drawing.cdxml", sanitize=True, removeHs=True)
for m in mols:
print(Chem.MolToSmiles(m))
block = open("drawing.cdxml", encoding="utf-8").read()
mols = rdChemDraw.MolsFromChemDrawBlock(block, sanitize=True, removeHs=True)
mols_legacy = Chem.MolsFromCDXML(block) # CDXML-only fallback, no ChemDraw SDK neededReactionsFromChemDrawBlock interprets <step>/<arrow> and returns ChemicalReactions with reactants, agents, and products split out. Note the reaction reader defaults sanitize=False.
from rdkit import Chem
from rdkit.Chem import rdChemDraw, rdChemReactions
block = open("reaction.cdxml", encoding="utf-8").read()
for rxn in rdChemDraw.ReactionsFromChemDrawBlock(block, sanitize=True):
print("reactants:", [Chem.MolToSmiles(m) for m in rxn.GetReactants()])
print("products :", [Chem.MolToSmiles(m) for m in rxn.GetProducts()])
rxns = rdChemReactions.ReactionsFromCDXMLBlock(block, sanitize=True) # legacy equivalentMolToChemDrawBlock writes one molecule to CDXML (str). CDX (binary) write is broken in rdChemDraw (UnicodeDecodeError); use the legacy writer for CDX bytes.
from rdkit import Chem
from rdkit.Chem import rdChemDraw, rdDepictor, rdmolfiles
mol = Chem.MolFromSmiles("c1ccccc1O")
rdDepictor.Compute2DCoords(mol) # coords first, always
cdxml = rdChemDraw.MolToChemDrawBlock(mol, rdChemDraw.CDXFormat.CDXML) # str (preferred)
cdx_bytes = Chem.MolToCDXMLBlock(mol, rdmolfiles.CDXMLFormat.CDX) # bytes (legacy writer)Layout quality is set before writing. CoordGen gives more natural coordinates; template alignment keeps a shared scaffold oriented consistently across a series. Note: CoordGen still tangles cages and bridged bicyclics — check those in the render.
from rdkit import Chem
from rdkit.Chem import rdDepictor
rdDepictor.SetPreferCoordGen(True)
mol = Chem.MolFromSmiles("O=C(Nc1ccc(cc1)S(=O)(=O)N)C")
rdDepictor.Compute2DCoords(mol)
rdDepictor.StraightenDepiction(mol)
rdDepictor.NormalizeDepiction(mol) # uniform median bond length# Align a series to a shared scaffold so the core is drawn identically each time
template = Chem.MolFromSmiles("c1ccc(cc1)S(=O)(=O)N")
rdDepictor.Compute2DCoords(template)
for m in [Chem.MolFromSmiles(s) for s in ["Cc1ccc(cc1)S(=O)(=O)N", "Clc1ccc(cc1)S(=O)(=O)N"]]:
rdDepictor.GenerateDepictionMatching2DStructure(m, template)A reaction arrow is an <arrow> with Head3D/Tail3D ("x y z", y increases downward). ArrowheadHead/ArrowheadType style the head. Equilibrium/resonance/retrosynthetic arrows use a <graphic> Line with ArrowType.
import xml.etree.ElementTree as ET
def make_arrow(arrow_id, tail_xy, head_xy):
(tx, ty), (hx, hy) = tail_xy, head_xy
return ET.Element("arrow", {
"id": str(arrow_id), "FillType": "None", "ArrowheadType": "Solid",
"ArrowheadHead": "Full", "HeadSize": "2250",
"BoundingBox": f"{min(tx,hx)} {min(ty,hy)-4} {max(tx,hx)} {max(ty,hy)+4}",
"Head3D": f"{hx} {hy} 0", "Tail3D": f"{tx} {ty} 0"})
print(ET.tostring(make_arrow(40, (160, 100), (210, 100)), encoding="unicode"))
equil = ET.Element("graphic", {"id": "41", "GraphicType": "Line",
"ArrowType": "Equilibrium", "BoundingBox": "160 100 210 100"})A <scheme> groups <step> objects that reference page objects by id: ReactionStepReactants, ReactionStepProducts, ReactionStepArrows, ReactionStepPlusses, and objects above/below the arrow.
import xml.etree.ElementTree as ET
def make_plus(gid, x, y):
return ET.Element("graphic", {"id": str(gid), "GraphicType": "Symbol",
"SymbolType": "Plus", "BoundingBox": f"{x} {y-7} {x+15} {y+8}"})
scheme = ET.Element("scheme", {"id": "60"})
ET.SubElement(scheme, "step", {"id": "61", "ReactionStepReactants": "10 20",
"ReactionStepProducts": "50", "ReactionStepArrows": "40",
"ReactionStepPlusses": "30", "ReactionStepObjectsAboveArrow": "70"})
print(ET.tostring(scheme, encoding="unicode"))Free text is a <t> at p="x y" holding one or more <s> styled-string children. <s> references a font id (<fonttable>) and color index (<colortable>); face is a bitmask (1=bold, 2=italic, 32=subscript, 64=superscript). Split a <t> into multiple <s> runs for subscripts (Br₂, CO₂H). Indigo renders subscript (32) but not superscript (64) — it drops the run's leading text — so keep charges inline (H+, OH-). °C (temperatures) and Δ (heat) render with the Arial font; avoid other non-Latin-1 characters (hν, en-dashes).
import xml.etree.ElementTree as ET
def make_text(tid, x, y, runs, font_id=21, size=10):
"""runs: list of (text, face). face 0=normal, 1=bold, 32=subscript, 64=superscript."""
t = ET.Element("t", {"id": str(tid), "p": f"{x} {y}"})
for text, face in runs:
ET.SubElement(t, "s", {"font": str(font_id), "size": str(size),
"color": "0", "face": str(face)}).text = text
return t
print(ET.tostring(make_text(70, 175, 92, [("reflux, 2 h", 0)]), encoding="unicode"))
print(ET.tostring(make_text(80, 158, 135, [("Br", 0), ("2", 32), (" (excess)", 0)]),
encoding="unicode")) # Br<sub>2</sub> (excess)ElementTree round-trips arrows, text, and graphics it does not understand, so you can edit a real ChemDraw file without losing objects — unlike an RDKit Mol round-trip.
import xml.etree.ElementTree as ET
tree = ET.parse("reaction.cdxml") # DOCTYPE is dropped on re-save (harmless)
root = tree.getroot()
for s in root.iter("s"): # relabel "Cl" -> "Br"
if s.text == "Cl":
s.text = "Br"
cap = ET.SubElement(root.find("page"), "t", {"p": "100 300"})
ET.SubElement(cap, "s", {"font": "21", "size": "12", "color": "0"}).text = "Scheme 1"
tree.write("reaction_edited.cdxml", encoding="unicode", xml_declaration=True)Render the PNG next to the CDXML (same basename), look at it, then deliver both. Indigo (epam.indigo) loads a CDXML — a scheme with arrows as a reaction, a lone structure as a molecule — and rasterizes arrows, text, and layout faithfully. (RDKit's own Draw.ReactionToImage re-lays-out molecules and drops the ChemDraw arrows/text, so use Indigo to render a file as authored.)
from pathlib import Path
from indigo import Indigo
from indigo.renderer import IndigoRenderer
def render_cdxml(cdxml_path, png_path=None, width=1600):
png_path = png_path or str(Path(cdxml_path).with_suffix(".png"))
ind = Indigo(); rnd = IndigoRenderer(ind)
ind.setOption("render-output-format", "png")
ind.setOption("render-background-color", "1,1,1")
ind.setOption("render-image-width", width)
cdxml = open(cdxml_path, encoding="utf-8").read()
try:
obj = ind.loadReaction(cdxml) # scheme with arrows
except Exception:
obj = ind.loadMolecule(cdxml) # single structure
rnd.renderToFile(obj, png_path)
return png_path
print("Wrote", render_cdxml("scheme.cdxml"))y increases downward (origin top-left). Atoms: p="x y"; arrows: Head3D/Tail3D="x y z"; graphics/text: BoundingBox="x1 y1 x2 y2". Default bond length ≈ 30.
def shift_fragment(frag, dx, dy): # move a fragment onto the canvas
for n in frag.iter("n"):
x, y = map(float, n.get("p").split())
n.set("p", f"{x+dx} {y+dy}")
return fragEvery object has a unique integer id; reactions and groups reference members by id, not by nesting. When merging fragments from separate RDKit outputs (each starts ids at 1), renumber all ids to stay globally unique, then wire <step> to the new ids.
| Task | RDKit rdChemDraw | Direct XML |
|---|---|---|
| Read molecules / reactions | ✅ | — |
| Write molecule structure | ✅ (CDXML) | — |
| Write arrows / plus / scheme / text | ❌ | ✅ |
| Preserve objects while editing | ❌ (drops on Mol round-trip) | ✅ |
from rdkit import Chem
from rdkit.Chem import rdChemDraw, rdDepictor
def smiles_to_cdxml(smiles, path):
mol = Chem.MolFromSmiles(smiles)
if mol is None:
raise ValueError(f"Invalid SMILES: {smiles}")
rdDepictor.SetPreferCoordGen(True)
rdDepictor.Compute2DCoords(mol)
rdDepictor.StraightenDepiction(mol)
open(path, "w", encoding="utf-8").write(rdChemDraw.MolToChemDrawBlock(mol))
return path
print("Wrote", smiles_to_cdxml("CC(=O)Oc1ccccc1C(=O)O", "aspirin.cdxml"))Combine _fragment_of (write a mol, extract <fragment>, renumber ids, shift x) with an arrow, a plus, conditions text, and a <step>. Render with Module 9. For multi-step schemes prefer Workflow 4.
from rdkit import Chem
from rdkit.Chem import rdChemDraw, rdDepictor, rdChemReactions
import xml.etree.ElementTree as ET
def _fragment_of(smiles, base_id, dx):
m = Chem.MolFromSmiles(smiles); rdDepictor.Compute2DCoords(m)
frag = ET.fromstring(rdChemDraw.MolToChemDrawBlock(m)).find("page/fragment")
remap = {}
for i, el in enumerate([frag, *frag.iter("n"), *frag.iter("b")]):
remap[el.get("id")] = str(base_id + i); el.set("id", remap[el.get("id")])
for b in frag.iter("b"):
b.set("B", remap[b.get("B")]); b.set("E", remap[b.get("E")])
for n in frag.iter("n"):
x, y = map(float, n.get("p").split()); n.set("p", f"{x+dx} {y}")
return frag
root = ET.Element("CDXML", {"BondLength": "30"}); page = ET.SubElement(root, "page")
page.append(_fragment_of("CCO", 100, 0))
ET.SubElement(page, "graphic", {"id": "30", "GraphicType": "Symbol",
"SymbolType": "Plus", "BoundingBox": "60 -7 75 8"})
page.append(_fragment_of("CC(=O)O", 200, 120))
ET.SubElement(page, "arrow", {"id": "40", "FillType": "None", "ArrowheadHead": "Full",
"ArrowheadType": "Solid", "HeadSize": "2250", "Head3D": "320 3 0", "Tail3D": "260 3 0"})
cond = ET.SubElement(page, "t", {"id": "70", "p": "270 -12"})
ET.SubElement(cond, "s", {"font": "21", "size": "9", "color": "0"}).text = "H+, reflux"
page.append(_fragment_of("CCOC(C)=O", 300, 420))
scheme = ET.SubElement(page, "scheme", {"id": "60"})
ET.SubElement(scheme, "step", {"id": "61", "ReactionStepReactants": "100 200",
"ReactionStepProducts": "300", "ReactionStepArrows": "40", "ReactionStepPlusses": "30"})
ET.SubElement(ET.SubElement(root, "fonttable"), "font",
{"id": "21", "charset": "x-mac-roman", "name": "Helvetica"})
cdxml = ET.tostring(root, encoding="unicode")
open("esterification.cdxml", "w", encoding="utf-8").write(cdxml)
print("reactions re-parsed:", len(rdChemReactions.ReactionsFromCDXMLBlock(cdxml, sanitize=True)))import xml.etree.ElementTree as ET
tree = ET.parse("input_reaction.cdxml"); root = tree.getroot()
title = ET.SubElement(root.find("page"), "t", {"p": "50 -30"})
ET.SubElement(title, "s", {"font": "21", "size": "14", "color": "0", "face": "1"}).text = "Route A"
for arrow in root.iter("arrow"):
arrow.set("HeadSize", "3000")
tree.write("output_reaction.cdxml", encoding="unicode", xml_declaration=True)scripts/build_reaction_scheme.py turns (smiles, name, conditions) steps into a laid-out scheme and its PNG in one call, handling grid layout, globally unique ids, single arrows, and conditions text placed clear of structures — the defects that recur when schemes are hand-built. Cells auto-size to the largest structure, so big molecules never overlap. Model convergent/multi-component steps by folding co-reactants into conditions (e.g. ["+ (MeO2C)2C=CHOMe", "Base, MeCN"]), keeping one main-chain structure per cell.
Copy the scripts into your working directory with your file tools — not from Python. Inside the execution sandbox the /SciAgent-Skills/... path is reachable only through your read-file tool; it is not on the sandbox filesystem, so a Python open() or import of that path fails with FileNotFoundError/ModuleNotFoundError. For each of build_reaction_scheme.py and check_scheme.py (each is self-contained — rdkit + epam.indigo only — copy just what you need):
/SciAgent-Skills/skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml/scripts/<name> (the leading slash routes to the skills backend) → returns the script text../<name> in the working directory.Then import the local copies. (Importing writes a harmless __pycache__/; set PYTHONDONTWRITEBYTECODE=1 to suppress it.)
from build_reaction_scheme import build_scheme # local copies, already in the workdir
from check_scheme import check_all
steps = [
{"smiles": "O=C1CCCC1", "name": "cyclopentanone"},
{"smiles": "O=C1C(Br)C(Br)C(Br)C1Br", "name": "tetrabromoketone",
"conditions": ["Br2 (excess)", "AcOH, 25 C"]}, # reagents for the arrow into this step
{"smiles": "O=C1C=CC=C1Br", "name": "2-bromocyclopentadienone",
"conditions": ["Et2NH", "cold Et2O"]},
{"smiles": "C12C3C4C1C5C2C3C45", "name": "cubane", "conditions": ["(remaining steps)"]},
]
cdxml, png = build_scheme(steps, "cubane.cdxml", title="Total Synthesis of Cubane", cols=4)
check_all("cubane.cdxml", expect={3: "C12C3C4C1C5C2C3C45"}) # validate before delivering
print(f"Deliverables: {cdxml} + {png}")| Parameter | Module / Function | Default | Options | Effect |
|---|---|---|---|---|
format | MolToChemDrawBlock | CDXFormat.CDXML | CDXML, CDX | Use CDXML (str); for CDX bytes use legacy MolToCDXMLBlock |
sanitize | MolsFromChemDrawBlock | True | True/False | False to inspect raw/invalid input |
sanitize | ReactionsFromChemDrawBlock | False | True/False | Defaults False — pass True for clean SMILES |
SetPreferCoordGen | rdDepictor | False | True/False | True gives more natural 2D layouts |
ArrowheadHead | <arrow> XML | — | Full, HalfLeft, HalfRight, None | Arrowhead style |
ArrowType | <graphic> Line | — | FullHead, Equilibrium, Resonance, RetroSynthetic, NoGo | Special arrow semantics |
BondLength | <CDXML> root | "" (RDKit) | numeric, e.g. 30 | Canvas scale; set a number so structures/arrows scale together |
SetPreferCoordGen(True) then Compute2DCoords); a molecule without coordinates writes as a degenerate layout.<step> references and doubles arrows; renumber into disjoint blocks.rdChemDraw raises UnicodeDecodeError; only legacy Chem.MolToCDXMLBlock(mol, CDXMLFormat.CDX) returns valid CDX bytes.<CDXML BondLength=...> plus a standard <fonttable>/<colortable> and page dimensions. See references/cdxml-schema-reference.md.°C for temperatures and Δ for heat (both render); keep charges inline (H+, OH-) since Indigo has no superscript; avoid other non-Latin-1 characters. Render heteroatoms via <n Element=...>, not free <t> text; don't add decorative flags ("Chiral"/"racemic") — use wedge bonds. Keep labels clear of the arrow line: names under the structure, conditions offset above/beside the arrow. (build_scheme does all of this — 0 C→0 °C, heat→Δ, subscripts, spacing — automatically.)check_scheme.check_all first. The render and the critic catch overlaps, duplicate/degenerate arrows, dropped intermediates, and connectivity errors before the user sees them.from rdkit import Chem
from rdkit.Chem import rdChemDraw, rdDepictor
from pathlib import Path
rdDepictor.SetPreferCoordGen(True); Path("out").mkdir(exist_ok=True)
for i, smi in enumerate(["CCO", "c1ccccc1", "CC(=O)O"]):
m = Chem.MolFromSmiles(smi); rdDepictor.Compute2DCoords(m)
Path(f"out/mol_{i}.cdxml").write_text(rdChemDraw.MolToChemDrawBlock(m), encoding="utf-8")import xml.dom.minidom as minidom
print(minidom.parseString(open("esterification.cdxml", encoding="utf-8").read())
.toprettyxml(indent=" ")[:1500])| Problem | Cause | Solution |
|---|---|---|
Exception on MolToChemDrawBlock | RDKit built without ChemDraw support | Check Chem.HasChemDrawCDXSupport(); install a build with the Revvity parser |
UnicodeDecodeError writing CDX | rdChemDraw CDX path is broken | Use legacy Chem.MolToCDXMLBlock(mol, CDXMLFormat.CDX), or write CDXML |
| Structure written flat/overlapping | No 2D coordinates | Call rdDepictor.Compute2DCoords(mol) before writing |
| Edited reaction lost arrows/text | File round-tripped through a Mol | Edit the XML tree (ElementTree); RDKit writes structures only |
| Reaction won't re-parse | <step> references missing ids (collision after merge) | Renumber fragment ids globally unique; update ReactionStep* |
| Structures/arrows mismatched size | <CDXML BondLength=""> empty | Set a numeric BondLength (e.g. 30) on the root |
mols tuple empty on read | Wrong format, or unsanitizable structure | Retry with sanitize=False; confirm the file is genuine CDX/CDXML |
| Doubled labels ("OO", "BrBr") | Free-text <t> on top of Element nodes | Remove the free labels; let <n Element=...> render the symbol |
| Stray line crosses a structure | Duplicate or degenerate <arrow> | Run check_scheme; unique id + real length (Head3D≠Tail3D) per arrow |
| Conditions text overlaps a structure | Text placed on the structure, not over the arrow gap | Center conditions over the arrow midpoint; widen structure spacing |
| Text renders wrong/blank | non-ASCII, or <s font> id missing from <fonttable> | Keep text ASCII; reference an existing font id |
| No PNG / render error | epam.indigo missing, or loaded as molecule when it has arrows | pip install epam.indigo; try loadReaction before loadMolecule |
| "Chiral"/"racemic" printed above structures | Decorative flag text added as <t> | Remove it — stereochemistry is shown by wedge bonds; check_scheme flags it |
| A name or label sits on an arrow | Text placed on the arrow line | Names go under the structure, conditions offset above/beside the arrow; check_scheme flags text on an arrow |
stoi: no conversion loading in Indigo | <CDXML BondLength=""> empty | Set a numeric BondLength (e.g. 30) before rendering |
ModuleNotFoundError/FileNotFoundError on a helper script | imported or open()ed the /SciAgent-Skills/... path from Python | That path is reachable only via the read-file tool, not the sandbox filesystem — copy the script into the workdir first (Workflow 4), then import |
import indigo fails after a "successful" pip install | pip installed into a different Python than the runtime (system /usr/local vs the pixi/kernel env) | Install into the running interpreter (%pip install or python -m pip install), or pixi add epam.indigo; don't shell out to a different python |
A charge (H+) renders as a giant + | Indigo draws a standalone + as a reaction-plus symbol, and superscript (face 64) mangles ion text | Keep charges inline (H+, OH-), face 0 — a true raised superscript is not achievable in the Indigo preview. Subscripts (face 32) and °C/Δ render fine |
The scripts/ files can be read from the skill path but not imported from there — copy the one you need into your working directory (read_file it, write locally), then import or run it (see Workflow 4 for the exact copy snippet). Each is self-contained and depends only on rdkit (+ epam.indigo).
references/cdxml-schema-reference.md — element/attribute cheat-sheet (n, b, arrow, graphic, step/scheme, t/s, fonttable, colortable), coordinate conventions, enum tables, and a copy-paste document header.scripts/build_reaction_scheme.py — assemble a multi-step scheme from (smiles, name, conditions) steps and render the PNG in one call; auto-sizes cells so structures never overlap. Library (build_scheme(...)) or CLI (python build_reaction_scheme.py steps.json out.cdxml out.png "Title").scripts/check_scheme.py — pre-delivery validator/critic. check_all(path, expect=..., perspective_ids=...) rebuilds each molecule from the drawing, sanitizes, prints formulas for a mass-balance check, and flags duplicate ids, fragment overlaps, degenerate arrows, non-ASCII text, decorative flag words ("Chiral"), and labels sitting on an arrow line.rdkit.Chem.rdChemDraw — MolsFromChemDraw*, ReactionsFromChemDraw*, MolToChemDrawBlock, CDXFormat.cdxmlepam.indigo) — CDXML loading and PNG rendering© jaechang-hits, BSD-3-Clause. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 3 other files (scripts, references) in skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml of jaechang-hits/SciAgent-Skills.
Open the folder on GitHubat commit 82c862c
Rdkit Chemdraw Cdxml next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Rdkit Chemdraw Cdxml this skilljaechang-hits/SciAgent-Skills | 371 | — | ~6.9k | Automated safety check: Pass | BSD-3-Clause | |
| DiffDock Molecular DockingK-Dense-AI/scientific-agent-skills | 48k | 1 repos | ~3k | Automated safety check: Notes | MIT | |
| Edu Chem Reactionwy51ai/edulab | 1.4k | — | ~1.2k | Automated safety check: Pass | Apache-2.0 | |
| Biopipelineslocbp-uzh/biopipelines | 109 | — | ~2.4k | Automated safety check: Pass | MIT | |
| RDKit Cheminformatics Practicesaiming-lab/AutoResearchClaw | 15k | — | ~708 | Automated safety check: Pass | MIT | |
| Rowanlamm-mit/scienceclaw | 244 | 4 repos | ~3.1k | Automated safety check: Warn | Proprietary |
K-Dense-AI/scientific-agent-skills
Predicts how small molecules bind to a protein with DiffDock, covering batch docking, pose ranking by confidence and checks on the results; not for binding affinity.
wy51ai/edulab
把一个化学反应做成自包含的微观 3D 交互演示网页:左/上为 Three.js 可交互分子动画 (拖滑块看断键·成键·原子重组,分步高亮),右为 KaTeX 反应方程 + 分步讲解 + 原子守恒计数 + 可选能量-反应进程曲线。支持三入口——给定文字反应/方程、随机出题、上传图片识别后演示。
locbp-uzh/biopipelines
Design and run computational protein and ligand workflows on a GPU: binder and enzyme design, de novo backbone generation, inverse folding and sequence redesign, structure prediction, protein-ligand…
aiming-lab/AutoResearchClaw
Reference guide for working with molecules in RDKit: reading SMILES and SDF files, computing descriptors and fingerprints, and searching substructures.
lamm-mit/scienceclaw
Cloud-based quantum chemistry platform with Python API. An agent skill from lamm-mit/scienceclaw.
pemsley/coot
RDKit molecular manipulation and visualization within Coot's Python environment.
jaechang-hits/SciAgent-Skills
NEB-IRC activation energy pipeline for reaction barriers using GFN2-xTB and pysisyphus.
jaechang-hits/SciAgent-Skills
3Dmol.js WebGL molecular visualization emitted as self-contained HTML.
jaechang-hits/SciAgent-Skills
Constraint-based (COBRA) analysis of genome-scale metabolic models: FBA, FVA, knockouts, flux sampling, production envelopes, gapfilling, media optimization.
jaechang-hits/SciAgent-Skills
Programmatic PubMed access via NCBI E-utilities REST API. An agent skill from jaechang-hits/SciAgent-Skills.
jaechang-hits/SciAgent-Skills
Scaffold a new SciAgent-Skills entry. An agent skill from jaechang-hits/SciAgent-Skills.
jaechang-hits/SciAgent-Skills
Model interpretability via SHAP (Shapley values from game theory).
Works with
Categories
Read, write, and edit ChemDraw CDX/CDXML files with RDKit's rdkit.Chem.rdChemDraw plus direct XML editing, always paired with a rendered PNG. Rdkit Chemdraw Cdxml is an agent skill from jaechang-hits/SciAgent-Skills.rdChemDraw plus direct XML editing, always paired with a rendered PNG.
Rdkit Chemdraw Cdxml fits situations like: reaction schemes; synthesis routes.
Run `npx skills add jaechang-hits/SciAgent-Skills --skill rdkit-chemdraw-cdxml -a claude-code`. Or copy the skill folder (skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml in jaechang-hits/SciAgent-Skills) into .claude/skills/rdkit-chemdraw-cdxml in your project. Claude Code loads it when a task matches its description.
Run `npx skills add jaechang-hits/SciAgent-Skills --skill rdkit-chemdraw-cdxml -a codex`. Or copy the skill folder (skills/structural-biology-drug-discovery/rdkit-chemdraw-cdxml in jaechang-hits/SciAgent-Skills) into .agents/skills/rdkit-chemdraw-cdxml in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jaechang-hits/SciAgent-Skills --skill rdkit-chemdraw-cdxml -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/rdkit-chemdraw-cdxml, .gemini/skills/rdkit-chemdraw-cdxml, .github/skills/rdkit-chemdraw-cdxml and .opencode/skills/rdkit-chemdraw-cdxml in your project.
Going by SKILL.md and its folder, Rdkit Chemdraw Cdxml needs Python for the scripts in its folder and the command-line tools its instructions call (python and pip). Our summary lists: Python 3.
SKILL.md names 4 domains. As links in the text: lifescience.opensource.epam.com, rdkit.org, chemapps.stolaf.edu and github.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.
Rdkit Chemdraw Cdxml is published under the BSD-3-Clause licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.9k tokens (SKILL.md is roughly 28k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 2.1k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Rdkit Chemdraw Cdxml: DiffDock Molecular Docking (K-Dense-AI/scientific-agent-skills, 48k stars), Edu Chem Reaction (wy51ai/edulab, 1.4k stars), Biopipelines (locbp-uzh/biopipelines, 109 stars) and RDKit Cheminformatics Practices (aiming-lab/AutoResearchClaw, 15k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
jaechang-hits (a GitHub user) maintains it in jaechang-hits/SciAgent-Skills, which has 371 GitHub stars. The repository holds 169 skills in this directory. The repository was last updated on September 29, 2026.
Source: jaechang-hits/SciAgent-Skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.