Koskamo

clinicaltrialsgov-mcp-server

An MCP server that allows agents to search over 600,000 clinical trial studies on ClinicalTrials.gov, retrieve full study records and posted results, and match patient profiles to eligible recruiting trials. It supports full-text and field-specific queries, status/phase/geographic filters, and provides tools for discovering valid API fields and values.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

clinicaltrialsgov-mcp-server logo, by cyanheadsCommunity listingStreamable HTTPNo sign-inEndpoint checked 2026-11-07Published by cyanheads
MCP endpoint (Streamable HTTP)
https://clinicaltrials.caseyjhand.com/mcp
Vendor documentation

What its tools do

7 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

7 of 7 have a description · 7 of 7 declare behavior hints · 7 of 7 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Search for clinical trial studies using full-text or field-specific queries
  • Retrieve full study records and posted results by NCT ID
  • Match patient demographics and conditions to candidate recruiting trials

Source and maintenance

Community listingRegistry 2.11.1
Maintenance checked

Protocol and capabilities

Server
clinicaltrialsgov-mcp-server 2.11.1
MCP protocol negotiated in check
2025-11-25
Tools
7 advertised
Resources
1 advertised
Resource templates
2 advertised
Prompts
1 advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": true
  },
  "logging": {},
  "prompts": {
    "listChanged": true
  },
  "resources": {
    "subscribe": true,
    "listChanged": true
  },
  "extensions": {
    "io.modelcontextprotocol/skills": {
      "directoryRead": true
    }
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Use the clinicaltrials_* tools to access the ClinicalTrials.gov registry — public, read-only, 600K+ studies. Studies are addressed by NCT ID (NCT followed by 8 digits). Field names for the fields, advancedFilter, and sort parameters are PascalCase leaves (NCTId, OverallStatus, EnrollmentCount) — call clinicaltrials_get_field_definitions to discover them and clinicaltrials_get_field_values for valid enum values. Typical workflow: clinicaltrials_search_studies (compact per-study index by default, including hasResults; pass fields for specific leaves) → clinicaltrials_get_study_record → clinicaltrials_get_study_results (only when hasResults=true). Use clinicaltrials_get_study_count for cheap breakdowns and clinicaltrials_find_eligible for patient matching. The clinicaltrialsgov-guide skill (skill://clinicaltrialsgov-guide/SKILL.md) carries the gates for site versus study recruiting status, overlapping phase counts, RANGE and partial-date filters, the status vocabulary, and reading posted results.

Tools

7 advertised

clinicaltrials_search_studies — Clinicaltrials Search Studies
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Search for clinical trial studies from ClinicalTrials.gov. Supports full-text and field-specific queries, status/phase/geographic filters, pagination, sorting, and field selection. Returns a compact per-study index by default; pass the fields parameter to get specific leaves at full fidelity — full study records are ~70KB each.

clinicaltrials_search_studies input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "sort": {
      "type": "string",
      "description": "Sort order. Format: FieldName:asc or FieldName:desc. E.g., \"LastUpdatePostDate:desc\", \"EnrollmentCount:desc\". Max 2 fields comma-separated. For \"largest trials\" queries, pair EnrollmentCount:desc with advancedFilter \"AREA[StudyType]INTERVENTIONAL\" — the top enrollment counts are observational registry/claims studies enrolling tens of millions. Enrollment counts are sponsor-reported and not validated upstream beyond the unknown-enrollment sentinel exclusion. Use clinicaltrials_get_field_definitions to find sortable field names."
    },
    "query": {
      "type": "string",
      "description": "General free-text search across all fields. Runs the 57-field relevance search ClinicalTrials.gov publishes for this parameter — NCTId, NCTIdAlias, OrgStudyId, SecondaryId, Acronym, BriefTitle, OfficialTitle, Condition, InterventionName, InterventionOtherName, Phase, StdAge, StudyType, BriefSummary, outcome measures and their descriptions, LeadSponsorName, CollaboratorName, the Location* fields, the Design* fields, and the ConditionAncestorTerm/InterventionAncestorTerm MeSH umbrellas — so a hit need not carry your term in the field you had in mind. Plain words plus AND, OR, NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression — those work here as well as in advancedFilter, so AREA[Phase]PHASE2 is accepted in this parameter; a stray bracket fails. `( )` group sub-expressions and work when matched; `,` acts as AND. The dedicated *Query parameters (conditionQuery, interventionQuery, etc.) scope a search to one field."
    },
    "fields": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "PascalCase leaf names to return; strongly recommended since full records are ~70KB. Omit for the compact index projection — an empty list is rejected, not treated as omission. A comma- or pipe-joined entry (\"NCTId,BriefTitle\") is split into separate names. Common leaves: NCTId, BriefTitle, BriefSummary, OverallStatus, Phase, LeadSponsorName, Condition. Call clinicaltrials_get_field_definitions with a concept query (e.g., \"adverse events\", \"eligibility\") to find the exact leaf for any concept."
    },
    "nctIds": {
      "anyOf": [
        {
          "type": "string",
          "pattern": "^NCT\\d{8}$",
          "description": "A single NCT ID."
        },
        {
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^NCT\\d{8}$"
          },
          "maxItems": 1000,
          "description": "Multiple NCT IDs (OR), at most 1000 entries counting repeats."
        }
      ],
      "description": "Filter to specific NCT IDs for batch lookups. Omit to search every study — an empty list is rejected, not treated as \"no filter\". Repeated IDs collapse to one, first occurrence kept. One request carries as many leading IDs as fit ClinicalTrials.gov's URL length limit beside the other parameters — about 560 when nothing else is set, fewer beside long queries or field lists — and the rest come back unqueried in deferredNctIds, in order, for a follow-up call; every page of a walk queries the same IDs. A list over 1000 entries, repeats included, is rejected. Supplying this lifts the default unknown-enrollment exclusion, so an ID you name is never filtered out of its own lookup."
    },
    "pageSize": {
      "type": "integer",
      "default": 10,
      "maximum": 1000,
      "minimum": 1,
      "description": "Results per page, 1–1000. A value above this server's per-page cap (200 unless the operator changed it) returns a page at the cap, reported in truncated/shown/cap with nextPageToken to continue."
    },
    "geoFilter": {
      "type": "string",
      "description": "Geographic proximity filter. Format: distance(lat,lon,radius), where radius carries a `mi` or `km` suffix — e.g. \"distance(47.6062,-122.3321,50mi)\" for studies within 50 miles of Seattle. The suffix is required: a radius with no unit is rejected, as are a non-positive radius, a latitude outside [-90, 90], and a longitude outside [-180, 180]. When set, each study's locations are re-sorted by proximity to the center so the nearest matched site leads, annotated with its distance in miles; the full location list is preserved."
    },
    "pageToken": {
      "type": "string",
      "description": "Pagination cursor: a previous response's nextPageToken, passed back unchanged with the same criteria. Tokens expire when ClinicalTrials.gov refreshes its data."
    },
    "countTotal": {
      "type": "boolean",
      "default": true,
      "description": "Include total study count in response. Only computed on the first page."
    },
    "titleQuery": {
      "type": "string",
      "description": "Search within study titles and acronyms only. Matches Acronym, BriefTitle, and OfficialTitle. Plain words plus AND/OR/NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression, which this parameter accepts; a stray bracket fails. `( )` group sub-expressions when matched; `,` acts as AND."
    },
    "phaseFilter": {
      "anyOf": [
        {
          "type": "string",
          "description": "A single phase value."
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Multiple phase values (OR)."
        }
      ],
      "description": "Filter by trial phase. Omit to search all phases — an empty list is rejected, not treated as \"no filter\". Values: EARLY_PHASE1, PHASE1, PHASE2, PHASE3, PHASE4, NA. Case and spacing variants (\"Phase 3\", \"early phase 1\", \"Not Applicable\") are accepted, and a list or a comma- or pipe-joined string matches any of the phases. Each entry must name a phase — put search expressions (OR, NOT, AREA[…]) in advancedFilter."
    },
    "outcomeQuery": {
      "type": "string",
      "description": "Search within outcome measure fields. Matches PrimaryOutcomeMeasure, SecondaryOutcomeMeasure, OtherOutcomeMeasure, and OutcomeMeasureTitle, plus their description counterparts PrimaryOutcomeDescription, SecondaryOutcomeDescription, OtherOutcomeDescription, OutcomeMeasureDescription, and OutcomeMeasurePopulationDescription — so a term appearing only in outcome prose still matches. Plain words plus AND/OR/NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression, which this parameter accepts; a stray bracket fails. `( )` group sub-expressions when matched; `,` acts as AND."
    },
    "sponsorQuery": {
      "type": "string",
      "description": "Sponsor/collaborator name search. Matches LeadSponsorName, CollaboratorName, and OrgFullName. Plain words plus AND/OR/NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression, which this parameter accepts; a stray bracket fails. `( )` group sub-expressions when matched; `,` acts as AND."
    },
    "statusFilter": {
      "anyOf": [
        {
          "type": "string",
          "description": "A single status value."
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Multiple status values (OR)."
        }
      ],
      "description": "Filter by study status. Omit to search all statuses — an empty list is rejected, not treated as \"no filter\". Values: RECRUITING, COMPLETED, ACTIVE_NOT_RECRUITING, NOT_YET_RECRUITING, ENROLLING_BY_INVITATION, SUSPENDED, TERMINATED, WITHDRAWN, UNKNOWN, WITHHELD, NO_LONGER_AVAILABLE, AVAILABLE, APPROVED_FOR_MARKETING, TEMPORARILY_NOT_AVAILABLE."
    },
    "locationQuery": {
      "type": "string",
      "description": "Location search — city, state, country, or facility name. Matches LocationCity, LocationState, LocationCountry, LocationFacility, and LocationZip; a study matches when any of its sites does. Plain words plus AND/OR/NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression, which this parameter accepts; a stray bracket fails. `( )` group sub-expressions when matched; `,` acts as AND."
    },
    "advancedFilter": {
      "type": "string",
      "description": "Advanced filter using AREA[FieldName]value syntax. Examples: \"AREA[StudyType]INTERVENTIONAL\", \"AREA[EnrollmentCount]RANGE[100, 1000]\", \"AREA[Phase]PHASE2 AND AREA[StudyType]INTERVENTIONAL\", \"(AREA[Phase]PHASE3 OR AREA[Phase]PHASE4) AND AREA[StudyType]INTERVENTIONAL\". \"AREA[HasResults]true\" restricts to studies with posted results. AND/OR/NOT join complete AREA[FieldName]value expressions; parentheses group them. Call clinicaltrials_get_field_definitions to find AREA[]-compatible field names. A field name — a record field, an index-only piece such as NumLocations, or a search area such as ConditionSearch — that differs from the spelling AREA[] accepts only by case (AREA[overallstatus]) is corrected before the request, here and in the query parameters, and searchCriteria shows the expression as sent."
    },
    "conditionQuery": {
      "type": "string",
      "description": "Condition/disease-specific search. E.g., \"Type 2 Diabetes\", \"non-small cell lung cancer\". Matches Condition, BriefTitle, OfficialTitle, ConditionMeshTerm, ConditionAncestorTerm, Keyword, and NCTId. ConditionAncestorTerm is the MeSH umbrella above the conditions a study itself lists, so results run broader than those lists — a study can match a parent term it never names. Plain words plus AND/OR/NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression, which this parameter accepts; a stray bracket fails. `( )` group sub-expressions when matched; `,` acts as AND."
    },
    "interventionQuery": {
      "type": "string",
      "description": "Intervention/treatment search. E.g., \"pembrolizumab\", \"cognitive behavioral therapy\". Matches InterventionName, InterventionType, ArmGroupType, InterventionOtherName, BriefTitle, OfficialTitle, ArmGroupLabel, InterventionMeshTerm, Keyword, InterventionAncestorTerm, InterventionDescription, and ArmGroupDescription. InterventionAncestorTerm is the MeSH umbrella above the interventions a study itself lists, so results run broader than those lists. Plain words plus AND/OR/NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression, which this parameter accepts; a stray bracket fails. `( )` group sub-expressions when matched; `,` acts as AND."
    },
    "includeUnknownEnrollment": {
      "type": "boolean",
      "default": false,
      "description": "Include studies whose EnrollmentCount is the upstream \"unknown\" sentinel (99999999). Excluded by default — the sentinel pollutes RANGE[N, MAX] queries and EnrollmentCount:desc sorts. Set true for data-quality audits or when targeting unknown-enrollment studies specifically."
    }
  },
  "additionalProperties": false
}
clinicaltrials_search_studies output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "studies"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "integer",
      "maximum": 9007199254740991,
      "description": "The server's per-page cap, served in place of the requested pageSize when truncated is true.",
      "exclusiveMinimum": 0
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "blank_value",
                "ids_not_found",
                "field_invalid",
                "enum_invalid",
                "query_parse_error",
                "geo_invalid",
                "sort_invalid",
                "page_token_invalid",
                "request_too_long",
                "rate_limited"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `blank_value`: A parameter was supplied with a blank, whitespace-only, or empty-list value. A fields or phaseFilter entry of only invisible format characters (zero-width space) is blank, and so is a phaseFilter entry of only quotes. `ids_not_found`: One or more NCT IDs in the nctIds filter are not present at ClinicalTrials.gov. `field_invalid`: A name in the fields parameter is not a field, or an AREA[] expression names a field ClinicalTrials.gov does not recognize or cannot search by value — often a module or group such as LeadSponsor instead of a leaf piece such as LeadSponsorName. `enum_invalid`: A phaseFilter entry resolves to none of the six phase values, or statusFilter or an AREA[] expression carries a value ClinicalTrials.gov does not accept. `query_parse_error`: A free-text query or advancedFilter expression uses syntax the upstream Essie parser rejects — typically a `[` or `]` outside an AREA[…] / RANGE[…] expression, an unmatched `(` / `)`, or an unterminated quote in a query/conditionQuery/etc. value. `geo_invalid`: geoFilter is not a well-formed distance(lat,lon,radius) expression. `sort_invalid`: sort is not FieldName:asc / FieldName:desc, or names more than 2 fields. `page_token_invalid`: ClinicalTrials.gov rejected pageToken as malformed (not a token it issued), or as unresumable (issued before a data refresh, or altered after issue). `request_too_long`: The request URL runs past the length ClinicalTrials.gov accepts — long free-text queries, advancedFilter, or fields — or the other parameters leave no room for even one nctIds entry. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 0,
      "description": "Studies on this page when truncated is true."
    },
    "notice": {
      "type": "string",
      "description": "Recovery guidance when no studies matched — echoes the constraint and suggests how to broaden, and names nctIds as part of the unmatched criteria when an ID list was supplied. On a page cut to the server's per-page cap, states the requested and served page sizes and points at nextPageToken. Absent on other pages with results, and on an exhausted continuation page, where the cohort already matched and there is nothing to broaden."
    },
    "studies": {
      "type": "array",
      "items": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {}
      },
      "description": "Matching studies. By default each entry is a COMPACT index projection — nctId, briefTitle, overallStatus, phases, enrollmentCount, leadSponsor, conditions, hasResults, startDate and primaryCompletionDate (YYYY-MM or YYYY-MM-DD, as registered), and a bounded locations summary ({ total, nearest: { facility, city, state, country, status, distanceMi } }). nearest is the site closest to the geoFilter center, carrying distanceMi, or the lead registered site when no geoFilter is set; its status is that one site's own recruitment status, which can differ from the study's overallStatus, and is absent when the site publishes none. Keys the study does not publish are omitted — mirroring the rendered result, NOT the full ~70KB record. Pass the fields parameter to receive exactly the requested leaves at full fidelity instead (e.g. all locations). Fetch a full single record with clinicaltrials_get_study_record."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when pageSize was above the server's per-page cap and this page filled to the cap with a nextPageToken. Without a total to check against (countTotal: false, or a continuation page), that next page can be empty. Absent otherwise."
    },
    "totalCount": {
      "type": "number",
      "description": "Total matching studies (first page only when countTotal=true)."
    },
    "nextPageToken": {
      "type": "string",
      "description": "Token for the next page. Absent when this response already carries every matching study; otherwise it mirrors the upstream cursor, which ClinicalTrials.gov emits whenever a page fills to pageSize — so on a continuation page a token can still lead to an empty page."
    },
    "pageExhausted": {
      "type": "boolean",
      "description": "True when this call supplied a pageToken and the continuation page came back empty — the walk is finished and no further pages exist. Absent on every other response, including an empty first page, which is an unmatched search rather than exhausted pagination."
    },
    "deferredNctIds": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "IDs from nctIds that did not fit in one ClinicalTrials.gov request beside the other parameters, deduplicated, in first-occurrence order. Not queried — studies and totalCount cover only the IDs that went out; pass these as nctIds in a follow-up call with the same criteria. Every page of a walk defers the same IDs. Absent when every requested ID was queried."
    },
    "searchCriteria": {
      "type": "object",
      "description": "Echo of active query/filter criteria applied to this search, including sentinelFilterActive when the default unknown-enrollment exclusion is in effect. Present on every response.",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    },
    "requestedFields": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Echo of the explicit fields parameter, with comma- or pipe-joined entries split into separate names and repeated names listed once — present only when the caller passed fields. Signals that studies carry the requested leaves at full fidelity (not the default compact index) and that the rendered truncation cap is lifted so all of them appear."
    }
  },
  "additionalProperties": false
}
clinicaltrials_search_studies annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true
}
clinicaltrials_get_study_record — Clinicaltrials Get Study Record
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Fetch a single clinical trial study by NCT ID from ClinicalTrials.gov. Returns the full study record including protocol details, eligibility criteria, outcomes, arms, interventions, contacts, and locations. Optional locationLimit / outcomeLimit / referenceLimit / nearLocation parameters trim locations, outcomes, and references — original totals are preserved in `filtersApplied` only when a cap actually trims the set.

clinicaltrials_get_study_record input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "nctId"
  ],
  "properties": {
    "nctId": {
      "type": "string",
      "pattern": "^NCT\\d{8}$",
      "description": "NCT identifier — format `NCT` followed by 8 digits (e.g., `NCT03722472`)."
    },
    "nearLocation": {
      "type": "object",
      "required": [
        "lat",
        "lon"
      ],
      "properties": {
        "lat": {
          "type": "number",
          "maximum": 90,
          "minimum": -90,
          "description": "Latitude in decimal degrees."
        },
        "lon": {
          "type": "number",
          "maximum": 180,
          "minimum": -180,
          "description": "Longitude in decimal degrees."
        },
        "radiusMi": {
          "type": "number",
          "default": 50,
          "minimum": 1,
          "description": "Radius in miles, at least 1. Default 50. A radius past the farthest site keeps every site with published coordinates."
        }
      },
      "description": "Filter returned locations to those within radius of (lat, lon) and sort by distance. Adds distanceMi to each location. Locations without published coordinates are dropped — most US sites carry them; international sites less reliably so. Distances reflect ClinicalTrials.gov geocoding granularity — typically city-centroid, not facility-level — so multiple sites in the same city resolve to near-identical distances. For broader geographic filtering across studies, use clinicaltrials_search_studies with geoFilter.",
      "additionalProperties": false
    },
    "outcomeLimit": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Optional cap on the number of secondary and other outcomes returned. Omit for no cap (full upstream lists); a value at or past a list length also returns that whole list. Primary outcomes are never capped. Original totals preserved in filtersApplied.totalSecondaryOutcomes / totalOtherOutcomes only when the cap trims a list."
    },
    "locationLimit": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Optional cap on the number of locations returned. Omit for no cap (full upstream list); a value at or past the list length also returns every location. Pairs naturally with nearLocation for narrowing a large multi-site trial. Original total preserved in filtersApplied.totalLocations only when the cap trims the list."
    },
    "referenceLimit": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Optional cap on the number of references returned. Omit for no cap (full upstream list); a value at or past the list length also returns every reference. Original total preserved in filtersApplied.totalReferences only when the cap trims the list. seeAlsoLinks are never capped."
    }
  },
  "additionalProperties": false
}
clinicaltrials_get_study_record output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "study",
        "filtersApplied"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "study_not_found",
                "rate_limited"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `study_not_found`: The provided NCT ID does not match any study at ClinicalTrials.gov. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "study": {
      "type": "object",
      "description": "Full study record with caller-requested filters already applied to locations and outcomes. Top-level keys: protocolSection (identification, status, sponsor, conditions, design, arms/interventions, outcomes, eligibility, contacts/locations), derivedSection (MeSH-normalized terms), hasResults, documentSection. The heavy resultsSection is omitted — see resultsSummary for counts and clinicaltrials_get_study_results for full results data. Use clinicaltrials_get_field_definitions to explore the schema.",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    },
    "filtersApplied": {
      "type": "object",
      "properties": {
        "nearLocation": {
          "type": "object",
          "required": [
            "lat",
            "lon",
            "radiusMi"
          ],
          "properties": {
            "lat": {
              "type": "number",
              "description": "Latitude in decimal degrees."
            },
            "lon": {
              "type": "number",
              "description": "Longitude in decimal degrees."
            },
            "radiusMi": {
              "type": "number",
              "description": "Radius in miles."
            }
          },
          "description": "Echo of the nearLocation input.",
          "additionalProperties": false
        },
        "outcomeLimit": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Echo of the outcomeLimit input — present only when the cap trimmed a list."
        },
        "locationLimit": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Echo of the locationLimit input — present only when the cap trimmed the list."
        },
        "referenceLimit": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Echo of the referenceLimit input — present only when the cap trimmed the list."
        },
        "totalLocations": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Upstream location count before any filter was applied."
        },
        "totalReferences": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Upstream reference count before referenceLimit was applied."
        },
        "totalOtherOutcomes": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Upstream other outcomes count before outcomeLimit was applied."
        },
        "locationsWithoutGeo": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Number of upstream locations dropped because they lacked geoPoint when nearLocation was provided."
        },
        "totalSecondaryOutcomes": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Upstream secondary outcomes count before outcomeLimit was applied."
        }
      },
      "description": "Metadata about the filtering applied to `study`.",
      "additionalProperties": false
    },
    "resultsSummary": {
      "type": "object",
      "properties": {
        "outcomeMeasures": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Posted outcome measures."
        },
        "baselineMeasures": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Baseline characteristic measures."
        },
        "otherAdverseEvents": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Distinct other (non-serious) adverse-event terms."
        },
        "seriousAdverseEvents": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Distinct serious adverse-event terms."
        },
        "participantFlowPeriods": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "Participant-flow periods."
        }
      },
      "description": "Compact counts of posted results, present when hasResults is true. The full resultsSection is intentionally omitted from this record-level tool — fetch it via clinicaltrials_get_study_results.",
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}
clinicaltrials_get_study_record annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true
}
clinicaltrials_get_study_count — Clinicaltrials Get Study Count
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Get total clinical trial study count from ClinicalTrials.gov matching a query, without fetching study data. Fast and lightweight. Use for quick statistics or to build breakdowns by calling multiple times with different filters (e.g., count by phase, count by status, count recruiting vs completed for a condition).

clinicaltrials_get_study_count input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "query": {
      "type": "string",
      "description": "General free-text search across all fields. Runs the 57-field relevance search ClinicalTrials.gov publishes for this parameter — NCTId, NCTIdAlias, OrgStudyId, SecondaryId, Acronym, BriefTitle, OfficialTitle, Condition, InterventionName, InterventionOtherName, Phase, StdAge, StudyType, BriefSummary, outcome measures and their descriptions, LeadSponsorName, CollaboratorName, the Location* fields, the Design* fields, and the ConditionAncestorTerm/InterventionAncestorTerm MeSH umbrellas — so a hit need not carry your term in the field you had in mind. Plain words plus AND, OR, NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression — those work here as well as in advancedFilter, so AREA[Phase]PHASE2 is accepted in this parameter; a stray bracket fails. `( )` group sub-expressions and work when matched; `,` acts as AND. The dedicated *Query parameters (conditionQuery, interventionQuery, etc.) scope a search to one field."
    },
    "titleQuery": {
      "type": "string",
      "description": "Search within study titles and acronyms only. Matches Acronym, BriefTitle, and OfficialTitle. Plain words plus AND/OR/NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression, which this parameter accepts; a stray bracket fails. `( )` group sub-expressions when matched; `,` acts as AND."
    },
    "phaseFilter": {
      "anyOf": [
        {
          "type": "string",
          "description": "A single phase value."
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Multiple phase values (OR)."
        }
      ],
      "description": "Filter by trial phase. Omit to count all phases — an empty list is rejected, not treated as \"no filter\". Values: EARLY_PHASE1, PHASE1, PHASE2, PHASE3, PHASE4, NA. Case and spacing variants (\"Phase 3\", \"early phase 1\", \"Not Applicable\") are accepted, and a list or a comma- or pipe-joined string matches any of the phases. Each entry must name a phase — put search expressions (OR, NOT, AREA[…]) in advancedFilter."
    },
    "outcomeQuery": {
      "type": "string",
      "description": "Search within outcome measure fields. Matches PrimaryOutcomeMeasure, SecondaryOutcomeMeasure, OtherOutcomeMeasure, and OutcomeMeasureTitle, plus their description counterparts PrimaryOutcomeDescription, SecondaryOutcomeDescription, OtherOutcomeDescription, OutcomeMeasureDescription, and OutcomeMeasurePopulationDescription — so a term appearing only in outcome prose still matches. Plain words plus AND/OR/NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression, which this parameter accepts; a stray bracket fails. `( )` group sub-expressions when matched; `,` acts as AND."
    },
    "sponsorQuery": {
      "type": "string",
      "description": "Sponsor/collaborator name search. Matches LeadSponsorName, CollaboratorName, and OrgFullName. Plain words plus AND/OR/NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression, which this parameter accepts; a stray bracket fails. `( )` group sub-expressions when matched; `,` acts as AND."
    },
    "statusFilter": {
      "anyOf": [
        {
          "type": "string",
          "description": "A single status value."
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Multiple status values (OR)."
        }
      ],
      "description": "Filter by study status. Omit to count all statuses — an empty list is rejected, not treated as \"no filter\". Values: RECRUITING, COMPLETED, ACTIVE_NOT_RECRUITING, NOT_YET_RECRUITING, ENROLLING_BY_INVITATION, SUSPENDED, TERMINATED, WITHDRAWN, UNKNOWN, WITHHELD, NO_LONGER_AVAILABLE, AVAILABLE, APPROVED_FOR_MARKETING, TEMPORARILY_NOT_AVAILABLE."
    },
    "locationQuery": {
      "type": "string",
      "description": "Location search — city, state, country, or facility name. Matches LocationCity, LocationState, LocationCountry, LocationFacility, and LocationZip; a study matches when any of its sites does. Plain words plus AND/OR/NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression, which this parameter accepts; a stray bracket fails. `( )` group sub-expressions when matched; `,` acts as AND."
    },
    "advancedFilter": {
      "type": "string",
      "description": "Advanced filter using AREA[FieldName]value syntax. Examples: \"AREA[StudyType]INTERVENTIONAL\", \"AREA[EnrollmentCount]RANGE[100, 1000]\", \"AREA[Phase]PHASE2 AND AREA[StudyType]INTERVENTIONAL\", \"(AREA[Phase]PHASE3 OR AREA[Phase]PHASE4) AND AREA[StudyType]INTERVENTIONAL\". AND/OR/NOT join complete AREA[FieldName]value expressions; parentheses group them. Call clinicaltrials_get_field_definitions to find AREA[]-compatible field names. A field name — a record field, an index-only piece such as NumLocations, or a search area such as ConditionSearch — that differs from the spelling AREA[] accepts only by case (AREA[overallstatus]) is corrected before the request, here and in the query parameters, and searchCriteria shows the expression as sent."
    },
    "conditionQuery": {
      "type": "string",
      "description": "Condition/disease-specific search. E.g., \"Type 2 Diabetes\", \"non-small cell lung cancer\". Matches Condition, BriefTitle, OfficialTitle, ConditionMeshTerm, ConditionAncestorTerm, Keyword, and NCTId. ConditionAncestorTerm is the MeSH umbrella above the conditions a study itself lists, so results run broader than those lists — a study can match a parent term it never names. Plain words plus AND/OR/NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression, which this parameter accepts; a stray bracket fails. `( )` group sub-expressions when matched; `,` acts as AND."
    },
    "interventionQuery": {
      "type": "string",
      "description": "Intervention/treatment search. E.g., \"pembrolizumab\", \"cognitive behavioral therapy\". Matches InterventionName, InterventionType, ArmGroupType, InterventionOtherName, BriefTitle, OfficialTitle, ArmGroupLabel, InterventionMeshTerm, Keyword, InterventionAncestorTerm, InterventionDescription, and ArmGroupDescription. InterventionAncestorTerm is the MeSH umbrella above the interventions a study itself lists, so results run broader than those lists. Plain words plus AND/OR/NOT. `[ ]` are valid only inside an AREA[FieldName]value or RANGE[min, max] expression, which this parameter accepts; a stray bracket fails. `( )` group sub-expressions when matched; `,` acts as AND."
    },
    "includeUnknownEnrollment": {
      "type": "boolean",
      "default": false,
      "description": "Include studies whose EnrollmentCount is the upstream \"unknown\" sentinel (99999999). Excluded by default — the sentinel pollutes RANGE[N, MAX] queries. Set true for data-quality audits."
    }
  },
  "additionalProperties": false
}
clinicaltrials_get_study_count output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "totalCount"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "blank_value",
                "field_invalid",
                "enum_invalid",
                "query_parse_error",
                "request_too_long",
                "rate_limited"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `blank_value`: A parameter was supplied with a blank, whitespace-only, or empty-list value. A phaseFilter entry of only quotes or invisible format characters (zero-width space) is blank. `field_invalid`: An AREA[] expression in advancedFilter or a query parameter names a field ClinicalTrials.gov does not recognize or cannot search by value — often a module or group such as LeadSponsor instead of a leaf piece such as LeadSponsorName. `enum_invalid`: A phaseFilter entry resolves to none of the six phase values, or statusFilter or an AREA[] expression carries a value ClinicalTrials.gov does not accept. `query_parse_error`: A free-text query or advancedFilter expression uses syntax the upstream Essie parser rejects — typically a `[` or `]` outside an AREA[…] / RANGE[…] expression, an unmatched `(` / `)`, or an unterminated quote in a query/conditionQuery/etc. value. `request_too_long`: The request URL runs past the length ClinicalTrials.gov accepts — typically a very long free-text query or advancedFilter expression. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "notice": {
      "type": "string",
      "description": "Recovery guidance when totalCount is 0 — suggests how to broaden the query or filters."
    },
    "totalCount": {
      "type": "number",
      "description": "Total studies matching the query/filters."
    },
    "searchCriteria": {
      "type": "object",
      "description": "Echo of active query/filter criteria applied to this count, including sentinelFilterActive when the default unknown-enrollment exclusion is in effect.",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {}
    }
  },
  "additionalProperties": false
}
clinicaltrials_get_study_count annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true
}
clinicaltrials_get_field_values — Clinicaltrials Get Field Values
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Discover valid values for ClinicalTrials.gov fields with study counts per value. Use to explore available filter options before building a search — e.g., valid OverallStatus, Phase, InterventionType, StudyType, or LeadSponsorClass values.

clinicaltrials_get_field_values input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "fields"
  ],
  "properties": {
    "fields": {
      "anyOf": [
        {
          "type": "string",
          "description": "A single PascalCase field name."
        },
        {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Multiple PascalCase field names (at least one required)."
        }
      ],
      "description": "PascalCase field name(s) to get value statistics for — an empty list is rejected, not treated as \"every field\". A comma- or pipe-joined string (\"Phase,StudyType\") is split into separate names. Examples: OverallStatus, Phase, StudyType, Sex, LeadSponsorClass. Use clinicaltrials_get_field_definitions with a query to find more field names."
    }
  },
  "additionalProperties": false
}
clinicaltrials_get_field_values output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "fieldStats"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "blank_value",
                "field_invalid",
                "request_too_long",
                "rate_limited"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `blank_value`: A parameter was supplied with a blank, whitespace-only, or empty-list value. `field_invalid`: A requested field name is not a valid PascalCase piece name. `request_too_long`: The fields list makes the request URL longer than ClinicalTrials.gov accepts — a few hundred piece names in one call. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "notice": {
      "type": "string",
      "description": "Present when a longest value was cut to a preview — names, for each such field, the clinicaltrials_search_studies arguments that return its full text."
    },
    "fieldStats": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "field",
          "piece",
          "type"
        ],
        "properties": {
          "avg": {
            "type": "number",
            "description": "Mean of the recorded values. Present for INTEGER/NUMBER fields."
          },
          "max": {
            "anyOf": [
              {
                "type": "number",
                "description": "Largest value of an INTEGER/NUMBER field."
              },
              {
                "type": "string",
                "description": "Latest value of a DATE field, at the precision recorded."
              }
            ],
            "description": "Largest recorded value — a number for INTEGER/NUMBER, a date string for DATE."
          },
          "min": {
            "anyOf": [
              {
                "type": "number",
                "description": "Smallest value of an INTEGER/NUMBER field."
              },
              {
                "type": "string",
                "description": "Earliest value of a DATE field, at the precision recorded — a partial date such as \"1900-01\" stays partial."
              }
            ],
            "description": "Smallest recorded value — a number for INTEGER/NUMBER, a date string for DATE."
          },
          "type": {
            "type": "string",
            "description": "Field data type (ENUM, BOOLEAN, STRING, DATE, etc.)."
          },
          "field": {
            "type": "string",
            "description": "Full dot-notation field path."
          },
          "piece": {
            "type": "string",
            "description": "PascalCase piece name."
          },
          "formats": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "A date pattern, e.g. \"yyyy-MM-dd\"."
            },
            "description": "Date patterns this field is recorded in. Present for DATE fields; more than one means the field mixes precisions across studies."
          },
          "longest": {
            "type": "object",
            "required": [
              "value",
              "length",
              "nctId"
            ],
            "properties": {
              "nctId": {
                "type": "string",
                "description": "NCT ID of a study carrying it."
              },
              "value": {
                "type": "string",
                "description": "The longest recorded value — when truncated is true, only a prefix of at most 2,000 characters (1,999 when the cut would split a surrogate pair)."
              },
              "length": {
                "type": "number",
                "description": "Full length of the recorded value in characters, even when truncated."
              },
              "truncated": {
                "type": "boolean",
                "const": true,
                "description": "True when value is a preview of at most 2,000 characters; absent when value is whole. The notice names the clinicaltrials_search_studies call that returns the full text."
              }
            },
            "description": "Longest recorded value with its length and a study carrying it. Present for STRING fields only.",
            "additionalProperties": false
          },
          "topValues": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "value",
                "studiesCount"
              ],
              "properties": {
                "value": {
                  "type": "string",
                  "description": "Field value."
                },
                "studiesCount": {
                  "type": "number",
                  "description": "Number of studies with this value."
                }
              },
              "description": "A value and its study count.",
              "additionalProperties": false
            },
            "description": "Values ranked by frequency (capped at 250 by the API). Present for ENUM/STRING fields. When multiValued is true, studiesCount sums can exceed the study total."
          },
          "trueCount": {
            "type": "number",
            "description": "Studies where field is true. Present for BOOLEAN fields."
          },
          "falseCount": {
            "type": "number",
            "description": "Studies where field is false. Present for BOOLEAN fields."
          },
          "multiValued": {
            "type": "boolean",
            "description": "True when the field is repeated — array-typed itself (Phase, Condition) or nested under a repeated object (LocationCountry, one per site) — so a study can carry several values and the per-value studiesCount buckets sum above the study total. Use to avoid computing a percentage against the corpus."
          },
          "uniqueValuesCount": {
            "type": "number",
            "description": "Number of distinct values, as ClinicalTrials.gov reports it. Free-text STRING fields it does not count (DetailedDescription, EligibilityCriteria) report 0 here alongside uniqueValuesCounted: false — that 0 is not a count. A 0 without the flag means no recorded values."
          },
          "missingStudiesCount": {
            "type": "number",
            "description": "Number of studies where this field is absent."
          },
          "uniqueValuesCounted": {
            "type": "boolean",
            "const": false,
            "description": "False when ClinicalTrials.gov did not count distinct values for this field, so the uniqueValuesCount of 0 is not a real count — the field has recorded values (see longest) but no topValues. Absent otherwise."
          }
        },
        "description": "Statistics for a single requested field.",
        "additionalProperties": false
      },
      "description": "One entry per requested field: canonical path, PascalCase piece name, data type, and the statistics variant that type carries — top values with study counts plus unique/longest for ENUM/STRING, trueCount/falseCount for BOOLEAN, min/max/avg for INTEGER/NUMBER, min/max/formats for DATE."
    }
  },
  "additionalProperties": false
}
clinicaltrials_get_field_values annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true
}
clinicaltrials_get_field_definitions — Clinicaltrials Get Field Definitions
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Resolve valid field names from the ClinicalTrials.gov data model — the canonical PascalCase identifiers (OverallStatus, EnrollmentCount, LeadSponsorName) accepted by the `fields`, `advancedFilter`, and `sort` parameters of other tools, and as input to clinicaltrials_get_field_values. Select a mode: `"search"` — keyword search returning ranked matches (pass `query`, e.g. "enrollment", "sponsor", "adverse events"); `"drill"` — drill into a specific section by dot-notation path (pass `path`, e.g. "protocolSection.designModule"); `"overview"` — top-level summary of all sections (no additional args).

clinicaltrials_get_field_definitions input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "mode"
  ],
  "properties": {
    "mode": {
      "enum": [
        "search",
        "drill",
        "overview"
      ],
      "type": "string",
      "description": "Operation mode. \"search\" — keyword search (requires `query`); \"drill\" — drill into a section by path (requires `path`); \"overview\" — list all top-level sections (no other args needed)."
    },
    "path": {
      "type": "string",
      "description": "drill mode only. Dot-notation path to drill into — e.g., \"protocolSection.designModule\", \"protocolSection.eligibilityModule\", \"resultsSection\". Returns the section's individual fields."
    },
    "limit": {
      "type": "integer",
      "default": 20,
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "search mode only. Maximum results to return. Default: 20. A value at or past the match count returns every match."
    },
    "query": {
      "type": "string",
      "description": "search mode only. Keyword to search field names by — e.g., \"enrollment\", \"sponsor\", \"adverse events\". Returns matching field names ranked by relevance with their full paths and data types."
    },
    "includeIndexedOnly": {
      "type": "boolean",
      "description": "drill mode only. Also list index-only pieces (search-index fields such as StudyFirstPostYear) alongside the record fields. Default: false."
    }
  },
  "additionalProperties": false
}
clinicaltrials_get_field_definitions output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "fields",
        "totalFields"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "number",
      "description": "The limit cap applied to this search (search mode only)."
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "blank_value",
                "mode_mismatch",
                "mode_requires",
                "path_not_found",
                "rate_limited"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `blank_value`: The selected mode's required argument was supplied with a whitespace-only value. `mode_mismatch`: An argument belonging to a different mode was supplied alongside the selected mode. `mode_requires`: The selected mode's required argument was omitted. `path_not_found`: The dot-notation path does not match any node in the field tree. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "number",
      "description": "Number of fields returned (search mode only)."
    },
    "fields": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Field name (camelCase)."
          },
          "path": {
            "type": "string",
            "description": "Full dot-notation path."
          },
          "type": {
            "type": "string",
            "description": "Semantic type."
          },
          "piece": {
            "type": "string",
            "description": "PascalCase identifier for use in `fields`/`AREA[]`/`sort` params."
          },
          "isEnum": {
            "type": "boolean",
            "description": "Whether the field is an enum type."
          },
          "children": {
            "type": "array",
            "items": {
              "type": "object",
              "propertyNames": {
                "type": "string"
              },
              "additionalProperties": {}
            },
            "description": "Child fields (overview mode only)."
          },
          "sourceType": {
            "type": "string",
            "description": "Data type in the model."
          },
          "description": {
            "type": "string",
            "description": "Human-readable description from the upstream data model. Often absent."
          }
        },
        "description": "A single field definition node.",
        "additionalProperties": false
      },
      "description": "Field definitions, ordered by relevance when mode is \"search\"."
    },
    "notice": {
      "type": "string",
      "description": "Recovery guidance when search mode returns no matches, or a truncation note when results are capped."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when the field list was capped by the limit parameter (search mode only)."
    },
    "searchQuery": {
      "type": "string",
      "description": "Echo of the keyword used in search mode. Absent for drill and overview."
    },
    "totalFields": {
      "type": "number",
      "description": "Total fields returned."
    },
    "resolvedPath": {
      "type": "string",
      "description": "Resolved path when mode is \"drill\"."
    },
    "totalMatches": {
      "type": "number",
      "description": "Total fields matching the query before the limit cap was applied (search mode only). Compare against `shown` to size a follow-up limit, or to see that a capped result set is barely over the cap rather than hundreds deep."
    }
  },
  "additionalProperties": false
}
clinicaltrials_get_field_definitions annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true
}
clinicaltrials_get_study_results — Clinicaltrials Get Study Results
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Fetch clinical trial results data from ClinicalTrials.gov for completed studies — outcome measures with statistics, adverse events, participant flow, baseline characteristics, and results metadata (limitations & caveats, certain-agreement disclosure restrictions, results point of contact). Only available for studies where hasResults is true. Use clinicaltrials_search_studies first to find studies with results. Each call fetches up to 20 distinct NCT IDs and returns any further IDs in deferredNctIds for a follow-up call. A results-rich record can exceed 500KB per study in full mode — bound it with summary=true, narrower sections, or the outcomeLimit / adverseEventLimit caps; outcomeLimit / outcomeOffset also page summarized outcomes. A bounded list is resumable: outcomeOffset / seriousEventOffset / otherEventOffset start the next window, and each study's filtersApplied reports what was trimmed and the next offset for every list left short. A previous (alias) NCT ID resolves to its canonical study, named in canonicalNctId.

clinicaltrials_get_study_results input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "nctIds"
  ],
  "properties": {
    "nctIds": {
      "anyOf": [
        {
          "type": "string",
          "pattern": "^NCT\\d{8}$",
          "description": "A single NCT ID."
        },
        {
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^NCT\\d{8}$"
          },
          "maxItems": 500,
          "description": "Multiple NCT IDs, at most 500 entries counting repeats."
        }
      ],
      "description": "One or more NCT IDs — an empty list is rejected, and a repeated ID collapses to one results entry in first-occurrence order. A call fetches the first 20 distinct IDs; any further distinct IDs come back unfetched in deferredNctIds, in first-occurrence order, for a follow-up call. A list over 500 entries, repeats included, is rejected. E.g., \"NCT12345678\" or [\"NCT12345678\", \"NCT87654321\"]. Use summary=true for large batches to avoid large payloads."
    },
    "summary": {
      "type": "boolean",
      "default": false,
      "description": "Return condensed summaries instead of full data. Full mode renders every row and field on both output channels, so a large results set can exceed 500KB per study; summary mode typically cuts that to a few KB, scaling with the measure count rather than to a fixed ceiling. An outcome summary keeps the title, type, timeframe, paramType, dispersionType, unit, group/class/analysis counts, per-group denominators, a top-line projection of a single class/category cell — labelled with the class and category titles it came from, that class’s own denominators, and a count of the siblings it omits — and the first statistical analysis with its group description and compared groups named by title. The measurements outside that cell and the remaining analyses are dropped; re-run with summary=false to reach them. outcomeLimit / outcomeOffset page the summarized outcome list as they page full mode; the adverse-event bounds do not apply here, since topEvents ranks the whole event list. For a middle ground, keep full mode and cap the two lists that carry the bulk with outcomeLimit / adverseEventLimit."
    },
    "sections": {
      "anyOf": [
        {
          "enum": [
            "outcomes",
            "adverseEvents",
            "participantFlow",
            "baseline",
            "moreInfo"
          ],
          "type": "string",
          "description": "A single section name."
        },
        {
          "type": "array",
          "items": {
            "enum": [
              "outcomes",
              "adverseEvents",
              "participantFlow",
              "baseline",
              "moreInfo"
            ],
            "type": "string"
          },
          "description": "Multiple section names."
        }
      ],
      "description": "Filter which sections to return. Values: outcomes, adverseEvents, participantFlow, baseline, moreInfo. Omit for all sections — an empty list is rejected, not treated as omission."
    },
    "outcomeLimit": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Optional cap on the number of outcome measures returned per study, taken in the order ClinicalTrials.gov publishes them. Omit for no cap (every measure); a limit at or past the list length returns the whole list. Applies in both modes: each surviving measure keeps its complete groups/classes/measurements/analyses tree in full mode, or its whole summary projection with summary: true. Upstream total preserved in filtersApplied.totalOutcomes only when the cap trims the list."
    },
    "outcomeOffset": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 0,
      "description": "Optional index of the first outcome measure to return, in the order ClinicalTrials.gov publishes them. Omit or 0 to start at the first. Pair with outcomeLimit to page a long list: each response reports filtersApplied.nextOutcomeOffset for the study, and the list is exhausted when that field is absent. Applied to every study in the call. An offset at or past the end returns an empty list with filtersApplied.totalOutcomes stating the upstream length, not an error. Works in summary mode too, paging the summarized measures. Rejected when sections excludes outcomes."
    },
    "otherEventOffset": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 0,
      "description": "Optional index of the first other (non-serious) adverse event to return, in upstream order. Omit or 0 to start at the first. Pages independently of seriousEventOffset and pairs with adverseEventLimit. Continue from filtersApplied.nextOtherEventOffset until that field is absent. Applied to every study in the call. Rejected with summary: true or when sections excludes adverseEvents."
    },
    "adverseEventLimit": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Optional cap on the number of serious and other adverse events returned per study, applied to each list separately in upstream order. Omit for no cap (every event); a limit at or past a list’s length returns that whole list. Applies to full mode only — summary mode already ranks the top 20 by the most participants affected in any one event group. Event groups are never capped. Upstream totals preserved in filtersApplied.totalSeriousEvents / totalOtherEvents only when the cap trims a list."
    },
    "seriousEventOffset": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 0,
      "description": "Optional index of the first serious adverse event to return, in upstream order. Omit or 0 to start at the first. Pages independently of otherEventOffset — the two lists have uncorrelated lengths — and pairs with adverseEventLimit, which bounds each list separately. Continue from filtersApplied.nextSeriousEventOffset until that field is absent. Applied to every study in the call. Rejected with summary: true or when sections excludes adverseEvents."
    }
  },
  "additionalProperties": false
}
clinicaltrials_get_study_results output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "results"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "blank_value",
                "offset_not_applicable",
                "rate_limited"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `blank_value`: A parameter was supplied with a blank, whitespace-only, or empty-list value. `offset_not_applicable`: An offset was supplied for a list this call does not return as a window — an adverse-event offset in summary mode, which ranks the whole event list into topEvents, or any offset whose own section the sections filter excludes. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "results": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "nctId",
          "title",
          "hasResults"
        ],
        "properties": {
          "nctId": {
            "type": "string",
            "description": "The NCT identifier as requested, trimmed and uppercased. When it is a previous (alias) ID, ClinicalTrials.gov answers with the canonical record and canonicalNctId names it."
          },
          "title": {
            "type": "string",
            "description": "Study title."
          },
          "baseline": {
            "type": "object",
            "description": "Baseline characteristics. Summary mode: groupCount, measureCount, and measures (title, paramType, unitOfMeasure). Full mode: adds groups and measures with per-group classes/categories/measurements.",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          },
          "moreInfo": {
            "type": "object",
            "description": "Results metadata from moreInfoModule. Summary mode: limitationsAndCaveats, certainAgreement flags (piSponsorEmployee, restrictiveAgreement, restrictionType), and pointOfContact. Full mode: adds certainAgreement.otherDetails.",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          },
          "outcomes": {
            "type": "array",
            "items": {
              "type": "object",
              "propertyNames": {
                "type": "string"
              },
              "additionalProperties": {}
            },
            "description": "Outcome measures with per-group statistics. Summary mode (compact): type, title, timeFrame, paramType, dispersionType, unitOfMeasure, groupCount / classCount, analysisCount (how many analyses the measure carries, when it has any), denoms (the whole measure’s per-group denominators keyed by group title), topStats (the per-group cells of one class/category — each carrying the upstream value verbatim, including an NA/NR sentinel, plus spread, lowerLimit/upperLimit, and the record’s own comment when present), topStatsFrom (classTitle / categoryTitle naming where that cell came from, classDenoms — that class’s own denominators, shaped like denoms, when upstream publishes them — omittedClasses / omittedCategories counts, and a note pointing at summary=false when siblings were dropped), and topAnalysis (statisticalMethod, pValue, paramType/Value, ciPctValue/Lower/Upper, nonInferiorityType, groupDescription naming the subgroup or comparison, groupIds, and groups — the compared groups’ titles in groupIds order — lifted from analyses[0]) when present. Every summary field is resolved per measure. Full mode (default): adds raw groups, classes, categories, measurements, and analyses arrays."
          },
          "hasResults": {
            "type": "boolean",
            "description": "Whether study has posted results."
          },
          "adverseEvents": {
            "type": "object",
            "description": "Adverse events. Summary mode: timeFrame, frequencyThreshold, groupCount, seriousEventCount, otherEventCount, eventGroups (id and title of each event group), plus topEvents — up to 20 events ranked by the most participants affected in any one event group, each with term, organSystem, kind, and byGroup (one { groupId, numAffected, numAtRisk } row per event group; resolve groupId against eventGroups). Counts are never pooled across groups: groups can overlap (a crossover or second-course group re-counts participants of its parent arm), so compare arms row by row. Full mode: frequencyThreshold, eventGroups with descriptions and per-group totals, plus seriousEvents and otherEvents with per-event term and per-group affected/at-risk stats. frequencyThreshold, in either mode, is the reporting threshold as upstream sends it: other (non-serious) events are listed only when their frequency reaches it, so an other event the study does not list may still have occurred below it. Usually a percentage (\"5\", \"0\"), occasionally text (\"any\"); absent when the study publishes none.",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          },
          "canonicalNctId": {
            "type": "string",
            "description": "The canonical NCT identifier of the study that answered — present only when the requested nctId is a previous (alias) ID pointing at a different record. Absent means nctId is already canonical. Requesting an alias and its own canonical ID together returns one entry per requested ID, both carrying the same study."
          },
          "filtersApplied": {
            "type": "object",
            "properties": {
              "outcomeLimit": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "Echo of the outcomeLimit input — present only when the cap cut measures off the end of the window."
              },
              "outcomeOffset": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "Echo of the outcomeOffset input — present only when it skipped measures before the window."
              },
              "totalOutcomes": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "Upstream outcome measure count, before the bounds trimmed the list."
              },
              "otherEventOffset": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "Echo of the otherEventOffset input — present only when it skipped events before the window."
              },
              "totalOtherEvents": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "Upstream other adverse event count, before the bounds trimmed the list."
              },
              "adverseEventLimit": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "Echo of the adverseEventLimit input — present only when the cap cut events off the end of a window. Which list it cut is named by that list’s own next offset."
              },
              "nextOutcomeOffset": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "The outcomeOffset to request next for this study — present only when measures remain past the window. Absent means this study’s outcome list is exhausted."
              },
              "seriousEventOffset": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "Echo of the seriousEventOffset input — present only when it skipped events before the window."
              },
              "totalSeriousEvents": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "Upstream serious adverse event count, before the bounds trimmed the list."
              },
              "nextOtherEventOffset": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "The otherEventOffset to request next for this study — present only when other events remain past the window. Absent means this study’s other event list is exhausted."
              },
              "nextSeriousEventOffset": {
                "type": "integer",
                "maximum": 9007199254740991,
                "minimum": -9007199254740991,
                "description": "The seriousEventOffset to request next for this study — present only when serious events remain past the window. Absent means this study’s serious event list is exhausted."
              }
            },
            "description": "What the outcomeLimit / adverseEventLimit caps and the outcomeOffset / seriousEventOffset / otherEventOffset offsets trimmed on this study, plus the next offset for each list left short. In summary mode only the outcome bounds apply. Present only when a bound actually reduced a list — a window that started at zero and reached the end trimmed nothing. Absent means the payload is the complete upstream set for the requested sections. Offsets apply uniformly to every study in the call, so continuation is reported per study: each exhausts its lists at a different index.",
            "additionalProperties": false
          },
          "participantFlow": {
            "type": "object",
            "description": "Participant flow milestones and drop-outs. Summary mode: groupCount, periodCount. Full mode: adds groups and periods with per-period milestones, achievements, and dropWithdraws.",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          }
        },
        "description": "Extracted results for one study.",
        "additionalProperties": false
      },
      "description": "Results per study."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when a bound — a cap or an offset — trimmed a list on at least one study; absent when nothing was trimmed, matching filtersApplied one level down. Which study, which list, and where to resume is named in that study’s filtersApplied."
    },
    "fetchErrors": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "nctId",
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message."
          },
          "nctId": {
            "type": "string",
            "description": "NCT ID."
          }
        },
        "description": "A single fetch error.",
        "additionalProperties": false
      },
      "description": "Studies that could not be fetched."
    },
    "deferredNctIds": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Requested NCT IDs past the per-call cap of 20 distinct IDs, normalized and deduplicated, in first-occurrence order. Not fetched — pass them as nctIds in a follow-up call. Absent when every requested ID was processed."
    },
    "studiesWithoutResults": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "NCT IDs that do not have results data."
    }
  },
  "additionalProperties": false
}
clinicaltrials_get_study_results annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true
}
clinicaltrials_find_eligible — Clinicaltrials Find Eligible
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Find candidate clinical trials for a patient profile. Provide age, sex, conditions, and location to get studies with their demographic limits, contact information, and recruiting locations. Candidates are matched on age, sex, location, recruitment status, and ClinicalTrials.gov's fuzzy condition search only — inclusion/exclusion criteria are not checked, and a candidate can exclude the requested condition, so review each one's criteria with clinicaltrials_get_study_record before treating it as a match. Results are re-ranked so studies whose own condition matches a requested condition surface above tangential matches from ClinicalTrials.gov's fuzzy condition search. Each candidate returns only the sites matching the requested location (capped by locationLimit), not the study's full registered site list — a large trial can register hundreds of sites worldwide. When none of a candidate's matched sites is recruiting, one recruiting site is added so an enrollable site is never hidden behind a closer closed one: the one nearest the matched sites by their published coordinates, in the requested country whenever a site there recruits, carrying distanceMi, or the first in match order when coordinates are missing. Fetch a study's complete record with clinicaltrials_get_study_record.

clinicaltrials_find_eligible input schema
{
  "type": "object",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "required": [
    "age",
    "sex",
    "conditions",
    "location"
  ],
  "properties": {
    "age": {
      "type": "integer",
      "maximum": 120,
      "minimum": 0,
      "description": "Patient age as a whole number in ageUnit (years unless ageUnit says otherwise)."
    },
    "sex": {
      "enum": [
        "FEMALE",
        "MALE",
        "ALL"
      ],
      "type": "string",
      "description": "Patient's biological sex. Use 'ALL' to include studies regardless of sex restrictions."
    },
    "ageUnit": {
      "enum": [
        "years",
        "months",
        "weeks",
        "days"
      ],
      "type": "string",
      "description": "Unit age is given in: years (default), months, weeks, or days; case and singular forms are accepted. Use a smaller unit for an infant or young child whose eligibility window is narrower than a year — age 7 with ageUnit \"months\" matches a study registered for 6 Months to 8 Months, which no whole number of years reaches. ClinicalTrials.gov compares ages across units, so the unit only sets how precisely age is stated."
    },
    "location": {
      "type": "object",
      "required": [
        "country"
      ],
      "properties": {
        "city": {
          "type": "string",
          "description": "City name."
        },
        "state": {
          "type": "string",
          "description": "State or province, compared with the state the site files. A US state or DC abbreviation (WA, DC) is compared as its full name when the country is the United States or a synonym for it. With city also given, a site that files no state still matches; without city, only sites filing this state match."
        },
        "country": {
          "type": "string",
          "description": "Country name, e.g. \"United States\". Common synonyms rank sites as the registry spelling does: USA and US as United States, UK and England as United Kingdom, Czech Republic as Czechia, Republic of Korea as South Korea, and PR, GU, VI, AS, and MP as the US territories, which the registry files as countries."
        }
      },
      "description": "Patient location as `{ country (required), state?, city? }`. Country is required; state/city narrow the match. Every part given must hold for the same study site: country and state are compared with the site's filed country and state, while city is matched against the site's whole location text, so a site filed under a borough or neighbouring town that names the city still counts. For radius-based geographic search, use clinicaltrials_search_studies with geoFilter.",
      "additionalProperties": false
    },
    "conditions": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Medical conditions or diagnoses, e.g. [\"Type 2 Diabetes\", \"Hypertension\"]. Each entry is matched as a condition: an entry containing whitespace is quoted and matches as a phrase, and any other entry is sent as written, punctuation included (double quotes are stripped from every entry); multiple entries are combined with OR, so studies for any listed condition qualify. Returned studies are re-ranked so those whose own condition list names a requested condition rank above tangential matches the upstream fuzzy search pulls in via the MeSH umbrella."
    },
    "maxResults": {
      "type": "integer",
      "default": 10,
      "maximum": 1000,
      "minimum": 1,
      "description": "Maximum candidates to return, 1–1000. Each call returns at most 50; a larger value returns 50, reported in truncated/shown/cap when more studies match, and the searchCriteria replay through clinicaltrials_search_studies pages the rest."
    },
    "locationLimit": {
      "type": "integer",
      "default": 10,
      "maximum": 9007199254740991,
      "minimum": 1,
      "description": "Cap on the sites returned per candidate. Each candidate keeps only the sites matching the requested location at the narrowest level that matched (city, else state, else country), capped at this many; the rest of the study's registered sites are omitted. The cap governs those matched sites — when none of them is recruiting, one recruiting site is added on top of it (the nearest to any matched site, measured before this cap, when coordinates allow — in the requested country whenever a site there recruits), so a candidate can carry one site more than this. Raise it to see more nearby sites — there is no upper bound, and a limit past the matched sites returns all of them — or fetch the complete site list with clinicaltrials_get_study_record. Each candidate reports totalLocations / matchedLocations / locationsTruncated / nearestRecruitingSiteAdded in locationSummary only when the bound actually dropped sites."
    },
    "recruitingOnly": {
      "type": "boolean",
      "default": true,
      "description": "Only include actively recruiting studies."
    },
    "healthyVolunteer": {
      "type": "boolean",
      "default": false,
      "description": "Whether the patient is a healthy volunteer. When true, only studies accepting healthy volunteers are queried."
    }
  },
  "additionalProperties": false
}
clinicaltrials_find_eligible output schema
{
  "type": "object",
  "anyOf": [
    {
      "not": {
        "required": [
          "error"
        ]
      },
      "required": [
        "studies",
        "searchCriteria",
        "funnel"
      ]
    },
    {
      "required": [
        "error"
      ]
    }
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "cap": {
      "type": "integer",
      "maximum": 9007199254740991,
      "description": "The tool's per-call cap, served in place of the requested maxResults when truncated is true.",
      "exclusiveMinimum": 0
    },
    "error": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "integer",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "description": "JSON-RPC error code for this failure."
        },
        "data": {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string",
              "examples": [
                "blank_value",
                "field_invalid",
                "query_parse_error",
                "request_too_long",
                "rate_limited"
              ],
              "description": "Machine-readable failure mode. Declared by this tool: `blank_value`: A conditions entry or location.country was supplied blank — empty, whitespace-only, or made only of `\"` characters, invisible format characters such as zero-width spaces, and whitespace, since `\"` is stripped before the query is built — or conditions was an empty list. `field_invalid`: A conditions entry carries an AREA[] expression naming a field ClinicalTrials.gov does not recognize or cannot search by value. `query_parse_error`: A conditions entry uses syntax the upstream Essie parser rejects — typically an unmatched `(` or `)`, or a `[` or `]` outside an AREA[…] expression. `request_too_long`: The conditions list or location makes the request URL longer than ClinicalTrials.gov accepts — several hundred conditions in one call. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler."
            },
            "recovery": {
              "type": "object",
              "required": [
                "hint"
              ],
              "properties": {
                "hint": {
                  "type": "string"
                }
              },
              "description": "Actionable next step for the caller.",
              "additionalProperties": {}
            },
            "retryable": {
              "type": "boolean",
              "description": "Whether retrying may succeed."
            }
          },
          "additionalProperties": {}
        },
        "message": {
          "type": "string",
          "description": "Human-readable description of what went wrong."
        }
      },
      "description": "Present when the call failed. Absent on success.",
      "additionalProperties": {}
    },
    "shown": {
      "type": "integer",
      "maximum": 9007199254740991,
      "minimum": 0,
      "description": "Candidates returned when truncated is true."
    },
    "funnel": {
      "type": "object",
      "required": [
        "conditionMatched",
        "locationMatched",
        "demographicsMatched"
      ],
      "properties": {
        "locationMatched": {
          "type": "number",
          "description": "Studies matching condition + location — diagnoses geographic narrowing."
        },
        "conditionMatched": {
          "type": "number",
          "description": "Studies matching the condition query alone (broadest stage)."
        },
        "demographicsMatched": {
          "type": "number",
          "description": "Studies matching the full filter set (condition + location + age/sex + status). Equal to totalCount."
        }
      },
      "description": "Match counts at each filter stage. Shows where the funnel collapsed — e.g., conditionMatched=298 but demographicsMatched=2 means age/sex/status are the constraint.",
      "additionalProperties": false
    },
    "notice": {
      "type": "string",
      "description": "When no studies matched, recovery guidance that identifies which filter stage collapsed and suggests how to broaden. When studies are returned, one caveat for the whole response: candidates were matched on demographics, location, recruitment status, and a fuzzy condition search, not on inclusion/exclusion criteria. When maxResults was above the tool's per-call cap and more studies match, a sentence follows stating the requested, served, and total counts and pointing at the searchCriteria replay."
    },
    "studies": {
      "type": "array",
      "items": {
        "type": "object",
        "propertyNames": {
          "type": "string"
        },
        "additionalProperties": {}
      },
      "description": "Candidate studies with their demographic limits (age, sex, healthy volunteers), contacts, and location fields — matched on age, sex, location, recruitment status, and the fuzzy condition search; inclusion/exclusion criteria are not checked and are not in these records, so review each candidate with clinicaltrials_get_study_record. Each candidate's protocolSection.contactsLocationsModule.locations is BOUNDED to the sites matching the requested location (capped at locationLimit) plus, when none of those is recruiting, one added recruiting site — not the study's full registered site list. The added site is the one nearest any matched site by published coordinates, taken from the requested country whenever a site there recruits, and carries distanceMi (miles to that nearest matched site); when the matched or recruiting sites publish no coordinates it is the first in match order and carries no distanceMi. A candidate whose sites were bounded also carries a top-level locationSummary object — { totalLocations, matchedLocations, locationsTruncated, nearestRecruitingSiteAdded?, retrieveFullStudyWith } — absent when nothing was dropped; nearestRecruitingSiteAdded is present only when that extra site was added (the key keeps its name in the match-order fallback). Fetch a study's complete record and site list with clinicaltrials_get_study_record."
    },
    "truncated": {
      "type": "boolean",
      "description": "True when maxResults was above the tool's per-call cap and more studies match than were returned. Absent otherwise."
    },
    "totalCount": {
      "type": "number",
      "description": "Total matching studies from the API."
    },
    "searchCriteria": {
      "type": "object",
      "required": [
        "conditions",
        "location",
        "age",
        "sex"
      ],
      "properties": {
        "age": {
          "type": "number",
          "description": "Patient age, in ageUnit when present, else in years."
        },
        "sex": {
          "type": "string",
          "description": "Patient sex."
        },
        "ageUnit": {
          "enum": [
            "years",
            "months",
            "weeks",
            "days"
          ],
          "type": "string",
          "description": "The unit age was given in. Present only for months, weeks, or days; absent means years."
        },
        "location": {
          "type": "string",
          "description": "The exact queryLocn string sent upstream: the parts AND-joined inside SEARCH[Location](…) so every part must match the same site. The city is a search term, quoted unless it is a single run of letters and digits (Toronto stays bare; \"Winston-Salem\" and \"L'Aquila\" are quoted); the state is AREA[LocationState]\"…\", ORed with AREA[LocationState]MISSING when a city is given; the country is AREA[LocationCountry]\"…\", ORed with the same spelling without diacritics when it carries any (México also tries Mexico). Any embedded double quote is stripped and any backslash in a quoted value doubled. Pass as locationQuery to clinicaltrials_search_studies to reproduce the location filter beyond the maxResults cap."
        },
        "conditions": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Conditions searched."
        },
        "statusFilter": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "The status filter applied ([\"RECRUITING\"] when recruitingOnly). Pass as statusFilter to clinicaltrials_search_studies. Absent when recruitingOnly is false."
        },
        "advancedFilter": {
          "type": "string",
          "description": "The exact AREA[] advancedFilter (age range, plus sex/healthy-volunteer when constrained) sent upstream. Pass as advancedFilter to clinicaltrials_search_studies to reproduce the demographic constraints."
        },
        "conditionQuery": {
          "type": "string",
          "description": "The exact queryCond string sent upstream (multi-word terms quoted, OR-joined). Pass as conditionQuery to clinicaltrials_search_studies to reproduce the full match set beyond the maxResults cap."
        }
      },
      "description": "Normalized search criteria applied to this eligibility query, including the exact upstream query strings needed to reproduce the full match set via clinicaltrials_search_studies (replay with includeUnknownEnrollment=true, which find_eligible always sets).",
      "additionalProperties": false
    }
  },
  "additionalProperties": false
}
clinicaltrials_find_eligible annotations
{
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true
}

Prompts

1 advertised

analyze_trial_landscape

Advertised by the server during the last successful anonymous check.

Guides analysis of a clinical trial landscape using the ClinicalTrials.gov MCP tools. Adaptable workflow for breakdowns by status, phase, sponsor, geography, etc.

topic
Disease, condition, or research area to analyze. (required)
focusAreas
Comma-separated aspects to focus on, e.g.: "status, phases, sponsors, geography, timeline, interventions".

Resources

1 advertised

clinicaltrialsgov-guide

Advertised by the server during the last successful anonymous check.

Gates and query syntax for the clinicaltrials_* tools over ClinicalTrials.gov. Covers study versus site recruiting status, SEARCH[Location], RANGE and MISSING in advancedFilter, overlapping phase counts, partial dates, the status vocabulary, and reading posted results (group IDs, the adverse-event threshold, results published elsewhere). Use when finding trials near a place, counting or trending trials, building an advancedFilter, or interpreting a trial's results.

clinicaltrialsgov-guide URI
skill://clinicaltrialsgov-guide/SKILL.md

MIME type: text/markdown

Clinical Trial Study — Clinical Trial Study

Advertised by the server during the last successful anonymous check.

Fetch a single clinical study by NCT ID as JSON. The protocol record comes back whole apart from three capped lists (locations, secondary/other outcomes, references — 50 each), and the results data, which reaches ~600KB on a large trial, is replaced by its counts. Anything omitted is reported in truncated, filtersApplied, and resultsSummary, with the tool that retrieves it named in retrieval.

Clinical Trial Study URI template
clinicaltrials://{nctId}

MIME type: application/json

io.modelcontextprotocol/skills

Advertised by the server during the last successful anonymous check.

io.modelcontextprotocol/skills URI template
skill://{+path}

90-day uptime

A lightweight connection check about every six hours, sampled on hosts with many listings. It shows the server answered, not that its tools work.

Too few checks for a percentage yet (1 of 1 answered).

  1. 2026-11-07: 1 of 1 checks answered

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
578 ms
95th percentile latency
578 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 578 ms · metadata changed · 7 tool(s), 1 resource(s), 2 resource template(s), 1 prompt(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http clinicaltrialsgov-mcp-server-caseyjhand https://clinicaltrials.caseyjhand.com/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add clinicaltrialsgov-mcp-server-caseyjhand --url https://clinicaltrials.caseyjhand.com/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable clinicaltrialsgov-mcp-server-caseyjhand in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "clinicaltrialsgov-mcp-server-caseyjhand": {
      "url": "https://clinicaltrials.caseyjhand.com/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "clinicaltrialsgov-mcp-server-caseyjhand": {
      "type": "streamableHttp",
      "url": "https://clinicaltrials.caseyjhand.com/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start clinicaltrialsgov-mcp-server-caseyjhand and inspect its tools.
VS Code configuration
{
  "servers": {
    "clinicaltrialsgov-mcp-server-caseyjhand": {
      "type": "http",
      "url": "https://clinicaltrials.caseyjhand.com/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http clinicaltrialsgov-mcp-server-caseyjhand https://clinicaltrials.caseyjhand.com/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://clinicaltrials.caseyjhand.com/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "clinicaltrialsgov-mcp-server-caseyjhand": {
      "serverUrl": "https://clinicaltrials.caseyjhand.com/mcp"
    }
  }
}

Let your agent find its tools

Find servers like clinicaltrialsgov-mcp-server from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.