# Tamarind Bio

Tamarind runs 300+ computational biology tools behind one uniform job API: protein
structure prediction, protein/antibody/peptide/binder design, protein-ligand and
protein-protein docking, binding affinity, MSA generation and molecular dynamics. You
submit a job, poll it, and download results — the same shape for every tool, whether it is
AlphaFold or a Rosetta protocol.

Get started at [/app](/app), or read [/SKILL.md](/SKILL.md) if you are an AI agent.

**Resolve every link below against the host that served this file.** They are
root-relative on purpose. Most callers are on `https://app.tamarind.bio`, but an
organisation with a dedicated deployment (e.g. `https://acme.tamarind.bio`) has its own
jobs, files and **API keys** on that host — a key minted on the shared app does not work
there, and a job sent to `app.tamarind.bio` from a tenant account **succeeds** and lands
where that user will never see it.

## What you can run

Every tool is one `type` string against the same endpoint. These are intent tags, not
products — narrow the catalog with `/tools.json?tag=<tag>`.

- [Structure prediction](/tools.json?tag=structure-prediction): fold a sequence, or predict a complex — AlphaFold, Boltz, Chai, ESMFold, Protenix.
- [De novo binder design](/tools.json?tag=binder-design): design a binder against a target structure — RFdiffusion, BindCraft, BoltzGen.
- [Antibody design](/tools.json?tag=antibody-design): design or optimise antibodies and nanobodies — RFantibody, NbForge, germline and CDR tools.
- [Protein-ligand docking](/tools.json?tag=protein-ligand-docking): dock a small molecule into a receptor, with or without a known pocket.
- [Protein-protein docking](/tools.json?tag=protein-protein-docking): dock two chains and score the interface.
- [Binding affinity](/tools.json?tag=binding-affinity): predict binding strength for a complex, and rank designs by it.
- [Inverse folding](/tools.json?tag=inverse-folding): design a sequence for a given backbone — ProteinMPNN, LigandMPNN.
- [Developability](/tools.json?tag=developability): stability, solubility, aggregation, humanness, immunogenicity.
- [Molecular dynamics](/tools.json?tag=molecular-dynamics), [enzyme design](/tools.json?tag=enzyme-design), [RNA design](/tools.json?tag=rna-design), [small molecules](/tools.json?tag=generate-small-mols), and more — the full tag list ships in every `/tools.json` response.

## Developer tools

- [Agent skill](/SKILL.md): setup and task instructions for AI agents — install, authenticate, find a tool, validate, submit, download, plus the contract rules that break generated code. **Start here if you are an agent.**
- [Tool catalog, no API key required](/tools.json): every submittable `type` with its description, intent tags and REQUIRED settings. Generated live from the tool registry, so it cannot go stale. Also as [a table](/tools.md).
- [MCP server](https://mcp.tamarind.bio/mcp): hosted Model Context Protocol server (streamable HTTP; OAuth 2.1 or `x-api-key`). Prefer this over raw HTTP when your client speaks MCP. [Setup](/api-docs/mcp-server).
- [CLI](/api-docs/cli): `uv tool install tamarind-cli`. Emits JSON when stdout is not a TTY.
- [Full API guide for LLMs](/llms-full.txt): the complete REST reference — auth, discovery, submit/poll/download, file handling, every contract detail.
- [OpenAPI specification](/api/openapi.json) · [Interactive API docs](/api-docs) · [Get an API key](/api-docs/api-key)

## Setup for agents

```text
Step 1: Set up Tamarind

Read /SKILL.md on the host that served this file and follow its setup instructions: get a
TAMARIND_API_KEY configured and verify it against the API before writing any other code.
A key cannot be minted programmatically — a human creates one in the web app at
/api-docs/api-key. If no key is present, stop and ask for one; name the env var rather
than guessing at auth.

Step 2: Ask the user

Would you like to:
a) Run one job now from the terminal (no project)
b) Integrate Tamarind into an existing codebase
c) Start a fresh script or project
d) Add Tamarind as MCP tools in this agent or another MCP client

Step 3: Set up the chosen path

Before any of them: find the tool. GET /tools.json needs no API key and lists every
submittable `type` with its REQUIRED settings. Narrow it with ?tag= or ?type= instead of
pulling the whole ~160KB document. Tool names are exact, case-sensitive, and are NOT the
display name: "Boltz-2" is a label, `boltz` is the type. Never invent a `type` or a
settings key — an unrecognised settings key is not rejected and not dropped, it is carried
through, so a synonym (`seq`, `protein_file`) resurfaces later as "missing required field"
pointing at the field you thought you had set.

If the answer to Step 2 is (a) - Terminal only:

Install the CLI: uv tool install tamarind-cli (requires Python 3.10+; pipx install
tamarind-cli also works). Set TAMARIND_API_KEY in the environment, or run tamarind auth
login to store it in ~/.tamarind/config.json.
Then: tamarind tools --search <keyword>, tamarind validate <type> --input job.yaml, and
tamarind submit <type> --input job.yaml --name my-run --wait --download ./out

If the answer to Step 2 is (b) - Existing codebase:

Read the codebase first to learn its language, package manager, HTTP client, and how
secrets are handled (.env, config, secret manager). Match those conventions.

THERE IS NO OFFICIAL SDK. Do not install the PyPI package `tamarind` or the npm package
`tamarind` — they are unrelated third-party projects. Two supported options:
  - Call the REST API with the language's own HTTP client (four endpoints: submit, poll,
    result, upload). This is usually right for a codebase.
  - Shell out to the CLI (`tamarind --json ...`), which prints JSON when stdout is not a
    TTY. Reasonable for scripts and CI.

Ask the user what Tamarind should do in their project (fold sequences, design binders,
dock ligands, score or rank designs), then write the integration against /llms-full.txt.

If the answer to Step 2 is (c) - Fresh script or project:

Ask which language. Scaffold a minimal project, read TAMARIND_API_KEY from the process
environment (load .env explicitly if you use one — python-dotenv, or node --env-file=.env),
and write a first script from the SKILL.md quickstart: pick a tool from /tools.json,
validate the payload, submit it, poll until the status is terminal (Complete, Stopped,
Failed or Deleted — not Complete alone, or the script hangs on every run that fails),
then download the result on Complete and read the logs otherwise.

If the answer to Step 2 is (d) - MCP tools:

Follow the SKILL.md "MCP Server" section. The hosted server is
https://mcp.tamarind.bio/mcp (streamable HTTP; OAuth 2.1, or an x-api-key header).
For Claude Code: claude mcp add -s user --transport http tamarind https://mcp.tamarind.bio/mcp
Restart the client, confirm the Tamarind tools appear (getAvailableTools, getJobSchema,
validateJob, submitJob, getJobs, getResult, ...), then verify by calling getAvailableTools.

Step 4: Verify

Run these three, in order, before building anything on top:
  1. curl -s "$TAMARIND_HOST/tools.json?type=alphafold"   -> works with NO key. If this
     fails, it is a network or host problem, not an auth problem.
  2. curl -s "$TAMARIND_HOST/api/jobs" -H "x-api-key: $TAMARIND_API_KEY"   -> your job
     list. If (1) worked and (2) did not, you have a key problem.
  3. POST /api/validate-job with a real payload -> {valid, normalized, missing_fields}.
     It is free. Submit the `normalized` object verbatim; it has defaults filled in.

Then submit one real job and confirm it reaches Complete before writing a pipeline.

If something fails, diagnose it. The failures that mislead:

- A missing or wrong API key is HTTP 400 on the job/file endpoints, NOT 401. So is an
  unknown job name (400, not 404). Branch on "not 2xx", not on a specific code. A few
  older routes (/api/models, /api/finetuned-models, /api/usage-statistics) do answer 401.
- validate-job answers 200 even when the payload is invalid. Branch on the `valid` field,
  not on the status code.
- jobName is NORMALIZED, not validated: every character outside [A-Za-z0-9_.-] is stripped
  and whitespace becomes _, with no length check and no rejection. "my run!" is accepted
  and stored as my_run, and polling for "my run!" then reports an unknown job. Send a name
  that is already clean and poll with exactly what you sent.
- Every REST route lives under /api/. POST /submit-job without the prefix is a 404.
- A file-typed setting takes the bare filename of something you already uploaded, not a
  local path and not the file's contents. Upload first (PUT /api/upload/<name>), then pass
  "<name>". Chain a previous job's output as "<JobName>/<file>".
- Treat `Complete`, `Stopped`, `Failed` and `Deleted` as terminal and stop polling on any of
  them. But don't wait for `Failed` as the sign something broke — a classic job that went
  wrong is usually `Stopped`, or `Complete` with no useful output, so check the logs.
- Work submitted from a dedicated-deployment account to app.tamarind.bio succeeds and
  disappears. Use the org's own host for both the key and the request.
```

## More

- [Agent skill](/SKILL.md)
- [LLM documentation index](/llms.txt)
- [Full API guide for LLMs](/llms-full.txt)
- [Tool catalog, no API key required](/tools.json)
- [MCP capabilities catalog](/.well-known/ai-catalog.json)
- [Product documentation](https://docs.tamarind.bio) — every page is also Markdown, by appending `.md`
- Contact: info@tamarind.bio
