# Clinical Trials and Drug Data MCP Server (`mrbridge/clinical-pharma-mcp`) Actor

Clinical trial, drug label and chemistry data for Claude, ChatGPT and Cursor: one MCP server, 13 read-only tools. Search studies and posted results, count adverse event reports, check U.S. recalls, shortages and approvals, and compare compounds. For research, not medical advice.

- **URL**: https://apify.com/mrbridge/clinical-pharma-mcp.md
- **Developed by:** [MrBridge](https://apify.com/mrbridge) (community)
- **Categories:** MCP servers, AI, Education
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 read operations

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Clinical Trials and Drug Data MCP Server

Clinical Trials and Drug Data MCP Server connects Claude, ChatGPT, Cursor and any MCP client to three public U.S. government sources through 13 read-only tools. It searches the ClinicalTrials.gov registry and reads the results that studies posted. Through openFDA it counts the adverse event reports sent to FDA and reads drug labels, recalls, shortages and approval records, while PubChem supplies compound lookups and comparisons.

Ask Claude "When was atorvastatin first approved, and under which application?" and it calls `pharma_get_drug_approvals`. The answer names NDA020702, first approved on 1996-12-17, with its products and their marketing status, plus a link to the record. A follow-up such as "any valsartan recalls?" goes to `pharma_search_recalls`, which lists enforcement reports newest first, each with its class and reason.

> Informational only, not medical advice. Do not use this server to make decisions about diagnosis, treatment or medication: talk to a qualified health professional. This is an independent server, not affiliated with or endorsed by the U.S. Food and Drug Administration, the National Institutes of Health, the National Library of Medicine or NCBI.

### What this server exposes

This server gives an AI client 13 read-only tools over three public U.S. government sources. From ClinicalTrials.gov it searches registered studies by condition, intervention, sponsor, place, status and phase, reads one study record, lists its sites and returns the results a study posted (participant flow, outcome measures, adverse events by group). From openFDA it counts the adverse event reports sent to FDA for a drug (by reaction, outcome, seriousness, sex, age group, reporter, country or year), finds and reads drug labels, searches drug, device and food recalls, checks drug shortage records and reads Drugs@FDA approval records. From PubChem it reads the identity and computed properties of a compound, searches compounds by name, similarity, substructure or formula, and compares up to ten of them. No account or API key is needed from the user. Every answer names its source and carries a not-medical-advice notice. This server is not affiliated with or endorsed by the NLM, the NIH, NCBI or FDA.

### Tools

| Tool | What it answers | Billed event |
|---|---|---|
| `pharma_search_trials` | Search clinical trials on ClinicalTrials.gov | `tool-read` |
| `pharma_get_trial` | Get one clinical trial record | `tool-read` |
| `pharma_list_trial_locations` | List the sites of a clinical trial | `tool-read` |
| `pharma_get_trial_results` | Get the posted results of a clinical trial | `tool-read` |
| `pharma_drug_adverse_events` | Count FDA adverse event reports for a drug | `tool-read` |
| `pharma_search_drug_labels` | Search FDA drug labels | `tool-read` |
| `pharma_get_drug_label` | Read sections of an FDA drug label | `tool-read` |
| `pharma_search_recalls` | Search FDA recall enforcement reports | `tool-read` |
| `pharma_check_drug_shortages` | Check FDA drug shortage records | `tool-read` |
| `pharma_get_drug_approvals` | Get FDA drug approval records (Drugs@FDA) | `tool-read` |
| `pharma_get_compound` | Get a chemical compound from PubChem | `tool-action` |
| `pharma_search_compounds` | Search chemical compounds in PubChem | `tool-read` |
| `pharma_compare_compounds` | Compare chemical compounds side by side | `tool-action` |

#### `pharma_search_trials`: Search clinical trials on ClinicalTrials.gov

Use this when you need registered clinical studies for a condition, a drug or other intervention, a sponsor or a place: which trials exist, which are recruiting, in which phase, with how many participants, and whether results are posted. Do not use for one known trial (pharma_get_trial), its sites (pharma_list_trial_locations) or its results (pharma_get_trial_results). The data is informational: it does not recommend any trial or treatment. Parameters (at least one search text): `condition` (e.g. "type 2 diabetes"), `intervention` (e.g. "semaglutide"), `terms` (other words, e.g. "obesity"), `sponsor` (e.g. "Novo Nordisk"), `location` (e.g. "Boston, Massachusetts"). Filters: `status` (list, e.g. \["RECRUITING"]), `phase` (list of EARLY_PHASE1, PHASE1, PHASE2, PHASE3, PHASE4, NA), `study_type` (INTERVENTIONAL, OBSERVATIONAL, EXPANDED_ACCESS), `with_results_only`. `sort`: relevance (default), last_updated, newest, start_date or enrollment. `limit` 1 to 25 (default 10, at most 10 in detailed mode), `offset` within the first 250 results, `response_format` ("detailed" adds the brief summary, sponsor class and completion date).

| Parameter | Type | Required | Example |
|---|---|---|---|
| `condition` | string | no | `"type 2 diabetes"` |
| `intervention` | string | no | `"semaglutide"` |
| `terms` | string | no | `"obesity"` |
| `sponsor` | string | no | `"Novo Nordisk"` |
| `location` | string | no | `"Boston, Massachusetts"` |
| `status` | array of string | no | `["RECRUITING"]` |
| `phase` | array of string | no | `["PHASE3"]` |
| `study_type` | "INTERVENTIONAL" or "OBSERVATIONAL" or "EXPANDED_ACCESS" | no | `"INTERVENTIONAL"` |
| `with_results_only` | boolean | no | `true` |
| `sort` | "relevance" or "last_updated" or "newest" or "start_date" or "enrollment" | no | `"last_updated"` |
| `limit` | integer | no | `10` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ query, total_matching, trials[], notice, pagination, attribution }`. Upstream: ClinicalTrials.gov. Cache: hourly (1 hour). Read-only.

#### `pharma_get_trial`: Get one clinical trial record

Use this when you need the record of one registered study by its NCT number: title, status and dates, design and phase, enrollment, conditions, interventions, sponsor, brief summary, eligibility criteria, primary outcomes and a summary of its sites by country. Do not use for finding trials (pharma_search_trials), the full list of sites (pharma_list_trial_locations) or posted results (pharma_get_trial_results). Informational only: eligibility text is quoted from the registry and is not an assessment of any person. Parameters: `nct_id` (e.g. "NCT04368728"), `response_format` ("concise" cuts the criteria to 1,000 characters and lists 5 primary outcomes, "detailed" adds the official title, design details, arms, secondary outcomes, officials by affiliation and role, PubMed links of the references and longer texts). Contact names, phone numbers and e-mail addresses are never returned: the url leads to the study page.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `nct_id` | string | yes | `"NCT04368728"` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ trial, next_steps[], notice, attribution }`. Upstream: ClinicalTrials.gov. Cache: hourly (1 hour). Read-only.

#### `pharma_list_trial_locations`: List the sites of a clinical trial

Use this when you need where one registered study runs: its sites (hospital or institution, city, state, country) and each site's recruitment status, optionally only in one country or city, or only the sites that are recruiting. Do not use for finding trials near a place (pharma_search_trials with location) or for the study record itself (pharma_get_trial). Site contact names, phone numbers and e-mail addresses are never returned: the url leads to the study page. Informational only. Parameters: `nct_id` (e.g. "NCT04368728"), `country` (e.g. "France", matches the country name), `city` (part of the city name, e.g. "Boston"), `recruiting_only` (sites with status RECRUITING, default false), `limit` 1 to 100 (default 25), `offset`, `response_format` ("detailed" adds the zip code and coordinates).

| Parameter | Type | Required | Example |
|---|---|---|---|
| `nct_id` | string | yes | `"NCT04368728"` |
| `country` | string | no | `"France"` |
| `city` | string | no | `"Boston"` |
| `recruiting_only` | boolean | no | `true` |
| `limit` | integer | no | `25` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ nct_id, title, overall_status, url, total_sites, matching, countries[], sites[], notice, pagination, attribution }`. Upstream: ClinicalTrials.gov. Cache: hourly (1 hour). Read-only.

#### `pharma_get_trial_results`: Get the posted results of a clinical trial

Use this when you need the results a study posted on ClinicalTrials.gov: participants started and completed per group, outcome measures with their values per group, and adverse events per group with the most frequent serious and other events. Do not use for the study design or eligibility (pharma_get_trial) or for post-marketing adverse event reports (pharma_drug_adverse_events). Informational only: results are reported by the sponsor, adverse events in a trial do not prove causation, and nothing here is medical advice. Parameters: `nct_id` (e.g. "NCT04368728"), `outcome_type` ("primary" default, "secondary" or "all"), `limit` 1 to 5 outcome measures (default 3, at most 3 in detailed mode), `offset`, and `response_format` ("detailed" adds statistical analyses, more categories per measure, population descriptions and 25 instead of 10 top adverse events). Values and analyses refer to groups by group_id, listed with their titles in each measure.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `nct_id` | string | yes | `"NCT04368728"` |
| `outcome_type` | "primary" or "secondary" or "all" | no | `"primary"` |
| `limit` | integer | no | `3` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ nct_id, title, overall_status, url, participant_flow, baseline, outcome_measures_total, outcomes[], adverse_events, notice, pagination, attribution }`. Upstream: ClinicalTrials.gov. Cache: hourly (1 hour). Read-only.

#### `pharma_drug_adverse_events`: Count FDA adverse event reports for a drug

Use this when you need aggregate counts of the adverse event reports sent to FDA (FAERS) for a drug: the most reported reactions, or the reports by outcome, seriousness, patient sex, age group, reporter type, country or year, optionally for one reaction, serious reports only or a date range. Do not use for adverse events measured in a clinical trial (pharma_get_trial_results) or for the label's adverse reactions section (pharma_get_drug_label). Adverse event reports do not prove causation and counts are not incidence rates: informational only, never medical advice. Individual reports are never returned. Parameters: `drug` (brand or generic name, e.g. "ibuprofen"), `group_by` (reaction default, outcome, seriousness, sex, age_group, reporter, country, year), `reaction` (optional MedDRA term, e.g. "nausea"), `serious_only` (default false), `received_from` and `received_to` (YYYY-MM-DD, e.g. "2020-01-01"), `limit` 1 to 100 groups (default 20), `offset` (up to 499), `response_format`. Groups with fewer than 5 reports are left out, and no breakdown is given when fewer than 11 reports match.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `drug` | string | yes | `"ibuprofen"` |
| `group_by` | "reaction" or "outcome" or "seriousness" or "sex" or "age_group" or "reporter" or "country" or "year" | no | `"reaction"` |
| `reaction` | string | no | `"nausea"` |
| `serious_only` | boolean | no | `true` |
| `received_from` | string | no | `"2020-01-01"` |
| `received_to` | string | no | `"2024-12-31"` |
| `limit` | integer | no | `20` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ drug, group_by, filters, total_reports, count_unit, groups[], suppressed_groups, data_last_updated, notice, pagination, attribution }`. Upstream: openFDA. Cache: daily (1 day). Read-only.

#### `pharma_search_drug_labels`: Search FDA drug labels

Use this when you need to find the FDA drug labels (package inserts) of a drug: several manufacturers and versions often exist, and this lists them, newest first, with their set_id, brand and generic names, manufacturer, product type, route and whether they carry a boxed warning. Do not use for reading the label text (pharma_get_drug_label with a set_id from here), for approvals (pharma_get_drug_approvals) or for adverse event reports (pharma_drug_adverse_events). Informational only. Parameters: `drug` (brand, generic or substance name, e.g. "atorvastatin"), `manufacturer` (optional, e.g. "Pfizer"), `product_type` ("prescription" or "otc", optional), `limit` 1 to 10 (default 5), `offset` (first 100 labels), `response_format` ("detailed" adds application numbers and substances).

| Parameter | Type | Required | Example |
|---|---|---|---|
| `drug` | string | yes | `"atorvastatin"` |
| `manufacturer` | string | no | `"Pfizer"` |
| `product_type` | "prescription" or "otc" | no | `"prescription"` |
| `limit` | integer | no | `5` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ drug, total, labels[], data_last_updated, notice, pagination, attribution }`. Upstream: openFDA. Cache: daily (1 day). Read-only.

#### `pharma_get_drug_label`: Read sections of an FDA drug label

Use this when you need what an FDA drug label says: indications, boxed warning, contraindications, warnings and precautions, adverse reactions, drug interactions, use in pregnancy and other specific populations, mechanism of action, description, or the active ingredients of an OTC product. Do not use for finding which labels exist (pharma_search_drug_labels) or for FDA adverse event report counts (pharma_drug_adverse_events). Informational only, not medical advice: dosage, administration and overdose sections are never returned, read the full label on DailyMed with the dailymed_url. Parameters: `set_id` (label set id from pharma_search_drug_labels, e.g. "c6e131fe-e7df-4876-83f7-9156fc4e8228") or `drug` (brand or generic name, e.g. "atorvastatin", the newest label is used), `manufacturer` and `product_type` (optional, with `drug`), `sections` (list among indications, boxed_warning, contraindications, warnings, adverse_reactions, drug_interactions, specific_populations, mechanism, description, active_ingredients, default the first five), `response_format` (sections cut to 1,500 characters concise, 6,000 detailed).

| Parameter | Type | Required | Example |
|---|---|---|---|
| `set_id` | string | no | `"c6e131fe-e7df-4876-83f7-9156fc4e8228"` |
| `drug` | string | no | `"atorvastatin"` |
| `manufacturer` | string | no | `"Pfizer"` |
| `product_type` | "prescription" or "otc" | no | `"prescription"` |
| `sections` | array of string | no | `["indications","boxed_warning"]` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ label, sections[], missing_sections[], other_labels, next_steps[], data_last_updated, notice, attribution }`. Upstream: openFDA. Cache: daily (1 day). Read-only.

#### `pharma_search_recalls`: Search FDA recall enforcement reports

Use this when you need FDA recalls of drugs, medical devices or foods: which products were recalled, why, by which firm, how serious (Class I most serious, then II and III), the recall status and dates, newest reports first. Do not use for drug shortages (pharma_check_drug_shortages) or adverse event reports (pharma_drug_adverse_events). FDA does not update a recall status after classification and says this data must not be used to issue public alerts: informational only. Parameters: `product_type` ("drug" default, "device" or "food"), `query` (words in the product description or recall reason, e.g. "valsartan"), `firm` (recalling firm, optional), `classification` ("class_i", "class_ii" or "class_iii"), `status` ("ongoing", "completed" or "terminated"), `reported_from` and `reported_to` (YYYY-MM-DD), `limit` 1 to 25 (default 10, at most 10 in detailed mode), `offset` (first 1,000 reports), `response_format` ("detailed" adds quantities, lot codes, notification and classification details).

| Parameter | Type | Required | Example |
|---|---|---|---|
| `product_type` | "drug" or "device" or "food" | no | `"drug"` |
| `query` | string | no | `"valsartan"` |
| `firm` | string | no | `"Teva"` |
| `classification` | "class_i" or "class_ii" or "class_iii" | no | `"class_i"` |
| `status` | "ongoing" or "completed" or "terminated" | no | `"ongoing"` |
| `reported_from` | string | no | `"2024-01-01"` |
| `reported_to` | string | no | `"2024-12-31"` |
| `limit` | integer | no | `10` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ product_type, total, recalls[], data_last_updated, notice, pagination, attribution }`. Upstream: openFDA. Cache: daily (1 day). Read-only.

#### `pharma_check_drug_shortages`: Check FDA drug shortage records

Use this when you need to know whether FDA lists a drug in shortage in the United States: the status (current, resolved, to be discontinued), availability, the reason, the company and presentation, and the posting and update dates, or the latest shortage records of a therapeutic category. Do not use for recalls (pharma_search_recalls) or approvals (pharma_get_drug_approvals). A missing or resolved record is not proof that a product is available, and nobody should stop or change a medication because of a record: informational only. Parameters: `drug` (generic or brand name, e.g. "amoxicillin", optional), `therapeutic_category` (e.g. "Oncology", optional), `status` ("current" default, "resolved", "to_be_discontinued" or "any"), `limit` 1 to 25 (default 10, at most 15 in detailed mode), `offset` (first 1,000 records), `response_format` ("detailed" adds the resolution note and related information).

| Parameter | Type | Required | Example |
|---|---|---|---|
| `drug` | string | no | `"amoxicillin"` |
| `therapeutic_category` | string | no | `"Oncology"` |
| `status` | "current" or "resolved" or "to_be_discontinued" or "any" | no | `"current"` |
| `limit` | integer | no | `10` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ total, shortages[], data_last_updated, notice, pagination, attribution }`. Upstream: openFDA. Cache: hourly (1 hour). Read-only.

#### `pharma_get_drug_approvals`: Get FDA drug approval records (Drugs@FDA)

Use this when you need the FDA application behind a drug: the application number (NDA, ANDA or BLA), the sponsor, the products with their active ingredients, dosage forms, routes and marketing status, the original approval date and the latest submission. Do not use for the label text (pharma_get_drug_label), recalls (pharma_search_recalls) or shortages (pharma_check_drug_shortages). Approval records describe regulatory history, not a recommendation to use a product: informational only. Parameters: `drug` (brand name or active ingredient, e.g. "atorvastatin") or `application_number` (e.g. "NDA020702"), `sponsor` (optional, e.g. "Pfizer"), `limit` 1 to 10 applications (default 5, at most 3 in detailed mode), `offset` (first 100), `response_format` ("detailed" adds the latest 15 submissions and 10 documents such as letters and reviews).

| Parameter | Type | Required | Example |
|---|---|---|---|
| `drug` | string | no | `"atorvastatin"` |
| `application_number` | string | no | `"NDA020702"` |
| `sponsor` | string | no | `"Pfizer"` |
| `limit` | integer | no | `5` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ total, applications[], data_last_updated, notice, pagination, attribution }`. Upstream: openFDA. Cache: daily (1 day). Read-only.

#### `pharma_get_compound`: Get a chemical compound from PubChem

Use this when you need the identity and computed properties of one chemical compound or drug substance: PubChem CID, title, IUPAC name, molecular formula and weight, SMILES, InChIKey, XLogP, polar surface area, hydrogen bond donors and acceptors, charge, common names and a short description. Do not use for searching several compounds by partial name or structure (pharma_search_compounds), for comparing compounds (pharma_compare_compounds), or for drug safety data (pharma_drug_adverse_events, pharma_get_drug_label). Informational only. Parameters: `query` (e.g. "aspirin", "2244", "CC(=O)OC1=CC=CC=C1C(=O)O" or "BSYNRYMUTXBXSQ-UHFFFAOYSA-N"), `by` ("name" default, "cid", "smiles" or "inchikey"), `response_format` ("concise": 10 names and one description, "detailed": exact mass, InChI, complexity, 40 names and up to 5 descriptions). Descriptions come only from sources whose licence allows reuse, with their attribution.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `query` | string | yes | `"aspirin"` |
| `by` | "name" or "cid" or "smiles" or "inchikey" | no | `"name"` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ compound, other_cids[], synonyms[], descriptions[], next_steps[], notice, attribution }`. Upstream: PubChem. Cache: reference (30 days). Read-only.

#### `pharma_search_compounds`: Search chemical compounds in PubChem

Use this when you need several compounds from PubChem: every compound whose name contains a word, compounds structurally similar to a SMILES (2D Tanimoto similarity), compounds containing a substructure, or compounds with a molecular formula. Do not use for the full record of one compound (pharma_get_compound) or for comparing known compounds (pharma_compare_compounds). Informational only. Parameters: `mode` ("name" default, "similarity", "substructure" or "formula"), `query` (a word such as "statin", a SMILES such as "CC(=O)OC1=CC=CC=C1C(=O)O", or a formula such as "C9H8O4"), `threshold` (similarity only, 80 to 100, default 90), `limit` 1 to 20 (default 10, at most 10 in detailed mode), `offset` (first 200 hits), `response_format` ("detailed" adds SMILES, InChIKey and XLogP).

| Parameter | Type | Required | Example |
|---|---|---|---|
| `mode` | "name" or "similarity" or "substructure" or "formula" | no | `"similarity"` |
| `query` | string | yes | `"CC(=O)OC1=CC=CC=C1C(=O)O"` |
| `threshold` | integer | no | `90` |
| `limit` | integer | no | `10` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ mode, query, total_found, compounds[], notice, pagination, attribution }`. Upstream: PubChem. Cache: daily (1 day). Read-only.

#### `pharma_compare_compounds`: Compare chemical compounds side by side

Use this when you need to compare 2 to 10 compounds or drug substances on their computed properties: molecular formula and weight, XLogP (lipophilicity), topological polar surface area, hydrogen bond donors and acceptors, rotatable bonds, charge, and the number of Lipinski rule-of-five violations. Do not use for one compound (pharma_get_compound) or for finding compounds (pharma_search_compounds). Drug-likeness rules are rough screening heuristics, not a judgement on a medicine: informational only. Parameters: `compounds` (2 to 10 names or CIDs, e.g. \["aspirin", "ibuprofen", "naproxen"] or \["2244", "3672"]), `response_format` ("detailed" adds exact mass, complexity, heavy atoms and SMILES).

| Parameter | Type | Required | Example |
|---|---|---|---|
| `compounds` | array of string | yes | `["aspirin","ibuprofen","naproxen"]` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ rows[], not_found[], ranges, notice, attribution }`. Upstream: PubChem. Cache: reference (30 days). Read-only.

### Connect

Endpoint (Streamable HTTP): `https://mrbridge--clinical-pharma-mcp.apify.actor/mcp`

Every client authenticates with your Apify API token, found in [Apify Console > Settings > API & Integrations](https://console.apify.com/settings/integrations?fpr=mrbridge). Clients that support custom headers send it as `Authorization: Bearer <token>`. The others use the `?token=` URL variant, which must be treated as a secret: keep it out of commits, screenshots and shared logs.

#### Claude Code

```bash
claude mcp add --transport http clinical-pharma "https://mrbridge--clinical-pharma-mcp.apify.actor/mcp" --header "Authorization: Bearer ${APIFY_TOKEN}"
```

#### Cursor, VS Code and other JSON configurations

```json
{
  "mcpServers": {
    "clinical-pharma": {
      "type": "http",
      "url": "https://mrbridge--clinical-pharma-mcp.apify.actor/mcp",
      "headers": {
        "Authorization": "Bearer ${APIFY_TOKEN}"
      }
    }
  }
}
```

#### claude.ai and Claude Desktop

Add a custom connector with the URL `https://mrbridge--clinical-pharma-mcp.apify.actor/mcp?token=YOUR_APIFY_TOKEN` and no authentication. Prefilled link (replace the token placeholder before saving): [add Clinical Trials and Drug Data MCP Server to Claude](https://claude.ai/customize/connectors?modal=add-custom-connector\&connectorName=Clinical%20Trials%20and%20Drug%20Data%20MCP%20Server\&connectorUrl=https%3A%2F%2Fmrbridge--clinical-pharma-mcp.apify.actor%2Fmcp%3Ftoken%3DYOUR_APIFY_TOKEN).

#### ChatGPT (developer mode)

Settings > Apps > Create, URL `https://mrbridge--clinical-pharma-mcp.apify.actor/mcp?token=YOUR_APIFY_TOKEN`, authentication "No authentication". ChatGPT snapshots the tool list: after a server update, an admin has to click Refresh on the app.

#### OpenAI Responses API

```json
{
  "type": "mcp",
  "server_label": "clinical_pharma",
  "server_url": "https://mrbridge--clinical-pharma-mcp.apify.actor/mcp",
  "headers": {
    "Authorization": "Bearer YOUR_APIFY_TOKEN"
  },
  "require_approval": "never"
}
```

Add `allowed_tools` to restrict the tool list. Tool calls must finish within about 60 seconds on this API, and every tool of this server answers in under 50 seconds.

#### Anthropic Messages API

```json
{
  "mcp_servers": [
    {
      "type": "url",
      "url": "https://mrbridge--clinical-pharma-mcp.apify.actor/mcp",
      "name": "clinical-pharma",
      "authorization_token": "YOUR_APIFY_TOKEN"
    }
  ],
  "tools": [
    {
      "type": "mcp_toolset",
      "mcp_server_name": "clinical-pharma"
    }
  ]
}
```

Send the beta header `anthropic-beta: mcp-client-2025-11-20`.

#### One-click OAuth alternative

`https://mcp.apify.com/?tools=mrbridge/clinical-pharma-mcp` connects through Apify OAuth without a token. It exposes the Actor as a single tool rather than the granular tools listed above.

#### Cost control

Each Standby run has a spending limit (`maxTotalChargeUsd`). When a call uses the last of it, the result is still returned, and later calls in that run answer `CHARGE_LIMIT_REACHED` until the limit is raised.

### Why use this server

Free MCP servers already cover ClinicalTrials.gov or openFDA, one source each. This one is built for questions that cross them. You can look up a trial, open the label of the drug it tests and check the structure of the active compound without switching connectors.

- **Adverse event counts in one call.** Group the reports for a drug by reaction, outcome, seriousness, sex, age band, reporter type, country or year. Groups under 5 reports are hidden and no breakdown is given under 11 reports, so narrow filters cannot rebuild a single report.
- **Posted results you can actually read.** The PALLAS study (NCT02513394) lists 341 serious and 1,688 other adverse event terms. The tool sums them into the 10 most frequent and adds the participant flow and the outcome measures per group.
- Chemistry sits next to the clinical data. Similarity and substructure searches return candidates, and a comparison table counts Lipinski rule-of-five violations.
- **Filtering happens before anything is stored.** Trial contacts, individual reports, street addresses and description sources with restrictive licences (DrugBank, HMDB) never reach the cache.

Every answer names its source and the date of its data, with a link to the terms. In the platform test of 2026-10-05, warm calls took between 0.1 and 2.8 seconds.

### Pricing (Pay-per-Event)

| Event | Charged when | Price |
|---|---|---|
| `apify-actor-start` | run start (platform default) | see the Store page |
| `tool-read` (primary event) | each successful read tool call | see the Store page |
| `tool-action` | each successful call of a detailed or computed tool | see the Store page |

Never charged: initialize, tools/list, pings, readiness probes, and any call that ends in an error (invalid input, not found, upstream failure, timeout, spending limit).

Platform usage comes on top of these events. This server runs in Apify Standby mode, and you also pay the platform usage of your own Standby run, billed to your Apify account like any other run: the memory set for the Standby run, for as long as the server is up, idle time included, until the run stops at its idle timeout.
The [Apify pay-per-event documentation](https://docs.apify.com/actors/publishing/monetize/pay-per-event#platform-usage-costs) says so: "For runs in Standby mode, users always pay the platform usage costs in addition to the event charges."

### Limits, caveats and attribution

- **Not medical advice.** All data is informational. No tool recommends a treatment, a trial or a dose, and label dosage, administration and overdose sections are never returned (the `dailymed_url` leads to the full label). Every answer opens its `attribution.notices` with the medical notice.
- **Adverse events.** Adverse event reports do not prove causation. FAERS counts reflect what was reported to FDA, not how often a reaction happens, and FAERS data may lag by three months or more. The server returns counts only, never an individual report. Groups with fewer than 5 reports are left out of every breakdown, key included, and no breakdown is given when fewer than 11 reports match. A drug is matched in any role on a report (suspect, concomitant or interacting).
- **Clinical trials.** Study data comes from sponsors and investigators. The U.S. government does not review or approve the safety and science of all listed studies. Contact names, phone numbers and e-mail addresses are removed, and the study page gives the way to reach the study team. Answers show the ClinicalTrials.gov processing date and each study's last update. A search pages through its first 250 studies.
- **Labels, recalls, shortages, approvals.** FDA states that label content was reformatted but neither altered nor verified by FDA, and may differ from the label on the products sold today. FDA does not update a recall status after classification and asks that enforcement data not be used to issue public alerts. A missing or resolved shortage record is not proof that a product is available. Street addresses and company contact details are not returned.
- **Chemistry.** Computed properties are PubChem's own. Descriptions come only from sources whose licence allows reuse (MeSH, LiverTox, NCI Thesaurus, FDA Pharmacologic Classes, LOTUS, ChEBI), each with its attribution. DrugBank and HMDB texts are never returned, and CAS Registry Numbers are left out of the names.
- **Rate limits.** The server calls openFDA with the Actor owner's free openFDA API key, which allows 240 requests per minute and 120,000 per day, shared by every user of this Actor. It never retries an openFDA request and paces itself at half these limits, so very heavy use can answer `UPSTREAM_RATE_LIMITED`, which is never charged. PubChem asks for at most 5 requests per second and throttles harder clients. ClinicalTrials.gov publishes no limit, and the server keeps to 25 requests per minute.
- **Freshness.** Trial data and shortage records are cached for one hour, FAERS counts, labels, recalls and approvals for one day, PubChem compound data for 30 days.
- **Size.** Long texts are cut and marked with "...". Detailed answers hold fewer items per call than concise ones, and each tool says when it lowered a limit.

### Data terms

The three sources are U.S. government services with their own terms. When you reuse what this server returns:

- ClinicalTrials.gov (https://clinicaltrials.gov/about-site/terms-conditions): attribute the data to ClinicalTrials.gov, keep it current, show the date ClinicalTrials.gov processed it, describe any change you make to it, and do not use e-mail addresses from the registry for marketing. Outside the United States the data carries an international copyright. Lead sponsors who are individual investigators are listed under their own name, as the registry publishes them.
- openFDA (https://open.fda.gov/terms/): the data is dedicated to the public domain (CC0). FDA asks for the credit "Data provided by the U.S. Food and Drug Administration (https://open.fda.gov)" and says not to rely on openFDA to make decisions regarding medical care. Do not imply that FDA endorses you or your product.
- PubChem (https://www.ncbi.nlm.nih.gov/home/about/policies/): acknowledge the National Library of Medicine as the source. Some PubChem content comes from third parties with their own terms, which is why this server filters descriptions by source and keeps each source's attribution.

The fee for this server pays for the service (hosting, caching, normalisation, scrubbing and filtering), not for a licence on the data.

### Use cases

- **Trial landscape for a condition.** A business development analyst asks for recruiting phase 3 interventional trials in type 2 diabetes and reads sponsors, enrollment, phases and countries, 10 rows at a time. On 2026-10-05 the registry held 866 recruiting studies for that condition alone, which is why the filters matter.
- A regulatory affairs team checks every Monday for new drug recalls on its molecules, then looks at the current shortage records of a therapeutic category such as oncology.
- **Dossier background.** A medical writer pulls the indications and boxed warning of a label, then the approval history of the same product. Source and data date come ready to cite.
- Researchers who study reporting patterns can split a drug's reports by country or by year. Counts describe what was reported, not how often a reaction happens. Reports do not prove causation.
- **Compound screening.** A chemist searches for compounds at 90 percent similarity to a lead structure and compares the shortlist on weight, XLogP, polar surface area and rule-of-five violations.
- A data team lets an internal agent answer questions on trials and labels, and stores the attribution block of each answer as its citation.

### Frequently asked questions

#### How much does a call cost?

Pricing is pay-per-event. Each successful tool call is one `tool-read` event at $0.005, or one `tool-action` event at $0.01 for `pharma_get_compound` and `pharma_compare_compounds`. Apify also charges its standard `apify-actor-start` event each time your Standby run starts, which happens on your first call and again on the first call after each idle stop. Nothing is charged for initialize, tools/list, pings, readiness probes, or a call that ends in an error (invalid input, not found, upstream failure, timeout, spending limit).

The events are not the whole cost. On top of them you pay the platform usage of your own Standby run, billed to your Apify account like any other run: the memory set for the run (256 MB by default), for as long as the server is up, idle time included, until it stops at its idle timeout (about 5 minutes without a call by default). So 100 successful read calls come to $0.50 in `tool-read` events, plus the start event and the platform usage of the run. These are the FREE plan prices, and Apify plan discounts lower them. To cap spending, set `maxTotalChargeUsd` on the run. The [Pricing tab](https://apify.com/mrbridge/clinical-pharma-mcp/pricing?fpr=mrbridge) shows the event prices for each Apify plan.

#### Can I use it for medical decisions?

No. The data is informational, and the server gives no advice on care or dosing. Label sections on dosage, administration and overdose are never returned. Every answer repeats the notice, and any decision about your health belongs with a qualified professional.

#### What does the server not do?

It never ranks or recommends a trial. Individual case reports stay out, and so does dosing information. Labels, recalls, shortages and approvals cover the United States only. DrugBank and HMDB descriptions and CAS Registry Numbers are left out on licence grounds.

It is not a live feed either. Trial and shortage data is cached for an hour, compound data for 30 days, and everything else for a day.

#### Can I reuse the data?

Yes, within each source's terms. The Data terms section above sums them up, and the short version runs like this: openFDA data is CC0 with a requested credit line, while ClinicalTrials.gov wants to be named as the source, with current data, its processing date shown and your changes described. Registry data also carries an international copyright outside the United States. PubChem asks for an acknowledgement of the National Library of Medicine. Your fee pays for the service, not for a licence on the data.

#### What happens to personal data?

Contact details of study teams are removed before caching, and so are investigator names in the official and responsible party fields. A site named after a person gets renamed. Post-market reports arrive only as totals per group, and small groups are hidden. Recall and shortage records lose street addresses and company contacts. One case stays open: when an individual investigator is a study's lead sponsor, the registry lists that person as the sponsor and the server returns the name.

#### Why is the first call slower?

Standby mode. After about 5 minutes without a call your run stops, and the next call starts a new one. In the 2026-10-05 platform test that cold start took about 4.7 seconds, and warm calls then answered in 0.1 to 2.8 seconds.

#### Do I need an API key from the data sources?

No, only your Apify API token. The three sources are public and the server paces its requests to their published limits. Under heavy use a call can answer `UPSTREAM_RATE_LIMITED`, which is never charged.

#### Your feedback

Found a wrong answer or a bug? Open an issue on the [Issues tab](https://apify.com/mrbridge/clinical-pharma-mcp/issues?fpr=mrbridge) with the tool name and the arguments you used, and we will look at it. Other MCP servers and data studies from the same team live on the [MrBridge site](https://mr-bridge.com).

### Changelog

- 0.1.5: Output, dataset and key-value store schemas, as Apify asks for publication: the Output tab of a run started from the Console shows the connection details and one row per tool.
- 0.1.4: the Input tab shows the endpoint and how to connect an AI client, and a run started from the Console outputs the connection details and the tool list
- 0.1.3: pricing events tool-read and tool-action
- 0.1.2: when openFDA refuses a request for its quota, the answer names the daily quota of the owner's openFDA key, which is set, instead of a keyless quota and a key to set. Without a key it still names the keyless quota.
- 0.1.1: server name aligned with the Store title (connector name and connection page), and the limits section says that small counts are left out of every adverse event breakdown and that openFDA is called with the owner's key. The endpoint and the tools do not change.
- 0.1.0: initial build (private, unpublished)

# Actor input Schema

## `mcpEndpoint` (type: `string`):

Paste this URL into your MCP client (Streamable HTTP). It is shown here for copying only: the server ignores this form, and every parameter goes in your questions.

## Actor input object example

```json
{
  "mcpEndpoint": "https://mrbridge--clinical-pharma-mcp.apify.actor/mcp"
}
```

# Actor output Schema

## `connection` (type: `string`):

The item written by a run started from the Console: endpoint, token options, client recipes and the list of tools with the event each one bills.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mcpEndpoint": "https://mrbridge--clinical-pharma-mcp.apify.actor/mcp"
};

// Run the Actor and wait for it to finish
const run = await client.actor("mrbridge/clinical-pharma-mcp").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "mcpEndpoint": "https://mrbridge--clinical-pharma-mcp.apify.actor/mcp" }

# Run the Actor and wait for it to finish
run = client.actor("mrbridge/clinical-pharma-mcp").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mcpEndpoint": "https://mrbridge--clinical-pharma-mcp.apify.actor/mcp"
}' |
apify call mrbridge/clinical-pharma-mcp --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mrbridge/clinical-pharma-mcp"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/QGxgVHWfwupHYTW3E/builds/403UNJzdQoQ7T6y3z/openapi.json
