Skip to main content
Glama
ImmPort MCP Server

ImmPort MCP Server

Official
by ImmPortDB

Search Subjects

search_subjects

Search ImmPort subjects across studies by demographics, disease, assay, and program to find patient cohorts for cross-study discovery and filtering.

Instructions

Full-text and faceted search across all ImmPort subjects/participants. Returns a compact shape: {total, returned, subjects, facets}. 'subjects' is a flat list of subject records (no OpenSearch envelope/score/highlight noise). 'facets' is omitted unless you pass the facets parameter. Useful for cross-study cohort discovery (e.g. find all female subjects in influenza studies). No authentication required.

Key parameters:

  • term: partial matching by default; use quotes for exact phrase

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

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

  • research_focus: e.g. 'Vaccine Response', 'Allergy'

  • condition_or_disease: disease/condition name (use lookup_controlled_vocabulary('lkDisease'))

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

  • clinical_trial: 'Y' or 'N'

  • 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'))

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

  • min_age: minimum subject age (numeric)

  • age_range: age range string filter

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

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

  • has_assessment: 'Y' or 'N'

  • has_lab_test: 'Y' or 'N'

  • 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, not when you just need the matching subjects 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' (a doc count, not a list of hidden values — raise facet_limit if you need the actual long-tail categories). study_accession/subject_accession are never returned as facets since they'd just duplicate the 'subjects' list.

  • facet_limit: max buckets returned per facet (default 15). Raise this (e.g. 50, 100) when the 'other' bucket is large and you need the long-tail breakdown, not just top values.

  • sort_field: field to sort by. Valid values: subject_accession (string sort), study_accession (string sort), assay_method, biosample_type, clinical_trial, condition_or_disease, ethnicity, sex, has_assessment, has_lab_test, min_age, race, research_focus, species

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

  • search_fields: limit text search to specific fields

  • source_fields: list of fields to return (e.g. ['study_accession', 'subject_accession']). Common fields: study_accession, subject_accession, condition_or_disease, research_focus, species, sex, race, ethnicity, min_age, max_age, assay_method, biosample_type, clinical_trial. For the FULL field list — including nested objects like pubmed (journal, year, doi), reagent, experiment, cde — dot-path projection syntax (e.g. 'pubmed.journal'), 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 the 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 subject (default False). Results are always returned in relevance order regardless of this flag.

EFFICIENCY TIPS:

  • Cross-study questions (e.g. 'which subjects had assay 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.

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
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: 'No authentication required', default facets omitted, hard cap of 10000 on page_size, results always in relevance order regardless of include_score, and quantified response-size costs (~2,500 chars/row full vs ~150 chars restricted). It even flags a concrete trap — '*' does not work as a wildcard for source_fields.

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?

The purpose and return shape are front-loaded before the parameter list, and the sectioned layout (Key parameters / EFFICIENCY TIPS) makes it navigable. It is long, and a few lines such as the page_size sizing arithmetic are verbose, but almost every sentence carries actionable information for a 26-parameter tool.

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?

Given 26 optional parameters, no annotations, and a rich output, the definition covers invocation, sizing, pagination loop procedure, facet semantics, and cross-references to resources for the full field list. An agent could call this correctly on the first try without opening the schema; the output schema covers return values, so the description rightly does not restate them.

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 26 parameters, so the description must compensate, and it documents nearly all of them with examples, accepted values, and defaults (sort_field enumerates all valid values; facet_limit explains the 'other' bucket semantics; source_fields lists common fields and points to immport://search-fields). Only minor gaps remain, such as the format of age_range and search_fields.

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 subjects/participants') plus the exact return shape {total, returned, subjects, facets}. It is clearly distinguishable from siblings search_studies and get_study_data, and the example use case ('find all female subjects in influenza studies') pins down the subject-level scope.

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 routes: use ONE call with wide page_size instead of looping get_study_data per study, and issue lookup_controlled_vocabulary calls in parallel rather than first. It also states when NOT to use facets ('omit for discovery/lookup queries... only request facets when the question is about distribution/breakdown'), which is exactly the kind of exclusion guidance most definitions omit.

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