phylokit-mcp
Summary: phylokit-mcp is an MCP server for core phylogenetics work: aligning sequences, choosing substitution models, inferring ML trees with bootstrap support, comparing topologies, simulating alignments, and mapping alignment positions.
align_sequences: Align unaligned DNA/protein FASTA with MAFFT, inline or to a new file; verifies gap-stripped output matches input.select_substitution_model: Rank 100+ nucleotide/protein models by AIC/AICc/BIC, showing Δ to runners-up and whether criteria agree.infer_tree: Build a maximum-likelihood tree with mandatory bootstrap support (nonparametric or UFBoot2), reporting per-clade support, conflicting clades, fraction resolved, likelihood, and alignment stats.compare_trees: Compute Robinson–Foulds distance and identify clades/splits that differ between two Newick trees.simulate_alignment: Simulate sequences along a specified tree, model, length, and seed as a positive control.map_positions: Map a residue to its alignment column and that column across sequences, optionally aligning with MAFFT first.capabilities: Report engine/IQ-TREE/MAFFT versions, supported models and criteria, limits, and support thresholds.Inputs can be FASTA/Newick text or file paths, and some tools accept file output for reuse.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@phylokit-mcpinfer tree for alignment 'my_sequences.fasta' with 200 bootstrap replicates"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
phylokit-mcp
phylokit-mcp is an MCP server that lets AI agents build maximum-likelihood trees with IQ-TREE 3 and align sequences with MAFFT.
A topology without support is not a result. infer_tree always runs a
bootstrap and returns per-clade support. There is no flag to skip it.
Why the rule
A maximum-likelihood tree looks the same whether or not the data support it. Measured on alignments simulated from a known 7-taxon tree (JC, 100 replicates, seed 1):
Sites | Informative sites | Recovered the true tree? | Lowest clade support |
300 | 51 | yes, exactly | 1.00 |
60 | 11 | no, RF 2 | 0.57 |
At 60 sites the tree contains a clade (C,D,G) that does not exist and omits
one that does (E,F,G). Both runs return a fully resolved Newick string of the
same shape. Only the support values tell them apart, and the false clade is the
lowest-supported one in the tree.
Related MCP server: STRING-db MCP Server
What it reports that a Newick string cannot
Conflicting clades: groupings the data support at ≥0.70 that are absent from the reported tree. A support-annotated Newick string has nowhere to put them.
fraction_resolved: the share of clades clearing 0.70. The headline number, before any single grouping is repeated as fact.Model runners-up with ΔAIC, not just a winner. On the 300-site alignment above, simulated under JC, the AIC winner is not JC (TPM2u and TPM2 tie), and several models, JC among them at ΔAIC 0.7, sit inside the conventional ±2 margin (
seed=1, piqtree 0.8.3).Length versus evidence:
n_parsimony_informativealongsiden_sites. A 10,000-site alignment of near-identical sequences supports nothing.
Tools
Tool | What it does |
| ML tree plus bootstrap support (nonparametric or UFBoot2), per clade. |
| Ranks 100+ models with ΔAIC/AICc/BIC, and says when the criteria disagree. |
| Robinson–Foulds distance and the clades that differ. Compares splits, not strings. |
| Generates sequences along a tree you specify: the positive control. |
| Aligns unaligned FASTA with MAFFT, inline or to a new file ( |
| Maps a residue to its alignment column, and that column to every other sequence. |
| piqtree and IQ-TREE versions, 215 substitution models, MAFFT version, limits. |
Tools that take FASTA or Newick also take a file path (fasta_path, or
trees_path for two trees), read by the server; a relative path resolves
against the server's working directory.
The tests run real IQ-TREE and real MAFFT (no mocked engine), with 23 mutation checks and a real-process JSON-RPC handshake test.
Install
pip install phylokit-mcpRequires Python 3.12+. IQ-TREE 3 comes through
piqtree 0.8, which builds it into its
wheel. align_sequences also needs the
MAFFT binary on PATH, as does
map_positions on unaligned input; the other tools work without it. Details: docs/INSTALL.md.
Configure your MCP client
{
"mcpServers": {
"phylokit": {
"command": "uvx",
"args": ["phylokit-mcp"]
}
}
}If uvx picks a Python older than 3.12, use
"args": ["--python", "3.12", "phylokit-mcp"].
What the benchmark shows
Claude with the server was compared with Claude writing Python in an environment we set up with piqtree, cogent3 and MAFFT, on 38 phylogenetics questions, 3 runs each. A tie means the server matches that result without you building the environment. Questions right in every run, server against Python: Claude Haiku 5.5 34 against 37, Sonnet 5.5 37 against 35, Opus 5.5 36 against 35 (on the commit that takes file paths). None is separated (pre-registered; Holm-adjusted McNemar p = 0.75 on both Haiku and Sonnet). The server cost about the same as Python on Haiku and more on Sonnet (1.23×) and Opus (1.26×).
The chart is the first Opus 5.5 run, on a release that took the data as text. Counting answers, the server got 110 of 114 right and Python 113; counting questions, 36 of 38 were right in every run against 37 (sign test p = 1). Per question the server took 6.0 times as long (95% CI 4.4 to 8.3) and cost 14.4 times as much (9.9 to 20.2), each a geometric mean of per-question ratios. Most of that cost was the model pasting the data file into tool calls; taking file paths (pre-registered re-run, 2026-10-18) brought it down to 1.26 times (1.04 to 1.55).
We wrote the questions and ran the benchmark ourselves; an outside re-run is welcome. The benchmark does not score support values; method, controls and other limitations are in benchmarks/agent_qa; the Haiku and Sonnet runs: 2026-10-20 re-run.
Reproducibility
Not bit-exact, in any setting: IQ-TREE reads the wall clock during its search,
so the same request and seed can differ in the trailing digits of branch
lengths and log-likelihood, and a support value can move by a replicate
flipping. The server reports deterministic_across_processes: false. Compare
trees with compare_trees and numbers with a tolerance, never by string
equality. Measurements: docs/REPRODUCIBILITY.md.
Limitations
Nucleotide and protein, no codon models. Pass
sequence_type="protein"and a protein model (LG,WAG, …). The molecule type is declared, never sniffed: an A/C/G/T-only alignment is also valid protein (Ala/Cys/Gly/Thr), and a wrong guess returns a wrong tree, likelihood and support with no warning.Two bootstraps, no aLRT or approximate Bayes. The default is the nonparametric bootstrap (Felsenstein 1985), computed here, clades supported at 0.70; it is the only one that reports well-supported clades missing from the ML tree.
support_method="ufboot"is IQ-TREE's UFBoot2 (Hoang et al. 2018), clades supported at 0.95.Nonparametric cost is linear in replicates, each a full ML search: on 89 taxa x 435 sites one replicate took 25-93 s, and 1000 UFBoot2 replicates 83 s. Capped at 200 taxa, 1000 nonparametric and 10000 UFBoot2 replicates. Every tool sends a progress notification every 15 s, so a client idle timeout does not abort a long call.
Alignment is MAFFT
--auto, single-threaded, and nothing else: no strategy choice, profile alignment or trimming; at most 200 sequences of 100,000 residues and 600 s. Gapped input is refused, not degapped. The tree tools refuse ragged input rather than align it.Unrooted trees. No rooting, dating or ancestral reconstruction.
License
GPL-2.0-only, because piqtree is GPL-2.0-only, which is incompatible
with GPL-3.0. cogent3 is BSD.
If you publish results from this server, cite IQ-TREE 3, piqtree and (when it made the alignment) MAFFT, not this wrapper. The references are in CITATION.cff, and licensing and affiliation are in NOTICE.
Available Tools
7 toolsalign_sequencesAlign sequences with MAFFT, ready for infer_treeA
Align unaligned sequences with MAFFT, ready for infer_tree.
The returned fasta has every row the same length and can be passed to
infer_tree or select_substitution_model unchanged. Each output row, with
its gaps removed, is verified to equal the input sequence before it is
returned.
Args:
fasta: UNALIGNED sequences in FASTA, 2-200 of them. Gap characters are
refused: input that is already aligned does not need this tool.
sequence_type: "dna" (default) or "protein". Declared, never sniffed,
and passed to MAFFT explicitly so it does not guess either.
fasta_path: Path of a FASTA file to read instead of fasta.
out_path: Write the aligned FASTA to this NEW file (never overwritten;
its directory must exist) instead of returning it: fasta comes
back None and written_to holds the absolute path, which
infer_tree, select_substitution_model and map_positions take
as fasta_path. Use it rather than copying rows between calls.
| Name | Required | Description | Default |
|---|---|---|---|
| fasta | No | ||
| out_path | No | ||
| fasta_path | No | ||
| sequence_type | No | dna |
Output Schema
| Name | Required | Description |
|---|---|---|
| fasta | Yes | |
| engine | Yes | |
| warnings | Yes | |
| alignment | Yes | |
| written_to | Yes | |
| input_lengths | Yes | |
| sequence_type | Yes | |
| ready_for_infer_tree | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations mark this readOnly=false and idempotent=false, and the description supplies exactly the context the annotations cannot: every output row is verified gap-stripped against the input, out_path is never overwritten and its directory must pre-exist, and fasta returns None with written_to holding the absolute path. That is substantive behavioral disclosure for a write-capable 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 one-sentence purpose and return contract before the Args block, and every sentence carries information. Slightly dense in the out_path sentence, where a clause about which tools accept written_to as fasta_path could be tightened, but there is no filler.
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?
A 4-parameter mutation tool with an output schema, and the description still tells the agent everything needed: input constraints, sequence-type handling, the return-shape switch on out_path, and how downstream tools consume either form. Nothing an agent needs in order to call it correctly is missing.
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 carry all four parameters – and it does: fasta (2-200 unaligned sequences, gaps refused), sequence_type (dna/protein, declared never sniffed, passed to MAFFT explicitly), fasta_path (file alternative to fasta), and out_path (new file, directory must exist, changes return shape). This far exceeds the schema's bare titles and defaults.
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 (align unaligned sequences with MAFFT) plus the downstream purpose (ready for infer_tree). It names the exact siblings that consume the output (infer_tree, select_substitution_model, map_positions), so an agent can place it in the workflow without opening other schemas.
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 says input must be UNALIGNED and that gap characters are refused because already-aligned input 'does not need this tool' – a clear when-not condition. It also directs the agent to prefer out_path rather than shuffling rows between calls, which is prescriptive routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
capabilitiesEngine capabilities and limitsARead-onlyIdempotent
What this server can do, and the bounds it enforces.
engine_version is the installed piqtree version (e.g. "0.8.3");
iqtree_version is the IQ-TREE build inside it (e.g. "3.1.2").
Args: include_models: Include the full substitution-model list (long).
| Name | Required | Description | Default |
|---|---|---|---|
| include_models | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| engine | Yes | |
| limits | Yes | |
| criteria | Yes | |
| aligner_error | Yes | |
| engine_version | Yes | |
| iqtree_version | Yes | |
| threads_pinned | Yes | |
| aligner_version | Yes | |
| support_thresholds | Yes | |
| substitution_models | No | |
| n_substitution_models | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, and the description adds useful context about the version fields and the behavior of include_models. It also mentions enforced bounds, which goes beyond the structured annotations without contradicting them.
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 short, front-loaded with the tool's purpose, and each line serves a clear function. The 'Args:' header is slightly redundant with the schema, but there is no wasted prose.
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 tool's simplicity, the existing output schema, and the annotations, the description is complete enough for correct invocation. It covers the version fields and the one behavioral toggle without needing to restate return formats.
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 for the single parameter. The line about include_models adds real meaning by clarifying that it controls whether the full substitution-model list is included and warns that the output is long.
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 clearly conveys that the tool reports what the server can do and the limits it enforces, which distinguishes it from the phylogenetic analysis siblings. It lacks an explicit operative verb like 'returns' or 'lists', but the intent is unambiguous.
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 description implies this is an introspection capability for discovering server capabilities and limits, but it never explicitly says when to call it versus alternatives. It offers no direct 'use this when' guidance or comparison to sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compare_treesCompare two tree topologiesARead-onlyIdempotent
Robinson-Foulds distance between two trees, and which clades differ.
Compares SPLITS, not strings: the same topology has many valid Newick representations, so string equality answers a different question.
Args: newick_a: First tree in Newick format. newick_b: Second tree in Newick format. trees_path: Instead of the two strings, the path of a file holding exactly two Newick trees, A then B.
| Name | Required | Description | Default |
|---|---|---|---|
| newick_a | No | ||
| newick_b | No | ||
| trees_path | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| warnings | Yes | |
| only_in_a | Yes | |
| only_in_b | Yes | |
| shared_taxa | Yes | |
| n_shared_clades | Yes | |
| robinson_foulds | Yes | |
| identical_topology | Yes | |
| normalised_robinson_foulds | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent and closed-world behavior, and the description adds useful substance: the metric used, that equivalent topologies have many valid Newick strings, and that clade differences are part of the result. However, with all three parameters optional and defaulting to null, it never says what happens if neither the two strings nor a path are supplied, nor how malformed Newick is handled.
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 key semantic point — splits, not strings — is front-loaded before the argument list. The Args block is compact and each entry adds information rather than restating the parameter name.
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 return values need no explanation, and the mutually exclusive input modes are spelled out. The remaining gap is the all-optional parameter set: an agent cannot tell from the description what constitutes a valid call (pair of strings vs path) or what happens when everything is null.
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 coverage is 0%, so the description has to carry all parameter meaning, and it does name and explain all three. 'trees_path' gets the strongest treatment, specifying that the file must hold exactly two Newick trees, A then B, which is meaning nothing in the schema conveys. The two Newick string args are defined only as 'First/Second tree', leaving the pairing A-to-B implied rather than stated.
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 metric (Robinson-Foulds distance) applied to a specific resource (two trees), plus the secondary output (which clades differ). The clarification that it compares SPLITS rather than strings sharpens the purpose beyond the title and clearly separates it from the alignment/model siblings.
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 warns that string equality 'answers a different question', which is a genuine when-to-use signal, and frames the two input modes as mutually exclusive ('Instead of the two strings...'). It stops short of naming any sibling tool or stating when a different comparison approach would be preferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
infer_treeInfer a phylogenetic tree with bootstrap supportARead-onlyIdempotent
Build a maximum-likelihood tree and measure how well the data support it.
Always bootstraps. There is deliberately no option to skip it: an
unsupported topology is the failure mode this server exists to prevent.
support_method picks which bootstrap; see its entry for the cost.
Args:
fasta: Aligned sequences in FASTA, nucleotide or protein as declared by
sequence_type. All sequences must be the same length — run
align_sequences first if they are not.
model: Substitution model, e.g. "JC", "HKY", "GTR+G" (or "LG+G" for
protein). Run select_substitution_model first if you do not have a
reason to prefer one.
replicates: Bootstrap replicates. Nonparametric: 20-1000, default 100,
and each one costs a full ML search, so the call takes about
replicates x one search. UFBoot2: 1000-10000, default 1000.
seed: 0 to 2**31-1. Fixes the column resampling exactly; the engine's
search is seeded too but is not bit-exact (see reproducibility).
sequence_type: "dna" (default) or "protein". DECLARED, never sniffed: an
alignment of only A/C/G/T is a valid protein alignment too, so
guessing would silently fit a nucleotide model to protein data. A
protein alignment also needs a protein model — "LG+G" or "WAG",
not the nucleotide default — so run select_substitution_model with
the same sequence_type first.
fasta_path: Path of a FASTA file to read instead of fasta.
support_method: "bootstrap" (default): the nonparametric bootstrap,
clades supported at 0.70, and the only method that reports
well-supported clades the ML tree lacks (conflicting_support).
"ufboot": IQ-TREE's ultrafast bootstrap (UFBoot2, Hoang et al.
2018), clades supported at 0.95; far faster, use it when the
nonparametric cost (replicates x one ML search) is too high, e.g.
more than a few dozen taxa.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | ||
| fasta | No | ||
| model | No | GTR+G | |
| fasta_path | No | ||
| replicates | No | ||
| sequence_type | No | dna | |
| support_method | No | bootstrap |
Output Schema
| Name | Required | Description |
|---|---|---|
| model | Yes | |
| engine | Yes | |
| newick | Yes | |
| support | Yes | |
| warnings | Yes | |
| alignment | Yes | |
| log_likelihood | Yes | |
| newick_topology | Yes | |
| reproducibility | Yes | |
| newick_supported | Yes | |
| branch_length_units | Yes | |
| newick_with_support | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/openWorld/idempotent annotations, the description discloses the mandatory bootstrap policy, cost scaling for replicates, support thresholds for each method, seed caveats, and the risk of silently fitting a nucleotide model to protein data. These are substantive behavioral details not available in the annotations.
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 long but appropriately sized for a seven-parameter tool with no schema descriptions. The core purpose and mandatory-bootstrap behavior are front-loaded, followed by a tightly structured parameter list where each entry carries useful context.
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 high complexity, zero schema description coverage, and the presence of an output schema, the description covers everything needed to call the tool correctly: prerequisites, parameter meanings, cost tradeoffs, and model/sequence-type constraints.
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 fully, and it does: all seven parameters are explained with formats, defaults, valid ranges, method-dependent replicate costs, and operational caveats. It also clarifies sequence_type is declared rather than inferred and that protein data requires a protein model.
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 verb and resource: build a maximum-likelihood tree and measure bootstrap support. It distinguishes the tool from alignment, model selection, and tree comparison by naming their roles as prerequisites or alternatives.
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 explicitly routes the agent: run align_sequences first if sequences are not aligned, run select_substitution_model first when no model is preferred, and use ufboot when nonparametric bootstrap cost is too high. It also explains that bootstrap cannot be skipped.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
map_positionsMap a residue to its alignment column and across sequencesARead-onlyIdempotent
Map a residue to its alignment column, and the column to every sequence.
Answers "which residue of B is in the same column as residue N of A" without
counting by hand. Positions count residues from 1, gaps not counted; columns
count from 1. At a gap, a row's position is null and between gives the
residues either side.
Args:
aligned: true if the input is an alignment; false if unaligned, and it
is aligned with MAFFT first, as align_sequences would.
sequence: The sequence whose residue position is meant.
position: A residue position in sequence. Give this or column.
column: An alignment column. Give this or position.
fasta: The sequences in FASTA.
fasta_path: Path of a FASTA file to read instead of fasta.
sequence_type: "dna" (default) or "protein".
| Name | Required | Description | Default |
|---|---|---|---|
| fasta | No | ||
| column | No | ||
| aligned | Yes | ||
| position | No | ||
| sequence | No | ||
| fasta_path | No | ||
| sequence_type | No | dna |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | Yes | |
| query | Yes | |
| column | Yes | |
| window | Yes | |
| warnings | Yes | |
| n_columns | Yes | |
| aligned_by | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotentHint/openWorldHint=false, so safety is covered; the description adds genuinely new behavioral facts beyond them — 1-based residue counting, gaps excluded from position counts, null positions at gapped rows with `between` supplying flanking residues, and the hidden MAFFT alignment step for unaligned input. It stops short of warning about the cost/nondeterminism of that implicit alignment or what happens on invalid positions.
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 core behavior and the clarifying question are front-loaded, and the args block is compact with one line per parameter. The `aligned` entry carries slightly more prose than the rest, but no sentence is filler.
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 return values need not be fully spelled out, and all seven parameters plus the aligned/unaligned branch are covered. Remaining gaps are edge-case handling: what happens if both or neither of `position`/`column` are supplied, and how `sequence` is matched against `fasta`.
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?
With schema description coverage at 0%, the description must carry all seven parameters, and it does — each of aligned, sequence, position, column, fasta, fasta_path, and sequence_type gets a one-line explanation including the dna default. The weak spot is `sequence`, described only as "the sequence whose residue `position` is meant," leaving unclear whether it is an identifier/name key into `fasta` or the sequence text itself.
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 line states a precise verb and two-directional resource: residue -> alignment column, and column -> every sequence. The concrete question it answers ("which residue of B is in the same column as residue N of A") removes any ambiguity about what output to expect, and it is clearly distinct from alignment-building siblings like align_sequences.
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 description states both invocation modes explicitly ("Give this or `column`") and explains the branch on `aligned`: true means the input is already an alignment, false means it is aligned with MAFFT first. It does not, however, name a case where an agent should skip this tool entirely or point to a specific better alternative beyond the parenthetical reference to `align_sequences`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
select_substitution_modelRank substitution models, with the margin over the runners-upARead-onlyIdempotent
Compare substitution models and report how much the winner won by.
A single model name reads as a finding. The ranking, the delta to the next model, and whether AIC/AICc/BIC agree are what make it one.
Args:
fasta: Aligned sequences in FASTA, nucleotide or protein as declared by
sequence_type.
criterion: "AIC", "AICc" or "BIC". BIC penalises parameters more heavily.
seed: Fixes the engine's search.
top_n: How many ranked models to return.
sequence_type: "dna" (default) or "protein". Ranks within that molecule
type's model set — nucleotide and protein models are not comparable.
fasta_path: Path of a FASTA file to read instead of fasta.
models: Rank only these models (IQ-TREE names, e.g. ["JC", "K2P",
"F81+F", "HKY+F"]), all returned. Bare "F81"/"HKY" have equal base
frequencies in IQ-TREE; JC69, K80 and HKY85 are accepted.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | ||
| fasta | No | ||
| top_n | No | ||
| models | No | ||
| criterion | No | AIC | |
| fasta_path | No | ||
| sequence_type | No | dna |
Output Schema
| Name | Required | Description |
|---|---|---|
| seed | Yes | |
| ranking | Yes | |
| warnings | Yes | |
| alignment | Yes | |
| criterion | Yes | |
| best_model | Yes | |
| restricted_to | No | |
| criteria_agree | Yes | |
| resolved_names | No | |
| best_by_criterion | Yes | |
| n_models_compared | Yes | |
| indistinguishable_from_best | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and closed-world behavior, so the description is not carrying the safety burden. It adds substantial domain behavior: nucleotide and protein model sets are not comparable, BIC penalizes parameters more heavily, bare 'F81'/'HKY' have equal base frequencies in IQ-TREE, and aliases like JC69/K80/HKY85 are accepted. This is meaningful context beyond the structured fields.
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 front-loaded with the core purpose, then explains why the ranking matters, then lists arguments cleanly. It is appropriately sized for a seven-parameter tool, though the middle rationale sentence is slightly editorial rather than strictly operational.
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 seven parameters, no schema descriptions, and an output schema already present, the description is nearly complete: it covers every parameter and the main semantic caveats around model comparability and naming. It does not address edge cases such as what happens when neither fasta nor fasta_path is supplied, which keeps it from a 5.
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 carry parameter meaning entirely, and it does. It documents all seven parameters, including criterion choices and their trade-off, seed's role in fixing the engine search, sequence_type's default and model-set implications, and detailed IQ-TREE naming/alias rules for models.
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 states a specific verb and resource: 'Compare substitution models and report how much the winner won by.' It also explains the ranking/delta/agreement output, making the tool's role concrete. It does not explicitly distinguish itself from siblings such as infer_tree, so it stops short of a 5.
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 description implies when to use it by contrasting a single model name with a full ranking ('A single model name reads as a finding...'), so the usage context is inferable. However, it gives no explicit when-not-to-use guidance and never names an alternative tool, leaving routing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
simulate_alignmentSimulate an alignment from a known treeARead-onlyIdempotent
Generate sequences along a tree you specify, so the true answer is known.
This is the positive control for everything else here: infer a tree from the
output and compare it back with compare_trees. If inference cannot recover
a topology you generated from, the problem is the data or the settings, not
the biology.
Args:
newick: The true tree, with a branch length on every edge.
model: Substitution model to simulate under. A protein model ("LG",
"WAG", ...) simulates protein; pass the output to infer_tree with
sequence_type="protein". alignment.moltype says which it is.
length: Number of sites.
seed: Fixes the simulation.
| Name | Required | Description | Default |
|---|---|---|---|
| seed | No | ||
| model | No | JC | |
| length | No | ||
| newick | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| seed | Yes | |
| fasta | Yes | |
| model | Yes | |
| warnings | Yes | |
| alignment | Yes | |
| true_newick | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only and idempotent behavior. The description adds useful context beyond that: the output has a known true tree, the seed fixes the simulation, protein models produce sequences whose moltype is recorded, and every newick edge needs a branch length. There is no contradiction with annotations.
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 front-loaded with the core purpose, then gives the practical workflow context, then compactly documents each parameter. There is no filler or repetition of schema defaults; every sentence contributes.
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 simulation tool with an output schema and safety annotations already provided, the description covers the essential usage loop, parameter semantics, and expected result semantics. Nothing an agent needs to call it correctly or interpret its output is missing.
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 carries the full burden, and it succeeds. It explains newick (true tree with branch lengths), model (substitution model and moltype implication), length (number of sites), and seed (fixes simulation) in plain terms that add meaning beyond the raw schema.
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 verb and resource: 'Generate sequences along a tree you specify, so the true answer is known.' It also orients the tool as the 'positive control for everything else here,' distinguishing it clearly from inference and comparison siblings like infer_tree and compare_trees.
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 description gives clear context for when to use the tool: as a positive control for validating inference workflows. It names the follow-up steps (infer_tree, compare_trees) and explains how to interpret failure, but it does not explicitly state when not to use it or name an alternative simulation approach.
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.
2 tool updates
v0.8.0- Changed
align_sequences5 fields changed- added
Input schema / properties / out_pathAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Out Path" +} - added
Output schema / properties / fasta / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Output schema / properties / fasta / typeRemoved value: -"string" - added
Output schema / properties / written_toAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Written To" +} - changed
Output schema / requiredPrevious value: -[ - "fasta", - "alignment", - "sequence_type", - "input_lengths", - "engine", - "ready_for_infer_tree", - "warnings" -]New value: +[ + "fasta", + "written_to", + "alignment", + "sequence_type", + "input_lengths", + "engine", + "ready_for_infer_tree", + "warnings" +]
- Changed
infer_tree7 fields changed- added
Input schema / properties / replicates / anyOfAdded value: +[ + { + "type": "integer" + }, + { + "type": "null" + } +] - changed
Input schema / properties / replicates / defaultPrevious value: -100New value: +null - removed
Input schema / properties / replicates / typeRemoved value: -"integer" - added
Input schema / properties / support_methodAdded value: +{ + "default": "bootstrap", + "enum": [ + "bootstrap", + "ufboot" + ], + "title": "Support Method", + "type": "string" +} - added
Output schema / properties / newick_supportedAdded value: +{ + "title": "Newick Supported", + "type": "string" +} - added
Output schema / properties / newick_topologyAdded value: +{ + "title": "Newick Topology", + "type": "string" +} - changed
Output schema / requiredPrevious value: -[ - "newick", - "newick_with_support", - "model", - "log_likelihood", - "alignment", - "support", - "reproducibility", - "engine", - "branch_length_units", - "warnings" -]New value: +[ + "newick", + "newick_with_support", + "newick_supported", + "newick_topology", + "model", + "log_likelihood", + "alignment", + "support", + "reproducibility", + "engine", + "branch_length_units", + "warnings" +]
5 tool updates
v0.7.0- Changed
align_sequences5 fields changed- added
Input schema / properties / fasta / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - added
Input schema / properties / fasta / defaultAdded value: +null - removed
Input schema / properties / fasta / typeRemoved value: -"string" - added
Input schema / properties / fasta_pathAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Fasta Path" +} - removed
Input schema / requiredRemoved value: -[ - "fasta" -]
- Changed
compare_trees8 fields changed- added
Input schema / properties / newick_a / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - added
Input schema / properties / newick_a / defaultAdded value: +null - removed
Input schema / properties / newick_a / typeRemoved value: -"string" - added
Input schema / properties / newick_b / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - added
Input schema / properties / newick_b / defaultAdded value: +null - removed
Input schema / properties / newick_b / typeRemoved value: -"string" - added
Input schema / properties / trees_pathAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Trees Path" +} - removed
Input schema / requiredRemoved value: -[ - "newick_a", - "newick_b" -]
- Changed
infer_tree5 fields changed- added
Input schema / properties / fasta / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - added
Input schema / properties / fasta / defaultAdded value: +null - removed
Input schema / properties / fasta / typeRemoved value: -"string" - added
Input schema / properties / fasta_pathAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Fasta Path" +} - removed
Input schema / requiredRemoved value: -[ - "fasta" -]
- Added
map_positions - Changed
select_substitution_model8 fields changed- added
Input schema / properties / fasta / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - added
Input schema / properties / fasta / defaultAdded value: +null - removed
Input schema / properties / fasta / typeRemoved value: -"string" - added
Input schema / properties / fasta_pathAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Fasta Path" +} - added
Input schema / properties / modelsAdded value: +{ + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Models" +} - removed
Input schema / requiredRemoved value: -[ - "fasta" -] - added
Output schema / properties / resolved_namesAdded value: +{ + "additionalProperties": { + "type": "string" + }, + "title": "Resolved Names", + "type": "object" +} - added
Output schema / properties / restricted_toAdded value: +{ + "items": { + "type": "string" + }, + "title": "Restricted To", + "type": "array" +}
1 tool update
v0.6.0- Changed
capabilities2 fields changed- added
Output schema / properties / iqtree_versionAdded value: +{ + "title": "Iqtree Version", + "type": "string" +} - changed
Output schema / requiredPrevious value: -[ - "engine", - "engine_version", - "n_substitution_models", - "criteria", - "aligner_version", - "aligner_error", - "limits", - "support_thresholds", - "threads_pinned" -]New value: +[ + "engine", + "engine_version", + "iqtree_version", + "n_substitution_models", + "criteria", + "aligner_version", + "aligner_error", + "limits", + "support_thresholds", + "threads_pinned" +]
2 tool updates
v0.5.0- Added
align_sequences - Changed
capabilities4 fields changed- added
Output schema / properties / aligner_errorAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Aligner Error" +} - added
Output schema / properties / aligner_versionAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Aligner Version" +} - removed
Output schema / properties / substitution_models / defaultRemoved value: -null - changed
Output schema / requiredPrevious value: -[ - "engine", - "engine_version", - "n_substitution_models", - "criteria", - "limits", - "support_thresholds", - "threads_pinned" -]New value: +[ + "engine", + "engine_version", + "n_substitution_models", + "criteria", + "aligner_version", + "aligner_error", + "limits", + "support_thresholds", + "threads_pinned" +]
2 tool updates
v0.3.0- Changed
infer_tree4 fields changed- added
Input schema / properties / sequence_typeAdded value: +{ + "default": "dna", + "title": "Sequence Type", + "type": "string" +} - added
Output schema / properties / branch_length_unitsAdded value: +{ + "title": "Branch Length Units", + "type": "string" +} - added
Output schema / properties / engineAdded value: +{ + "additionalProperties": true, + "title": "Engine", + "type": "object" +} - changed
Output schema / requiredPrevious value: -[ - "newick", - "newick_with_support", - "model", - "log_likelihood", - "alignment", - "support", - "reproducibility", - "warnings" -]New value: +[ + "newick", + "newick_with_support", + "model", + "log_likelihood", + "alignment", + "support", + "reproducibility", + "engine", + "branch_length_units", + "warnings" +]
- Changed
select_substitution_model1 field changed- added
Input schema / properties / sequence_typeAdded value: +{ + "default": "dna", + "title": "Sequence Type", + "type": "string" +}
5 tool updates
v0.1.0- First observed
capabilities - First observed
compare_trees - First observed
infer_tree - First observed
select_substitution_model - First observed
simulate_alignment
TDQS
Scored across 7 tools
Each tool targets a distinct step in a phylogenetics workflow: alignment, model selection, tree inference, tree comparison, simulation, position mapping, and capability discovery. The only slight overlap is that map_positions can align unaligned input internally, but its purpose is clearly mapping rather than alignment.
Six of seven names follow a clear verb_noun snake_case pattern: align_sequences, compare_trees, infer_tree, map_positions, select_substitution_model, simulate_alignment. The lone exception, capabilities, is a reasonable utility name but breaks the otherwise consistent convention.
Seven tools is well scoped for a phylogenetics server, covering a complete core workflow without excessive surface area. Each tool earns its place and there is no obvious padding.
The surface covers the main lifecycle: align, select model, infer tree, compare trees, simulate, and map positions. Minor gaps exist, such as no dedicated tree summarization/manipulation or alignment trimming tool, but agents can work around these for core workflows.
Maintenance
Related MCP Connectors
Validated molecular biology tools: cloning, primers, CRISPR, Sanger, alignment, qPCR, phylogenetics
Hosted DNA language models: promoter, splice, enhancer, chromatin, expression, annotation
Protein analysis: ESM-2/ESMC embeddings, mutation scoring, landscape scans, ESMFold structure.
MCP gateway federating 22 biomedical MCP servers behind one endpoint: gnomAD, ClinVar, HPO, VEP.
Related MCP Servers
- AlicenseBqualityDmaintenanceA comprehensive Model Context Protocol (MCP) server that provides access to the AlphaFold Protein Structure Database through a rich set of tools and resources for protein structure prediction analysis.1937MIT
- AlicenseBqualityDmaintenanceA comprehensive Model Context Protocol (MCP) server for accessing the STRING protein interaction database. This server provides powerful tools for protein network analysis, functional enrichment, and comparative genomics through the STRING API.64MIT
- AlicenseAqualityDmaintenanceEnables the generation, mutation, and evolution of DNA and protein sequences using various evolutionary models and phylogenetic algorithms. It supports realistic next-generation sequencing read simulation and population-level evolutionary tracking for bioinformatics research and testing.6BSD 2-Clause "Simplified"
- AlicenseAqualityDmaintenanceMCP server for single-cell lineage tracing analysis, enabling conversational reconstruction, visualization, and heritability analysis of lineage trees using Cassiopeia, pycea, and treedata.18MIT