MCP server exposing clinical trials, drug recalls, adverse events, labels, and drug-name normalization as typed tools
MedBridge demonstrates solid definition quality with well-structured tool names, comprehensive descriptions, and proper input schemas. All 6 tools follow verb_noun naming (search_*, get_*, normalize_*). Descriptions are detailed (150-300 chars) and include WHEN to use each tool and WHAT it returns. Input schemas use Pydantic with proper types, enums, and constraints. However, output schemas are not explicitly documented in the visible code, and error handling lacks recovery guidance (e.g., 'try normalize_drug_name first'). Tool composition is clean, each tool has one responsibility. Security is sound: no credentials in parameters, read-only operations only. The codebase shows mature error handling patterns (ValidationError → _invalid, MedBridgeError → _upstream) but the error responses themselves lack actionable recovery steps for the LLM.
Summarize which side effects are most often reported for a drug. Returns the total number of FDA adverse event reports mentioning the drug and the most frequently reported reactions with their counts, rather than individual case records. These are voluntary reports. A report does not establish that the drug caused the event, common drugs accumulate more reports simply by being common, and counts cannot be compared between drugs without knowing how many people take each. Present these as reported associations, never as side effects the drug is known to cause.
Read the FDA-approved product label for a drug. Use this for what a drug is approved to treat and what its labeled warnings say. Returns brand and generic name, manufacturer, approved indications, and warnings; the long text fields are truncated and flagged when cut. Labels are per product, so a search can match a combination product or one manufacturer's version of a generic. Check the returned brand and generic names before relying on the text.
Read one clinical trial in full, including who is eligible to join. Use this after search_trials when a specific trial matters, or whenever a conversation names an NCT number. Returns title, status, phase, conditions, the eligibility criteria text with structured age range and sex, every study location, and the study description.
Resolve a drug name to its canonical RxNorm identifier and standard name. Use this when a drug name is uncertain or misspelled, or when you need to verify that a name refers to a real drug. Returns the RxCUI (RxNorm Concept Unique Identifier), the canonical name, and the term type. If the name matches nothing exactly, returns a ranked list of close alternatives from spelling suggestions and approximate matching so a model can pick the right one or ask the user.
Output schemas not documented in tool descriptions. LLMs cannot plan downstream calls or extract fields without knowing what each tool returns. The code shapes responses (shaping.shape_trial_search, etc.) but these transformations are not visible in the tool docstrings.
Error responses lack recovery guidance. When a drug name is not found or a trial search returns no results, the error object should suggest next steps (e.g., 'Try normalize_drug_name first' or 'Broaden location or status filters'). Current _upstream and _invalid handlers return structured errors but no actionable hints.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | <=2025-11-25 | v2 |
Look up FDA recall and enforcement reports for a drug. Use this to answer whether a drug has been recalled and why. Returns one entry per recall with its date, the affected product, the reason, the FDA hazard classification (Class I is most serious), the recall's current status, and the recalling firm. An empty result means no recall records matched, which is meaningfully different from a failure -- it is safe to report as "no recalls found".
Find clinical trials studying a condition, newest registrations first. Use this to answer questions like "are there trials for X" or "what studies near Y are enrolling". Returns one entry per trial with its NCT number, title, recruitment status, conditions, a summary of where it runs, a short truncated description, and a link to the full record. Call get_trial with an NCT number from these results for eligibility criteria and full details.
Parameter descriptions lack explicit format/constraint hints. E.g., 'condition' says 'prefer medical name' but does not state what happens if a colloquial term is passed. 'location' says 'city, state, or country' but does not clarify if partial matches work. Descriptions should include format rules and examples of valid/invalid inputs.
No tool annotations (readOnlyHint, idempotentHint) visible in FastMCP registration. All tools are read-only and idempotent, but this is not declared in the schema. Tool annotations help LLMs reason about safety and retry logic.
Pagination not implemented for search tools. search_trials and search_drug_recalls accept max_results but do not return a total_count or next_cursor. Large result sets could exhaust context; pagination guidance is missing.