Generated banner for Boltz Small Molecule Design
Generated logo for Boltz Small Molecule Design

Boltz Small Molecule Design

OpenAIOfficialCreated by BoltzDistributed by OpenAI

  • Skill
  • Workflow
  • Science and research
  • MIT
  • No issues found

From the author

Design new small-molecule binders with Boltz. Use when generating novel ligands or hits for a target without a fixed compound library. Not for screening existing molecules or one-off docking.
— the description by Boltz

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured workflow for de novo small-molecule design. It enables users to generate novel ligands for a specific protein target without requiring a pre-existing compound library. The process involves defining the target protein, specifying the number of molecules to generate, and optionally applying chemical space constraints or filters. The workflow includes cost estimation, submission, background downloading of results, and post-generation ranking based on binding confidence or optimization scores.

What it does

  • Normalizes protein target sequences and pocket definitions for design.
  • Estimates generation costs based on the requested number of molecules.
  • Submits de novo design jobs to the Boltz API.
  • Handles background downloading and polling of generated molecule data.
  • Provides ranking metrics for hit discovery and lead optimization.
  • Surfaces ADME properties for developability triage.

When to use it

  • When you need to discover novel small-molecule binders for a protein target.
  • When you do not have a fixed compound library to screen.
  • When you need to perform lead optimization on a specific target.
  • When you need to evaluate the developability of generated hits using ADME metrics.

Advantages

  • Enables de novo discovery rather than simple library screening.
  • Includes free ADME property estimation for every generated molecule.
  • Supports flexible target definition including pocket residues and reference ligands.
  • Provides clear cost transparency before job submission.

Usage examples

“Design 500 novel small-molecule binders for my protein target defined in target.yaml.”
The agent will validate the count, run an estimate-cost check, request your confirmation, and then initiate the design job, providing the job ID and monitoring instructions.
“Generate 1000 molecules for this target, restricted to the Enamine REAL library.”
The agent will include the chemical_space: enamine_real parameter in the payload, estimate the cost, and proceed with the generation workflow upon your approval.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/openai/boltz-small-molecule-design/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip boltz-small-molecule-design.zip -d .agents/skills

Documentation by Boltz

Workflow

If boltz-api is missing from PATH, use boltz-cli-setup for install/update guidance before retrying. If a command reports missing or expired authentication, use boltz-cli-setup to start boltz-api auth login --device-code before retrying; do not ask permission first. If the agent host sandbox blocks boltz-api install/auth/API calls, use boltz-cli-setup to request the host sandbox bypass/escalation needed for user-wide CLI install, browser login, credential storage, temp files, or API access before retrying.

Use this skill when the user wants de novo small-molecule binders (no existing library).

  1. Normalize the target: one or more protein sequences into target.entities, plus optional pocket_residues (0-based) and/or reference_ligands (known binders to help locate the pocket).

  2. Pick num_molecules — valid range 10 to 1,000,000 (server rejects outside it). If the user says fewer than 10, explain the floor and propose 10.

  3. Only add chemical_space (e.g. "enamine_real") if the user explicitly wants generation restricted to synthesizable molecules within that library.

  4. Supported optional features include chemical_space and molecule_filters; only add them on explicit request. Read references/api.md for exact shapes and filter options.

  5. Author the payload YAML or JSON, run estimate-cost, show the USD cost, wait for explicit confirmation. Cost is a flat $0.025 per molecule (size-independent); still quote estimated_cost_usd from the response as the authoritative total.

  6. start to submit (synchronous). Capture the ID.

  7. Launch download-results with the agent runtime's background/non-blocking command facility; it polls, paginates, downloads per-hit structures, and exits when terminal. In Claude Code, use Bash with run_in_background: true. In Codex, run download-results as a foreground shell command with yield_time_ms: 1000; if Codex returns a session_id, keep it for optional same-thread polling, but treat download-status plus the run directory as the durable source of truth. In Codex app/desktop runtimes that expose same-thread heartbeat automations, create a heartbeat that checks download-status periodically and posts a concise completion or failure update when the download reaches a terminal state. After launching the downloader, always report the job ID, run name, and output directory. Include the next check cadence if the heartbeat was created; otherwise include the download-status command.

  8. Rank hits from <output-root>/<run-name>/results/index.jsonl by binding_confidence for hit discovery or optimization_score for lead optimization. Each generated molecule also carries a free adme block (solubility, permeability, lipophilicity) — surface it for developability triage when the user cares about ADME, or when a top hit looks risky. Read references/results.md for output layout and metric details.

Command Pattern

# Replace placeholders with concrete absolute paths before running.
# Use a short descriptive run name, for example: sm-design-<target>-<batch>-v1

boltz-api small-molecule:design estimate-cost \
  --input @yaml:///absolute/path/payload.yaml

boltz-api small-molecule:design start \
       --idempotency-key "<run-name>" \
       --input @yaml:///absolute/path/payload.yaml \
       --raw-output --transform id

# Copy the printed job ID into this command, then launch it in the agent
# runtime's background/non-blocking mode.
# Claude Code: Bash with run_in_background=true.
# Codex: foreground shell command with yield_time_ms=1000; keep the returned session_id if one is provided.
# Do not append "&" or use nohup in Codex.
boltz-api download-results \
  --id "<job-id-from-start>" --name "<run-name>" \
  --root-dir "/absolute/path/boltz-experiments" \
  --poll-interval-seconds 60
# -> /absolute/path/boltz-experiments/<run-name>/results/<pres_*>/...

Payload keys are num_molecules, target, chemical_space, molecule_filters — the API body field names.

Always Do This

  • Enforce 10 <= num_molecules <= 1,000,000 before calling estimate-cost. The server rejects values outside that range.

  • Cost is a flat $0.025 per molecule (size-independent). estimate-cost returns the authoritative total.

  • Treat pocket residue indices as 0-based.

  • Keep payload field names exactly as the API body names shown in references/api.md.

  • Use absolute paths for the output root, payload files, and embedded target files. Do not cd into the run directory for follow-up commands; pass the same --root-dir and use absolute paths so later relative paths do not drift.

  • Prefer one merged top-level payload via --input @yaml:///absolute/path/payload.yaml or @json:///absolute/path/payload.json for estimate-cost and start. Keep --idempotency-key and --workspace-id top-level; if they also appear inside --input, the top-level flags win.

  • Direct object flags still work as overrides: for example --target @yaml:///absolute/path/target.yaml or --molecule-filters @json:///absolute/path/filters.json. Piped YAML / JSON on stdin also works, but it must use API body field names. Never use @file://.

  • Use the same slug as both --idempotency-key at submit and --name on download-results.

  • In permission-gated agents such as Claude Code, keep each Boltz call as a top-level command that starts with boltz-api. Prefer concrete arguments over sh -c, inline environment assignments, aliases, wrapper scripts, loops, or pipelines around the boltz-api invocation unless the user already allowed that exact command form. Use --raw-output --transform id, read the printed ID, then paste that literal ID into the next download-results command.

  • Prefer the agent runtime's background/non-blocking command mode for download-results. In Codex specifically, keep download-results in the foreground and set the shell tool yield to 1000 ms; Codex will return a session_id if the command is still running. Do not append & or use nohup in Codex because the tool runner may clean up shell-backgrounded descendants before .boltz-run.json is fully written.

  • After the background/session starts, do not manually wait on it or run ad hoc polling loops. Wall-clock time scales roughly with num_molecules: under 100 often finishes in a few minutes, 100-1,000 may take several minutes to tens of minutes, and larger runs can take longer or hours depending on inputs and system load. Don't quote a fixed duration. --poll-interval-seconds 60 is a sensible default for the downloader. download-results emits JSONL progress on stderr by default; add --progress-format text --verbose only when you explicitly want human-readable logs.

  • In Codex app/desktop runtimes with same-thread heartbeat automation support, schedule a heartbeat after launching download-results. The heartbeat should run boltz-api --format json download-status --name "<run-name>" --root-dir "/absolute/path/boltz-experiments" and stop once terminal. Choose cadence by num_molecules: under 100 -> every 1-2 minutes; 100-1,000 -> every 5 minutes; over 1,000 -> every 15 minutes. Post only material status changes or terminal completion/failure. Poll the saved session_id with an empty write_stdin only for interactive, user-requested progress checks. Never run a manual poll loop in the current turn.

  • If the current host has no heartbeat automation support, do not claim an automatic next check. Report the job ID, run name, output directory, and the command needed to check download-status.

  • If detached download needs to be restarted, re-run boltz-api download-results with the same --name "<run-name>" and the same --root-dir.

  • Do not invent filters; only add molecule_filters on user request.

Escape Hatch

Read references/api.md for the target, chemical_space, and molecule_filters shapes (filter catalog matches the screen endpoint). Read references/results.md after download when ranking generated molecules or explaining outputs.

Outputs

Rank from results/index.jsonl after download-results; use references/results.md for local file layout and metric meanings.

Files

references/api.md

Small Molecule Design — Payload Reference

Covers the small-molecule:design endpoint. Prefer a single merged top-level --input payload. Field names below are API body field names, not CLI flag names.

Minimal CLI pattern:

boltz-api small-molecule:design estimate-cost --input @yaml:///absolute/path/payload.yaml
boltz-api small-molecule:design start --idempotency-key "<run-name>" --input @yaml:///absolute/path/payload.yaml --raw-output --transform id

In permission-gated agents, keep the submit command as a top-level boltz-api ... start invocation. Read the printed job ID from stdout and paste it into the later download-results command.

Keep --idempotency-key and --workspace-id top-level; if they also appear inside --input, the top-level flags win. Direct object flags still work as overrides, such as --target @yaml:///absolute/path/target.yaml or --molecule-filters @json:///absolute/path/filters.json. Piped YAML / JSON on stdin remains supported when you need it, but the body must use API field names.

Contents

  • Top-level request

  • num_molecules minimum

  • Cost

  • chemical_space

  • target

  • molecule_filters

  • Outputs (after download-results)

  • Escape hatch

Top-level request

# payload.yaml
num_molecules: 10
target:
  entities:
    - type: protein
      chain_ids: [A]
      value: MKTAYIAKQRQISFVKSHFSRQ
  pocket_residues:
    A: [42, 43, 44]         # 0-based
  reference_ligands:
    - "CC(=O)Oc1ccccc1C(=O)O"
chemical_space: enamine_real
molecule_filters:
  boltz_smarts_catalog_filter_level: recommended

Top-level fields:

  • num_molecules (required) — number to generate. Must be between 10 and 1,000,000 (server rejects outside this range).

  • target (required) — protein target object (same shape as the screen endpoint).

  • chemical_space (optional) — generation space constraint. Currently "enamine_real" is the documented value. Omit for default.

  • molecule_filters (optional) — filter candidates before they're scored. Same schema as the screen endpoint.

Also passed as separate start flags:

  • --idempotency-key <slug>

  • --workspace-id <id> (admin keys only)

num_molecules minimum

The server rejects num_molecules < 10 or > 1000000 with VALIDATION_ERROR. Validate client-side before submitting.

Cost

Cost is a flat $0.025 per molecule (size-independent — verified against estimate-cost: the per-unit rate does not change with target or molecule size). estimate-cost returns the authoritative total — always report estimated_cost_usd.

chemical_space

Optional. Documented value: "enamine_real" — restricts generation to synthesizable molecules from the Enamine REAL library. Omit unless the user explicitly wants this.

target

Identical shape to small-molecule:library-screen. Only protein entities are supported.

target:
  entities:
    - type: protein
      chain_ids: [A]
      value: MKTAYIAKQRQISFVKSHFSRQ
      cyclic: false           # optional
      modifications: []       # optional; defaults to []
  pocket_residues:
    A: [42, 43, 44]           # 0-based
  reference_ligands:
    - "CC(=O)Oc1ccccc1C(=O)O"

Entity fields:

  • type: protein (required)

  • chain_ids (required)

  • value (required)

  • modifications (optional)

  • cyclic (optional, bool)

Optional target fields:

  • pocket_residues — {chain_id: [0-based residue_index, ...]}.

  • reference_ligands — list of SMILES to help locate the pocket.

Polymer modifications
modifications:
  - residue_index: 12         # 0-based
    type: ccd
    value: MSE

type must be ccd — SMILES polymer modifications are not supported (the API rejects them with modifications[].type must be "ccd").

molecule_filters

Same schema as the screen endpoint. Applied during generation so candidates that fail are never scored.

Top-level:

  • boltz_smarts_catalog_filter_level — "recommended" (default), "extra", "aggressive", "disabled".

  • custom_filters — list, AND-combined.

lipinski_filter
custom_filters:
  - type: lipinski_filter
    max_mw: 500
    max_logp: 5
    max_hbd: 5
    max_hba: 10
    allow_single_violation: true

All four caps (max_mw, max_logp, max_hbd, max_hba) are required together — only allow_single_violation is optional. For a partial cap (e.g. MW + logP only), use rdkit_descriptor_filter, whose descriptor keys are independently optional; a partial lipinski_filter is rejected with a confusing union error.

rdkit_descriptor_filter
custom_filters:
  - type: rdkit_descriptor_filter
    mol_wt: {min: 250, max: 550}
    mol_logp: {min: 1, max: 5}
    num_h_donors: {max: 5}
    num_h_acceptors: {max: 10}
    num_rotatable_bonds: {max: 10}
    num_rings: {min: 1, max: 6}
    num_aromatic_rings: {max: 3}
    num_heteroatoms: {min: 1, max: 15}
    fraction_csp3: {min: 0.2, max: 1.0}
    tpsa: {min: 20, max: 140}

Descriptor keys: mol_wt, mol_logp, num_h_donors, num_h_acceptors, num_rotatable_bonds, num_rings, num_aromatic_rings, num_heteroatoms, fraction_csp3, tpsa. Each takes {min?, max?}.

smarts_catalog_filter
custom_filters:
  - type: smarts_catalog_filter
    catalog: PAINS

Catalogs: PAINS, PAINS_A, PAINS_B, PAINS_C, BRENK, CHEMBL, CHEMBL_BMS, CHEMBL_Dundee, CHEMBL_Glaxo, CHEMBL_Inpharmatica, CHEMBL_LINT, CHEMBL_MLSMR, CHEMBL_SureChEMBL, NIH.

smarts_custom_filter
custom_filters:
  - type: smarts_custom_filter
    patterns: ["[N+](=O)[O-]"]
smiles_regex_filter
custom_filters:
  - type: smiles_regex_filter
    patterns: ["Cl", "Br"]

Outputs (after download-results)

Under <output-root>/<run-name>/:

  • .boltz-run.json

  • run.json — sanitized remote run record

  • results/index.jsonl — one generated candidate per line, copied from list-results metadata plus local artifact paths

  • results/<pres_*>/metadata.json — per-result metadata copied from the list-results record

  • results/<pres_*>/archive.tar.gz — one dir per generated candidate

  • results/<pres_*>/files/result/{metrics.json, <result-id>_predicted.cif, pae.npz} (the CIF is named <pres_*>_predicted.cif — prefer the paths.structure field from index.jsonl over hard-coding the filename)

Per-result fields (available in results/index.jsonl, results/<pres_*>/metadata.json, and the list-results stream):

  • id — server-assigned pres_* ID

  • smiles — generated SMILES

  • metrics.binding_confidence — primary for hit discovery

  • metrics.optimization_score — ranks by binding strength for lead optimization

  • metrics.structure_confidence

  • metrics.complex_plddt, metrics.complex_iplddt

  • metrics.iptm, metrics.ptm

  • adme — Tier-1 ADME triage returned free per generated molecule (sibling of metrics, not nested in it). Object with solubility (categorical: high-confidence / medium-confidence / high-risk), permeability (numeric score), and lipophilicity (numeric LogD). Approximate estimates for triage/ranking, not absolute measurements.

  • artifacts.structure.url, artifacts.archive.url (presigned, short-lived)

  • warnings — optional array of {code, message} quality flags (e.g. low_confidence, unusual_geometry); empty or absent on clean results. Surface them when presenting top hits.

Rank from results/index.jsonl after download-results. binding_confidence and optimization_score are parallel intents (hit discovery vs. lead optimization), not a primary/fallback hierarchy. Sort by whichever matches the user's goal.

Escape hatch

Requirements and compatibility

Written for: OpenAI Codex

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs Python

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
Boltz
Publisher
OpenAI (Official)
Distributed by
OpenAI
Source
openai/plugins · plugins/boltz-api-cli/skills/boltz-small-molecule-design · commit d420d13
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from plugins/boltz-api-cli/LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Boltz or OpenAI.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download boltz-small-molecule-design.zip