Skip to main content
Glama
ImmPort MCP Server

ImmPort MCP Server

Official
by ImmPortDB

Search Studies

search_studies

Search across ImmPort studies by full-text terms and filters such as disease, species, assay, or program; get compact study records and optional facet counts for discovery workflows.

Instructions

Full-text and faceted search across all ImmPort studies. Returns a compact shape: {total, returned, studies, facets}. 'studies' is a flat list of study records (no OpenSearch envelope/score/highlight noise). 'facets' is omitted unless you pass the facets parameter. Use this as the entry point for any study discovery workflow. No authentication required.

Key parameters:

  • term: partial matching by default ('flu' finds 'influenza'); use quotes for exact phrase (e.g. '"influenza vaccine"')

  • research_focus: e.g. 'Vaccine Response', 'Allergy', 'Autoimmune' (use lookup_research_focus() for valid values)

  • condition_or_disease: disease/condition name, e.g. 'Influenza', 'Atopic Dermatitis' (use lookup_disease() for valid values)

  • program_name: NIH program name, e.g. 'HIPC', 'ITN', 'SeroNet'

  • clinical_trial: 'Y' or 'N' to filter to clinical trials only

  • species: e.g. 'Homo sapiens', 'Mus musculus' (use lookup_controlled_vocabulary('lkSpecies'))

  • sex: 'Female', 'Male', 'Unknown' (use lookup_controlled_vocabulary('lkSex'))

  • race: e.g. 'White', 'Black or African American' (use lookup_controlled_vocabulary('lkRace'))

  • ethnicity: e.g. 'Hispanic or Latino' (use lookup_controlled_vocabulary('lkEthnicity'))

  • min_age: minimum subject age filter (numeric)

  • age_range: age range string filter

  • assay_method: measurement technique, e.g. 'Flow Cytometry', 'ELISA', 'RNA sequencing' (use lookup_controlled_vocabulary('lkExpMeasurementTech'))

  • biosample_type: e.g. 'PBMC', 'Whole Blood', 'Serum' (use lookup_controlled_vocabulary('lkSampleType'))

  • has_assessment: 'Y' or 'N'

  • has_lab_test: 'Y' or 'N'

  • study_accession: filter by specific study IDs, e.g. ['SDY1', 'SDY2']

  • subject_accession: filter by specific subject IDs, e.g. ['SUB00240']

  • facets: list of facet names to compute, e.g. ['assay_method', 'condition_or_disease']. Omit this (default) for discovery/lookup queries — no aggregations are computed, which keeps responses small and fast. Only request facets when the question is about distribution/breakdown (e.g. 'what assay types exist across these studies?'), not when you just need the matching studies themselves. Valid names: gender, race, ethnicity, species, clinical_trial, condition_or_disease, research_focus, assay_method, program_name, biosample_type, has_lab_test, has_assessment, age. Each returned facet is {value: count} for up to facet_limit non-zero values, with any remainder folded into 'other' (note: 'other' is a doc count, not a list of hidden values — if it's non-trivial and you need the actual long-tail categories, raise facet_limit rather than guessing). study_accession/subject_accession are never returned as facets since they'd just duplicate the 'studies' list.

  • facet_limit: max buckets returned per facet (default 15). Raise this (e.g. 50, 100) when the 'other' bucket is large and you actually need the long-tail breakdown rather than just the top values — e.g. 'list every condition_or_disease in these results', not just the most common ones. Values ≤ 15 use the backend's cheapest pre-capped response; higher values cost more (the backend returns its full, still zero-count-trimmed, aggregation and the cap is applied here instead).

  • sort_field: field to sort by. Valid values: study_accession_number (numeric — use desc for most recently added studies), study_accession (string sort only — do NOT use for recency), latest_data_release_date (date — use desc for most recently updated studies), latest_data_release_version_number (numeric release version, use desc for latest), initial_data_release_date (date — use desc for newest additions), initial_data_release_version_number (numeric), brief_title, min_age, max_age, condition_or_disease, research_focus, species, study_pi, actual_enrollment, planned_visit_total_count, shared_subject_count

  • sort_field_direction: 'asc' (default) or 'desc'

  • search_fields: limit text search to specific fields (comma-separated)

  • source_fields: list of fields to return (e.g. ['study_accession', 'brief_title']). Common fields: study_accession, brief_title, brief_description, condition_or_disease, research_focus, species, study_pi, program_name, clinical_trial, assay_method, biosample_type, doi, pubmed_id. For the FULL field list — including nested objects like pubmed (journal, year, doi), reagent, experiment, personnel, cde — dot-path projection syntax (e.g. 'pubmed.journal'), fields that exist but can't be retrieved, and known data-quality caveats, see the immport://search-fields resource. '*' does NOT work as a wildcard for 'all fields' — it returns an empty object. Restrict to only fields you need to reduce response size.

  • from_record: zero-based pagination offset (default 0)

  • page_size: max records per page (default 10, hard cap 10000)

  • include_score: adds a 'relevance_score' field to each study (default False). Results are always returned in relevance order regardless of this flag — only use this when you need the actual numeric score (e.g. to judge whether low-ranked hits are only tangentially related).

  • include_highlights: adds a 'highlights' field to each study showing which text snippets matched term, e.g. distinguishing 'adjuvant vaccine' from 'adjuvant chemotherapy' (default False). Only meaningful when term is set; ignored otherwise. Not available on search_subjects (backend limitation).

EFFICIENCY TIPS:

  • Cross-study questions (e.g. 'top journals', 'which studies used X'): use ONE call with page_size covering the full result set and narrow source_fields — do not loop get_study_data per study. See immport://query-tips for a worked example.

  • source_fields: Always specify only the fields you need — omitting this returns full OpenSearch documents and produces very large responses.

  • Sizing page_size: each row costs ~2,500 chars with full documents (no source_fields) vs. ~150 chars when source_fields is restricted to 2-3 fields. To fetch many results in one call instead of paginating, restrict source_fields first, then raise page_size (e.g. page_size=1000 with 2-3 source_fields is ~125KB; the same page_size with full documents would be ~2.5MB and likely exceed the response size limit). Don't raise page_size much past 50 unless source_fields is restricted.

  • Pagination: Always check the top-level 'total' field. If total > page_size, issue additional calls incrementing from_record by page_size until all results are fetched.

  • Parallel lookups: lookup_controlled_vocabulary is served from in-memory cache with no API cost — issue lookup calls in parallel with this search, not before it.

  • Recency sort: use study_accession_number desc for most recently added; latest_data_release_date desc for most recently updated. Do NOT use study_accession for recency — it is a string (SDY10 sorts before SDY9).

Input Schema

NameRequiredDescriptionDefault
sexNo
raceNo
termNo
facetsNo
min_ageNo
speciesNo
age_rangeNo
ethnicityNo
page_sizeNo
sort_fieldNo
facet_limitNo
from_recordNo
assay_methodNo
has_lab_testNo
program_nameNo
include_scoreNo
search_fieldsNo
source_fieldsNo
biosample_typeNo
clinical_trialNo
has_assessmentNo
research_focusNo
study_accessionNo
subject_accessionNo
include_highlightsNo
condition_or_diseaseNo
sort_field_directionNoasc

Output Schema

NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv1.4.0

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so: it discloses no authentication required, that facets are omitted unless requested, that facets are {value: count} with a folded 'other' bucket that is a doc count not hidden values, that facet_limit above 15 costs more backend work, and that '*' is not a wildcard. It also documents response-size ceilings, pagination via the top-level 'total', and which flags are ignored in which conditions (include_highlights ignored without term).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, return shape, and entry-point guidance, then a parameter list, then efficiency tips — a sensible structure for a 27-parameter tool. It is long and a few passages restate the same sizing advice (source_fields/response size appears in three bullets), so it is not maximally tight, but the length is largely justified by the parameter surface.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for a high-complexity 27-parameter search tool: coverage, cost, pagination, sorting pitfalls, facet mechanics, and cross-references to immport://search-fields and immport://query-tips are all present. The output schema exists, yet the description still supplies the compact-shape summary an agent needs before calling, which is additive rather than redundant.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 27 parameters, so the description must compensate entirely, and it does — nearly every parameter gets an example value, a valid-value source, and a default or behavior note. It goes beyond naming: it explains partial vs quoted phrase matching for term, why study_accession is unsafe for recency sorting (SDY10 before SDY9), and the numeric vs string distinction among sort_field values.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Full-text and faceted search across all ImmPort studies') and immediately gives the return shape {total, returned, studies, facets}. It also distinguishes itself from siblings by naming lookup_* tools for vocabulary validation and warning against looping get_study_data per study.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly designates itself as 'the entry point for any study discovery workflow' and gives a concrete when/when-not rule for facets (only for distribution questions, not for retrieving matching studies). It routes to alternatives repeatedly: lookup_research_focus, lookup_disease, lookup_controlled_vocabulary for value validation, and parallel lookup calls rather than sequential ones.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.