AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP unreviewed MIT Self-run

Clinicaltrials Mcp Server

mcp-blencorp-clinicaltrials-mcp-server · by blencorp

MCP server for ClinicalTrials.gov (by Blen). Unaffiliated with NIH/NLM.

No reviews yet
0 installs
39 views
0.0% view→install

Install

$ agentstack add mcp-blencorp-clinicaltrials-mcp-server

Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Pipes remote content directly into a shell (remote code execution).

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution Used
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Reliability & compatibility

Not yet reviewed
0 installs to date
no reviews yet
5mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Clinicaltrials Mcp Server? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

ClinicalTrials.gov Explorer (by BLEN)

MCP server for ClinicalTrials.gov. Exposes the v2 REST API as a typed TypeScript SDK that the model calls from inside a secure sandbox, following Cloudflare's "code mode" pattern.

> Display name in the Claude directory: ClinicalTrials.gov Explorer (by BLEN). > Unaffiliated with NIH / NLM / ClinicalTrials.gov. Data retrieved live from > .


Table of contents

  • [What "code mode" means here](#what-code-mode-means-here)
  • [Quickstart — use it with Claude Desktop (npx)](#quickstart--use-it-with-claude-desktop-npx)
  • [Build an MCPB desktop extension](#build-an-mcpb-desktop-extension)
  • [Local development](#local-development)
  • [Prerequisites](#prerequisites)
  • [Troubleshooting: No sandbox executor available](#troubleshooting-no-sandbox-executor-available)
  • [Setup](#setup)
  • [Running the server locally](#running-the-server-locally)
  • [Point Claude Desktop at your dev checkout (stdio)](#point-claude-desktop-at-your-dev-checkout-stdio)
  • [Useful scripts](#useful-scripts)
  • [Architecture at a glance](#architecture-at-a-glance)
  • [MCP tools](#mcp-tools)
  • [Configuration reference](#configuration-reference)
  • [Sandbox](#sandbox)
  • [Remote (hosted) mode](#remote-hosted-mode)
  • [AWS deploy](#aws-deploy)
  • [Directory submission](#directory-submission)
  • [Testing](#testing)
  • [Behavior when no sandbox is installed](#behavior-when-no-sandbox-is-installed)
  • [Data handling](#data-handling)
  • [Contributing, support, license](#contributing-support-license)

What "code mode" means here

Rather than exposing each API operation as a separate MCP tool (the usual pattern, which quickly blows up the LLM's context), this server ships three tools:

| Tool | Purpose | |---|---| | search_api | BM25 search over endpoints + study-field docs. Returns a TypeScript snippet the model should paste. | | describe_schema | Look up study-field docs by exact path or prefix. | | execute | Run a short async TypeScript body against a typed ctgov SDK in a sandboxed V8 isolate (or Deno fallback). |

The full ClinicalTrials.gov surface fits in a few hundred tokens this way. The model writes one function, chains calls, filters locally, and returns results.


Quickstart — use it with Claude Desktop (npx)

Prerequisites

  • Node.js 20.10+ (22.x recommended when you want the smoothest

isolated-vm experience)

  • One sandbox runtime — the execute tool needs somewhere to run

untrusted code. You need either:

  • isolated-vm (installed automatically by pnpm install / npm install

when prebuilt binaries exist for your platform, or when a C toolchain + Python 3 are available for a native build), or

  • the Deno CLI on PATH as a fallback

(brew install deno on macOS, curl -fsSL https://deno.land/install.sh | sh on Linux/WSL).

If neither is present, the server will start but refuse execute calls with No sandbox executor available. See [Troubleshooting](#troubleshooting-no-sandbox-executor-available) for the fix.

# One-time sanity check
npx -y @blen/clinicaltrial-mcp-server --version

Add to your Claude Desktop config (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json, Windows: %APPDATA%\Claude\claude_desktop_config.json):

{
  "mcpServers": {
    "ctgov": {
      "command": "npx",
      "args": ["-y", "@blen/clinicaltrial-mcp-server"]
    }
  }
}

Restart Claude Desktop; the tools appear under the ClinicalTrials.gov Explorer entry.


Build an MCPB desktop extension

This repo can now generate a Claude Desktop extension bundle (.mcpb) using Anthropic's MCPB workflow. The default bundle is cross-platform for Claude Desktop on macOS and Windows: it embeds the Deno helpers needed by the execute sandbox so end users do not have to install Deno themselves.

Build the extension:

pnpm install
pnpm mcpb:pack

That usually produces:

.mcpb/dist/clinicaltrial-mcp-server-.mcpb

Useful commands:

pnpm mcpb:prepare   # stage a clean production bundle under .mcpb/stage
pnpm mcpb:validate  # validate the generated manifest with the official CLI
pnpm mcpb:pack      # validate + pack the final .mcpb archive

Notes:

  • The pack step requires a local Deno binary on the build machine. The script

copies the host binary into the extension bundle, downloads matching helpers for the other bundled targets, and points CTGOV_DENO_ROOT at the packaged helper directory.

  • The default target set is darwin-arm64, darwin-x64, and win32-x64, so

the same .mcpb works in Claude Desktop on macOS and Windows.

  • To narrow or customize the bundle, set CTGOV_MCPB_TARGETS, for example:

CTGOV_MCPB_TARGETS=darwin-arm64,win32-x64 pnpm mcpb:pack.

  • Installation in Claude Desktop follows Anthropic's MCPB flow:

double-click the file, drag it into Claude Desktop, or use Developer -> Extensions -> Install Extension.


Local development

Clone the repo, install, run tests, and point Claude at your local checkout.

Prerequisites

  • Node.js 20.10+ (22.x recommended for native isolated-vm)
  • pnpm 10.33+ (corepack enable && corepack prepare pnpm@10.33.0 --activate)
  • A sandbox runtime — at least one of:
  • isolated-vm (default, fastest). Native addon; installs via pnpm install.

Prebuilt binaries cover common platforms; when they don't, a C toolchain + Python 3 is required (build-essential on Debian/Ubuntu; xcode-select --install on macOS).

  • Deno — the subprocess fallback. Install with

brew install deno / curl -fsSL https://deno.land/install.sh | sh.

  • (Optional) Docker + BuildKit for the container build
  • (Optional) Terraform ≥ 1.7 and AWS CLI v2 for the AWS deploy module
Troubleshooting: No sandbox executor available

If pnpm test prints CtGovError: No sandbox executor available. Install isolated-vm (...) or the Deno CLI (...), your machine has neither sandbox configured. Pick one:

Easiest — install Deno (works on every platform, no toolchain needed):

# macOS
brew install deno
# Linux / WSL
curl -fsSL https://deno.land/install.sh | sh

Then re-run pnpm test. The sandbox-requiring tests will pick up Deno automatically; you'll see them pass instead of skip.

Alternative — make isolated-vm build locally:

# macOS (Apple Silicon or Intel)
xcode-select --install            # installs clang + headers
# pnpm's prebuild fallback will invoke node-gyp against system Python 3

# Debian / Ubuntu
sudo apt-get install -y build-essential python3

# Then rebuild just this native dep:
pnpm rebuild isolated-vm
node -e 'require("isolated-vm"); console.log("ok")'

If pnpm install finished with Ignored build scripts: isolated-vm — pnpm's approve-builds policy blocked the native compile. This repo ships pnpm-workspace.yaml with onlyBuiltDependencies: [isolated-vm] which should allow it; if it still complains, run pnpm approve-builds once and re-run pnpm install.

Sandbox-requiring test suites (sandbox.spec.ts, sandboxChaos.spec.ts, httpServer.spec.ts, authHttp.spec.ts, embeddedEndToEnd.spec.ts) skip gracefully when neither sandbox is available so the rest of the suite stays green.

Setup

git clone https://github.com/blencorp/claude-playground.git
cd claude-playground
cp .env.example .env               # edit values; see Configuration reference
pnpm install                        # builds isolated-vm via node-gyp
pnpm typecheck                      # strict TS pass
pnpm lint                           # eslint
pnpm test                           # ~60 tests, stdio | Streamable HTTP + OAuth"]
    Server["buildMcpServertools: search_api, describe_schema, execute"]
    Supervisor["SubjectQuota (per-sub + global 10 rps)HttpClient: undici, LRU, retry, zod, audit, stale-cache"]
    Sandbox["Sandbox (isolated-vm | deno)AST allow-list (acorn)ctgov.* SDK via RPC only"]
    CTGov[("ClinicalTrials.gov v2")]

    Transport --> Server
    Server --> Supervisor
    Supervisor --> Sandbox
    Supervisor --> CTGov

Details in [docs/ARCHITECTURE.md](./docs/ARCHITECTURE.md).


MCP tools

search_api(query, k?)

Semantic BM25 search over the 9 API endpoints and the curated study-field dictionary. Returns a TypeScript snippet the model should paste plus a short summary of hit counts.

describe_schema(path? | prefix?)

Lookup for study-data fields by exact dotted path (e.g. protocolSection.eligibilityModule.eligibilityCriteria) or by prefix (e.g. protocolSection.designModule).

execute(code, timeoutMs?, memoryMb?)

Wraps the submitted body as async (ctgov) => { } and runs it in the sandbox. The return value is JSON-serialized and returned. The SDK surface inside the sandbox:

ctgov.studies.search(params)        // GET /studies
ctgov.studies.searchAll(params, o?) // async iterator over pages
ctgov.studies.get(nctId, params?)   // GET /studies/{nctId}
ctgov.studies.metadata(params?)     // GET /studies/metadata
ctgov.studies.searchAreas()         // GET /studies/search-areas
ctgov.studies.enums()               // GET /studies/enums
ctgov.stats.size()                  // GET /stats/size
ctgov.stats.fieldValues({fields})   // GET /stats/field/values
ctgov.stats.fieldSizes({fields})    // GET /stats/field/sizes
ctgov.version()                     // GET /version

Five worked examples live in [examples/](./examples).


Configuration reference

All configuration is via environment variables. Copy [.env.example](./.env.example) to .env and edit.

Transport / runtime

| Variable | Default | Description | |---|---|---| | PORT | 8080 | HTTP port (used with --http). | | HOST | 0.0.0.0 | HTTP bind address. | | CTGOV_LOG_LEVEL | info | debug / info / warn / error. | | CTGOV_SANDBOX | auto | isolate / deno / auto. Equivalent to --sandbox. | | CTGOV_DENO_PATH | (PATH lookup) | Explicit path to the deno binary for the fallback executor. | | CTGOV_DENO_ROOT | (none) | Directory containing bundled Deno helpers laid out as -/deno(.exe); mainly used by the packaged MCPB bundle. |

Auth

| Variable | Default | Description | |---|---|---| | CTGOV_AUTH_PROVIDER | none | clerk / workos / auth0 / generic-oidc / embedded / none. | | CTGOV_AUTH_ISSUER | (none) | Authorization server URL. Required when provider ≠ none. | | CTGOV_AUTH_JWKS_URL | derived | Defaults to ${issuer}/.well-known/jwks.json (or ${issuer}/as/jwks.json for embedded). | | CTGOV_AUTH_RESOURCE | https://clinicaltrials.mcp.blencorp.com/mcp | RFC 8707 audience / our resource identifier. | | CTGOV_AUTH_SCOPES | ctgov.read | Whitespace- or comma-separated list. |

Network / rate limiting

| Variable | Default | Description | |---|---|---| | CTGOV_TRUST_PROXY | (off) | Set to 1 when the server sits behind a known reverse proxy (Railway, Cloudflare, ALB). The per-IP limiter will then read the first entry of x-forwarded-for instead of the socket peer. | | CTGOV_IP_RPS | 5 | Sustained per-IP request rate on /mcp and /as/*. Health checks are exempt. | | CTGOV_IP_BURST | 20 | Burst capacity per IP. Requests over the bucket get 429 with Retry-After. | | CTGOV_MAX_SESSIONS | 500 | Upper bound on concurrent MCP sessions (idle-swept every minute). |

Embedded AS (self-host only)

| Variable | Description | |---|---| | CTGOV_EMBEDDED_USERS | alice:pass1,bob:pass2 — HTTP Basic credentials resolved during /as/authorize. |

Tests / scripts

| Variable | Description | |---|---| | CTGOV_LIVE | Set to 1 to enable test/liveIntegration.spec.ts (hits real CT.gov). | | CTGOV_BASE | Override the upstream base URL for the regen:sdk and verify:schema scripts. |


Sandbox

Auto-selects isolated-vm (V8 isolate, native addon) and falls back to a deno subprocess with --no-prompt --allow-none --no-npm --no-remote when the native addon isn't available. Both enforce identical policy:

  • No network, no filesystem, no env, no FFI, no subprocess.
  • AST preflight (acorn) rejects direct escape hatches like import,

dynamic import(), eval, new Function, process, __host, and unsafe prototype access before execution. The runtime sandbox remains the primary security boundary.

  • 15 s wall-clock, 64 MB heap (isolate mode); per-call overrides available

via timeoutMs / memoryMb.

  • Only capability: the ctgov.* binding proxied over host RPC.

Force a specific executor:

clinicaltrial-mcp-server --sandbox isolate    # require isolated-vm
clinicaltrial-mcp-server --sandbox deno       # require deno on PATH
clinicaltrial-mcp-server --sandbox auto       # default

Remote (hosted) mode

Run the same server over the MCP Streamable HTTP transport with a real OAuth Authorization Server in front.

With Clerk (production default)

export CTGOV_AUTH_PROVIDER=clerk
export CTGOV_AUTH_ISSUER=https://clerk.blencorp.com
export CTGOV_AUTH_RESOURCE=https://clinicaltrials.mcp.blencorp.com/mcp
export CTGOV_AUTH_SCOPES=ctgov.read
node dist/bin.js --http --port 8080

Clerk (or WorkOS / Auth0 / any OIDC AS) must be configured with RFC 7591 Dynamic Client Registration so Claude can self-register, and the audience / resource set to https://clinicaltrials.mcp.blencorp.com/mcp (RFC 8707).

With the built-in embedded AS (self-host)

export CTGOV_AUTH_PROVIDER=embedded
export CTGOV_AUTH_ISSUER=https://your.host     # must match where this server is reachable
export CTGOV_AUTH_RESOURCE=https://your.host/mcp
export CTGOV_EMBEDDED_USERS=alice:wonderland
node dist/bin.js --http --port 8080

Endpoints exposed:

| Path | Purpose | |---|---| | POST /mcp | MCP Streamable HTTP (stateful per-session transport). | | GET /healthz, /readyz | ALB health checks. | | GET /.well-known/oauth-protected-resource | RFC 9728 PRM. | | GET /.well-known/oauth-authorization-server | RFC 8414 AS metadata (proxied from issuer, or served directly by the embedded AS). | | POST /as/register | (embedded) RFC 7591 DCR. | | GET /as/authorize | (embedded) OAuth 2.1 + PKCE S256. | | POST /as/token | (embedded) authorizationcode / refreshtoken grants. | | GET /as/jwks.json | (embedded) public JWKS. |

A missing/invalid bearer returns 401 with WWW-Authenticate: Bearer realm="…", resource_metadata="…" pointing at the PRM.


AWS deploy

Terraform module at [deploy/aws/](./deploy/aws/README.md) stands up:

ECS Fargate + ALB + ACM + Route 53 + Secrets Manager + CloudWatch Logs + WAFv2

on clinicaltrials.mcp.blencorp.com, with a GitHub Actions OIDC deployer role. The container is built from [deploy/Dockerfile](./deploy/Dockerfile) (multi-stage, non-root, tini, isolated-vm compiled in).

cd deploy/aws
cp terraform.tfvars.example terraform.tfvars   # edit clerk_issuer, CIDRs, etc.
terraform init
terraform apply

# Build & push first image
ACCOUNT=$(aws sts get-caller-identity --query Account --output text)
ECR=$(terraform output -raw ecr_repository_url)
aws ecr get-login-password --region us-east-1 | \
  docker login --username AWS --password-stdin "$ACCOUNT.dkr.ecr.us-east-1.amazonaws.com"
docker buildx build --platform linux/amd64 -t "$ECR:v0.1.0-alpha.0" -f deploy/Dockerfile . --push
aws ecs update-service --cluster clinicaltrial-mcp-server --service clinicaltrial-mcp-server --force-new-deployment

Subsequent deploys happen automatically from [.github/workflows/deploy.yml](./.github/workflows/deploy.yml) on pushes to main.


Railway deploy (alternative)

Railway can host the same container directly from [deploy/Dockerfile](./deploy/Dockerfile). Railway terminates TLS, manages th

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.