- name
- setup-complexa-remote-tool
- description
- Set up, launch, validate, and troubleshoot the Proteina-Complexa ToolUniverse remote tool and optionally relay it through ToolUniverse Connect. Use when deploying or auditing this implementation.
# Set up Proteina-Complexa as a remote tool
> Validation status (2026-10-02): Proteina-Complexa 1.1.0 (NVIDIA's flow-matching binder generator -- it DESIGNS proteins against a target structure, it does not fold one) ran on the NVIDIA GB10 (aarch64, cc 12.1) with the optimization kit in `fast` mode, all six levers engaged. Verified on FOUR CONSECUTIVE IDENTICAL REQUESTS, a mixed-shape sequence (100, 100, 200, 100 residues) and an ascending ladder (100/200/400), plus a sequence that changed the ENGINE KEY (`num_steps`, batch size, binder length, the target, the seed) and returned to the first request, which reproduced byte for byte. The held worker's design for the smoke target is byte-identical to the kit's own `run.sh design` in a fresh process, and to a worker built from the lock in an empty venv. Per-request peak reserved runs from 1.70 GiB (100 residues) to 20.25 GiB at the ceiling corner, which is the declared budget. One thing to know before deploying: torch 2.7.0+cu128's NVRTC does not know this card, and without the pinned 12.9 NVRTC every request dies in `torch.prod` (see the environment section). Public publication, cross-user isolation, concurrency, recovery and design quality (binding, designability) are untested; keep this deployment private.
## What a request is
A target protein STRUCTURE (PDB text), a crop of one of its chains (`A1-115`), hotspot residues on its surface (`["A37", "A39"]`, numbered as in that file), a binder length and a design count. The model samples that many binders, and each comes back as a decoded amino-acid sequence (and, with `return_pdb`, a PDB: chain A the target crop, chain B the new binder). It is NOT a predictor: nothing says a design binds, and this deployment runs upstream's **generation stage alone** -- upstream's own `++generation.search.algorithm=single-pass ++generation.reward_model=null` -- so the designs are raw, unscored and unranked. Upstream's shipped configuration also scores every design with an AlphaFold2 reward model whose parameters are not carried here.
The tool validates the target before it queues: the chain must exist in the PDB, the crop must hold residues, every hotspot must be a residue of that crop. This is not pedantry. Upstream does not refuse a hotspot it cannot find (measured: a request naming `A400` in a 115-residue target designed a binder anyway, against fewer hotspots than the caller thought).
## Prerequisites
- Run from the ToolUniverse repository root on Linux with Python 3.12.
- A CUDA GPU is required. This provider holds its model resident between requests; CPU is not a target.
- Keep provider data, weights, caches, and credentials outside Git.
- Bind to loopback. A non-loopback bind requires TOOLUNIVERSE_API_TOKEN; never put it in arguments or results.
Run the standard-library contract check before downloading large dependencies:
~~~bash
python scripts/remote_validation/setup_skill_preflight.py --implementation complexa
~~~
After exporting provider resources, add `--check-provider-env`. After the
server starts, add `--live` to verify the exact MCP tool set without running
the model. Before sharing, add `--check-connect-prereqs`; this reports only
whether a key is set and never prints its value.
## Create the two environments
This provider is on the remote-tool standard, so it has two environments, not
one: the MCP server runs in ToolUniverse's, and the model runs in its own,
built from a pinned lock. They cannot import each other, and that is the point.
~~~bash
python3 -m venv .venvs/complexa
. .venvs/complexa/bin/activate
python -m pip install --upgrade pip
python -m pip install -e .
python -m pip install fastmcp
~~~
The model half lives at the path `TOOLUNIVERSE_COMPLEXA_PYTHON` names, and
nothing above creates it. Create an empty CPython 3.12.10 interpreter there with
the STDLIB venv module, not `uv venv` (this kit activates through a `.pth` file
and a `uv venv` `_virtualenv.pth` has broken that detection for another kit):
~~~bash
uv python install 3.12.10
~/.local/share/uv/python/cpython-3.12.10-linux-aarch64-gnu/bin/python3.12 -m venv ~/complexa-venv
export TOOLUNIVERSE_COMPLEXA_PYTHON=~/complexa-venv/bin/python
~~~
`tu remote setup --only environment` then fills it from
`src/tooluniverse/remote/complexa/environment/requirements.lock` with `--no-deps`
(~160 distributions, about 8 GB, torch 2.7.0+cu128 included). The lock's header
records every change from the kit's own x86-64 lock. Two matter here.
- **torch is 2.7.0+cu128, not the kit's +cu126.** 2.7.0 is above the 2.7 line below which no CUDA build can drive this card at all, and an sm_120 cubin runs on sm_121. It is the same upstream version; the kit's pin check treats its torch line as a label.
- **The lock carries a NEWER NVRTC than torch does, and without it every request dies.** torch 2.7.0+cu128 bundles NVRTC 12.8, which does not know sm_121, so `torch.prod(x, dim=-1)` -- which upstream's openfold transforms call on every target's side-chain torsion features -- raises `nvrtc: error: invalid value for --gpu-architecture (-arch)` on every CUDA dtype. `nvidia-cuda-nvrtc-cu12==12.9.86` is pinned and the launcher puts its `lib` directory first on `LD_LIBRARY_PATH` (the loader reads it once at process start, so it has to be the child's environment). Nothing else in the model is affected; this is the only op that failed.
The rest is built by `tu remote setup`, which reads
`src/tooluniverse/remote/complexa/provider.toml` and runs five steps: preflight,
environment, kit, weights, smoke. Each refuses by name and carries its fix.
~~~bash
tu remote setup complexa
~~~
Run one step at a time with `--only preflight|environment|kit|weights|smoke`
while bringing a machine up. The smoke step holds the model, sends one request,
asserts the provider produced a design file (`job_*_n_*_id_*.pdb` -- not `*.pdb`,
which would match the target the provider itself writes), and records the
measured peak VRAM to `~/.cache/tooluniverse/measured/complexa.json`. A host
schedules on that file.
The kit step also builds `torch_scatter` 2.1.2 from the PyPI sdist, CPU-only
(`FORCE_ONLY_CPU=1`): no aarch64 wheel exists, pip's isolated build cannot import
torch, and this host has nvcc 13 beside a cu128 torch. Upstream imports exactly
one name from it, `scatter_mean`, which is torch-native and runs on CUDA tensors.
Package/network-dependent commands must be rerun in a clean environment before marking this skill complete.
## Obtain credentials, data, and model weights
- No credential is needed. The two checkpoints (`complexa.ckpt`, 2,934,289,381 bytes; `complexa_ae.ckpt`, 4,100,101,779 bytes; 6.6 GiB together) come from NVIDIA's own repository `nvidia/NV-Proteina-Complexa-Protein-Target-160M-v1` on the Hugging Face Hub, which answers 200 without a token (`gated: false`), through the kit's own fetcher. Their licence is the NVIDIA Open Model License: commercially usable, derivative models allowed, no ownership claim on outputs. Do not substitute a third-party mirror.
- Nothing is fetched at request time. The manifest declares both files with size and sha256, and the launch refuses if one is off its pin. `CKPT_PATH` names the directory (default `~/complexa_weights`).
- The resident worker forces the data loader to 0 workers and nothing on the path forks: every reply carries `child_processes`, which is 0.
## Authorize once, then share with one short command
After installing dependencies, exporting the provider resources above, and
installing the pinned relay SDK described under Connect below, run from the
repository root. Log in only once per machine (and again after key
rotation):
~~~bash
tu remote login
# Or import an existing protected 0600 file without sourcing it:
tu remote login --env-file /path/to/tooluniverse-service.env
~~~
Then each private share is one short command:
~~~bash
tu remote share complexa
~~~
By default, `tu remote login` requests a short-lived device code, opens the
TU Platform approval page, and polls until the signed-in user approves. No key
copy/paste is required. On a headless machine, add `--no-browser` and open the
printed link elsewhere. The CLI exchanges the approval for a computer-only key,
verifies `/remote-servers/preflight`, stores it in a local 0600 config file, and
never displays it.
The share command runs environment and TU Platform preflights, starts or reuses
the exact loopback endpoint, validates discovery, and keeps the relay in the
foreground until Ctrl-C. It automatically uses the reviewed Python, name,
and worker count. Override them only when needed:
~~~bash
tu remote share complexa --name my-complexa-remote --workers 1
~~~
Use `tu remote check complexa` for a non-sharing readiness check and
`tu remote run complexa` for a local-only foreground server.
In an interactive terminal, sharing automatically starts the same browser flow
when the key is missing, expired, or revoked. A malformed or revoked explicit
`TOOLUNIVERSE_SERVICE_KEY` fails fast instead of being silently replaced; unset
or correct it, then run `tu remote login`. Non-interactive jobs also fail fast.
Use `tu remote logout` to remove only the local copy. Use `tu remote logout --revoke` to revoke the computer-only platform connection first; the server record remains offline for owner inspection.
## Start and verify locally
~~~bash
python -m tooluniverse.remote.complexa.complexa_tool
~~~
The Streamable HTTP endpoint is http://127.0.0.1:8056/mcp. In a second activated shell run:
~~~bash
python - <<'PY'
import asyncio
from fastmcp import Client
async def main():
async with Client("http://127.0.0.1:8056/mcp") as client:
print([tool.name for tool in await client.list_tools()])
asyncio.run(main())
PY
~~~
Confirm discovery contains complexa_design_binder; stop on empty, duplicate, or schema-drifted discovery.
The first request after a restart pays the interpreter, the import graph and the model build; the ones after it do not. That is the whole reason this provider is resident, and a benchmark that measures only the first call measures the wrong thing.
## Connect to ToolUniverse Connect
The `tuplatform-connect` relay is not yet published on PyPI. Install the reviewed public wheel below; its SHA-256 is pinned. Interactive sharing uses browser device authorization, so no key copy/paste or GitHub access is required.
~~~bash
python -m pip install fastmcp pyyaml "tuplatform-connect @ https://connect.aiscientist.tools/downloads/tuplatform_connect-0.3.0-py3-none-any.whl#sha256=3fad5eee5ecf7887a693d93ccd1aa112dc0955617a885d1fc3daded0030f9ae0"
tu doctor --forward http://127.0.0.1:8056/mcp --json
tu serve --share --forward http://127.0.0.1:8056/mcp --name validation-complexa --workers 1
~~~
Prefer browser device authorization. For CI or migration, supply
`TOOLUNIVERSE_SERVICE_KEY` only through a protected environment or use
`tu remote login --manual-key`; never put a key in shell arguments.
This implementation was added after the authenticated 2026-08-16 Platform
matrix and was not part of it. That matrix imported each implementation it
covered as unpublished owner drafts and invoked them through
`/expert-sessions/{id}/test`; this provider was imported as no such draft and
invoked through no such route. It has not been exercised through the Platform
at all: the evidence above is local, on one card, through the loopback
endpoint. Public publication, independent-caller authorization/isolation,
saturation, and persistent supervision are untested.
## Run a verified example
Operation: complexa_design_binder
The first 50 residues of PD-L1 (chain A, residues 1-50 of upstream's own `PD-L1.pdb` target), two 40-residue binders, 50 integration steps instead of the default 400 so it finishes in minutes, hotspots A37, A39 and A49:
~~~json
{"target_pdb":"ATOM 1 N ALA A 1 32.691 -38.552 -22.954 1.00 81.30 N\nATOM 2 CA ALA A 1 31.571 -39.485 -22.907 1.00 81.30 C\nATOM 3 C ALA A 1 31.589 -40.427 -24.111 1.00 81.30 C\nATOM 4 CB ALA A 1 30.249 -38.724 -22.851 1.00 81.30 C\nATOM 5 O ALA A 1 32.117 -40.080 -25.173 1.00 81.30 O\nATOM 6 N PHE A 2 31.571 -41.687 -23.868 1.00 91.90 N\nATOM 7 CA PHE A 2 31.405 -42.668 -24.925 1.00 91.90 C\nATOM 8 C PHE A 2 30.440 -42.160 -25.988 1.00 91.90 C\nATOM 9 CB PHE A 2 30.900 -44.000 -24.355 1.00 91.90 C\nATOM 10 O PHE A 2 29.295 -41.814 -25.685 1.00 91.90 O\nATOM 11 CG PHE A 2 30.814 -45.108 -25.372 1.00 91.90 C\nATOM 12 CD1 PHE A 2 29.634 -45.343 -26.067 1.00 91.90 C\nATOM 13 CD2 PHE A 2 31.916 -45.913 -25.632 1.00 91.90 C\nATOM 14 CE1 PHE A 2 29.552 -46.368 -27.008 1.00 91.90 C\nATOM 15 CE2 PHE A 2 31.843 -46.936 -26.569 1.00 91.90 C\nATOM 16 CZ PHE A 2 30.659 -47.163 -27.256 1.00 91.90 C\nATOM 17 N THR A 3 30.893 -42.044 -27.248 1.00 94.64 N\nATOM 18 CA THR A 3 30.063 -41.472 -28.304 1.00 94.64 C\nATOM 19 C THR A 3 30.098 -42.346 -29.553 1.00 94.64 C\nATOM 20 CB THR A 3 30.521 -40.043 -28.659 1.00 94.64 C\nATOM 21 O THR A 3 31.171 -42.723 -30.029 1.00 94.64 O\nATOM 22 CG2 THR A 3 29.627 -39.430 -29.731 1.00 94.64 C\nATOM 23 OG1 THR A 3 30.465 -39.229 -27.487 1.00 94.64 O\nATOM 24 N VAL A 4 28.968 -42.656 -30.048 1.00 96.76 N\nATOM 25 CA VAL A 4 28.801 -43.338 -31.321 1.00 96.76 C\nATOM 26 C VAL A 4 28.644 -42.316 -32.445 1.00 96.76 C\nATOM 27 CB VAL A 4 27.584 -44.291 -31.297 1.00 96.76 C\nATOM 28 O VAL A 4 27.914 -41.331 -32.298 1.00 96.76 O\nATOM 29 CG1 VAL A 4 27.346 -44.899 -32.678 1.00 96.76 C\nATOM 30 CG2 VAL A 4 27.786 -45.389 -30.255 1.00 96.76 C\nATOM 31 N THR A 5 29.369 -42.520 -33.544 1.00 97.00 N\nATOM 32 CA THR A 5 29.263 -41.639 -34.702 1.00 97.00 C\nATOM 33 C THR A 5 28.881 -42.433 -35.951 1.00 97.00 C\nATOM 34 CB THR A 5 30.583 -40.886 -34.954 1.00 97.00 C\nATOM 35 O THR A 5 29.033 -43.654 -35.986 1.00 97.00 O\nATOM 36 CG2 THR A 5 30.983 -40.064 -33.741 1.00 97.00 C\nATOM 37 OG1 THR A 5 31.617 -41.835 -35.244 1.00 97.00 O\nATOM 38 N VAL A 6 28.274 -41.662 -36.892 1.00 97.54 N\nATOM 39 CA VAL A 6 27.944 -42.275 -38.176 1.00 97.54 C\nATOM 40 C VAL A 6 28.630 -41.513 -39.306 1.00 97.54 C\nATOM 41 CB VAL A 6 26.418 -42.316 -38.411 1.00 97.54 C\nATOM 42 O VAL A 6 28.642 -40.277 -39.311 1.00 97.54 O\nATOM 43 CG1 VAL A 6 25.733 -43.201 -37.373 1.00 97.54 C\nATOM 44 CG2 VAL A 6 25.839 -40.903 -38.378 1.00 97.54 C\nATOM 45 N PRO A 7 29.284 -42.304 -40.230 1.00 97.01 N\nATOM 46 CA PRO A 7 29.857 -41.614 -41.388 1.00 97.01 C\nATOM 47 C PRO A 7 28.799 -40.960 -42.274 1.00 97.01 C\nATOM 48 CB PRO A 7 30.587 -42.730 -42.140 1.00 97.01 C\nATOM 49 O PRO A 7 29.023 -39.876 -42.819 1.00 97.01 O\nATOM 50 CG PRO A 7 29.972 -43.993 -41.632 1.00 97.01 C\nATOM 51 CD PRO A 7 29.492 -43.759 -40.230 1.00 97.01 C\nATOM 52 N LYS A 8 27.647 -41.681 -42.396 1.00 96.46 N\nATOM 53 CA LYS A 8 26.498 -41.188 -43.164 1.00 96.46 C\nATOM 54 C LYS A 8 25.197 -41.414 -42.406 1.00 96.46 C\nATOM 55 CB LYS A 8 26.439 -41.874 -44.530 1.00 96.46 C\nATOM 56 O LYS A 8 24.934 -42.514 -41.922 1.00 96.46 O\nATOM 57 CG LYS A 8 27.607 -41.543 -45.444 1.00 96.46 C\nATOM 58 CD LYS A 8 27.473 -42.228 -46.800 1.00 96.46 C\nATOM 59 CE LYS A 8 28.685 -41.967 -47.685 1.00 96.46 C\nATOM 60 NZ LYS A 8 28.571 -42.671 -48.995 1.00 96.46 N\nATOM 61 N ASP A 9 24.424 -40.296 -42.388 1.00 96.78 N\nATOM 62 CA ASP A 9 23.166 -40.391 -41.655 1.00 96.78 C\nATOM 63 C ASP A 9 21.995 -40.653 -42.602 1.00 96.78 C\nATOM 64 CB ASP A 9 22.913 -39.114 -40.849 1.00 96.78 C\nATOM 65 O ASP A 9 20.888 -40.956 -42.156 1.00 96.78 O\nATOM 66 CG ASP A 9 22.858 -37.870 -41.714 1.00 96.78 C\nATOM 67 OD1 ASP A 9 23.039 -37.973 -42.945 1.00 96.78 O\nATOM 68 OD2 ASP A 9 22.633 -36.771 -41.158 1.00 96.78 O\nATOM 69 N LEU A 10 22.267 -40.643 -43.987 1.00 97.96 N\nATOM 70 CA LEU A 10 21.300 -40.966 -45.023 1.00 97.96 C\nATOM 71 C LEU A 10 21.925 -41.849 -46.099 1.00 97.96 C\nATOM 72 CB LEU A 10 20.749 -39.684 -45.656 1.00 97.96 C\nATOM 73 O LEU A 10 22.977 -41.515 -46.647 1.00 97.96 O\nATOM 74 CG LEU A 10 19.786 -39.865 -46.832 1.00 97.96 C\nATOM 75 CD1 LEU A 10 18.476 -40.481 -46.355 1.00 97.96 C\nATOM 76 CD2 LEU A 10 19.534 -38.530 -47.530 1.00 97.96 C\nATOM 77 N TYR A 11 21.234 -43.022 -46.354 1.00 97.64 N\nATOM 78 CA TYR A 11 21.620 -43.926 -47.435 1.00 97.64 C\nATOM 79 C TYR A 11 20.507 -44.030 -48.475 1.00 97.64 C\nATOM 80 CB TYR A 11 21.954 -45.315 -46.884 1.00 97.64 C\nATOM 81 O TYR A 11 19.348 -44.278 -48.131 1.00 97.64 O\nATOM 82 CG TYR A 11 23.261 -45.372 -46.133 1.00 97.64 C\nATOM 83 CD1 TYR A 11 24.391 -45.952 -46.705 1.00 97.64 C\nATOM 84 CD2 TYR A 11 23.371 -44.847 -44.851 1.00 97.64 C\nATOM 85 CE1 TYR A 11 25.599 -46.010 -46.014 1.00 97.64 C\nATOM 86 CE2 TYR A 11 24.570 -44.894 -44.153 1.00 97.64 C\nATOM 87 OH TYR A 11 26.869 -45.529 -44.055 1.00 97.64 O\nATOM 88 CZ TYR A 11 25.678 -45.476 -44.744 1.00 97.64 C\nATOM 89 N VAL A 12 20.788 -43.692 -49.677 1.00 97.61 N\nATOM 90 CA VAL A 12 19.878 -43.935 -50.791 1.00 97.61 C\nATOM 91 C VAL A 12 20.359 -45.143 -51.594 1.00 97.61 C\nATOM 92 CB VAL A 12 19.760 -42.700 -51.702 1.00 97.61 C\nATOM 93 O VAL A 12 21.456 -45.123 -52.160 1.00 97.61 O\nATOM 94 CG1 VAL A 12 18.758 -42.951 -52.833 1.00 97.61 C\nATOM 95 CG2 VAL A 12 19.351 -41.470 -50.892 1.00 97.61 C\nATOM 96 N VAL A 13 19.521 -46.212 -51.575 1.00 97.39 N\nATOM 97 CA VAL A 13 19.980 -47.479 -52.137 1.00 97.39 C\nATOM 98 C VAL A 13 18.982 -47.980 -53.176 1.00 97.39 C\nATOM 99 CB VAL A 13 20.186 -48.547 -51.036 1.00 97.39 C\nATOM 100 O VAL A 13 17.799 -47.640 -53.120 1.00 97.39 O\nATOM 101 CG1 VAL A 13 21.329 -48.148 -50.102 1.00 97.39 C\nATOM 102 CG2 VAL A 13 18.895 -48.754 -50.247 1.00 97.39 C\nATOM 103 N GLU A 14 19.433 -48.775 -54.214 1.00 97.62 N\nATOM 104 CA GLU A 14 18.574 -49.353 -55.246 1.00 97.62 C\nATOM 105 C GLU A 14 17.991 -50.685 -54.799 1.00 97.62 C\nATOM 106 CB GLU A 14 19.346 -49.526 -56.555 1.00 97.62 C\nATOM 107 O GLU A 14 18.665 -51.474 -54.134 1.00 97.62 O\nATOM 108 CG GLU A 14 19.779 -48.217 -57.193 1.00 97.62 C\nATOM 109 CD GLU A 14 18.632 -47.425 -57.783 1.00 97.62 C\nATOM 110 OE1 GLU A 14 18.708 -46.174 -57.833 1.00 97.62 O\nATOM 111 OE2 GLU A 14 17.633 -48.054 -58.203 1.00 97.62 O
View on GitHub