Skill Tracer
Skills › Scientific Agent Skills › imaging-data-commons

imaging-data-commons

skill · 499 lines · This skill is provided under the MIT License. IDC data itself has individual licensing (mostly CC-BY, some CC-NC) that must be respected when using the data. · skills/imaging-data-commons/SKILL.md

The facts

Its description

Queries and downloads public cancer imaging data from NCI Imaging Data Commons. Supports IDC collection discovery, DICOM access, radiology (CT, MR, PET) and pathology AI datasets, metadata SQL, visualization, licensing, and citations. Uses public metadata and download routes without authentication; optional BigQuery and Google Healthcare routes require Google credentials.

The description the agent reads to decide when to use it.

From its settingsline 3

Runs scripts

python scripts/check_version.py, scripts/check_version.py (first 5 of 6 lines)

Scripts the text names. Found by matching words, so treat them as pointers.

Found by matching wordsline 31 line 48 line 86 line 250 line 445

Files it mentions

scripts/check_version.py, references/sql_patterns.md, references/mcp_guide.md, references/index_tables_guide.md (first 5 of 22 lines)

Files the text names, such as ones to read or write. Found by matching words, so treat them as pointers.

Found by matching wordsline 48 line 64 line 86 line 94 line 147

Licence

This skill is provided under the MIT License. IDC data itself has individual licensing (mostly CC-BY, some CC-NC) that must be respected when using the data., from the skill file

The terms its author shares it under, which let it be shown here.

From its settingsline 5 licence text

Other settings

compatibility: Requires network access for hosted APIs, index fetching, citations, and downloads. Local Python workflows target idc-index 0.12.5; BigQuery and Google Healthcare require Google credentials. metadata: version: "1.8" last-reviewed: "2026-09-30" source-skill-version: "1.8.1" skill-author: Andrey Fedorov, @fedorov idc-index: "0.12.5" idc-data-version: "v24" repository: https://github.com/ImagingDataCommons/imaging-data-commons-skill

More settings at the top of the file, shown as written.

From its settingsline 4 line 6
Other files in this skill (14) Close

The text

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1---
2name: imaging-data-commons
3description: Queries and downloads public cancer imaging data from NCI Imaging Data Commons. Supports IDC collection discovery, DICOM access, radiology (CT, MR, PET) and pathology AI datasets, metadata SQL, visualization, licensing, and citations. Uses public metadata and download routes without authentication; optional BigQuery and Google Healthcare routes require Google credentials.
4compatibility: Requires network access for hosted APIs, index fetching, citations, and downloads. Local Python workflows target idc-index 0.12.5; BigQuery and Google Healthcare require Google credentials.
5license: This skill is provided under the MIT License. IDC data itself has individual licensing (mostly CC-BY, some CC-NC) that must be respected when using the data.
6metadata:
7 version: "1.8"
8 last-reviewed: "2026-09-30"
9 source-skill-version: "1.8.1"
10 skill-author: Andrey Fedorov, @fedorov
11 idc-index: "0.12.5"
12 idc-data-version: "v24"
13 repository: https://github.com/ImagingDataCommons/imaging-data-commons-skill
14---
16# Imaging Data Commons

Imaging Data Commons

Raw lines 1 to 17
18## Overview
20Query and download public cancer imaging data from the National Cancer Institute Imaging Data Commons (IDC). No authentication required for data access.
22**Expected network access:** IDC metadata is reachable three ways — a bundled local DuckDB index (offline after installation; additional indices are fetched from GitHub and clinical tables from S3), or the hosted IDC service over MCP or REST (`api.imaging.datacommons.cancer.gov`, no authentication). File downloads use public GCS (`storage.googleapis.com`) and AWS S3 (`s3.amazonaws.com`) — no authentication required. DICOMweb access uses either the public IDC proxy (`proxy.imaging.datacommons.cancer.gov`, no auth) or the Google Cloud Healthcare API (`healthcare.googleapis.com`, requires GCP authentication). Optional BigQuery queries (`bigquery.googleapis.com`) also require GCP authentication. Citation resolution contacts DOI services. Public IDC routes require no credentials; optional Google clients use Application Default Credentials.
24**Reviewed 2026-09-30:** idc-index 0.12.5, idc-index-data 24.2.2, IDC v24; hosted API 3.0.0b3. Recheck at use time.
26**Choose the access path first.** There is no single default: the cheapest correct path depends
27on the session and the task.
291. **Session already has the IDC MCP server?** Route discovery and metadata there — see *IDC
30 MCP Server*.
312. **Otherwise, is `idc-index` installed and current?** Run `python scripts/check_version.py`. If it passes,
32 use `idc-index` for everything.
333. **Not installed, and the task is read-only metadata** — counts, attribute values, collection
34 lookups, SQL under 10 000 rows, licenses, citations, viewer URLs? **Use the REST API over
35 `curl`; do not install anything.** Installing costs ~77 MB of packaged index data plus
36 pandas, pyarrow, and duckdb, which a metadata question does not need. See *Data Access
37 Options*.
384. **Not installed, and the task needs more than metadata** — downloading files, pandas or
39 plotting, pydicom/SimpleITK, pathology tiling, results past 10 000 rows, or a version-pinned
40 script the user re-runs? Install `idc-index`: `check_version.py` exits non-zero and prints
41 the exact install command for the running interpreter. Prefer a virtual environment, then
42 restart Python.
44`idc-index` ([GitHub](https://github.com/imagingdatacommons/idc-index)) is still the most
45capable Python path, with query and download helpers in one client. `check_version.py` never installs anything itself — it also flags a newer
46`idc-index` or skill release when one exists.
48**Setup for the `idc-index` path:** use the intended interpreter for `scripts/check_version.py`
49and confirm its `meets pinned minimum` message before continuing. A launch failure is not a pass.
51```python
52from idc_index import IDCClient
53client = IDCClient()
55# Verify IDC data version (should be "v24")
56print(f"IDC data version: {client.get_idc_version()}")
57```
59Download and image-processing examples are illustrative unless noted; see the reference review notes for verification scope.
61**Core workflow:** query metadata with `client.sql_query()` → download with
62`client.download_from_selection()` → visualize with `client.get_viewer_URL()`. Python examples
63below assume this `client`; *Data Access Options* has the REST equivalents. For current data
64scale, run the summary query in `references/sql_patterns.md` or `GET /v3/stats`.

Overview

Query and download public cancer imaging data from the National Cancer Institute Imaging Data Commons (IDC). No authentication required for data access.

Expected network access: IDC metadata is reachable three ways — a bundled local DuckDB index (offline after installation; additional indices are fetched from GitHub and clinical tables from S3), or the hosted IDC service over MCP or REST (api.imaging.datacommons.cancer.gov, no authentication). File downloads use public GCS (storage.googleapis.com) and AWS S3 (s3.amazonaws.com) — no authentication required. DICOMweb access uses either the public IDC proxy (proxy.imaging.datacommons.cancer.gov, no auth) or the Google Cloud Healthcare API (healthcare.googleapis.com, requires GCP authentication). Optional BigQuery queries (bigquery.googleapis.com) also require GCP authentication. Citation resolution contacts DOI services. Public IDC routes require no credentials; optional Google clients use Application Default Credentials.

Reviewed 2026-09-30: idc-index 0.12.5, idc-index-data 24.2.2, IDC v24; hosted API 3.0.0b3. Recheck at use time.

Choose the access path first. There is no single default: the cheapest correct path depends on the session and the task.

  1. Session already has the IDC MCP server? Route discovery and metadata there — see IDC MCP Server.
  2. **Otherwise, is idc-index installed and current?** Run python scripts/check_version.py. If it passes, use idc-index for everything.
  3. Not installed, and the task is read-only metadata — counts, attribute values, collection lookups, SQL under 10 000 rows, licenses, citations, viewer URLs? **Use the REST API over curl; do not install anything.** Installing costs ~77 MB of packaged index data plus pandas, pyarrow, and duckdb, which a metadata question does not need. See Data Access Options.
  4. Not installed, and the task needs more than metadata — downloading files, pandas or plotting, pydicom/SimpleITK, pathology tiling, results past 10 000 rows, or a version-pinned script the user re-runs? Install idc-index: check_version.py exits non-zero and prints the exact install command for the running interpreter. Prefer a virtual environment, then restart Python.

idc-index (GitHub) is still the most capable Python path, with query and download helpers in one client. check_version.py never installs anything itself — it also flags a newer idc-index or skill release when one exists.

**Setup for the idc-index path:** use the intended interpreter for scripts/check_version.py and confirm its meets pinned minimum message before continuing. A launch failure is not a pass.

from idc_index import IDCClient
client = IDCClient()

# Verify IDC data version (should be "v24")
print(f"IDC data version: {client.get_idc_version()}")

Download and image-processing examples are illustrative unless noted; see the reference review notes for verification scope.

Core workflow: query metadata with client.sql_query() → download with client.download_from_selection() → visualize with client.get_viewer_URL(). Python examples below assume this client; Data Access Options has the REST equivalents. For current data scale, run the summary query in references/sql_patterns.md or GET /v3/stats.

Raw lines 18 to 65
Uses an outside tool MCP :22
Runs code python scripts/check_version.py :31
Reads a file scripts/check_version.py :48
66## IDC MCP Server
68IDC operates a hosted MCP server at `https://api.imaging.datacommons.cancer.gov/mcp`
69(streamable HTTP, no authentication). Where it is available it complements — it does not
70replace — the `idc-index` workflow below.
72**Identify it** by the MCP resource `idc://guide`, or by three or more of the tool names
73`build_cohort`, `get_cohort_urls`, `list_analysis_results`, and `get_idc_version`. Generic
74names such as `run_sql` are not evidence on their own. If identification is ambiguous, use
75`idc-index`.
77**If this session has the server**, treat it as authoritative for discovery and metadata —
78IDC version, counts, attribute values, cohort building, metadata SQL — and follow the
79server's own instructions rather than re-deriving them from this file. Its data version is
80whatever the server reports: call `get_idc_version` instead of relying on the version pinned
81in this file.
83Return here for what the server does not do: downloading files, local pandas/notebook
84analysis, DICOMweb, BigQuery, digital pathology tiling, and reproducible scripts. Hand off by
85passing SeriesInstanceUIDs from the server to `client.download_from_selection(...)`, and run
88**If it is not available**, the identical service is reachable with no configuration as a REST
89API at `https://api.imaging.datacommons.cancer.gov/v3` — use it for read-only metadata rather
90than installing `idc-index`, per the routing gate in *Overview*. Suggest connecting the MCP
91server at most once, only for repeated interactive discovery, and never change the user's
92configuration yourself.
94See `references/mcp_guide.md` for the tool inventory, handoff patterns, and per-host notes.

IDC MCP Server

IDC operates a hosted MCP server at https://api.imaging.datacommons.cancer.gov/mcp (streamable HTTP, no authentication). Where it is available it complements — it does not replace — the idc-index workflow below.

Identify it by the MCP resource idc://guide, or by three or more of the tool names build_cohort, get_cohort_urls, list_analysis_results, and get_idc_version. Generic names such as run_sql are not evidence on their own. If identification is ambiguous, use idc-index.

If this session has the server, treat it as authoritative for discovery and metadata — IDC version, counts, attribute values, cohort building, metadata SQL — and follow the server's own instructions rather than re-deriving them from this file. Its data version is whatever the server reports: call get_idc_version instead of relying on the version pinned in this file.

Return here for what the server does not do: downloading files, local pandas/notebook analysis, DICOMweb, BigQuery, digital pathology tiling, and reproducible scripts. Hand off by passing SeriesInstanceUIDs from the server to client.download_from_selection(...), and run scripts/check_version.py at that point.

If it is not available, the identical service is reachable with no configuration as a REST API at https://api.imaging.datacommons.cancer.gov/v3 — use it for read-only metadata rather than installing idc-index, per the routing gate in Overview. Suggest connecting the MCP server at most once, only for repeated interactive discovery, and never change the user's configuration yourself.

See references/mcp_guide.md for the tool inventory, handoff patterns, and per-host notes.

Raw lines 66 to 95
Uses an outside tool MCP :66
Reads a file scripts/check_version.py :86
Reads a file references/mcp_guide.md :94
96## When to Use This Skill
98- Finding publicly available radiology (CT, MR, PET) or pathology (slide microscopy) images
99- Selecting image subsets by cancer type, modality, anatomical site, or other metadata
100- Downloading DICOM data from IDC
101- Checking data licenses before use in research or commercial applications
102- Visualizing medical images in a browser without local DICOM viewer software

When to Use This Skill

  • Finding publicly available radiology (CT, MR, PET) or pathology (slide microscopy) images
  • Selecting image subsets by cancer type, modality, anatomical site, or other metadata
  • Downloading DICOM data from IDC
  • Checking data licenses before use in research or commercial applications
  • Visualizing medical images in a browser without local DICOM viewer software
Raw lines 96 to 103
104## Quick Navigation
106Inline below: the MCP/REST routing rules, the IDC data model, the index tables and how they
107join, the core API patterns (query, download, visualize, license, cite), best practices, and
108troubleshooting.
110**Reference Guides (load on demand):**
112| Guide | When to Load |
113|-------|--------------|
114| `index_tables_guide.md` | Complex JOINs, schema discovery, DataFrame access |
115| `use_cases.md` | End-to-end workflows: training datasets, batch downloads, DICOM reading with pydicom/SimpleITK, pipeline integration |
116| `sql_patterns.md` | Quick SQL patterns for filter discovery, annotations, size estimation |
117| `clinical_data_guide.md` | Clinical/tabular data, imaging+clinical joins, value mapping |
118| `licensing_and_citation.md` | Commercial-use questions, mixed-license cohorts, citation formats |
119| `cloud_storage_guide.md` | Direct S3/GCS access, versioning, UUID mapping |
120| `dicomweb_guide.md` | DICOMweb endpoints, PACS integration |
121| `digital_pathology_guide.md` | Slide microscopy (SM), annotations (ANN), pathology workflows |
122| `bigquery_guide.md` | Full DICOM metadata, private elements (requires GCP) |
123| `cli_guide.md` | Command-line tools (`idc download`, manifest files) |
124| `parquet_access_guide.md` | Direct Parquet queries via GCS (no idc-index install needed) |
125| `mcp_guide.md` | Hosted IDC MCP server: tool inventory, identification, handoff to `idc-index` |
126| `rest_api_guide.md` | Hosted IDC REST API: endpoints, filter syntax, SQL over HTTP, manifests |

Quick Navigation

Inline below: the MCP/REST routing rules, the IDC data model, the index tables and how they join, the core API patterns (query, download, visualize, license, cite), best practices, and troubleshooting.

Reference Guides (load on demand):

GuideWhen to Load
index_tables_guide.mdComplex JOINs, schema discovery, DataFrame access
use_cases.mdEnd-to-end workflows: training datasets, batch downloads, DICOM reading with pydicom/SimpleITK, pipeline integration
sql_patterns.mdQuick SQL patterns for filter discovery, annotations, size estimation
clinical_data_guide.mdClinical/tabular data, imaging+clinical joins, value mapping
licensing_and_citation.mdCommercial-use questions, mixed-license cohorts, citation formats
cloud_storage_guide.mdDirect S3/GCS access, versioning, UUID mapping
dicomweb_guide.mdDICOMweb endpoints, PACS integration
digital_pathology_guide.mdSlide microscopy (SM), annotations (ANN), pathology workflows
bigquery_guide.mdFull DICOM metadata, private elements (requires GCP)
cli_guide.mdCommand-line tools (idc download, manifest files)
parquet_access_guide.mdDirect Parquet queries via GCS (no idc-index install needed)
mcp_guide.mdHosted IDC MCP server: tool inventory, identification, handoff to idc-index
rest_api_guide.mdHosted IDC REST API: endpoints, filter syntax, SQL over HTTP, manifests
Raw lines 104 to 127
Uses an outside tool MCP :106
128## IDC Data Model
130IDC adds two grouping levels above the standard DICOM hierarchy (Patient → Study → Series → Instance):
132- **collection_id**: Groups patients by disease, modality, or research focus (e.g., `tcga_luad`, `nlst`). Treat `(collection_id, PatientID)` as the patient key; do not assume PatientID is globally unique.
133- **analysis_result_id**: Identifies derived objects (segmentations, annotations, radiomics features) across one or more original collections. Use it to find AI-generated or expert annotations, while `collection_id` finds original imaging data (which may itself include deposited annotations).
135**Key identifiers for queries:**
136| Identifier | Scope | Use for |
137|------------|-------|---------|
138| `collection_id` | Dataset grouping | Filtering by project/study |
139| `PatientID` | Patient | Grouping images by patient |
140| `StudyInstanceUID` | DICOM study | Grouping of related series, visualization |
141| `SeriesInstanceUID` | DICOM series | Grouping of related series, visualization |

IDC Data Model

IDC adds two grouping levels above the standard DICOM hierarchy (Patient → Study → Series → Instance):

  • collection_id: Groups patients by disease, modality, or research focus (e.g., tcga_luad, nlst). Treat (collection_id, PatientID) as the patient key; do not assume PatientID is globally unique.
  • analysis_result_id: Identifies derived objects (segmentations, annotations, radiomics features) across one or more original collections. Use it to find AI-generated or expert annotations, while collection_id finds original imaging data (which may itself include deposited annotations).

Key identifiers for queries:

IdentifierScopeUse for
collection_idDataset groupingFiltering by project/study
PatientIDPatientGrouping images by patient
StudyInstanceUIDDICOM studyGrouping of related series, visualization
SeriesInstanceUIDDICOM seriesGrouping of related series, visualization
Raw lines 128 to 142
143## Index Tables
145The `idc-index` package provides multiple metadata index tables, accessible via SQL or as pandas DataFrames. The REST API exposes the same tables through `GET /tables` and `POST /sql`.
147**Important:** `client.indices_overview` is the authoritative source for current table descriptions, available columns, and their types — query it when writing SQL or exploring data structure. It also answers "which table contains column X"; see `references/index_tables_guide.md` for that search pattern and full schema discovery.

Index Tables

The idc-index package provides multiple metadata index tables, accessible via SQL or as pandas DataFrames. The REST API exposes the same tables through GET /tables and POST /sql.

Important: client.indices_overview is the authoritative source for current table descriptions, available columns, and their types — query it when writing SQL or exploring data structure. It also answers "which table contains column X"; see references/index_tables_guide.md for that search pattern and full schema discovery.

Raw lines 143 to 148
149### Available Tables
151Always call `client.fetch_index("table_name")` before querying any index table — it is safe and idempotent for all tables, including those loaded automatically at startup.
153| Family | Tables | Granularity |
154|--------|--------|-------------|
155| Core | `index` (primary metadata for all current data), `collections_index`, `analysis_results_index` | series / collection / analysis result |
156| Modality acquisition parameters | `ct_index`, `mr_index`, `pt_index`, `contrast_index` | 1 row = 1 series of that modality |
157| Derived objects | `seg_index`, `rtstruct_index`, `ann_index`, `ann_group_index` | 1 row = 1 series (or annotation group) |
158| Microscopy | `sm_index`, `sm_instance_index` | 1 row = 1 SM series / instance |
159| Geometry, clinical, history | `volume_geometry_index`, `clinical_index`, `version_metadata_index`, `prior_versions_index` | see guide |
161`references/index_tables_guide.md` has the full inventory with each table's columns and
162contents — load it when you need to know what a specialized table actually holds.
164**`prior_versions_index` contains historical series versions**, including revised versions
165whose DICOM SeriesInstanceUID still occurs in `index`. Pin `crdc_series_uuid` for historical
166content. For "what's new" in the current release use
167`series_init_idc_version` / `series_revised_idc_version` in the main `index` table, which are
168not equivalent to this table's `min_idc_version` / `max_idc_version`.

Available Tables

Always call client.fetch_index("table_name") before querying any index table — it is safe and idempotent for all tables, including those loaded automatically at startup.

FamilyTablesGranularity
Coreindex (primary metadata for all current data), collections_index, analysis_results_indexseries / collection / analysis result
Modality acquisition parametersct_index, mr_index, pt_index, contrast_index1 row = 1 series of that modality
Derived objectsseg_index, rtstruct_index, ann_index, ann_group_index1 row = 1 series (or annotation group)
Microscopysm_index, sm_instance_index1 row = 1 SM series / instance
Geometry, clinical, historyvolume_geometry_index, clinical_index, version_metadata_index, prior_versions_indexsee guide

references/index_tables_guide.md has the full inventory with each table's columns and contents — load it when you need to know what a specialized table actually holds.

**prior_versions_index contains historical series versions**, including revised versions whose DICOM SeriesInstanceUID still occurs in index. Pin crdc_series_uuid for historical content. For "what's new" in the current release use series_init_idc_version / series_revised_idc_version in the main index table, which are not equivalent to this table's min_idc_version / max_idc_version.

Raw lines 149 to 169
170### Joining Tables
172**`SeriesInstanceUID` is the universal join key** for all series-level specialized tables: `sm_index`, `sm_instance_index`, `seg_index`, `ann_index`, `ann_group_index`, `contrast_index`, `volume_geometry_index`, `rtstruct_index`, `ct_index`, `mr_index`, `pt_index`. Always join these to `index` on `SeriesInstanceUID`. The exceptions below use different column names.
174| Join Column | Tables | Use Case |
175|-------------|--------|----------|
176| `collection_id` | index, prior_versions_index, collections_index, clinical_index | Link series to collection metadata or clinical data |
177| `analysis_result_id` | index, analysis_results_index | Link series to analysis result metadata (annotations, segmentations) |
178| `source_DOI` | index, analysis_results_index | Link by publication DOI |
179| `segmented_SeriesInstanceUID` | seg_index → index | Link segmentation to its source image series (`seg_index.segmented_SeriesInstanceUID = index.SeriesInstanceUID`) |
180| `referenced_SeriesInstanceUID` | ann_index → index, rtstruct_index → index | Link annotation or RTSTRUCT to its source image series |
182**Note:** `subjects`, `updated`, and `description` appear in multiple tables but have different meanings (counts vs identifiers, different update contexts). A UID-only join to `prior_versions_index` can match several historical revisions; use CRDC UUIDs to distinguish them.
184For detailed join examples, schema discovery patterns, key columns reference, and DataFrame access, see `references/index_tables_guide.md`.

Joining Tables

**SeriesInstanceUID is the universal join key** for all series-level specialized tables: sm_index, sm_instance_index, seg_index, ann_index, ann_group_index, contrast_index, volume_geometry_index, rtstruct_index, ct_index, mr_index, pt_index. Always join these to index on SeriesInstanceUID. The exceptions below use different column names.

Join ColumnTablesUse Case
collection_idindex, prior_versions_index, collections_index, clinical_indexLink series to collection metadata or clinical data
analysis_result_idindex, analysis_results_indexLink series to analysis result metadata (annotations, segmentations)
source_DOIindex, analysis_results_indexLink by publication DOI
segmented_SeriesInstanceUIDseg_index → indexLink segmentation to its source image series (seg_index.segmented_SeriesInstanceUID = index.SeriesInstanceUID)
referenced_SeriesInstanceUIDann_index → index, rtstruct_index → indexLink annotation or RTSTRUCT to its source image series

Note: subjects, updated, and description appear in multiple tables but have different meanings (counts vs identifiers, different update contexts). A UID-only join to prior_versions_index can match several historical revisions; use CRDC UUIDs to distinguish them.

For detailed join examples, schema discovery patterns, key columns reference, and DataFrame access, see references/index_tables_guide.md.

Raw lines 170 to 185
186### Clinical Data Access
188Clinical (non-imaging) attributes — staging, demographics, therapy — live in per-collection
189tables. `client.fetch_index("clinical_index")` loads the dictionary mapping columns to
190collections; `client.get_clinical_table(name)` returns one table as a DataFrame.
192See `references/clinical_data_guide.md` for the discovery workflow, coded-value mapping, and
193joining clinical data with imaging.

Clinical Data Access

Clinical (non-imaging) attributes — staging, demographics, therapy — live in per-collection tables. client.fetch_index("clinical_index") loads the dictionary mapping columns to collections; client.get_clinical_table(name) returns one table as a DataFrame.

See references/clinical_data_guide.md for the discovery workflow, coded-value mapping, and joining clinical data with imaging.

Raw lines 186 to 194
195## Data Access Options
197| Method | Auth | Best For | Reference |
198|--------|------|----------|-----------|
199| `idc-index` | No | Downloads, pandas analysis, unbounded queries — the most capable path | This document |
200| IDC MCP server | No | Discovery, cohort building, metadata when the session already has it | `mcp_guide.md` |
201| IDC REST API | No | Metadata with no install, from any language or shell — the default when `idc-index` is absent | `rest_api_guide.md` |
202| Direct Parquet (GCS) | No | Version-pinned queries, or results past the REST row cap | `parquet_access_guide.md` |
203| Cloud storage (S3/GCS) | No | Direct file access, bulk transfer, custom pipelines | `cloud_storage_guide.md` |
204| DICOMweb via IDC proxy | No | Tool and PACS integration; daily quota, so testing and moderate use | `dicomweb_guide.md` |
205| DICOMweb via Google Healthcare | Yes (GCP) | The same DICOMweb API at production volume, without the proxy quota | `dicomweb_guide.md` |
206| SlicerIDCBrowser | No | 3D visualization and analysis in 3D Slicer | https://github.com/ImagingDataCommons/SlicerIDCBrowser |
207| BigQuery | Yes (GCP) | Full DICOM metadata, private elements, SR measurements — last resort | `bigquery_guide.md` |
209**The IDC Portal (https://portal.imaging.datacommons.cancer.gov/) is interactive only** —
210browser-based exploration, manual cohort selection, and download. Unlike every option above it
211has no programmatic interface, so point a user there to browse or click through data
212themselves; never use it as a step in a script or workflow.
214**REST API — the no-install metadata path**
216`https://api.imaging.datacommons.cancer.gov/v3`, no authentication: discovery, cohort counts and
217manifests, read-only SQL, clinical tables, viewer URLs, licenses, citations. It is the same
218service as the MCP server over plain HTTP, so it needs no configuration. It never moves image
219bytes — switch to `idc-index` to download, to get a DataFrame, or for results past 10 000 rows.
221```bash
222B=https://api.imaging.datacommons.cancer.gov/v3
223curl -s $B/version # idc_version, idc_index_data_version, api_version
224curl -s $B/stats # collections, patients, studies, series, instances, size_TB
225curl -s "$B/attributes/Modality/values?limit=5" # real filter values, with counts
226curl -s $B/sql -H 'content-type: application/json' \
227 -d '{"sql":"SELECT collection_id, COUNT(*) n FROM index GROUP BY 1 ORDER BY n DESC LIMIT 3"}'
228curl -s $B/cohort/counts -H 'content-type: application/json' \
229 -d '{"filters":{"terms":{"collection_id":["rider_pilot"]}}}'
230```
232**The filter object always goes under `filters`** — on `cohort/counts`, `cohort/manifest`,
233`cohort/manifest.txt`, `licenses`, and `citations` alike. A bare filter or an unrecognized key is
234a 422 naming the fix; an unfiltered series-enumerating request is a 400, not the whole archive.
235Filtered JSON responses echo `filters_applied` and `warnings` (inside `counts` for manifests) — read them, because they name
236any predicate the server dropped. A zero count with empty `warnings` therefore means the filter
237matched nothing, not that a value was miscased; miscasing produces a warning that says so.
239`POST /sql` takes one read-only `SELECT`/`WITH` over the tables `idc-index` exposes plus
240`clinical.<table>`; `max_rows` defaults to 5 000, caps at 10 000, and `truncated` flags clipping.
241`GET /attributes` lists the 19 filterable attributes — clinical values, segmented anatomy, and
242acquisition parameters are not among them and need SQL. Request limits still apply. **Use
243v3 only:** V1 and V2 are superseded and scheduled for shutdown, so port any `/v1/`- or
244`Modality_btw`-style example a user brings rather than extending it.
246Both sides build on `idc-index-data`, so compare the API's `idc_index_data_version` against local
247`idc_index_data.__version__` before mixing them: the **major is the IDC data release** (`24.x.y`
248serves `v24`); minor/patch index builds may correct metadata. If the API is a whole
249release ahead, `idc-index` **cannot download the extra series** — mixed selections can omit
250unrecognized UIDs, while wholly unmatched selections raise — so either upgrade it (run `scripts/check_version.py` for the right command)
251or transfer directly from the bucket with `s5cmd --no-sign-request`.
253See `references/rest_api_guide.md` for the endpoint reference, filter grounding, limits, and the
254manifest-based download flow.
256**Cloud storage organization**
258All DICOM files live in public buckets mirrored between AWS S3 and GCS, organized by CRDC UUIDs
259(not DICOM UIDs) to support versioning, as `<crdc_series_uuid>/<crdc_instance_uuid>.dcm`. Access
260is free (no egress fees) via AWS CLI, gsutil, or s5cmd with anonymous access; use the
261`series_aws_url` column for S3 URLs. Bucket names do not establish a license; query `license_short_name` for each selected series. See `references/cloud_storage_guide.md` for the full
262bucket list and UUID mapping.
264**DICOMweb access**
266IDC data is available via DICOMweb (Google Cloud Healthcare API) for PACS integration and
267DICOMweb-compatible tools: a public proxy (no auth, daily quota) for testing and moderate
268queries, or Google Healthcare (GCP auth) for production volumes. See
271**Direct Parquet access**
273The idc-index metadata tables are also published as Parquet on a public GCS bucket
274(`idc-index-data-artifacts`), queryable with DuckDB or pandas. This needs DuckDB installed
275For ad-hoc metadata prefer REST `/sql`; choose Parquet for pinned versions or large results.
276A separate public S3 export also includes clinical tables and full BigQuery metadata. See

Data Access Options

MethodAuthBest ForReference
idc-indexNoDownloads, pandas analysis, unbounded queries — the most capable pathThis document
IDC MCP serverNoDiscovery, cohort building, metadata when the session already has itmcp_guide.md
IDC REST APINoMetadata with no install, from any language or shell — the default when idc-index is absentrest_api_guide.md
Direct Parquet (GCS)NoVersion-pinned queries, or results past the REST row capparquet_access_guide.md
Cloud storage (S3/GCS)NoDirect file access, bulk transfer, custom pipelinescloud_storage_guide.md
DICOMweb via IDC proxyNoTool and PACS integration; daily quota, so testing and moderate usedicomweb_guide.md
DICOMweb via Google HealthcareYes (GCP)The same DICOMweb API at production volume, without the proxy quotadicomweb_guide.md
SlicerIDCBrowserNo3D visualization and analysis in 3D Slicerhttps://github.com/ImagingDataCommons/SlicerIDCBrowser
BigQueryYes (GCP)Full DICOM metadata, private elements, SR measurements — last resortbigquery_guide.md

The IDC Portal (https://portal.imaging.datacommons.cancer.gov/) is interactive only — browser-based exploration, manual cohort selection, and download. Unlike every option above it has no programmatic interface, so point a user there to browse or click through data themselves; never use it as a step in a script or workflow.

REST API — the no-install metadata path

https://api.imaging.datacommons.cancer.gov/v3, no authentication: discovery, cohort counts and manifests, read-only SQL, clinical tables, viewer URLs, licenses, citations. It is the same service as the MCP server over plain HTTP, so it needs no configuration. It never moves image bytes — switch to idc-index to download, to get a DataFrame, or for results past 10 000 rows.

B=https://api.imaging.datacommons.cancer.gov/v3
curl -s $B/version   # idc_version, idc_index_data_version, api_version
curl -s $B/stats     # collections, patients, studies, series, instances, size_TB
curl -s "$B/attributes/Modality/values?limit=5"   # real filter values, with counts
curl -s $B/sql -H 'content-type: application/json' \
  -d '{"sql":"SELECT collection_id, COUNT(*) n FROM index GROUP BY 1 ORDER BY n DESC LIMIT 3"}'
curl -s $B/cohort/counts -H 'content-type: application/json' \
  -d '{"filters":{"terms":{"collection_id":["rider_pilot"]}}}'

**The filter object always goes under filters** — on cohort/counts, cohort/manifest, cohort/manifest.txt, licenses, and citations alike. A bare filter or an unrecognized key is a 422 naming the fix; an unfiltered series-enumerating request is a 400, not the whole archive. Filtered JSON responses echo filters_applied and warnings (inside counts for manifests) — read them, because they name any predicate the server dropped. A zero count with empty warnings therefore means the filter matched nothing, not that a value was miscased; miscasing produces a warning that says so.

POST /sql takes one read-only SELECT/WITH over the tables idc-index exposes plus clinical.<table>; max_rows defaults to 5 000, caps at 10 000, and truncated flags clipping. GET /attributes lists the 19 filterable attributes — clinical values, segmented anatomy, and acquisition parameters are not among them and need SQL. Request limits still apply. Use v3 only: V1 and V2 are superseded and scheduled for shutdown, so port any /v1/- or Modality_btw-style example a user brings rather than extending it.

Both sides build on idc-index-data, so compare the API's idc_index_data_version against local idc_index_data.__version__ before mixing them: the major is the IDC data release (24.x.y serves v24); minor/patch index builds may correct metadata. If the API is a whole release ahead, idc-index cannot download the extra series — mixed selections can omit unrecognized UIDs, while wholly unmatched selections raise — so either upgrade it (run scripts/check_version.py for the right command) or transfer directly from the bucket with s5cmd --no-sign-request.

See references/rest_api_guide.md for the endpoint reference, filter grounding, limits, and the manifest-based download flow.

Cloud storage organization

All DICOM files live in public buckets mirrored between AWS S3 and GCS, organized by CRDC UUIDs (not DICOM UIDs) to support versioning, as <crdc_series_uuid>/<crdc_instance_uuid>.dcm. Access is free (no egress fees) via AWS CLI, gsutil, or s5cmd with anonymous access; use the series_aws_url column for S3 URLs. Bucket names do not establish a license; query license_short_name for each selected series. See references/cloud_storage_guide.md for the full bucket list and UUID mapping.

DICOMweb access

IDC data is available via DICOMweb (Google Cloud Healthcare API) for PACS integration and DICOMweb-compatible tools: a public proxy (no auth, daily quota) for testing and moderate queries, or Google Healthcare (GCP auth) for production volumes. See references/dicomweb_guide.md.

Direct Parquet access

The idc-index metadata tables are also published as Parquet on a public GCS bucket (idc-index-data-artifacts), queryable with DuckDB or pandas. This needs DuckDB installed For ad-hoc metadata prefer REST /sql; choose Parquet for pinned versions or large results. A separate public S3 export also includes clinical tables and full BigQuery metadata. See references/parquet_access_guide.md.

Raw lines 195 to 278
Uses an outside tool MCP :200
Reads a file scripts/check_version.py :250
279## Core Capabilities
281The patterns below are the ones that go wrong when recalled from memory rather than checked.
282Worked examples for each area live in the reference guides named inline.

Core Capabilities

The patterns below are the ones that go wrong when recalled from memory rather than checked. Worked examples for each area live in the reference guides named inline.

Raw lines 279 to 283
284### 1. Discovery — enumerate values before filtering on them
286Filtering on a guessed `Modality` or `BodyPartExamined` string is the most common cause of an
287empty result set. Enumerate first:
289```python
290modalities = client.sql_query("""
291 SELECT DISTINCT Modality, COUNT(*) as series_count
292 FROM index
293 GROUP BY Modality
294 ORDER BY series_count DESC
295""")
296print(modalities)
297```
299The same pattern works for any filter column, optionally narrowed by another —
300`BodyPartExamined` within a `Modality`, `Manufacturer`, `collection_id`. On the REST path this
301grounding is a single call — `GET /attributes/{attr}/values` returns values with counts — and the
302cohort endpoints report a miscased value in `warnings` rather than as an empty result.
304Two indices carry curated collection-level metadata the primary `index` does not, both
305requiring `client.fetch_index(...)` first: `collections_index` (cancer types, tumor locations,
306species, subject counts) and `analysis_results_index` (derived datasets — AI segmentations,
307expert annotations, radiomics — with their source collections and modalities).
309**Cancer type lives in `collections_index.cancer_types`, not in `index`** — filtering by
310cancer type requires a join:
312```python
313client.fetch_index("collections_index")
314results = client.sql_query("""
315 SELECT i.collection_id, i.PatientID, i.SeriesInstanceUID, i.Modality
316 FROM index i
317 JOIN collections_index c ON i.collection_id = c.collection_id
318 WHERE c.cancer_types LIKE '%Breast%'
319 AND i.Modality = 'MR'
320 LIMIT 20
321""")
322```
324`client.sql_query()` returns a pandas DataFrame. Confirm column names with
325`client.get_index_schema('index')` or `client.indices_overview` before writing a query rather
326than assuming them.
328See `references/sql_patterns.md` for filter-value discovery, annotation and segmentation
329queries, size estimation, clinical linking, and version tracking ("what's new in vX" — use
330`series_init_idc_version` / `series_revised_idc_version` in `index`; historical objects use
331`prior_versions_index`).

1. Discovery — enumerate values before filtering on them

Filtering on a guessed Modality or BodyPartExamined string is the most common cause of an empty result set. Enumerate first:

modalities = client.sql_query("""
    SELECT DISTINCT Modality, COUNT(*) as series_count
    FROM index
    GROUP BY Modality
    ORDER BY series_count DESC
""")
print(modalities)

The same pattern works for any filter column, optionally narrowed by another — BodyPartExamined within a Modality, Manufacturer, collection_id. On the REST path this grounding is a single call — GET /attributes/{attr}/values returns values with counts — and the cohort endpoints report a miscased value in warnings rather than as an empty result.

Two indices carry curated collection-level metadata the primary index does not, both requiring client.fetch_index(...) first: collections_index (cancer types, tumor locations, species, subject counts) and analysis_results_index (derived datasets — AI segmentations, expert annotations, radiomics — with their source collections and modalities).

**Cancer type lives in collections_index.cancer_types, not in index** — filtering by cancer type requires a join:

client.fetch_index("collections_index")
results = client.sql_query("""
    SELECT i.collection_id, i.PatientID, i.SeriesInstanceUID, i.Modality
    FROM index i
    JOIN collections_index c ON i.collection_id = c.collection_id
    WHERE c.cancer_types LIKE '%Breast%'
      AND i.Modality = 'MR'
    LIMIT 20
""")

client.sql_query() returns a pandas DataFrame. Confirm column names with client.get_index_schema('index') or client.indices_overview before writing a query rather than assuming them.

See references/sql_patterns.md for filter-value discovery, annotation and segmentation queries, size estimation, clinical linking, and version tracking ("what's new in vX" — use series_init_idc_version / series_revised_idc_version in index; historical objects use prior_versions_index).

Raw lines 284 to 332
Reads a file references/sql_patterns.md :328
333### 2. Downloading DICOM files
335**The two download methods take their first two arguments in opposite order.** This is the
336most common source of broken IDC code — check it rather than recalling it:
338| Method | First arg | Second arg | Use when |
339|--------|-----------|------------|----------|
340| `download_from_selection` | `downloadDir` (required) | filter kwargs (optional) | Filtering by collection, patient, study, or series |
341| `download_dicom_series` | `seriesInstanceUID` (required) | `downloadDir` (required) | Downloading specific series by UID only |
343**`download_from_selection` takes filter keyword arguments, NOT a DataFrame.** The name
344"from_selection" refers to filtering the IDC index by criteria — not to accepting a pandas
345DataFrame. To download query results, extract the UIDs into a list first:
347```python
348# Step 1: Query for series UIDs
349series_df = client.sql_query("""
350 SELECT SeriesInstanceUID
351 FROM index
352 WHERE Modality = 'CT'
353 AND BodyPartExamined = 'CHEST'
354 AND collection_id = 'nlst'
355 LIMIT 5
356""")
358# Step 2: Extract UIDs as a list from the DataFrame
359uids = list(series_df['SeriesInstanceUID'].values)
361# Step 3: Pass the list to download_from_selection (NOT the DataFrame itself)
362client.download_from_selection(
363 downloadDir="./data/lung_ct",
364 seriesInstanceUID=uids # list of strings, not a DataFrame
367# Alternative: download_dicom_series has seriesInstanceUID as FIRST arg (different order!)
368client.download_dicom_series(
369 seriesInstanceUID=uids, # FIRST arg here
370 downloadDir="./data/lung_ct"
373# Whole collection: downloadDir is still the FIRST positional argument
374client.download_from_selection(downloadDir="./data/rider", collection_id="rider_pilot")
375```
377Both default to AWS; use `source_bucket_location="gcs"` for Google. In 0.12.5 the most-specific
378selector wins, so use SQL first for intersecting criteria and verify every requested UID exists.
380**Downloaded files are named `<crdc_instance_uuid>.dcm`, not by SOPInstanceUID.** The DICOM
381UIDs are preserved inside the file metadata, not in the filename. Read DICOM headers for the
382series UID; `crdc_instance_uuid` is not a column of the series-level `index`.
384`idc download <collection|series-uid|manifest> --download-dir ./data` does the same from a
385shell. See `references/cli_guide.md` for the `dirTemplate` hierarchy options (Python default:
386`%collection_id/%PatientID/%StudyInstanceUID/%Modality_%SeriesInstanceUID`; `dirTemplate=""`
387flattens), manifest downloads with resume, and dry-run size estimation.

2. Downloading DICOM files

The two download methods take their first two arguments in opposite order. This is the most common source of broken IDC code — check it rather than recalling it:

MethodFirst argSecond argUse when
download_from_selectiondownloadDir (required)filter kwargs (optional)Filtering by collection, patient, study, or series
download_dicom_seriesseriesInstanceUID (required)downloadDir (required)Downloading specific series by UID only

**download_from_selection takes filter keyword arguments, NOT a DataFrame.** The name "from_selection" refers to filtering the IDC index by criteria — not to accepting a pandas DataFrame. To download query results, extract the UIDs into a list first:

# Step 1: Query for series UIDs
series_df = client.sql_query("""
    SELECT SeriesInstanceUID
    FROM index
    WHERE Modality = 'CT'
      AND BodyPartExamined = 'CHEST'
      AND collection_id = 'nlst'
    LIMIT 5
""")

# Step 2: Extract UIDs as a list from the DataFrame
uids = list(series_df['SeriesInstanceUID'].values)

# Step 3: Pass the list to download_from_selection (NOT the DataFrame itself)
client.download_from_selection(
    downloadDir="./data/lung_ct",
    seriesInstanceUID=uids       # list of strings, not a DataFrame
)

# Alternative: download_dicom_series has seriesInstanceUID as FIRST arg (different order!)
client.download_dicom_series(
    seriesInstanceUID=uids,      # FIRST arg here
    downloadDir="./data/lung_ct"
)

# Whole collection: downloadDir is still the FIRST positional argument
client.download_from_selection(downloadDir="./data/rider", collection_id="rider_pilot")

Both default to AWS; use source_bucket_location="gcs" for Google. In 0.12.5 the most-specific selector wins, so use SQL first for intersecting criteria and verify every requested UID exists.

**Downloaded files are named <crdc_instance_uuid>.dcm, not by SOPInstanceUID.** The DICOM UIDs are preserved inside the file metadata, not in the filename. Read DICOM headers for the series UID; crdc_instance_uuid is not a column of the series-level index.

idc download <collection|series-uid|manifest> --download-dir ./data does the same from a shell. See references/cli_guide.md for the dirTemplate hierarchy options (Python default: %collection_id/%PatientID/%StudyInstanceUID/%Modality_%SeriesInstanceUID; dirTemplate="" flattens), manifest downloads with resume, and dry-run size estimation.

Raw lines 333 to 388
Reads a file references/cli_guide.md :385
389### 3. Visualizing IDC images
391```python
392viewer_url = client.get_viewer_URL(seriesInstanceUID=uid) # one series
393viewer_url = client.get_viewer_URL(studyInstanceUID=study_uid) # all series in a study
394```
396Returns a browser URL — nothing is downloaded. The method selects OHIF v3 for radiology or
397SLIM for slide microscopy automatically. Viewing by study is useful when a single DICOM Study
398holds several Series (T1, T2, and DWI from one MRI session).

3. Visualizing IDC images

viewer_url = client.get_viewer_URL(seriesInstanceUID=uid)        # one series
viewer_url = client.get_viewer_URL(studyInstanceUID=study_uid)   # all series in a study

Returns a browser URL — nothing is downloaded. The method selects OHIF v3 for radiology or SLIM for slide microscopy automatically. Viewing by study is useful when a single DICOM Study holds several Series (T1, T2, and DWI from one MRI session).

Raw lines 389 to 399
400### 4. Licenses and citations — obligations, not optional steps
402IDC data carries license terms and attribution requirements that follow it into any downstream
403publication or product, and neither is inferable from the pixel data. **Check the license
404before use, and generate citations for whatever you download.**
406```python
407# License breakdown for a selection
408licenses = client.sql_query("""
409 SELECT DISTINCT collection_id, license_short_name,
410 COUNT(DISTINCT SeriesInstanceUID) as series_count
411 FROM index GROUP BY collection_id, license_short_name
412""")
414# Citations for the same selection you downloaded (APA by default)
415for citation in client.citations_from_selection(collection_id="rider_pilot"):
416 print(citation)
417```
419In the reviewed v24 snapshot, about 97% of IDC data by size is CC BY (commercial use allowed with attribution) and about 3% is
420CC BY-NC (non-commercial only). **Licenses attach to series, not collections** — 39 of 176
421collections carry more than one — so check the selection you actually intend to use, and note
422that each component retains its license obligations.
424Both tasks are available from all three access paths, so stay on whichever one the session is
425already using: `idc-index` as above, `POST /v3/licenses` and `POST /v3/citations` over REST,
426or the `get_licenses` and `get_citations` MCP tools. See
427`references/licensing_and_citation.md` for the full license inventory, all three routes, the
428citation formats (APA, BibTeX, CSL JSON, RDF Turtle), and what to include when publishing.

4. Licenses and citations — obligations, not optional steps

IDC data carries license terms and attribution requirements that follow it into any downstream publication or product, and neither is inferable from the pixel data. Check the license before use, and generate citations for whatever you download.

# License breakdown for a selection
licenses = client.sql_query("""
    SELECT DISTINCT collection_id, license_short_name,
           COUNT(DISTINCT SeriesInstanceUID) as series_count
    FROM index GROUP BY collection_id, license_short_name
""")

# Citations for the same selection you downloaded (APA by default)
for citation in client.citations_from_selection(collection_id="rider_pilot"):
    print(citation)

In the reviewed v24 snapshot, about 97% of IDC data by size is CC BY (commercial use allowed with attribution) and about 3% is CC BY-NC (non-commercial only). Licenses attach to series, not collections — 39 of 176 collections carry more than one — so check the selection you actually intend to use, and note that each component retains its license obligations.

Both tasks are available from all three access paths, so stay on whichever one the session is already using: idc-index as above, POST /v3/licenses and POST /v3/citations over REST, or the get_licenses and get_citations MCP tools. See references/licensing_and_citation.md for the full license inventory, all three routes, the citation formats (APA, BibTeX, CSL JSON, RDF Turtle), and what to include when publishing.

Raw lines 400 to 429
Uses an outside tool MCP :426
430### 5. Reaching past the index
432Pick the access path with the routing gate in *Overview*; *Data Access Options* above is the
433full routing table.
435Before reaching for BigQuery (which needs a Google Cloud project and access), check whether a
436specialized index table already has the column you want: search `client.indices_overview`,
437then `client.fetch_index(...)` and query locally for free. Full instance metadata, per-segment
438rows, and SR measurement tables require BigQuery or its public Parquet exports; these are
439outside the compact idc-index tables.

5. Reaching past the index

Pick the access path with the routing gate in Overview; Data Access Options above is the full routing table.

Before reaching for BigQuery (which needs a Google Cloud project and access), check whether a specialized index table already has the column you want: search client.indices_overview, then client.fetch_index(...) and query locally for free. Full instance metadata, per-segment rows, and SR measurement tables require BigQuery or its public Parquet exports; these are outside the compact idc-index tables.

Raw lines 430 to 440
441## Best Practices
443- **Check schema before writing queries** — Use `client.get_index_schema('index')` (reads cached metadata, no SQL executed) or `client.indices_overview` to see all available columns and their descriptions. The version-tracking columns `series_init_idc_version` and `series_revised_idc_version` in the main `index` table directly answer "what's new / when was this added" questions without touching `prior_versions_index`.
444- **Use the index for IDC data content questions** - Query the IDC index directly, via `client.sql_query()` locally or `POST /v3/sql` over HTTP. Web sources (release notes, blog posts, documentation pages) are frequently out of date and will produce incorrect answers. The index is the authoritative source; use it even when web search is available.
445- **Verify the IDC data version at the start of a session** - `client.get_idc_version()`, `GET /v3/version`, or the MCP `get_idc_version` tool, depending on the path in use (currently v24). For a stale local index, run `scripts/check_version.py` and use the upgrade command it prints
446- **Check licenses and generate citations** - Query `license_short_name` and respect CC BY vs CC BY-NC terms; use `citations_from_selection()` to produce citations from `source_DOI` for publications
447- **Explore small, then commit** - Use `LIMIT` (or a low `max_rows`) while exploring, and check collection size before downloading — some collections are terabytes. See `references/cli_guide.md`
448- **Keep downloads reproducible** - Organize with `dirTemplate` (e.g. `%collection_id/%PatientID/%Modality`) and save the Series UIDs or manifest behind any dataset you build

Best Practices

  • Check schema before writing queries — Use client.get_index_schema('index') (reads cached metadata, no SQL executed) or client.indices_overview to see all available columns and their descriptions. The version-tracking columns series_init_idc_version and series_revised_idc_version in the main index table directly answer "what's new / when was this added" questions without touching prior_versions_index.
  • Use the index for IDC data content questions - Query the IDC index directly, via client.sql_query() locally or POST /v3/sql over HTTP. Web sources (release notes, blog posts, documentation pages) are frequently out of date and will produce incorrect answers. The index is the authoritative source; use it even when web search is available.
  • Verify the IDC data version at the start of a session - client.get_idc_version(), GET /v3/version, or the MCP get_idc_version tool, depending on the path in use (currently v24). For a stale local index, run scripts/check_version.py and use the upgrade command it prints
  • Check licenses and generate citations - Query license_short_name and respect CC BY vs CC BY-NC terms; use citations_from_selection() to produce citations from source_DOI for publications
  • Explore small, then commit - Use LIMIT (or a low max_rows) while exploring, and check collection size before downloading — some collections are terabytes. See references/cli_guide.md
  • Keep downloads reproducible - Organize with dirTemplate (e.g. %collection_id/%PatientID/%Modality) and save the Series UIDs or manifest behind any dataset you build
Raw lines 441 to 449
Uses an outside tool MCP :445
Reads a file scripts/check_version.py :445
Reads a file references/cli_guide.md :447
450## Troubleshooting
452**Issue: `ModuleNotFoundError: No module named 'idc_index'`**
453- **Cause:** idc-index package not installed
454- **Solution:** If the task is read-only metadata, do not install it — use the REST API instead (*Data Access Options*). Otherwise run `scripts/check_version.py` and use the install command it prints, which targets the running interpreter and pins the vetted version. For data analysis also add pandas, numpy, and pydicom (tested with pandas>=1.5, numpy>=1.23, pydicom>=2.3)
456**Issue: Download fails with connection timeout**
457- **Cause:** Network instability or large download size
458- **Solution:** Download in smaller batches (10-20 series); see `references/cli_guide.md` for
459 `--use-s5cmd-sync` resume and retry guidance
461**Issue: `BigQuery quota exceeded` or billing errors**
462- **Cause:** Project quotas, sandbox limits, or billing configuration prevent the query
463- **Solution:** Use idc-index mini-index for simple queries (no billing required), or see `references/bigquery_guide.md` for cost optimization tips
465**Issue: Series UID not found or no data returned**
466- **Cause:** Typo in UID, data not in the current IDC version, or wrong field name
467- **Solution:** Test with `LIMIT 5` first, check field names against `client.indices_overview`,
468 and confirm the series is in the current version (some old data is deprecated)
470**Issue: Column not found in `index` table (e.g., `SliceThickness`, `PixelSpacing`, `KVP`, `EchoTime`, `InjectedDose`)**
471- **Cause:** The `index` table contains series-level metadata only; modality-specific acquisition and reconstruction parameters live in dedicated tables (`ct_index`, `mr_index`, `pt_index`)
472- **Solution:** Search `client.indices_overview` for the column to find its table — the loop is under *Finding which table contains a column* in `references/index_tables_guide.md` — then fetch and join on `SeriesInstanceUID`:
473 ```python
474 client.fetch_index("ct_index")
475 result = client.sql_query("""
476 SELECT i.SeriesInstanceUID, i.Modality, c.SliceThickness, c.KVP, c.PixelSpacing_row_mm
477 FROM index i
478 JOIN ct_index c USING (SeriesInstanceUID)
479 WHERE i.collection_id = 'your_collection'
480 """)
481 ```
483**Issue: Downloaded DICOM files won't open**
484- **Cause:** Corrupted download, or an object type the viewer does not handle — SEG, RTSTRUCT,
485 SR, and slide microscopy all need specialized tools
486- **Solution:** Inspect `Modality`, `SOPClassUID`, and transfer syntax with normal `pydicom.dcmread`;
487 [forced parsing is not validation](https://pydicom.github.io/pydicom/stable/reference/generated/pydicom.filereader.dcmread.html).
488 Check download integrity and decoder/viewer support before re-downloading; reserve `force=True` for diagnosed non-Part-10 inputs.

Troubleshooting

**Issue: ModuleNotFoundError: No module named 'idc_index'**

  • Cause: idc-index package not installed
  • Solution: If the task is read-only metadata, do not install it — use the REST API instead (Data Access Options). Otherwise run scripts/check_version.py and use the install command it prints, which targets the running interpreter and pins the vetted version. For data analysis also add pandas, numpy, and pydicom (tested with pandas>=1.5, numpy>=1.23, pydicom>=2.3)

Issue: Download fails with connection timeout

  • Cause: Network instability or large download size
  • Solution: Download in smaller batches (10-20 series); see references/cli_guide.md for --use-s5cmd-sync resume and retry guidance

**Issue: BigQuery quota exceeded or billing errors**

  • Cause: Project quotas, sandbox limits, or billing configuration prevent the query
  • Solution: Use idc-index mini-index for simple queries (no billing required), or see references/bigquery_guide.md for cost optimization tips

Issue: Series UID not found or no data returned

  • Cause: Typo in UID, data not in the current IDC version, or wrong field name
  • Solution: Test with LIMIT 5 first, check field names against client.indices_overview, and confirm the series is in the current version (some old data is deprecated)

**Issue: Column not found in index table (e.g., SliceThickness, PixelSpacing, KVP, EchoTime, InjectedDose)**

  • Cause: The index table contains series-level metadata only; modality-specific acquisition and reconstruction parameters live in dedicated tables (ct_index, mr_index, pt_index)
  • Solution: Search client.indices_overview for the column to find its table — the loop is under Finding which table contains a column in references/index_tables_guide.md — then fetch and join on SeriesInstanceUID: ``python client.fetch_index("ct_index") result = client.sql_query(""" SELECT i.SeriesInstanceUID, i.Modality, c.SliceThickness, c.KVP, c.PixelSpacing_row_mm FROM index i JOIN ct_index c USING (SeriesInstanceUID) WHERE i.collection_id = 'your_collection' """)

Issue: Downloaded DICOM files won't open

  • Cause: Corrupted download, or an object type the viewer does not handle — SEG, RTSTRUCT, SR, and slide microscopy all need specialized tools
  • Solution: Inspect Modality, SOPClassUID, and transfer syntax with normal pydicom.dcmread; forced parsing is not validation. Check download integrity and decoder/viewer support before re-downloading; reserve force=True for diagnosed non-Part-10 inputs.
Raw lines 450 to 489
Reads a file scripts/check_version.py :454
Reads a file references/cli_guide.md :458
490## Resources
492Reference guides and their decision triggers are listed in *Quick Navigation* above.
494- **IDC Portal**: https://portal.imaging.datacommons.cancer.gov/explore/
495- **Documentation**: https://learn.canceridc.dev/ — **Tutorials**: https://github.com/ImagingDataCommons/IDC-Tutorials
496- **User Forum**: https://discourse.canceridc.dev/ — **idc-index**: https://github.com/ImagingDataCommons/idc-index
497- **[indices_reference](https://idc-index.readthedocs.io/en/latest/indices_reference.html)** — external index-table docs (may be ahead of the installed version)
498- **Citation**: Fedorov, A., et al. "National Cancer Institute Imaging Data Commons: Toward Transparency, Reproducibility, and Scalability in Imaging Artificial Intelligence." RadioGraphics 43.12 (2023). https://doi.org/10.1148/rg.230180
499- **Skill updates**: [releases page](https://github.com/ImagingDataCommons/imaging-data-commons-skill/releases); watch the repository (Watch → Custom → Releases)

Resources

Reference guides and their decision triggers are listed in Quick Navigation above.

  • IDC Portal: https://portal.imaging.datacommons.cancer.gov/explore/
  • Documentation: https://learn.canceridc.dev/ — Tutorials: https://github.com/ImagingDataCommons/IDC-Tutorials
  • User Forum: https://discourse.canceridc.dev/ — idc-index: https://github.com/ImagingDataCommons/idc-index
  • indices_reference — external index-table docs (may be ahead of the installed version)
  • Citation: Fedorov, A., et al. "National Cancer Institute Imaging Data Commons: Toward Transparency, Reproducibility, and Scalability in Imaging Artificial Intelligence." RadioGraphics 43.12 (2023). https://doi.org/10.1148/rg.230180
  • Skill updates: releases page; watch the repository (Watch → Custom → Releases)
Raw lines 490 to 499

From K-Dense-AI/scientific-agent-skills at 5f2bc03, 2026-10-26. Not read by a model yet. Summary and techniques by Claude Opus 5.5 on 2026-11-06.