# GA4GH TRS Tool Registry Extractor (`datamule/ga4gh-trs-tool-registry-extractor`) Actor

Point at ANY GA4GH TRS v2 registry (Dockstore, WorkflowHub) and pull tools, workflows, tool classes, versions and CWL/WDL/NFL/GALAXY descriptors into clean flat rows. Auto-pages via next\_page, round-trips %2F tool ids, surfaces each version's descriptor types. Pay per tool.

- **URL**: https://apify.com/datamule/ga4gh-trs-tool-registry-extractor.md
- **Developed by:** [Datamule](https://apify.com/datamule) (community)
- **Categories:** Developer tools, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.35 / 1,000 tool rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## GA4GH TRS Tool Registry Extractor

Point at **any GA4GH TRS (Tool Registry Service) v2 registry** and pull its tools,
workflows, tool classes, versions and workflow descriptors into clean, flat,
tabular rows — one actor for the whole standard, no per-registry scraper.

TRS is the [Global Alliance for Genomics & Health](https://www.ga4gh.org/) standard
for **describing and discovering runnable analysis tools and workflows**. Registries
like **Dockstore** and **WorkflowHub** all expose the same uniform `/ga4gh/trs/v2`
grammar, so this actor harvests any of them the same way.

### What it does

Give it one or more TRS **base URLs** and a **mode**:

| Mode | Returns |
|------|---------|
| `tools` | One row per tool / workflow (paginated, filterable by name, class, organization, registry, author, checker). |
| `toolClasses` | The registry's tool-class taxonomy (CommandLineTool, Workflow, Notebook, Service…). |
| `service-info` | The registry's identity, TRS spec version and software version. |
| `tool-versions` | One row per version of each tool (all tools, or a given `toolId` list). |
| `tool-descriptor` | The descriptor file (CWL / WDL / Nextflow / Galaxy / Snakemake) for each version — surfacing whatever types the version actually advertises. |

Every row is normalized to the **same flat shape** regardless of which registry it
came from, plus a lossless `_raw` copy of the original record and `_source` /
`_trsName` / `_registrySoftware` provenance.

### Verified registries (live)

- **Dockstore** — `https://dockstore.org/api/ga4gh/trs/v2` (2,200+ tools & workflows)
- **WorkflowHub** — `https://workflowhub.eu/ga4gh/trs/v2` (1,500+ workflows)

Any other conformant GA4GH TRS v2 endpoint works too — just pass its base URL.

### Example input

List workflows on Dockstore:

```json
{
  "sources": ["https://dockstore.org/api/ga4gh/trs/v2"],
  "mode": "tools",
  "toolClass": "Workflow",
  "maxRecords": 500
}
```

Pull the CWL/WDL/Nextflow/Galaxy descriptor files for one tool:

```json
{
  "sources": ["https://dockstore.org/api/ga4gh/trs/v2"],
  "mode": "tool-descriptor",
  "toolId": ["quay.io/collaboratory/dockstore-tool-bedtools-genomecov"]
}
```

Harvest two registries in one run:

```json
{
  "sources": [
    "https://dockstore.org/api/ga4gh/trs/v2",
    "https://workflowhub.eu/ga4gh/trs/v2"
  ],
  "mode": "tools",
  "maxRecords": 1000
}
```

### Output fields

Common: `_source`, `_mode`, `_trsName`, `_trsVersion` (TRS spec, e.g. 2.0.1),
`_apiVersion` (registry software version), `_registrySoftware`, `id`, `name`,
`description`, `organization`, `toolclass`, `url`, `aliases`, `_raw`.

Tools add `versionsCount`, `descriptorTypes`, `has_checker`, `checker_url`.
Versions add `toolId`, `versionId`, `versionName`, `authors`, `imageCount`,
`containerfile`, `is_production`, `verified`.
Descriptors add `descriptorType`, `descriptorContent`, `descriptorUrl`,
`descriptorContentLength`.

### How it handles the tricky bits

- **Pagination is followed the way each registry advertises it** (via the
  `next_page` response header), so it works whether a host counts pages or rows —
  and every tool is de-duplicated so overlaps never double-emit.
- **Tool IDs that contain slashes** (e.g. `quay.io/org/tool`) are URL-encoded
  correctly for every sub-request.
- **Descriptor languages are read from each version**, never assumed — a Galaxy
  workflow returns its Galaxy descriptor, a CWL tool returns CWL.
- **Honest results only.** A registry that errors or times out is skipped with a
  warning and the run continues; if *no* source returns anything the run fails
  loudly instead of emitting an empty success.

### Pricing

Pay-per-event: you are charged **per tool / row returned**. No subscription, no
platform-usage surprises — you pay only for the records you actually get, with
volume discounts at higher usage tiers.

### Auth

The public registries need no authentication. For a private or auth-gated TRS
endpoint, supply a `bearerToken` (sent as `Authorization: Bearer …`, never logged)
or arbitrary `extraHeaders`.

# Actor input Schema

## `sources` (type: `array`):

One or more GA4GH TRS (Tool Registry Service) v2 base/root URLs. Examples: https://dockstore.org/api/ga4gh/trs/v2 (Dockstore) and https://workflowhub.eu/ga4gh/trs/v2 (WorkflowHub). Point at the TRS BASE — do NOT append an endpoint like /tools; the actor builds the paths for you.

## `mode` (type: `string`):

Which part of the registry to harvest. 'tools' lists tools/workflows (paginated, filterable). 'toolClasses' returns the registry taxonomy. 'service-info' returns the registry's identity. 'tool-versions' returns one row per version (all tools, or the ones in Tool ID). 'tool-descriptor' returns the descriptor file (CWL/WDL/NFL/GALAXY…) for each version — surfacing whatever types the version advertises.

## `toolId` (type: `array`):

Optional. For 'tool-versions' or 'tool-descriptor' mode, restrict to these TRS tool ids instead of walking every tool. Use the id EXACTLY as the registry returns it (e.g. quay.io/collaboratory/dockstore-tool-bedtools-genomecov on Dockstore, or 2 on WorkflowHub) — the actor URL-encodes the slashes for you. Leave empty to harvest versions/descriptors across all tools (bounded by Max records).

## `descriptorType` (type: `string`):

Optional. For 'tool-descriptor' mode, pin a single descriptor language to fetch (CWL, WDL, NFL for Nextflow, GALAXY, or SMK for Snakemake). Leave empty to fetch every type each version actually advertises — different tools expose different languages, so the default follows the version. In 'tools' mode this is also forwarded as the TRS descriptorType filter.

## `versionId` (type: `string`):

Optional. For 'tool-descriptor' mode, restrict to a single version (matched against the version id OR name). Leave empty to emit descriptors for every version of each selected tool.

## `includeDescriptorContent` (type: `boolean`):

For 'tool-descriptor' mode: when true (default), each row carries the descriptor file's text in descriptorContent (capped for very large files). Turn off to emit only the descriptor's metadata + URL (smaller rows).

## `name` (type: `string`):

Optional TRS /tools filter. Free-text tool name / search query (Dockstore treats this as a search over name & description).

## `toolClass` (type: `string`):

Optional TRS /tools filter. Restrict to a tool class, e.g. Workflow, CommandLineTool, Notebook, Service. Use 'toolClasses' mode first to see what a registry offers.

## `organization` (type: `string`):

Optional TRS /tools filter. Restrict to tools published by an organization (e.g. collaboratory, nf-core).

## `registry` (type: `string`):

Optional TRS /tools filter. Restrict to tools whose image lives in this container registry host (e.g. quay.io).

## `author` (type: `string`):

Optional TRS /tools filter. Restrict to tools by author.

## `checker` (type: `boolean`):

Optional TRS /tools filter. When true, restrict to tools that have a checker workflow. Leave unset for all tools.

## `extraParams` (type: `object`):

Optional extra TRS query parameters as a JSON object, forwarded verbatim on /tools requests (e.g. an id or alias filter). The limit/offset paging is managed for you and cannot be overridden.

## `maxRecords` (type: `integer`):

Maximum total rows to emit across all sources. Pagination (following the registry's next\_page) is followed until this cap is reached, so a huge registry never runs forever. Each returned row is one billable event. Default 1000.

## `bearerToken` (type: `string`):

Optional OAuth2 bearer token for auth-gated registries or private tools. Sent as Authorization: Bearer \*\*\*. NOT required for public registries (Dockstore, WorkflowHub) — leave empty. Never logged.

## `extraHeaders` (type: `object`):

Optional extra HTTP headers to send with every request, as a JSON object (e.g. an API-key header a specific registry requires). Leave empty for public registries.

## Actor input object example

```json
{
  "sources": [
    "https://dockstore.org/api/ga4gh/trs/v2"
  ],
  "mode": "tools",
  "descriptorType": "",
  "includeDescriptorContent": true,
  "checker": false,
  "maxRecords": 1000
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "sources": [
        "https://dockstore.org/api/ga4gh/trs/v2"
    ],
    "maxRecords": 1000
};

// Run the Actor and wait for it to finish
const run = await client.actor("datamule/ga4gh-trs-tool-registry-extractor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "sources": ["https://dockstore.org/api/ga4gh/trs/v2"],
    "maxRecords": 1000,
}

# Run the Actor and wait for it to finish
run = client.actor("datamule/ga4gh-trs-tool-registry-extractor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "sources": [
    "https://dockstore.org/api/ga4gh/trs/v2"
  ],
  "maxRecords": 1000
}' |
apify call datamule/ga4gh-trs-tool-registry-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=datamule/ga4gh-trs-tool-registry-extractor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/Ue7om7MCKIlUtMKu2/builds/Wvpg7AFX6MbMJYJN3/openapi.json
