Skip to main content
Glama

OpenFDA MCP Server

A Model Context Protocol (MCP) server for querying drug information from the OpenFDA API.

Features

2.0.0 registers one tool per openFDA drug endpoint, each with the same shape: a field + value search, limit/skip for paging, detail for the returned record shape, and (where the endpoint supports it) sort and count for ordering and frequency aggregation. Adding an endpoint means adding a row here, not rewriting the pattern.

  • drug-label — Search FDA structured product labels (SPL): prescribing and OTC drug info. field: drug_name (brand/generic/substance, tiered), ndc, spl_product_data_elements, effective_time, id, set_id, brand_name, generic_name, substance_name, manufacturer_name, route, product_type, application_number, unii, rxcui. detail: summary (default; identity plus the safety narrative, every field present, empty if absent), safety (warnings, contraindications, interactions and overdosage — see the migration table below for the 1.x tool this replaces), full (the raw upstream record). count: openfda.route.exact, openfda.product_type.exact, openfda.manufacturer_name.exact. sort: effective_time:desc/effective_time:asc. limit default 1, max 25.

  • drug-event — Search FAERS adverse event reports (voluntarily submitted side-effect reports; not evidence of causation). field: drug_name (unions patient.drug.openfda.generic_name, patient.drug.openfda.substance_name and patient.drug.medicinalproduct), brand_name, manufacturer_name, product_ndc, pharm_class, drug_characterization, indication, reaction, reaction_outcome, serious, seriousness_death, patient_sex, reporter_qualification, country, received_date, report_id. detail: summary (default; one row per report, FAERS codes decoded, (reaction, outcome) pairs deduplicated), full. Also takes seriousness (serious/non-serious/all, default all). sort: receivedate:desc/receivedate:asc; without sort, results are a deterministic earliest-report_id slice. count: patient.reaction.reactionmeddrapt.exact, patient.reaction.reactionoutcome, serious, patient.patientsex, occurcountry.exact, patient.drug.openfda.generic_name.exact (see the migration table below for the 1.x tool this replaces). limit default 10, max 50. Note: the searchable received_date field maps to receivedate, but the summary projection's returned report_date reads receiptdate — two different, near-duplicate FAERS date fields. Filtering by one and reading the other back will not, in general, show the same date.

  • drug-drugsfda — Search Drugs@FDA application data: approvals, sponsors, products and submissions. field: products.brand_name (default drug-name search, 98.79% populated), application_number, sponsor_name (stored uppercase upstream; normalised automatically), products.active_ingredients.name, products.dosage_form, products.route, products.marketing_status, products.reference_drug, products.te_code, openfda.brand_name, openfda.generic_name, openfda.substance_name, openfda.manufacturer_name, openfda.route, openfda.product_ndc (the openfda.* names are the openFDA-harmonised spelling of the same identifiers, but populated on only ~42% of applications — the precise alternative to products.brand_name, not the default), submissions.submission_type, submissions.submission_status, submissions.submission_status_date, submissions.submission_class_code, submissions.review_priority. detail: summary (default; application number, sponsor, openfda block and products — each product carries te_code, null when absent — plus a submission_count, with no submissions array), full (adds submissions, capped at 10 per record, plus submissions_truncated when more were omitted). count: sponsor_name, products.marketing_status, products.dosage_form.exact. limit default 5, max 100. Seven search paths openFDA publishes on this endpoint are deliberately not exposed here — see Migrating from 1.x below.

  • drug-ndc — Search the NDC Directory: every drug product currently listed with the FDA (packaging, labeler, marketing category and application number). This is the product registry, distinct from drug-label's ndc field, which searches labelling text by NDC — see the migration table below for the 1.x NDC lookup this tool is not a replacement for. field: product_ndc, packaging.package_ndc, generic_name, brand_name, active_ingredients.name, openfda.manufacturer_name, marketing_category, application_number, dosage_form, route, product_type, pharm_class, marketing_start_date, openfda.unii, openfda.rxcui, openfda.spl_set_id. detail: summary (default; identity, packaging and marketing status), full (raw upstream record). count: dosage_form.exact, route.exact, product_type.exact, marketing_category, openfda.manufacturer_name.exact. limit default 5, max 50.

  • drug-enforcement — Search FDA drug recall and enforcement reports. classification is the hazard level (Class I: reasonable probability of serious harm or death; II: temporary or reversible harm; III: unlikely harm) and status says whether a recall is Ongoing, Completed or Terminated — a recall appearing in results does not mean it is still in effect. field: product_description (default drug-name search, 100% populated), recall_number, event_id, code_info, recalling_firm, reason_for_recall, classification, status, voluntary_mandated, state, country, recall_initiation_date, report_date, termination_date, openfda.generic_name, openfda.brand_name, openfda.product_ndc (the last three are exact but populated on only ~18% of recalls — the precise alternative to product_description, not the default). detail: summary (default; every field above except the three openfda.* names, which are bundled as one openfda object), full (raw upstream record). count: classification.exact, status.exact, state.exact, voluntary_mandated.exact, recalling_firm.exact. sort: report_date:desc/report_date:asc/recall_initiation_date:desc. limit default 5, max 50.

  • drug-orangebook — Search the Orange Book: FDA-approved drug products with their therapeutic-equivalence ratings. Almost all data lives in the nested products array, which this tool flattens into one entry per product. field: products.brand_name, products.active_ingredients.name, products.application_number, products.application_type, products.application_full_name, products.application_name, products.therapeutic_equivalence_codes, products.reference_listed_drug, products.reference_standard, products.dosage_form, products.route, approval_date. detail: summary (default; approval_date, product_number and the flattened products array — reference_listed_drug and reference_standard are booleans always returned, false a fact rather than a missing value), full (raw upstream record). count: products.application_type, products.dosage_form.exact, products.route.exact, products.therapeutic_equivalence_codes. sort: approval_date:desc/approval_date:asc. limit default 5, max 50.

  • drug-shortages — Search FDA drug shortage reports. status is one of three values, live-verified 2026-09-21: Current (1153 records), To Be Discontinued (443), or Resolved (7) — a product appearing here is not necessarily short now, and To Be Discontinued is neither "current" nor "resolved" but the larger of the two non-Current states. openFDA sends an empty string, not null, for an absent date on this endpoint; this tool normalises those to null. field: generic_name (default), company_name, openfda.manufacturer_name, openfda.brand_name, openfda.substance_name, package_ndc, openfda.product_ndc, status, therapeutic_category, dosage_form, update_type, initial_posting_date, update_date. detail: summary (default; the openfda.* names are bundled as one openfda object), full (raw upstream record). count: status, dosage_form.exact, therapeutic_category, company_name.exact. sort: update_date:desc/update_date:asc/initial_posting_date:desc. limit default 10, max 50. Smallest drug dataset (~1,600 records); a coverage percentage here represents far fewer records than the same percentage elsewhere.

Every tool's response envelope carries matched_via (which field path actually matched), total (the upstream match count, not the number of records in this response), returned (how many records it does carry), limit, dropped_for_budget (how many rows were dropped to stay within the 60,000-character response budget — 0 when none were, never omitted), next_skip (the offset to resume paging from; null when the result set is exhausted or the next offset would exceed SKIP_MAX) and results. Page by next_skip, not skip + limit — the budget can drop trailing rows, so skip + limit silently steps over exactly the rows that were dropped. A search that matches nothing returns a plain no-results message, not an error.

limit means two different things depending on whether count is set: for a record search it caps rows returned, capped at that tool's max below; for an aggregation it caps buckets, defaulting to 100 (openFDA's own bucket ceiling) when omitted. This is an asymmetry on every tool except drug-drugsfda (whose record max is already 100): omitting limit under count can return up to 100 buckets, but an explicit limit is still rejected above the tool's record max — so a caller can receive more buckets than it can explicitly request. Record maxes: drug-label 25, drug-event 50, drug-drugsfda 100, drug-ndc 50, drug-enforcement 50, drug-orangebook 50, drug-shortages 50.

An aggregated response is trimmed to the same 60,000-character budget as a record response, and reports dropped_for_budget for the buckets it dropped — returned counts the buckets actually kept. It carries no next_skip: an aggregation has no result total and no skip semantics, so an offset to resume from would be a number with nothing behind it.

Route vocabularies differ across tools. drug-label's route field (openfda.route, the SPL route of administration) and drug-drugsfda's products.route field (the Drugs@FDA product route) are different controlled vocabularies. The same insulin glargine product is reported as SUBCUTANEOUS in one and INJECTION in the other, so joining or filtering on route across tools will silently miss matches.

  1. Set up your OpenFDA API Key

    The server reads OPENFDA_API_KEY from its process environment. It is launched by your MCP client, so the key belongs in the env block of your client configuration (shown below) — a .env file is not read.

    Get a key from OpenFDA API Key Registration. A key raises your limit from 40 to 240 requests per minute.

    Without a key, every tool call returns a configuration error rather than failing confusingly upstream. To run on the unauthenticated tier anyway, set OPENFDA_ALLOW_KEYLESS=1 — note that tier reports no rate-limit headers, so exhausting it surfaces as slow, intermittent failures.

    Note: Never commit your real API key to version control.

  2. Example MCP Server Configuration

    If you are integrating this server with a larger MCP system, your configuration might look like:

     {
       "mcpServers": {
           "openfda": {
               "command": "npx",
               "args": [
                   "-y",
                   "@ythalorossy/openfda"
               ],
               "env": {
                   "OPENFDA_API_KEY": "*****************************************"
               },
               "timeout": 60000,
               "autoApprove": [
                   "drug-label",
                   "drug-event",
                   "drug-drugsfda",
                   "drug-ndc",
                   "drug-enforcement",
                   "drug-orangebook",
                   "drug-shortages"
               ]
           }
       }
     }

    Replace the asterisks with your actual API key.

Related MCP server: drugbank-mcp-server

Want to run it locally?

git clone https://github.com/ythalorossy/openfda.git
cd openfda
npm install
npm run build

Then start the server:

node dist/index.js

Or use it directly with npx:

npx @ythalorossy/openfda

Configuration

Export OPENFDA_API_KEY in your shell before running locally: export OPENFDA_API_KEY=your_key.

Migrating from 1.x

2.0.0 replaces the nine get-* tools with one tool per openFDA drug endpoint. Pin 1.3.0 if you are not ready to migrate.

1.x tool

2.0.0 call

get-drug-by-name

drug-label { field: "drug_name", value }

get-drug-by-generic-name

drug-label { field: "generic_name", value }

get-drugs-by-manufacturer

drug-label { field: "manufacturer_name", value }

get-drug-safety-info

drug-label { field: "drug_name", value, detail: "safety" }

get-drug-by-ndc

drug-label { field: "ndc", value }

get-drug-by-product-ndc

drug-label { field: "ndc", value }

get-drug-adverse-events

drug-event { field: "drug_name", value }

get-drug-adverse-event-counts

drug-event { value, count: "patient.reaction.reactionmeddrapt.exact" }

get-drugsfda

drug-drugsfda { field: "application_number", value } or { field: "products.brand_name", value }

drug-drugsfda field names carry no section prefix. 1.x grouped fields under a section parameter (application, products, submissions, openfda), so the table row above is illustrative, not literal: real field names are flat where 1.x had a section for the top-level application fields — application_number and sponsor_name carry no prefix — while products.*, submissions.* and openfda.* keep theirs. A caller who copies application.sponsor_name from 1.x muscle memory gets an unknown-field error; the correct value is sponsor_name.

get-drug-by-ndc did not search /drug/ndc.json. It searched labels by openfda.product_ndc, so it maps to drug-label ({ field: "ndc" }), not to drug-ndc. drug-ndc searches the actual NDC Directory — new capability this server did not previously expose — and returns different data than the label-based lookup 1.x actually performed: use drug-ndc for packaging, labeler and marketing-category questions, and drug-label for label text keyed off an NDC.

get-drug-by-product-ndc returned a pre-filtered available_packages — the label's package NDCs filtered down to the product you searched. drug-label's summary detail returns package_ndc unfiltered, so on a label that covers several products it mixes packages from all of them. Nothing is lost: summary also returns product_ndc[], so filtering by prefix is a one-line operation on the caller's side, and active_ingredient, purpose and dosage_and_administration are reachable via detail: "full" — but the convenience of a pre-filtered list is gone.

Seven Drugs@FDA search paths available in 1.x are deliberately not exposed on drug-drugsfda: openfda.application_number (a 42%-populated duplicate of the 100%-populated application_number), products.product_number and submissions.submission_number (per-application ordinals that match tens of thousands of unrelated records corpus-wide), and all four submissions.application_docs.{id,url,date,type} (opaque per-document values you must already possess in order to search by them). See docs/superpowers/notes/2026-09-20-field-selection.md (## drugsfda → "Deliberately not exposed") for the full reasoning. All seven remain reachable through the field-catalog resource a later release publishes, so nothing becomes unqueryable — they are simply no longer in the field enum.

Other behaviour changes:

  • Search-value injection is fixed. Every 1.x tool interpolated the caller's search value straight into the query string. A crafted value could append a clause and make the server report data for a different drug than the one named in its own matched_via — verified live: openfda.brand_name:"Advil" returns 39 records, openfda.brand_name:"Tylenol" returns 111, and the injected combination of the two returns 150. 2.0.0 escapes every value, and query assembly is confined to one file with a test enforcing it.

  • A search that matches nothing now returns a plain no-results message. Previously openFDA's HTTP 404 was reported as isError: true with "Failed to retrieve…", which was indistinguishable from an outage.

  • 'Unknown' placeholder strings are gone. Absent values are null or [], so a placeholder can no longer be mistaken for data.

  • get-drug-safety-info's scalar drug_name is now the array brand_name (on drug-label's detail: "safety").

  • Response headers are uniform across tools; the emoji/prose headers are gone.

  • Every response is capped at 60,000 characters, dropping trailing records and saying how many, rather than returning an unusable wall of text.

License

MIT

Buy me a Coffee

coff.ee/ythalorossy

Available Tools

7 tools
get-drug-adverse-eventsB

Get adverse event reports for a drug. This provides safety information about reported side effects and reactions. Use brand name or generic name.

ParametersJSON Schema
NameRequiredDescriptionDefault
drugNameYesDrug name (brand or generic)
limitNoMaximum number of events to return
seriousnessNoFilter by event seriousnessall

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions that the tool 'provides safety information about reported side effects and reactions,' which implies a read-only operation, but it doesn't disclose critical behavioral traits such as whether this is a query of a public database, potential rate limits, authentication needs, or what the output format looks like (e.g., list of events with details). This leaves significant gaps for an agent to understand how to handle the tool effectively.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized with three concise sentences that front-load the core purpose. Each sentence adds value: the first states the action, the second clarifies the type of information, and the third provides input guidance. There's no wasted text, making it efficient for quick understanding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (3 parameters, no output schema, no annotations), the description is somewhat complete but has gaps. It covers the purpose and basic input guidance but lacks details on behavioral aspects (e.g., output format, data source limitations) and doesn't leverage sibling context to clarify usage. Without annotations or output schema, more context on what to expect from the tool would improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters (drugName, limit, seriousness) with descriptions and defaults. The description adds minimal value by reiterating that drugName can be 'brand name or generic name,' which is already covered in the schema's description. It doesn't provide additional context like examples or usage tips beyond the schema, so it meets the baseline for high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb ('Get') and resource ('adverse event reports for a drug'), and it distinguishes the type of data (safety information about side effects and reactions). However, it doesn't explicitly differentiate from sibling tools like 'get-drug-safety-info', which might cover similar ground, so it falls short of a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides implied usage by specifying 'Use brand name or generic name' for the drugName parameter, which helps guide input. However, it lacks explicit guidance on when to use this tool versus alternatives like 'get-drug-safety-info' or other siblings, and it doesn't mention exclusions or prerequisites, leaving some ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-drug-by-generic-nameA

Get drug information by generic (active ingredient) name. Useful when you know the generic name but not the brand name. Returns all brand versions of the generic drug.

ParametersJSON Schema
NameRequiredDescriptionDefault
genericNameYesGeneric drug name (active ingredient)
limitNoMaximum number of results to return

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses that the tool returns 'all brand versions of the generic drug,' which adds useful behavioral context beyond the input schema. However, it lacks details on error handling, rate limits, authentication needs, or what specific information is included in the response. For a read-only tool with no annotations, this is adequate but not comprehensive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose, followed by usage context and return behavior. Every sentence adds value without redundancy, making it efficient and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (2 parameters, no output schema, no annotations), the description is reasonably complete. It covers purpose, usage context, and return behavior. However, without an output schema, it could benefit from more detail on the response format (e.g., structure of returned drug information).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already fully documents both parameters (genericName and limit). The description adds no additional parameter semantics beyond what the schema provides, such as format examples or constraints. Baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Get drug information by generic (active ingredient) name.' It specifies the verb ('Get'), resource ('drug information'), and key constraint ('by generic name'). It also distinguishes from siblings by emphasizing generic name lookup versus brand name or NDC-based alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool: 'Useful when you know the generic name but not the brand name.' This gives practical guidance. However, it does not explicitly state when not to use it or name specific alternatives among the sibling tools (e.g., get-drug-by-name for brand names).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-drug-by-nameA

Get drug by name. Use this tool to get the drug information by name. The drug name should be the brand name. It returns the brand name, generic name, manufacturer name, product NDC, product type, route, substance name, indications and usage, warnings, do not use, ask doctor, ask doctor or pharmacist, stop use, pregnancy or breast feeding.

ParametersJSON Schema
NameRequiredDescriptionDefault
drugNameYesDrug name

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It describes the return values (e.g., brand name, generic name, manufacturer name) and specifies that the input should be a brand name, which adds useful context. However, it doesn't cover potential errors, rate limits, or authentication needs, leaving gaps in behavioral transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and usage, followed by a detailed list of return values. While the list of return values is lengthy, each item is relevant to the tool's function. The structure is efficient, with no redundant sentences, though it could be slightly more concise by grouping related return categories.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (single parameter, no output schema, no annotations), the description is adequate but has gaps. It explains the purpose, input semantics, and return values, but lacks error handling, performance expectations, or integration with sibling tools. Without annotations or output schema, more behavioral context would improve completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, with the parameter 'drugName' documented as 'Drug name.' The description adds semantic value by clarifying that 'The drug name should be the brand name,' which provides crucial context beyond the schema. Since there's only one parameter, this compensation is effective, warranting a score above the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose as 'Get drug by name' and specifies it retrieves drug information, which is a specific verb+resource combination. However, it doesn't explicitly differentiate from sibling tools like 'get-drug-by-generic-name' or 'get-drug-by-ndc' beyond mentioning 'brand name' in the description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides some guidance by stating 'The drug name should be the brand name,' which implies when to use this tool versus alternatives like 'get-drug-by-generic-name.' However, it lacks explicit when-not-to-use instructions or clear alternatives, leaving usage context somewhat implied rather than fully articulated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-drug-by-ndcB

Get drug information by National Drug Code (NDC). Accepts both product NDC (XXXXX-XXXX) and package NDC (XXXXX-XXXX-XX) formats. Also accepts NDC codes without dashes.

ParametersJSON Schema
NameRequiredDescriptionDefault
ndcCodeYesNational Drug Code (NDC) - accepts formats: XXXXX-XXXX, XXXXX-XXXX-XX, or without dashes

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It describes the input formats but doesn't cover critical aspects like whether this is a read-only operation, potential rate limits, error handling, or what the output includes (e.g., drug details, availability). For a tool with no annotations, this leaves significant gaps in understanding its behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise and front-loaded, with three sentences that efficiently cover the tool's purpose and input handling. Every sentence adds value: the first states the purpose, the second specifies formats, and the third clarifies dash handling. There is no wasted text or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (a lookup with one parameter) and the lack of annotations and output schema, the description is incomplete. It doesn't explain what 'drug information' entails in the output, potential limitations, or how it integrates with sibling tools. For a tool with no structured output or behavioral hints, more context is needed to ensure effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, with the parameter 'ndcCode' fully documented in the schema. The description adds value by reiterating the acceptable formats (e.g., 'XXXXX-XXXX, XXXXX-XXXX-XX, or without dashes'), but this doesn't provide new semantic meaning beyond what's already in the schema. This meets the baseline of 3 for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Get drug information by National Drug Code (NDC).' It specifies the verb ('Get') and resource ('drug information'), and while it doesn't explicitly differentiate from siblings like 'get-drug-by-product-ndc', the focus on NDC codes provides some implicit distinction. However, it doesn't fully explain how it differs from 'get-drug-by-product-ndc', which might handle similar inputs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by detailing the acceptable NDC formats, suggesting when to use this tool (for NDC-based lookups). However, it provides no explicit guidance on when to choose this over alternatives like 'get-drug-by-product-ndc' or 'get-drug-by-name', nor does it mention any exclusions or prerequisites. The context is clear but lacks comparative direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-drug-by-product-ndcA

Get drug information by product NDC only (XXXXX-XXXX format). This ignores package variations and finds all packages for a product.

ParametersJSON Schema
NameRequiredDescriptionDefault
productNDCYesProduct NDC in format XXXXX-XXXX

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden but only states what the tool does operationally. It doesn't disclose behavioral traits like whether this is a read-only operation, what format the drug information returns, error handling, rate limits, or authentication requirements for a tool that accesses drug data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise with just two sentences that are front-loaded with the core purpose. Every word earns its place - the first sentence states what the tool does, and the second clarifies its scope and behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple lookup tool with 100% schema coverage but no annotations or output schema, the description adequately covers the basic operation. However, it doesn't address what 'drug information' includes, the response format, or potential limitations - gaps that become more significant without structured output documentation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents the single parameter's format. The description reinforces the format requirement but doesn't add meaningful semantic context beyond what the schema provides, such as examples of valid NDCs or what constitutes a 'product' versus 'package' NDC.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific verb ('Get drug information') and resource ('by product NDC'), and explicitly distinguishes from sibling tools by specifying it uses product NDC format and ignores package variations (unlike 'get-drug-by-ndc' which likely handles package-level NDCs).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context about when to use this tool ('by product NDC only') and what it does ('ignores package variations and finds all packages for a product'), but doesn't explicitly mention when NOT to use it or name specific alternatives among the sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-drug-safety-infoB

Get comprehensive safety information for a drug including warnings, contraindications, drug interactions, and precautions. Use brand name.

ParametersJSON Schema
NameRequiredDescriptionDefault
drugNameYesDrug brand name

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden for behavioral disclosure. While it mentions the tool 'gets' information (implying read-only), it doesn't explicitly state whether this requires authentication, has rate limits, what format the information returns in, or potential limitations. For a tool with no annotation coverage, this leaves significant behavioral gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately concise with two sentences that efficiently convey the tool's purpose and key usage requirement. The first sentence clearly states what the tool does, and the second provides necessary input guidance. No wasted words or unnecessary elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has no annotations, no output schema, and a simple single parameter, the description provides adequate basic information about purpose and input format. However, for a tool that returns 'comprehensive safety information', the description should ideally mention what format the information comes in (structured data, text summary, etc.) or any limitations, making it minimally complete but with clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with the single parameter 'drugName' clearly documented in the schema as 'Drug brand name'. The description adds minimal value beyond this by repeating 'Use brand name', which essentially restates what the schema already provides. Baseline 3 is appropriate when schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Get comprehensive safety information for a drug' with specific details about what information is included (warnings, contraindications, drug interactions, precautions). It distinguishes from some siblings by focusing on safety information rather than general drug lookup or adverse events, though it doesn't explicitly contrast with all siblings like 'get-drug-by-generic-name'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides some usage guidance: 'Use brand name' specifies the required input format. However, it doesn't explicitly state when to use this tool versus alternatives like 'get-drug-adverse-events' (which might focus on different safety aspects) or other drug lookup tools. The guidance is implied rather than explicit about tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get-drugs-by-manufacturerA

Get all drugs manufactured by a specific company. Useful for finding alternatives or checking manufacturer portfolios.

ParametersJSON Schema
NameRequiredDescriptionDefault
manufacturerNameYesManufacturer/company name
limitNoMaximum number of drugs to return

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions the tool 'Get all drugs' but does not specify behavioral traits like whether it returns a list, pagination details, error handling, or performance characteristics (e.g., rate limits). The description adds minimal context beyond the basic operation, leaving gaps in transparency for an agent to use it effectively.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose in the first sentence and adds useful context in the second, with no wasted words. Both sentences earn their place by clarifying the tool's function and typical use cases, making it efficient and well-structured for quick understanding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (a filtered list operation with 2 parameters), no annotations, and no output schema, the description is adequate but incomplete. It covers the purpose and usage context but lacks details on return values, error conditions, or behavioral nuances. This leaves the agent with gaps, especially since there's no output schema to clarify what the tool returns.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both parameters ('manufacturerName' and 'limit') well-documented in the schema. The description does not add any parameter-specific details beyond what the schema provides, such as format examples or constraints. Given the high schema coverage, the baseline score of 3 is appropriate, as the description does not compensate but also does not detract.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb ('Get') and resource ('all drugs manufactured by a specific company'), distinguishing it from siblings like 'get-drug-by-name' or 'get-drug-by-ndc' which focus on individual drug lookup rather than manufacturer-based filtering. It explicitly mentions the manufacturer scope, making the purpose distinct and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear usage context by stating it's 'Useful for finding alternatives or checking manufacturer portfolios,' which implicitly guides when to use this tool (e.g., for manufacturer-related queries). However, it does not explicitly mention when not to use it or name specific alternatives among sibling tools, such as preferring 'get-drug-by-name' for individual drug lookups, which prevents a score of 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 7 tool updates
    • First observedget-drug-adverse-events
    • First observedget-drug-by-generic-name
    • First observedget-drug-by-name
    • First observedget-drug-by-ndc
    • First observedget-drug-by-product-ndc
    • First observedget-drug-safety-info
    • First observedget-drugs-by-manufacturer

TDQS

A3.7/5.0

Scored across 7 tools

Disambiguation3/5

The tools have overlapping purposes that could cause confusion, particularly between get-drug-by-name, get-drug-by-generic-name, and get-drug-by-ndc, which all retrieve drug information but with different input parameters. Descriptions help clarify the distinctions, but an agent might misselect when the query is ambiguous about whether to use brand name, generic name, or NDC. The safety-focused tools (get-drug-adverse-events and get-drug-safety-info) are more distinct, but overall there is moderate overlap in the information retrieval tools.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern with hyphens, specifically 'get-drug-by-X' or 'get-drug-X', where X is a specific attribute like name, ndc, or safety-info. This predictability makes it easy for an agent to understand the naming convention and infer tool purposes. There are no deviations in style, such as mixing camelCase or snake_case, ensuring high readability and consistency throughout the set.

Tool Count5/5

With 7 tools, the server is well-scoped for its domain of drug information retrieval from OpenFDA. Each tool serves a distinct purpose, such as looking up drugs by different identifiers or accessing safety data, and none appear redundant or unnecessary. This count is typical for a focused API server, providing enough functionality without being overwhelming or too sparse, making it appropriate for the server's purpose.

Completeness4/5

The tool set covers the core domain of drug information retrieval comprehensively, including lookups by brand name, generic name, NDC, manufacturer, and safety data. Minor gaps exist, such as the lack of update or delete operations, but this is reasonable since OpenFDA is a read-only public database. Agents can work around these gaps, and the surface supports common queries without dead ends, though advanced features like filtering or pagination might be missing but are not essential for basic coverage.

Maintenance

ActivityMaintained
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • F
    license
    B
    quality
    D
    maintenance
    A comprehensive MCP server that provides access to U.S. FDA public datasets via the openFDA API, enabling querying of drug adverse events, labeling, recalls, approvals, shortages, NDC directory, and medical device regulatory data.
    10
    24
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    A Model Context Protocol (MCP) server exposing the FDA Purple Book — the database of licensed biological products (reference biologics, biosimilars, and interchangeables), with BLA numbers, applicants, approval dates, and exclusivity expiry.
    -