Skip to main content

phylokit-mcp

ci PyPI python license Glama DOI

Phylogenetic inference over MCP, driving IQ-TREE 2 through piqtree.

A topology without support is not a result. infer_tree always runs a bootstrap and always returns per-clade support. There is no flag to skip it.

6 tools, 105 tests against real IQ-TREE and real MAFFT (no mocked engine), 23 mutation checks, and a real-process JSON-RPC handshake test.

Why the rule

A maximum-likelihood tree looks identical whether or not the data support it. Measured here, on alignments simulated from a known 7-taxon tree so the right answer is not in doubt:

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; nothing about the topology itself distinguishes them. The support values do — and the false clade is the lowest-supported one in the tree.

That is the entire argument for this server. Returning a bare tree returns a result the caller cannot evaluate.

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 attach these, so the standard format silently drops them.
  • fraction_resolved — the share of clades clearing 0.70. The headline number, before any individual 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 F81, with several models inside the conventional ±2 indistinguishability margin. A winner without its margin is a claim the numbers do not support.
  • 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, per clade. Never one without the other.
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; the output goes straight into infer_tree.
capabilities Engine version, 215 substitution models, enforced limits.

Install

pip install phylokit-mcp

piqtree ships prebuilt wheels, so there is no compiler, no R and no conda step — but it requires Python 3.12+, and so does this package.

align_sequences is the one tool that needs something pip cannot install: the MAFFT binary on PATH (apt install mafft, brew install mafft, or conda install -c bioconda mafft). The other five tools work without it, capabilities reports aligner_version: null, and calling align_sequences returns a refusal that names the install rather than a crash. A MAFFT that is installed but does not answer --version is a different state: aligner_version is still null and aligner_error says what happened.

Configure your MCP client

{
  "mcpServers": {
    "phylokit": {
      "command": "uvx",
      "args": ["phylokit-mcp"]
    }
  }
}

uvx fetches the released package on demand, so this needs no prior install — but it must resolve a Python 3.12+ interpreter, since that is piqtree's wheel floor. If uvx picks an older one, pin it with "args": ["--python", "3.12", "phylokit-mcp"].

If you installed it yourself instead, "command": "phylokit-mcp" works when the executable is on your PATH; give the absolute path to the entry point in the environment you installed into if it is not.

The same file ships as .mcp.json in this repo, which Claude Code picks up automatically when the repo is your working directory.

Reproducibility, stated precisely

Measured, not assumed:

  • Across fresh processes: exact. Three runs of an identical 30-replicate bootstrap returned byte-identical support.
  • Within one long-lived process: not bit-exact. Passing the same rand_seed does not fully reset IQ-TREE's internal state — building the same tree three times gave call 1 == call 2 but call 3 different.

The practical size: over six repeated 50-replicate calls, three of four clades were bit-identical and one moved 0.02 — a single replicate flipping, well inside the bootstrap's own sampling error (~0.07 at 50 replicates). The topology and every conclusion were unchanged. This is reported in every response rather than papered over, because an MCP server is long-lived by design and that is exactly the condition which exposes it.

Threads are pinned to 1 before piqtree is imported: likelihood sums accumulate in thread-completion order, floating-point addition is not associative, and near-tied topologies can flip on the last bits.

Limitations

  • Nucleotide and protein alignments. Pass sequence_type="protein" and a protein model (LG, WAG, …). Codon models are still not exposed. The molecule type is declared, never sniffed: an alignment of only A/C/G/T is a valid protein alignment too (Ala/Cys/Gly/Thr), so guessing would fit a nucleotide model to protein data and return a tree, a likelihood and support values that are all wrong and none of which complain.
  • Bootstrap only — no aLRT, no approximate Bayes, no UFBoot. Support is the nonparametric bootstrap (Felsenstein 1985), computed here rather than read back from IQ-TREE, because piqtree 0.8.3 runs bootstrap_replicates but does not expose the resulting values.
  • Cost is linear in replicates. ~130 ms per replicate at 7 taxa / 300 sites, and it grows with taxon count. Capped at 200 taxa and 1000 replicates.
  • Alignment is MAFFT --auto, single-threaded, and nothing else. No choice of strategy, no profile alignment, no trimming, at most 200 sequences of 100,000 residues, and a 600 s wall-clock cap. Input that already contains gaps is refused rather than silently degapped. The tree tools still refuse ragged input; they do not align it for you.
  • Unrooted trees. No rooting, no dating, no ancestral reconstruction.

Licence

GPL-2.0-only. The "only" is load-bearing: piqtree declares GPL-2.0-only, which is incompatible with GPL-3.0, so the distributed combination cannot be GPL-3. cogent3 is BSD and imposes nothing.

Unofficial. Not affiliated with, endorsed by, or sponsored by the IQ-TREE authors or the cogent3 project. IQ-TREE 2 is academic software and expects to be cited — if results from this server appear in published work, cite IQ-TREE 2 as directed at iqtree.org, not this wrapper. The same holds for MAFFT when align_sequences produced the alignment: Katoh & Standley 2013, doi:10.1093/molbev/mst010. MAFFT is BSD-licensed and is run as a separate program, not linked. See NOTICE.

Release files for phylokit-mcp 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for phylokit-mcp 0.5.0
File Size Uploaded
phylokit_mcp-0.5.0.tar.gz 78.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for phylokit-mcp 0.5.0
File Interpreter ABI Platform
phylokit_mcp-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 120.2 kB

Release files / phylokit_mcp-0.5.0.tar.gz

Download URL phylokit_mcp-0.5.0.tar.gz
Size 78.9 kB
Tags Source
SHA-256 checksum
How to use checksums
f8a8fda8b73873d2f8e9ab190f4f082957052086d2d5f94959c09144c5418be9
BLAKE2b-256 checksum
How to use checksums
a9567a3407bcc0d2ff2a9bef232a174479ca2d9afe9982b5e1fa9cef088f6d27
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / phylokit_mcp-0.5.0-py3-none-any.whl

Download URL phylokit_mcp-0.5.0-py3-none-any.whl
Size 41.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c76b780a987e1f9b307a122b833099af8fc70a0bb8ffc456dca1dd94db88a6ca
BLAKE2b-256 checksum
How to use checksums
de076e283479889254352408b866c8e3b6727d9175d45c73f7a4ad2e3ac18817
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.6.0

2 release files

0.5.1

2 release files

This release

0.5.0 This release

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page