### Rowan
Works with
name: "rowan"
description: "Rowan is a cloud-native molecular modeling and medicinal-chemistry workflow platform with a Python API. Use for pKa and macropKa prediction, conformer and tautomer ensembles, docking and analogue dock..."
AI-first code editor with Composer
Before installing skills in Cursor, ensure your development environment meets these requirements:
node --versionrowanExecute the skills CLI command in your project's root directory to begin installation:
Fetches rowan from K-Dense-AI/scientific-agent-skills and configures it for Cursor.
The CLI shows a list of agents. Use arrow keys and space to select Cursor:
Confirm successful installation by checking the skill directory location:
Restart Cursor to activate rowan. Access via /rowan in your agent's command palette.
We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.
Skills execute code in your environment. Always review source, verify the publisher, and test in isolation before production.
Submit your Claude Code skill and start earning
Automate repetitive workflows and reduce manual effort
Example
Generate reports, summarize documents, draft communications
Save 3-5 hours per week on routine tasks
Learn new skills, understand complex topics, get expert guidance
Example
Explain concepts, provide examples, suggest learning resources
Accelerate learning and skill development by 2x
Enhance output quality through reviews, suggestions, and refinements
Example
Review drafts, suggest improvements, catch errors
Improve work quality by 30-40% with less effort
0
total installs
0
this week
0
upvotes
Run in your terminal
0
installs
0
this week
—
stars
| name | rowan |
| description | Rowan is a cloud-native molecular modeling and medicinal-chemistry workflow platform with a Python API. Use for pKa and macropKa prediction, conformer and tautomer ensembles, docking and analogue docking, protein-ligand cofolding, MSA generation, molecular dynamics, permeability, descriptor workflows, and related small-molecule or protein modeling tasks. Ideal for programmatic batch screening, multi-step chemistry pipelines, and workflows that would otherwise require maintaining local HPC/GPU infrastructure. |
| license | Proprietary (API key required) |
| compatibility | Python 3.12+, API key required |
| metadata | version: "1.1" skill-author: Rowan Science trigger-keywords: "pKa prediction, molecular docking, conformer search, chemistry workflow, drug discovery, SMILES, protein structure, batch molecular modeling, cloud chemistry" |
Rowan is a cloud-native workflow platform for molecular simulation, medicinal chemistry, and structure-based design. Its Python API exposes a unified interface for small-molecule modeling, property prediction, docking, molecular dynamics, and AI structure workflows.
Use Rowan when you want to run medicinal-chemistry or molecular-design workflows programmatically without maintaining local HPC infrastructure, GPU provisioning, or a collection of separate modeling tools. Rowan handles all infrastructure, result management, and computation scaling.
Rowan is a good fit for:
Rowan is not the right fit for:
Rowan uses a credit-based usage model. All users, including free-tier users, can create API keys and use the Python API.
Credits are consumed according to compute type:
Purchased credits are priced per credit and remain valid for up to one year from purchase.
| Workflow | Typical Runtime | Estimated Credits | Notes |
|---|---|---|---|
| Descriptors | <1 min | 0.5–2 | Lightweight, good for triage |
| pKa (single transition) | 2–5 min | 2–5 | Depends on molecule size |
| MacropKa (pH 0–14) | 5–15 min | 5–15 | Broader sampling, higher cost |
| Conformer search | 3–10 min | 3–10 | Ensemble quality matters |
| Tautomer search | 2–5 min | 2–5 | Heterocyclic systems |
| Docking (single ligand) | 5–20 min | 5–20 | Depends on pocket size, refinement |
| Analogue docking series (10–50 ligands) | 30–120 min | 30–100+ | Shared reference frame |
| MSA generation | 5–30 min | 5–30 | Sequence length dependent |
| Protein-ligand cofolding | 15–60 min | 20–50+ | AI structure prediction, GPU-heavy |
uv pip install rowan-python
import rowan
rowan.api_key = "your_api_key_here" # or set ROWAN_API_KEY env var
# Submit a descriptors workflow — completes in under a minute
wf = rowan.submit_descriptors_workflow("CC(=O)Oc1ccccc1C(=O)O", name="aspirin")
result = wf.result()
print(result.descriptors['MW']) # 180.16
print(result.descriptors['SLogP']) # 1.19
print(result.descriptors['TPSA']) # 59.44
If that prints without error, you're set up correctly.
uv pip install rowan-python
# or: pip install rowan-python
Set an API key via environment variable (recommended):
export ROWAN_API_KEY="your_api_key_here"
Or set directly in Python:
import rowan
rowan.api_key = "your_api_key_here"
Verify authentication:
import rowan
user = rowan.whoami() # Returns user info if authenticated
print(f"User: {user.email}")
print(f"Credits available: {user.credits_available_string}")
For webhook signature verification, manage secrets through your user account:
import rowan
# Get your current webhook secret (returns None if none exists)
secret = rowan.get_webhook_secret()
if secret is None:
secret = rowan.create_webhook_secret()
print(f"Secret key: {secret.secret}")
# Rotate your secret (invalidates old, creates new)
# Use this periodically for security
new_secret = rowan.rotate_webhook_secret()
print(f"New secret created (old secret disabled): {new_secret.secret}")
# Verify incoming webhook signatures
is_valid = rowan.verify_webhook_secret(
request_body=b"...", # Raw request body (bytes)
signature="X-Rowan-Signature", # From request header
secret=secret.secret
)
Rowan accepts molecules in the following formats:
"CCO", "c1ccccc1O""InChI=1S/C2H6O/c1-2-3/h3H,2H2,1H3"The API will validate input and raise a rowan.ValidationError if a molecule cannot be parsed. Always use canonicalized SMILES for reproducibility.
Tip: Use RDKit to validate SMILES before submission:
from rdkit import Chem
smiles = "CCO"
mol = Chem.MolFromSmiles(smiles)
if mol is None:
raise ValueError(f"Invalid SMILES: {smiles}")
Most Rowan tasks follow the same three-step pattern:
import rowan
# 1. Submit — use the specific workflow function (not the generic submit_workflow)
workflow = rowan.submit_descriptors_workflow(
"CC(=O)Oc1ccccc1C(=O)O",
name="aspirin descriptors",
)
# 2. & 3. Wait and retrieve
result = workflow.result() # Blocks until done (default: wait=True, poll_interval=5)
print(result.data) # Raw dict
print(result.descriptors['MW']) # 180.16 — use result.descriptors dict, not result.molecular_weight
For long-running workflows, use streaming:
for partial in workflow.stream_result(poll_interval=5):
print(f"Progress: {partial.complete}%")
print(partial.data)
| Pattern | Use When | Duration |
|---|---|---|
result() | You can wait for the full result | <5 min typical |
stream_result() | You want progress feedback or need early partial results | >5 min, or interactive use |
Guideline: Use result() for descriptors, pKa. Use stream_result() for conformer search, docking, cofolding.
Rowan's API includes typed workflow result objects with convenience properties.
Results have two access patterns:
result.descriptors, result.best_pose, result.conformer_energiesresult.data — raw dictionary from the APIExample:
result = rowan.submit_descriptors_workflow(
"CCO",
name="ethanol",
).result()
# Convenience property (returns dict of all descriptors):
print(result.descriptors['MW']) # 46.042
print(result.descriptors['SLogP']) # -0.001
print(result.descriptors['TPSA']) # 57.96
# Raw data fallback (descriptors are nested under 'descriptors' key):
print(result.data['descriptors'])
# {'MW': 46.042, 'SLogP': -0.001, 'TPSA': 57.96, 'nHBDon': 1.0, 'nHBAcc': 1.0, ...}
Note: DescriptorsResult does not have a molecular_weight property. Descriptor keys use short names (MW, SLogP, nHBDon) not verbose names.
Some result properties are lazily loaded (e.g., conformer geometries, protein structures). To refresh:
result.clear_cache()
new_structures = result.conformer_molecules # Refetched
For nontrivial campaigns, use projects and folders to keep work organized.
import rowan
# Create a project
project = rowan.create_project(name="CDK2 lead optimization")
rowan.set_project("CDK2 lead optimization")
# All subsequent workflows go into this project
wf = rowan.submit_descriptors_workflow("CCO", name="test compound")
# Retrieve later
project = rowan.retrieve_project("CDK2 lead optimization")
workflows = rowan.list_workflows(project=project, size=50)
# Create a hierarchical folder structure
folder = rowan.create_folder(name="docking/batch_1/screening")
wf = rowan.submit_docking_workflow(
# ... docking params ...
folder=folder,
name="compound_001",
)
# List workflows in a folder
results = rowan.list_workflows(folder=folder)
Use microscopic pKa when:
Use macropKa when:
Example decision:
Phenol (pKa ~10): Use microscopic pKa
Amine (pKa ~9–10): Use microscopic pKa
Multi-ionizable drug (N, O, acidic group): Use macropKa
ADME assessment across GI pH: Use macropKa
Use conformer search when:
Use tautomer search when:
Combined workflow:
# Step 1: Find best tautomer
taut_wf = rowan.submit_tautomer_search_workflow(
initial_molecule="O=c1[nH]ccnc1",
name="imidazole tautomers",
)
best_taut = taut_wf.result().best_tautomer
# Step 2: Generate conformers from best tautomer
conf_wf = rowan.submit_conformer_search_workflow(
initial_molecule=best_taut,
name="imidazole conformers",
)
| Workflow | Use When | Input | Output |
|---|---|---|---|
| Docking | Single ligand, known pocket | Protein + SMILES + pocket coords | Pose, score, dG |
| Analogue docking | 5–100+ related compounds | Protein + SMILES list + reference ligand | All poses, reference-aligned |
| Protein-ligand cofolding | Sequence + ligand, no crystal structure | Protein sequence + SMILES | ML-predicted bound complex |
A lightweight entry point for batch triage, SAR, or exploratory scripts.
wf = rowan.submit_descriptors_workflow(
"CC(=O)Oc1ccccc1C(=O)O", # positional arg, accepts SMILES string
name="aspirin descriptors",
)
result = wf.result()
print(result.descriptors['MW']) # 180.16
print(result.descriptors['SLogP']) # 1.19
print(result.descriptors['TPSA']) # 59.44
print(result.data['descriptors'])
# {'MW': 180.16, 'SLogP': 1.19, 'TPSA': 59.44, 'nHBDon': 1.0, 'nHBAcc': 4.0, ...}
Common descriptor keys:
| Key | Description | Typical drug range |
|---|---|---|
MW | Molecular weight (Da) | <500 (Lipinski) |
SLogP | Calculated LogP (lipophilicity) | -2 to +5 |
TPSA | Topological polar surface area (Ų) | <140 for oral bioavailability |
nHBDon | H-bond donor count | ≤5 (Lipinski) |
nHBAcc | H-bond acceptor count | ≤10 (Lipinski) |
nRot | Rotatable bond count | <10 for oral drugs |
nRing | Ring count | — |
nHeavyAtom | Heavy atom count | — |
FilterItLogS | Estimated aqueous solubility (LogS) | >-4 preferred |
Lipinski | Lipinski Ro5 pass (1.0) or fail (0.0) | — |
The result contains hundreds of additional molecular descriptors (BCUT, GETAWAY, WHIM, etc.); access any via result.descriptors['key'].
For protonation-state energetics and acid/base behavior of a specific structure.
Two methods are available:
| Method | Input | Speed | Covers | Use when |
|---|---|---|---|---|
chemprop_nevolianis2025 | SMILES string | Fast | Deprotonation only (anionic conjugate bases) | Acidic groups only; quick screening |
starling | SMILES string | Fast | Acid + base (full protonation/deprotonation) | Most drug-like molecules; preferred SMILES method |
aimnet2_wagen2024 (default) | 3D molecule object | Slower, higher accuracy | Acid + base | You already have a 3D structure (e.g. from conformer search) |
# Fast path: SMILES input with full acid+base coverage (use starling method when available)
wf = rowan.submit_pka_workflow(
initial_molecule="c1ccccc1O", # phenol SMILES; param is initial_molecule, not initial_smiles
method="starling", # fast SMILES method, covers acid+base; chemprop_nevolianis2025 is deprotonation-only
name="phenol pKa",
)
result = wf.result()
print(result.strongest_acid) # 9.81 (pKa of the most acidic site)
print(result.conjugate_bases) # list of {pka, smiles, atom_index, ...} per deprotonatable site
For pH-dependent protonation behavior across a range.
wf = rowan.submit_macropka_workflow(
initial_smiles="CN1CCN(CC1)C2=NC=NC3=CC=CC=C32", # imidazole
min_pH=0,
max_pH=14,
min_charge=-2, # default
max_charge=2, # default
compute_aqueous_solubility=True, # default
name="imidazole macropKa",
)
result = wf.result()
print(result.pka_values) # list of pKa values
print(result.logd_by_ph) # dict of {pH: logD}
print(result.aqueous_solubility_by_ph) # dict of {pH: solubility}
print(result.isoelectric_point) # isoelectric point
print(result.data)
# {'pKa_values': [...], 'logD_by_pH': {...}, 'aqueous_solubility_by_pH': {...}, ...}
For 3D ensemble generation when ensemble quality matters.
wf = rowan.submit_conformer_search_workflow(
initial_molecule="CCOC(=O)N1CCC(CC1)Oc1ncnc2ccccc12",
num_conformers=50, # Optional: override default
name="conformer search",
)
result = wf.result()
print(result.conformer_energies) # [0.0, 1.2, 2.5, ...]
print(result.conformer_molecules) # List of 3D molecules
print(result.best_conformer) # Lowest-energy conformer
For heterocycles and systems where tautomer state affects downstream modeling.
wf = rowan.submit_tautomer_search_workflow(
initial_molecule="O=c1[nH]ccnc1", # or keto tautomer
name="imidazolone tautomers",
)
result = wf.result()
print(result.best_tautomer) # Most stable SMILES string
print(result.tautomers) # List of tautomeric SMILES
print(result.molecules) # List of molecule objects
For protein-ligand docking with optional pose refinement and conformer generation.
# Upload protein once, reuse in multiple workflows
protein = rowan.upload_protein(
name="CDK2",
file_path="cdk2.pdb",
)
# Define binding pocket
pocket = {
"center": [10.5, 24.2, 31.8],
"size": [18.0, 18.0, 18.0],
}
# Submit docking
wf = rowan.submit_docking_workflow(
protein=protein,
pocket=pocket,
initial_molecule="CCNc1ncc(c(Nc2ccc(F)cc2)n1)-c1cccnc1",
do_pose_refinement=True,
do_conformer_search=True,
name="lead docking",
)
result = wf.result()
print(result.scores) # Docking scores (kcal/mol)
print(result.best_pose) # Mol object with 3D coordinates
print(result.data) # Raw result dict
Protein preparation tips:
rowan.create_protein_from_pdb_id() insteadFor placing a compound series into a shared binding context.
# Analogue series (e.g., SAR campaign)
analogues = [
"CCNc1ncc(c(Nc2ccc(F)cc2)n1)-c1cccnc1", # reference
"CCNc1ncc(c(Nc2ccc(Cl)cc2)n1)-c1cccnc1", # chloro
"CCNc1ncc(c(Nc2ccc(OC)cc2)n1)-c1cccnc1", # methoxy
"CCNc1ncc(c(Nc2cc(C)c(F)cc2)n1)-c1cccnc1", # methyl, fluoro
]
wf = rowan.submit_analogue_docking_workflow(
analogues=analogues,
initial_molecule=analogues[0], # Reference ligand
protein=protein,
pocket=pocket,
name="SAR series docking",
)
result = wf.result()
print(result.analogue_scores) # List of scores for each analogue
print(result.best_poses) # List of poses
For multiple-sequence alignment (useful for downstream cofolding).
wf = rowan.submit_msa_workflow(
initial_protein_sequences=[
"MENFQKVEKIGEGTYGVVYKARNKLTGEVVALKKIRLDTETEGVP"
],
output_formats=["colabfold", "chai", "boltz"],
name="target MSA",
)
result = wf.result()
result.download_files() # Downloads alignments to disk
For AI-based bound-complex prediction when no crystal structure is available.
wf = rowan.submit_protein_cofolding_workflow(
initial_protein_sequences=[
"MENFQKVEKIGEGTYGVVYKARNKLTGEVVALKKIRLDTETEGVP"
],
initial_smiles_list=[
"CCNc1ncc(c(Nc2ccc(F)cc2)n1)-c1cccnc1"
],
name="protein-ligand cofolding",
)
result = wf.result()
print(result.predictions) # List of predicted structures
print(result.messages) # Model metadata/warnings
predicted_structure = result.get_predicted_structure()
predicted_structure.write("predicted_complex.pdb")
All workflows follow the same submit → wait → retrieve pattern and support webhooks and project/folder organization.
| Workflow | Function | When to use |
|---|---|---|
| Descriptors | submit_descriptors_workflow | First-pass triage: MW, LogP, TPSA, HBA/HBD, Lipinski filter |
| pKa | submit_pka_workflow | Single ionizable group; need protonation thermodynamics |
| MacropKa | submit_macropka_workflow | Multi-ionizable drugs; pH-dependent charge/LogD/solubility |
| Conformer Search | submit_conformer_search_workflow | 3D ensemble for docking, MD, or SAR; known tautomer |
| Tautomer Search | submit_tautomer_search_workflow | Heterocycles, keto–enol; uncertain tautomeric form |
| Solubility | submit_solubility_workflow | Aqueous or solvent-specific solubility prediction |
| Membrane Permeability | submit_membrane_permeability_workflow | Caco-2, PAMPA, BBB, plasma permeability |
| ADMET | submit_admet_workflow | Broad drug-likeness and ADMET property sweep |
| Workflow | Function | When to use |
|---|---|---|
| Docking | submit_docking_workflow | Single ligand, known binding pocket |
| Analogue Docking | submit_analogue_docking_workflow | SAR series (5–100+ compounds) in a shared pocket |
| Batch Docking | submit_batch_docking_workflow | Fast library screening; large compound sets |
| Protein MD | submit_protein_md_workflow | Long-timescale dynamics; conformational sampling |
| Pose Analysis MD | submit_pose_analysis_md_workflow | MD refinement of a docking pose |
| Protein Cofolding | submit_protein_cofolding_workflow | No crystal structure; AI-predicted bound complex |
| Protein Binder Design | submit_protein_binder_design_workflow | De novo binder generation against a protein target |
| Workflow | Function | When to use |
|---|---|---|
| Basic Calculation | submit_basic_calculation_workflow | QM/ML geometry optimization or single-point energy |
| Electronic Properties | submit_electronic_properties_workflow | Dipole, partial charges, HOMO-LUMO, ESP |
| BDE | submit_bde_workflow | Bond dissociation energies; metabolic soft-spot prediction |
| Redox Potential | submit_redox_potential_workflow | Oxidation/reduction potentials |
| Spin States | submit_spin_states_workflow | Spin-state energy ordering for organometallics/radicals |
| Strain | submit_strain_workflow | Conformational strain relative to global minimum |
| Scan | submit_scan_workflow | PES scans; torsion profiles |
| Multistage Optimization | submit_multistage_opt_workflow | Progressive optimization across levels of theory |
| Workflow | Function | When to use |
|---|---|---|
| Double-Ended TS Search | submit_double_ended_ts_search_workflow | Transition state between two known structures |
| IRC | submit_irc_workflow | Confirm TS connectivity; intrinsic reaction coordinate |
| Workflow | Function | When to use |
|---|---|---|
| NMR | submit_nmr_workflow | Predicted 1H/13C chemical shifts for structure verification |
| Ion Mobility | submit_ion_mobility_workflow | Collision cross-section (CCS) for MS method development |
| Hydrogen Bond Strength | submit_hydrogen_bond_basicity_workflow | H-bond donor/acceptor strength for formulation/solubility |
| Fukui | submit_fukui_workflow | Site reactivity indices for electrophilic/nucleophilic attack |
| Interaction Energy Decomposition | submit_interaction_energy_decomposition_workflow | Fragment-level interaction analysis |
| Workflow | Function | When to use |
|---|---|---|
| RBFE/FEP | submit_relative_binding_free_energy_perturbation_workflow | Relative ΔΔG for congeneric series |
| RBFE Graph | submit_rbfe_graph_workflow | Build and optimize an RBFE perturbation network |
| Workflow | Function | When to use |
|---|---|---|
| MSA | submit_msa_workflow | Multiple sequence alignment for cofolding (ColabFold, Chai, Boltz) |
| Solvent-Dependent Conformers | submit_solvent_dependent_conformers_workflow | Solvation-aware conformer ensembles |
For libraries or analogue series, submit in a loop using the specific workflow function. The generic rowan.batch_submit_workflow() and rowan.submit_workflow() functions currently return 422 errors from the API — use the named functions (submit_descriptors_workflow, submit_pka_workflow, etc.) instead.
smileses = ["CCO", "CC(=O)O", "c1ccccc1O"]
names = ["ethanol", "acetic acid", "phenol"]
workflows = [
rowan.submit_descriptors_workflow(smi, name=name)
for smi, name in zip(smileses, names)
]
print(f"Submitted {len(workflows)} workflows")
statuses = rowan.batch_poll_status([wf.uuid for wf in workflows])
# Returns aggregate counts — not per-UUID:
# {'queued': 0, 'running': 1, 'complete': 2, 'failed': 0, 'total': 3, ...}
if statuses["complete"] == statuses["total"]:
print("All workflows done")
elif statuses["failed"] > 0:
print(f"{statuses['failed']} workflows failed")
results
Prerequisites
Time Estimate
15-45 minutes depending on use case complexity
Steps
Common Pitfalls
✓ Do
✗ Don't
💡 Pro Tips
✓ Use when
Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.
✗ Avoid when
Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.
K-Dense-AI/scientific-agent-skills
K-Dense-AI/scientific-agent-skills
K-Dense-AI/scientific-agent-skills
K-Dense-AI/scientific-agent-skills
google-deepmind/science-skills
google-deepmind/science-skills
Useful defaults in rowan — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
Registry listing for rowan matched our evaluation — installs cleanly and behaves as described in the markdown.
rowan reduced setup friction for our internal harness; good balance of opinion and flexibility.
We added rowan from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
rowan fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.
Solid pick for teams standardizing on skills: rowan is focused, and the summary matches what you get after install.
Useful defaults in rowan — fewer surprises than typical one-off scripts, and it plays nicely with `npx skills` flows.
Registry listing for rowan matched our evaluation — installs cleanly and behaves as described in the markdown.
We added rowan from the explainx registry; install was straightforward and the SKILL.md answered most questions upfront.
rowan is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.
showing 1-10 of 69