정보
타마린드 스킬은 구조 예측, 단백질 설계, 도킹 모델을 포함한 타마린드 바이오의 오픈소스 분자 설계 도구 모음에 클라우드 API 접근을 제공합니다. 이 스킬을 통해 개발자는 REST API 또는 MCP 서버를 통해 로컬 GPU 자원 없이도 AlphaFold, RFdiffusion, DiffDock와 같은 도구를 실행할 수 있습니다. 프로그램 방식으로 서열 배치를 제출해 구조적 특성을 분석하거나 타마린드의 생물정보학 플랫폼을 활용해야 할 때 이 스킬을 사용하세요.
빠른 설치
Claude Code
추천npx skills add K-Dense-AI/claude-scientific-skills -a claude-code/plugin add https://github.com/K-Dense-AI/claude-scientific-skillsgit clone https://github.com/K-Dense-AI/claude-scientific-skills.git ~/.claude/skills/tamarindClaude Code에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요
문서
Tamarind Bio
Tamarind Bio is a cloud platform that runs computational biology tools — structure prediction, protein and antibody design, docking, binding-affinity, MSA generation, and molecular dynamics — on managed GPUs. Users submit sequences or structures and get back predicted structures, designs, and biophysical scores, without provisioning their own hardware. It exposes hundreds of tools (AlphaFold, Boltz-2, Chai-1, RFdiffusion, ProteinMPNN, BoltzGen, ESMFold2, DiffDock, Autodock Vina, and many more) through one uniform job API.
Official docs: app.tamarind.bio/api-docs · platform UI at app.tamarind.bio
Canonical sources — fetch these, don't rely on a stale copy
Tamarind publishes live, machine-readable sources. Prefer fetching them at runtime over trusting any hardcoded list — tool names, schemas, and endpoints change frequently:
https://app.tamarind.bio/llms.txt— LLM index: links to the spec, API docs, and MCP guide.https://app.tamarind.bio/openapi.yaml— OpenAPI 3.0 spec for the 8 core job endpoints (submit-job/-batch, jobs, result, upload, files, delete-job/-file; authApiKeyAuth). Fetch it for those exact shapes. Discovery/management endpoints (/tools,/usage-statistics, pipelines, …) aren't in it — use the MCP/REST discovery tools for those.https://docs.tamarind.bio/llms.txt— documentation index; every page has a.mdform (e.g.docs.tamarind.bio/tamarind/batch.md,/tamarind/api.md,/tamarind/pipelines.md).- Live tool discovery —
GET /tools(REST) or MCPgetAvailableTools+getJobSchema(jobType)are the source of truth for what tools exist and their parameters.
This skill teaches the surface + the non-obvious behaviors those sources don't spell out (see the reference files). When in doubt about a shape, fetch openapi.yaml.
When to use this skill
Use Tamarind when the user wants to:
- Predict structure of a protein, complex, or protein-ligand system (AlphaFold, Boltz-2, Chai-1, ESMFold2, Chai/Boltz cofolding)
- Design proteins or binders (RFdiffusion, BoltzGen, BindCraft, ProteinMPNN/LigandMPNN inverse folding)
- Design or characterize antibodies/nanobodies (sequence generation, humanization, developability, immunogenicity)
- Dock small molecules to a protein (DiffDock, Autodock Vina) or predict binding affinity
- Generate MSAs for downstream folding
- Run molecular dynamics or other biophysical workflows on managed GPUs
- Batch-screen many sequences or designs through the same tool
- Chain tools into pipelines (e.g. design → fold → score) using the output of one job as the input of the next
This skill is the right fit when the work should run on Tamarind's managed cloud rather than on a local install. For purely local cheminformatics or one-off sequence I/O, use a local library (RDKit, BioPython) instead.
Access and authentication
- Sign in at app.tamarind.bio and create an API key from the account/API settings.
- Authenticate every REST request with the
x-api-keyheader. - Never hardcode the key. Read it from the
TAMARIND_API_KEYenvironment variable or a.envfile (usepython-dotenv). Never commit keys to source control.
Pricing: Every user gets 10 free jobs. For larger usage, contact [email protected] to purchase a subscription.
export TAMARIND_API_KEY="your_api_key"
# List available tools
curl https://app.tamarind.bio/api/tools \
-H "x-api-key: $TAMARIND_API_KEY"
Base URL: https://app.tamarind.bio/api/
There is no official Python SDK — the PyPI package named tamarind is an unrelated Neo4j tool. Do not pip install tamarind. Write plain requests calls against the REST API (the endpoint shapes are in openapi.yaml), or use the MCP server for agent hosts.
Two ways to call Tamarind
MCP server (best for AI agents)
Tamarind hosts an MCP server at https://mcp.tamarind.bio/mcp (API-key auth via the X-API-Key header). When your agent host supports MCP, prefer it — the tools mirror the REST API with agent-friendly schemas:
listModalities()/listTags()— the live filter vocabulary (molecule type / function) with labels + tool counts; call these to learn validmodality/functionvalues instead of hardcodinggetAvailableTools(modality?, function?, search?, custom?)— discover tools (category/tagare deprecated aliases still honored)getJobSchema(jobType)— exact parameter schema for a tool, plus anexampleJobstarting payload (validate it before submitting)validateJob(jobName, type, settings)— dry-run validation before submittingsubmitJob(jobName, type, settings)/submitBatch(batchName, type, settings[], jobNames[])getJobs(jobName?, batch?, limit?, includeSequences?)— list/inspect jobs and statuses (the bulky per-job input blob is omitted by default; passincludeSequences=trueto keep it)getJobLogs(jobName)— fetch output logs for debugginglistJobFiles(jobName)— list output files (returnss3Pathfor chaining)getResult(jobName, fileName?)— download resultsuploadFile(filename)— presigned upload URL; oruploadFileContent(filename, content, encoding?)to send file content through MCP when the host can't reach S3 (sandboxed agents)
Scope note: MCP query tools (getJobs, getResult, listJobFiles, …) are scoped to the authenticated account.
REST API (universal)
Use plain HTTP with requests — the endpoint shapes are in openapi.yaml. The core loop is below; references/workflows.md has full recipes.
Core workflow
Always follow discover → schema → validate → submit → poll → results. Do not hardcode tool names or settings — the catalog changes frequently.
import os, time, requests
BASE = "https://app.tamarind.bio/api"
HEADERS = {"x-api-key": os.environ["TAMARIND_API_KEY"]}
# 1. Discover tools. REST /tools returns the full list; filter client-side.
tools = requests.get(f"{BASE}/tools", headers=HEADERS).json()
alphafold = next(t for t in tools if t["name"] == "alphafold")
# 2. Get the exact schema for the chosen tool.
# REST: each /tools entry already includes its inline `settings` schema
# (parameter list) — find the entry whose name == your job type.
# MCP: getJobSchema(jobType) returns the same per-tool detail.
# 3. Submit a job. `settings` is tool-specific — match the schema exactly.
payload = {
"jobName": "my-alphafold-run", # ^[a-zA-Z0-9_-]+$, <=100 chars, unique
"type": "alphafold",
"settings": {
"sequence": "MKTVRQERLKSIVRILERSKEPVSGAQLAEELSVSRQVIVQDIAYLRSLGYNIVATPRGYVLAGG",
"numRecycles": 3,
},
}
resp = requests.post(f"{BASE}/submit-job", headers=HEADERS, json=payload)
resp.raise_for_status() # 200 ok; 400 bad request; 403 budget exceeded; 401 unauthorized
# 4. Poll for completion.
# NOTE the response shape: GET /jobs?jobName=<name> returns the job ROW
# directly (no "jobs" wrapper); the list query (no jobName) returns
# {"jobs": [...]}. Don't index ["jobs"][0] on the by-name response.
while True:
job = requests.get(f"{BASE}/jobs", headers=HEADERS,
params={"jobName": "my-alphafold-run"}).json()
if job["JobStatus"] in ("Complete", "Stopped", "Deleted"):
break
time.sleep(30)
# 5. Retrieve results. POST /result returns a presigned URL *string*;
# GET that URL to download the actual results zip (two-step).
url = requests.post(f"{BASE}/result", headers=HEADERS,
json={"jobName": "my-alphafold-run"}).text.strip('"')
open("my-alphafold-run.zip", "wb").write(requests.get(url).content)
For the agentic version of this loop using MCP tools, and for richer examples, see references/workflows.md.
Discovering tools
The catalog has hundreds of tools. Always enumerate at runtime — never rely on a hardcoded list.
REST GET /tools returns the full list (it does not filter server-side); each item is {name, displayName, github, paper, description, settings} where settings is that tool's inline parameter schema. Filter client-side:
tools = requests.get(f"{BASE}/tools", headers=HEADERS).json() # a list
boltz = [t for t in tools if "boltz" in t["name"].lower()]
Note: both surfaces return one row per tool name — REST /tools and MCP getAvailableTools are both deduplicated (the MCP keeps the newest tool version), so a name match returns a single row.
MCP getAvailableTools(search=..., modality=..., function=...) filters server-side and adds categories/tags per tool (category/tag are deprecated aliases of modality/function, still honored). Don't hardcode the vocabulary — it drifts. Get the live values from listModalities() / listTags() (each returns value, label, description, and toolCount), or read the availableCategories / availableTags facet arrays returned on every getAvailableTools response. Modalities are molecule types (protein, antibody, peptide, small-molecule, nucleic-acid, …); functions are what a tool does (structure-prediction, binder-design, protein-ligand-docking, …).
A representative set of widely-used tools (verify with /tools): alphafold, boltz (Boltz-2), chai (Chai-1), esmfold / esmfold2, rfdiffusion, proteinmpnn, ligandmpnn, boltzgen, bindcraft, diffdock. See references/tool_catalog.md for the full category/tag map and how to read tool metadata.
Choosing the right tool
The catalog has many tools per task; don't hardcode a favorite — filter by function (and modality), then read each candidate's description and match it to the user's actual goal (input you have, output you need, constraints like speed or "no MSA"). The description and tags fields are the public "what it's for" signal; let them, plus validateJob, drive the pick. Quick orientation by task:
- Fold a single protein / complex (
function=structure-prediction): the AlphaFold3-class reproductions —boltz/chai/openfold/protenix/intfold— are the accurate default for everything, including protein-only systems; they also handle nucleic-acid + small-molecule complexes, so reach for them whenever a ligand/RNA/DNA is part of the system (andboltzadds binding-affinity).alphafold(AF2) remains a solid choice for monomers + multimers (join chains with:).esmfoldis single-sequence (no MSA) and fast — reach for it when you want speed and have no MSA;esmfold2is newer and conditions on an MSA by default (itsmodelsetting offers a faster single-sequence mode). Specialized folders exist for antibodies (abodybuilder,immunebuilder), cyclic peptides (highfold), and conformational ensembles (afcluster,alphaflow) — filter and read descriptions. - Design a binder (
function=binder-design):bindcraft(de novo miniprotein binders) andboltzgen(binders for protein and small-molecule targets, incl. nanobodies/antibodies/peptides) are the go-to de novo binder tools;rfdiffusionalso does binder design and is the pick for motif scaffolding / diversifying an existing backbone. Antibody-specific generators live underfunction=antibody-design. - Design sequence for a known backbone (
function=inverse-folding):proteinmpnn(general),ligandmpnn(ligand-aware), plus thermostable/soluble/antibody MPNN variants. Inverse folding takes a structure and emits sequences — fold them back to verify (see chaining). - Dock a small molecule (
function=protein-ligand-docking): preferboltz/chai— they co-fold the ligand into the complex and predict the bound structure rather than docking into a fixed receptor; reach forautodock-vinawhen you need fast, large-scale screening against a known pocket. - Predict binding affinity (
function=binding-affinity) or generate an MSA (searchmsa) — filter and read.
When the user names a specific tool, evaluate that one and sanity-check the alternatives in its tag group — a faster or more appropriate sibling often exists. When unsure, getJobSchema/validateJob to confirm a candidate actually accepts the input you have before committing.
Job settings, schemas, and validation
Each tool has its own settings schema. Fetch it before submitting:
- REST
/toolsentry: eachsettingsparam is a trimmed dict. Onlynameandrequiredare always present;type,default,description,optionsappear only when relevant (≈60% havetype) — so useparam.get("type"), notparam["type"]. The advanced gating keys (exclude,conditionals) are NOT in the REST response at all. - MCP
getJobSchema(jobType): the full schema, includingexclude,conditionals, and bounds. Use MCP when you need to reason about those gating keys. (restrictOrgsis stripped on both surfaces — an org-gated param you can't use is simply omitted; seereferences/api_reference.md.)
Always validateJob (MCP) before submitting — it's the reliable guard. It runs the same validation as /submit-job without submitting, and surfaces the first missing/invalid field. Don't try to hand-derive which fields to strip from the schema keys (over REST you can't see them anyway) — let validateJob tell you. (The response may include a source field, e.g. "static-fallback" — an internal note on which schema source validated; valid: true/false is the signal you act on.)
validateJob echoes a normalized view of your settings with defaults filled in. Submit the same clean settings you validated; treat normalized as informational (it can carry defaults you didn't set, and for some tools platform-managed fields), so build your submit from your own settings rather than the normalized blob.
Sequences: amino-acid string; separate chains of a multimer with a colon (:), e.g. "MVLS...:EVQL...". Note that some tools (e.g. boltz, chai) require more than sequence — boltz also requires inputFormat (and accepts yamlFile/molecules). Always getJobSchema/validateJob to learn a tool's required fields; don't assume sequence alone suffices.
Platform-internal fields — never set these yourself; the platform owns them: submit_method, monomer_msa, msa. See references/api_reference.md for the full field-handling rules.
Surface consequential choices before submitting, don't default silently. When the request fully specifies what to run, proceed. But when it's open-ended, or when a setting materially changes the results, runtime, or cost (model/variant, number of samples or seeds, MSA on/off, GPU tier, batch size), present the meaningful options plus the default you'd otherwise apply and let the user pick before you submit — rather than choosing silently and reporting it after the job is queued. getJobSchema and validateJob's normalized show exactly which knobs you're filling in on the user's behalf, so you can flag the few worth a quick confirm. This matters most for batches, where one shared-settings choice multiplies across every job.
File inputs (PDB, CIF, SDF, …)
Tools with file parameters accept input three ways:
- Upload first, then reference by bare filename.
PUT /upload/{filename}, or MCPuploadFile→ presigned URL →curl -X PUT -T file "<url>". If your host can't reach S3 (a sandboxed agent with no outbound network), use MCPuploadFileContent(filename, content, encoding?)to send the file's content through the MCP channel instead — text by default,encoding="base64"for binary. The object lands at the S3 key{email}/{filename}, but you reference it insettingsby the barefilenameonly (e.g."targetFile": "GLP1R_ECD.pdb") — the platform scopes it to your account automatically. Do NOT prefix the email: passing{email}/{filename}double-prefixes the lookup andsubmit-job400s with"The following files have not been uploaded: <email>/<file>". Confirm the exact name the store registered with MCPgetFiles(search=...)/ RESTGET /files(a flat list of bare names). - Reference a prior job's output by its path:
JobName/path/to/file.ext(this is how you chain jobs — see below). - Inline content. Send the file's text content directly as the field value.
Foot-gun: for a file-typed parameter, a plain string value is treated as inline file content, not as a path to an existing object. To point at an already-uploaded file, use the bare filename (not the {email}/... S3 key) or, for a prior job's output, the JobName/... path form — not a bare string you expect to resolve to new content.
validateJob notes. The response may carry a source field (e.g. "static-fallback") — it labels how the tool's schema was resolved (built-in tools always report static-fallback), not whether the validator was reachable, so act on valid, not source. For file params: reference an uploaded file by its bare filename (above) — a bare name resolves to your account-scoped object, whereas an email-prefixed string can be read as inline content and fail the file-type check ("... must contain ATOM records"). And passing inline file content makes validateJob upload it synchronously before validating, which can be slow; prefer referencing an uploaded file by name (above). If a dry-run is slow, skip it and let submit-job validate.
Chaining jobs into pipelines
A finished job's output becomes the next job's input — no download/re-upload. Match the input type the next tool actually wants: a sequence-design tool (ProteinMPNN) emits sequences, so you fold them by passing each as a sequence; a tool that takes a file parameter takes a path.
The cleanest design→fold chain is the MCP submitBatch(fromJob=...), which reads a completed design job's generated sequences and folds each as one job:
# ProteinMPNN designs sequences -> fold every one with AlphaFold, one call:
submitBatch(batchName="verify-designs", type="alphafold", fromJob="my-proteinmpnn-job")
For a file input (e.g. a tool that takes a .pdb/.cif), reference a prior job's output by the path form JobName/path/to/file.ext in that file parameter. Two cautions, both confirmed by validation: (1) match the parameter's required file type — e.g. AlphaFold's templateFiles accepts only .cif and is a list, and is gated behind templateMode: "custom"; (2) templateFiles is for structural templates, not for "fold this designed sequence" — to fold a sequence, pass sequence. Always getJobSchema/validateJob to confirm a file param's type/conditions before chaining into it.
To discover a job's exact output paths, use MCP listJobFiles(job1) — it returns each file's s3Path, usable directly in the next submitJob. (The REST GET /files lists your account's uploaded files as a flat name list; it does not enumerate a job's outputs.) Tamarind also supports saved pipelines: build one in the UI, then drive it with /run-pipeline ({pipelineName, initialInputs, inputs}) or define stages[] inline via /submit-pipeline (each stage names a task + toolSettings, using "pdbFile": "pipe" to thread one stage's output into the next). See references/workflows.md.
Batch submission
Submit many jobs of the same tool in one call. The Python form uses parallel settings[] and jobNames[] arrays (same length, up to 100):
requests.post(f"{BASE}/submit-batch", headers=HEADERS, json={
"batchName": "egfr-binder-screen",
"type": "alphafold",
"jobNames": ["seq1", "seq2", "seq3"],
"settings": [{"sequence": "..."}, {"sequence": "..."}, {"sequence": "..."}],
# optional: "maxRuntimeSeconds": 3600, "weightedHoursBudget": 100,
# (some accounts also accept an optional "gpuType" — confirm with support)
})
Poll the batch parent on batchStatus, not subjob JobStatus. A batch creates a parent job (Type: "batch") plus subjobs. Subjobs flip to Complete as soon as they finish computing, but the batch then spends a few minutes aggregating results into the final downloadable output. Fetch the parent by name and watch batchStatus:
import time
while True:
# ?jobName= returns the parent ROW directly (no "jobs" wrapper)
parent = requests.get(f"{BASE}/jobs", headers=HEADERS,
params={"jobName": "egfr-binder-screen"}).json()
bs = parent.get("batchStatus")
if bs == "Complete":
break
if bs in ("Stopped", "AggregationFailed"):
raise RuntimeError(parent.get("AggregationError", bs))
time.sleep(15) # Running / Aggregating -> keep waiting
# When Complete, the parent carries a presigned `resultUrl` and a `statuses`
# subjob tally ({Complete, Running, In Queue, Stopped}).
open("batch.zip", "wb").write(requests.get(parent["resultUrl"]).content)
Add includeSubjobs=true to GET /jobs?batch=<name> to list per-subjob rows.
Job status lifecycle
Single jobs report JobStatus; batch parents report batchStatus (poll that for batches — see above).
| Status | Meaning |
|---|---|
In Queue | Accepted, waiting for capacity |
Running | Executing on a worker |
Complete | Finished successfully — results available |
Stopped | Stopped (failure, timeout, manual stop, or budget) |
Deleted | Job was deleted out-of-band |
Aggregating | (batch parent only) subjobs done; building the final output |
AggregationFailed | (batch parent only) aggregation step failed |
Completed jobs carry a Score (tool-specific metrics, e.g. pLDDT/pTM/ipTM for folding) and WeightedHours. Treat Complete/Stopped/Deleted (and AggregationFailed for batches) as terminal; poll on a 15-30s interval. Break your poll loop on any terminal status, not just Complete/Stopped — a job that goes Deleted mid-poll would otherwise loop forever. For a Stopped job, fetch getJobLogs(jobName) to see why. WeightedHours is the usage unit billed per job; cap a batch with weightedHoursBudget, and a 403 on submit means a budget was hit (see references/api_reference.md and the /usage-statistics endpoint).
Error handling
| Code | Meaning | Action |
|---|---|---|
| 400 | Bad request / invalid settings | Re-check against the schema; run validateJob first |
| 401 | Unauthorized | Check x-api-key |
| 403 | Budget exceeded (org/team) | Lower scope or raise the budget |
| 429 | Rate limited | Back off and retry |
| 500 | Server error | Retry; if persistent, contact support |
Reference files
The openapi.yaml spec is the source of truth for endpoint shapes; these files add the behaviors and gotchas the spec doesn't spell out:
references/examples.md— validatedsettingspayloads per common tool (alphafold/boltz/diffdock/autodock-vina/proteinmpnn/batch), a copy-paste self-check, the "what fails and the exact error" list, and output-shape notes. Start here for a working payload.references/api_reference.md— endpoint quick-reference + the non-obvious shapes:/jobsby-name returns a bare row (not{jobs:[...]}),/resultis a two-step download, batch parents poll onbatchStatus,/filesis a flat name list, thesettingsfield-handling rules.references/tool_catalog.md— category/tag map, how to read tool + parameter metadata, common tool families.references/workflows.md— end-to-end recipes: fold a sequence, validate-before-submit, upload + reference a file, design→fold chaining, batch screen with aggregation polling, usage stats, pagination, and the non-blocking submit-now/check-later pattern for long jobs.
GitHub 저장소
Frequently asked questions
What is the tamarind skill?
tamarind is a Claude Skill by K-Dense-AI. Skills package instructions and resources that Claude loads on demand, so Claude can perform tamarind-related tasks without extra prompting.
How do I install tamarind?
Use the install commands on this page: add tamarind to Claude Code as a plugin, or clone its repository into your skills directory, then restart Claude so it picks up the skill.
What category does tamarind belong to?
tamarind is in the Meta category, tagged ai, api, mcp and design.
Is tamarind free to use?
Yes. tamarind is listed on AIMCP and free to install. It runs inside Claude, so no separate service account is required to use the skill itself.
연관 스킬
이 스킬은 콘텐츠 콜렉션(Content Collections)을 위한 프로덕션 검증된 설정을 제공합니다. 콘텐츠 콜렉션은 Markdown/MDX 파일을 Zod 검증이 포함된 타입 안전한 데이터 콜렉션으로 변환해주는 TypeScript 최우선 도구입니다. 블로그, 문서 사이트 또는 콘텐츠 중심의 Vite + React 애플리케이션을 구축할 때 타입 안전성과 자동 콘텐츠 검증을 보장하기 위해 사용하세요. Vite 플러그인 구성과 MDX 컴파일부터 배포 최적화 및 스키마 검증에 이르기까지 모든 것을 다룹니다.
이 스킬은 개발자들이 Polymarket 예측 시장 플랫폼을 활용한 애플리케이션을 구축할 수 있도록 지원하며, 거래 및 시장 데이터를 위한 API 통합 기능을 포함합니다. 또한 WebSocket을 통한 실시간 데이터 스트리밍을 제공하여 실시간 거래와 시장 활동을 모니터링할 수 있습니다. 이를 통해 거래 전략을 구현하거나 실시간 시장 업데이트를 처리하는 도구를 생성하는 데 활용할 수 있습니다.
이 스킬은 개발자들이 명령어, 파일, LSP 작업 등 25개 이상의 이벤트 유형에 연결되는 OpenCode 플러그인을 만들 수 있도록 돕습니다. JavaScript/TypeScript 모듈을 위한 플러그인 구조, 이벤트 API 명세, 구현 패턴을 제공합니다. OpenCode AI 어시스턴트의 라이프사이클을 사용자 정의 이벤트 기반 로직으로 가로채거나, 모니터링하거나, 확장해야 할 때 사용하세요.
SGLang은 RadixAttention 프리픽스 캐싱을 활용하여 JSON, 정규식, 에이전트 워크플로우를 위한 고속 구조화 생성에 특화된 고성능 LLM 서빙 프레임워크입니다. 특히 반복되는 프리픽스가 있는 작업에서 상당히 빠른 추론 속도를 제공하여 복잡한 구조화 출력 및 다중 턴 대화에 이상적입니다. 제약 디코딩이 필요하거나 광범위한 프리픽스 공유가 있는 애플리케이션을 구축할 때는 vLLM과 같은 대안보다 SGLang을 선택하십시오.
