just-prs-mcp
The just-prs-mcp server enables AI agents to search, compute, and interpret Polygenic Risk Scores (PRS) using 5,000+ published models from the PGS Catalog.
Search & Discovery
Search the PGS Catalog by free text (
search_scores), retrieve detailed score metadata (score_info), and fetch best published evaluation metrics — OR, HR, AUROC, C-index, ancestry info (best_performance).Find traits by name, returning EFO IDs, synonyms, and associated PGS models (
search_traits,trait_info).
Genome Processing
Download public sample genomes (Anton, Livia) from Zenodo (
download_sample_genome).Normalize VCF files into quality-filtered genotype Parquet format for fast, reusable scoring (
normalize_vcf).
PRS Computation
Compute a single PRS for one VCF against one model (
compute_prs), run batch scoring across many models (compute_prs_batch), or score all models for a specific trait (compute_prs_by_trait).
Interpretation & Risk
Estimate population percentile using a 3-tier fallback (reference panel → theoretical → AUROC approximation), broken down by 1000 Genomes superpopulation (
percentile).Convert a PRS z-score into lifetime disease probability and risk ratio using prevalence data (
absolute_risk).Classify result reliability as High/Moderate/Low based on match rate and AUROC (
assess_quality).Compare and rank PRS results across multiple individuals (
compare_genomes).
Extended Mode (opt-in): batch downloads, array data normalization (23andMe/AncestryDNA), HuggingFace upload, multi-method risk estimation, prevalence priors, and reference panel scoring via pgenlib.
Allows downloading public whole-genome sequencing sample genomes from Zenodo for PRS computation and analysis.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@just-prs-mcpsearch for type 2 diabetes scores"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
just-prs-mcp: Conversational and Programmatic Polygenic Risk Scores
just-prs-mcp brings the
just-prs bioinformatics toolbox into
Claude, Cursor, Codex, and any other
Model Context Protocol client. It exposes
typed tools for searching 5,000+ published polygenic scoring models,
normalizing VCF and consumer-array data, computing PRS, comparing results with
reference populations, estimating absolute risk, and assessing result quality.
It is useful whether you are:
a bioinformatician adding reproducible PRS operations to an MCP-enabled research environment;
a researcher or analyst who wants to inspect models and evidence through a conversational interface;
a Claude or Cursor user who wants to analyze a local genome without writing a pipeline; or
a developer embedding PRS tools in an agent, application, or internal system.
The server runs locally by default, needs no API key, and does not upload your
genome. The underlying scoring, catalog, and reference-panel logic remains in
just-prs; this repository provides the MCP tools, Claude plugin, packaging,
prompts, and guided interpretation workflows.
The server is published in the BioContextAI Registry, a community registry for agentic biomedical systems, where researchers can discover its scientific scope, supported features, and registry metadata.
See the evidence, not just a score

Instead of hiding uncertainty behind one number, the server gives clients the evidence needed to judge a result: PGS IDs, variant-match rates, model quality, reference population, percentiles, absolute-risk context, and agreement or conflict across models for the same trait.
Related MCP server: GeneChat MCP Server
How it fits into your workflow
flowchart LR
U["Researcher, bioinformatician,<br/>or genome owner"]
C["Claude · Cursor · Codex<br/>or another MCP client"]
M["just-prs-mcp<br/>typed tools + prompts + skill"]
J["just-prs<br/>scoring and catalog engine"]
V["Local VCF / array"]
P["PGS Catalog metadata<br/>and reference distributions"]
U --> C --> M --> J
V --> J
P --> J
J --> M --> CUse case | Recommended interface |
Ask questions and receive an evidence-aware interpretation | |
Add structured PRS tools to Claude, Cursor, Codex, or an internal system | |
Build scripts, notebooks, pipelines, or a browser UI directly | |
Evaluate quickly without personal genomic data |
What can you ask?
These are queries an MCP client can resolve with the current tools. One genome
is always a one-element samples list; two or more people use the same tools
with a longer list. compute_prs_by_trait interprets percentiles by default.
"Search the PGS Catalog for type 2 diabetes and explain which models are best supported."
"Download Anton's public genome and compute PRS for type 2 diabetes.
Give me the HTML report link and say which models agree."
"What's Livia's genetic predisposition for venous thromboembolism? Include
absolute risk, not just a percentile."
"Compare Anton and Livia on intelligence. Show all associated models,
use the median, check whether a high percentile is favorable, and open
the overlay HTML report."
"Detect the build and ancestry of this VCF, then score coronary artery disease
with superpopulation=auto."
"Compute BMI PRS directly from ~/data/me.vcf.gz. Do not normalize it first;
if list_genomes already has a cached Parquet for this genome, reuse that path."
"I already have result JSON from a previous run — plot the trait panel and
build the Ask-AI write-up from those result_paths."
"Score this genome against PGS000337 only, then give the percentile and quality."The tool always returns html_link: an HTTP URL over Streamable HTTP
(GET /reports/<file> on the MCP origin) or a file:// URI over local
stdio. The model must quote that exact target as a markdown link and tell
the user to open the interactive report; it must not fetch or paste the HTML.
The client chooses the tools and keeps the provenance (PGS IDs, match rates, quality, ancestry). You can also call every tool from your own MCP application.
Connect Claude, Cursor, or another MCP client
Local use requires uv. uvx creates an isolated
environment for the published package, so there is no repository clone or
project-level installation step.
Claude Code
Add the MCP server:
claude mcp add just-prs -- uvx just-prs-mcp@latest stdio
claude mcp listUse a pinned version in reproducible research environments:
claude mcp add just-prs -- uvx just-prs-mcp@0.5.0 stdioFor the MCP server plus the bundled trait-interpretation skill, use the Claude plugin.
Cursor
Add to .cursor/mcp.json (project) or your user MCP config
(Cursor MCP docs):
{
"mcpServers": {
"just-prs": {
"command": "uvx",
"args": ["just-prs-mcp@latest", "stdio"],
"env": { "PRS_MCP_MODE": "essentials" }
}
}
}From a checkout, uv run just-prs-mcp stdio is the same server. File log:
<cache>/logs/mcp.log. HTTP (just-prs-mcp http, then
"url": "http://127.0.0.1:3011/mcp") is optional if you want a process that
outlives the Cursor session.
Codex
Install the native plugin from the shared DNA Seq marketplace to get both the MCP server and the evidence-aware trait-interpretation skill:
codex plugin marketplace add dna-seq/dna-seq-claude-marketplaceIn Codex Desktop, open Plugins, choose DNA Seq Genomics, and install just-prs: Polygenic Risk Scores. If no Codex CLI is installed, clone the marketplace repository and open that checkout in Codex Desktop; its repository marketplace is discovered automatically.
For a tools-only configuration, add this to ~/.codex/config.toml:
[mcp_servers.just-prs]
command = "uvx"
args = ["just-prs-mcp@latest", "stdio"]Other MCP clients and internal systems
Use the same local stdio process:
{
"command": "uvx",
"args": ["just-prs-mcp@latest", "stdio"],
"env": {
"PRS_MCP_MODE": "essentials"
}
}The server is built with FastMCP and returns structured Pydantic outputs, so it can be used interactively or orchestrated by your own MCP client.
Claude plugin
The repository is also packaged as a Claude Code / Cowork plugin.
.claude-plugin/plugin.json registers the
prs-trait-interpretation skill, while .mcp.json launches the
MCP server through uvx. The skill guides Claude through model selection,
quality filtering, percentile interpretation, model agreement, and research-use
caveats rather than treating the first available score as definitive.
Install it from the shared marketplace:
claude plugin marketplace add dna-seq/dna-seq-claude-marketplace
claude plugin install just-prs@dna-seqOr use the working tree directly during development:
claude plugin validate .
claude --plugin-dir .Or build the minimal ZIP for manual upload in Claude Desktop / Cowork:
uv run pack plugin
# dist/just-prs-claude-plugin-<version>.zipThe ZIP contains only the plugin manifest, MCP configuration, skill, README, and license. See the official Claude plugin documentation.
Claude Desktop (.mcpb extension)
If you only need the MCP tools, package a Claude Desktop extension:
uv run pack mcpb
# dist/just-prs-mcp-<version>.mcpbDouble-click the .mcpb or drag it into Claude Desktop. The extension still
runs the server locally. Metadata and configurable options are declared in
manifest.json.
Version pinning tip
uvx caches the first version it resolves for a bare package name. Prefer
just-prs-mcp@latest or just-prs-mcp@<version> — avoid the bare name.
Use --mode extended or PRS_MCP_MODE=extended for bulk downloads, HuggingFace
upload, prevalence priors, multi-method absolute risk, and reference-panel
scoring.
From a clone (development)
The plugin's .mcp.json launches the pinned PyPI release. To run the working
tree while developing:
[mcp_servers.just-prs]
command = "uv"
args = ["run", "just-prs-mcp", "stdio"]What is a PRS?
Many traits and common diseases — type 2 diabetes, coronary artery disease, height, longevity — are polygenic: influenced by thousands of small genetic effects. A Polygenic Risk Score adds those effects and places the result relative to a reference population. It is not a diagnosis; it can visualize inherited predisposition and, where evidence allows, translate a percentile into an absolute-risk estimate.
What is MCP?
The Model Context Protocol lets AI assistants
and applications call external tools through a shared protocol. Here, MCP turns
the just-prs Python API into discoverable, typed operations with structured
inputs and outputs. A chat client can use them conversationally; a
bioinformatics platform can orchestrate the same operations programmatically.
Contents
Quickstart (developers)
uv sync # deps (incl. dev)
uv sync --extra reference # + pgenlib (Linux/WSL)
uv run just-prs-mcp stdio # stdio for MCP clients
uv run just-prs-mcp stdio --mode extended # full tool surface
uv run just-prs-mcp http # HTTP (default :3011)
uv run fastmcp dev fastmcp.json # MCP Inspector
uv run pytest
uv run ruff check .
uv run pyrightThe server boots with no environment configured — every setting is optional.
Test genomes (quick play)
Two public WGS datasets from just-dna-lite are built in:
Sample | Zenodo | VCF | Size | License | Parameter |
Anton Kulaga |
| ~482 MB | CC0 |
| |
Livia Zaharia |
| ~349 MB | CC-BY-4.0 |
|
"Download Anton's sample genome and compute the PRS for type 2 diabetes."Typical tool chain: download_sample_genome → (auto-normalize) →
compute_prs_by_trait → percentile → absolute_risk → optional
plot_trait_panel / build_prs_prompt. Download both anton and livia for
a two-person comparison.
Tools
Essentials (always available)
Tool | Description |
| Search the PGS Catalog by free text |
| Cleaned metadata for one PGS ID |
| Best evaluation metrics (OR / HR / AUROC / C-index) |
| REST trait search with synonym retry |
| Trait by EFO / MONDO ID + associated PGS IDs |
| Inventory of downloaded and normalized genomes in the cache |
| Fetch a public sample WGS VCF from Zenodo (auto-normalizes by default; can take several minutes) |
| Optional VCF → reusable genotype Parquet preprocessing; never required before compute |
| Detect build, WGS/array/gVCF, and inferred ancestry; recommends restoration + superpopulation |
| Score one genome against one PGS model ( |
| Score one genome against many PGS models |
| Score raw VCFs or Parquets for 1+ genomes ( |
| Poll a long scoring/download job ( |
| Recover a |
| Population percentile (reference panel / theoretical / AUROC fallback) |
| Absolute disease risk from a PRS z-score + prevalence |
| Quality label + interpretation (pure logic, no I/O) |
| Cross-genome comparison + optional just-prs LLM prompt |
| Reusable |
| just-prs trait HTML report; always returns |
Extended (opt-in via --mode extended)
Tool | Description |
| 23andMe / AncestryDNA → Parquet |
| One harmonized scoring file from EBI FTP |
| All PGS IDs on EBI FTP |
| All metadata sheets as Parquet |
| Many/all scoring files |
| Population prevalence priors for a score or trait |
| Multi-method absolute-risk estimation |
| Upload cleaned catalog to HuggingFace (needs token) |
| Fetch 1000G / HGDP+1kGP panel |
| Score against a reference panel (needs |
| PLINK2 binary ops (needs |
File paths: computation tools take local paths on the server filesystem. Over stdio that is your machine. Reference / pgen tools need
uv sync --extra reference(Linux/WSL).
Prompts and resources
Prompt | Description |
| Step-by-step: search → score raw VCF/Parquet inputs directly → interpret |
| End-to-end trait read (optional multi-genome compare) |
| Interpret a single PGS result (prefer |
| Interpret combined results across models / people |
Resource | Description |
| Reference panels, genome builds, and the active cache directory |
| JSON catalog of cached VCFs / Parquets (same as |
Typical MCP workflow
1. search_traits("venous thromboembolism") → trait ID (e.g. EFO_0001645)
2. download_sample_genome(sample="anton") → VCF (+ optional cached Parquet)
3. vcf_metainfo(vcf_path=...) → optional: build + ancestry
4. compute_prs_by_trait(trait_id, samples=["Anton=<raw VCF path>"],
superpopulation="auto") → TraitPRSReports
5. absolute_risk / assess_quality → as needed
6. build_prs_prompt(result_paths=...) → reusable LLM write-up
7. plot_trait_panel(result_paths=...) → html_link (HTTP or file://)Same tools for a two-person (or family) comparison — samples and
result_paths are always lists:
2. download_sample_genome("anton"); download_sample_genome("livia")
3. compute_prs_by_trait(trait_id,
samples=["Anton=<anton VCF>", "Livia=<livia VCF>"],
superpopulation="auto")
4. compare_genomes(result_paths=...) → 2+ genomes (median, not "best")
5. build_prs_prompt(result_paths=...) → comparison-first prompt
6. plot_trait_panel(result_paths=...) → overlay HTML (or html_link from step 3)compute_prs_by_trait returns a PRSJob immediately. Poll
prs_job_status(job_id, wait_seconds=25) until done. Then result is
TraitPRSReports (reports, result_paths, sample_labels, html_link,
plus transport-specific html_path / html_url). The job also copies
html_link onto the top-level record. One genome is n_samples=1.
There is no vcf_path argument — always samples. interpret defaults to
True; profile defaults to all (every associated score). Pass
profile="curated" only for the shortlist. Pass interpret=False only for
raw scores.
Raw VCF input is first-class: do not call normalize_vcf as a prerequisite.
Normalization is only an optional optimization for intentional repeated reuse.
If a normalized Parquet already exists, list_genomes exposes it.
normalize_vcf, download_sample_genome, and compute_prs_batch are the
same job+poll pattern. Do not start a second identical compute after a
timeout — call prs_job_status or list_prs_jobs instead.
Modes
PRS_MCP_MODE (env) or --mode (CLI), default essentials:
Mode | What's registered |
| Catalog + core compute/analyze + comparison. Smaller tool list for clients. |
| Batch downloads, HF upload, prevalence, multi-method risk, reference/pgen. |
Configuration
All settings are optional. See .env.example and
settings.py.
Variable | Description |
|
|
| Cache for catalog data, scoring files, panels, results |
| Default genome build ( |
| Default reference panel ( |
| DuckDB memory for batch scoring (e.g. |
| HuggingFace token for |
|
|
| Bind address for HTTP/SSE (default |
| Optional public origin for trait HTML ( |
| Transparently normalize/cache raw VCFs once for multi-score tools (default |
| Run VCF normalization and multi-score DuckDB/Polars work in |
| Native genomic workloads allowed per server process (default |
| How long a submitting |
| Logging level ( |
| Rotating file log (default |
Methodology
Percentile estimation
Percentiles use the 1000 Genomes Project phase 3 panel (2,504 individuals;
AFR, AMR, EAS, EUR, SAS) on GRCh38 harmonized scoring files. PRS is
Σ(effect_weight × dosage) for matched variants; the user sample is placed on
the same distribution.
Quality scoring
Synthetic quality score (0–100) from four tiers:
T1a: AUROC / C-index (strongest)
T1b: Beta only (0.95×)
T2: OR / HR only (0.90×; probit transform)
T3: No performance metric (0.6× floor)
Also factors cohort size, coverage, and harmonized-score penalty. Labels: High (≥70), Normal (≥50), Moderate (≥30), Low (<30).
Absolute risk
For disease traits, absolute_risk converts a z-score into lifetime probability
and risk ratio vs population average. risk_ratio 1.0 = average; >1 elevated;
<1 reduced. If prevalence data is unavailable, the tool reports that explicitly.
Interpreting results
Built-in instructions guide agents to:
Present PRS as predisposition, not a trait measurement
Call
absolute_riskafterpercentilefor disease traitsRespect trait directionality
Flag ancestry mismatches, low coverage, and model disagreement
Cite PGS IDs with links to the PGS Catalog
See the just-prs interpretation guide.
Research use only
PRS results are for research and educational purposes only and do not constitute medical advice.
PRS models are statistical proxies, not causal readouts.
Catalog listing does not mean clinical readiness.
Environment, lifestyle, age, sex, and biomarkers often matter as much as or more than common-variant signal.
Low match rates (common with consumer arrays) mean a noisier, less informative score.
Ancestry matters: accuracy often drops outside the training population.
A high PRS is not a diagnosis; a low PRS is not a guarantee.
Privacy
Genomic computation is designed to stay local:
Over stdio / Claude Desktop / the Claude plugin, tools read paths on your machine. VCFs are not uploaded to a third-party API by this server.
There is deliberately no client-to-server VCF upload or remote-fetch tool.
Optional HuggingFace upload (
push_catalog_to_hf, extended mode) sends catalog metadata, not personal genotype files, and only when you invoke it with a token.
Deployment
Docker:
docker build -t just-prs-mcp . && docker run -p 3011:3011 just-prs-mcpSmithery (GitHub connect): repo is ready —
smithery.yaml(runtime: python)[tool.smithery]pointing atjust_prs_mcp.server:start_mcp_smithery.
Push this repo to GitHub.
Follow the current Smithery publishing guide.
Optional: set
PRS_MCP_MODE=extended(or otherPRS_MCP_*) in the Smithery project env if you want the full tool surface on the hosted instance. Local smoke-test of the same entrypoint:uv run smithery dev/uv run playground/uv run start.
Declarative:
fastmcp.jsonforfastmcp run/fastmcp dev
Project layout
src/just_prs_mcp/
server.py build_server(), CLI, graceful shutdown, Smithery entrypoint
settings.py pydantic-settings (PRS_MCP_*), safe defaults
client.py shared PRSCatalog / REST-client construction + adapters
models.py Pydantic tool I/O models (+ reused just-prs models)
jobs.py PRSJob store, submit/poll, scoring semaphore
native_worker.py isolated native scoring / normalize subprocess
plugin_package.py minimal Claude plugin ZIP builder
logging_setup.py stdlib logging → stderr + `<cache>/logs/mcp.log`
tools/
catalog.py essentials — PGS Catalog search and lookup
compute.py essentials — normalize, compute, compare, prompts
extended.py extended — batch downloads, HF upload, prevalence, multi-risk
reference.py extended — reference-panel / pgen scoring (pgenlib)
tests/ in-memory client tests (wiring + logic, no network)License
MIT — see LICENSE.
Available Tools
20 toolsabsolute_riskAbsolute riskARead-onlyIdempotent
Estimate absolute disease risk from a PRS z-score and population prevalence.
Joins the score's trait to prevalence + effect-size data. z_score is
the PRS in standard deviations from the population mean. Raises if the
required prevalence / effect-size data is unavailable for this score.
| Name | Required | Description | Default |
|---|---|---|---|
| sex | No | ||
| pgs_id | Yes | ||
| z_score | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| method | Yes | Estimation method: 'or_per_sd' or 'auc_bivariate' |
| caveats | No | Warnings about estimation quality (e.g. 'cohort prevalence used, not population') |
| confidence | Yes | Data quality confidence: 'high', 'moderate', or 'low' |
| risk_ratio | Yes | Risk ratio vs population average (e.g. 1.64x) |
| absolute_risk | Yes | Estimated absolute risk (e.g. 0.18 = 18% lifetime risk) |
| prevalence_type | Yes | Type of prevalence: 'lifetime', 'point', or 'cohort' |
| prevalence_source | Yes | Where the prevalence data came from |
| effect_size_citation | No | Paper citation for the OR/AUROC used (e.g. 'Smith et al. 2023, JAMA (PMID: 12345678)') |
| population_prevalence | Yes | Population baseline prevalence (e.g. 0.11 = 11%) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint, idempotentHint, etc.), the description discloses that the tool raises an error if prevalence/effect-size data is missing. This adds meaningful behavioral context without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is remarkably concise with three front-loaded sentences. Key information (purpose, join behavior, parameter meaning, error condition) is included without redundancy or extraneous detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has an output schema, so return values are covered. The description explains the main functionality, parameter z_score, and the error case. It could clarify that prevalence and effect-size data come from internal sources, but it's mostly complete for a 3-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must explain all parameters. Only z_score is explicitly described (as PRS in standard deviations). pgs_id is implied but not detailed, and sex is not mentioned at all. This is insufficient compensation for the lack of schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool estimates absolute disease risk from a PRS z-score and population prevalence, with a specific verb 'estimate' and resource 'absolute disease risk'. It adds context about joining data and error conditions, making the purpose precise and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implicitly guides usage by specifying requirements (z-score and available prevalence data) and the error case when data is unavailable. While no sibling tools exist to compare against, this provides clear context for when the tool is applicable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assess_qualityAssess qualityARead-onlyIdempotent
Classify and interpret a PRS result's quality (pure logic — no I/O).
match_rate is the fraction of scoring variants matched (0-1). Returns
a quality label/color and a human-readable interpretation combining match
rate, AUROC, and (optionally) the result percentile. Pass
percentile_method / reliable / caveat from the percentile
tool so the summary describes how the percentile was actually derived and
echoes any low-coverage caveat.
| Name | Required | Description | Default |
|---|---|---|---|
| auroc | No | ||
| caveat | No | ||
| reliable | No | ||
| match_rate | Yes | ||
| percentile | No | ||
| percentile_method | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| summary | Yes | Human-readable interpretation. |
| quality_color | Yes | Semantic color token for the label. |
| quality_label | Yes | High / Moderate / Low / Very Low. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, lowering the bar. The description adds behavior context beyond annotations by explaining the tool's core logic: it combines match rate, AUROC, and optionally result percentile into a quality label/color and interpretation, and it echoes low-coverage caveats. This goes beyond simple read-only claims and details what the tool actually computes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is reasonably concise and front-loaded with the core purpose. The additional paragraph about parameter provenance and return structure earns its place, as it clarifies how to pass percentile-derived fields. It's slightly dense with backticks, but the content is structured and not redundant with the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description doesn't need to detail return values, but it does explain what the interpretation combines and how the summary derives from passed parameters. It covers the core inputs and logic, and provides important context about the dependency on the percentile tool. Given the tool's moderate complexity, the description is sufficiently complete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains match_rate as 'the fraction of scoring variants matched (0-1)', and references AUROC, result percentile, percentile_method, reliable, and caveat, indicating their roles in the interpretation. While it doesn't formally define each parameter, it gives enough meaning for an agent to understand how the parameters relate to the output.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Classify and interpret a PRS result's quality (pure logic — no I/O).' This clearly distinguishes it from sibling tools by emphasizing that it performs pure logic with no I/O, and the resource (PRS result quality) is precise. The rest of the description reinforces the purpose by explaining what it returns (label/color and interpretation).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit workflow guidance: 'Pass percentile_method / reliable / caveat from the percentile tool so the summary describes how the percentile was actually derived.' This tells the agent when to use this tool (after obtaining percentile output) and how to wire it. It doesn't explicitly name alternative tools or say when not to use it, but the 'pure logic — no I/O' hint and reference to the percentile tool provide sufficient context for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
best_performanceBest performanceARead-onlyIdempotent
Look up the best evaluation performance for a score (largest sample, EUR-preferred).
Returns parsed effect sizes (OR/HR/Beta) and classification metrics (AUROC/C-index) plus pre-formatted display strings.
| Name | Required | Description | Default |
|---|---|---|---|
| pgs_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| found | Yes | Whether a performance row was found. |
| pgs_id | Yes | PGS Catalog Score ID. |
| effect_size | No | Formatted effect size, e.g. 'OR=1.55 [1.52-1.58]'. |
| hr_estimate | No | Hazard ratio per SD. |
| or_estimate | No | Odds ratio per SD. |
| beta_estimate | No | Beta per SD. |
| n_individuals | No | Evaluation sample size. |
| ancestry_broad | No | Evaluation cohort ancestry. |
| auroc_estimate | No | AUROC. |
| classification | No | Formatted classification, e.g. 'AUROC=0.72'. |
| cindex_estimate | No | Harrell's C-index. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that the tool is read-only, idempotent, and non-destructive. The description adds useful behavioral context beyond the annotations: it explains how results are chosen ('largest sample, EUR-preferred') and what output formats are provided, which is genuine supplementary information.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: first sentence states the core action, second sentence summarizes the output. Every clause adds value and nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read-only lookup with a known output schema, the description provides necessary selection criteria and return-item summary. It lacks an explicit usage-guidance statement, but overall it is sufficient for this tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema only exposes pgs_id without any description, leaving 0% schema coverage. The tool description indirectly connects pgs_id to 'a score', which helps but does not define the identifier format or its origin. Since the parameter name is self-descriptive and the tool context implies polygenic score, this is adequate but minimal.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Look up the best evaluation performance for a score' and immediately clarifies the selection criteria ('largest sample, EUR-preferred'). It also names the returned data types, distinguishing it from sibling tools like search_scores or score_info.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool—when parsed effect sizes and classification metrics are needed—but it does not explicitly state when to use this tool over alternatives. No exclusion conditions or alternative tool references are provided, making the guidance indirect rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
build_prs_promptBuild PRS promptARead-onlyIdempotent
Build the reusable just-prs LLM prompt from saved by-trait results.
This is the MCP equivalent of prs prompt / the UI Ask-AI buttons.
result_paths is always a list (one genome is fine; two or more
becomes a comparison-first prompt). The returned prompt can be
followed in this conversation or pasted into another assistant. Set
include_url=True with assistant claude/chatgpt/perplexity/grok
for a prefilled link.
kind: trait_results (default, full per-model panel),
trait_summary (aggregated cards), or score (one PGS ID; pass
pgs_id or the first scored row is used).
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | trait_results | |
| limit | No | ||
| pgs_id | No | ||
| ancestry | No | EUR | |
| assistant | No | other | |
| include_url | No | ||
| model_scope | No | usable | |
| result_paths | Yes | ||
| genome_labels | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | No | Optional prefilled assistant URL (claude / chatgpt / perplexity / grok) when include_url=True. 'other' is paste-only. |
| kind | Yes | 'score' (one PGS result), 'trait_summary' (aggregated cards), or 'trait_results' (full per-model panel; multi-sample when several genomes). |
| trait | Yes | Trait label used in the prompt. |
| prompt | Yes | Ready-to-paste interpretation prompt. Pipe it into another LLM, or follow it yourself. Multi-sample prompts are comparison-first. |
| summary | Yes | Human-readable summary of what the prompt covers. |
| assistant | Yes | Character-budget target: claude, chatgpt, perplexity, grok, or other. |
| n_samples | Yes | Number of genomes covered by the prompt. |
| char_limit | Yes | Character budget applied to the prompt. |
| model_scope | Yes | just-prs model scope (usable / all / high_quality / high_moderate). |
| prompt_chars | Yes | Length of the returned prompt text. |
| sample_names | Yes | Genome labels in prompt order. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey readOnlyHint, idempotentHint, and destructiveHint safety traits. The description adds meaningful behavioral context: multiple `result_paths` produce a comparison-first prompt, `include_url=True` with specific assistants generates a prefilled link, and `kind='score'` uses `pgs_id` or the first scored row. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first sentence, and the following sentences each add necessary behavior or parameter detail. It is reasonably compact for a 9-parameter tool, though a more structured list format could improve scannability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core purpose, prompt usability, comparison behavior, URL prefill options, and `kind` variants, while the output schema and annotations cover return values and safety. Auxiliary parameters like `limit`, `ancestry`, `model_scope`, and `genome_labels` are not explained, but their schema defaults provide partial context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema coverage, the description carries the parameter-semantics burden. It explains `result_paths`, `kind`, `include_url`, `assistant`, and `pgs_id`, but leaves `limit`, `ancestry`, `model_scope`, and `genome_labels` without any descriptive guidance, relying solely on their names and defaults.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Build the reusable just-prs LLM prompt from saved by-trait results.' It further anchors the tool as the MCP equivalent of `prs prompt` / the UI Ask-AI buttons, which clearly distinguishes it from sibling compute, plotting, and query tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context on when to use the tool: when a reusable prompt is needed from saved by-trait results and when the prompt may be used in-conversation or pasted elsewhere. It also explains the one-vs-multiple genome behavior and the `kind` variants, but it does not explicitly name alternative tools or state when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compare_genomesCompare genomesARead-onlyIdempotent
Compare saved by-trait PRS reports across two or more genomes.
result_paths — the result_paths list from compute_prs_by_trait
(or any saved report JSONs). At least two paths are required. Files are
grouped by trait, so a family comparison across several traits is one call.
Rankings use just-prs summarize_trait_rows: the median in-scope
percentile is the headline (not a single "best" model). High percentile is
not automatically good or bad — interpret direction from the trait.
When every path is the same trait, include_prompt=True (default) attaches
the same multi-sample LLM prompt as prs prompt / the UI Ask-AI buttons.
| Name | Required | Description | Default |
|---|---|---|---|
| ancestry | No | EUR | |
| assistant | No | other | |
| model_scope | No | usable | |
| result_paths | Yes | ||
| genome_labels | No | ||
| include_prompt | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| prompt | No | just-prs multi-sample LLM prompt (same text as ``prs prompt`` / the UI Ask-AI buttons). Present when include_prompt=True and every path is the same trait. Multi-trait comparisons leave this null — call build_prs_prompt per trait. |
| traits | Yes | Per-trait comparison details. |
| summary | Yes | Human-readable summary of the comparison. |
| n_traits | Yes | Number of traits compared. |
| model_scope | No | just-prs trait-summary scope used for medians (usable / all / high_quality / high_moderate). |
| genome_labels | Yes | Labels of the compared genomes, in input order. |
| most_divergent_traits | Yes | Trait labels sorted by percentile_spread descending — traits where the genomes differ most, for the LLM to highlight. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and non-destructive behavior; the description adds meaningful context beyond that: rankings use the median in-scope percentile, high percentile is direction-dependent, and include_prompt attaches the same multi-sample LLM prompt as prs prompt/UI. This helps the agent interpret results and understand side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the main purpose and organized into focused paragraphs for inputs, ranking interpretation, and prompt behavior. It avoids obvious filler, though the internal 'just-prs' jargon and the conditional include_prompt detail keep it slightly above a minimal two-sentence description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core workflow, input provenance, and ranking interpretation, and an output schema exists so return-value details are not required. However, five optional parameters have no schema descriptions and are not explained here, which leaves the tool incomplete for non-default use cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% description coverage, so the description must compensate. It thoroughly explains result_paths (source, minimum count, grouping) and partially explains include_prompt, but leaves ancestry, assistant, model_scope, and genome_labels completely undefined. The required parameter is covered, but four optional parameters remain semantically opaque.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence names a specific action ('Compare saved by-trait PRS reports') and resource ('two or more genomes'), clearly distinguishing it from computing PRS or building prompts. It also states the expected input type and grouping behavior, so the purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: result_paths must come from compute_prs_by_trait or saved report JSONs, at least two paths are required, and files are grouped by trait. It does not explicitly enumerate when-not-to-use cases or alternative tools, but the source requirement and one-call family-comparison note provide strong usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compute_prsCompute PRSARead-onlyIdempotent
Compute a polygenic risk score for one genome against one PGS model.
Pass the raw VCF directly; a separate normalize_vcf call is not needed.
If this VCF has a fresh normalized cache, it is reused automatically;
genotypes_path is the explicit Parquet fast path. For a trait panel —
one genome or several — use
compute_prs_by_trait(samples=[...]), then
compare_genomes / build_prs_prompt / plot_trait_panel.
Reference restoration (F15/F22). reference_restoration fills a scoring
variant's missing reference allele from the precomputed reference-allele
universe (pulled from HuggingFace on first use) so a locus the sample is
confidently hom-ref at scores as dose-0 instead of being dropped as
unscorable-absent — recovering the ~50% coverage gap on genome-wide WGS
scores. Default "auto" detects the input: whole-universe restoration for
WGS, the matching chip scope for a genotyping array, off otherwise. Pass
"off", "wgs", or a chip id (e.g. "gsa_v3") to force a scope. The
result's variants_ref_resolved_panel / variants_ref_resolved_fasta
counters show how many loci were recovered.
Set infer_ancestry=True to also infer and attach the sample's genetic
ancestry (sample_ancestry). genotype_input_mode ("auto" /
"variant_only" / "all_sites") controls how absent loci are read.
Set attach_performance=True to embed the score's best published
performance (effect sizes, AUROC/C-index, evaluation ancestry) on the
result in the same call. The result also carries detected_genome_build /
build_mismatch from the VCF (F4).
Recommended follow-up: percentile then absolute_risk (disease
traits), or build_prs_prompt(kind='score') for a reusable LLM write-up.
| Name | Required | Description | Default |
|---|---|---|---|
| pgs_id | Yes | ||
| vcf_path | Yes | ||
| genome_build | No | ||
| genotypes_path | No | ||
| infer_ancestry | No | ||
| attach_performance | No | ||
| genotype_input_mode | No | auto | |
| reference_restoration | No | auto |
Output Schema
| Name | Required | Description |
|---|---|---|
| score | Yes | Computed polygenic risk score |
| pgs_id | Yes | PGS Catalog Score ID |
| z_score | No | Standardized score (score - reference_mean) / reference_std, set when a percentile was computed |
| ancestry | No | Ancestry superpopulation used for percentile (AFR, AMR, EAS, EUR, SAS) |
| match_rate | Yes | Fraction of scoring variants matched (0-1) |
| percentile | No | Estimated population percentile (0-100) from theoretical distribution |
| performance | No | Best available performance metric from PGS Catalog |
| absolute_risk | No | Absolute disease risk estimate based on PRS z-score and prevalence data |
| reference_std | No | Reference/theoretical distribution std used for the percentile and z-score |
| build_mismatch | No | True when the detected VCF build differs from the genome_build used for scoring |
| reference_mean | No | Reference/theoretical distribution mean used for the percentile and z-score |
| trait_reported | No | Reported trait for the score |
| variants_total | Yes | Total number of variants in scoring file |
| sample_ancestry | No | Inferred genetic ancestry of the sample (super-pop + confidence, fine population, informational mixture); populated when ancestry inference is requested |
| theoretical_std | No | Theoretical population SD of PRS: sqrt(sum(w_i^2 * 2 * p_i * (1-p_i))) |
| theoretical_mean | No | Theoretical population mean PRS computed from allele frequencies: sum(w_i * 2 * p_i) |
| variants_matched | Yes | Number of scoring variants matched in VCF |
| variants_no_call | No | Scoring loci present in the genotype input but carrying a missing/no-call GT |
| percentile_method | No | Method used to compute percentile: 'reference_panel', 'theoretical', or 'auroc_approx' |
| variants_observed | No | Scoring loci present in the genotype input with a genotype row |
| weight_mass_total | No | Sum of |effect_weight| over all scoring variants (per-dosage formats use max|dosage_k_weight|) |
| genotype_input_mode | No | How absent genotype loci were interpreted during scoring |
| variants_maf_filled | No | Absent loci filled with population MAF dosage (2 * allelefrequency_effect) instead of being unscorable |
| weight_mass_matched | No | Sum of |effect_weight| over matched scoring variants (per-dosage formats use max|dosage_k_weight|) |
| weight_mass_coverage | No | C_wt: weight_mass_matched / weight_mass_total — fraction of total effect-weight mass carried by matched variants |
| detected_genome_build | No | Genome build inferred from the VCF header/contigs (None if undetectable or genotypes were pre-normalized) |
| has_allele_frequencies | No | Whether the scoring file contained allelefrequency_effect data |
| variants_assumed_hom_ref | No | Absent loci treated as homozygous-reference under variant-only VCF semantics |
| variants_unscorable_absent | No | Absent loci that could not be scored because the reference allele was unknown |
| variants_ref_resolved_fasta | No | Absent loci whose missing reference allele was resolved from the reference FASTA faidx (subset of variants_assumed_hom_ref) |
| variants_ref_resolved_panel | No | Absent loci whose missing reference allele was resolved from the reference panel .pvar (subset of variants_assumed_hom_ref) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnly, idempotent), the description reveals behavioral details such as caching of normalized VCFs, automatic reuse of cached data, and the behavior of reference_restoration (auto, wgs, off) and genotype_input_mode. It also notes that ancestry inference and performance attachment are optional and controlled by flags.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is thorough but somewhat lengthy; it uses structured paragraphs and bold headings to organize information. While every sentence adds value, the level of detail might be slightly more than necessary, but it remains acceptable for a complex tool with many options.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers all aspects: purpose, usage, parameter semantics, and follow-up actions. It even hints at output fields like variants_ref_resolved_panel and detected_genome_build, providing a comprehensive context despite the lack of an explicit output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description provides detailed explanations for most parameters, including genotype_input_mode, reference_restoration, genotypes_path, infer_ancestry, and attach_performance. However, it does not explicitly explain the genome_build parameter, which is a minor gap given the schema has 0% description coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the function: compute a polygenic risk score for one genome against one PGS model. It distinguishes from batch and trait-panel alternatives by explicitly noting 'one genome against one PGS model'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit usage guidance, stating when to use compute_prs_by_trait for trait panels, and recommends follow-up operations like percentile, absolute_risk, or build_prs_prompt. It also explains the optional flags and their effects, giving a clear decision context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compute_prs_batchCompute PRS (batch)ARead-onlyIdempotent
Compute PRS for one genome against many PGS models.
Pass the raw VCF directly; a separate normalization call is not required.
The tool transparently creates or reuses a collision-safe normalized cache,
then uses the memory-safe DuckDB engine with spill-to-disk. It reuses the
scoring caches across scores. This is still one genome × many PGS IDs.
For a trait panel across people, use compute_prs_by_trait(samples=[...])
then compare_genomes / build_prs_prompt.
Set attach_performance=True to embed each score's best published
performance on its result in the same pass.
reference_restoration (default "auto") recovers absent-hom-ref
coverage on WGS/array input — see compute_prs; the reference-allele
universe is resolved once and reused across every score. genotype_input_mode
("auto" / "variant_only" / "all_sites") controls how absent loci
are read.
Returns a PRSJob immediately. When done, result is the list of
successful PRSResult objects. If status is queued or running, poll
prs_job_status(job_id, wait_seconds=25).
| Name | Required | Description | Default |
|---|---|---|---|
| pgs_ids | Yes | ||
| vcf_path | Yes | ||
| genome_build | No | ||
| attach_performance | No | ||
| genotype_input_mode | No | auto | |
| reference_restoration | No | auto |
Output Schema
| Name | Required | Description |
|---|---|---|
| tool | Yes | Tool that created the job. |
| error | No | Failure message when status is failed. |
| job_id | Yes | Pass this to prs_job_status until status is done or failed. |
| result | No | When status is done: the original tool payload (TraitPRSReports, NormalizeResult, OpResult, or a list of PRSResult). Read html_link / result_paths from this object. |
| status | Yes | queued/running: call prs_job_status. done: read result and html_link. failed: read error. Do not start a second identical compute while queued/running. |
| message | Yes | Latest progress line. |
| progress | No | Completed work units, when known. |
| html_link | No | PRIMARY REPORT DELIVERY TARGET. When set, put this exact value in the user reply as a markdown link and explicitly tell the user to open the interactive report. It is an HTTP URL when available and a file:// URI for local stdio. Never omit, fetch, or paste the HTML. |
| poll_with | No | Poll this tool with job_id. Optional wait_seconds keeps one poll under typical client timeouts (try 25). |
| created_at | Yes | UTC timestamp when the job was created. |
| html_error | No | Optional HTML-generation error. Scores remain valid when this is set. |
| progress_total | No | Total work units, when known. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnlyHint and idempotentHint, but the description adds substantial behavioral detail: it explains internal caching ('creates or reuses a collision-safe normalized cache'), the DuckDB engine with spill-to-disk, and the async job model with polling ('If status is queued or running, poll prs_job_status'). It also explains reference_restoration and genotype_input_mode behaviors. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed but well-structured, with a clear front-loaded purpose and paragraphs for usage, parameters, and async behavior. Every sentence adds value, though it is slightly long. The use of bold for key terms and explicit defaults aids readability. No excess fluff, but it could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 params, output schema, async job), the description covers most bases: it explains the async behavior and polling, parameter semantics for major parameters, and distinguishes from sibling tools. It references compute_prs for deeper detail on reference_restoration, which is acceptable. The only notable gap is the omission of genome_build, but overall it is quite complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 0% description coverage, so the description carries the full burden for parameter meaning. It explains attach_performance, reference_restoration, genotype_input_mode, and indirectly vcf_path and pgs_ids from the purpose. However, genome_build is not mentioned at all, leaving a gap. Overall it adds meaning beyond the bare schema but misses one parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Compute PRS for one genome against many PGS models' with a specific verb and scope. It explicitly distinguishes from siblings by saying 'For a trait panel across people, use compute_prs_by_trait(samples=[...])' and emphasizes 'This is still **one genome × many PGS IDs**.' This fully differentiates it from broader alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage context: it says no separate normalization is needed, and it directs users to alternative tools for trait panels. It also explains when to use attach_performance and how to poll with prs_job_status, giving clear when-to-use vs when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compute_prs_by_traitCompute PRS by trait (give user html_link)AIdempotent
Compute the PRS scores associated with a trait for one or more genomes.
REQUIRED REPORT DELIVERY: when html_link is set, your reply MUST include it as a markdown link (for example Open the interactive trait report) and explicitly tell the user to open it. This is the primary user-facing result, not an implementation detail. Do not skip the link, merely say the report was saved, fetch it, or paste the HTML. html_link is an HTTP URL when available and a file:// URI on local stdio.
Pass a raw .vcf/.vcf.gz path directly. Do NOT call normalize_vcf first as a prerequisite: multi-score tools transparently create or reuse a safe normalized cache, and single-score tools read the VCF directly. normalize_vcf is only an optional explicit step for custom filters. If list_genomes already shows a normalized Parquet, it can be passed directly.
trait_id may be an EFO or MONDO identifier. samples is always a
list (one genome is fine): each entry is Label=path or a bare path;
.parquet is a normalized genotype source. Every genome is auto-saved;
the return carries reports, result_paths, and (when models have
percentiles) the primary html_link plus transport-specific
html_url / html_path — the just-prs trait HTML report (same page
as prs plot trait -o *.html).
Pass result_paths to compare_genomes (2+), plot_trait_panel,
or build_prs_prompt.
Profile (curation): profile="all" (default) returns the raw
associated panel. profile="curated" is the interpreted shortlist —
it drops toy scores (<10 variants), scores with no performance evidence,
scores below the C_wt coverage floor, and de-dups score families.
interpret=True (default) attaches percentiles/quality per model.
Set interpret=False for raw scores only — the report then says so.
reference_restoration defaults to "auto". superpopulation
may be a 1000G code or "auto". Set include_prompt=True to also
attach the just-prs LLM prompt covering every genome in this call.
This tool returns a PRSJob immediately. If status is queued or running, call prs_job_status(job_id, wait_seconds=25) until done or failed. Do not start a second identical compute — the server reuses the in-flight job. When done, html_link and result (TraitPRSReports) are on the job. Native multi-score work is isolated in a child process so a DuckDB/Polars crash fails the batch without killing the MCP transport.
| Name | Required | Description | Default |
|---|---|---|---|
| build | No | ||
| limit | No | ||
| panel | No | ||
| top_n | No | ||
| profile | No | all | |
| samples | Yes | ||
| ancestry | No | ||
| trait_id | Yes | ||
| interpret | No | ||
| min_auroc | No | ||
| genome_build | No | ||
| include_prompt | No | ||
| min_match_rate | No | ||
| superpopulation | No | EUR | |
| include_children | No | ||
| genotype_input_mode | No | auto | |
| reference_restoration | No | auto |
Output Schema
| Name | Required | Description |
|---|---|---|
| tool | Yes | Tool that created the job. |
| error | No | Failure message when status is failed. |
| job_id | Yes | Pass this to prs_job_status until status is done or failed. |
| result | No | When status is done: the original tool payload (TraitPRSReports, NormalizeResult, OpResult, or a list of PRSResult). Read html_link / result_paths from this object. |
| status | Yes | queued/running: call prs_job_status. done: read result and html_link. failed: read error. Do not start a second identical compute while queued/running. |
| message | Yes | Latest progress line. |
| progress | No | Completed work units, when known. |
| html_link | No | PRIMARY REPORT DELIVERY TARGET. When set, put this exact value in the user reply as a markdown link and explicitly tell the user to open the interactive report. It is an HTTP URL when available and a file:// URI for local stdio. Never omit, fetch, or paste the HTML. |
| poll_with | No | Poll this tool with job_id. Optional wait_seconds keeps one poll under typical client timeouts (try 25). |
| created_at | Yes | UTC timestamp when the job was created. |
| html_error | No | Optional HTML-generation error. Scores remain valid when this is set. |
| progress_total | No | Total work units, when known. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations contradiction. The description clearly goes beyond the structured annotations by revealing that every genome is auto-saved, an in-flight compute is reused, work runs in a child process to avoid killing the MCP transport, and the returned PRSJob may be queued/running before completion. It also makes the non-negotiable user-facing html_link behavior explicit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded with the most important operational fact: the report link must be given to the user. It then covers input path handling, profile semantics, async behavior, and safety. It is longer than ideal, and paragraph-like formatting makes scanning a little harder, but most sentences carry necessary information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
It is largely complete for a complex 17-parameter compute-and-report tool: it documents the async job flow, the return of html_link/result_paths, the report equivalence to ``prs plot trait``, reuse of normalized caches, and the role of result_paths in sibling tools. It loses a point because several optional parameters and their intended interactions are not addressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
It adds real semantics for trait_id (EFO/MONDO), samples (list with Label=path or bare path), profile ('all' vs 'curated'), interpret, reference_restoration, superpopulation, and include_prompt. However, with 17 parameters and 0% schema description coverage, several meaningful advanced parameters such as limit, top_n, panel, min_auroc, min_match_rate, ancestry, genome_build, and include_children are left to name-inference only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific action and resource: 'Compute the PRS scores associated with a trait for one or more genomes.' The description also orients the tool among siblings by calling out multi-score vs single-score behavior and by clarifying that this tool ultimately produces the trait HTML report.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-and-when-not guidance: 'Do NOT call normalize_vcf first as a prerequisite' and clarifies that normalize_vcf is only optional for custom filters. It also tells the agent when to poll with prs_job_status, not to start a duplicate identical compute, and how to route outputs to compare_genomes, plot_trait_panel, or build_prs_prompt.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
download_sample_genomeDownload sample genomeAIdempotent
Download a public sample WGS VCF from Zenodo to try PRS without your own data.
Two whole-genome sequencing (WGS) datasets open-sourced by the just-dna-lite project are pre-configured — download both when you want a multi-person comparison:
sample="anton"— Anton Kulaga's genome (~482 MB, CC0 public domain, Zenodo record 18370498, file: antonkulaga.vcf).sample="livia"— Livia Zaharia's genome (~349 MB, CC-BY-4.0, Zenodo record 19487816, file: SIMHIFQTILQ.hard-filtered.vcf.gz).
Pass record_url (e.g. 'https://zenodo.org/records/18370498') to fetch
any other Zenodo record, and filename to pick a specific file when a
record has several.
The downloaded VCF lands under <cache_dir>/samples/ (or output_dir)
and is a drop-in path for normalize_vcf / compute_prs /
compute_prs_by_trait (including samples=["Anton=<path>", ...]).
auto_normalize defaults to True: the download is normalized to a
reusable Parquet in the same call, so data carries both path (the
raw VCF) and normalized_path — a one-call, compute-ready genotype
source with no separate normalize_vcf round-trip. (Normalization is
idempotent, so a re-download of an already-staged sample is cheap.) Pass
auto_normalize=False to fetch the raw VCF only.
Use list_genomes to see which genomes have already been downloaded
and/or normalized.
Idempotent: if the target VCF already exists with the size Zenodo
reports, the ~hundreds-of-MB download is skipped and the cached file is
reused; likewise a present Parquet skips re-normalization. data echoes
reused_cache (download skipped) and downloaded_bytes (bytes
actually transferred, 0 on a cache hit) so the caller can tell a cache
hit from a fresh fetch. Pass force=True to re-download/re-normalize
regardless.
Returns a PRSJob immediately. When done, result is an OpResult
whose data carries the local path. Poll prs_job_status if
status is still running — the download is hundreds of MB.
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | ||
| sample | No | anton | |
| filename | No | ||
| output_dir | No | ||
| record_url | No | ||
| auto_normalize | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| tool | Yes | Tool that created the job. |
| error | No | Failure message when status is failed. |
| job_id | Yes | Pass this to prs_job_status until status is done or failed. |
| result | No | When status is done: the original tool payload (TraitPRSReports, NormalizeResult, OpResult, or a list of PRSResult). Read html_link / result_paths from this object. |
| status | Yes | queued/running: call prs_job_status. done: read result and html_link. failed: read error. Do not start a second identical compute while queued/running. |
| message | Yes | Latest progress line. |
| progress | No | Completed work units, when known. |
| html_link | No | PRIMARY REPORT DELIVERY TARGET. When set, put this exact value in the user reply as a markdown link and explicitly tell the user to open the interactive report. It is an HTTP URL when available and a file:// URI for local stdio. Never omit, fetch, or paste the HTML. |
| poll_with | No | Poll this tool with job_id. Optional wait_seconds keeps one poll under typical client timeouts (try 25). |
| created_at | Yes | UTC timestamp when the job was created. |
| html_error | No | Optional HTML-generation error. Scores remain valid when this is set. |
| progress_total | No | Total work units, when known. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description provides extensive details beyond annotations: idempotency with size-checking, cache reuse, force flag behavior, return of PRSJob and OpResult with data.path, and distinguishes cache hits via reused_cache and downloaded_bytes. No contradiction with idempotentHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with bullet points and clear sections, but the length is somewhat verbose. However, every piece serves a purpose given the tool's complexity, and it front-loads the primary purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, parameters, caching, normalization, async behavior, return format, and integration across the pipeline. No missing critical information for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description is the sole source for parameter meaning. It explains sample (anton/livia with metadata), record_url, filename, output_dir, auto_normalize, and force with practical examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool downloads a public sample WGS VCF from Zenodo for PRS testing without personal data. It names specific samples and distinguishes itself from compute/analysis siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly specifies when to use (try PRS without own data), how to integrate with downstream tools (normalize_vcf, compute_prs), and references list_genomes as the complementary tool. Also explains when to use auto_normalize or custom record_url.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_genomesList genomesARead-onlyIdempotent
List genomes available in the server's cache directory.
Scans <cache_dir>/samples/ for downloaded raw VCF files and
<cache_dir>/normalized/ for normalized Parquet files. Also lists
the pre-configured sample genomes that can be downloaded via
download_sample_genome (even if not yet downloaded).
Use this to discover genomes you can score or compare (Anton + Livia are the built-in pair):
Which genomes have already been downloaded (ready for direct scoring).
Which genomes have already been normalized (ready for compute_prs /
compute_prs_by_traitas an optional reusable fast path).Which pre-configured samples are available for download.
No network access required — reads the local filesystem only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| message | Yes | Human-readable summary. |
| cache_dir | Yes | Root cache directory path. |
| downloaded | No | Raw VCF files in <cache_dir>/samples/. |
| normalized | No | Normalized Parquet files in <cache_dir>/normalized/. |
| available_samples | No | Pre-configured sample genomes that can be downloaded via download_sample_genome (name, description, size, license). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes beyond the annotations by stating it does a local filesystem scan, reads specific directories, and has no network access. It also explains that it lists pre-configured samples even if not downloaded, which is a behavioral nuance. The annotations (readOnlyHint, idempotentHint, destructiveHint) are consistent and the description adds detail about what it inspects. However, it doesn't describe output format or pagination, but given the annotations cover safety, this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a well-structured paragraph with bullet-like points in prose. It's concise, using clear sections and specific file paths. Every sentence adds value—explains what it scans, what it lists, and its network behavior. No fluff. Slightly verbose with the bulleted hints but still efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no parameters and an output schema (not detailed here), the description explains the sources and purpose well. It mentions key use cases (scoring, comparison), but does not explicitly describe the output structure since that is provided by the output schema. It is complete for the tool's simple nature. It could mention if it returns any errors or edge cases, but that's not critical. Overall, it's well-rounded.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are 0 parameters, so schema coverage is 100% trivially. The description adds no parameter-specific info because none exist, but it does explain the scope of what is listed (cache dirs, pre-configured samples). Since there are no parameters, a baseline of 4 is appropriate as the description provides context about the tool's operation without needing to explain parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb+resource: 'List genomes available in the server's cache directory.' It specifies the exact directories scanned and the distinction between downloaded, normalized, and pre-configured sample genomes. It also differentiates from siblings like compare_genomes and download_sample_genome by explicitly mentioning the built-in pair and the purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool: 'Use this to discover genomes you can score or compare' and lists what to look for (downloaded, normalized, pre-configured). It also provides an exclusion: 'No network access required — reads the local filesystem only,' implying it's not for network operations. The mention of alternative tools (download_sample_genome, compute_prs, etc.) in the context implies when to use this instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_prs_jobsList PRS jobsARead-onlyIdempotent
List recent scoring/download jobs on this server process.
Use after a client timeout to recover the job_id instead of starting
the same compute again.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | Yes | Newest jobs last. result is omitted to keep this small. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is fully specified. The description adds context about it being server-process-scoped and the recovery scenario for job_id, which enriches the behavioral understanding without contradicting annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences: first states what it does, second gives a practical usage hint. Every word earns its place, and it is front-loaded with the action and resource.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and an existing output schema, the description sufficiently covers the tool's purpose and a key usage scenario. It mentions both 'scoring/download jobs' and the recovery of job_id, which is complete for a simple list operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the schema covers everything trivially. The description doesn't need to explain parameter meaning. Per guidelines, the baseline for zero-parameter tools is 4, and there is no missing parameter information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('List') and the resource ('recent scoring/download jobs on this server process'), which is specific and distinguishes it from sibling tools like 'prs_job_status' or 'search_scores'. The verb and resource are unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides a concrete use case: 'Use after a client timeout to recover the job_id instead of starting the same compute again.' This tells the agent exactly when to invoke this tool, a clear guideline that adds value beyond the basic purpose.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
normalize_vcfNormalize VCFAIdempotent
Normalize a VCF to a quality-filtered genotype Parquet.
This tool is optional preprocessing, not a prerequisite for scoring:
compute_prs, compute_prs_batch, and compute_prs_by_trait accept
raw VCF paths directly. Use normalization when you intentionally want a
reusable Parquet for many later analyses or custom quality filters. Before
normalizing, list_genomes can show whether a cached Parquet already exists.
Strips the chr prefix, renames id→rsid, computes genotype from GT, applies
optional quality filters (FILTER allow-list, min DP, min QUAL), and writes
zstd-compressed Parquet. The output is a drop-in genotype source for
compute_prs / compute_prs_batch (genotypes_path) and for
compute_prs_by_trait (a samples entry ending in .parquet), so
each VCF is normalized once and reused. Normalize every genome you plan
to compare; scoring still happens per genome.
Idempotent: if the target Parquet already exists it is reused and the
(slow) normalization is skipped — reused_cache=True flags the hit.
Custom filters (pass_filters / min_depth / min_qual / sex)
always re-run, since the cached Parquet may not reflect them. Pass
force=True to re-normalize unconditionally.
Normalization is the slow step (seconds to minutes depending on VCF size).
Returns a PRSJob immediately; poll prs_job_status when status is
running. When done, result is a NormalizeResult.
| Name | Required | Description | Default |
|---|---|---|---|
| sex | No | ||
| force | No | ||
| min_qual | No | ||
| vcf_path | Yes | ||
| min_depth | No | ||
| output_path | No | ||
| genome_build | No | ||
| pass_filters | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| tool | Yes | Tool that created the job. |
| error | No | Failure message when status is failed. |
| job_id | Yes | Pass this to prs_job_status until status is done or failed. |
| result | No | When status is done: the original tool payload (TraitPRSReports, NormalizeResult, OpResult, or a list of PRSResult). Read html_link / result_paths from this object. |
| status | Yes | queued/running: call prs_job_status. done: read result and html_link. failed: read error. Do not start a second identical compute while queued/running. |
| message | Yes | Latest progress line. |
| progress | No | Completed work units, when known. |
| html_link | No | PRIMARY REPORT DELIVERY TARGET. When set, put this exact value in the user reply as a markdown link and explicitly tell the user to open the interactive report. It is an HTTP URL when available and a file:// URI for local stdio. Never omit, fetch, or paste the HTML. |
| poll_with | No | Poll this tool with job_id. Optional wait_seconds keeps one poll under typical client timeouts (try 25). |
| created_at | Yes | UTC timestamp when the job was created. |
| html_error | No | Optional HTML-generation error. Scores remain valid when this is set. |
| progress_total | No | Total work units, when known. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the idempotentHint annotation, the description explains the idempotency rule in detail (reuse existing Parquet, skip normalization) and the caveat about custom filters. It discloses the actual transformations (chr prefix stripping, id→rsid, genotype computation) and the async behavior (returns PRSJob, poll status), adding significant context not available from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear paragraphs, each serving a purpose: overview, usage guidance, behavioral details, and async/result note. No redundancy exists—every sentence adds value (e.g., 'Normalize every genome you plan to compare') while remaining concise for the complexity covered.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (8 params, async execution, idempotency, filters), the description is complete. It covers all operational aspects, includes the output schema reference (NormalizeResult), and explains the async pattern, making it self-sufficient for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite schema description coverage of 0%, the description explicitly names and elaborates on all key parameters: vcf_path, output_path, pass_filters, min_depth, min_qual, sex, force. It explains that custom filters always re-run and that force=True triggers unconditional normalization, giving meaning beyond the schema's type definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool normalizes a VCF to a quality-filtered genotype Parquet, which is specific and action-oriented. It explicitly distinguishes this from scoring tools like compute_prs, establishing its role as optional preprocessing, not a prerequisite.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance on when to use this tool: 'Use normalization when you intentionally want a reusable Parquet for many later analyses or custom quality filters.' It also directs users to check list_genomes for existing caches, and clarifies that raw VCF paths are accepted directly by scoring tools, providing clear when-not.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
percentilePRS percentileARead-onlyIdempotent
Estimate the population percentile (0-100) for a computed PRS value.
Uses the 3-tier fallback: precomputed reference-panel distributions
(best), then a theoretical distribution, then an AUROC approximation.
superpopulation is a 1000G code (AFR/AMR/EAS/EUR/SAS) and should
match that genome's ancestry — when comparing people, call this
once per score×genome (or rely on compute_prs_by_trait(interpret=True)).
Pass weight_mass_coverage (C_wt) from compute_prs so a deflated
low-coverage percentile is flagged reliable=False with a caveat
instead of presented as authoritative. Also returns the true z-score and
reference mean/std used, so absolute risk can be computed without
inverting the percentile.
Important next step: for disease traits, feed the returned
z_score directly into absolute_risk to get the concrete
lifetime probability and risk ratio vs the population average. This is
more informative than the percentile alone.
| Name | Required | Description | Default |
|---|---|---|---|
| panel | No | ||
| pgs_id | Yes | ||
| prs_score | Yes | ||
| superpopulation | No | EUR | |
| weight_mass_coverage | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| caveat | No | Human-readable warning explaining why the percentile is caveated. |
| method | Yes | 'reference_panel', 'theoretical', 'auroc_approx', or 'unavailable'. |
| pgs_id | Yes | PGS Catalog Score ID. |
| z_score | No | True z-score ((score − reference_mean)/reference_std) used for this percentile — feed directly to absolute_risk instead of inverting the percentile. |
| ancestry | Yes | Requested 1000G superpopulation (AFR/AMR/EAS/EUR/SAS). |
| reliable | No | False when the percentile should be treated as caveated or unreliable. |
| prs_score | Yes | The PRS value that was scored. |
| percentile | No | Estimated percentile (0-100), or null if unavailable. |
| reference_std | No | Reference-distribution SD used, when known. |
| reference_mean | No | Reference-distribution mean used, when known. |
| reference_panel | No | Reference panel identifier used (reference_panel method only). |
| reference_panel_ancestry | No | Superpopulation of the reference panel actually used (reference_panel method only) — check it matches the sample's ancestry before trusting the percentile. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations (readOnlyHint, idempotentHint) already establish safety, but the description adds rich behavioral detail: the 3-tier fallback logic, reliability flagging for low coverage, and inclusion of z-score/mean/std for downstream risk calculation. This goes beyond annotation-derived expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured and dense; the main purpose is front-loaded, and each sentence adds substantive value. The 'Important next step' is a legitimate usage addition, not filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 5 parameters, a complex fallback algorithm, and linkage to absolute_risk, the description covers core behavior, caveats, parameter meaning, and next steps. The existence of an output schema fills in exact return fields.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the burden. It thoroughly explains superpopulation as a 1000G code and weight_mass_coverage as C_wt from compute_prs for reliability flagging. However, 'panel' is only indirectly referenced via 'reference-panel distributions' without explicit parameter clarification.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: 'Estimate the population percentile (0-100) for a computed PRS value.' This clearly differentiates from siblings like compute_prs and absolute_risk.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use versus alternatives: suggests compute_prs_by_trait(interpret=True) for comparative scenarios and directs disease-trait users to absolute_risk with the returned z_score. Also gives context for superpopulation matching.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plot_trait_panelPlot trait panel (give user html_link)AIdempotent
Write the just-prs trait HTML report and return a URL or file path.
REQUIRED REPORT DELIVERY: when html_link is set, your reply MUST include it as a markdown link (for example Open the interactive trait report) and explicitly tell the user to open it. This is the primary user-facing result, not an implementation detail. Do not skip the link, merely say the report was saved, fetch it, or paste the HTML. html_link is an HTTP URL when available and a file:// URI on local stdio.
This is the MCP equivalent of prs plot trait ... -o intel_o_family.html:
just_prs.viz.plot_trait_scores + save_trait_report. The page has
the Vega-Lite panel, median cards, model table, and Ask-AI buttons.
result_paths is always a list (one genome is fine; two or more
overlay people). On Streamable HTTP html_url is served from this
same origin at /reports/<file> with no extra config.
| Name | Required | Description | Default |
|---|---|---|---|
| panel | No | ||
| ancestry | No | EUR | |
| model_scope | No | usable | |
| output_path | No | ||
| result_paths | Yes | ||
| genome_labels | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| label | Yes | Trait label. |
| summary | Yes | Human-readable summary of what was written. |
| html_url | No | REQUIRED when set: browser URL for this report on the FastMCP HTTP origin (``/reports/<file>``). Put this exact URL in your reply as a markdown link and tell the user to open it. Do not skip it. Do not fetch or paste the HTML. |
| trait_id | Yes | Trait ontology ID plotted. |
| html_link | Yes | PRIMARY REPORT DELIVERY TARGET. Put this exact value in the user reply as a markdown link and explicitly tell the user to open the interactive report. It is an HTTP URL when available and a file:// URI for local stdio. Never omit, fetch, or paste the HTML. |
| html_path | Yes | Server filesystem path of the written just-prs HTML report. Use only when ``html_url`` is absent (stdio): tell the user to open this file. Never paste the HTML. |
| n_markers | Yes | Number of scored models with a percentile on the chart. |
| n_samples | No | Number of genomes overlaid on the panel (1 = single-genome markers). |
| sample_labels | No | Genome labels drawn on the panel, in overlay order. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, and destructiveHint=false. The description adds valuable behavioral context: what the report contains, that html_link is an HTTP URL or file:// URI depending on transport, and that on Streamable HTTP the URL is served at /reports/<file>. It also emphasizes the required user-facing link, which is a behavior beyond what annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: a brief purpose sentence, a clearly highlighted REQUIRED REPORT DELIVERY block, and supporting context. It is not overly verbose and every part adds relevant information. The use of bold/labeled sections aids readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the critical delivery requirement and gives background (MCP equivalent, page contents, URL serving). However, it lacks explanations for most input parameters, which is a notable gap given the absence of schema descriptions. The output schema exists, so return values are not a concern, but parameter understanding is incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description carries the burden. It only clarifies `result_paths` ('always a list, one genome is fine; two or more overlay people'). It does not explain `panel`, `ancestry`, `model_scope`, `output_path`, or `genome_labels`. This is insufficient for an agent to confidently set these parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Write the just-prs trait HTML report and return a URL or file path.' It clearly distinguishes this from siblings like compute_prs by framing it as a plotting/visualization tool (MCP equivalent of `prs plot trait`). The description also clarifies the page contents and that `result_paths` can contain one or more genomes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context on how to use the tool, especially the mandatory delivery of `html_link` as a markdown link. It implies this tool is used after PRS computation, and the underlying functions are named. However, it does not explicitly list alternatives or say when not to use this tool, so a slight gap remains.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prs_job_statusPRS job statusARead-onlyIdempotent
Poll a long scoring/download job started by this server.
compute_prs_by_trait, compute_prs_batch, normalize_vcf, and
download_sample_genome return a PRSJob instead of blocking. Call
this with that job_id. wait_seconds=25 waits inside one call
(safe for Cursor) and returns as soon as the job finishes. When
status is done, read html_link and result.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | ||
| wait_seconds | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| tool | Yes | Tool that created the job. |
| error | No | Failure message when status is failed. |
| job_id | Yes | Pass this to prs_job_status until status is done or failed. |
| result | No | When status is done: the original tool payload (TraitPRSReports, NormalizeResult, OpResult, or a list of PRSResult). Read html_link / result_paths from this object. |
| status | Yes | queued/running: call prs_job_status. done: read result and html_link. failed: read error. Do not start a second identical compute while queued/running. |
| message | Yes | Latest progress line. |
| progress | No | Completed work units, when known. |
| html_link | No | PRIMARY REPORT DELIVERY TARGET. When set, put this exact value in the user reply as a markdown link and explicitly tell the user to open the interactive report. It is an HTTP URL when available and a file:// URI for local stdio. Never omit, fetch, or paste the HTML. |
| poll_with | No | Poll this tool with job_id. Optional wait_seconds keeps one poll under typical client timeouts (try 25). |
| created_at | Yes | UTC timestamp when the job was created. |
| html_error | No | Optional HTML-generation error. Scores remain valid when this is set. |
| progress_total | No | Total work units, when known. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds value beyond annotations by explaining that wait_seconds causes the call to block until job completion, and by noting what to read when status is done (html_link, result). This is useful behavioral context not present in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, with two short paragraphs. The first sentence sets the purpose, and the second provides necessary context about the initiating tools and usage. The list of four tools is slightly verbose but serves to clarify which jobs this applies to. No unnecessary fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Since an output schema exists, the description need not detail return formats. It covers the key flow: call with job_id, optionally wait, check status, and read outputs when done. It doesn't address error conditions or non-done statuses, but these are likely captured in the output schema. The mention of 'safe for Cursor' adds practical context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Given 0% schema coverage, the description compensates by explaining both parameters: job_id is the identifier from the returning tools, and wait_seconds controls how long to wait within the call. It correctly implies that wait_seconds=0 returns immediately, reinforcing the polling semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool polls a long scoring/download job and explicitly references the four tools that return PRSJob objects. It distinguishes this from siblings like list_prs_jobs by focusing on polling a specific job rather than listing jobs. The verb 'poll' and resource 'job' are specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage context: call it with the job_id returned by the aforementioned tools, and explains the wait_seconds behavior (waits inside one call, safe for Cursor). It doesn't explicitly state when not to use it or name alternatives like list_prs_jobs, but the context is clear enough for an agent to know when to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
score_infoScore metadataARead-onlyIdempotent
Get cleaned metadata for a single PGS score by its ID (e.g. 'PGS000001').
| Name | Required | Description | Default |
|---|---|---|---|
| pgs_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | Score name. |
| pgs_id | Yes | PGS Catalog Score ID, e.g. 'PGS000001'. |
| trait_efo | No | EFO trait label(s). |
| weight_type | No | Weight type (beta/OR/HR). |
| genome_build | No | Original genome build. |
| is_harmonized | No | True when the score's native build differs from the queried build. |
| quality_label | No | Synthetic quality label, when available. |
| trait_reported | No | Reported trait. |
| variants_number | No | Number of variants. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this as read-only, idempotent, and non-destructive. The description's addition of 'cleaned' is vague and does not disclose any further behavioral traits (e.g., rate limits, authentication needs, or side effects). It neither contradicts the annotations nor adds meaningful beyond-safety context, so the description under-delivers.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no unnecessary words. It front-loads the action and resource, includes a concrete example, and leaves no room for ambiguity. Perfectly concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple metadata retrieval tool with one parameter and an existing output schema, the description is sufficiently complete. It covers the core intent and the parameter usage. A deduction is warranted because it doesn't mention any potential errors or special cases, but given the simplicity, these are not critical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% because the parameter lacks a description field, so the description must compensate. The phrase 'by its ID' and the example 'PGS000001' imply the expected format, offering some semantic value. However, it could be more explicit about the required pattern or additional constraints, though this minimal compensation is adequate for a single-parameter tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves cleaned metadata for a single PGS score by ID, using a specific verb ('Get') and resource ('metadata for a single PGS score'). It differentiates from siblings like 'search_scores' by focusing on a single known ID rather than searching, and gives an example ID format for clarity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage—when you have a specific PGS ID and need metadata—but does not explicitly state when to prefer this over alternatives like 'search_scores' or mention any exclusions. The example ID provides a hint but no explicit when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_scoresSearch PGS scoresARead-onlyIdempotent
Search the PGS Catalog for polygenic scores by free text.
Case-insensitive substring match across PGS ID, score name, reported
trait, and EFO trait. Optionally filter to a genome build (GRCh37 /
GRCh38, harmonized cross-build scores included). Returns up to limit
matches with their key metadata.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes | ||
| genome_build | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only and idempotent behavior, but the description adds key behavioral details: case-insensitivity, substring matching, fields searched, handling of genome builds with harmonized cross-build scores, and the limit on returned matches. This significantly enriches the static annotation information.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, front-loaded with the main purpose, and every sentence adds value. It covers behavior, parameters, and edge cases in three sentences without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity and zero parameter descriptions in the schema, the description covers all relevant aspects: search semantics, optional filters, special handling (cross-build), and result limits. An output schema exists, so return format details are unnecessary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, yet the description compensates by explaining all three parameters: 'free text' for query, 'filter to a genome build (GRCh37 / GRCh38, harmonized cross-build scores included)' for genome_build, and 'up to limit matches' for limit. It adds meaning far beyond the bare types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool 'Search the PGS Catalog for polygenic scores by free text', providing a specific verb and resource. It further distinguishes by listing exact match fields (PGS ID, score name, reported trait, EFO trait) and optional filtering, differentiating it from sibling search tools like search_traits.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context on how the search behaves (case-insensitive substring match) and when filters apply, but does not explicitly mention when not to use it or name alternative tools. The context is sufficient for basic usage without explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_traitsSearch traitsARead-onlyIdempotent
Search the PGS Catalog REST API for traits by term.
Upstream matching is exact-substring over labels and synonyms, so this
wrapper retries a few punctuation/order variants when the first query is
empty. By default, results include counts of directly associated PGS IDs
and child-trait PGS IDs; set include_pgs_ids for the full arrays.
| Name | Required | Description | Default |
|---|---|---|---|
| term | Yes | ||
| limit | No | ||
| include_pgs_ids | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, so the description only needs to add context beyond that. It explains the exact-substring matching and retry of variants, which is useful. It also clarifies default output (counts of PGS IDs) and how to get full arrays via include_pgs_ids, adding behavioral nuance not covered by annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long, front-loaded with the purpose and then providing helpful behavioral details. No unnecessary information or redundancy—every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description does not need to explain return values. It covers the core behavior (matching, retry, default counts), and the parameter effect for include_pgs_ids. For a simple read-only search tool, this is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% because the description does not explain term or limit. It does explain include_pgs_ids partially by describing 'full arrays.' However, term is self-evident from context, and limit remains unaddressed. Given the low coverage, the description should compensate more; it only partially does for include_pgs_ids, so a baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Search the PGS Catalog REST API for traits by term,' specifying the verb (search), resource (traits), and scope (by term). It distinguishes itself from sibling tools like search_scores (for scores) and trait_info (likely for specific trait details), making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for finding traits by term but does not explicitly contrast with alternatives like trait_info or mention when not to use it. It provides context about matching behavior but lacks direct exclusions or alternative recommendations, though the purpose is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
trait_infoTrait infoARead-onlyIdempotent
Fetch a trait by ontology ID (EFO or MONDO) with its associated PGS IDs.
| Name | Required | Description | Default |
|---|---|---|---|
| efo_id | No | ||
| trait_id | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | EFO trait ID (e.g. EFO_0001645) |
| url | No | EFO URL |
| label | No | Trait label |
| description | No | Trait description |
| trait_synonyms | No | Trait synonyms |
| trait_categories | No | Trait categories |
| associated_pgs_ids | No | Associated PGS IDs |
| child_associated_pgs_ids | No | Child trait associated PGS IDs |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, open-world, and non-destructive hints. The description adds that it returns associated PGS IDs, which is output-related but not behavioral. It does not disclose potential errors, authentication requirements, or null returns, but the annotation coverage lowers the bar.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that is direct and front-loaded. No extraneous words or redundancy. Excellent conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, and an output schema likely exists, reducing need to describe return format. However, the parameter ambiguity and lack of context about how to select between EFO and MONDO make it incomplete for a typical agent. It is adequate for a simple fetch but has clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It mentions EFO or MONDO IDs but does not explicitly map them to the efo_id and trait_id parameters. It also does not clarify whether both or one is required, leaving ambiguity. This is insufficient given the complete lack of parameter documentation in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool fetches a trait by ontology ID (EFO or MONDO) and returns its associated PGS IDs. This specific verb+resource distinguishes it from sibling tools like search_traits, which implies searching rather than direct fetching.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when an ontology ID is available, but it does not explicitly mention when not to use it or mention alternatives like search_traits. The guidance is implicit rather than explicit, so the score is moderate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
vcf_metainfoVCF meta-infoARead-onlyIdempotent
Detect a genome's build, input type (WGS/array/gVCF), and genetic ancestry.
One call that pairs WGS-vs-array/gVCF detection with population (super-population) inference, so before scoring you already know: the genome build (read from the VCF header), whether the input is whole-genome sequencing, a consumer genotyping array (and which chip), or a gVCF / all-sites callset, and the sample's inferred super-population.
Pass genotypes_path (a normalized Parquet from normalize_vcf /
download_sample_genome) for the fast path, or a raw vcf_path.
Genome-build detection reads the VCF header, so it is only available on the
vcf_path branch.
The result carries ready-to-use recommendations:
recommended_reference_restoration (feed to compute_prs /
compute_prs_batch / compute_prs_by_trait as reference_restoration
— though those tools default to "auto" and derive the same thing) and
recommended_superpopulation (feed as superpopulation). Set
infer_population=False to skip ancestry inference (it pulls a small model
from HuggingFace on first use).
| Name | Required | Description | Default |
|---|---|---|---|
| panel | No | ||
| vcf_path | No | ||
| resolution | No | superpop | |
| genome_build | No | ||
| genotypes_path | No | ||
| infer_population | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | Yes | Genotype source inspected (VCF or normalized Parquet). |
| chip_id | No | Detected genotyping-array chip id (array input only). |
| is_gvcf | No | True when reference-block / all-sites (gVCF) records were detected. |
| summary | Yes | Human-readable summary of the detected properties. |
| warnings | No | Non-fatal caveats (e.g. ancestry inference skipped). |
| input_type | Yes | Detected input kind: 'wgs', 'genotyping_array', or 'unknown'. |
| n_variants | Yes | Number of variant rows in the genotype source. |
| marker_count | Yes | Variant/marker count used for the input-type call. |
| chip_platform | No | Detected chip platform label (array input only). |
| ancestry_error | No | Why ancestry inference was skipped/failed, if it was. |
| ancestry_panel | No | Reference panel used for ancestry inference (e.g. '1000g'). |
| fine_population | No | Finer population call when resolution='population'. |
| superpopulation | No | Inferred super-population (AFR/AMR/EAS/EUR/SAS), or null if not inferred. |
| ancestry_coverage | No | Fraction of the ancestry model's sites covered by the sample. |
| ancestry_confidence | No | Classifier confidence for the super-population call (0-1). |
| genotype_input_mode | Yes | Resolved genotype interpretation: 'variant_only', 'all_sites', or 'plink_present_only'. |
| chip_generation_label | No | Detected chip generation label (array input only). |
| detected_genome_build | No | Genome build read from the VCF header ('GRCh37'/'GRCh38'), or null. |
| ancestry_probabilities | No | Per-super-population classifier posteriors. |
| n_variants_ancestry_used | No | Number of sample variants used by the ancestry model. |
| recommended_superpopulation | No | Super-population to pass to percentile / compute_prs_by_trait, when inferred. |
| recommended_reference_restoration | Yes | Scope to pass as compute_prs* reference_restoration: 'wgs', a chip id, or 'off'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds meaningful behavior beyond the read-only/idempotent annotations: it reveals dependency on a HuggingFace model on first ancestry inference, explains that build detection only works on the vcf_path branch, and clarifies that the returned reference_restoration recommendation is already derived by downstream tools in their default mode. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured and front-loaded with a clear, high-level purpose. It is somewhat long and repeats the output/consumption idea several times, but the detail is largely relevant, especially for distinguishing fast-path vs vcf-only behavior and for explaining external model usage.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a reasonably complex metadata tool with an output schema and no required parameters, the description covers the key invocation options, important branch constraints, side effects, and downstream consuming tools. Missing parameter semantics for three fields and some resource/cost caveats prevent a perfect score.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description compensates for a 0% schema-description coverage by explaining genotypes_path, vcf_path, infer_population, and the recommended output fields. However, panel, resolution, and genome_build remain unclear as parameters, and the reader must infer their role from general context. This is useful but incomplete parameter-level guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb and resource: 'Detect a genome's build, input type (WGS/array/gVCF), and genetic ancestry.' It clearly differentiates this tool as a metadata-inference step rather than a file-normalization or PRS-scoring tool, making its purpose unambiguous against the sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete usage guidance: pass a normalized Parquet from normalize_vcf/download_sample_genome for the fast path, or a raw vcf_path when VCF-header build detection is needed. It also explains when to set infer_population=False and how the recommendations feed downstream compute_prs tools. It does not explicitly name alternative tools or state when not to use it, but the context is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Most tools target a distinct action-resource pair: search, info, compute, post-process, report, and job handling are clearly separated. The main ambiguity is between compute_prs_batch and compute_prs_by_trait, which both handle multiple scores, though their descriptions clarify the one-genome-vs-many-genomes distinction.
The majority of tools follow a snake_case verb_noun pattern (compute_prs, list_genomes, build_prs_prompt, compare_genomes). A few noun-style names (best_performance, vcf_metainfo, percentile, absolute_risk, score_info, trait_info) break the pattern, but the overall convention remains predictable.
At 20 tools, this is on the heavy side and spans a very wide pipeline from catalog search to VCF normalization to reporting. The count is defensible for the domain, but some tools like percentile, absolute_risk, and assess_quality are narrowly scoped and could conceivably be folded into compute/interpretation results.
The tool surface covers the full PRS lifecycle: discovery, input preparation, computation, interpretation, comparison, reporting, and async job recovery. There are no obvious dead ends — job IDs feed prs_job_status, result paths feed compare_genomes/build_prs_prompt/plot_trait_panel, and computed z-scores feed absolute_risk.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP gateway federating 21 biomedical MCP servers behind one endpoint: gnomAD, ClinVar, HPO, VEP.
Auditable MCP server for PubMed, Europe PMC, ClinicalTrials.gov, and bioRxiv/medRxiv queries
MCP server for Product Management
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceFederates 13 gene-related MCP backends (gnomAD, GTEx, etc.) behind a single Streamable HTTP endpoint with collision-free namespacing and search-based tool discovery.2MIT
- AlicenseNot gradedqualityCmaintenanceA local-first MCP server that annotates whole-genome VCF files and lets you query pharmacogenomics, disease risk, and carrier status through natural language.4MIT
- FlicenseNot gradedqualityAmaintenanceMCP server for querying PROSPERO registered protocols, enabling search, retrieval, and registration workflow management.
- AlicenseBqualityDmaintenanceMCP server that exposes the Open Targets Platform GraphQL API as a set of tools for querying biomedical data such as targets, diseases, drugs, and genetic evidence.6819MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/dna-seq/just-prs-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server