Token Map
nexu-io/open-design
Map an extracted Figma / source-code token bag onto the active OD design system, producing a deterministic mapping the generate stage can consume.
Comprehensive structure validation combining model-to-map analysis and unmodeled density detection
$ npx skills add pemsley/coot --skill coot-validation -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install pemsley/coot coot-validation --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/pemsley/coot.git skills-src && mkdir -p .claude/skills && cp -r skills-src/mcp/docs/skills/validation .claude/skills/coot-validation && 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 "coot-validation" agent skill from https://github.com/pemsley/coot/tree/main/mcp/docs/skills/validation into .claude/skills/coot-validation/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "coot-validation", 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/pemsley/coot/tree/main/mcp/docs/skills/validationType 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 pemsley/coot --skill coot-validation -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install pemsley/coot coot-validation --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pemsley/coot.git skills-src && mkdir -p .agents/skills && cp -r skills-src/mcp/docs/skills/validation .agents/skills/coot-validation && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "coot-validation" agent skill from https://github.com/pemsley/coot/tree/main/mcp/docs/skills/validation into .agents/skills/coot-validation/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "coot-validation", 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 pemsley/coot --skill coot-validation -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install pemsley/coot coot-validation --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pemsley/coot.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/mcp/docs/skills/validation .cursor/skills/coot-validation && 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 "coot-validation" agent skill from https://github.com/pemsley/coot/tree/main/mcp/docs/skills/validation into .cursor/skills/coot-validation/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "coot-validation", 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/pemsley/coot.git --path mcp/docs/skills/validation--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 pemsley/coot --skill coot-validation -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install pemsley/coot coot-validation --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pemsley/coot.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/mcp/docs/skills/validation .gemini/skills/coot-validation && 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 "coot-validation" agent skill from https://github.com/pemsley/coot/tree/main/mcp/docs/skills/validation into .gemini/skills/coot-validation/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "coot-validation", 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 pemsley/coot coot-validationInstalls 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 pemsley/coot --skill coot-validation -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/pemsley/coot.git skills-src && mkdir -p .github/skills && cp -r skills-src/mcp/docs/skills/validation .github/skills/coot-validation && 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 "coot-validation" agent skill from https://github.com/pemsley/coot/tree/main/mcp/docs/skills/validation into .github/skills/coot-validation/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "coot-validation", 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 pemsley/coot --skill coot-validation -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install pemsley/coot coot-validation --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/pemsley/coot.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/mcp/docs/skills/validation .opencode/skills/coot-validation && 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 "coot-validation" agent skill from https://github.com/pemsley/coot/tree/main/mcp/docs/skills/validation into .opencode/skills/coot-validation/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "coot-validation", 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.
coot-validationComprehensive structure validation combining model-to-map analysis and unmodeled density detection
Coot Validation is an agent skill from pemsley/coot. Comprehensive structure validation combining model-to-map analysis and unmodeled density detection
Its SKILL.md is about 6.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
The repository describes itself as: Software for macromolecular model-building. The licence is GPL-3.0.
2 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 6e3c026. 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.
No scripts in the folder and no shell commands in SKILL.md (its code samples are python).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From 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.
Coot Validation loads about 6.2k tokens when it runs. Until then it costs about 29 tokens; SKILL.md has 1,459 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); files beside SKILL.md are not scanned.
The full file from pemsley/coot at commit 6e3c026, republished under its GPL-3.0 licence (© pemsley). 1,459 words, ~6,205 tokens.
.claude/skills/coot-validation/SKILL.md (or your agent's skills folder).When performing structure validation in Coot with both a model and a map, you need to analyze the structure from three complementary perspectives:
All three perspectives are essential for comprehensive validation.
These functions analyze how well your current model fits the density. They lead you to places in the model that need attention:
CRITICAL: rotamer_graphs_py() and score_rotamers_py() report different things
There are two functions that report rotamer information, and they measure fundamentally different aspects:
rotamer_graphs_py(imol) - Continuous Probability DensityReturns the probability density at the exact chi angles of the current conformation.
rotamers = coot.rotamer_graphs_py(0)
# Returns: [[chain_id, resno, ins_code, score_percentage, resname], ...]
# score_percentage is the continuous probability density at the actual chi anglesInterpretation guidelines:
score_rotamers_py(...) - Discrete Bin ProbabilitiesReturns the discrete rotamer library showing what % of structures have each named rotamer.
rotamers = coot.score_rotamers_py(0, "A", 42, "", "", 1, 1, 0.001)
# Returns: [[name, probability, density_score, atom_list, richardson_score], ...]
# probability is the discrete bin frequency (e.g., m-85 appears in 43% of structures)Why the scores differ:
Number of chi angles determines score expectations:
| Residue Type | Chi Angles | Typical # Rotamers | Best Rotamer % | Good Score |
|---|---|---|---|---|
| VAL, THR, SER | 1 | 3 | 70-75% | > 40% |
| PHE, TYR, ASP, ASN | 2 | 4-9 | 35-45% | > 20% |
| GLU, GLN, MET, ILE, LEU | 3 | 9-15 | 20-35% | > 10% |
| LYS, ARG | 4 | 30-35 | 9-10% | > 5% |
Key insight: More chi angles = more rotamers = lower individual probabilities
Examples from validation:
DON'T: Use arbitrary cutoffs like "< 10% is bad"
DO: Use context-aware validation:
# Step 1: Get current rotamer scores
rotamers = coot.rotamer_graphs_py(0)
# Step 2: For flagged residues, get alternatives
for chain, resno, inscode, score, resname in rotamers:
if score < 20: # Preliminary flag
# Get all possible rotamers to understand context
alternatives = coot.score_rotamers_py(0, chain, resno, "", "", 1, 1, 0.001)
if len(alternatives) == 0:
continue # GLY, ALA - no rotamers
# Sort by density fit
sorted_alts = sorted(alternatives, key=lambda x: x[2], reverse=True)
best_density = sorted_alts[0][2]
current_density = sorted_alts[0][2] # Approximate
# Check how many rotamers exist
n_rotamers = len(alternatives)
# Decision logic
if n_rotamers < 5 and score < 10:
# Few rotamers (VAL, PHE, etc.) and low score = likely wrong
print(f"PROBLEM: {chain}/{resno} {resname}: {score:.1f}% (few alternatives)")
elif n_rotamers > 20 and score < 2:
# Many rotamers (LYS, ARG) and very low score = likely wrong
print(f"PROBLEM: {chain}/{resno} {resname}: {score:.1f}% (many alternatives)")
elif best_density - current_density > 3.0:
# Alternative has much better density fit
print(f"PROBLEM: {chain}/{resno} {resname}: better rotamer available")A residue needs fixing if:
A low rotamer score alone is NOT sufficient - always check:
Atom overlap detection identifies clashes between atoms that may not be caught by local geometry validation. These reveal packing problems such as:
Critical insight: Ramachandran and rotamer validation catch local geometry problems (within a residue or its immediate neighbors), while atom overlap detection catches global packing problems between any atoms in the structure.
The blob-finding function identifies regions of significant density that are not explained by your current model. It leads you to places in the map where you might be missing:
Always include blob detection when performing structure validation with a map.
blobs = coot.find_blobs_py(
imol_model=0, # your protein model
imol_map=1, # the map to search (often difference map)
cut_off_density_level=3.0 # sigma threshold (typically 2.5-4.0)
)
# Returns: list of (position, score) tuples
# [(clipper::Coord_orth, float), ...]imol_model: The model molecule - density explained by this model will be excludedimol_map: The map to search for blobs (usually a difference map, but can be regular map)cut_off_density_level: Sigma threshold for blob detectionfor position, score in blobs:
x = position.x()
y = position.y()
z = position.z()
print(f"Blob at ({x:.2f}, {y:.2f}, {z:.2f}) - score: {score:.2f}")The score represents the strength/volume of the unmodeled density. Higher scores indicate more significant features that should be investigated.
The user likes to see what you are considering and how you change the model, so, if you can, try to use coot.set_rotation_centre() or coot.set_go_to_atom_chain_residue_atom_name() or some such to bring the currently interesting issue to the centre of the screen.
# Ramachandran outliers
rama_outliers = coot.all_molecule_ramachandran_score_py(0)
# Rotamer outliers
rotamer_outliers = coot.rotamer_graphs_py(0)
# Per-residue density correlation
correlation_stats = coot.map_to_model_correlation_stats_per_residue_range_py(
0, # imol_model
"A", # chain_id
1, # imol_map
3, # n_residues_per_residue_range
1 # exclude_mainchain_NOC_flag
)
# Geometry validation
chiral = coot.chiral_volume_errors_py(0)# Get worst 30 atom overlaps
overlaps = coot.molecule_atom_overlaps_py(0, 30)
# Check for severe clashes
severe_clashes = [o for o in overlaps if o['overlap-volume'] > 5.0]
if severe_clashes:
print(f"WARNING: {len(severe_clashes)} severe clashes found!")
# For full analysis (caution: can be very large!)
# all_overlaps = coot.molecule_atom_overlaps_py(0, -1)# Find unmodeled density in difference map
diff_map_blobs = coot.find_blobs_py(
imol_model=0,
imol_map=2, # difference map
cut_off_density_level=3.0
)
# Find features in regular map (alternative approach)
regular_map_blobs = coot.find_blobs_py(
imol_model=0,
imol_map=1, # 2mFo-DFc map
cut_off_density_level=1.0 # Lower threshold for fitted map
)def comprehensive_validation(imol_model, imol_map, imol_diff_map=None):
"""
Perform complete structure validation combining model and map analysis.
Returns dictionary with all validation metrics.
"""
results = {}
# Model-to-map validation
results['ramachandran'] = coot.all_molecule_ramachandran_score_py(imol_model)
results['rotamers'] = coot.rotamer_graphs_py(imol_model)
# Atom overlap validation
results['atom_overlaps'] = coot.molecule_atom_overlaps_py(imol_model, 30)
severe_clashes = [o for o in results['atom_overlaps'] if o['overlap-volume'] > 5.0]
results['severe_clash_count'] = len(severe_clashes)
# Per-residue correlation (requires chain info)
import coot_utils
chains = coot_utils.chain_ids(imol_model)
results['correlation_by_chain'] = {}
for chain in chains:
n_residues = coot.chain_n_residues(chain, imol_model)
if n_residues > 0:
stats = coot.map_to_model_correlation_stats_per_residue_range_py(
imol_model, chain, 1, 9999, imol_map
)
results['correlation_by_chain'][chain] = stats
# Map-to-model validation (blobs)
if imol_diff_map is not None:
results['diff_map_blobs'] = coot.find_blobs_py(
imol_model, imol_diff_map, 3.0
)
results['map_blobs'] = coot.find_blobs_py(
imol_model, imol_map, 1.0
)
return results
# Usage
validation = comprehensive_validation(
imol_model=0,
imol_map=1,
imol_diff_map=2
)Difference Map (mFo-DFc) Blobs:
Regular Map (2mFo-DFc) Blobs:
blobs = coot.find_blobs_py(0, 2, 3.0) # diff map, 3 sigma
# Large score (>50): Likely missing ligand, metal, or several waters
# Medium score (10-50): Likely 1-3 waters or alternative conformation
# Small score (3-10): Likely single water or weak alternative conformation
for position, score in blobs:
if score > 50:
print(f"Large feature at {position} - investigate for ligand/metal")
elif score > 10:
print(f"Medium feature at {position} - likely waters")
else:
print(f"Small feature at {position} - check carefully")Always include atom overlap checking when validating structure geometry.
# Get worst 30 atom overlaps (default behavior after API update)
overlaps = coot.molecule_atom_overlaps_py(
imol=0,
n_pairs=30 # Number of worst overlaps to return (default: 30)
)
# Get ALL overlaps (use with caution - can be hundreds!)
all_overlaps = coot.molecule_atom_overlaps_py(
imol=0,
n_pairs=-1 # -1 means return all overlaps
)
# Each overlap is a dict with:
# {
# 'atom-1-spec': [imol, chain, resno, inscode, atom_name, altconf],
# 'atom-2-spec': [imol, chain, resno, inscode, atom_name, altconf],
# 'overlap-volume': float, # in Ų
# 'radius-1': float,
# 'radius-2': float
# }Overlap volume indicates severity:
Common clash patterns:
overlaps = coot.molecule_atom_overlaps_py(0, 30)
for overlap in overlaps:
atom1 = overlap['atom-1-spec']
atom2 = overlap['atom-2-spec']
volume = overlap['overlap-volume']
chain1, res1, atom_name1 = atom1[1], atom1[2], atom1[4]
chain2, res2, atom_name2 = atom2[1], atom2[2], atom2[4]
if volume > 5.0:
print(f"SEVERE: {chain1}/{res1} {atom_name1} ↔ {chain2}/{res2} {atom_name2}: {volume:.2f} Ų")
elif volume > 2.0:
print(f"MODERATE: {chain1}/{res1} {atom_name1} ↔ {chain2}/{res2} {atom_name2}: {volume:.2f} Ų")Example from tutorial data:
Key lesson: A model can have perfect Ramachandran and rotamer scores but catastrophic packing problems. You need both local geometry validation (Rama/rotamer) AND global packing validation (overlaps).
CRITICAL: Never use absolute rotamer score thresholds without considering residue type
Before prioritizing rotamer fixes, understand what's "bad" for each residue:
def assess_rotamer_severity(chain, resno, score, resname):
"""
Determine if a rotamer score is actually problematic.
Returns: 'critical', 'moderate', 'acceptable', or 'good'
"""
# Get all possible rotamers to understand the distribution
alternatives = coot.score_rotamers_py(0, chain, resno, "", "", 1, 1, 0.001)
n_rotamers = len(alternatives)
# Context-aware thresholds based on number of possible rotamers
if n_rotamers <= 3: # VAL, THR, SER (1 chi)
if score < 10: return 'critical'
elif score < 30: return 'moderate'
else: return 'acceptable'
elif n_rotamers <= 9: # PHE, TYR, etc. (2 chi)
if score < 5: return 'critical'
elif score < 15: return 'moderate'
else: return 'acceptable'
elif n_rotamers <= 15: # GLU, GLN, MET (3 chi)
if score < 3: return 'critical'
elif score < 10: return 'moderate'
else: return 'acceptable'
else: # LYS, ARG (4 chi, 30+ rotamers)
if score < 1: return 'critical'
elif score < 5: return 'moderate'
else: return 'acceptable'Priority 1: Combined problems (multiple red flags)
Priority 2: Single severe issues
Important: A low rotamer score with GOOD density correlation (>0.8) may be correct - it could be a genuine unusual but real conformation. Don't "fix" it unless there's supporting evidence (clashes, poor density, chemical implausibility).
score_rotamers_py()def validate_and_fix_chain(imol_model, chain_id, imol_map, imol_diff_map):
"""
Automated validation and suggested fixes for a chain.
"""
issues = []
# 1. Check for atom overlaps
overlaps = coot.molecule_atom_overlaps_py(imol_model, 50)
for overlap in overlaps:
atom1 = overlap['atom-1-spec']
atom2 = overlap['atom-2-spec']
volume = overlap['overlap-volume']
# Only report if at least one atom is in this chain
if atom1[1] == chain_id or atom2[1] == chain_id:
severity = 'high' if volume > 5.0 else ('medium' if volume > 2.0 else 'low')
issues.append({
'type': 'atom_overlap',
'atom1': f"{atom1[1]}/{atom1[2]} {atom1[4]}",
'atom2': f"{atom2[1]}/{atom2[2]} {atom2[4]}",
'severity': severity,
'value': volume
})
# 2. Check correlation for each residue
stats = coot.map_to_model_correlation_stats_per_residue_range_py(
imol_model, chain_id, 1, 9999, imol_map
)
for residue_spec, correlation in stats:
if correlation < 0.7: # Poor fit threshold
issues.append({
'type': 'poor_correlation',
'residue': residue_spec,
'severity': 'high',
'value': correlation
})
# 3. Find nearby blobs that might explain poor correlation
blobs = coot.find_blobs_py(imol_model, imol_diff_map, 3.0)
for position, score in blobs:
issues.append({
'type': 'unmodeled_density',
'position': (position.x(), position.y(), position.z()),
'severity': 'high' if score > 50 else 'medium',
'score': score
})
# 4. Check Ramachandran
rama = coot.all_molecule_ramachandran_score_py(imol_model)
for outlier in rama:
if outlier[4] == 'OUTLIER': # Ramachandran region
issues.append({
'type': 'ramachandran_outlier',
'residue': outlier[0:3], # chain, resno, inscode
'severity': 'high'
})
return sorted(issues, key=lambda x: {'high': 0, 'medium': 1, 'low': 2}[x['severity']])
# Usage
issues = validate_and_fix_chain(0, "A", 1, 2)
for issue in issues[:10]: # Top 10 issues
print(f"{issue['type']}: {issue}")# Find blobs in difference map
blobs = coot.find_blobs_py(0, 2, 3.0)
# Add waters at blob positions
for position, score in blobs:
if 5 < score < 30: # Typical water blob size
# Check if appropriate for water
x, y, z = position.x(), position.y(), position.z()
# Add water at this position
coot.place_typed_atom_at_pointer("HOH")# Look for large blobs that might be missing residues
blobs = coot.find_blobs_py(0, 2, 3.0)
missing_residue_candidates = [
(pos, score) for pos, score in blobs
if score > 100 # Large feature
]
for position, score in missing_residue_candidates:
print(f"Large unmodeled density at {position} - check for missing residues")get_hydrogen_bonds_py()coot.get_hydrogen_bonds_py(imol, selection_1, selection_2, mcdonald_and_thornton)Parameters:
imol: model molecule indexselection_1: MMDB selection string for first group (e.g. "//A/35")selection_2: MMDB selection string for second group (e.g. "//A/34-56")mcdonald_and_thornton: 1 = use McDonald & Thornton algorithm (requires H atoms); 0 = geometry-onlyReturns: list of H-bond candidates. Each entry is a list of 12 elements:
[0] hydrogen atom (dict, or None if no H)
[1] donor atom (dict)
[2] acceptor atom (dict)
[3] donor neighbour/antecedent atom (dict, or None)
[4] acceptor neighbour/antecedent atom (dict, or None)
[5] angle_1 (float, degrees)
[6] angle_2 (float, degrees)
[7] angle_3 (float, degrees)
[8] distance (float, Å)
[9] ligand_atom_is_donor (bool)
[10] hydrogen_is_ligand_atom (bool)
[11] bond_has_hydrogen_flag (bool)Each atom dict has keys: x, y, z, charge, occ, b_iso, element, name, model, chain, altLoc, residue_name
IMPORTANT: Always use mcdonald_and_thornton=0 unless the model has explicit hydrogens.
The function returns all geometrically plausible H-bond candidates — distance alone is not
sufficient to confirm a hydrogen bond; the angles must also be checked.
Example:
hbonds = coot.get_hydrogen_bonds_py(0, "//A/35", "//A/50-56", 0)
for hb in hbonds:
donor = hb[1]
acceptor = hb[2]
dist = hb[8]
has_H = hb[11]
d_str = donor['chain'] + " " + donor['residue_name'] + " " + donor['name'].strip()
a_str = acceptor['chain'] + " " + acceptor['residue_name'] + " " + acceptor['name'].strip()
print("H-bond: " + d_str + " -> " + a_str + " dist=" + str(dist) + " has_H=" + str(has_H))# Rotamer validation - primary metric (continuous probability density)
rotamers = coot.rotamer_graphs_py(imol)
# Returns: [[chain_id, resno, ins_code, score_percentage, resname], ...]
# Rotamer alternatives - for understanding context
alternatives = coot.score_rotamers_py(imol, chain, resno, "", "", imol_map, 1, 0.001)
# Returns: [[name, probability, density_score, atom_list, richardson_score], ...]
# Atom overlap detection
overlaps = coot.molecule_atom_overlaps_py(imol, n_pairs=30) # Default: 30 worst
all_overlaps = coot.molecule_atom_overlaps_py(imol, n_pairs=-1) # All overlaps
# Blob detection (map-to-model)
blobs = coot.find_blobs_py(imol_model, imol_map, sigma_cutoff)
# Ramachandran validation
rama = coot.all_molecule_ramachandran_score_py(imol)
# Rotamer validation
rotamers = coot.rotamer_graphs_py(imol)
# Density correlation (model-to-map)
corr = coot.map_to_model_correlation_stats_per_residue_range_py(
imol, chain, imol_map, n_per_range, exclude_NOC_flag
)
# Geometry validation
chiral = coot.chiral_volume_errors_py(imol)Remember:
© pemsley, GPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in mcp/docs/skills/validation of pemsley/coot.
Open the folder on GitHubat commit 6e3c026
Coot Validation 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 |
|---|---|---|---|---|---|---|
| Coot Validation this skillpemsley/coot | 168 | — | ~6.2k | Automated safety check: Pass | GPL-3.0 | |
| Token Mapnexu-io/open-design | 100k | — | ~1.4k | Automated safety check: Pass | Apache-2.0 | |
| Maps Geographyasgeirtj/system_prompts_leaks | 69k | — | ~717 | Automated safety check: Pass | CC0-1.0 | |
| Feature Maponyx-dot-app/onyx | 32k | — | ~459 | Automated safety check: Pass | Custom licence | |
| Source Mapsthedaviddias/Front-End-Checklist | 74k | — | ~445 | Automated safety check: Pass | MIT | |
| Customer Journey Mapphuryn/pm-skills | 27k | — | ~816 | Automated safety check: Pass | MIT |
nexu-io/open-design
Map an extracted Figma / source-code token bag onto the active OD design system, producing a deterministic mapping the generate stage can consume.
asgeirtj/system_prompts_leaks
Accurate maps from real geo data — use for any map, or whenever geography would make a good graphic for a deliverable
onyx-dot-app/onyx
Use the Onyx feature map (.agents/feature-map/) to learn what a product surface does, the code behind it, and what a change can break.
thedaviddias/Front-End-Checklist
A skill your agent uses when auditing slow page loads, heavy assets, or rendering delays related to Provide source maps for production debugging.
phuryn/pm-skills
Create an end-to-end customer journey map with stages, touchpoints, emotions, pain points, and opportunities.
github/awesome-copilot
Generate a map of all files relevant to a task before making changes
pemsley/coot
Create interactive inline Chart.js graphs directly in the chat from live Coot data.
pemsley/coot
RDKit molecular manipulation and visualization within Coot's Python environment.
pemsley/coot
Best practices for protein structure refinement and validation in Coot.
pemsley/coot
API documentation to be loaded at startup - when starting a Coot session, immediately call getfunctiondescriptions() with the functions listed in this skill.
pemsley/coot
Best practices for creating publication-quality molecular graphics figures in Coot using user-defined colors, ribbons, and molecular representations
pemsley/coot
Best Practices for Model-Building Tools and Refinement. An agent skill from pemsley/coot.
Comprehensive structure validation combining model-to-map analysis and unmodeled density detection. Coot Validation is an agent skill from pemsley/coot.
Run `npx skills add pemsley/coot --skill coot-validation -a claude-code`. Or copy the skill folder (mcp/docs/skills/validation in pemsley/coot) into .claude/skills/coot-validation in your project. Claude Code loads it when a task matches its description.
Run `npx skills add pemsley/coot --skill coot-validation -a codex`. Or copy the skill folder (mcp/docs/skills/validation in pemsley/coot) into .agents/skills/coot-validation 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 pemsley/coot --skill coot-validation -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/coot-validation, .gemini/skills/coot-validation, .github/skills/coot-validation and .opencode/skills/coot-validation in your project.
SKILL.md names no scripts, command-line tools or credentials: Coot Validation is instructions for the agent only. Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. 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. Review the folder before installing.
Coot Validation is published under the GPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.2k tokens (SKILL.md is roughly 25k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Coot Validation: Token Map (nexu-io/open-design, 100k stars), Maps Geography (asgeirtj/system_prompts_leaks, 69k stars), Feature Map (onyx-dot-app/onyx, 32k stars) and Source Maps (thedaviddias/Front-End-Checklist, 74k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
pemsley (a GitHub user) maintains it in pemsley/coot, which has 168 GitHub stars. The repository holds 11 skills in this directory. The repository was last updated on October 7, 2026.
Source: pemsley/coot on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.