1. Conduid
  2. AI
  3. Clinicaltrialsgov MCP Server
MCP server · AI

Clinicaltrialsgov MCP Server

Search ClinicalTrials.gov trials, retrieve study details and results, and match patients to eligible trials via MCP. STDIO or Streamable HTTP.

80Excellent

Scored 3 days ago · breakdown

About Clinicaltrialsgov MCP Server

Clinicaltrialsgov MCP Server is an MCP server published by cyanheads in the AI category: search ClinicalTrials.gov trials, retrieve study details and results, and match patients to eligible trials via MCP. STDIO or Streamable HTTP.

The repository has 99 stars and 24 forks, with the last commit 4 days ago. Recent commit activity is the strongest signal that reported issues will get attention.

Install

From source
git clone https://github.com/cyanheads/clinicaltrialsgov-mcp-server

This server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.

Ask AI

✦

Ask AI about Clinicaltrialsgov MCP Server

Powered by Claude · Grounded in docs

I know everything about Clinicaltrialsgov MCP Server. Ask me about installation, configuration, usage, or troubleshooting.

Security checks

Static checks derived from the repository 4 days ago. Heuristics on the source, not an audit.

  • ✓README presentThe repository ships documentation.
  • ✓License declaredUsable under a stated license.
  • ✓Tests presentA test suite exists in the repository.
  • ✓Dependencies pinnedA lockfile pins dependency versions.
  • ✓No dynamic code executionSource scan found no eval, dynamic Function, or shell execution.
  • !Scoped permissionsDoesn't declare a permission scope. Assume it can do anything its process can.

Releases

v2.10.0v2.10.0: Input normalization, candidate framing, summary-mode results · 14 Oct 2026Input normalization, candidate framing, summary-mode results BREAKING: phaseFilter entries naming no phase fail as `enum_invalid`; case, spacing, and `,`/`|` variants normalize to canonical phases (#144) BREAKING: find_eligible rejects…
v2.9.11v2.9.11: mcp-ts-core 0.13.12 adoption and template catch-up · 5 Oct 2026mcp-ts-core 0.13.12 adoption and template catch-up mcp-ts-core ^0.13.6 → ^0.13.12 — error `data` no longer carries stack traces (0.13.7) or request context (0.13.8); an argument sent as a JSON-stringified object, or an integer sent for a…
v2.9.10v2.9.10: per-group adverse events, distance-ranked site admission · 22 Sep 2026per-group adverse events, distance-ranked site admission `get_study_results` summary-mode adverse events report per-group `byGroup` counts against an `eventGroups` roster, ranked by the largest single group, not a pooled…
v2.9.9v2.9.9: mcp-ts-core 0.13.6, search results flags, input normalization · 22 Sep 2026mcp-ts-core 0.13.6, search results flags, input normalization `search_studies` compact index gains `hasResults`, `startDate`, `primaryCompletionDate` (#139) `statusFilter` and NCT ID inputs normalize case/spacing variants before the…
v2.9.8v2.9.8: mcp-ts-core 0.13.4, declared stateless session mode · 18 Sep 2026mcp-ts-core 0.13.4, declared stateless session mode Declared stateless session mode — `createApp` now sets `sessionMode: 'stateless'`; `.env.example` sets `MCP_SESSION_MODE=stateless` actively, and the README config table documents it; an…

README

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

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 600K+ clinical trial studies. Search trials, fetch full study records and posted results, discover field names and valid values, and match patient demographics to candidate 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
clinicaltrials_search_studies Search studies with full-text and field-specific queries, status/phase/geographic filters, pagination, sorting, and field selection
clinicaltrials_get_study_record Fetch a single study by NCT ID — full protocol record with optional location/outcome/reference caps
clinicaltrials_get_study_count Fast total study count for a query, without fetching data
clinicaltrials_get_field_values Discover valid values for API fields, with per-value study counts
clinicaltrials_get_field_definitions Resolve valid field names — keyword search, path drill-down, or top-level overview
clinicaltrials_get_study_results Fetch posted results — outcomes, adverse events, participant flow, baseline — for completed studies
clinicaltrials_find_eligible Match patient demographics and conditions to candidate recruiting trials, without checking inclusion/exclusion criteria

Resources

Resource Description
clinicaltrials://{nctId} Fetch a single clinical study by NCT ID as JSON, with capped lists and results replaced by counts

Prompts

Prompt Description
analyze_trial_landscape Guides a data-driven clinical trial landscape analysis using the count and search tools

Capability reference

clinicaltrials_search_studies tool

  • Free-text query plus field-specific conditionQuery / interventionQuery / locationQuery / sponsorQuery / titleQuery / outcomeQuery, statusFilter / phaseFilter enums (case and spacing variants accepted; a phaseFilter entry that names no phase, such as an OR expression, fails as enum_invalid), advancedFilter (AREA[FieldName]value / RANGE[min, max]), and geoFilter (distance(lat,lon,radius) with a mi/km suffix); pageSize 1–200 (default 10), pageToken cursor, sort on up to 2 fields
  • Returns a compact per-study index by default (nctId, briefTitle, overallStatus, phases, enrollmentCount, hasResults, …); fields (PascalCase leaves) selects a full-fidelity projection — full records run ~70KB
  • Typed 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 optional locationLimit (≤500), outcomeLimit / referenceLimit (≤100), and nearLocation (lat, lon, radiusMi) to bound and sort locations
  • filtersApplied reports upstream totals when a cap trims a list; resultsSection is replaced by resultsSummary counts. Typed errors: study_not_found, rate_limited

clinicaltrials_get_study_count tool

  • Same query and filter surface as clinicaltrials_search_studies, returning only totalCount — no study data fetched
  • Typed 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), or min / max / avg for numeric and date fields and trueCount / falseCount for booleans
  • multiValued flags 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 (keyword query, limit ≤100, default 20), drill (dot-notation path), or overview — resolves the PascalCase names accepted by fields, advancedFilter, sort, and clinicaltrials_get_field_values
  • Typed errors: blank_value, mode_mismatch, mode_requires, path_not_found, rate_limited

clinicaltrials_get_study_results tool

  • Up to 20 nctIds per call; sections (outcomes, adverseEvents, participantFlow, baseline, moreInfo), summary to condense a result set that can exceed 500KB per study, and outcomeLimit (≤100) / adverseEventLimit (≤500) with resumable outcomeOffset / seriousEventOffset / otherEventOffset
  • Per-study fetchErrors / studiesWithoutResults instead of a whole-batch failure, and canonicalNctId when 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 (country required, state / city optional), healthyVolunteer, recruitingOnly (default true), maxResults (≤50), locationLimit (≤500)
  • Each candidate's locations are bounded to the sites matching the requested location, plus one recruiting site when none of those is open; funnel reports match counts per filter stage (condition → +location → +demographics)
  • Candidates are matched on age, sex, location, recruitment status, and a fuzzy condition search; a notice on every non-empty response says inclusion/exclusion criteria were not checked and points to clinicaltrials_get_study_record for review
  • 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 arguments
  • Results data is replaced by resultsSummary counts; truncated and filtersApplied disclose what was capped, with retrieval naming the tools that fetch the full data
  • Typed errors: study_not_found, rate_limited

analyze_trial_landscape prompt

  • Arguments: topic required; focusAreas (comma-separated) optional
  • Returns 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 correction; a comma- or pipe-joined fields entry ("NCTId,BriefTitle") is split into separate names first, each name kept once
  • Detects 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
  • Excludes ClinicalTrials.gov's "unknown" enrollment sentinel (99999999) from searches and counts by default — includeUnknownEnrollment brings it back, and an nctIds lookup never filters it

Agent-friendly output:

  • Provenance — clinicaltrials_search_studies / clinicaltrials_get_study_count / clinicaltrials_find_eligible echo searchCriteria on every call, including sentinelFilterActive when the default unknown-enrollment exclusion applies, and clinicaltrials_get_study_results names canonicalNctId when a previous (alias) ID resolves to a different study
  • Graceful partial failure — clinicaltrials_get_study_results returns per-study fetchErrors / studiesWithoutResults rows instead of failing the whole batch when one ID is malformed or lacks results
  • Discriminated output — typed error reason codes per tool (study_not_found, blank_value, offset_not_applicable, …), and bounded lists (filtersApplied, locationSummary) carry a next*Offset only when more remains, so callers branch on presence instead of parsing text
  • Response shaping — clinicaltrials_search_studies and clinicaltrials_find_eligible return a compact per-study index or location-bounded set by default instead of the ~70KB full record, escalating to full fidelity only via fields or clinicaltrials_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/mcp

Prerequisites

Installation

  1. Clone the repository:
git clone https://github.com/cyanheads/clinicaltrialsgov-mcp-server.git
  1. Navigate into the directory:
cd clinicaltrialsgov-mcp-server
  1. Install dependencies:
bun install

Configuration

All configuration is optional — the server works with defaults and no API keys.

Variable Description Default
CT_API_BASE_URL ClinicalTrials.gov API base URL. https://clinicaltrials.gov/api/v2
CT_REQUEST_TIMEOUT_MS Per-request timeout in milliseconds. 30000
CT_MAX_PAGE_SIZE Maximum page size cap. 200
MCP_TRANSPORT_TYPE Transport: stdio or http. stdio
MCP_HTTP_PORT Port for HTTP server. 3010
MCP_SESSION_MODE HTTP session mode: stateless, stateful, or auto. stateless
MCP_AUTH_MODE Auth mode: none, jwt, or oauth. none
MCP_LOG_LEVEL Log level (RFC 5424). info
LOGS_DIR Directory for log files (Node.js only). <project-root>/logs
OTEL_ENABLED Enable OpenTelemetry tracing. false
OTEL_EXPORTER_OTLP_ENDPOINT OTLP base URL; traces export to /v1/traces, metrics to /v1/metrics. Unset exports nothing. —
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT Opt-in OTLP log export; the base endpoint never enables it. —
LOG_TOOL_FAILURE_PAYLOADS Log each failed tool call's arguments and result, redacted by key name and capped at LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES (default 16384). A secret inside a free-form value is not redacted. false

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:stdio
    
  • Run 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-server

The 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
src/index.ts createApp() entry point — registers tools/resources/prompts and inits the ClinicalTrials.gov service.
src/config Server-specific environment variable parsing and validation with Zod.
src/mcp-server/tools Tool definitions (*.tool.ts).
src/mcp-server/resources Resource definitions (*.resource.ts).
src/mcp-server/prompts Prompt definitions (*.prompt.ts).
src/services/clinical-trials ClinicalTrials.gov REST API v2 client — retry, rate limiting, field search, types.
tests/ Unit and integration tests.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for request-scoped logging, no console calls
  • Register new tools and resources via the barrels in src/mcp-server/*/definitions/index.ts
  • Validate 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 test

License

Apache-2.0 — see LICENSE for details.

README fetched from the repository 4 days ago. The original is authoritative.

Questions

About Clinicaltrialsgov MCP Server

How do I install Clinicaltrialsgov MCP Server?

No package has been published for this server, so install it from source: clone the repository and follow its README.

Is Clinicaltrialsgov MCP Server safe to use with an AI agent?

Its trust score is 80 out of 100 (excellent). It passes 5 of the 6 static security checks run so far; the failures are listed above. It has no ConduID identity yet, so agent calls to it are not receipted.

Is Clinicaltrialsgov MCP Server still maintained?

Yes — the latest release is v2.10.0 (14 Oct 2026), and the last commit was 4 days ago. The repository has 99 stars and 6 open issues.