chemdraw-mcp
chemdraw-mcp
Chat → estructura química. Un servidor MCP para Claude Desktop: describes una molécula, una reacción o un resultado de laboratorio en palabras sencillas, y él dibuja la figura — un PNG/SVG listo para imprimir renderizado localmente con RDKit, además de una vista previa interactiva dentro del chat. "Dibuja aspirina" ya es un comando completo.
Diseñado para estudiantes de farmacia y química que pierden demasiado tiempo haciendo clic en hexágonos. 20 herramientas cubren lo que un informe o una diapositiva necesitan de verdad: estructuras, esquemas de reacción, mecanismos paso a paso, figuras de alcance de sustrato, placas de TLC, curvas de valoración, espectros esquemáticos, fichas de datos de sustancias, cálculos de ensayo Ph.Eur. y mazos de Anki.
Lo que te cuesta: un comando de instalación. Apache-2.0, sin clave de API, sin registro para el servidor, sin licencia de ChemDraw — necesitas Claude Desktop y uv, todo lo demás se descarga una sola vez. El renderizado se ejecuta íntegramente en tu máquina; solo la resolución de nombres y las consultas a bases de datos llegan a internet. El CDXML de ChemDraw es un formato extra opcional para quienes quieran seguir editando allí, nunca un requisito.
Ejemplo de salida
"Dibuja cafeína" — PNG listo para imprimir, generado por generate_molecule:
"Muestra la esterificación de Fischer del etanol con ácido acético" —
generate_reaction renderiza el esquema con las condiciones sobre la flecha,
en vivo en el panel del chat:
"Muestra el mecanismo de la esterificación de Fischer paso a paso" —
generate_mechanism renderiza flechas curvas de flujo electrónico en el panel
interactivo:
"Haz una figura de alcance de mis acoplamientos de Suzuki: 3a 92%, 3b 88% tras 12 h,
3c 64% con ee 94% y dr 10:1, 3d 71%" — generate_scope_table coloca la
ecuación general con sus condiciones arriba y los productos debajo, con una
longitud de enlace compartida y una línea base de leyenda compartida:
"Dibuja el espectro IR del acetato de etilo" — generate_spectrum (dibuja
los picos que se le dan, con convenciones de ejes por tipo):
"TLC de mi esterificación: educto en 0,30, producto en 0,65, el co-spot muestra
ambos, queda algo de educto" — generate_tlc dibuja la placa que pide el
informe de laboratorio, con fase móvil y detección como leyenda:
"Muestra la cafeína en 3D" — generate_3d incrusta la molécula (ETKDG +
campo de fuerza) y abre un visor de bolas y varillas arrastrable para rotar en
el panel del chat:
"¿Qué distingue al ibuprofeno del naproxeno y del ketoprofeno?" —
compare_molecules mantiene neutro el andamiaje compartido (MCS) y resalta
todo lo que difiere:
"Curva de valoración del ácido fosfórico con NaOH, fenolftaleína como
indicador" — generate_titration_curve calcula el pH a partir del balance
de carga exacto, con puntos de equivalencia, puntos tampón (pH = pKa) y la
banda del indicador; su gemelo generate_species_distribution muestra qué
especie de protonación domina en cada pH:
"Crea un mazo de Anki con moléculas importantes y ábrelo en Anki" —
export_anki_deck construye un .apkg listo para importar
con estructuras renderizadas incrustadas; con el complemento opcional
AnkiConnect las tarjetas llegan directamente a Anki en ejecución, sin clics:
Related MCP server: ChemMCP
Características
Las 20 herramientas que expone el servidor. Los archivos se escriben en
~/ChemDraw-Output/; cada herramienta de dibujo también devuelve una vista
previa en vivo para el panel del chat.
Estructuras y esquemas
generate_molecule— nombre/SMILES → estructura 2D como PNG + SVG (opcionalmente CDXML), con propiedades, detección de grupos funcionales y una comprobación de la regla de Lipinskibatch_generate— una lista completa de estructuras en una sola llamadagenerate_reaction— eductos + productos + condiciones → esquema de reacción con las condiciones colocadas sobre la flechagenerate_mechanism— mecanismos con flechas curvas (SN1, SN2, esterificación de Fischer) paso a pasogenerate_scope_table— la figura de alcance de sustrato de la literatura metodológica: la ecuación general con sus condiciones arriba, debajo una cuadrícula de productos, cada uno con su identificador ("1a") y rendimiento ("78%") más ee/dr/tiempo opcionales. Todas las estructuras comparten una longitud de enlace, todas las leyendas una línea base; una entrada que no se puede resolver se notifica, no es fatalcompare_molecules— 2–4 estructuras lado a lado, diferencias resaltadas, andamiaje compartido (MCS) neutrogenerate_3d— conformero 3D de bolas y varillas rotable en el panel del chat (ETKDGv3 + campo de fuerza) más exportación SDF
Resultados de laboratorio y análisis
generate_spectrum— espectros esquemáticos a partir de listas de picos (IR, NIR, Raman, UV/Vis, fluorescencia, ORD, CD, ¹H/¹³C RMN, EM) con convenciones de ejes por tipo — dibuja los picos dados, no predice espectrosgenerate_tlc— dibujo de placa de TLC a partir de valores de Rf: línea de inicio abajo, frente de disolvente arriba, un carril con leyenda por punto de aplicación (educto / reacción / co-spot), Rf anotado en cada mancha, fase móvil y detección impresas como leyenda — el dibujo que pide un informe de laboratoriogenerate_titration_curve— pH frente a volumen de valorante a partir del balance de carga exacto, con puntos de equivalencia, puntos tampón (pH = pKa) y banda de transición del indicadorgenerate_species_distribution— fracciones de especies de protonación frente al pH (Henderson–Hasselbalch) con los cruces de pKa marcadosgenerate_calibration_curve— recta de mínimos cuadrados a través de tus patrones, y las incógnitas leídas de ella como harías con una regla. Una muestra fuera del rango calibrado se etiqueta como extrapolada en lugar de notificarse en silencio; los límites de detección y cuantificación (DIN 32645) vienen incluidos para la cuestión de validación
Cálculos de banco (el número y el desarrollo — un informe de laboratorio pide ambos)
calculate_solution— qué pesar (m = c · V · M), lo que realmente obtuviste, diluciones (C₁V₁ = C₂V₂ con el volumen de disolvente especificado), el cuadrado de mezclas y masas molares incluyendo hidratos comoCuSO₄·5H₂O. Avisa cuando la porción calculada cae por debajo de lo que resuelve una balanza analítica — entonces diluir una porción mayor es lo correctocalculate_content— una determinación de contenido como la quiere el protocolo: un contenido por medición → prueba de outliers de Grubbs → media, s, RSD → prueba t contra el contenido declarado. Valoración (con determinación de título a partir de valoraciones de referencia) y fotometría, además de los índices de grasas (ácido, saponificación, éster y yodo) y el contenido de agua por Karl Fischer comomethods adicionalescalculate_ph— ácidos y bases débiles y fuertes, tampones y recetas de tampones hasta masas pesables. Resuelto mediante el balance de carga exacto con la aproximación de libro impresa al lado: donde ambas discrepan, la aproximación ha perdido sus supuestos y lo dice. HCl 10⁻⁸ M sale a pH 6,98, no 8
Datos de sustancias (consultas en línea)
lookup— los datos como texto, untopicpor pregunta:properties(fórmula, masa, CAS, InChIKey — el valor predeterminado),safety(indicaciones de peligro GHS, pictogramas, palabra de advertencia),physical(punto de fusión/ebullición, solubilidad, densidad),biochem(clasificación ChEBI más entradas UniProt relacionadas),pathway(rutas metabólicas de KEGG)lookup_molecule_data— PubChem + GHS combinados en una sola ficha de datos para el panel del chat, estructura incluidapredict_spectrum— qué bandas IR debería mostrar una estructura (con intensidad y forma de banda), a qué podría corresponder un número de onda medido y cuántas señales de ¹H esperar con su relación integral. Determinista, así que dice lo que no puede hacer: sin desplazamientos químicos en ppm, y los protones diastereotópicos se cuentan como una sola señal
Preparación de exámenes
export_anki_deck— tarjetas flash como un.apkgde Anki listo para importar: ejercicios de estructura↔nombre (opcionalmente invertidos: una nota, ambas direcciones), tarjetas de cloze/rellenar el hueco, reacciones de identidad/detección, asignación de bandas espectrales — con imágenes renderizadas incrustadas, etiquetas por tarjeta, subdecksParent::Child; reexportar un mazo actualiza las tarjetas en lugar de duplicarlas. Entrega opcional directamente en Anki en ejecución mediante el complemento AnkiConnect. Pasacurated_deck_iden lugar de tus propias tarjetas para un mazo inicial pequeño y verificado por fórmulas (analgésicos clásicos, reacciones de identidad Ph.Eur.)
Cada herramienta pertenece a una de cinco áreas — dibujar, gráficos de
laboratorio, consultar, calcular, Anki — y cada una dice para qué no sirve,
en ambas direcciones, de modo que "dibuja aspirina" no puede acabar en una
cuadrícula de alcance de sustrato y "¿qué pH tiene mi tampón?" no puede acabar
en una herramienta de trazado. Una herramienta queda fuera de ellas: save_png es la
mitad del servidor del botón de exportación del panel, se llama al hacer clic
en él, nunca por sí sola.
Dos herramientas opcionales de vault (search_vault, read_vault_entry)
aparecen solo cuando CHEMDRAW_VAULT_PATH está definido; sin él, el servidor
expone exactamente las 20 herramientas anteriores.
Opciones de las herramientas de dibujo
formats—["png","svg"]por defecto;"cdxml"además de eso paragenerate_molecule,generate_reactionybatch_generate. Las herramientas de figuras (generate_scope_table,generate_tlc,generate_spectrum) rechazan CDXML con un error claro en lugar de escribir algo sin sentido.abbreviate_groups=True— dibuja los sustituyentes comunes como las etiquetas que los químicos escriben de verdad: Ph, Bn, OMe, OAc, tBu, CO₂H, Boc, Ts, TBS. Merece la pena siempre que las celdas se hacen pequeñas — una figura de alcance sigue siendo legible porque solo lo que difiere entre los sustratos permanece escrito. Disponible engenerate_molecule,generate_reaction,generate_scope_table,batch_generate.render_style— un aspecto con nombre en lugar de un montón de parámetros de renderizado, en las mismas cuatro herramientas."compact"(enlaces finos, tamaño de etiqueta limitado, márgenes ajustados) para una figura pequeña en un diseño de dos columnas,"presentation"(doble grosor de enlace, tamaño de fuente mínimo, más relleno) para una diapositiva de clase,"grayscale"para impresión en blanco y negro, donde el rojo y el azul se convertirían en dos grises indistinguibles. Vacío significa el aspecto predeterminado, sin tocar.annotate_stereo=True— imprime descriptores CIP (R/S, E/Z) en el dibujo 2D (generate_molecule,batch_generate).
Instalación
Tres formas de entrar; elige una. Las opciones 1 y 2 se fusionan en la configuración de forma idempotente, haz una copia de seguridad primero y deja intacto cualquier otro servidor MCP que tengas configurado. Después reinicia Claude Desktop y pregunta: "dibuja cafeína".
Opción 1 — clonar el repositorio (recomendada si quieres leer o cambiar el código; instala uv si falta, sincroniza las dependencias, registra el servidor):
git clone https://github.com/jurimaxam-dotcom/chemdraw-mcp.git
cd chemdraw-mcp && ./install.shOpción 2 — desde PyPI, sin clonar (necesita uv):
uv tool install chemdraw-mcp
chemdraw-installchemdraw-install escribe la entrada de Claude Desktop por ti, usando la
ruta absoluta del lanzador instalado, e imprime el comando de inicio que
registró.
Opción 3 — editar la configuración a mano. Añade esto a
claude_desktop_config.json bajo mcpServers (macOS:
~/Library/Application Support/Claude/claude_desktop_config.json):
"chemdraw-tool": {
"command": "/opt/homebrew/bin/uvx",
"args": ["chemdraw-mcp"]
}El único escollo que rompe toda instalación manual: Claude Desktop no inicia los servidores MCP desde un shell de inicio de sesión — usa el PATH mínimo de la GUI. Un
"uvx"o"uv"desnudo no se puede resolver allí, y el servidor falla al iniciar sin decirlo. Pon siempre la ruta absoluta quewhich uvximprime en tu máquina encommand. Las opciones 1 y 2 hacen esto por ti.
Extras opcionales
Un runtime de Java (p. ej.
brew install openjdk) permite que OPSIN analice nombres IUPAC sistemáticos sin conexión — incluidos los que ninguna base de datos indexa. Sin Java el resolvedor simplemente continúa con la búsqueda en línea de PubChem/NCI.El complemento AnkiConnect permite que
export_anki_deckenvíe tarjetas directamente a un Anki en ejecución. Sin él obtienes el archivo.apkgy lo importas tú mismo.ChemDraw (macOS) nunca es necesario: solicita
formats=["cdxml"]y abre el archivo tú mismo si quieres seguir editando allí.
¿Algo no funciona? Ejecuta el doctor
chemdraw-doctor # after "uv tool install chemdraw-mcp"
uv run chemdraw-doctor # in the cloned repo
uvx --from chemdraw-mcp chemdraw-doctor # without installing anythingEsto es lo primero que hay que probar — convierte "el servidor no hace nada"
en una causa con nombre. Comprueba las seis cosas que hacen que el servidor
parezca muerto en el chat (renderizado de RDKit, el runtime de Java/OPSIN, la
ruta de uv, la entrada de Claude Desktop, las bases de datos de nombres, el
directorio de salida) e imprime, para cada problema, el comando exacto que lo
arregla. Se distinguen tres niveles: [OK], [LIMITED] (funciona, pero
restringido) y [FAIL] (roto); [NOTE] marca comprobaciones que simplemente
no aplican, como no tener Claude Desktop instalado. El código de salida
permanece en 0 mientras el servidor sea utilizable, para que pueda ejecutarse
en scripts. (Desde una instalación de PyPI las comprobaciones de uv y
Claude Desktop informan [NOTE] — se relacionan con el instalador del
repositorio.)
Limitaciones
Dicho de antemano, para que nada te sorprenda en un informe:
Java es opcional, y eso tiene un precio. Sin un JRE, OPSIN se omite y los nombres se resuelven en línea vía PubChem/NCI — así que las búsquedas de nombres necesitan conexión a internet y solo funcionan para nombres que esas bases de datos indexan. La entrada SMILES nunca toca la red.
Los espectros son esquemáticos.
generate_spectrumdibuja los picos que se le dan, con las convenciones de eje correctas para el tipo de espectro. No mide nada ni predice nada — si los valores de los picos vinieron del chat en lugar de tu instrumento, verifícalos antes de que entren en un informe.La intensidad de TLC es una pista de dibujo. La
intensityopcional (0…1) hace que una mancha sea más tenue en el boceto. No es densitometría y no tiene significado cuantitativo.CDXML es un camino lateral. Se escribe desde la molécula de RDKit y se valida de ida y vuelta, pero PNG/SVG son las salidas principales y las que cubren las pruebas de píxeles. CDXML está desactivado por defecto y limitado a estructuras y esquemas de reacción — las placas de TLC, las figuras de alcance y los espectros lo rechazan.
3D es un conformero.
generate_3dincrusta con ETKDGv3 y optimiza con MMFF (UFF como respaldo). Es una geometría plausible para mirar, no una búsqueda conformacional ni una declaración de energía.El puente de ChemDraw es solo para macOS y necesita un ChemDraw instalado localmente. Todo lo demás funciona sin él.
Cómo funciona
name / SMILES
│
▼
resolver ──► OPSIN (systematic IUPAC names, offline) ──► PubChem / NCI (names) · direct parse (SMILES)
│
▼
RDKit 2D coordinates ──► validation (sanity, round-trip)
│
├──► image_export → PNG + SVG files (primary, offline)
├──► svg_renderer → interactive chat preview (MCP App resource)
└──► cdxml_writer → ChemDraw CDXML (optional, on request)Desarrollo
Python 3.11+, gestor de paquetes uv.
uv sync # backend deps
cd chemdraw_tool/ui && npm install && npx playwright install chromium # frontend, once
./test.sh # the gate: pytest + JS unit + headless-Chromium e2eMás de 600 pruebas, escritas primero la prueba. La prueba e2e rasteriza un SVG real de RDKit en Chromium sin interfaz y lo compara contra una captura de píxeles exacta — la ruta de exportación y la vista previa en el chat se mantienen con las mismas constantes de dibujo.
Licencia
Apache-2.0 — ver LICENSE. Copyright 2026 jurimaxam-dotcom.
Aviso: Este es un proyecto no oficial e independiente, no afiliado ni respaldado por Revvity. ChemDraw es una marca comercial de Revvity Signals Software, Inc. Esta herramienta no incluye ni requiere ChemDraw; puede exportar opcionalmente archivos en el formato abierto CDXML.
Available Tools
7 toolsbatch_generateA
Draw several individual compounds as separate PNG/SVG files and panels.
Failed names are reported in failed while successful structures are returned. Pass English or IUPAC names, or SMILES.
Not this tool for: one compound (use generate_molecule), structural differences (use compare_molecules), or a reaction scheme (use generate_reaction).
Args: molecules: List of English/IUPAC compound names or SMILES strings. formats: Output file formats, any of "png", "svg", "cdxml" (default: ["png", "svg"]). Include "cdxml" ONLY when the user wants to edit the structures in ChemDraw. abbreviate_groups: Set True to draw common substituents as short labels (Ph, Bn, OAc, OMe, CO2H, tBu, Boc, Ts …) instead of full skeletons. Applies to every molecule in the batch, so a series of structures stays visually consistent. render_style: Named look applied to every molecule in the batch. Empty = standard style. "compact" for small printed figures, "presentation" for slides, "grayscale" for grayscale printing.
| Name | Required | Description | Default |
|---|---|---|---|
| formats | No | ||
| molecules | Yes | ||
| render_style | No | ||
| annotate_stereo | No | ||
| abbreviate_groups | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| type | No | |
| failed | No | |
| molecules | No | |
| cdxml_paths | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Since no annotations are provided, the description carries the full burden and performs well. It explicitly details a key behavioral trait: failed names are reported while successful structures are returned. It also explains the conditional use of 'cdxml' for ChemDraw editing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The tool definition is structured logically, starting with the core function, then providing limitations, and finally detailing parameters. Every section is tightly written and efficiently organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of handling batch processing, multiple formats, and custom rendering, the description is remarkably complete. It provides all the necessary context and constraints for an agent to invoke the tool correctly despite the sparse structured data.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite having 0% schema description coverage, the description provides high-value semantic context for every parameter. For instance, it explains the functional difference between 'abbreviate_groups' (consistency) and 'render_style' (use case for printing/slides), adding meaning far beyond the schema data.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The purpose is highly specific: drawing multiple individual compounds as PNG/SVG files and panels. It clearly distinguishes itself from sibling tools by stating it is not suitable for single compounds (use generate_molecule), reaction schemes, or structural comparisons.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The tool explicitly forbids certain use cases, detailing that it should not be used for single molecules, structural differences, or reaction schemes. It provides direct redirection to the correct alternative sibling tool for each specific scenario.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compare_moleculesA
Compare 2-4 molecules side by side with their DIFFERENCES highlighted.
Computes the maximum common substructure (MCS): the shared scaffold stays neutral, everything outside it is highlighted — ideal for teaching drug classes ("what distinguishes ibuprofen from naproxen?"), homologous series or derivatives.
Use this when the user wants to compare structures, see differences between compounds, or study a drug class.
Reach for it in conversation too, not only on request: the word "difference" in a question about two substances is the trigger. Answering "what distinguishes ibuprofen from naproxen?" in prose leaves the reader to find the difference in two separate pictures — this figure marks it.
Not this tool for: a single structure (generate_molecule), or several structures that are merely to be drawn rather than contrasted (batch_generate).
Args: structures: 2-4 English/IUPAC names or SMILES strings. labels: Optional display names under each panel (localizable). title: Optional heading for the comparison (localizable).
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | ||
| labels | No | ||
| structures | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| svg | No | |
| name | Yes | |
| type | No | |
| files | No | |
| notes | No | |
| subtitle | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full load — it discloses the algorithmic behavior (MCS computed, shared scaffold kept neutral for contrast) and that the result is a figure rather than prose, which is meaningful behavioral context. It stops short of stating failure behavior for unresolvable names or whether a file is written, which are the remaining gaps for an annotation-free tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core definition, then usage, then exclusions, then args — a rational order with clear sectioning. The conversational-trigger paragraph is slightly padded and repeats the ibuprofen/naproxen example already used earlier, costing a point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need no explanation, and the description covers scope, exclusions, and all three parameters. The only thin spot is edge-case behavior — what happens with fewer than 2 structures, more than 4, or an unresolvable name.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: structures accepts 2-4 English/IUPAC names or SMILES, labels are per-panel display names that are localizable, and title is an optional localizable heading. This adds real meaning beyond the bare schema types and closes the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Compare 2-4 molecules side by side') and explains the mechanism (maximum common substructure with non-shared parts highlighted), which tells the agent exactly what the output depicts. It also names the siblings it is not (generate_molecule, batch_generate), so it is distinguishable without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use triggers ('user wants to compare structures', 'study a drug class'), an explicit not-for clause with named alternatives for both exclusions, and even a conversational trigger word ('difference'). Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_anki_deckA
Export an Anki flashcard deck (.apkg) with rendered chemistry images.
Use this whenever the user wants flashcards, Anki cards or a study deck for molecules, reactions (e.g. pharmacopoeia identity tests) or spectra. A stated intention to learn or an exam coming up is the same request: offer a deck and write the cards yourself.
Two ways to fill the deck. Either pass cards you wrote yourself, or
pass curated_deck_id for a ready-made, formula-verified starter deck:
"analgesics-structures": structure → name drills for 8 classic analgesics (NSAIDs, paracetamol, morphine, celecoxib).
"pheur-identity-basics": classic Ph.Eur. identity tests — reagent, observation and reaction scheme where it helps.
The tool renders the images — YOU supply the card content from your knowledge. Each card side carries text plus at most ONE visual: structure (name or SMILES), reaction ({reactants, products, conditions}) or spectrum ({spectrum_type, peaks, title}). Proven types: structure↔name, identity reactions (question front, scheme back), functional-group recognition, band assignment, name drills.
Re-exporting under the SAME deck name updates existing cards instead of duplicating them — the front identifies the card.
Options: reversed=true drills both directions (one note, two cards); cloze=true makes fill-in-the-blank cards (front.text carries {{c1::...}}, back.text becomes the extra note). "Parent::Child" nests subdecks.
IMPORTANT: structures take English/IUPAC names or SMILES; card TEXTS may be localized. Never deliver via AnkiConnect unless asked.
Args: deck_name: Deck name, also the filename; re-use it to update a deck. Ignored when curated_deck_id is set. cards: The flashcards. Fronts unambiguous, explanations on the back. default_tags: Tags added to every card. deliver: "apkg" (file only), "open" (also opens it in Anki, macOS) or "ankiconnect" (imports via the AnkiConnect add-on). curated_deck_id: "analgesics-structures" or "pheur-identity-basics".
| Name | Required | Description | Default |
|---|---|---|---|
| cards | No | ||
| deliver | No | apkg | |
| deck_name | No | ||
| default_tags | No | ||
| curated_deck_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| file | No | |
| name | Yes | |
| type | No | |
| cards | Yes | |
| media | Yes | |
| fronts | No | |
| delivery | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does it well: same deck name updates rather than duplicates (front is the key), `deck_name` is ignored when `curated_deck_id` is set, `deliver` has three concrete modes, `reversed` produces one note/two cards, `cloze` changes what front/back mean, and 'Parent::Child' nests subdecks. These are non-obvious side effects an agent could not infer from the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Long but front-loaded and segmented: purpose first, then triggers, then the two fill paths, then card anatomy, then options, then per-argument notes. Every paragraph answers a distinct question an agent would otherwise have to guess at.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex nested-card export tool with 5 params, the description covers card construction, proven card types, update semantics and delivery modes; the output schema relieves it of explaining return values. Minor gap: it doesn't say what happens if neither `cards` nor `curated_deck_id` is supplied, nor where the .apkg file is written.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% at the top level, but the Args block documents all five parameters, including the enum-like values for `deliver` and `curated_deck_id` that the schema does not constrain. The card-side constraint (text plus at most ONE visual, with the shapes of structure/reaction/spectrum) supplies the nesting semantics the schema leaves implicit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and artifact: 'Export an Anki flashcard deck (.apkg) with rendered chemistry images.' It also clarifies the division of labour (tool renders images, the agent supplies card content), which no sibling tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the triggering situations (flashcards, study deck, exam coming up, intent to learn) and routes between the two fill modes: own `cards` vs `curated_deck_id`. It also states an exclusion ('Never deliver via AnkiConnect unless asked') and names both curated deck IDs with their contents.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_moleculeA
Draw one compound as a 2D structure — the default for a single substance.
Writes PNG/SVG files and returns an interactive panel with the structure, properties and functional groups. A bare compound name ("caffeine") also means this tool, and so does a question about why one compound behaves as it does (acidity, solubility) — the answer is in its structure. No ChemDraw required. A Fischer or Haworth projection of a sugar or amino acid, or a drawing with all H atoms, is this tool too: set view to "fischer", "haworth" or "all_h".
Not this tool for: several individual structures (use batch_generate), structural differences (use compare_molecules), a reaction scheme (use generate_reaction), or a data sheet (use lookup_molecule_data).
Pass English or IUPAC names, or SMILES; use label for a localized display name.
Args: name_or_smiles: English/IUPAC compound name or SMILES string. label: Display name shown below the structure (may be localized). formats: Any of "png", "svg", "cdxml" (default: png + svg). Add "cdxml" only when the structure is to be edited in ChemDraw. annotate_stereo: True prints CIP descriptors (R/S, E/Z) at each stereocenter. abbreviate_groups: True draws common substituents as the short labels chemists write by hand (Ph, Bn, OAc, OMe, CO2H, NO2, tBu, Boc, Ts, TMS). The chemistry is unchanged; no hover tooltips in the panel. render_style: "" standard · "compact" thin bonds for small print · "presentation" thick bonds for slides · "grayscale" b/w palette. stereo_variants: True returns every stereoisomer of the open centers (max 3) as a pick list instead of a drawing; only on request. view: "fischer"/"haworth"/"all_h" opens on that drawing, only if the user names it.
| Name | Required | Description | Default |
|---|---|---|---|
| view | No | ||
| label | No | ||
| formats | No | ||
| render_style | No | ||
| name_or_smiles | Yes | ||
| annotate_stereo | No | ||
| stereo_variants | No | ||
| abbreviate_groups | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| svg | No | |
| name | No | |
| type | No | |
| atoms | No | |
| files | No | |
| views | No | |
| message | No | |
| viewSvg | No | |
| lipinski | No | |
| subtitle | No | |
| viewAtoms | No | |
| candidates | No | |
| cdxml_path | No | |
| properties | No | |
| stereoNote | No | |
| initialView | No | |
| viewRequest | No | |
| projectionNote | No | |
| stereoWarnings | No | |
| functionalGroups | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the file side effects (writes PNG/SVG), the return artifact (interactive panel with structure, properties, functional groups), and non-obvious behavioral consequences per flag (abbreviate_groups kills hover tooltips; stereo_variants returns a pick list instead of a drawing). It stops short of error behavior for invalid names/SMILES or whether existing files are overwritten.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Roughly front-loaded: purpose first, then routing, then args. Minor redundancy — the fischer/haworth/all_h options are stated once in prose and again under view — and 'No ChemDraw required' is filler, but no sentence is genuinely wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Eight parameters, no annotations, and an output schema. The description covers routing, all parameter semantics, side effects, and the return artifact, so an agent can call it correctly without reading anything else.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must supply all meaning, and it does: formats lists allowed values and the default, view names its three accepted values, render_style enumerates all four modes with intent, and the boolean flags each explain their effect (CIP R/S and E/Z labels; abbreviation set Ph/Bn/OAc/...; max 3 stereoisomer pick list).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence gives a specific verb and resource ('draw one compound as a 2D structure') plus its scope ('the default for a single substance'). It then enumerates non-obvious inputs that also route here (bare compound name, a behavior question like acidity/solubility, Fischer/Haworth projections) and names each sibling that handles the other cases.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
An explicit 'Not this tool for:' block routes to batch_generate (several structures), compare_molecules (differences), generate_reaction (reaction schemes) and lookup_molecule_data (data sheets). Positive triggers are also given, including indirect ones like a question about why a compound behaves as it does.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_reactionA
Draw a reaction scheme from reactants, products and conditions.
Writes PNG/SVG files and returns a panel with conditions above and below the arrow. arrow: "forward" (→), "equilibrium" (⇌, reversible) or "retro" (⇒). Use it when explaining a reaction as well as for explicit drawing requests. This draws the net reaction, without step-by-step electron-flow mechanisms. Pass English or IUPAC compound names, or SMILES.
Not this tool for: one compound or a property of one compound such as its acidity (use generate_molecule), independent structures (use batch_generate), or structural differences (use compare_molecules).
Args: reactants: List of English/IUPAC reactant names or SMILES strings. products: List of English/IUPAC product names or SMILES strings. conditions: Text above the arrow (e.g. 'H2SO4, 0-5 °C'); formula digits are subscripted, a line break starts a new line. conditions_below: Text under the arrow (e.g. 'reflux, 2 h'). arrow: "forward" (→), "equilibrium" (⇌, reversible reaction) or "retro" (⇒, retrosynthesis: target as reactants, precursors as products). name: Display name for the reaction step (can be localized). formats: Any of "png", "svg", "cdxml" (default: png + svg). Add "cdxml" only when the scheme is to be edited in ChemDraw. abbreviate_groups: True draws common substituents as short labels (Ph, OAc, OMe, CO2H, tBu, Boc …); the CDXML keeps full structures. render_style: "" standard · "compact" small print · "presentation" slides · "grayscale" b/w palette. coefficients: One integer per species, reactants then products ([2, 1, 2] draws 2 H2 + O2 → 2 H2O). Set only when the user asks for a balanced equation; otherwise draw as given — the panel's "Apply coefficients" button sets them.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| arrow | No | forward | |
| formats | No | ||
| products | Yes | ||
| reactants | Yes | ||
| conditions | No | ||
| coefficients | No | ||
| render_style | No | ||
| conditions_below | No | ||
| abbreviate_groups | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | |
| type | No | |
| arrow | No | |
| files | No | |
| balance | No | |
| request | No | |
| products | No | |
| reactants | No | |
| cdxml_path | No | |
| conditions | No | |
| coefficients | No | |
| conditions_below | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description does the heavy lifting: it discloses side effects (writes PNG/SVG/CDXML files), the return artifact (a panel with conditions above/below the arrow), and a limitation (no electron-flow mechanisms). It also warns that coefficients are only applied on request and that the CDXML keeps full structures under abbreviation. Missing only concrete file locations or overwrite behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then exclusions, then a per-argument list — easy to scan. It loses a point for duplicating the arrow enum definition verbatim in both the opening paragraph and the Args block.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter generative tool with an output schema, everything an agent needs is present: triggers, exclusions, input formats, output formats and defaults. Return value explanation is correctly omitted since an output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description fully compensates: it defines every non-obvious parameter, gives the enum meanings for arrow with glyphs and the retro semantics, enumerates formats with a default, explains render_style values, and specifies coefficients ordering ('reactants then products') with a worked example.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Draw a reaction scheme from reactants, products and conditions') and immediately scopes it as the net reaction rather than a mechanism. Explicitly names each sibling it is not for and what to use instead.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives both a positive trigger ('Use it when explaining a reaction as well as for explicit drawing requests') and an explicit exclusion block listing generate_molecule, batch_generate and compare_molecules with the condition that selects each.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_molecule_dataA
Show a compound's data sheet: structure, PubChem properties and GHS safety.
Use it for a data sheet or facts available from those sources. The molecule panel also calls this tool when the user clicks Data. Internet access is required. Missing values are not evidence that a property or hazard is absent.
Not this tool for: a bare compound name with no data requested — use generate_molecule. Pass English or IUPAC names, or SMILES.
Args: name: English/IUPAC compound name or SMILES (e.g. 'Aspirin').
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | |
| type | No | |
| atoms | No | |
| smiles | No | |
| sources | No | |
| stereoNote | No | |
| molecule_svg | No | |
| stereoWarnings | No | |
| functionalGroups | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Since no annotations were provided, the description carries the full burden of transparency. It explicitly states that 'Missing values are not evidence that a property or hazard is absent,' which is a critical behavioral caveat for a lookup tool pulling external data. It also notes the dependency on internet access.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is highly efficient. Every sentence adds value, moving from primary function to operational requirements, exclusions, and finally, parameter guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the critical nature of distinguishing it from `generate_molecule` and specifying input formats (SMILES/IUPAC/English), the description is maximally complete for an AI agent attempting correct tool selection.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema is extremely sparse (just 'name': 'string'). The description significantly enhances the schema by detailing that 'name' can be an English/IUPAC compound name or a SMILES string, providing concrete examples like 'Aspirin' to guide usage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The purpose is immediately clear: to show a compound's data sheet including structure, PubChem properties, and GHS safety. It successfully differentiates itself from sibling tools by specifying its function as data retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The tool provides explicit instructions on when to use it and when *not* to use it, referring the agent to `generate_molecule` for bare compound names. It also adds the necessary operational constraint: internet access is required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_pngA
Internal helper for the panel UI — never call this directly.
The panel's export button calls it when the image clipboard is blocked by the sandbox; saving a picture is the user's click, not yours. The generate_* tools already write their PNG and SVG files themselves.
Expects a base64 PNG (with or without a data:image/png;base64,
prefix) and returns the path it was written to.
| Name | Required | Description | Default |
|---|---|---|---|
| filename | Yes | ||
| png_base64 | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral burden and does disclose the invocation context, the clipboard/sandbox condition, accepted input format, and that it returns the written path. It does not mention overwrite behavior, permissions, or error handling for file writes, which are relevant gaps for a save operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The warning not to call the tool is front-loaded, and the remaining sentences are short and purposeful. Every sentence adds either usage context or a relevant input/output detail without repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description need not explain return values in detail, and it already states that a path is returned. For a two-parameter internal helper it is largely complete, though filename semantics remain underspecified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It partially does by explaining that png_base64 is a base64 PNG with an optional data:image/png;base64, prefix, but it says nothing about the filename parameter's expected path, directory, extension, or overwrite semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action (save a PNG), the expected input (base64 PNG), and the result (returns the written path). It also explicitly distinguishes this from the generate_* tools, which already write their own PNG and SVG files, so an agent can tell this is not the normal image-generation path.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an unusually explicit usage rule: never call this directly, because the panel's export button invokes it when sandbox clipboard access is blocked. It also names the relevant alternative behavior by noting that generate_* tools already write their files themselves.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.6.0- Changed
batch_generate12 fields changed- added
Output schema / $defs / IsomerCandidateAdded value: +{ + "description": "One structure a family name (\"xylene\", \"Glucose\") can mean.", + "properties": { + "label": { + "title": "Label", + "type": "string" + }, + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "smiles": { + "title": "Smiles", + "type": "string" + }, + "svg": { + "default": "", + "title": "Svg", + "type": "string" + } + }, + "required": [ + "label", + "smiles" + ], + "title": "IsomerCandidate", + "type": "object" +} - added
Output schema / $defs / MoleculePayload / properties / candidatesAdded value: +{ + "default": [], + "items": { + "$ref": "#/$defs/IsomerCandidate" + }, + "title": "Candidates", + "type": "array" +} - added
Output schema / $defs / MoleculePayload / properties / initialViewAdded value: +{ + "default": "", + "title": "Initialview", + "type": "string" +} - added
Output schema / $defs / MoleculePayload / properties / messageAdded value: +{ + "default": "", + "title": "Message", + "type": "string" +} - added
Output schema / $defs / MoleculePayload / properties / projectionNoteAdded value: +{ + "default": "", + "title": "Projectionnote", + "type": "string" +} - added
Output schema / $defs / MoleculePayload / properties / stereoNoteAdded value: +{ + "default": "", + "title": "Stereonote", + "type": "string" +} - added
Output schema / $defs / MoleculePayload / properties / stereoWarningsAdded value: +{ + "default": [], + "items": { + "$ref": "#/$defs/StereoWarning" + }, + "title": "Stereowarnings", + "type": "array" +} - added
Output schema / $defs / MoleculePayload / properties / viewAtomsAdded value: +{ + "default": [], + "items": { + "$ref": "#/$defs/AtomData" + }, + "title": "Viewatoms", + "type": "array" +} - added
Output schema / $defs / MoleculePayload / properties / viewRequestAdded value: +{ + "additionalProperties": true, + "default": {}, + "title": "Viewrequest", + "type": "object" +} - added
Output schema / $defs / MoleculePayload / properties / viewSvgAdded value: +{ + "default": "", + "title": "Viewsvg", + "type": "string" +} - added
Output schema / $defs / MoleculePayload / properties / viewsAdded value: +{ + "default": [], + "items": { + "type": "string" + }, + "title": "Views", + "type": "array" +} - added
Output schema / $defs / StereoWarningAdded value: +{ + "description": "Ein Stereoelement, dessen Konfiguration die Eingabe offen lässt.", + "properties": { + "atoms": { + "default": [], + "items": { + "type": "integer" + }, + "title": "Atoms", + "type": "array" + }, + "kind": { + "title": "Kind", + "type": "string" + }, + "label": { + "default": "", + "title": "Label", + "type": "string" + } + }, + "required": [ + "kind" + ], + "title": "StereoWarning", + "type": "object" +}
- Changed
generate_molecule14 fields changed- added
Input schema / properties / stereo_variantsAdded value: +{ + "default": false, + "title": "Stereo Variants", + "type": "boolean" +} - added
Input schema / properties / viewAdded value: +{ + "default": "", + "title": "View", + "type": "string" +} - added
Output schema / $defs / IsomerCandidateAdded value: +{ + "description": "One structure a family name (\"xylene\", \"Glucose\") can mean.", + "properties": { + "label": { + "title": "Label", + "type": "string" + }, + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "smiles": { + "title": "Smiles", + "type": "string" + }, + "svg": { + "default": "", + "title": "Svg", + "type": "string" + } + }, + "required": [ + "label", + "smiles" + ], + "title": "IsomerCandidate", + "type": "object" +} - added
Output schema / $defs / StereoWarningAdded value: +{ + "description": "Ein Stereoelement, dessen Konfiguration die Eingabe offen lässt.", + "properties": { + "atoms": { + "default": [], + "items": { + "type": "integer" + }, + "title": "Atoms", + "type": "array" + }, + "kind": { + "title": "Kind", + "type": "string" + }, + "label": { + "default": "", + "title": "Label", + "type": "string" + } + }, + "required": [ + "kind" + ], + "title": "StereoWarning", + "type": "object" +} - added
Output schema / properties / candidatesAdded value: +{ + "default": [], + "items": { + "$ref": "#/$defs/IsomerCandidate" + }, + "title": "Candidates", + "type": "array" +} - added
Output schema / properties / initialViewAdded value: +{ + "default": "", + "title": "Initialview", + "type": "string" +} - added
Output schema / properties / messageAdded value: +{ + "default": "", + "title": "Message", + "type": "string" +} - added
Output schema / properties / projectionNoteAdded value: +{ + "default": "", + "title": "Projectionnote", + "type": "string" +} - added
Output schema / properties / stereoNoteAdded value: +{ + "default": "", + "title": "Stereonote", + "type": "string" +} - added
Output schema / properties / stereoWarningsAdded value: +{ + "default": [], + "items": { + "$ref": "#/$defs/StereoWarning" + }, + "title": "Stereowarnings", + "type": "array" +} - added
Output schema / properties / viewAtomsAdded value: +{ + "default": [], + "items": { + "$ref": "#/$defs/AtomData" + }, + "title": "Viewatoms", + "type": "array" +} - added
Output schema / properties / viewRequestAdded value: +{ + "additionalProperties": true, + "default": {}, + "title": "Viewrequest", + "type": "object" +} - added
Output schema / properties / viewSvgAdded value: +{ + "default": "", + "title": "Viewsvg", + "type": "string" +} - added
Output schema / properties / viewsAdded value: +{ + "default": [], + "items": { + "type": "string" + }, + "title": "Views", + "type": "array" +}
- Changed
generate_reaction10 fields changed- added
Input schema / properties / arrowAdded value: +{ + "default": "forward", + "enum": [ + "forward", + "equilibrium", + "retro" + ], + "title": "Arrow", + "type": "string" +} - added
Input schema / properties / coefficientsAdded value: +{ + "anyOf": [ + { + "items": { + "type": "integer" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Coefficients" +} - added
Input schema / properties / conditions_belowAdded value: +{ + "default": "", + "title": "Conditions Below", + "type": "string" +} - added
Output schema / $defs / MolEntry / properties / coefficientAdded value: +{ + "default": 1, + "title": "Coefficient", + "type": "integer" +} - added
Output schema / $defs / ReactionBalanceAdded value: +{ + "description": "Atom and charge balance of the equation as drawn (all coefficients 1).", + "properties": { + "balanced": { + "title": "Balanced", + "type": "boolean" + }, + "chargeDifference": { + "default": 0, + "title": "Chargedifference", + "type": "integer" + }, + "difference": { + "additionalProperties": { + "type": "integer" + }, + "default": {}, + "title": "Difference", + "type": "object" + }, + "formulas": { + "default": [], + "items": { + "type": "string" + }, + "title": "Formulas", + "type": "array" + }, + "note": { + "default": "", + "title": "Note", + "type": "string" + }, + "suggestedCoefficients": { + "anyOf": [ + { + "items": { + "type": "integer" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggestedcoefficients" + }, + "suggestedEquation": { + "default": "", + "title": "Suggestedequation", + "type": "string" + }, + "summary": { + "default": "", + "title": "Summary", + "type": "string" + } + }, + "required": [ + "balanced" + ], + "title": "ReactionBalance", + "type": "object" +} - added
Output schema / properties / arrowAdded value: +{ + "default": "forward", + "title": "Arrow", + "type": "string" +} - added
Output schema / properties / balanceAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/ReactionBalance" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / properties / coefficientsAdded value: +{ + "default": [], + "items": { + "type": "integer" + }, + "title": "Coefficients", + "type": "array" +} - added
Output schema / properties / conditions_belowAdded value: +{ + "default": "", + "title": "Conditions Below", + "type": "string" +} - added
Output schema / properties / requestAdded value: +{ + "additionalProperties": true, + "default": {}, + "title": "Request", + "type": "object" +}
- Changed
lookup_molecule_data9 fields changed- added
Output schema / $defs / DatabaseSource / properties / groupsAdded value: +{ + "default": [], + "items": { + "$ref": "#/$defs/GhsGroup" + }, + "title": "Groups", + "type": "array" +} - added
Output schema / $defs / DatabaseSource / properties / noteAdded value: +{ + "default": "", + "title": "Note", + "type": "string" +} - added
Output schema / $defs / DatabaseSource / properties / statusAdded value: +{ + "default": "", + "title": "Status", + "type": "string" +} - added
Output schema / $defs / GhsGroupAdded value: +{ + "description": "Die Einstufung EINER Quelle (PubChem ReferenceNumber).", + "properties": { + "hazards": { + "default": [], + "items": { + "$ref": "#/$defs/GhsHazard" + }, + "title": "Hazards", + "type": "array" + }, + "id": { + "title": "Id", + "type": "string" + }, + "lead": { + "default": false, + "title": "Lead", + "type": "boolean" + }, + "not_classified": { + "anyOf": [ + { + "$ref": "#/$defs/GhsNotClassified" + }, + { + "type": "null" + } + ], + "default": null + }, + "note": { + "default": "", + "title": "Note", + "type": "string" + }, + "p_codes": { + "default": [], + "items": { + "type": "string" + }, + "title": "P Codes", + "type": "array" + }, + "pictograms": { + "default": [], + "items": { + "type": "string" + }, + "title": "Pictograms", + "type": "array" + }, + "record_name": { + "default": "", + "title": "Record Name", + "type": "string" + }, + "reports_total": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reports Total" + }, + "signal": { + "default": "", + "title": "Signal", + "type": "string" + }, + "source": { + "title": "Source", + "type": "string" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + } + }, + "required": [ + "id", + "source" + ], + "title": "GhsGroup", + "type": "object" +} - added
Output schema / $defs / GhsHazardAdded value: +{ + "properties": { + "code": { + "title": "Code", + "type": "string" + }, + "percent": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Percent" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "required": [ + "code" + ], + "title": "GhsHazard", + "type": "object" +} - added
Output schema / $defs / GhsNotClassifiedAdded value: +{ + "description": "Eine Quelle meldet ausdruecklich \"erfuellt die GHS-Kriterien nicht\".", + "properties": { + "percent": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Percent" + }, + "reports": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reports" + }, + "total": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Total" + } + }, + "title": "GhsNotClassified", + "type": "object" +} - added
Output schema / $defs / StereoWarningAdded value: +{ + "description": "Ein Stereoelement, dessen Konfiguration die Eingabe offen lässt.", + "properties": { + "atoms": { + "default": [], + "items": { + "type": "integer" + }, + "title": "Atoms", + "type": "array" + }, + "kind": { + "title": "Kind", + "type": "string" + }, + "label": { + "default": "", + "title": "Label", + "type": "string" + } + }, + "required": [ + "kind" + ], + "title": "StereoWarning", + "type": "object" +} - added
Output schema / properties / stereoNoteAdded value: +{ + "default": "", + "title": "Stereonote", + "type": "string" +} - added
Output schema / properties / stereoWarningsAdded value: +{ + "default": [], + "items": { + "$ref": "#/$defs/StereoWarning" + }, + "title": "Stereowarnings", + "type": "array" +}
7 tool updates
v0.1.0- First observed
batch_generate - First observed
compare_molecules - First observed
export_anki_deck - First observed
generate_molecule - First observed
generate_reaction - First observed
lookup_molecule_data - First observed
save_png
TDQS
Scored across 7 tools
Each tool has a clearly distinct purpose, and the descriptions explicitly cross-reference when to use another tool (single vs. batch, compare vs. draw, reaction vs. molecule, data sheet vs. bare name). The only internal helper, save_png, is explicitly marked as never called directly, so it does not create ambiguity.
All names use snake_case and are mostly verb-first (generate_molecule, lookup_molecule_data, generate_reaction, compare_molecules, export_anki_deck, save_png). The only minor deviation is batch_generate, where the verb is not first, but the convention remains readable and predictable overall.
Seven tools is well within the appropriate range and each tool covers a distinct workflow: single drawing, batch drawing, reaction drawing, comparison, data lookup, Anki export, and an internal save helper. The set feels scoped rather than bloated or thin.
The surface covers the core chemical drawing lifecycle: single structures, batches, reactions, side-by-side comparison, external data lookup, and flashcard export. Minor gaps exist, such as no dedicated spectrum-generation tool despite spectra being supported in Anki card visuals, and no mechanism/electron-flow tool, though that appears intentionally out of scope.
Maintenance
Related MCP Connectors
Chemistry, pharma and biotech tools for AI assistants: NMR, MS, IR and UV analysis, ADMET and ICH M7, stability (ICH Q1), HPLC methods, DoE, docking, retrosynthesis, biologics. Deterministic results you can check. Built in Leipzig, Germany.
Turn any LLM into your lab assistant: search samples, track experiments, analyze data with AI.
Build study flashcards and exam-prep decks from your AI chat, all stored locally.
Free: turn your AI chats into spaced-repetition vocabulary. 13 tools, reads and writes.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables AI agents and applications to search, retrieve, and analyze chemical compounds, substances, and bioassays from PubChem's vast chemical information database through comprehensive tools for chemical research and discovery.101,804 npm10Apache 2.0

ChemMCPofficial
AlicenseNot gradedqualityCmaintenanceChemMCP is an easy-to-use and extensible chemistry toolkit for LLMs and AI assistants, enabling molecular analysis, property prediction, and reaction synthesis tasks without domain-specific training.74Apache 2.0- AlicenseCqualityDmaintenanceEnables chemical reaction predictions (retrosynthesis, product, reagents), molecule validation, and property calculation through the Model Context Protocol, integrating with AI assistants.5MIT
- AlicenseNot gradedqualityBmaintenanceProvides an MCP interface for publication-quality chemical structure and reaction rendering from SMILES/InChI/molblock, with validation and name parsing. Enables AI agents to draw molecules and reactions as images.MIT