Skip to main content
Glama
phylokit-mcp
by musharna

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.

CI PyPI Python License DOI Glama

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_informative alongside n_sites. A 10,000-site alignment of near-identical sequences supports nothing.

Tools

Tool

What it does

infer_tree

ML tree plus bootstrap support (nonparametric or UFBoot2), per clade.

select_substitution_model

Ranks 100+ models with ΔAIC/AICc/BIC, and says when the criteria disagree.

compare_trees

Robinson–Foulds distance and the clades that differ. Compares splits, not strings.

simulate_alignment

Generates sequences along a tree you specify: the positive control.

align_sequences

Aligns unaligned FASTA with MAFFT, inline or to a new file (out_path).

map_positions

Maps a residue to its alignment column, and that column to every other sequence.

capabilities

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-mcp

Requires 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 tools
align_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.

NameRequiredDescriptionDefault
fastaNo
out_pathNo
fasta_pathNo
sequence_typeNodna

Output Schema

NameRequiredDescription
fastaYes
engineYes
warningsYes
alignmentYes
written_toYes
input_lengthsYes
sequence_typeYes
ready_for_infer_treeYes

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 limitsA
Read-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).

NameRequiredDescriptionDefault
include_modelsNo

Output Schema

NameRequiredDescription
engineYes
limitsYes
criteriaYes
aligner_errorYes
engine_versionYes
iqtree_versionYes
threads_pinnedYes
aligner_versionYes
support_thresholdsYes
substitution_modelsNo
n_substitution_modelsYes

TDQS

A3.9/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 topologiesA
Read-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.

NameRequiredDescriptionDefault
newick_aNo
newick_bNo
trees_pathNo

Output Schema

NameRequiredDescription
warningsYes
only_in_aYes
only_in_bYes
shared_taxaYes
n_shared_cladesYes
robinson_fouldsYes
identical_topologyYes
normalised_robinson_fouldsYes

TDQS

A4.2/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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 supportA
Read-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.

NameRequiredDescriptionDefault
seedNo
fastaNo
modelNoGTR+G
fasta_pathNo
replicatesNo
sequence_typeNodna
support_methodNobootstrap

Output Schema

NameRequiredDescription
modelYes
engineYes
newickYes
supportYes
warningsYes
alignmentYes
log_likelihoodYes
newick_topologyYes
reproducibilityYes
newick_supportedYes
branch_length_unitsYes
newick_with_supportYes

TDQS

A5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 sequencesA
Read-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".

NameRequiredDescriptionDefault
fastaNo
columnNo
alignedYes
positionNo
sequenceNo
fasta_pathNo
sequence_typeNodna

Output Schema

NameRequiredDescription
rowsYes
queryYes
columnYes
windowYes
warningsYes
n_columnsYes
aligned_byYes

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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-upA
Read-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.

NameRequiredDescriptionDefault
seedNo
fastaNo
top_nNo
modelsNo
criterionNoAIC
fasta_pathNo
sequence_typeNodna

Output Schema

NameRequiredDescription
seedYes
rankingYes
warningsYes
alignmentYes
criterionYes
best_modelYes
restricted_toNo
criteria_agreeYes
resolved_namesNo
best_by_criterionYes
n_models_comparedYes
indistinguishable_from_bestYes

TDQS

A4/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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 treeA
Read-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.

NameRequiredDescriptionDefault
seedNo
modelNoJC
lengthNo
newickYes

Output Schema

NameRequiredDescription
seedYes
fastaYes
modelYes
warningsYes
alignmentYes
true_newickYes

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

  1. 2 tool updatesv0.8.0
    • Changedalign_sequences5 fields changed
      • addedInput schema / properties / out_path
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Out Path"
        +}
      • addedOutput schema / properties / fasta / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedOutput schema / properties / fasta / type
        Removed value: -"string"
      • addedOutput schema / properties / written_to
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "title": "Written To"
        +}
      • changedOutput schema / required
        Previous 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"
        +]
    • Changedinfer_tree7 fields changed
      • addedInput schema / properties / replicates / anyOf
        Added value: +[
        +  {
        +    "type": "integer"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / replicates / default
        Previous value: -100New value: +null
      • removedInput schema / properties / replicates / type
        Removed value: -"integer"
      • addedInput schema / properties / support_method
        Added value: +{
        +  "default": "bootstrap",
        +  "enum": [
        +    "bootstrap",
        +    "ufboot"
        +  ],
        +  "title": "Support Method",
        +  "type": "string"
        +}
      • addedOutput schema / properties / newick_supported
        Added value: +{
        +  "title": "Newick Supported",
        +  "type": "string"
        +}
      • addedOutput schema / properties / newick_topology
        Added value: +{
        +  "title": "Newick Topology",
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous 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"
        +]
  2. 5 tool updatesv0.7.0
    • Changedalign_sequences5 fields changed
      • addedInput schema / properties / fasta / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / fasta / default
        Added value: +null
      • removedInput schema / properties / fasta / type
        Removed value: -"string"
      • addedInput schema / properties / fasta_path
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Fasta Path"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "fasta"
        -]
    • Changedcompare_trees8 fields changed
      • addedInput schema / properties / newick_a / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / newick_a / default
        Added value: +null
      • removedInput schema / properties / newick_a / type
        Removed value: -"string"
      • addedInput schema / properties / newick_b / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / newick_b / default
        Added value: +null
      • removedInput schema / properties / newick_b / type
        Removed value: -"string"
      • addedInput schema / properties / trees_path
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Trees Path"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "newick_a",
        -  "newick_b"
        -]
    • Changedinfer_tree5 fields changed
      • addedInput schema / properties / fasta / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / fasta / default
        Added value: +null
      • removedInput schema / properties / fasta / type
        Removed value: -"string"
      • addedInput schema / properties / fasta_path
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Fasta Path"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "fasta"
        -]
    • Addedmap_positions
    • Changedselect_substitution_model8 fields changed
      • addedInput schema / properties / fasta / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / fasta / default
        Added value: +null
      • removedInput schema / properties / fasta / type
        Removed value: -"string"
      • addedInput schema / properties / fasta_path
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Fasta Path"
        +}
      • addedInput schema / properties / models
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Models"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "fasta"
        -]
      • addedOutput schema / properties / resolved_names
        Added value: +{
        +  "additionalProperties": {
        +    "type": "string"
        +  },
        +  "title": "Resolved Names",
        +  "type": "object"
        +}
      • addedOutput schema / properties / restricted_to
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "title": "Restricted To",
        +  "type": "array"
        +}
  3. 1 tool updatev0.6.0
    • Changedcapabilities2 fields changed
      • addedOutput schema / properties / iqtree_version
        Added value: +{
        +  "title": "Iqtree Version",
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous 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"
        +]
  4. 2 tool updatesv0.5.0
    • Addedalign_sequences
    • Changedcapabilities4 fields changed
      • addedOutput schema / properties / aligner_error
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "title": "Aligner Error"
        +}
      • addedOutput schema / properties / aligner_version
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "title": "Aligner Version"
        +}
      • removedOutput schema / properties / substitution_models / default
        Removed value: -null
      • changedOutput schema / required
        Previous 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"
        +]
  5. 2 tool updatesv0.3.0
    • Changedinfer_tree4 fields changed
      • addedInput schema / properties / sequence_type
        Added value: +{
        +  "default": "dna",
        +  "title": "Sequence Type",
        +  "type": "string"
        +}
      • addedOutput schema / properties / branch_length_units
        Added value: +{
        +  "title": "Branch Length Units",
        +  "type": "string"
        +}
      • addedOutput schema / properties / engine
        Added value: +{
        +  "additionalProperties": true,
        +  "title": "Engine",
        +  "type": "object"
        +}
      • changedOutput schema / required
        Previous 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"
        +]
    • Changedselect_substitution_model1 field changed
      • addedInput schema / properties / sequence_type
        Added value: +{
        +  "default": "dna",
        +  "title": "Sequence Type",
        +  "type": "string"
        +}
  6. 5 tool updatesv0.1.0
    • First observedcapabilities
    • First observedcompare_trees
    • First observedinfer_tree
    • First observedselect_substitution_model
    • First observedsimulate_alignment

TDQS

A4.3/5.0

Scored across 7 tools

Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count5/5

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.

Completeness4/5

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

ActivityActive
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    A 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.
    6
    4
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables 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.
    6
    BSD 2-Clause "Simplified"