clinicaltrialsgov-mcp-server
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-serverMatch a 58-year-old with type 2 diabetes to recruiting trials in Texas"
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
Search 600K+ studies on ClinicalTrials.gov, the US National Library of Medicine's trial registry. Fetch full study records and posted results, discover fields and valid values, and match a patient's profile to recruiting trials. No API key required.
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 candidate recruiting trials, without checking inclusion/exclusion criteria |
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: clinicaltrialsgov-mcp-server
Capability reference
clinicaltrials_search_studies tool
Free-text
queryplus field-specificconditionQuery/interventionQuery/locationQuery/sponsorQuery/titleQuery/outcomeQuery,statusFilter/phaseFilterenums (case and spacing variants accepted),advancedFilter(AREA[FieldName]value/RANGE[min, max]), andgeoFilter(distance(lat,lon,radius)with ami/kmsuffix);pageSize1–200 (default 10),pageTokencursor,sorton up to 2 fieldsReturns a compact per-study index by default (
nctId,briefTitle,overallStatus,phases,enrollmentCount,hasResults, …);fields(PascalCase leaves) selects a full-fidelity projection — full records run ~70KBTyped errors:
blank_value,ids_not_found,field_invalid,enum_invalid,query_parse_error,geo_invalid,sort_invalid,page_token_invalid,rate_limited
clinicaltrials_get_study_record tool
Full protocol record by
nctId, with optionallocationLimit(≤500),outcomeLimit/referenceLimit(≤100), andnearLocation(lat,lon,radiusMi) to bound and sort locationsfiltersAppliedreports upstream totals when a cap trims a list;resultsSectionis replaced byresultsSummarycounts. Typed errors:study_not_found,rate_limited
clinicaltrials_get_study_count tool
Same query and filter surface as
clinicaltrials_search_studies, returning onlytotalCount— no study data fetchedTyped errors:
blank_value,field_invalid,enum_invalid,query_parse_error,rate_limited
clinicaltrials_get_field_values tool
One or more PascalCase
fields(e.g.OverallStatus,Phase) — returns each field's type and top values with study counts (capped at 250 by the API), ormin/max/avgfor numeric and date fields andtrueCount/falseCountfor booleansmultiValuedflags fields whose per-value counts can sum above the study total. Typed errors:blank_value,field_invalid,rate_limited
clinicaltrials_get_field_definitions tool
mode:search(keywordquery,limit≤100, default 20),drill(dot-notationpath), oroverview— resolves the PascalCase names accepted byfields,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
nctIdsper call;sections(outcomes,adverseEvents,participantFlow,baseline,moreInfo),summaryto condense a result set that can exceed 500KB per study, andoutcomeLimit(≤100) /adverseEventLimit(≤500) with resumableoutcomeOffset/seriousEventOffset/otherEventOffsetPer-study
fetchErrors/studiesWithoutResultsinstead of a whole-batch failure, andcanonicalNctIdwhen an alias ID resolves to another study. Typed errors:blank_value,offset_not_applicable,rate_limited
clinicaltrials_find_eligible tool
age,sex(FEMALE/MALE/ALL),conditions[],location(countryrequired,state/cityoptional),healthyVolunteer,recruitingOnly(default true),maxResults(≤50),locationLimit(≤500)Matches on age, sex, location, recruitment status, and a fuzzy condition search;
funnelreports match counts per filter stage, and anoticesays inclusion/exclusion criteria were not checked (useclinicaltrials_get_study_recordto review them)Typed 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 and HTML error pages
Auto-corrects field names passed to
fields/sort(case, whitespace, legacy aliases likeRecruitmentStatus→OverallStatus) and logs each correctionGeographic proximity search and nearest-site re-ranking, with no geocoding dependency
Excludes the "unknown" enrollment sentinel (
99999999) from searches and counts by default;includeUnknownEnrollmentbrings it back
Agent-friendly output:
Provenance — search, count, and eligibility tools echo
searchCriteria;clinicaltrials_get_study_resultsnamescanonicalNctIdwhen an alias ID resolves to another studyGraceful partial failure —
clinicaltrials_get_study_resultsreturns per-studyfetchErrors/studiesWithoutResultsinstead of failing the whole batchTyped errors — each tool returns
reasoncodes (study_not_found,blank_value, …), and bounded lists carry anext*Offsetonly when more remainsResponse shaping — search and eligibility return a compact index by default instead of the ~70KB full 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. |
|
| HTTP session mode: |
|
| Auth mode: |
|
| Log level (RFC 5424). |
|
| Directory for log files (Node.js only). |
|
| Enable OpenTelemetry tracing. |
|
| OTLP base URL for traces and metrics. | — |
| OTLP endpoint for log export. | — |
| Log each failed tool call's arguments and result, redacted by key name and capped at |
|
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.
This server cannot be deployed
Maintenance
Related MCP Connectors
Search ClinicalTrials.gov: find studies, retrieve results, match patients to candidate trials.
Provide structured access to ClinicalTrials.gov data for searching, retrieving, and analyzing clin…
Search and read ClinicalTrials.gov studies, sites and outcomes.
Search and analyze ClinicalTrials.gov: trials by keyword/condition/drug/status/phase, one study's…
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables searching ClinicalTrials.gov studies with filters, fetching full study records and posted results, discovering API field names and values, and matching patient demographics to candidate recruiting trials. Runs over STDIO or Streamable HTTP against a public, read-only API requiring no authentication.725 npmApache 2.0
- AlicenseNot gradedqualityAmaintenanceEnables searching the ClinicalTrials.gov registry, retrieving full study records and posted results, exploring valid field names and values, and matching patient demographics to candidate recruiting trials. Runs over STDIO or Streamable HTTP, with no authentication required.725 npmApache 2.0
- AlicenseNot gradedqualityAmaintenanceEnables searching ClinicalTrials.gov studies, retrieving full study records and posted results, discovering valid field names and values, and matching patient demographics and conditions to candidate recruiting trials. Runs over STDIO or Streamable HTTP against the public, read-only ClinicalTrials.gov REST API v2 with no authentication required.725 npmApache 2.0
- AlicenseNot gradedqualityAmaintenanceEnables searching the ClinicalTrials.gov registry, retrieving full study records and posted results, discovering valid field names and values, and matching patient demographics to candidate recruiting trials. Runs over STDIO or Streamable HTTP with no authentication required.725 npmApache 2.0