clinicaltrialsgov-mcp-server
This server is an MCP interface to ClinicalTrials.gov for searching, retrieving, analyzing, and matching clinical trial data.
Search trials with
clinicaltrials_search_studies: full-text/field-specific queries, status/phase/geographic/advanced filters, pagination, sorting, compact or full-field results.Fetch study records with
clinicaltrials_get_study_record: full protocol by NCT ID, with optional location/outcome/reference caps and proximity-based location filtering.Get study counts quickly via
clinicaltrials_get_study_countfor statistics and breakdowns.Discover field values with
clinicaltrials_get_field_values: valid values, counts, min/max/avg, booleans, and multi-valued flags.Resolve field names via
clinicaltrials_get_field_definitions: keyword search, section drill-down, or top-level overview.Retrieve posted results with
clinicaltrials_get_study_results: outcomes, adverse events, participant flow, baseline, and metadata; summary/full modes with pagination and caps.Match patients to eligible trials with
clinicaltrials_find_eligible: age, sex, conditions, location, healthy-volunteer status, recruiting-only filtering, plus a filter-funnel breakdown.Use the built-in resource
clinicaltrials://{nctId}for a capped JSON study record.Use the
analyze_trial_landscapeprompt for guided data-driven landscape analysis.Deploy or connect via stdio or Streamable HTTP, self-hosted or through the public hosted endpoint, with no authentication required.
Provides the project repository on GitHub for access to source code and documentation.
Uses Hono as a high-performance HTTP server featuring session management, CORS, and IP-based rate limiting.
Supports returning clinical trial data in markdown format for improved readability in AI responses.
Requires Node.js (>=18.0.0) as the runtime environment for the MCP server.
Distributes the server via npm package management system, allowing for easy installation.
Uses Prettier for consistent code formatting during development.
Built with TypeScript for type safety and robust error handling when interacting with the ClinicalTrials.gov database.
Implements input validation and sanitization using Zod schema validation for secure API interactions.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@clinicaltrialsgov-mcp-serverfind Phase 3 diabetes studies currently recruiting"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Public Hosted Server: https://clinicaltrials.caseyjhand.com/mcp
Overview
Clinical trial data from the ClinicalTrials.gov REST API v2 — the US National Library of Medicine's registry of ~577K clinical trial studies. Search trials, fetch full study records and posted results, discover field names and valid values, and match patient demographics to eligible recruiting trials. Public, read-only, no authentication required. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
Tools
Tool | Description |
| Search studies with full-text and field-specific queries, status/phase/geographic filters, pagination, sorting, and field selection |
| Fetch a single study by NCT ID — full protocol record with optional location/outcome/reference caps |
| Fast total study count for a query, without fetching data |
| Discover valid values for API fields, with per-value study counts |
| Resolve valid field names — keyword search, path drill-down, or top-level overview |
| Fetch posted results — outcomes, adverse events, participant flow, baseline — for completed studies |
| Match patient demographics and conditions to eligible recruiting trials |
Resources
Resource | Description |
| Fetch a single clinical study by NCT ID as JSON, with capped lists and results replaced by counts |
Prompts
Prompt | Description |
| Guides a data-driven clinical trial landscape analysis using the count and search tools |
Related MCP server: ClinicalTrials.gov MCP Server
Capability reference
clinicaltrials_search_studies tool
Free-text
queryplus field-specificconditionQuery/interventionQuery/locationQuery/sponsorQuery/titleQuery/outcomeQuery;statusFilter/phaseFilterenums,advancedFilter(AREA[FieldName]value/RANGE[min, max]syntax), andgeoFilter(distance(lat,lon,radius)with ami/kmsuffix) for proximity search with nearest-site re-rankingReturns a compact per-study index by default (
nctId,briefTitle,overallStatus,phases,enrollmentCount,leadSponsor,conditions, a bounded locations summary); passfields(PascalCase leaves) for a full-fidelity projection — full records run ~70KBpageSize1–CT_MAX_PAGE_SIZE(default 200), cursor pagination viapageToken,sorton up to 2 fieldsExcludes the upstream "unknown" enrollment sentinel (
99999999) by default —includeUnknownEnrollmentto include it, or automatically lifted whennctIdsis suppliedTyped errors:
blank_value,ids_not_found,field_invalid,enum_invalid,query_parse_error,geo_invalid,sort_invalid,rate_limited
clinicaltrials_get_study_record tool
Full protocol record by NCT ID — identification, status, sponsor, conditions, design, arms/interventions, outcomes, eligibility, contacts/locations
Optional
locationLimit(≤500),outcomeLimit/referenceLimit(≤100), andnearLocation(lat,lon,radiusMidefault 50) to bound and sort locations; upstream totals reported infiltersAppliedonly when a cap actually trims the listresultsSectionis replaced by compactresultsSummarycounts — fetch full results viaclinicaltrials_get_study_resultsTyped errors:
study_not_found,rate_limited
clinicaltrials_get_study_count tool
Same query/filter surface as
clinicaltrials_search_studies(free-text and field-specific queries, status/phase filters,advancedFilter) but returns onlytotalCount— no study data fetchedExcludes the unknown-enrollment sentinel by default (
includeUnknownEnrollmentto include it)Typed errors:
blank_value,field_invalid,enum_invalid,query_parse_error,rate_limited
clinicaltrials_get_field_values tool
One or more PascalCase field names (e.g.
OverallStatus,Phase,LeadSponsorClass) — returns each field's type, unique-value count, and top values with study counts (capped at 250 by the API)Numeric/date fields report
min/max/avg/formatsinstead of top values; boolean fields reporttrueCount/falseCountmultiValuedflags fields where a study can carry several values, so per-value study counts can sum above the study totalTyped errors:
blank_value,field_invalid,rate_limited
clinicaltrials_get_field_definitions tool
Three modes:
search(keyword, ranked matches,limitup to 100, default 20),drill(dot-notationpathinto a section),overview(top-level sections, no other args)Resolves the canonical PascalCase field names accepted by
fields,advancedFilter,sort, andclinicaltrials_get_field_valuesTyped errors:
blank_value,mode_mismatch,mode_requires,path_not_found,rate_limited
clinicaltrials_get_study_results tool
Up to 20 NCT IDs per call; only returns data for studies where
hasResultsis true — outcome measures, adverse events, participant flow, baseline characteristics, and results metadatasummary(default false) condenses a full result set — which can exceed 500KB per study — to a few KB; full mode supportsoutcomeLimit(≤100) andadverseEventLimit(≤500), resumable viaoutcomeOffset/seriousEventOffset/otherEventOffsetsectionsfilters tooutcomes,adverseEvents,participantFlow,baseline,moreInfoA previous (alias) NCT ID resolves to its canonical study, named in
canonicalNctIdTyped errors:
blank_value,offset_not_applicable,rate_limited
clinicaltrials_find_eligible tool
Takes
age,sex(FEMALE/MALE/ALL),conditions[],location(countryrequired,state/cityoptional),healthyVolunteer,recruitingOnly(default true),maxResults(≤50)Re-ranks results so studies whose own condition list names a requested condition surface above tangential MeSH-umbrella matches from the upstream fuzzy search
Bounds each candidate's locations to the sites matching the requested location (capped by
locationLimit, ≤500) instead of every registered site, adding the nearest recruiting site when none of the matched ones is openfunnelreports match counts at each filter stage (condition → +location → +demographics) to show where the query narrowed to zeroTyped errors:
blank_value,rate_limited
clinicaltrials://{nctId} resource
Full protocol record as
application/json, with locations, secondary/other outcomes, and references each capped at 50 — fixed server-side, no argumentsResults data is replaced by
resultsSummarycounts;truncatedandfiltersApplieddisclose what was capped, withretrievalnaming the tools that fetch the full dataTyped errors:
study_not_found,rate_limited
analyze_trial_landscape prompt
Arguments:
topicrequired;focusAreas(comma-separated) optionalReturns one user message pointing the agent at the count, search, field-discovery, and results tools for a data-driven landscape analysis
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
ClinicalTrials.gov-specific:
Type-safe client for the ClinicalTrials.gov REST API v2 — public, no authentication or API keys required
Serialized request queue enforcing ClinicalTrials.gov's ~1 req/sec rate limit, with retry and exponential backoff on 429/5xx responses
Auto-corrects field names passed to
fields/sort— case/whitespace fixes and known legacy aliases (e.g.RecruitmentStatus→OverallStatus) — before validating, logging every correctionDetects upstream HTML error pages returned with a JSON content-type and retries rather than parsing them as data
Geographic proximity search and nearest-site re-ranking, with no geocoding dependency
Agent-friendly output:
Provenance —
clinicaltrials_search_studies/clinicaltrials_get_study_count/clinicaltrials_find_eligibleechosearchCriteriaon every call, includingsentinelFilterActivewhen the default unknown-enrollment exclusion applies, andclinicaltrials_get_study_resultsnamescanonicalNctIdwhen a previous (alias) ID resolves to a different studyGraceful partial failure —
clinicaltrials_get_study_resultsreturns per-studyfetchErrors/studiesWithoutResultsrows instead of failing the whole batch when one ID is malformed or lacks resultsDiscriminated output — typed error
reasoncodes per tool (study_not_found,blank_value,offset_not_applicable, …), and bounded lists (filtersApplied,locationSummary) carry anext*Offsetonly when more remains, so callers branch on presence instead of parsing textResponse shaping —
clinicaltrials_search_studiesandclinicaltrials_find_eligiblereturn a compact per-study index or location-bounded set by default instead of the ~70KB full record, escalating to full fidelity only viafieldsorclinicaltrials_get_study_record
Getting started
Public Hosted Instance
A public instance is available at https://clinicaltrials.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"clinicaltrialsgov-mcp-server": {
"type": "streamable-http",
"url": "https://clinicaltrials.caseyjhand.com/mcp"
}
}
}Self-Hosted / Local
Add the following to your MCP client configuration file.
{
"mcpServers": {
"clinicaltrialsgov-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["clinicaltrialsgov-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"clinicaltrialsgov-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "clinicaltrialsgov-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with Docker:
{
"mcpServers": {
"clinicaltrialsgov-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/clinicaltrialsgov-mcp-server:latest"]
}
}
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Bun v1.4.0 or higher (or Node.js v24+).
Installation
Clone the repository:
git clone https://github.com/cyanheads/clinicaltrialsgov-mcp-server.gitNavigate into the directory:
cd clinicaltrialsgov-mcp-serverInstall dependencies:
bun installConfiguration
All configuration is optional — the server works with defaults and no API keys.
Variable | Description | Default |
| ClinicalTrials.gov API base URL. |
|
| Per-request timeout in milliseconds. |
|
| Maximum page size cap. |
|
| Transport: |
|
| Port for HTTP server. |
|
| Auth mode: |
|
| Log level (RFC 5424). |
|
| Directory for log files (Node.js only). |
|
| Enable OpenTelemetry tracing. |
|
See .env.example for the full list of optional overrides.
Running the server
Local development
Build and run:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdioRun checks and tests:
bun run devcheck # Lint, format, typecheck, and security audit bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t clinicaltrialsgov-mcp-server .
docker run --rm -p 3010:3010 clinicaltrialsgov-mcp-serverThe Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/clinicaltrialsgov-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
Directory | Purpose |
|
|
| Server-specific environment variable parsing and validation with Zod. |
| Tool definitions ( |
| Resource definitions ( |
| Prompt definitions ( |
| ClinicalTrials.gov REST API v2 client — retry, rate limiting, field search, types. |
| Unit and integration tests. |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor request-scoped logging, noconsolecallsRegister new tools and resources via the barrels in
src/mcp-server/*/definitions/index.tsValidate raw API responses, normalize to domain types, and never fabricate missing fields
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
Available Tools
7 toolsclinicaltrials_find_eligibleClinicaltrials Find EligibleARead-onlyIdempotentInspect
Match patient demographics and conditions to eligible recruiting clinical trials. Provide age, sex, conditions, and location to find studies with matching eligibility criteria, contact information, and recruiting locations. 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, its nearest recruiting site is added, so an enrollable site is never hidden behind a closer closed one. Fetch a study's complete record with clinicaltrials_get_study_record.
| Name | Required | Description | Default |
|---|---|---|---|
| age | Yes | Patient age in years. | |
| sex | Yes | Patient's biological sex. Use 'ALL' to include studies regardless of sex restrictions. | |
| location | Yes | Patient location as `{ country (required), state?, city? }`. Country is required; state/city narrow the match. For radius-based geographic search, use clinicaltrials_search_studies with geoFilter. | |
| conditions | Yes | Medical conditions or diagnoses, e.g. ["Type 2 Diabetes", "Hypertension"]. Each entry is matched as a condition (multi-word entries match as a phrase); 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 | No | Maximum results to return. | |
| locationLimit | No | 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, the candidate's nearest recruiting site is added on top of it, so a candidate can carry one site more than this. Raise it to see more nearby sites, 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 | No | Only include actively recruiting studies. | |
| healthyVolunteer | No | Whether the patient is a healthy volunteer. When true, only studies accepting healthy volunteers are queried. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| funnel | No | 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. |
| notice | No | Recovery guidance when no studies matched — identifies which filter stage collapsed and suggests how to broaden. Absent when results are returned. |
| studies | No | Matching studies with eligibility and location fields. 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, the candidate's nearest recruiting site — not the study's full registered site list. 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. Fetch a study's complete record and site list with clinicaltrials_get_study_record. |
| totalCount | No | Total matching studies from the API. |
| searchCriteria | No | 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). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the read-only, open-world, idempotent annotations, the description explains re-ranking of matching conditions, per-candidate site filtering capped by locationLimit, omission of non-matching registered sites, fallback inclusion of a nearest recruiting site, and conditional locationSummary fields. These details give the agent rich behavioral context not available in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then proceeds through matching, ranking, site filtering, fallback behavior, and an alternative tool. Despite its length, every sentence addresses behavior an agent needs for this complex, multi-parameter eligibility matching tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the 8-parameter schema, nested location object, annotations, and output schema, the description is complete. It covers purpose, input expectations, ranking, site truncation, fallback recruiting-site behavior, and when to fetch complete records elsewhere, leaving no critical gap for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces some parameter semantics such as condition matching and locationLimit truncation behavior, but these are already fully documented in the schema, so it does not add significantly more meaning beyond the structured fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource: matching patient demographics and conditions to eligible recruiting clinical trials. It distinguishes the tool from siblings by naming clinicaltrials_get_study_record for full records and clinicaltrials_search_studies with geoFilter for radius searches.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly says to provide age, sex, conditions, and location to find matching studies, and it routes to alternatives for complete records and radius-based geographic search. However, it does not explicitly state when this tool should be preferred over a general condition search or when patient demographics are insufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clinicaltrials_get_field_definitionsClinicaltrials Get Field DefinitionsARead-onlyIdempotentInspect
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).
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | 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 | No | drill mode only. Dot-notation path to drill into — e.g., "protocolSection.designModule", "protocolSection.eligibilityModule", "resultsSection". Returns the section's individual fields. | |
| limit | No | search mode only. Maximum results to return. Default: 20. | |
| query | No | 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 | No | drill mode only. Only return indexed (searchable) fields. Default: false. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The limit cap applied to this search (search mode only). |
| error | No | Present when the call failed. Absent on success. |
| shown | No | Number of fields returned (search mode only). |
| fields | No | Field definitions, ordered by relevance when mode is "search". |
| notice | No | Recovery guidance when search mode returns no matches, or a truncation note when results are capped. |
| truncated | No | True when the field list was capped by the limit parameter (search mode only). |
| searchQuery | No | Echo of the keyword used in search mode. Absent for drill and overview. |
| totalFields | No | Total fields returned. |
| resolvedPath | No | Resolved path when mode is "drill". |
| totalMatches | No | 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the safety profile is covered. The description adds behavioral value by describing what each mode returns — ranked matches, drilled section fields, top-level section summary — and by noting argument preconditions per mode. Minor gap: no pagination or truncation caveat for `limit`.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose before mode mechanics, and every sentence carries information — examples, downstream consumers, mode preconditions. Dense paragraph rather than scannable mode list, which costs a point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained, and the description still covers the ambiguity that matters (which mode to use, what each requires). An agent has everything needed to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (mode, path, query, limit, includeIndexedOnly) is already documented in the schema, including the same query and path examples. The description restates the mode-to-arg mapping without adding syntax or format detail beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (resolve) and resource (valid field names from the ClinicalTrials.gov data model) and pins down the exact artifact returned — canonical PascalCase identifiers like OverallStatus and EnrollmentCount. It also names where those identifiers matter (the `fields`, `advancedFilter`, and `sort` parameters of other tools), which cleanly separates it from the search/record siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit routing for each mode: use `search` for keyword lookup with a query example, `drill` for section traversal with a path example, and `overview` when no additional args are needed. It further identifies downstream consumers (clinicaltrials_get_field_values) and the sibling parameters that accept the resolved names, so an agent knows both when and why to call it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clinicaltrials_get_field_valuesClinicaltrials Get Field ValuesARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| fields | Yes | PascalCase field name(s) to get value statistics for — an empty list is rejected, not treated as "every field". Examples: OverallStatus, Phase, StudyType, Sex, LeadSponsorClass. Use clinicaltrials_get_field_definitions with a query to find more field names. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| fieldStats | No | 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, covering the safety profile. The description adds one behavioral detail beyond that — results are aggregated with per-value study counts — but says nothing about result size, pagination, or whether values are exhaustive for a field.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences: purpose first, then the action-oriented usage note with inline examples. No filler and the most important framing (explore before searching) is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description needn't explain return values, and it correctly focuses on purpose and usage. It is complete enough to invoke correctly; only cross-tool routing to the field-definitions sibling is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents the single 'fields' parameter, including PascalCase format, examples, and the empty-list rejection. The description's example field list (OverallStatus, Phase, etc.) duplicates the schema's own examples, adding no new meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Discover valid values for ClinicalTrials.gov fields') and even discloses the return payload ('study counts per value'). It distinguishes itself contextually by framing usage 'before building a search', but never names the sibling tools (e.g. clinicaltrials_get_field_definitions or clinicaltrials_search_studies) to sharpen the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear situational guidance: 'Use to explore available filter options before building a search.' That tells the agent when to reach for it, but it offers no exclusion conditions and does not name the alternative tool (clinicaltrials_get_field_definitions) that also deals with field names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clinicaltrials_get_study_countClinicaltrials Get Study CountARead-onlyIdempotentInspect
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).
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | 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 | No | 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 | No | 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. | |
| outcomeQuery | No | 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 | No | 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 | No | 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 | No | 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 | No | 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. | |
| conditionQuery | No | 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 | No | 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 | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Recovery guidance when totalCount is 0 — suggests how to broaden the query or filters. |
| totalCount | No | Total studies matching the query/filters. |
| searchCriteria | No | Echo of active query/filter criteria applied to this count, including sentinelFilterActive when the default unknown-enrollment exclusion is in effect. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, and idempotentHint. The description adds behavioral value by noting it is 'Fast and lightweight' and 'without fetching study data,' and by suggesting repeated calls with different filters, which reinforces safe, side-effect-free usage. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler. The core purpose is front-loaded, followed by concrete use cases. Every sentence earns its place, and the description is appropriately sized for the tool's simplicity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (11 optional parameters), the rich schema descriptions, and the presence of an output schema, the description is largely complete. It covers the main use cases and distinguishes the tool from siblings. It does not explicitly mention that calling with no filters returns the overall total, but the schema's optional parameters and the phrase 'matching a query' make that inferable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 11 parameters in detail. The description adds only high-level examples of filters ('phase, status, condition') that map to existing parameters, but no new semantic meaning beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Get total clinical trial study count from ClinicalTrials.gov matching a query.' It also distinguishes itself from sibling tools by explicitly saying 'without fetching study data,' which separates it from search/record tools. The use-case framing ('quick statistics', 'breakdowns') further clarifies its unique role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use it: 'Use for quick statistics or to build breakdowns by calling multiple times with different filters.' It implies the alternative (fetching study data) is not this tool's purpose, but it does not explicitly name sibling tools or state when not to use it. This is clear guidance with no exclusions, but not fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clinicaltrials_get_study_recordClinicaltrials Get Study RecordARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| nctId | Yes | NCT identifier — format `NCT` followed by 8 digits (e.g., `NCT03722472`). | |
| nearLocation | No | 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. | |
| outcomeLimit | No | Optional cap on the number of secondary and other outcomes returned. Omit for no cap (full upstream lists). Primary outcomes are never capped. Original totals preserved in filtersApplied.totalSecondaryOutcomes / totalOtherOutcomes only when the cap trims a list. | |
| locationLimit | No | Optional cap on the number of locations returned. Omit for no cap (full upstream list). 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 | No | Optional cap on the number of references returned. Omit for no cap (full upstream list). Original total preserved in filtersApplied.totalReferences only when the cap trims the list. seeAlsoLinks are never capped. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| study | No | 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. |
| filtersApplied | No | Metadata about the filtering applied to `study`. |
| resultsSummary | No | 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 or the clinicaltrials://{nctId} resource. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds meaningfully beyond the readOnly/openWorld/idempotent annotations: explains that caps preserve original totals in filtersApplied only when a list is actually trimmed, that primary outcomes and seeAlsoLinks are never capped, and that nearLocation geocoding is city-centroid and drops locations without coordinates. This is exactly the kind of non-obvious runtime behavior an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two front-loaded sentences with no filler: first states the primary purpose, second captures the one non-obvious behavioral subtlety about caps and filtersApplied. The prose is dense but every clause adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema handles return-value expectations, the param schema thoroughly documents behavior, annotations cover safety and idempotency, and the description adds scope, cap semantics, and geocoding limitations. For an agent deciding whether and how to call this tool, nothing meaningful is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and every parameter already has a thorough description including ranges, defaults, and behavior. The tool description itself adds little beyond a concise summary of the trimming behavior, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Starts with a specific verb and resource: 'Fetch a single clinical trial study by NCT ID'. Unambiguously distinguishes this from sibling tools like the search/count tools, and the 'by NCT ID' identifier makes the invocation target crystal clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes clear this is the tool for fetching one study by NCT ID, and the nearLocation parameter description explicitly points to clinicaltrials_search_studies for broad geographic filtering. However, it does not directly contrast with all relevant siblings such as clinicaltrials_get_study_results, so the routing guidance is good but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clinicaltrials_get_study_resultsClinicaltrials Get Study ResultsARead-onlyIdempotentInspect
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. A results-rich record can exceed 500KB per study in full mode — bound it with summary=true, narrower sections, or the outcomeLimit / adverseEventLimit caps. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| nctIds | Yes | One or more NCT IDs (max 20) — an empty list is rejected, and a repeated ID collapses to one results entry in first-occurrence order. E.g., "NCT12345678" or ["NCT12345678", "NCT87654321"]. Use summary=true for large batches to avoid large payloads. | |
| summary | No | 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 counts, per-group denominators, one statistical analysis, and a top-line projection of a single class/category cell — labelled with the class and category titles it came from and a count of the siblings it omits. The measurements outside that cell and the remaining analyses are dropped; re-run with summary=false to reach them. For a middle ground, keep full mode and cap the two lists that carry the bulk with outcomeLimit / adverseEventLimit. | |
| sections | No | 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 | No | 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). Applies to full mode only — summary mode is already condensed. Each surviving measure keeps its complete groups/classes/measurements/analyses tree. Upstream total preserved in filtersApplied.totalOutcomes only when the cap trims the list. | |
| outcomeOffset | No | 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. Rejected with summary: true or when sections excludes outcomes. | |
| otherEventOffset | No | 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 | No | 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). Applies to full mode only — summary mode already ranks the top 20 by participants affected. Event groups are never capped. Upstream totals preserved in filtersApplied.totalSeriousEvents / totalOtherEvents only when the cap trims a list. | |
| seriousEventOffset | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| results | No | Results per study. |
| truncated | No | 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 | No | Studies that could not be fetched. |
| studiesWithoutResults | No | NCT IDs that do not have results data. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly/idempotent/openWorld), but the description adds real behavioral context: payload-size risk (>500KB per study), resumability via offsets, filtersApplied reporting of what was trimmed, and alias-to-canonical NCT resolution. Some of this overlaps the parameter descriptions rather than being purely new, so it falls just short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and availability condition are front-loaded, and the remaining sentences each carry distinct operational value (size limits, bounding, pagination, alias handling). It is dense but slightly long, with a few clauses that restate schema-level detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an 8-parameter, multi-section tool with an output schema, the description covers everything an agent needs: the hasResults gate, the discovery prerequisite, size-mitigation options, pagination/resume mechanics, and alias canonicalization. Return-value structure is correctly left to the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema itself is highly detailed on every parameter, including offset/limit pairing. The description reinforces the same points (narrower sections, caps, resume offsets) but adds no semantics not already in the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (fetch) and resource (clinical trial results data) and enumerates the payload contents (outcome measures, adverse events, participant flow, baseline characteristics, results metadata). It implicitly distinguishes itself from clinicaltrials_get_study_record by scoping strictly to results data and the hasResults precondition.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit precondition (only available where hasResults is true) plus a concrete routing instruction: 'Use clinicaltrials_search_studies first to find studies with results.' It also names the bounding alternatives (summary=true, narrower sections, outcomeLimit/adverseEventLimit) which is genuine when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clinicaltrials_search_studiesClinicaltrials Search StudiesARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | 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 | No | 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 | No | 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. 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 | No | Filter to specific NCT IDs for batch lookups. Omit to search every study — an empty list is rejected, not treated as "no filter". Supplying this lifts the default unknown-enrollment exclusion, so an ID you name is never filtered out of its own lookup. | |
| pageSize | No | Results per page, 1–200. | |
| geoFilter | No | 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 | No | Pagination cursor from a previous response. | |
| countTotal | No | Include total study count in response. Only computed on the first page. | |
| titleQuery | No | 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 | No | 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. | |
| outcomeQuery | No | 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 | No | 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 | No | 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 | No | 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 | No | 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. | |
| conditionQuery | No | 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 | No | 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 | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | 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. Absent on pages with results, and on an exhausted continuation page, where the cohort already matched and there is nothing to broaden. |
| studies | No | Matching studies. By default each entry is a COMPACT index projection — nctId, briefTitle, overallStatus, phases, enrollmentCount, leadSponsor, conditions, and a bounded locations summary ({ total, nearest }) — 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. |
| totalCount | No | Total matching studies (first page only when countTotal=true). |
| nextPageToken | No | 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 | No | 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. |
| searchCriteria | No | 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. |
| requestedFields | No | Echo of the explicit fields parameter — 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, openWorld), so the description is not obligated to restate them. It adds genuinely useful behavioral context the annotations do not: the default compact projection, the ~70KB full-record size warning, and the fact that fields unlocks full-fidelity leaves — all of which shape how an agent calls it. It stops short of auth, rate limits, or pagination behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: purpose first, capability scope second, and the high-value return-size caveat last. Front-loaded and free of filler despite the tool's 18-parameter surface.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained in prose, and the 100% schema coverage means parameter semantics are handled elsewhere. The description covers purpose, default projection, and the size trap; the only remaining gap is guidance on when a search is the right call versus the record/count/eligibility siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the parameter descriptions are exceptionally rich (search-field enumerations, syntax rules, sentinel-enrollment handling, unit requirements for geoFilter), so the schema carries the semantic burden. The top-level description only briefly reinforces the fields parameter and adds no parameter meaning beyond what the schema already states — baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource ("Search for clinical trial studies from ClinicalTrials.gov") and enumerates the query/filter capabilities. The mention of returning a "compact per-study index by default" implicitly separates it from clinicaltrials_get_study_record, but no sibling is named, so differentiation is inferential rather than explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by "Search for clinical trial studies" plus the default-return note, which nudges the agent toward the fields parameter. However, there is no explicit when-to-use statement, no exclusion of cases better served by clinicaltrials_get_study_count, clinicaltrials_get_study_record, or clinicaltrials_find_eligible, and no prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v2.9.6- Changed
clinicaltrials_find_eligible1 field changed- changed
Output schema / properties / searchCriteria / properties / location / descriptionPrevious value: -"The exact queryLocn string sent upstream (city/state/country joined). Pass as locationQuery to clinicaltrials_search_studies to reproduce the location filter beyond the maxResults cap."New value: +"The exact queryLocn string sent upstream (city/state/country, multi-word components quoted, AND-joined). Pass as locationQuery to clinicaltrials_search_studies to reproduce the location filter beyond the maxResults cap."
- Changed
clinicaltrials_get_field_definitions2 fields changed- changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `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."New value: +"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." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "path_not_found", - "rate_limited" -]New value: +[ + "blank_value", + "mode_mismatch", + "mode_requires", + "path_not_found", + "rate_limited" +]
- Changed
clinicaltrials_get_field_values7 fields changed- changed
Output schema / properties / fieldStats / descriptionPrevious value: -"One entry per requested field: canonical path, PascalCase piece name, data type, missing/unique counts, and top values with study counts (or trueCount/falseCount for BOOLEAN fields)."New value: +"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." - added
Output schema / properties / fieldStats / items / properties / avgAdded value: +{ + "description": "Mean of the recorded values. Present for INTEGER/NUMBER fields.", + "type": "number" +} - added
Output schema / properties / fieldStats / items / properties / formatsAdded value: +{ + "description": "Date patterns this field is recorded in. Present for DATE fields; more than one means the field mixes precisions across studies.", + "items": { + "description": "A date pattern, e.g. \"yyyy-MM-dd\".", + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / fieldStats / items / properties / longestAdded value: +{ + "additionalProperties": false, + "description": "Longest recorded value with its length and a study carrying it. Present for STRING fields only.", + "properties": { + "length": { + "description": "Its length in characters.", + "type": "number" + }, + "nctId": { + "description": "NCT ID of a study carrying it.", + "type": "string" + }, + "value": { + "description": "The longest recorded value.", + "type": "string" + } + }, + "required": [ + "value", + "length", + "nctId" + ], + "type": "object" +} - added
Output schema / properties / fieldStats / items / properties / maxAdded value: +{ + "anyOf": [ + { + "description": "Largest value of an INTEGER/NUMBER field.", + "type": "number" + }, + { + "description": "Latest value of a DATE field, at the precision recorded.", + "type": "string" + } + ], + "description": "Largest recorded value — a number for INTEGER/NUMBER, a date string for DATE." +} - added
Output schema / properties / fieldStats / items / properties / minAdded value: +{ + "anyOf": [ + { + "description": "Smallest value of an INTEGER/NUMBER field.", + "type": "number" + }, + { + "description": "Earliest value of a DATE field, at the precision recorded — a partial date such as \"1900-01\" stays partial.", + "type": "string" + } + ], + "description": "Smallest recorded value — a number for INTEGER/NUMBER, a date string for DATE." +} - changed
Output schema / properties / fieldStats / items / properties / multiValued / descriptionPrevious value: -"True when the field is array-typed (a study can carry several values, e.g. Phase, Condition), so the per-value studiesCount buckets sum above the study total. Use to avoid computing a percentage against the corpus."New value: +"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."
- Changed
clinicaltrials_get_study_results23 fields changed- changed
Input schema / properties / nctIds / descriptionPrevious value: -"One or more NCT IDs (max 20) — an empty list is rejected. E.g., \"NCT12345678\" or [\"NCT12345678\", \"NCT87654321\"]. Use summary=true for large batches to avoid large payloads."New value: +"One or more NCT IDs (max 20) — an empty list is rejected, and a repeated ID collapses to one results entry in first-occurrence order. E.g., \"NCT12345678\" or [\"NCT12345678\", \"NCT87654321\"]. Use summary=true for large batches to avoid large payloads." - added
Input schema / properties / otherEventOffsetAdded value: +{ + "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.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / outcomeOffsetAdded value: +{ + "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. Rejected with summary: true or when sections excludes outcomes.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / seriousEventOffsetAdded value: +{ + "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.", + "maximum": 9007199254740991, + "minimum": 0, + "type": "integer" +} - changed
Input schema / properties / summary / descriptionPrevious value: -"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 reduces that to ~5KB. Summaries include outcome titles, types, timeframes, group counts, and top-level stats — omitting individual measurements, analyses, and per-group data. For a middle ground, keep full mode and cap the two lists that carry the bulk with outcomeLimit / adverseEventLimit."New value: +"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 counts, per-group denominators, one statistical analysis, and a top-line projection of a single class/category cell — labelled with the class and category titles it came from and a count of the siblings it omits. The measurements outside that cell and the remaining analyses are dropped; re-run with summary=false to reach them. For a middle ground, keep full mode and cap the two lists that carry the bulk with outcomeLimit / adverseEventLimit." - changed
Output schema / properties / error / properties / data / properties / reason / descriptionPrevious value: -"Machine-readable failure mode. Declared by this tool: `blank_value`: A parameter was supplied with a blank, whitespace-only, or empty-list value. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler."New value: +"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 — summary mode returns a condensed projection rather than a bounded window, or the sections filter excludes the offset’s own section. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler." - changed
Output schema / properties / error / properties / data / properties / reason / examplesPrevious value: -[ - "blank_value", - "rate_limited" -]New value: +[ + "blank_value", + "offset_not_applicable", + "rate_limited" +] - added
Output schema / properties / results / items / properties / canonicalNctIdAdded value: +{ + "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.", + "type": "string" +} - changed
Output schema / properties / results / items / properties / filtersApplied / descriptionPrevious value: -"What a cap trimmed on this study — present only when a cap actually reduced a list. Absent means the payload is the complete upstream set for the requested sections."New value: +"What the outcomeLimit / adverseEventLimit caps and the outcomeOffset / seriousEventOffset / otherEventOffset offsets trimmed on this study, plus the next offset for each list left short. 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." - changed
Output schema / properties / results / items / properties / filtersApplied / properties / adverseEventLimit / descriptionPrevious value: -"Echo of the adverseEventLimit input — present only when the cap trimmed a list."New value: +"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." - added
Output schema / properties / results / items / properties / filtersApplied / properties / nextOtherEventOffsetAdded value: +{ + "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.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Output schema / properties / results / items / properties / filtersApplied / properties / nextOutcomeOffsetAdded value: +{ + "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.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Output schema / properties / results / items / properties / filtersApplied / properties / nextSeriousEventOffsetAdded value: +{ + "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.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Output schema / properties / results / items / properties / filtersApplied / properties / otherEventOffsetAdded value: +{ + "description": "Echo of the otherEventOffset input — present only when it skipped events before the window.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - changed
Output schema / properties / results / items / properties / filtersApplied / properties / outcomeLimit / descriptionPrevious value: -"Echo of the outcomeLimit input — present only when the cap trimmed the list."New value: +"Echo of the outcomeLimit input — present only when the cap cut measures off the end of the window." - added
Output schema / properties / results / items / properties / filtersApplied / properties / outcomeOffsetAdded value: +{ + "description": "Echo of the outcomeOffset input — present only when it skipped measures before the window.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Output schema / properties / results / items / properties / filtersApplied / properties / seriousEventOffsetAdded value: +{ + "description": "Echo of the seriousEventOffset input — present only when it skipped events before the window.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - changed
Output schema / properties / results / items / properties / filtersApplied / properties / totalOtherEvents / descriptionPrevious value: -"Upstream other adverse event count before adverseEventLimit trimmed the list."New value: +"Upstream other adverse event count, before the bounds trimmed the list." - changed
Output schema / properties / results / items / properties / filtersApplied / properties / totalOutcomes / descriptionPrevious value: -"Upstream outcome measure count before outcomeLimit trimmed the list."New value: +"Upstream outcome measure count, before the bounds trimmed the list." - changed
Output schema / properties / results / items / properties / filtersApplied / properties / totalSeriousEvents / descriptionPrevious value: -"Upstream serious adverse event count before adverseEventLimit trimmed the list."New value: +"Upstream serious adverse event count, before the bounds trimmed the list." - changed
Output schema / properties / results / items / properties / nctId / descriptionPrevious value: -"NCT identifier."New value: +"The NCT identifier as requested, echoed verbatim. When it is a previous (alias) ID, ClinicalTrials.gov answers with the canonical record and canonicalNctId names it." - changed
Output schema / properties / results / items / properties / outcomes / descriptionPrevious value: -"Outcome measures with per-group statistics. Summary mode (compact): type, title, timeFrame, paramType, unitOfMeasure, group/class counts, plus topStats (per-group measurements) and topAnalysis (statisticalMethod, pValue, paramType/Value, ciPctValue/Lower/Upper, nonInferiorityType, groupIds — lifted from analyses[0]) when present. Full mode (default): adds raw groups, classes, categories, measurements, and analyses arrays."New value: +"Outcome measures with per-group statistics. Summary mode (compact): type, title, timeFrame, paramType, dispersionType, unitOfMeasure, group/class counts, denoms (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, with omittedClasses / omittedCategories counts and a note pointing at summary=false when siblings were dropped), and topAnalysis (statisticalMethod, pValue, paramType/Value, ciPctValue/Lower/Upper, nonInferiorityType, groupIds — lifted from analyses[0]) when present. Full mode (default): adds raw groups, classes, categories, measurements, and analyses arrays." - changed
Output schema / properties / truncated / descriptionPrevious value: -"True when a cap trimmed a list on at least one study; absent when nothing was trimmed, matching filtersApplied one level down. Which study and which list is named in that study’s filtersApplied."New value: +"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."
- Changed
clinicaltrials_search_studies3 fields changed- changed
Input schema / properties / geoFilter / descriptionPrevious value: -"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. Always include the suffix: a bare radius is accepted upstream but interpreted as meters, which silently matches almost nothing. 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."New value: +"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." - changed
Output schema / properties / notice / descriptionPrevious value: -"Recovery guidance when no studies matched — echoes the constraint and suggests how to broaden. Absent on pages with results."New value: +"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. Absent on pages with results, and on an exhausted continuation page, where the cohort already matched and there is nothing to broaden." - added
Output schema / properties / pageExhaustedAdded value: +{ + "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.", + "type": "boolean" +}
7 tool updates
v2.9.2- Changed
clinicaltrials_find_eligible7 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / location / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "studies", + "searchCriteria", + "funnel" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `blank_value`: A parameter was supplied with a blank, whitespace-only, or empty-list value. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler.", + "examples": [ + "blank_value", + "rate_limited" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "studies", - "searchCriteria", - "funnel" -]
- Changed
clinicaltrials_get_field_definitions6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "fields", + "totalFields" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `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.", + "examples": [ + "path_not_found", + "rate_limited" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "fields", - "totalFields" -]
- Changed
clinicaltrials_get_field_values6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "fieldStats" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "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. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler.", + "examples": [ + "blank_value", + "field_invalid", + "rate_limited" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "fieldStats" -]
- Changed
clinicaltrials_get_study_count6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "totalCount" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "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 field name in the advanced filter or AREA[] expression is invalid (often a module name instead of a piece name). `enum_invalid`: statusFilter or phaseFilter contains 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. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler.", + "examples": [ + "blank_value", + "field_invalid", + "enum_invalid", + "query_parse_error", + "rate_limited" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "totalCount" -]
- Changed
clinicaltrials_get_study_record7 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / nearLocation / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "study", + "filtersApplied" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "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.", + "examples": [ + "study_not_found", + "rate_limited" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "study", - "filtersApplied" -]
- Changed
clinicaltrials_get_study_results6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "results" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `blank_value`: A parameter was supplied with a blank, whitespace-only, or empty-list value. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler.", + "examples": [ + "blank_value", + "rate_limited" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "results" -]
- Changed
clinicaltrials_search_studies6 fields changed- changed
Input schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Input schema / additionalPropertiesAdded value: +false - changed
Output schema / $schemaPrevious value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema" - added
Output schema / anyOfAdded value: +[ + { + "not": { + "required": [ + "error" + ] + }, + "required": [ + "studies" + ] + }, + { + "required": [ + "error" + ] + } +] - added
Output schema / properties / errorAdded value: +{ + "additionalProperties": {}, + "description": "Present when the call failed. Absent on success.", + "properties": { + "code": { + "description": "JSON-RPC error code for this failure.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "data": { + "additionalProperties": {}, + "properties": { + "reason": { + "description": "Machine-readable failure mode. Declared by this tool: `blank_value`: A parameter was supplied with a blank, whitespace-only, or empty-list value. `ids_not_found`: One or more NCT IDs in the nctIds filter are not present at ClinicalTrials.gov. `field_invalid`: A field name in the fields parameter or AREA[] expression is invalid (often a module name instead of a piece name). `enum_invalid`: statusFilter or phaseFilter contains 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. `rate_limited`: ClinicalTrials.gov returned 429 after retry budget exhausted. Other values are possible when a failure originates below the handler.", + "examples": [ + "blank_value", + "ids_not_found", + "field_invalid", + "enum_invalid", + "query_parse_error", + "geo_invalid", + "sort_invalid", + "rate_limited" + ], + "type": "string" + }, + "recovery": { + "additionalProperties": {}, + "description": "Actionable next step for the caller.", + "properties": { + "hint": { + "type": "string" + } + }, + "required": [ + "hint" + ], + "type": "object" + }, + "retryable": { + "description": "Whether retrying may succeed.", + "type": "boolean" + } + }, + "type": "object" + }, + "message": { + "description": "Human-readable description of what went wrong.", + "type": "string" + } + }, + "required": [ + "code", + "message" + ], + "type": "object" +} - removed
Output schema / requiredRemoved value: -[ - "studies" -]
6 tool updates
v2.9.1- Changed
clinicaltrials_find_eligible3 fields changed- removed
Input schema / properties / conditions / minItemsRemoved value: -1 - added
Input schema / properties / locationLimitAdded value: +{ + "default": 10, + "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, the candidate's nearest recruiting site is added on top of it, so a candidate can carry one site more than this. Raise it to see more nearby sites, 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.", + "maximum": 500, + "minimum": 1, + "type": "integer" +} - changed
Output schema / properties / studies / descriptionPrevious value: -"Matching studies with eligibility and location fields."New value: +"Matching studies with eligibility and location fields. 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, the candidate's nearest recruiting site — not the study's full registered site list. 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. Fetch a study's complete record and site list with clinicaltrials_get_study_record."
- Changed
clinicaltrials_get_field_definitions1 field changed- added
Output schema / properties / totalMatchesAdded value: +{ + "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.", + "type": "number" +}
- Changed
clinicaltrials_get_field_values2 fields changed- changed
Input schema / properties / fields / anyOfPrevious value: -[ - { - "description": "A single PascalCase field name.", - "type": "string" - }, - { - "description": "Multiple PascalCase field names (at least one required).", - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" - } -]New value: +[ + { + "description": "A single PascalCase field name.", + "type": "string" + }, + { + "description": "Multiple PascalCase field names (at least one required).", + "items": { + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / fields / descriptionPrevious value: -"PascalCase field name(s) to get value statistics for. Examples: OverallStatus, Phase, StudyType, Sex, LeadSponsorClass. Use clinicaltrials_get_field_definitions with a query to find more field names."New value: +"PascalCase field name(s) to get value statistics for — an empty list is rejected, not treated as \"every field\". Examples: OverallStatus, Phase, StudyType, Sex, LeadSponsorClass. Use clinicaltrials_get_field_definitions with a query to find more field names."
- Changed
clinicaltrials_get_study_count9 fields changed- changed
Input schema / properties / conditionQuery / descriptionPrevious value: -"Condition/disease-specific search. E.g., \"Type 2 Diabetes\", \"non-small cell lung cancer\". Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."New value: +"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." - changed
Input schema / properties / interventionQuery / descriptionPrevious value: -"Intervention/treatment search. E.g., \"pembrolizumab\", \"cognitive behavioral therapy\". Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."New value: +"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." - changed
Input schema / properties / locationQuery / descriptionPrevious value: -"Location search — city, state, country, or facility name. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."New value: +"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." - changed
Input schema / properties / outcomeQuery / descriptionPrevious value: -"Search within outcome measure fields. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."New value: +"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." - changed
Input schema / properties / phaseFilter / descriptionPrevious value: -"Filter by trial phase. Values: EARLY_PHASE1, PHASE1, PHASE2, PHASE3, PHASE4, NA."New value: +"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." - changed
Input schema / properties / query / descriptionPrevious value: -"General free-text search across all fields. Plain words plus AND, OR, NOT. `[ ]` are reserved (advancedFilter AREA[] only); `( )` group sub-expressions and work when matched; `,` acts as AND. For field-scoped searches, use the dedicated *Query parameters (conditionQuery, interventionQuery, etc.) or advancedFilter with AREA[FieldName]value."New value: +"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." - changed
Input schema / properties / sponsorQuery / descriptionPrevious value: -"Sponsor/collaborator name search. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."New value: +"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." - changed
Input schema / properties / statusFilter / descriptionPrevious value: -"Filter by study status. 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."New value: +"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." - changed
Input schema / properties / titleQuery / descriptionPrevious value: -"Search within study titles and acronyms only. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."New value: +"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."
- Changed
clinicaltrials_get_study_results8 fields changed- added
Input schema / properties / adverseEventLimitAdded value: +{ + "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). Applies to full mode only — summary mode already ranks the top 20 by participants affected. Event groups are never capped. Upstream totals preserved in filtersApplied.totalSeriousEvents / totalOtherEvents only when the cap trims a list.", + "maximum": 500, + "minimum": 1, + "type": "integer" +} - changed
Input schema / properties / nctIds / anyOfPrevious value: -[ - { - "description": "A single NCT ID.", - "pattern": "^NCT\\d{8}$", - "type": "string" - }, - { - "description": "Multiple NCT IDs (max 20).", - "items": { - "pattern": "^NCT\\d{8}$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array" - } -]New value: +[ + { + "description": "A single NCT ID.", + "pattern": "^NCT\\d{8}$", + "type": "string" + }, + { + "description": "Multiple NCT IDs (max 20).", + "items": { + "pattern": "^NCT\\d{8}$", + "type": "string" + }, + "maxItems": 20, + "type": "array" + } +] - changed
Input schema / properties / nctIds / descriptionPrevious value: -"One or more NCT IDs (max 20). E.g., \"NCT12345678\" or [\"NCT12345678\", \"NCT87654321\"]. Use summary=true for large batches to avoid large payloads."New value: +"One or more NCT IDs (max 20) — an empty list is rejected. E.g., \"NCT12345678\" or [\"NCT12345678\", \"NCT87654321\"]. Use summary=true for large batches to avoid large payloads." - added
Input schema / properties / outcomeLimitAdded value: +{ + "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). Applies to full mode only — summary mode is already condensed. Each surviving measure keeps its complete groups/classes/measurements/analyses tree. Upstream total preserved in filtersApplied.totalOutcomes only when the cap trims the list.", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - changed
Input schema / properties / sections / descriptionPrevious value: -"Filter which sections to return. Values: outcomes, adverseEvents, participantFlow, baseline, moreInfo. Omit for all sections."New value: +"Filter which sections to return. Values: outcomes, adverseEvents, participantFlow, baseline, moreInfo. Omit for all sections — an empty list is rejected, not treated as omission." - changed
Input schema / properties / summary / descriptionPrevious value: -"Return condensed summaries instead of full data. Reduces payload from ~200KB to ~5KB per study. Summaries include outcome titles, types, timeframes, group counts, and top-level stats — omitting individual measurements, analyses, and per-group data."New value: +"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 reduces that to ~5KB. Summaries include outcome titles, types, timeframes, group counts, and top-level stats — omitting individual measurements, analyses, and per-group data. For a middle ground, keep full mode and cap the two lists that carry the bulk with outcomeLimit / adverseEventLimit." - added
Output schema / properties / results / items / properties / filtersAppliedAdded value: +{ + "additionalProperties": false, + "description": "What a cap trimmed on this study — present only when a cap actually reduced a list. Absent means the payload is the complete upstream set for the requested sections.", + "properties": { + "adverseEventLimit": { + "description": "Echo of the adverseEventLimit input — present only when the cap trimmed a list.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "outcomeLimit": { + "description": "Echo of the outcomeLimit input — present only when the cap trimmed the list.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "totalOtherEvents": { + "description": "Upstream other adverse event count before adverseEventLimit trimmed the list.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "totalOutcomes": { + "description": "Upstream outcome measure count before outcomeLimit trimmed the list.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "totalSeriousEvents": { + "description": "Upstream serious adverse event count before adverseEventLimit trimmed the list.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "type": "object" +} - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when a cap trimmed a list on at least one study; absent when nothing was trimmed, matching filtersApplied one level down. Which study and which list is named in that study’s filtersApplied.", + "type": "boolean" +}
- Changed
clinicaltrials_search_studies13 fields changed- changed
Input schema / properties / conditionQuery / descriptionPrevious value: -"Condition/disease-specific search. E.g., \"Type 2 Diabetes\", \"non-small cell lung cancer\". Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."New value: +"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." - changed
Input schema / properties / fields / descriptionPrevious value: -"PascalCase leaf names to return; strongly recommended since full records are ~70KB. 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."New value: +"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. 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." - changed
Input schema / properties / geoFilter / descriptionPrevious value: -"Geographic proximity filter. Format: distance(lat,lon,radius). E.g., \"distance(47.6062,-122.3321,50mi)\" for studies within 50 miles of Seattle. 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."New value: +"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. Always include the suffix: a bare radius is accepted upstream but interpreted as meters, which silently matches almost nothing. 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." - changed
Input schema / properties / interventionQuery / descriptionPrevious value: -"Intervention/treatment search. E.g., \"pembrolizumab\", \"cognitive behavioral therapy\". Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."New value: +"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." - changed
Input schema / properties / locationQuery / descriptionPrevious value: -"Location search — city, state, country, or facility name. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."New value: +"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." - changed
Input schema / properties / nctIds / descriptionPrevious value: -"Filter to specific NCT IDs for batch lookups."New value: +"Filter to specific NCT IDs for batch lookups. Omit to search every study — an empty list is rejected, not treated as \"no filter\". Supplying this lifts the default unknown-enrollment exclusion, so an ID you name is never filtered out of its own lookup." - changed
Input schema / properties / outcomeQuery / descriptionPrevious value: -"Search within outcome measure fields. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."New value: +"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." - changed
Input schema / properties / phaseFilter / descriptionPrevious value: -"Filter by trial phase. Values: EARLY_PHASE1, PHASE1, PHASE2, PHASE3, PHASE4, NA."New value: +"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." - changed
Input schema / properties / query / descriptionPrevious value: -"General free-text search across all fields. Plain words plus AND, OR, NOT. `[ ]` are reserved (advancedFilter AREA[] only); `( )` group sub-expressions and work when matched; `,` acts as AND. For field-scoped searches, use the dedicated *Query parameters (conditionQuery, interventionQuery, etc.) or advancedFilter with AREA[FieldName]value."New value: +"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." - changed
Input schema / properties / sponsorQuery / descriptionPrevious value: -"Sponsor/collaborator name search. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."New value: +"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." - changed
Input schema / properties / statusFilter / descriptionPrevious value: -"Filter by study status. 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."New value: +"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." - changed
Input schema / properties / titleQuery / descriptionPrevious value: -"Search within study titles and acronyms only. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."New value: +"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." - changed
Output schema / properties / nextPageToken / descriptionPrevious value: -"Token for the next page. Absent on last page."New value: +"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."
1 tool update
v2.8.2- Changed
clinicaltrials_find_eligible5 fields changed- changed
Output schema / properties / searchCriteria / descriptionPrevious value: -"Normalized search criteria applied to this eligibility query."New value: +"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)." - added
Output schema / properties / searchCriteria / properties / advancedFilterAdded value: +{ + "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.", + "type": "string" +} - added
Output schema / properties / searchCriteria / properties / conditionQueryAdded value: +{ + "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.", + "type": "string" +} - changed
Output schema / properties / searchCriteria / properties / location / descriptionPrevious value: -"Location searched."New value: +"The exact queryLocn string sent upstream (city/state/country joined). Pass as locationQuery to clinicaltrials_search_studies to reproduce the location filter beyond the maxResults cap." - added
Output schema / properties / searchCriteria / properties / statusFilterAdded value: +{ + "description": "The status filter applied ([\"RECRUITING\"] when recruitingOnly). Pass as statusFilter to clinicaltrials_search_studies. Absent when recruitingOnly is false.", + "items": { + "type": "string" + }, + "type": "array" +}
1 tool update
v2.8.0- Changed
clinicaltrials_search_studies2 fields changed- changed
Output schema / properties / requestedFields / descriptionPrevious value: -"Echo of the explicit fields parameter — present only when the caller passed fields. Lifts the default truncation cap so all requested leaves render in full."New value: +"Echo of the explicit fields parameter — 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." - changed
Output schema / properties / studies / descriptionPrevious value: -"Matching studies. Each entry is a nested ClinicalTrials.gov study record — top-level keys: protocolSection, derivedSection, hasResults, resultsSection, documentSection. Use clinicaltrials_get_field_definitions to explore the schema."New value: +"Matching studies. By default each entry is a COMPACT index projection — nctId, briefTitle, overallStatus, phases, enrollmentCount, leadSponsor, conditions, and a bounded locations summary ({ total, nearest }) — 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."
4 tool updates
v2.7.1- Changed
clinicaltrials_get_field_values3 fields changed- changed
Input schema / properties / fields / anyOfPrevious value: -[ - { - "description": "A single PascalCase field name.", - "type": "string" - }, - { - "description": "Multiple PascalCase field names.", - "items": { - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "description": "A single PascalCase field name.", + "type": "string" + }, + { + "description": "Multiple PascalCase field names (at least one required).", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + } +] - added
Output schema / properties / fieldStats / items / properties / multiValuedAdded value: +{ + "description": "True when the field is array-typed (a study can carry several values, e.g. Phase, Condition), so the per-value studiesCount buckets sum above the study total. Use to avoid computing a percentage against the corpus.", + "type": "boolean" +} - changed
Output schema / properties / fieldStats / items / properties / topValues / descriptionPrevious value: -"Values ranked by frequency (capped at 250 by the API). Present for ENUM/STRING fields."New value: +"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."
- Changed
clinicaltrials_get_study_count1 field changed- changed
Output schema / properties / searchCriteria / descriptionPrevious value: -"Echo of active query/filter criteria applied to this count."New value: +"Echo of active query/filter criteria applied to this count, including sentinelFilterActive when the default unknown-enrollment exclusion is in effect."
- Changed
clinicaltrials_get_study_record7 fields changed- changed
Input schema / properties / locationLimit / descriptionPrevious value: -"Optional cap on the number of locations returned. Omit for no cap (full upstream list). Pairs naturally with nearLocation for narrowing a large multi-site trial. Original total preserved in filtersApplied.totalLocations whenever a cap is applied."New value: +"Optional cap on the number of locations returned. Omit for no cap (full upstream list). Pairs naturally with nearLocation for narrowing a large multi-site trial. Original total preserved in filtersApplied.totalLocations only when the cap trims the list." - changed
Input schema / properties / nearLocation / descriptionPrevious value: -"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. For broader geographic filtering across studies, use clinicaltrials_search_studies with geoFilter."New value: +"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." - changed
Input schema / properties / outcomeLimit / descriptionPrevious value: -"Optional cap on the number of secondary and other outcomes returned. Omit for no cap (full upstream lists). Primary outcomes are never capped. Original totals preserved in filtersApplied.totalSecondaryOutcomes / totalOtherOutcomes whenever a cap is applied."New value: +"Optional cap on the number of secondary and other outcomes returned. Omit for no cap (full upstream lists). Primary outcomes are never capped. Original totals preserved in filtersApplied.totalSecondaryOutcomes / totalOtherOutcomes only when the cap trims a list." - changed
Input schema / properties / referenceLimit / descriptionPrevious value: -"Optional cap on the number of references returned. Omit for no cap (full upstream list). Original total preserved in filtersApplied.totalReferences whenever a cap is applied. seeAlsoLinks are never capped."New value: +"Optional cap on the number of references returned. Omit for no cap (full upstream list). Original total preserved in filtersApplied.totalReferences only when the cap trims the list. seeAlsoLinks are never capped." - changed
Output schema / properties / filtersApplied / properties / locationLimit / descriptionPrevious value: -"Echo of the locationLimit input."New value: +"Echo of the locationLimit input — present only when the cap trimmed the list." - changed
Output schema / properties / filtersApplied / properties / outcomeLimit / descriptionPrevious value: -"Echo of the outcomeLimit input."New value: +"Echo of the outcomeLimit input — present only when the cap trimmed a list." - changed
Output schema / properties / filtersApplied / properties / referenceLimit / descriptionPrevious value: -"Echo of the referenceLimit input."New value: +"Echo of the referenceLimit input — present only when the cap trimmed the list."
- Changed
clinicaltrials_search_studies1 field changed- changed
Input schema / properties / geoFilter / descriptionPrevious value: -"Geographic proximity filter. Format: distance(lat,lon,radius). E.g., \"distance(47.6062,-122.3321,50mi)\" for studies within 50 miles of Seattle."New value: +"Geographic proximity filter. Format: distance(lat,lon,radius). E.g., \"distance(47.6062,-122.3321,50mi)\" for studies within 50 miles of Seattle. 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."
4 tool updates
v2.7.0- Changed
clinicaltrials_find_eligible1 field changed- changed
Input schema / properties / conditions / descriptionPrevious value: -"Medical conditions or diagnoses. E.g., [\"Type 2 Diabetes\", \"Hypertension\"]. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."New value: +"Medical conditions or diagnoses, e.g. [\"Type 2 Diabetes\", \"Hypertension\"]. Each entry is matched as a condition (multi-word entries match as a phrase); 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."
- Changed
clinicaltrials_get_field_definitions4 fields changed- added
Output schema / properties / capAdded value: +{ + "description": "The limit cap applied to this search (search mode only).", + "type": "number" +} - changed
Output schema / properties / notice / descriptionPrevious value: -"Recovery guidance when search mode returns no matches — suggests alternative keywords."New value: +"Recovery guidance when search mode returns no matches, or a truncation note when results are capped." - added
Output schema / properties / shownAdded value: +{ + "description": "Number of fields returned (search mode only).", + "type": "number" +} - added
Output schema / properties / truncatedAdded value: +{ + "description": "True when the field list was capped by the limit parameter (search mode only).", + "type": "boolean" +}
- Changed
clinicaltrials_get_study_record3 fields changed- added
Input schema / properties / referenceLimitAdded value: +{ + "description": "Optional cap on the number of references returned. Omit for no cap (full upstream list). Original total preserved in filtersApplied.totalReferences whenever a cap is applied. seeAlsoLinks are never capped.", + "maximum": 100, + "minimum": 1, + "type": "integer" +} - added
Output schema / properties / filtersApplied / properties / referenceLimitAdded value: +{ + "description": "Echo of the referenceLimit input.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +} - added
Output schema / properties / filtersApplied / properties / totalReferencesAdded value: +{ + "description": "Upstream reference count before referenceLimit was applied.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" +}
- Changed
clinicaltrials_search_studies1 field changed- changed
Input schema / properties / sort / descriptionPrevious value: -"Sort order. Format: FieldName:asc or FieldName:desc. E.g., \"LastUpdatePostDate:desc\", \"EnrollmentCount:desc\". Max 2 fields comma-separated. Use clinicaltrials_get_field_definitions to find sortable field names."New value: +"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."
3 tool updates
v2.6.5- Changed
clinicaltrials_find_eligible1 field changed- changed
Input schema / properties / conditions / descriptionPrevious value: -"Medical conditions or diagnoses. E.g., [\"Type 2 Diabetes\", \"Hypertension\"]. Plain words only — reserved chars `[ ] ( ) ,` inside an entry will fail."New value: +"Medical conditions or diagnoses. E.g., [\"Type 2 Diabetes\", \"Hypertension\"]. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."
- Changed
clinicaltrials_get_study_count7 fields changed- changed
Input schema / properties / conditionQuery / descriptionPrevious value: -"Condition/disease-specific search. E.g., \"Type 2 Diabetes\", \"non-small cell lung cancer\". Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,"New value: +"Condition/disease-specific search. E.g., \"Type 2 Diabetes\", \"non-small cell lung cancer\". Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND." - changed
Input schema / properties / interventionQuery / descriptionPrevious value: -"Intervention/treatment search. E.g., \"pembrolizumab\", \"cognitive behavioral therapy\". Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,"New value: +"Intervention/treatment search. E.g., \"pembrolizumab\", \"cognitive behavioral therapy\". Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND." - changed
Input schema / properties / locationQuery / descriptionPrevious value: -"Location search — city, state, country, or facility name. Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,"New value: +"Location search — city, state, country, or facility name. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND." - changed
Input schema / properties / outcomeQuery / descriptionPrevious value: -"Search within outcome measure fields. Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,"New value: +"Search within outcome measure fields. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND." - changed
Input schema / properties / query / descriptionPrevious value: -"General free-text search across all fields. Plain words plus AND, OR, NOT only — reserved chars `[ ] ( ) ,` will fail. For field-scoped searches, use the dedicated *Query parameters (conditionQuery, interventionQuery, etc.) or advancedFilter with AREA[FieldName]value."New value: +"General free-text search across all fields. Plain words plus AND, OR, NOT. `[ ]` are reserved (advancedFilter AREA[] only); `( )` group sub-expressions and work when matched; `,` acts as AND. For field-scoped searches, use the dedicated *Query parameters (conditionQuery, interventionQuery, etc.) or advancedFilter with AREA[FieldName]value." - changed
Input schema / properties / sponsorQuery / descriptionPrevious value: -"Sponsor/collaborator name search. Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,"New value: +"Sponsor/collaborator name search. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND." - changed
Input schema / properties / titleQuery / descriptionPrevious value: -"Search within study titles and acronyms only. Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,"New value: +"Search within study titles and acronyms only. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."
- Changed
clinicaltrials_search_studies7 fields changed- changed
Input schema / properties / conditionQuery / descriptionPrevious value: -"Condition/disease-specific search. E.g., \"Type 2 Diabetes\", \"non-small cell lung cancer\". Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,"New value: +"Condition/disease-specific search. E.g., \"Type 2 Diabetes\", \"non-small cell lung cancer\". Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND." - changed
Input schema / properties / interventionQuery / descriptionPrevious value: -"Intervention/treatment search. E.g., \"pembrolizumab\", \"cognitive behavioral therapy\". Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,"New value: +"Intervention/treatment search. E.g., \"pembrolizumab\", \"cognitive behavioral therapy\". Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND." - changed
Input schema / properties / locationQuery / descriptionPrevious value: -"Location search — city, state, country, or facility name. Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,"New value: +"Location search — city, state, country, or facility name. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND." - changed
Input schema / properties / outcomeQuery / descriptionPrevious value: -"Search within outcome measure fields. Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,"New value: +"Search within outcome measure fields. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND." - changed
Input schema / properties / query / descriptionPrevious value: -"General free-text search across all fields. Plain words plus AND, OR, NOT only — reserved chars `[ ] ( ) ,` will fail. For field-scoped searches, use the dedicated *Query parameters (conditionQuery, interventionQuery, etc.) or advancedFilter with AREA[FieldName]value."New value: +"General free-text search across all fields. Plain words plus AND, OR, NOT. `[ ]` are reserved (advancedFilter AREA[] only); `( )` group sub-expressions and work when matched; `,` acts as AND. For field-scoped searches, use the dedicated *Query parameters (conditionQuery, interventionQuery, etc.) or advancedFilter with AREA[FieldName]value." - changed
Input schema / properties / sponsorQuery / descriptionPrevious value: -"Sponsor/collaborator name search. Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,"New value: +"Sponsor/collaborator name search. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND." - changed
Input schema / properties / titleQuery / descriptionPrevious value: -"Search within study titles and acronyms only. Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,"New value: +"Search within study titles and acronyms only. Plain words plus AND/OR/NOT. `[ ]` are reserved; `( )` group sub-expressions when matched; `,` acts as AND."
4 tool updates
v2.6.1- Changed
clinicaltrials_get_study_count3 fields changed- added
Input schema / properties / locationQueryAdded value: +{ + "description": "Location search — city, state, country, or facility name. Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,", + "type": "string" +} - added
Input schema / properties / outcomeQueryAdded value: +{ + "description": "Search within outcome measure fields. Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,", + "type": "string" +} - added
Input schema / properties / titleQueryAdded value: +{ + "description": "Search within study titles and acronyms only. Plain words plus AND/OR/NOT only — reserved chars: [ ] ( ) ,", + "type": "string" +}
- Changed
clinicaltrials_get_study_record2 fields changed- added
Output schema / properties / resultsSummaryAdded value: +{ + "additionalProperties": false, + "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 or the clinicaltrials://{nctId} resource.", + "properties": { + "baselineMeasures": { + "description": "Baseline characteristic measures.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "otherAdverseEvents": { + "description": "Distinct other (non-serious) adverse-event terms.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "outcomeMeasures": { + "description": "Posted outcome measures.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "participantFlowPeriods": { + "description": "Participant-flow periods.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "seriousAdverseEvents": { + "description": "Distinct serious adverse-event terms.", + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "type": "object" +} - changed
Output schema / properties / study / descriptionPrevious value: -"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, resultsSection, documentSection. Use clinicaltrials_get_field_definitions to explore the schema."New value: +"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."
- Changed
clinicaltrials_get_study_results4 fields changed- changed
Input schema / properties / sections / anyOfPrevious value: -[ - { - "description": "A single section name.", - "enum": [ - "outcomes", - "adverseEvents", - "participantFlow", - "baseline" - ], - "type": "string" - }, - { - "description": "Multiple section names.", - "items": { - "enum": [ - "outcomes", - "adverseEvents", - "participantFlow", - "baseline" - ], - "type": "string" - }, - "type": "array" - } -]New value: +[ + { + "description": "A single section name.", + "enum": [ + "outcomes", + "adverseEvents", + "participantFlow", + "baseline", + "moreInfo" + ], + "type": "string" + }, + { + "description": "Multiple section names.", + "items": { + "enum": [ + "outcomes", + "adverseEvents", + "participantFlow", + "baseline", + "moreInfo" + ], + "type": "string" + }, + "type": "array" + } +] - changed
Input schema / properties / sections / descriptionPrevious value: -"Filter which sections to return. Values: outcomes, adverseEvents, participantFlow, baseline. Omit for all sections."New value: +"Filter which sections to return. Values: outcomes, adverseEvents, participantFlow, baseline, moreInfo. Omit for all sections." - changed
Output schema / properties / results / items / properties / adverseEvents / descriptionPrevious value: -"Adverse events. Summary mode: timeFrame, groupCount, seriousEventCount, otherEventCount. Full mode: adds eventGroups, seriousEvents, otherEvents with per-event term and per-group affected/at-risk stats."New value: +"Adverse events. Summary mode: timeFrame, groupCount, seriousEventCount, otherEventCount, plus topEvents — the most frequent events ranked by participants affected, aggregated across arms (term, organSystem, kind, numAffected, numAtRisk). Full mode: adds eventGroups, seriousEvents, otherEvents with per-event term and per-group affected/at-risk stats." - added
Output schema / properties / results / items / properties / moreInfoAdded value: +{ + "additionalProperties": {}, + "description": "Results metadata from moreInfoModule. Summary mode: limitationsAndCaveats, certainAgreement flags (piSponsorEmployee, restrictiveAgreement, restrictionType), and pointOfContact. Full mode: adds certainAgreement.otherDetails.", + "propertyNames": { + "type": "string" + }, + "type": "object" +}
- Changed
clinicaltrials_search_studies1 field changed- changed
Output schema / properties / searchCriteria / descriptionPrevious value: -"Echo of active query/filter criteria. Present when results are empty."New value: +"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."
4 tool updates
v2.5.4- Changed
clinicaltrials_find_eligible4 fields changed- changed
Output schema / properties / funnel / descriptionPrevious value: -"Match counts at each filter stage. Diagnoses where the funnel collapsed on sparse results — e.g., conditionMatched=298 but demographicsMatched=2 means age/sex/status are the constraint."New value: +"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." - removed
Output schema / properties / noMatchHintsRemoved value: -{ - "description": "Hints when no studies match, with suggestions to broaden the search.", - "items": { - "type": "string" - }, - "type": "array" -} - added
Output schema / properties / noticeAdded value: +{ + "description": "Recovery guidance when no studies matched — identifies which filter stage collapsed and suggests how to broaden. Absent when results are returned.", + "type": "string" +} - changed
Output schema / properties / searchCriteria / descriptionPrevious value: -"Search criteria used."New value: +"Normalized search criteria applied to this eligibility query."
- Changed
clinicaltrials_get_field_definitions2 fields changed- added
Output schema / properties / noticeAdded value: +{ + "description": "Recovery guidance when search mode returns no matches — suggests alternative keywords.", + "type": "string" +} - changed
Output schema / properties / searchQuery / descriptionPrevious value: -"Echo of the keyword when mode is \"search\"."New value: +"Echo of the keyword used in search mode. Absent for drill and overview."
- Changed
clinicaltrials_get_study_count3 fields changed- removed
Output schema / properties / noMatchHintsRemoved value: -{ - "description": "Suggestions when no studies match (totalCount is 0).", - "items": { - "type": "string" - }, - "type": "array" -} - added
Output schema / properties / noticeAdded value: +{ + "description": "Recovery guidance when totalCount is 0 — suggests how to broaden the query or filters.", + "type": "string" +} - changed
Output schema / properties / searchCriteria / descriptionPrevious value: -"Echo of query/filter criteria used."New value: +"Echo of active query/filter criteria applied to this count."
- Changed
clinicaltrials_search_studies3 fields changed- removed
Output schema / properties / noMatchHintsRemoved value: -{ - "description": "Suggestions for broadening the search when no results are found.", - "items": { - "type": "string" - }, - "type": "array" -} - added
Output schema / properties / noticeAdded value: +{ + "description": "Recovery guidance when no studies matched — echoes the constraint and suggests how to broaden. Absent on pages with results.", + "type": "string" +} - changed
Output schema / properties / searchCriteria / descriptionPrevious value: -"Echo of query/filter criteria used. Present when results are empty."New value: +"Echo of active query/filter criteria. Present when results are empty."
7 tool updates
v2.5.1- Added
clinicaltrials_find_eligible - Added
clinicaltrials_get_field_definitions - Added
clinicaltrials_get_field_values - Added
clinicaltrials_get_study_count - Added
clinicaltrials_get_study_record - Added
clinicaltrials_get_study_results - Added
clinicaltrials_search_studies
7 tool updates
v2.4.12- Removed
clinicaltrials_find_eligible - Removed
clinicaltrials_get_field_definitions - Removed
clinicaltrials_get_field_values - Removed
clinicaltrials_get_study_count - Removed
clinicaltrials_get_study_record - Removed
clinicaltrials_get_study_results - Removed
clinicaltrials_search_studies
9 tool updates
v2.0.6- Removed
clinicaltrials_analyze_trends - Added
clinicaltrials_find_eligible - Added
clinicaltrials_get_field_definitions - Added
clinicaltrials_get_field_values - Removed
clinicaltrials_get_study - Added
clinicaltrials_get_study_count - Added
clinicaltrials_get_study_record - Added
clinicaltrials_get_study_results - Changed
clinicaltrials_search_studies32 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / advancedFilterAdded value: +{ + "description": "Advanced filter using AREA[] Essie syntax. E.g., \"AREA[StudyType]INTERVENTIONAL\", \"AREA[EnrollmentCount]RANGE[100, 1000]\". Combine with AND/OR/NOT and parentheses.", + "type": "string" +} - added
Input schema / properties / conditionQueryAdded value: +{ + "description": "Condition/disease-specific search. E.g., \"Type 2 Diabetes\", \"non-small cell lung cancer\".", + "type": "string" +} - added
Input schema / properties / countTotalAdded value: +{ + "default": true, + "description": "Include total study count in response. Only computed on the first page.", + "type": "boolean" +} - changed
Input schema / properties / fields / descriptionPrevious value: -"A list of specific top-level fields to include in the response."New value: +"Fields to return (PascalCase piece names). Strongly recommended to reduce payload. Common: NCTId, BriefTitle, OverallStatus, Phase, LeadSponsorName, Condition, InterventionName, BriefSummary, EnrollmentCount, StartDate." - removed
Input schema / properties / filterRemoved value: -{ - "additionalProperties": false, - "description": "A set of filters that narrow the search results without affecting ranking.", - "properties": { - "advanced": { - "description": "Apply an advanced filter using Essie expression syntax.", - "type": "string" - }, - "geo": { - "additionalProperties": false, - "description": "Filter results to a geographic area by providing a point and radius.", - "properties": { - "latitude": { - "maximum": 90, - "minimum": -90, - "type": "number" - }, - "longitude": { - "maximum": 180, - "minimum": -180, - "type": "number" - }, - "radius": { - "exclusiveMinimum": 0, - "type": "number" - }, - "unit": { - "default": "km", - "enum": [ - "km", - "mi" - ], - "type": "string" - } - }, - "required": [ - "latitude", - "longitude", - "radius" - ], - "type": "object" - }, - "ids": { - "description": "Return only studies with the specified NCT IDs.", - "items": { - "type": "string" - }, - "type": "array" - }, - "overallStatus": { - "description": "Filter results by one or more study statuses.", - "items": { - "enum": [ - "ACTIVE_NOT_RECRUITING", - "COMPLETED", - "ENROLLING_BY_INVITATION", - "NOT_YET_RECRUITING", - "RECRUITING", - "SUSPENDED", - "TERMINATED", - "WITHDRAWN", - "UNKNOWN" - ], - "type": "string" - }, - "type": "array" - } - }, - "type": "object" -} - added
Input schema / properties / geoFilterAdded value: +{ + "description": "Geographic proximity filter. Format: distance(lat,lon,radius). E.g., \"distance(47.6062,-122.3321,50mi)\" for studies within 50 miles of Seattle.", + "type": "string" +} - added
Input schema / properties / interventionQueryAdded value: +{ + "description": "Intervention/treatment search. E.g., \"pembrolizumab\", \"cognitive behavioral therapy\".", + "type": "string" +} - added
Input schema / properties / locationQueryAdded value: +{ + "description": "Location search — city, state, country, or facility name.", + "type": "string" +} - added
Input schema / properties / nctIdsAdded value: +{ + "anyOf": [ + { + "pattern": "^NCT\\d{8}$", + "type": "string" + }, + { + "items": { + "pattern": "^NCT\\d{8}$", + "type": "string" + }, + "type": "array" + } + ], + "description": "Filter to specific NCT IDs for batch lookups." +} - added
Input schema / properties / outcomeQueryAdded value: +{ + "description": "Search within outcome measure fields.", + "type": "string" +} - changed
Input schema / properties / pageSize / descriptionPrevious value: -"The number of studies to return per page (1-200). Defaults to 10."New value: +"Results per page, 1–200." - changed
Input schema / properties / pageToken / descriptionPrevious value: -"A token used to retrieve the next page of results."New value: +"Pagination cursor from a previous response." - added
Input schema / properties / phaseFilterAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "description": "Filter by trial phase. Values: EARLY_PHASE1, PHASE1, PHASE2, PHASE3, PHASE4, NA." +} - removed
Input schema / properties / query / additionalPropertiesRemoved value: -false - changed
Input schema / properties / query / descriptionPrevious value: -"A set of search terms that influence result ranking."New value: +"General full-text search across all fields." - removed
Input schema / properties / query / propertiesRemoved value: -{ - "cond": { - "description": "Search for conditions or diseases.", - "type": "string" - }, - "id": { - "description": "Search for study identifiers (e.g., NCT ID).", - "type": "string" - }, - "intr": { - "description": "Search for specific interventions or treatments.", - "type": "string" - }, - "locn": { - "description": "Search for study locations.", - "type": "string" - }, - "outc": { - "description": "Search for specific outcome measures.", - "type": "string" - }, - "spons": { - "description": "Search for sponsors or collaborators.", - "type": "string" - }, - "term": { - "description": "Search for other terms like interventions, outcomes, or sponsors.", - "type": "string" - }, - "titles": { - "description": "Search within study titles or acronyms.", - "type": "string" - } -} - changed
Input schema / properties / query / typePrevious value: -"object"New value: +"string" - changed
Input schema / properties / sort / descriptionPrevious value: -"Specify the sort order for the results."New value: +"Sort order. Format: FieldName:asc or FieldName:desc. E.g., \"LastUpdatePostDate:desc\", \"EnrollmentCount:desc\". Max 2 fields comma-separated." - removed
Input schema / properties / sort / itemsRemoved value: -{ - "type": "string" -} - changed
Input schema / properties / sort / typePrevious value: -"array"New value: +"string" - added
Input schema / properties / sponsorQueryAdded value: +{ + "description": "Sponsor/collaborator name search.", + "type": "string" +} - added
Input schema / properties / statusFilterAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "description": "Filter by study status. 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." +} - added
Input schema / properties / titleQueryAdded value: +{ + "description": "Search within study titles and acronyms only.", + "type": "string" +} - added
Output schema / properties / nextPageToken / descriptionAdded value: +"Token for the next page. Absent on last page." - added
Output schema / properties / noMatchHintsAdded value: +{ + "description": "Suggestions for broadening the search when no results are found.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / searchCriteriaAdded value: +{ + "additionalProperties": {}, + "description": "Echo of query/filter criteria used. Present when results are empty.", + "propertyNames": { + "type": "string" + }, + "type": "object" +} - added
Output schema / properties / studies / descriptionAdded value: +"Matching studies." - changed
Output schema / properties / studies / items / additionalPropertiesPrevious value: -trueNew value: +{} - removed
Output schema / properties / studies / items / propertiesRemoved value: -{ - "derivedSection": { - "additionalProperties": true, - "properties": { - "conditionBrowseModule": { - "additionalProperties": true, - "properties": { - "ancestors": { - "items": { - "additionalProperties": true, - "properties": { - "id": { - "type": "string" - }, - "term": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "browseBranches": { - "items": { - "additionalProperties": true, - "properties": { - "abbrev": { - "type": "string" - }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "browseLeaves": { - "items": { - "additionalProperties": true, - "properties": { - "asFound": { - "type": "string" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "relevance": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "meshes": { - "items": { - "additionalProperties": true, - "properties": { - "id": { - "type": "string" - }, - "term": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - } - }, - "type": "object" - }, - "interventionBrowseModule": { - "additionalProperties": true, - "properties": { - "ancestors": { - "items": { - "additionalProperties": true, - "properties": { - "id": { - "type": "string" - }, - "term": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "browseBranches": { - "items": { - "additionalProperties": true, - "properties": { - "abbrev": { - "type": "string" - }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "browseLeaves": { - "items": { - "additionalProperties": true, - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "relevance": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "meshes": { - "items": { - "additionalProperties": true, - "properties": { - "id": { - "type": "string" - }, - "term": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - } - }, - "type": "object" - }, - "miscInfoModule": { - "additionalProperties": true, - "properties": { - "versionHolder": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "hasResults": { - "type": "boolean" - }, - "protocolSection": { - "additionalProperties": true, - "properties": { - "armsInterventionsModule": { - "additionalProperties": true, - "properties": { - "arms": { - "items": { - "additionalProperties": true, - "properties": { - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "interventions": { - "items": { - "additionalProperties": true, - "properties": { - "armNames": { - "items": { - "type": "string" - }, - "type": "array" - }, - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - } - }, - "type": "object" - }, - "conditionsModule": { - "additionalProperties": true, - "properties": { - "conditions": { - "items": { - "type": "string" - }, - "type": "array" - }, - "keywords": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "contactsLocationsModule": { - "additionalProperties": true, - "properties": { - "locations": { - "items": { - "additionalProperties": true, - "properties": { - "city": { - "type": "string" - }, - "country": { - "type": "string" - }, - "state": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - } - }, - "type": "object" - }, - "descriptionModule": { - "additionalProperties": true, - "properties": { - "briefSummary": { - "type": "string" - }, - "detailedDescription": { - "type": "string" - } - }, - "type": "object" - }, - "designModule": { - "additionalProperties": true, - "properties": { - "designInfo": { - "additionalProperties": true, - "properties": { - "allocation": { - "type": "string" - }, - "interventionModel": { - "type": "string" - }, - "maskingInfo": { - "additionalProperties": true, - "properties": { - "masking": { - "type": "string" - } - }, - "type": "object" - }, - "primaryPurpose": { - "type": "string" - } - }, - "type": "object" - }, - "phases": { - "items": { - "type": "string" - }, - "type": "array" - }, - "studyType": { - "type": "string" - } - }, - "type": "object" - }, - "eligibilityModule": { - "additionalProperties": true, - "properties": { - "eligibilityCriteria": { - "type": "string" - }, - "healthyVolunteers": { - "type": "boolean" - }, - "minimumAge": { - "type": "string" - }, - "sex": { - "type": "string" - }, - "stdAges": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "identificationModule": { - "additionalProperties": true, - "properties": { - "acronym": { - "type": "string" - }, - "briefTitle": { - "type": "string" - }, - "nctId": { - "type": "string" - }, - "officialTitle": { - "type": "string" - }, - "orgStudyIdInfo": { - "additionalProperties": true, - "properties": { - "id": { - "type": "string" - } - }, - "type": "object" - }, - "organization": { - "additionalProperties": true, - "properties": { - "class": { - "type": "string" - }, - "fullName": { - "type": "string" - } - }, - "type": "object" - } - }, - "required": [ - "nctId" - ], - "type": "object" - }, - "sponsorCollaboratorsModule": { - "additionalProperties": true, - "properties": { - "collaborators": { - "items": { - "additionalProperties": true, - "properties": { - "class": { - "type": "string" - }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "type": "array" - }, - "leadSponsor": { - "additionalProperties": true, - "properties": { - "class": { - "type": "string" - }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "responsibleParty": { - "additionalProperties": true, - "properties": { - "type": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - }, - "statusModule": { - "additionalProperties": true, - "properties": { - "completionDateStruct": { - "additionalProperties": true, - "properties": { - "date": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "type": "object" - }, - "lastKnownStatus": { - "type": "string" - }, - "overallStatus": { - "type": "string" - }, - "primaryCompletionDateStruct": { - "additionalProperties": true, - "properties": { - "date": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "type": "object" - }, - "startDateStruct": { - "additionalProperties": true, - "properties": { - "date": { - "type": "string" - }, - "type": { - "type": "string" - } - }, - "type": "object" - } - }, - "type": "object" - } - }, - "type": "object" - } -} - added
Output schema / properties / studies / items / propertyNamesAdded value: +{ + "type": "string" +} - added
Output schema / properties / totalCount / descriptionAdded value: +"Total matching studies (first page only when countTotal=true)."
3 tool updates
v1.0.0- First observed
clinicaltrials_analyze_trends - First observed
clinicaltrials_get_study - First observed
clinicaltrials_search_studies
TDQS
Scored across 7 tools
Each tool targets a distinct operation: search, count, full record, results data, eligibility matching, field-value discovery, and field-name resolution. Overlap between metadata tools is minimal and clearly resolved by their descriptions.
All tools use a consistent clinicaltrials_ prefix with snake_case and a predictable verb_noun structure. The one slight variation, find_eligible, is still clear and follows the same prefix convention.
Seven tools is well-scoped for the ClinicalTrials.gov domain, with each tool covering a distinct and useful operation. No tool feels redundant or out of place.
The set covers search, count, full study retrieval, results data, field metadata, and patient eligibility matching. For a read-only clinical trials API, this provides a complete lifecycle without obvious dead ends.
Maintenance
Related MCP Connectors
Clinical trial search and status from ClinicalTrials.gov
Provide structured access to ClinicalTrials.gov data for searching, retrieving, and analyzing clin…
ClinicalTrials MCP — wraps ClinicalTrials.gov API v2 (free, no auth)
Search 36M+ PubMed biomedical articles and ClinicalTrials.gov studies.
Related MCP Servers
- AlicenseAqualityAmaintenanceProvides LLMs with structured access to critical biomedical databases including PubTator3 (PubMed/PMC), ClinicalTrials.gov, and MyVariant.info through the Model Context Protocol.35384 PyPI633MIT
- FlicenseNot gradedqualityDmaintenanceEnables searching and retrieving information from the ClinicalTrials.gov database of over 400,000 clinical studies, including trial details, eligibility criteria, locations, and results across 220+ countries.5-
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to search and access clinical trial data from ClinicalTrials.gov, including searching trials by keywords, retrieving detailed trial metadata by NCT ID, and managing trial data in CSV format for research and analysis.16-
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to search and analyze clinical trial data from ClinicalTrials.gov using both structured SQL queries for filtering trials by status, phase, and conditions, and semantic vector search for exploring detailed protocol information like exclusion criteria.-