bio-agent-tools
An MCP server that exposes three CRISPR and drug-discovery packages as agent tools, so guide design, screen analysis and docking happen in one conversation instead of three repos and three CLIs.
| Wrapped package | Does |
|---|---|
| Crispex | SpCas9 sgRNA design: Ensembl lookup, PAM scanning, on-target scoring, ranked CSV |
| Perturbio | Crop-Seq / CRISPR perturbation screen analysis at single-cell resolution |
| Bindigo | Protein-ligand binding prediction, AutoDock Vina docking plus ML |
Status · The five tools · A real session · Install · Configure · MCP client · Docker · Troubleshooting · Development · Design notes
Status
Read this before installing.
| Tool | State |
|---|---|
design_guides |
Working. Verified against live Ensembl |
analyze_screen |
Working. Verified on a real 300-cell h5ad |
top_hits |
Working |
plot_volcano |
Working. Writes a real PNG |
predict_binding |
Blocked upstream. See below |
predict_binding cannot return a binding affinity yet, and the reason is not
this server. Bindigo 0.1.0 ships a skeleton predict command:
bindigo/core/pipeline.py validates inputs and checks for AutoDock Vina, then
returns a placeholder — docking, ML prediction and "Format and save results"
are all TODO upstream. The command exits 0 and prints "Results saved to:
<path>" while writing no file at all, so this server treats a missing
output CSV as failure rather than trusting the exit code, and says exactly why.
The wrapper around it is complete and tested, including the CSV parsing path.
When Bindigo implements its pipeline, predict_binding starts returning real
results with no change here.
The five tools
| Tool | Arguments | Returns |
|---|---|---|
design_guides |
gene or region, species, top_n |
Ranked guide table plus CSV path |
predict_binding |
protein, ligand, optional center_x/y/z, size |
Kd, confidence, docking score, pose path |
analyze_screen |
h5ad, guides, control_label, min_cells, fdr_threshold |
Results directory plus summary stats |
top_hits |
results, perturbation, n |
Affected gene table |
plot_volcano |
results, perturbation, fdr_threshold |
PNG path |
Two rules shape every response. Tables plus a path, never bulk rows: a 100-guide request returns the top handful as markdown and a path to the full CSV. Large objects move as paths: h5ad files, results directories and PNGs cross the boundary as file paths, never as matrices.
A real session
Every block below is copied verbatim from an actual run on 2026-09-04. Nothing here is illustrative, and nothing was written by hand.
Designing guides
design_guides(gene="TP53", top_n=5), against the live Ensembl REST API:
### sgRNA guides for TP53
- **Target**: TP53
- **Species**: human
- **Guides returned**: 5
- **Full CSV**: C:\Users\siava\.bio-agent-tools\work\guides_TP53_20260904-171851.csv
| rank | guide_sequence | pam_sequence | strand | efficiency_score | gc_content | offtarget_risk_estimate_1mm | offtarget_risk_estimate_2mm | offtarget_risk_estimate_3mm |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | TGTAGTTCCAGCTACTCTGG | AGG | - | 71.0 | 50.0 | 0 | 6 | 23 |
| 2 | ACACTCATTGCAGACTCAGG | TGG | + | 71.0 | 50.0 | 2 | 6 | 23 |
| 3 | ACTCGGATAAGATGCTGAGG | AGG | + | 71.0 | 50.0 | 3 | 6 | 24 |
| 4 | CTTCCAGTGTGATGATGGTG | AGG | + | 70.0 | 50.0 | 0 | 7 | 24 |
| 5 | CAATTGAAGGCTGTCAGTCG | TGG | - | 70.0 | 50.0 | 0 | 7 | 25 |
> **Off-target values are heuristic estimates, not measured off-target sites.** ...
Run it twice and the offtarget_risk_estimate_* columns will differ. That is
the point of the warning: they are randomised heuristics, not site counts.
Analysing a screen
analyze_screen on the bundled 300-cell fixture:
### Screen analysed
- **Results directory**: C:\Users\siava\.bio-agent-tools\work\screen_tiny_20260904-171900
- **Cells**: 300
- **Genes**: 66
- **Perturbations tested**: 5
- **Perturbations**: BRCA1, EGFR, KRAS, MYC, TP53
- **Gene-level tests**: 330
- **Significant (FDR < 0.05)**: 41
Then top_hits(results=..., perturbation="TP53", n=5). Note the label is the
target gene, TP53, not the guide sgTP53_1:
| gene | log_fc | pval_adj |
| --- | --- | --- |
| sgTP53_1 | 65.358795 | 1.6019990490646224e-16 |
| GENE_000 | -10.910223 | 1.6019990490646224e-16 |
| sgNTC_1 | -65.27223 | 1.6019990490646224e-16 |
| GENE_002 | -10.743561 | 1.952670077949663e-16 |
| GENE_001 | -10.119792 | 1.952670077949663e-16 |
And plot_volcano:
### Volcano plot
- **Perturbation**: TP53
- **PNG**: C:\Users\siava\.bio-agent-tools\work\volcano_TP53_20260904-171919.png
- **Genes plotted**: 66
- **Significant (FDR < 0.05)**: 8
Docking, and why it stops
With no AutoDock Vina installed, predict_binding names the missing piece and
says the blast radius is one tool:
**predict_binding could not run.**
AutoDock Vina was not found. It is a native binary and cannot be installed with
pip: try `conda install -c conda-forge vina`, `brew install autodock-vina`, or a
release binary from https://github.com/ccsb-scripps/AutoDock-Vina/releases. If
it is installed elsewhere, set BIO_AGENT_VINA_PATH to its full path. This
disables predict_binding only; every other tool still works.
With Vina present, the call reaches Bindigo and stops there instead:
**predict_binding could not run.**
`bindigo predict` exited 0 but produced no results CSV. Bindigo 0.1.0's
prediction pipeline is a skeleton: it validates inputs and checks for AutoDock
Vina, then returns a placeholder without docking, scoring or writing output
(steps 3-9 are TODO upstream in bindigo/core/pipeline.py). No binding affinity
is available until that pipeline is implemented. Nothing is wrong with your
inputs or your Vina install.
This is the honest state of the chain today. design_guides runs, the handoff
works, and docking is blocked upstream rather than here.
The cell-count guard
analyze_screen runs synchronously, so it refuses oversized inputs rather than
queueing them. With BIO_AGENT_MAX_CELLS=100 against the 300-cell fixture:
**analyze_screen could not run.**
This dataset has 300 cells, above the limit of 100. analyze_screen runs
synchronously and a screen this size would block the session. Subset the data,
or raise the ceiling with the BIO_AGENT_MAX_CELLS environment variable if the
wait is acceptable.
The count is read from the h5ad in backed mode, so nothing large is loaded before the refusal.
Self-test
python -m bio_agent_tools.selftest on a machine with Crispex and Perturbio
installed but no Bindigo and no Vina:
Dependencies
------------------------------------------------------------------------
[ok ] Crispex (python package)
[ok ] Perturbio (python package)
[MISSING] bindigo (console script) -> disables predict_binding
[MISSING] AutoDock Vina (binary) -> disables predict_binding
[absent ] Crispex human genome -> not required by any tool
========================================================================
Summary
========================================================================
design_guides ok 300 tokens
predict_binding disabled 47 tokens
analyze_screen ok 173 tokens
top_hits ok 98 tokens
plot_volcano ok 46 tokens
All responses within the token budget.
Four tools working, one reporting exactly why it cannot, and every response well inside the 1,000-token ceiling.
Install
None of Crispex, Perturbio or Bindigo were published on PyPI as of
2026-09-04. pyproject.toml declares them by PyPI name, so once they are
published this is all you need:
pip install bio-agent-tools
Until then, install the three from git first, then this server without dependency resolution:
pip install "crispex @ git+https://github.com/Siavashghaffari/Crispex@main" \
"perturbio @ git+https://github.com/Siavashghaffari/Perturbio@main" \
"bindigo @ git+https://github.com/Siavashghaffari/Bindigo@main"
pip install --no-deps "bio-agent-tools @ git+https://github.com/Siavashghaffari/bio-agent-tools@main"
pip install "mcp>=2.1"
Prerequisites
| Requirement | Needed by | Notes |
|---|---|---|
Network access to rest.ensembl.org |
design_guides |
Sequences come from the Ensembl REST API |
| AutoDock Vina binary | predict_binding |
Not pip-installable. conda install -c conda-forge vina, brew install autodock-vina, or a release binary |
| An h5ad and a guide CSV | analyze_screen |
Guide IDs must appear among the gene names |
A reference genome is not required. Crispex 0.1.0 never reads one:
design_guides fetches sequence from Ensembl, and the off-target columns are
sequence-composition heuristics. crispex install-genome is not a prerequisite
for any tool here.
A missing dependency disables only the tools that need it. The server always starts, and each tool reports its own missing piece.
Configure
| Variable | Default | Purpose |
|---|---|---|
BIO_AGENT_WORKSPACE |
~/.bio-agent-tools/work |
Where outputs are written |
BIO_AGENT_INPUT_DIRS |
(none) | Extra directories tools may read, os.pathsep-separated |
BIO_AGENT_MAX_CELLS |
50000 |
analyze_screen refuses datasets above this |
BIO_AGENT_VINA_PATH |
(none) | Full path to the Vina binary if it is not on PATH |
BIO_AGENT_DOCKING_TIMEOUT |
900 |
Seconds before bindigo predict is killed |
Input paths are validated: a tool refuses any path outside the workspace and
the directories you list in BIO_AGENT_INPUT_DIRS.
Use it from an MCP client
{
"mcpServers": {
"bio-agent-tools": {
"command": "python",
"args": ["-m", "bio_agent_tools.server"],
"env": {
"BIO_AGENT_INPUT_DIRS": "/path/to/your/data"
}
}
}
}
The server speaks MCP over stdio.
Docker
The image bundles AutoDock Vina, which is the one prerequisite pip cannot install.
docker build -t bio-agent-tools .
docker run --rm -i -v /my/data:/data -e BIO_AGENT_INPUT_DIRS=/data bio-agent-tools
-i is required: the server talks over stdin/stdout.
The image installs the three packages from git, because they are not on PyPI
yet. Once they are published, delete that block from the Dockerfile and the
--no-deps flag below it; pip install . will then resolve them from PyPI.
The chained workflow, run in the image
Built image, verified 2026-09-04. Vina and the Bindigo console script are both present:
$ docker run --rm --entrypoint vina bio-agent-tools:0.1.0 --version
AutoDock Vina v1.2.7
$ docker run --rm --entrypoint bindigo bio-agent-tools:0.1.0 --version
bindigo, version 0.1.0
Then guide design feeding into docking, in one container:
>>> Step 1: design guides for TP53
### sgRNA guides for TP53
- **Target**: TP53
- **Species**: human
- **Guides returned**: 5
- **Full CSV**: /work/guides_TP53_20260904-212404.csv
| rank | guide_sequence | pam_sequence | strand | efficiency_score | gc_content | offtarget_risk_estimate_1mm | offtarget_risk_estimate_2mm | offtarget_risk_estimate_3mm |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1 | TGTAGTTCCAGCTACTCTGG | AGG | - | 71.0 | 50.0 | 0 | 6 | 24 |
| 2 | ACTCGGATAAGATGCTGAGG | AGG | + | 71.0 | 50.0 | 1 | 5 | 25 |
| 3 | ACACTCATTGCAGACTCAGG | TGG | + | 71.0 | 50.0 | 3 | 4 | 24 |
| 4 | CTTCCAGTGTGATGATGGTG | AGG | + | 70.0 | 50.0 | 0 | 6 | 23 |
| 5 | CAATTGAAGGCTGTCAGTCG | TGG | - | 70.0 | 50.0 | 3 | 6 | 26 |
> **Off-target values are heuristic estimates, not measured off-target sites.** ...
[tokens: 292 ]
>>> Step 2: dock against 4HHB
**predict_binding could not run.**
`bindigo predict` exited 0 but produced no results CSV. Bindigo 0.1.0's
prediction pipeline is a skeleton: it validates inputs and checks for AutoDock
Vina, then returns a placeholder without docking, scoring or writing output
(steps 3-9 are TODO upstream in bindigo/core/pipeline.py). No binding affinity
is available until that pipeline is implemented. Nothing is wrong with your
inputs or your Vina install.
[tokens: 112 ]
That is the whole chain as it stands. Step 1 completes against live Ensembl from inside the container. Step 2 reaches Bindigo with a working Vina v1.2.7 underneath it and stops at the upstream skeleton — which is the accurate result, not a workaround. When Bindigo's pipeline lands, this same image returns a Kd here.
The build also asserts that all five tools register before the image is tagged:
#17 [13/13] RUN python -c "import asyncio; from bio_agent_tools import server; ...
#17 1.585 tools: ['design_guides', 'predict_binding', 'analyze_screen', 'top_hits', 'plot_volcano']
Troubleshooting
pip install bio-agent-tools cannot resolve crispex / perturbio / bindigo.
They are not on PyPI yet. Use the git install shown under
Install.
The Docker build fails at the Vina download with SSL certificate problem:
unable to get local issuer certificate. Your network intercepts TLS and the
base image does not trust the interception CA. Export your organisation's root
certificate and add it before the download:
COPY corp-ca.pem /usr/local/share/ca-certificates/corp-ca.crt
RUN update-ca-certificates
ENV REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt GIT_SSL_CAINFO=/etc/ssl/certs/ca-certificates.crt
The same condition breaks git clone and pip on the host. Fix those with
git -c http.sslBackend=schannel (Windows), pip --use-feature=truststore, or
import truststore; truststore.inject_into_ssl(). Point tools at your system
trust store rather than disabling verification.
UnicodeEncodeError: 'charmap' codec can't encode characters. A non-UTF-8
console. The wrapped packages print box-drawing characters. Set
PYTHONIOENCODING=utf-8, or use the Docker image, which sets it already.
analyze_screen says a path is outside the allowed directories. By design:
tools read only from the workspace and from BIO_AGENT_INPUT_DIRS. Add the
directory holding your data:
export BIO_AGENT_INPUT_DIRS=/path/to/data
analyze_screen refuses a dataset as too large. It runs synchronously and
has no job queue. Subset the data, or raise BIO_AGENT_MAX_CELLS if you are
willing to wait.
predict_binding says Bindigo produced no results CSV. Expected today —
see Status. Nothing is wrong with your inputs or your Vina install.
Development
pip install --no-deps -e .
pip install "mcp>=2.1" pytest ruff
pytest tests/ -q
ruff check src tests
The offline suite mocks all three packages and passes with none of them
installed, no network and no Vina. One integration test runs Perturbio for real
on tests/fixtures/tiny.h5ad and skips when Perturbio is absent. Regenerate
the fixture with python tests/fixtures/make_fixtures.py.
A live smoke test that calls every tool once:
python -m bio_agent_tools.selftest
Design notes
server.pycontains no package logic. It defines tools, calls a wrapper, renders throughtrim, and returns.- Wrappers return plain dicts, never markdown, which is what lets them be tested with the underlying packages mocked out.
- The three packages are imported inside function bodies, so a missing package never stops the server from starting.
- stdout is the MCP transport, so everything the wrapped packages print is redirected to stderr. Perturbio prints progress unconditionally.
- Off-target estimates keep their long column names on purpose. See below.
About the off-target numbers
Any response carrying offtarget_risk_estimate_* values also carries this
warning, because the numbers are easy to misread:
Crispex 0.1.0 performs no genome-wide off-target search. It never reads the reference genome and never aligns anything. Those columns are a heuristic function of the guide's own sequence composition, randomised within a band, and they differ between runs.
perfect_match_assumedis assumed, not verified.
Validate guides with Cas-OFFinder, CRISPOR or CHOPCHOP before ordering.
Project
- CHANGELOG.md — release history and known limitations
- CONTRIBUTING.md — setup, conventions, scope boundaries
- docs/ — the design documents this server was built from
License
MIT. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bio_agent_tools-0.1.0.tar.gz.
File metadata
- Download URL: bio_agent_tools-0.1.0.tar.gz
- Upload date:
- Size: 64.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
877f1f0a557b732462a4f6d61c6f982e026d13d7fe686ffac2d062957eb3fcfb
|
|
| MD5 |
de9e5cf9996c7c149dd92c5fdb9ff9f1
|
|
| BLAKE2b-256 |
5c9bda26cdc98d8a8a839c988701413415b1224a10b2c1ed36478385e6370eb2
|
File details
Details for the file bio_agent_tools-0.1.0-py3-none-any.whl.
File metadata
- Download URL: bio_agent_tools-0.1.0-py3-none-any.whl
- Upload date:
- Size: 32.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.10.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
94ceb8f2f5ef1dfd4ed462af800a739fe615f1472b8bc5273122f1ad2e67e3b1
|
|
| MD5 |
9facb89b2540368470b80814577ddbd9
|
|
| BLAKE2b-256 |
a3033cbffa427c544b47659d3c4f0cd826bbd743b77698a1f7f7bb7934336342
|