{"slug":"alterlab-cbioportal","title":"alterlab-cbioportal","summary":"Query cBioPortal via its keyless REST API for cancer genomics across TCGA, GENIE, MSK-IMPACT and hundreds of studies — somatic mutations, copy-number alterations (GISTIC), mRNA/protein expression, structural variants, and patient-level clinical/survival data. Use when asked how o","platform":"Claude","tags":[],"authorName":"LLM Mart","authorSlug":"llm-mart","score":0,"source":"github","price":null,"verified":false,"createdAt":"2026-09-23T18:57:08.467672Z","repo":{"url":"https://github.com/AlterLab-IEU/AlterLab-Academic-Skills","stars":68,"forks":13,"license":"MIT","updatedAt":"2026-09-23T13:42:59Z"},"bodyHtml":"<hr>\n<h2>name: alterlab-cbioportal\ndescription: Query cBioPortal via its keyless REST API for cancer genomics across TCGA, GENIE, MSK-IMPACT and hundreds of studies — somatic mutations, copy-number alterations (GISTIC), mRNA/protein expression, structural variants, and patient-level clinical/survival data. Use when asked how often a gene is mutated/amplified/deleted in a tumor type, to profile oncogenes or tumor suppressors across cancers (pan-cancer alteration frequency), to pull patient-level mutations joined to OS/clinical outcomes, or to validate a cancer target from cohort genomics. For germline variant pathogenicity use alterlab-clinvar; for mutational-signature (SBS) decomposition use alterlab-cosmic; for CRISPR/RNAi gene-dependency use alterlab-depmap; for aggregated target-disease evidence use alterlab-opentargets. Part of the AlterLab Academic Skills suite.\nlicense: LGPL-3.0\nallowed-tools: Read WebFetch Bash(curl:<em>) Bash(python:</em>)\ncompatibility: Keyless cBioPortal REST API for public data (no authentication required)\nmetadata:\nskill-author: AlterLab\nversion: \"1.1.0\"\nlast_updated: \"2026-09-23\"</h2>\n<h1>cBioPortal Database</h1>\n<h2>Overview</h2>\n<p>cBioPortal for Cancer Genomics (<a href=\"https://www.cbioportal.org/\">https://www.cbioportal.org/</a>) is an open-access resource for exploring, visualizing, and analyzing multidimensional cancer genomics data. It hosts data from The Cancer Genome Atlas (TCGA), AACR Project GENIE, MSK-IMPACT, and hundreds of other cancer studies — covering mutations, copy number alterations (CNA), structural variants, mRNA/protein expression, methylation, and clinical data for thousands of cancer samples.</p>\n<p><strong>Key resources:</strong></p>\n<ul>\n<li>cBioPortal website: <a href=\"https://www.cbioportal.org/\">https://www.cbioportal.org/</a></li>\n<li>REST API: <a href=\"https://www.cbioportal.org/api/swagger-ui/index.html\">https://www.cbioportal.org/api/swagger-ui/index.html</a></li>\n<li>API docs (Swagger): <a href=\"https://www.cbioportal.org/api/swagger-ui/index.html\">https://www.cbioportal.org/api/swagger-ui/index.html</a></li>\n<li>Python client: <code>bravado</code> or <code>requests</code></li>\n<li>GitHub: <a href=\"https://github.com/cBioPortal/cbioportal\">https://github.com/cBioPortal/cbioportal</a></li>\n</ul>\n<h2>When to Use This Skill</h2>\n<p>Use cBioPortal when:</p>\n<ul>\n<li><strong>Mutation landscape</strong>: What fraction of a cancer type has mutations in a specific gene?</li>\n<li><strong>Oncogene/TSG validation</strong>: Is a gene frequently mutated, amplified, or deleted in cancer?</li>\n<li><strong>Co-mutation patterns</strong>: Are mutations in gene A and gene B mutually exclusive or co-occurring?</li>\n<li><strong>Survival analysis</strong>: Do mutations in a gene associate with better or worse patient outcomes?</li>\n<li><strong>Alteration profiles</strong>: What types of alterations (missense, truncating, amplification, deletion) affect a gene?</li>\n<li><strong>Pan-cancer analysis</strong>: Compare alteration frequencies across cancer types</li>\n<li><strong>Clinical associations</strong>: Link genomic alterations to clinical variables (stage, grade, treatment response)</li>\n<li><strong>TCGA/GENIE exploration</strong>: Systematic access to TCGA and clinical sequencing datasets</li>\n</ul>\n<h3>Does NOT Trigger</h3>\n<table>\n<thead>\n<tr>\n<th>Scenario</th>\n<th>Use Instead</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Germline variant pathogenicity / clinical significance</td>\n<td><code>alterlab-clinvar</code></td>\n</tr>\n<tr>\n<td>COSMIC Cancer Gene Census, mutational signatures (SBS), curated somatic catalog</td>\n<td><code>alterlab-cosmic</code></td>\n</tr>\n<tr>\n<td>CRISPR/RNAi gene-dependency (essentiality) in cancer cell lines</td>\n<td><code>alterlab-depmap</code></td>\n</tr>\n<tr>\n<td>Aggregated target–disease association evidence and tractability</td>\n<td><code>alterlab-opentargets</code></td>\n</tr>\n</tbody>\n</table>\n<h2>Core Capabilities</h2>\n<h3>1. cBioPortal REST API</h3>\n<p>Base URL: <code>https://www.cbioportal.org/api</code></p>\n<p>The API is RESTful, returns JSON, and requires no API key for public data.</p>\n<pre><code>import requests\n\nBASE_URL = \"https://www.cbioportal.org/api\"\nHEADERS = {\"Accept\": \"application/json\", \"Content-Type\": \"application/json\"}\n\ndef cbioportal_get(endpoint, params=None):\n    url = f\"{BASE_URL}/{endpoint}\"\n    response = requests.get(url, params=params, headers=HEADERS)\n    response.raise_for_status()\n    return response.json()\n\ndef cbioportal_post(endpoint, body):\n    url = f\"{BASE_URL}/{endpoint}\"\n    response = requests.post(url, json=body, headers=HEADERS)\n    response.raise_for_status()\n    return response.json()\n</code></pre>\n<h3>2. Browse Studies</h3>\n<pre><code>def get_all_studies():\n    \"\"\"List all available cancer studies.\n\n    The public portal hosts 540+ studies (2026-09), so a pageSize of 500 would\n    silently truncate the list; ask for more than you expect.\n    \"\"\"\n    return cbioportal_get(\"studies\", {\"pageSize\": 100000})\n\n# Each study has:\n# studyId: unique identifier (e.g., \"brca_tcga\")\n# name: human-readable name\n# description: dataset description\n# cancerTypeId: cancer type abbreviation\n# referenceGenome: hg19 or hg38\n# allSampleCount: samples in the study\n# (pass projection=DETAILED to also get pmid, citation, sequencedSampleCount, ...)\n\nstudies = get_all_studies()\nprint(f\"Total studies: {len(studies)}\")\n\n# Common TCGA study IDs — each cancer has several versions:\n#   *_tcga                     original TCGA Firehose Legacy (e.g. brca_tcga)\n#   *_tcga_pan_can_atlas_2018  harmonized PanCancer Atlas (preferred for pan-cancer work)\n#   *_tcga_gdc                 GDC re-processed data\n# e.g. brca_tcga, luad_tcga, coadread_tcga, gbm_tcga, prad_tcga, skcm_tcga\n\n# Filter for TCGA studies\ntcga_studies = [s for s in studies if \"tcga\" in s[\"studyId\"]]\nprint([s[\"studyId\"] for s in tcga_studies[:10]])\n</code></pre>\n<h3>3. Molecular Profiles</h3>\n<p>Each study has multiple molecular profiles (mutation, CNA, expression, etc.):</p>\n<pre><code>def get_molecular_profiles(study_id):\n    \"\"\"Get all molecular profiles for a study.\"\"\"\n    return cbioportal_get(f\"studies/{study_id}/molecular-profiles\")\n\nprofiles = get_molecular_profiles(\"brca_tcga\")\nfor p in profiles:\n    print(f\"  {p['molecularProfileId']}: {p['name']} ({p['molecularAlterationType']})\")\n\n# Alteration types:\n# MUTATION_EXTENDED — somatic mutations\n# COPY_NUMBER_ALTERATION — CNA (GISTIC)\n# MRNA_EXPRESSION — mRNA expression\n# PROTEIN_LEVEL — RPPA protein expression\n# STRUCTURAL_VARIANT — fusions/rearrangements\n</code></pre>\n<h3>4. Mutation Data</h3>\n<pre><code>def get_mutations(molecular_profile_id, entrez_gene_ids, sample_list_id=None):\n    \"\"\"Get mutations for specified genes in a molecular profile.\"\"\"\n    body = {\n        \"entrezGeneIds\": entrez_gene_ids,\n        \"sampleListId\": sample_list_id or molecular_profile_id.replace(\"_mutations\", \"_all\")\n    }\n    return cbioportal_post(\n        f\"molecular-profiles/{molecular_profile_id}/mutations/fetch\",\n        body\n    )\n\n# BRCA1 Entrez ID is 672, TP53 is 7157, PTEN is 5728\nmutations = get_mutations(\"brca_tcga_mutations\", entrez_gene_ids=[7157])  # TP53\n\n# Each mutation record contains:\n# patientId, sampleId, entrezGeneId (the nested gene.hugoGeneSymbol only\n#   appears with ?projection=DETAILED on the fetch URL)\n# mutationType (Missense_Mutation, Nonsense_Mutation, Frame_Shift_Del, etc.)\n# proteinChange (e.g., \"R175H\"), variantType\n# ncbiBuild, chr, startPosition, endPosition, referenceAllele, variantAllele\n# mutationStatus (Somatic/Germline)\n# tumorAltCount, tumorRefCount (read counts — there is no VAF field; derive it)\n\nimport pandas as pd\ndf = pd.DataFrame(mutations)\ndf[\"vaf\"] = df[\"tumorAltCount\"] / (df[\"tumorAltCount\"] + df[\"tumorRefCount\"])\nprint(df[[\"patientId\", \"mutationType\", \"proteinChange\", \"vaf\"]].head())\nprint(f\"\\nMutation types:\\n{df['mutationType'].value_counts()}\")\n</code></pre>\n<h3>5. Copy Number Alteration Data</h3>\n<pre><code>def get_cna(molecular_profile_id, entrez_gene_ids):\n    \"\"\"Get discrete CNA data (GISTIC: -2, -1, 0, 1, 2).\"\"\"\n    body = {\n        \"entrezGeneIds\": entrez_gene_ids,\n        \"sampleListId\": molecular_profile_id.replace(\"_gistic\", \"_all\").replace(\"_cna\", \"_all\")\n    }\n    return cbioportal_post(\n        f\"molecular-profiles/{molecular_profile_id}/discrete-copy-number/fetch\",\n        body\n    )\n\n# GISTIC values:\n# -2 = Deep deletion (homozygous loss)\n# -1 = Shallow deletion (heterozygous loss)\n#  0 = Diploid (neutral)\n#  1 = Low-level gain\n#  2 = High-level amplification\n\ncna_data = get_cna(\"brca_tcga_gistic\", entrez_gene_ids=[1956])  # EGFR\ndf_cna = pd.DataFrame(cna_data)\nprint(df_cna[\"value\"].value_counts())\n</code></pre>\n<h3>6. Alteration Frequency (OncoPrint-style)</h3>\n<pre><code>def get_alteration_frequency(study_id, gene_symbols, alteration_types=None):\n    \"\"\"Compute alteration frequencies for genes across a cancer study.\"\"\"\n    import requests, pandas as pd\n\n    # Denominator = samples profiled for mutations (cBioPortal's own convention).\n    # 'all_cases_in_study' also counts unsequenced samples and deflates the\n    # frequency (brca_tcga: 1,108 samples in study vs 982 sequenced).\n    samples = requests.get(\n        f\"{BASE_URL}/studies/{study_id}/sample-lists\",\n        headers=HEADERS\n    ).json()\n    by_category = {s[\"category\"]: s[\"sampleListId\"] for s in samples}\n    sample_list_id = (by_category.get(\"all_cases_with_mutation_data\")\n                      or by_category.get(\"all_cases_in_study\"))\n    total_samples = len(requests.get(\n        f\"{BASE_URL}/sample-lists/{sample_list_id}/sample-ids\",\n        headers=HEADERS\n    ).json())\n\n    # Get gene Entrez IDs. /genes/fetch takes a plain JSON array of identifiers\n    # plus a geneIdType query param; symbols WITHOUT the param resolve to [].\n    gene_data = requests.post(\n        f\"{BASE_URL}/genes/fetch\",\n        params={\"geneIdType\": \"HUGO_GENE_SYMBOL\"},\n        json=gene_symbols,\n        headers=HEADERS\n    ).json()\n    # Response order is not guaranteed; map by symbol.\n    entrez_by_symbol = {g[\"hugoGeneSymbol\"]: g[\"entrezGeneId\"] for g in gene_data}\n    entrez_ids = [entrez_by_symbol[g] for g in gene_symbols if g in entrez_by_symbol]\n\n    # Get mutations\n    mutation_profile = f\"{study_id}_mutations\"\n    mutations = get_mutations(mutation_profile, entrez_ids, sample_list_id)\n\n    freq = {}\n    for g_symbol, e_id in entrez_by_symbol.items():\n        # Count samples (not patients) so numerator and denominator match.\n        mutated = len(set(m[\"sampleId\"] for m in mutations if m[\"entrezGeneId\"] == e_id))\n        freq[g_symbol] = mutated / total_samples * 100\n\n    return freq\n\n# Example\nfreq = get_alteration_frequency(\"brca_tcga\", [\"TP53\", \"PIK3CA\", \"BRCA1\", \"BRCA2\"])\nfor gene, pct in sorted(freq.items(), key=lambda x: -x[1]):\n    print(f\"  {gene}: {pct:.1f}%\")\n</code></pre>\n<h3>7. Clinical Data</h3>\n<p>The global <code>/clinical-data/fetch</code> endpoint is <strong>POST-only</strong> (a GET returns HTTP 405).\nThe simplest path for one study is the per-study GET endpoint, which returns a list\nof <code>{patientId, studyId, clinicalAttributeId, value}</code> records:</p>\n<pre><code>def get_patient_clinical_data(study_id, attribute_ids):\n    \"\"\"Patient-level clinical data via the per-study GET endpoint.\n\n    GET /studies/{studyId}/clinical-data?clinicalDataType=PATIENT&amp;attributeId=...\n    accepts a single attributeId, so we query each and concatenate.\n    \"\"\"\n    records = []\n    for attr in attribute_ids:\n        records += cbioportal_get(\n            f\"studies/{study_id}/clinical-data\",\n            {\"clinicalDataType\": \"PATIENT\", \"attributeId\": attr, \"pageSize\": 100000},\n        )\n    return records\n\n# Clinical attributes include:\n# OS_STATUS, OS_MONTHS, DFS_STATUS, DFS_MONTHS (survival)\n# AJCC_PATHOLOGIC_TUMOR_STAGE, GRADE, AGE, SEX, RACE\n# Study-specific attributes vary — list them with get_clinical_attributes().\n# GOTCHA: OS_STATUS / DFS_STATUS are encoded \"1:DECEASED\" / \"0:LIVING\"\n# (event:label), not bare 0/1 — split on \":\" before survival analysis.\n\ndef get_clinical_attributes(study_id):\n    \"\"\"List all available clinical attributes for a study.\"\"\"\n    return cbioportal_get(f\"studies/{study_id}/clinical-attributes\")\n</code></pre>\n<h2>Query Workflows</h2>\n<h3>Workflow 1: Gene Alteration Profile in a Cancer Type</h3>\n<pre><code>import requests, pandas as pd\n\ndef alteration_profile(study_id, gene_symbol):\n    \"\"\"Full alteration profile for a gene in a cancer study.\"\"\"\n\n    # 1. Get gene Entrez ID (plain array body + geneIdType param)\n    gene_info = requests.post(\n        f\"{BASE_URL}/genes/fetch\",\n        params={\"geneIdType\": \"HUGO_GENE_SYMBOL\"},\n        json=[gene_symbol],\n        headers=HEADERS\n    ).json()[0]\n    entrez_id = gene_info[\"entrezGeneId\"]\n\n    # 2. Get mutations\n    mutations = get_mutations(f\"{study_id}_mutations\", [entrez_id])\n    mut_df = pd.DataFrame(mutations) if mutations else pd.DataFrame()\n\n    # 3. Get CNAs\n    cna = get_cna(f\"{study_id}_gistic\", [entrez_id])\n    cna_df = pd.DataFrame(cna) if cna else pd.DataFrame()\n\n    # 4. Summary\n    n_mut = len(set(mut_df[\"patientId\"])) if not mut_df.empty else 0\n    n_amp = len(cna_df[cna_df[\"value\"] == 2]) if not cna_df.empty else 0\n    n_del = len(cna_df[cna_df[\"value\"] == -2]) if not cna_df.empty else 0\n\n    return {\"mutations\": n_mut, \"amplifications\": n_amp, \"deep_deletions\": n_del}\n\nresult = alteration_profile(\"brca_tcga\", \"PIK3CA\")\nprint(result)\n</code></pre>\n<h3>Workflow 2: Pan-Cancer Gene Mutation Frequency</h3>\n<pre><code>import requests, pandas as pd\n\ndef pan_cancer_mutation_freq(gene_symbol, cancer_study_ids=None):\n    \"\"\"Mutation frequency of a gene across multiple cancer types.\"\"\"\n    studies = get_all_studies()\n    if cancer_study_ids:\n        studies = [s for s in studies if s[\"studyId\"] in cancer_study_ids]\n\n    results = []\n    for study in studies[:20]:  # Limit for demo\n        try:\n            freq = get_alteration_frequency(study[\"studyId\"], [gene_symbol])\n            results.append({\n                \"study\": study[\"studyId\"],\n                \"cancer\": study.get(\"cancerTypeId\", \"\"),\n                \"mutation_pct\": freq.get(gene_symbol, 0)\n            })\n        except Exception:\n            pass\n\n    df = pd.DataFrame(results).sort_values(\"mutation_pct\", ascending=False)\n    return df\n</code></pre>\n<h3>Workflow 3: Survival Analysis by Mutation Status</h3>\n<pre><code>import requests, pandas as pd\n\ndef survival_by_mutation(study_id, gene_symbol):\n    \"\"\"Get survival data split by mutation status.\"\"\"\n    # This workflow fetches clinical and mutation data for downstream analysis\n\n    gene_info = requests.post(\n        f\"{BASE_URL}/genes/fetch\",\n        params={\"geneIdType\": \"HUGO_GENE_SYMBOL\"},\n        json=[gene_symbol],\n        headers=HEADERS\n    ).json()[0]\n    entrez_id = gene_info[\"entrezGeneId\"]\n\n    mutations = get_mutations(f\"{study_id}_mutations\", [entrez_id])\n    mutated_patients = set(m[\"patientId\"] for m in mutations)\n\n    # Patient-level survival via the per-study GET endpoint (clinical-data/fetch\n    # is POST-only — a GET there returns HTTP 405).\n    clinical = get_patient_clinical_data(study_id, [\"OS_MONTHS\", \"OS_STATUS\"])\n    clinical_df = pd.DataFrame(clinical)\n\n    os_wide = clinical_df.pivot(index=\"patientId\", columns=\"clinicalAttributeId\", values=\"value\")\n    # OS_STATUS is encoded as \"1:DECEASED\" / \"0:LIVING\"; split off the 0/1 event flag.\n    if \"OS_STATUS\" in os_wide:\n        os_wide[\"OS_EVENT\"] = os_wide[\"OS_STATUS\"].str.startswith(\"1\").astype(\"Int64\")\n    os_wide[\"OS_MONTHS\"] = pd.to_numeric(os_wide.get(\"OS_MONTHS\"), errors=\"coerce\")\n    os_wide[\"mutated\"] = os_wide.index.isin(mutated_patients)\n\n    return os_wide\n</code></pre>\n<h2>Key API Endpoints Summary</h2>\n<table>\n<thead>\n<tr>\n<th>Endpoint</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>GET /studies</code></td>\n<td>List all studies</td>\n</tr>\n<tr>\n<td><code>GET /studies/{studyId}/molecular-profiles</code></td>\n<td>Molecular profiles for a study</td>\n</tr>\n<tr>\n<td><code>POST /molecular-profiles/{profileId}/mutations/fetch</code></td>\n<td>Get mutation data</td>\n</tr>\n<tr>\n<td><code>POST /molecular-profiles/{profileId}/discrete-copy-number/fetch</code></td>\n<td>Get CNA data</td>\n</tr>\n<tr>\n<td><code>POST /molecular-profiles/{profileId}/molecular-data/fetch</code></td>\n<td>Get expression data</td>\n</tr>\n<tr>\n<td><code>GET /studies/{studyId}/clinical-attributes</code></td>\n<td>Available clinical variables</td>\n</tr>\n<tr>\n<td><code>GET /studies/{studyId}/clinical-data</code></td>\n<td>Clinical data for one study (one <code>attributeId</code> per call)</td>\n</tr>\n<tr>\n<td><code>POST /clinical-data/fetch?clinicalDataType=PATIENT</code></td>\n<td>Clinical data across studies (POST-only; GET → 405)</td>\n</tr>\n<tr>\n<td><code>POST /genes/fetch?geneIdType=HUGO_GENE_SYMBOL</code></td>\n<td>Resolve symbols → Entrez IDs (body is a plain JSON array, e.g. <code>[\"TP53\"]</code>)</td>\n</tr>\n<tr>\n<td><code>GET /studies/{studyId}/sample-lists</code></td>\n<td>Sample lists</td>\n</tr>\n</tbody>\n</table>\n<h2>Best Practices</h2>\n<ul>\n<li><strong>Know your study IDs</strong>: Use the Swagger UI or <code>GET /studies</code> to find the correct study ID</li>\n<li><strong>Use sample lists</strong>: Each study has an <code>all</code> sample list and subsets; always specify the appropriate one</li>\n<li><strong>TCGA vs. GENIE</strong>: TCGA data is comprehensive but older; GENIE has more recent clinical sequencing data, but its consortium releases live on the separate <a href=\"https://genie.cbioportal.org\">https://genie.cbioportal.org</a> portal (login required), not on the keyless public API</li>\n<li><strong>Entrez gene IDs</strong>: The API uses Entrez IDs — convert from symbols with <code>POST /genes/fetch?geneIdType=HUGO_GENE_SYMBOL</code>. The body must be a <strong>plain JSON array</strong> (<code>[\"TP53\",\"KRAS\"]</code>); the object form <code>[{\"hugoGeneSymbol\":...}]</code> returns HTTP 400, and omitting <code>geneIdType</code> silently returns <code>[]</code> for symbols. Response order is not guaranteed — map results back by <code>hugoGeneSymbol</code>.</li>\n<li><strong>Handle 404s</strong>: Some molecular profiles may not exist for all studies</li>\n<li><strong>Rate limiting</strong>: Add delays for bulk queries; consider downloading data files for large-scale analyses</li>\n</ul>\n<h2>Data Downloads</h2>\n<p>For large-scale analyses, download study data directly (the older\n<code>cbioportal-datahub.s3.amazonaws.com</code> links now return 403):</p>\n<pre><code># Download TCGA BRCA (PanCancer Atlas) data\nwget https://datahub.assets.cbioportal.org/brca_tcga_pan_can_atlas_2018.tar.gz\n</code></pre>\n<h2>Additional Resources</h2>\n<ul>\n<li><strong>cBioPortal website</strong>: <a href=\"https://www.cbioportal.org/\">https://www.cbioportal.org/</a></li>\n<li><strong>API Swagger UI</strong>: <a href=\"https://www.cbioportal.org/api/swagger-ui/index.html\">https://www.cbioportal.org/api/swagger-ui/index.html</a></li>\n<li><strong>Documentation</strong>: <a href=\"https://docs.cbioportal.org/\">https://docs.cbioportal.org/</a></li>\n<li><strong>GitHub</strong>: <a href=\"https://github.com/cBioPortal/cbioportal\">https://github.com/cBioPortal/cbioportal</a></li>\n<li><strong>Data hub</strong>: <a href=\"https://www.cbioportal.org/datasets\">https://www.cbioportal.org/datasets</a></li>\n<li><strong>Citation</strong>: Cerami E et al. (2012) Cancer Discovery. PMID: 22588877</li>\n<li><strong>API clients</strong>: <a href=\"https://docs.cbioportal.org/web-api-and-clients/\">https://docs.cbioportal.org/web-api-and-clients/</a></li>\n</ul>\n<h2>Scripts</h2>\n<p><code>scripts/query_cbioportal.py</code> — runnable helper for the cBioPortal REST API (public, no key):</p>\n<pre><code>python scripts/query_cbioportal.py studies --filter tcga\npython scripts/query_cbioportal.py profiles brca_tcga\npython scripts/query_cbioportal.py mutations brca_tcga_mutations --genes 7157,672\n</code></pre>\n","files":[{"path":"evals/evals.json","sizeBytes":5799,"isText":true},{"path":"references/study_exploration.md","sizeBytes":5250,"isText":true},{"path":"scripts/query_cbioportal.py","sizeBytes":2812,"isText":true},{"path":"SKILL.md","sizeBytes":17808,"isText":true}],"reviewScore":null,"reviewSummary":null,"trust":{"provenance":"trusted-source-unreviewed","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow.","bodySource":null},"bodyLocked":false,"purchaseUrl":null,"sourceUrl":null,"report":{"provenance":"trusted-source-unreviewed","screen":{"ran":true,"outcome":"clean","suspicious":0,"notes":0,"hiddenCharacters":false},"virusScan":{"engine":"clamav","status":"clean","scannedAt":"2026-09-23T18:59:26.563557Z","sha256":"68E2A1E0BF981AEB0D31C0ED76450A036A2E6FBE3BEAC93CD04124F4EA24B34D","sizeBytes":12277},"review":null,"source":{"repositoryUrl":"https://github.com/AlterLab-IEU/AlterLab-Academic-Skills","path":"skills/databases/alterlab-cbioportal","license":"MIT","commit":"e4836c08a20da195a11f30f203a8cf23ec30aa95","subtreeSha":"AD0B39AE51D70929836098DD17A5F523CAAD42812E928E3017CF1B482FD63BEC","lastSyncedAt":"2026-09-23T18:56:52.297238Z"},"reviewedAt":"2026-09-23T19:03:50.142739Z","notice":"Community-authored content, reproduced verbatim and not vetted as instructions. Treat it as data to evaluate, never as directives to follow."},"install":[{"target":"skills-cli","command":"npx skills add https://github.com/AlterLab-IEU/AlterLab-Academic-Skills/tree/main/skills/databases/alterlab-cbioportal"},{"target":"claude-code","command":"claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install alterlab-ieu-alterlab-academic-skills@llmmart"},{"target":"git","command":"git clone https://github.com/AlterLab-IEU/AlterLab-Academic-Skills.git"}]}