# bio-agent-tools: MCP server for Crispex, Perturbio and Bindigo.
#
# Includes the AutoDock Vina binary, which cannot be installed with pip and is
# what predict_binding needs beyond the bindigo console script.
#
# Build:  docker build -t bio-agent-tools .
# Run:    docker run --rm -i bio-agent-tools
#
# The server speaks MCP over stdio, so -i (stdin attached) is required. Mount
# your own data and declare it readable:
#
#   docker run --rm -i -v /my/data:/data -e BIO_AGENT_INPUT_DIRS=/data \
#       bio-agent-tools

FROM python:3.11-slim

# AutoDock Vina release to install. Pinned so an image rebuild does not
# silently change the docking binary. Asset naming verified against the
# upstream releases API on 2026-09-04.
ARG VINA_VERSION=1.2.7

ENV PYTHONUNBUFFERED=1 \
    PIP_NO_CACHE_DIR=1 \
    # UTF-8 everywhere. Perturbio writes box-drawing characters to summary.txt
    # using the locale encoding, and Bindigo prints a Unicode banner; both fail
    # on a non-UTF-8 locale.
    PYTHONIOENCODING=utf-8 \
    LANG=C.UTF-8 \
    LC_ALL=C.UTF-8 \
    # Where tool outputs land inside the container.
    BIO_AGENT_WORKSPACE=/work \
    # The bundled demo fixtures are readable by default. Override with your
    # own data directory: -e BIO_AGENT_INPUT_DIRS=/data
    BIO_AGENT_INPUT_DIRS=/app/tests/fixtures

RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        ca-certificates \
        curl \
        git \
    && rm -rf /var/lib/apt/lists/*

# AutoDock Vina: a native binary from the upstream release page. Checked with
# `vina --version` below so a broken download fails the build rather than the
# first docking call.
RUN curl -fsSL -o /usr/local/bin/vina \
        "https://github.com/ccsb-scripps/AutoDock-Vina/releases/download/v${VINA_VERSION}/vina_${VINA_VERSION}_linux_x86_64" \
    && chmod +x /usr/local/bin/vina \
    && vina --version

WORKDIR /app

# The three wrapped packages.
#
# NOTE: none of Crispex, Perturbio or Bindigo were on PyPI as of 2026-09-04, so
# they are installed from git here. Once they are published, delete this block:
# `pip install .` will resolve them from PyPI through pyproject.toml, which
# already declares them by name.
RUN pip install --upgrade pip \
    && 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"

COPY pyproject.toml README.md LICENSE ./
COPY src/ ./src/
COPY tests/ ./tests/

# --no-deps because the three packages are already installed from git above.
# Drop the flag once they are on PyPI.
RUN pip install --no-deps . && pip install "mcp>=2.1"

RUN mkdir -p /work

# Sanity check at build time: the server must import and register all five
# tools even before any data is mounted.
RUN python -c "import asyncio; from bio_agent_tools import server; \
    names = [t.name for t in asyncio.run(server.mcp.list_tools())]; \
    assert len(names) == 5, names; print('tools:', names)"

# stdio transport: no port to expose.
ENTRYPOINT ["python", "-m", "bio_agent_tools.server"]
