A Model Context Protocol server providing comprehensive access to FDA datasets including drug adverse events, labels, NDC directory, recalls, approvals, shortages, device 510(k) clearances, classifications, adverse events, recalls, food adverse events and recalls
The FDA MCP server demonstrates solid fundamentals with complete tool definitions, proper schema structure, and reasonable descriptions. All 10 tools have explicit registrations with JSON Schema input definitions and descriptions. However, there are systematic gaps in parameter descriptions, output schema documentation, and error handling patterns that prevent a higher score. The tool definitions are comprehensive in breadth but lack the LLM-optimization depth of A-grade servers. No security or composition issues detected. Transport is STDIO-only, which creates a hard cap on protocol readiness but does not directly penalize definition quality.
Output schemas not documented in code. Tool descriptions and input schemas are complete, but there is no explicit documentation of what fields these tools return. LLMs cannot plan downstream chaining or extract the right data without knowing the response structure.
Parameter descriptions lack actionable constraints. Many parameters (e.g., 'date_from', 'date_to', 'count', 'route', 'product_code') have generic or minimal descriptions that do not explain format requirements, valid ranges, or expected values in enough detail for robust LLM invocation. The description for 'count' field is particularly vague ('Field to group results by for counting') and does not explain valid field names or OpenFDA API syntax.
Add explicit output schema documentation for each tool. Publish the response structure (e.g., for search_drug_adverse_events: {results: [{event_id, date, reaction, seriousness, ...}], total_count, next_cursor}). This enables LLMs to plan chaining and extract the right fields.
Expand parameter descriptions with format, range, and valid values. For example: 'date_from: Start date in YYYYMMDD format (e.g., 20240101). Must be ≤ date_to if both provided.' 'route: Route of administration. Valid values: ORAL, TOPICAL, INTRAVENOUS, INTRAMUSCULAR, SUBCUTANEOUS, RECTAL, VAGINAL, INHALATION, TRANSDERMAL, OPHTHALMIC, OTIC, NASAL, SUBLINGUAL, BUCCAL, IMPLANT.' 'count: OpenFDA field name for grouping (e.g., patient.drug.openfda.brand_name.exact, patient.reaction.reactionmeddrapt.exact). See OpenFDA API docs for valid field paths.'
Convert enumerable parameters to JSON Schema enums. For 'route' in drug_labels and device search tools, add enum: ['ORAL', 'TOPICAL', 'INTRAVENOUS', ...]. For 'dosage_form', add enum: ['TABLET', 'CAPSULE', 'INJECTION', ...]. For 'event_type' in device_adverse_events, enumerate known event types from FDA guidance.
Add error handling with recovery guidance. In handler implementations, when search returns zero results, return a structured error like: {error: 'No results found for drug_name="aspirin". Try: (1) broaden search filters (remove date_from/date_to), (2) use generic_name="acetylsalicylic acid" instead, (3) call search_drugs_fda first to verify the drug exists.}'
Document pagination behavior in tool descriptions. For example: 'Returns up to limit results. If more exist, response includes next_cursor. Repeat call with skip=<prior_results_count> to fetch subsequent pages.'
Enum constraints incomplete. Several parameters that logically should be enums (e.g., 'route' values like ORAL, TOPICAL, TOPICAL; 'dosage_form' like TABLET, CAPSULE, INJECTION; 'event_type') are declared as plain strings with no enum constraint, only hints in the description. This invites hallucinated values and prevents LLMs from self-correcting.
Error handling patterns not evident. The source code does not show error categorization, recovery guidance, or actionable error messages. A tool that fails to find results should guide the LLM to suggest corrections or alternatives; currently no such scaffolding is visible.
Missing pagination limits in tool descriptions. While limit and skip parameters are present with min/max constraints (1-100, 0+), the tool descriptions do not explicitly state the default limit, what happens if results exceed the limit, or whether the response includes a total_count or next_cursor for chaining.
Tool descriptions do not explain when to use each tool vs similar alternatives. With 10 similar search tools spanning drugs and devices, LLMs lack clear guidance on when to call search_drug_adverse_events vs search_drug_labels vs search_drug_ndc, or when to prefer search_drugs_fda over the others.
Add 'When to use' sections to tool descriptions. For example, search_drug_adverse_events: 'Use this to find adverse event reports for a specific drug, reaction, or patient demographic. If you need approved drug product info (NDA status), use search_drugs_fda instead. If you need drug label text (indications, warnings), use search_drug_labels.'
Provide handler implementation with proper input validation. Validate date_from <= date_to, limit within 1-100, patient_sex in ['1', '2'], status in enum values. Return actionable error messages like 'Invalid date_from: must be YYYYMMDD format and ≤ date_to.'
Consider adding a discovery tool or resource that documents OpenFDA API field paths and valid enum values for the 'count' and enumerable parameters. This eliminates guesswork for LLMs constructing complex queries.
Add idempotency/determinism guarantees. State whether these tools always return the same results for the same inputs, or if results vary by date (e.g., shortages data changes daily). This helps agents decide if retry is safe.
Return structured, LLM-friendly output. Ensure response fields map to subsequent tool inputs (e.g., if an LLM calls search_drug_adverse_events and then wants details on a specific drug, the response must include a drug_id or brand_name field to feed into search_drug_labels).