Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

io.github.cyanheads/openfda-mcp-server

REMOTE · OPENFDA.CASEYJHAND.COM · 2 COMPONENTS · SCANNED SEP 20

Query FDA data on drugs, food, devices, and recalls via openFDA. STDIO or Streamable HTTP.

0 this week 79 Trust /100
Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →

Endpoint Security66
  • The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
  • Authorisation not fully verified: no authorisation is required to call this server, and 14 tool(s) never declared a destructiveHint. The MCP spec treats an absent hint as destructive by default, so we cannot call this surface safe. See how to fix → View diagnostics → Unverified
  • HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
  • The HSTS (Strict-Transport-Security) header is present. View diagnostics → Pass
  • DNSSEC is configured correctly; the domain's records validate against the full chain to the root. View diagnostics → Pass
Transport & Reachability100
Schema Quality & AI Usability61
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 5879 tokens (~419/item across 14 items; 14 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management100
  • No destabilizing schema changes in the last 30 days.Pass
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 100% of tool parameters carry a description.Pass
  • Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • We read all 14 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
  • An AI judge read all 15 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a current MCP spec version (2026-07-28).Pass
Install

How do I install the io.github.cyanheads/openfda-mcp-server server?

io.github.cyanheads/openfda-mcp-server is a hosted endpoint at https://openfda.caseyjhand.com/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

remote · openfda.caseyjhand.com

# add to Claude Code
claude mcp add --transport http cyanheads-openfda-mcp-server 'https://openfda.caseyjhand.com/mcp'
// .cursor/mcp.json
{
  "mcpServers": {
    "cyanheads-openfda-mcp-server": {
      "url": "https://openfda.caseyjhand.com/mcp"
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "cyanheads-openfda-mcp-server": {
      "type": "http",
      "url": "https://openfda.caseyjhand.com/mcp"
    }
  }
}
# ~/.codex/config.toml
[mcp_servers.cyanheads-openfda-mcp-server]
url = "https://openfda.caseyjhand.com/mcp"
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "cyanheads-openfda-mcp-server": {
      "type": "remote",
      "url": "https://openfda.caseyjhand.com/mcp",
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add cyanheads-openfda-mcp-server --url 'https://openfda.caseyjhand.com/mcp' --transport streamable-http
# ~/.hermes/config.yaml
mcp_servers:
  cyanheads-openfda-mcp-server:
    url: "https://openfda.caseyjhand.com/mcp"
// ~/.netclaw/config/netclaw.json
{
  "McpServers": {
    "cyanheads-openfda-mcp-server": {
      "Transport": "http",
      "Url": "https://openfda.caseyjhand.com/mcp"
    }
  }
}
# add to Vellum
assistant mcp add cyanheads-openfda-mcp-server -t streamable-http -u 'https://openfda.caseyjhand.com/mcp'
// mcp.json
{
  "mcpServers": {
    "cyanheads-openfda-mcp-server": {
      "type": "http",
      "url": "https://openfda.caseyjhand.com/mcp"
    }
  }
}

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 16 Sept 26 0
    • Server version: 0.7.4 → 0.7.5 functional
  • 9 Sept 26 0
    • Stability: 0.97 → pass security
  • 8 Sept 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 93 to 97. That category is still filling its 30-day observation window: 28 days of observed history at the previous scan, 29 at this one. The score rises as the window fills, whether or not the server changes.

  • 7 Sept 26 −1
    • Stability: pass → 0.93 functional
  • 26 Aug 26 0
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 25 Aug 26 +1
    • Stability: 0.97 → pass security
    • MCP protocol: Implements a current MCP spec version (2026-07-28). functional
    • MCP protocol version: 2025-11-25 → 2026-07-28 functional
    • Server version: 0.7.3 → 0.7.4 functional
  • 23 Aug 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 90 to 93. That category is still filling its 30-day observation window: 27 days of observed history at the previous scan, 28 at this one. The score rises as the window fills, whether or not the server changes.

  • 11 Aug 26 0
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 20 Sept 2026 · Probed https://openfda.caseyjhand.com/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=caseyjhand.com CN=WE1,O=Google Trust Services,C=US 4 Sept 2026 3 Dec 2026 ECDSA 256 ECDSA-SHA256 a6985204ed51ae050e7738aa6be668e9
SANs: caseyjhand.com, *.caseyjhand.com
CN=WE1,O=Google Trust Services,C=US (CA) CN=GTS Root R4,O=Google Trust Services LLC,C=US 13 Dec 2023 20 Feb 2029 ECDSA 256 ECDSA-SHA384 7ff31977972c224a76155d13b6d685e3
CN=GTS Root R4,O=Google Trust Services LLC,C=US (CA) CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE 15 Nov 2023 28 Jan 2028 ECDSA 384 SHA256-RSA 7fe530bf331343bedd821610493d8a1b

Background: What to check on a remote MCP endpoint →

DNSSEC secure

Validation of openfda.caseyjhand.com. Secure

Zone DS Keys Algorithms Outcome
. trust_anchor 20326, 38696 8, 8 Verified
com. present 19718 13 Verified
caseyjhand.com. present 2371 13 Verified
openfda.caseyjhand.com. Verified address RRset verified with the apex keys
Authentication No authorisation required

The endpoint answered without asking for a token. Anyone who knows the URL can reach it.

Result No authorisation required
HTTP status 200
Header Value
strict-transport-security max-age=63072000; includeSubDomains; preload
x-content-type-options nosniff

Background: How OAuth 2.1 works in the 2026 MCP spec →

Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://openfda.caseyjhand.com/mcp Verified 200
http (plaintext) http://openfda.caseyjhand.com/mcp HTTPS enforced 301 https://openfda.caseyjhand.com/mcp
MCP tools · 14 exposed · ~5,777 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
openfda_count_values ~281

Aggregate and tally unique values for any field across any openFDA endpoint. Returns ranked term-count pairs sorted by count descending. Pair with openfda_search_adverse_events, openfda_search_drug_approvals, openfda_search_device_clearances, openfda_search_recalls, openfda_get_drug_label, or openfda_lookup_ndc when sample records help interpret the aggregates.

NameTypeReqDescription
countstringyesField to count. Append .exact for whole-phrase counting of free-text fields (e.g. "patient.reaction.reactionmeddrapt.exact"). Identifier fields openFDA already indexes as keywords (product_ndc, appli…
endpointstringyesFull openFDA endpoint path (e.g. "drug/event", "device/classification")
limitnumberNumber of top terms to return (default 100, max 1000)
searchstringFilter query to scope the count (e.g. patient.drug.medicinalproduct:"metformin"). Omit to count across every record in the endpoint. Double quotes, parentheses, and range brackets must balance, and t…
NameTypeReqDescription
capnumberThe limit applied to the term list.
errorobjectPresent when the call failed. Absent on success.
metaobjectResponse metadata
noticestringGuidance when no terms matched — how to verify the field name or adjust the count expression. Absent when terms are returned.
resultsarrayTerm-count pairs sorted by count descending
shownnumberNumber of terms returned in this response.
termCountnumberNumber of distinct terms returned
truncatedbooleanTrue when the term list was capped at the limit — more distinct terms may exist.
truncationCeilingnumberCount of the lowest-ranked term returned — omitted terms fall at or below it.

No examples provided.

openfda_dataframe_describe ~116

List the tables and column schemas on a DataCanvas staged by an openFDA search tool. Call before openfda_dataframe_query to discover the exact table name, column names, and DuckDB types needed for valid SQL. row_count is the full staged result set, not the inline preview count. Columns typed JSON hold nested openFDA objects/arrays — query them with DuckDB json functions.

NameTypeReqDescription
canvas_idstringyesCanvas ID from an openFDA search tool response (present when the search ran with stage=true).
NameTypeReqDescription
canvas_idstringCanvas ID that was described — pass to openfda_dataframe_query.
errorobjectPresent when the call failed. Absent on success.
tablesarrayAll tables and views available on this canvas.

No examples provided.

openfda_dataframe_query ~260

Run a read-only SQL SELECT against a DataCanvas table staged by an openFDA search tool (call one with stage=true; its response carries canvas_id + canvas_table). Enables GROUP BY, COUNT/SUM/AVG, time-series, and joins across the staged result set without re-paging the API. Call openfda_dataframe_describe first to get the exact table and column names. Results are capped at the canvas row limit — when truncated is true, page the rest with ORDER BY plus LIMIT/OFFSET. Scalar fields are stored as text (CAST for numeric math); nested objects/arrays are JSON columns — read them with DuckDB json functions, e.g. json_extract_string(openfda, '$.brand_name[0]'). Only SELECT is allowed — DDL, DML, COPY, and file-reading functions are blocked.

NameTypeReqDescription
canvas_idstringyesCanvas ID from an openFDA search tool response (the canvas_id field, present when the search ran with stage=true).
querystringyesSQL SELECT against the staged table. Use the table name from openfda_dataframe_describe. Example: "SELECT classification, COUNT(*) AS n FROM spilled_ab12cd34 GROUP BY classification ORDER BY n DESC".
NameTypeReqDescription
canvas_idstringCanvas ID that was queried — reuse for follow-up queries.
errorobjectPresent when the call failed. Absent on success.
row_countnumberNumber of rows in this response. Equals the canvas row limit when truncated is true.
rowsarrayRows returned by the query (capped at the canvas row limit).
truncatedbooleanTrue when the result hit the canvas row limit and rows beyond it were dropped. Page the rest with ORDER BY plus LIMIT/OFFSET.

No examples provided.

openfda_describe_fields ~101

Return the searchable field paths for an openFDA endpoint, grouped by category with type and description. Use before constructing a search query to find the correct dotted field path — field names differ per endpoint and are not discoverable from the tool schema alone.

NameTypeReqDescription
endpointstringyesopenFDA endpoint to describe (e.g. "drug/event", "drug/shortages", "device/510k"). Must be one of the cataloged endpoints.
NameTypeReqDescription
endpointstringThe endpoint these fields apply to
errorobjectPresent when the call failed. Absent on success.
groupsarrayField groups for this endpoint
queryTipsstringopenFDA query syntax reminders relevant to this endpoint

No examples provided.

openfda_drug_profile ~200

Resolve one drug name to its FDA identity, then fan out in parallel across the bounded per-drug openFDA endpoints and merge into one profile: identity, label highlights, adverse-event summary, recall history, Drugs@FDA approval, and shortage status. Replaces chaining openfda_get_drug_label, openfda_search_adverse_events, openfda_search_recalls, openfda_search_drug_approvals, and openfda_search_drug_shortages — and reconciles the identifier drift between endpoints that makes that chaining error-prone. Each section is best-effort: a miss returns null rather than failing the call. For deep dives into any one area, use the dedicated tool.

NameTypeReqDescription
drugstringyesDrug name to profile — brand or generic (e.g. "metformin", "Humira", "Glucophage"). Resolved once to canonical FDA identifiers, which then key every sub-query.
NameTypeReqDescription
adverse_eventsAdverse-event summary aggregated over drug/event, or null when unavailable.
approvalDrugs@FDA approval summary, or null when no application matched.
degradedarraySub-queries that failed upstream, empty when every section resolved. A section listed here is unknown, not absent — a null section with no entry here genuinely has no FDA record.
errorobjectPresent when the call failed. Absent on success.
identityobjectIdentity resolved once and reused across every sub-query to avoid identifier drift.
labelLabel highlights from drug/label, or null when no label matched.
metaobjectRequest metadata.
noticestringGuidance when the drug could not be resolved or upstream errors degraded the profile. Absent on a fully populated profile.
recallsarrayRecent drug/enforcement recall actions (may be empty).
sectionsFoundnumberHow many profile sections (label, adverse_events, recalls, approval, shortage) returned data.
shortageCurrent or most-recent drug shortage status, or null when none on record.

No examples provided.

openfda_get_drug_label ~468

Look up FDA drug labeling (package inserts / SPL documents). Check indications, warnings, dosage, contraindications, active ingredients, or any structured label section. A label runs to tens of thousands of tokens, so a page that exceeds the inline budget returns the list of available sections instead; re-call with sections to pull the ones you need.

NameTypeReqDescription
limitnumberMaximum number of results to return (1-1000). Default 5. Labels are large, and the cost of a sections selection is the section summed across every record on the page — so it scales with this limit. L…
searchstringyesQuery targeting label fields. Examples: openfda.brand_name:"aspirin", openfda.generic_name:"metformin", openfda.manufacturer_name:"pfizer". For a specific revision, pass set_id with the SPL UUID retu…
sectionsarrayLabel sections to return, e.g. ["boxed_warning","indications_and_usage"]. Names come from the outline an oversized page returns, or from openfda_describe_fields. Omit for the whole label — which retu…
skipnumberNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortstringSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: effective_time:desc. Field paths take only letters, digits, underscores, and dots;…
NameTypeReqDescription
capnumberThe limit applied to this page.
effectiveQuerystringSearch filter applied to the drug label query, as submitted to openFDA
errorobjectPresent when the call failed. Absent on success.
kindstringWhether this response carries label records ("full") or only the section outline of a page too large to inline ("outline").
metaobjectPagination and freshness metadata.
noticestringGuidance for this page: how to broaden filters or correct field names when results are empty or paging overshot, the sized re-call example when a page overflowed to its section outline, section names…
outlinearraySection names available across the matched page and their serialized size, largest first. Present when kind is "outline" — pass names back in sections to retrieve them.
resultsarrayDrug label records, present when kind is "full". Each carries an openfda block (brand_name, generic_name, manufacturer_name, route) plus optional SPL sections like indications_and_usage, warnings, do…
shownnumberNumber of labels returned in this response.
totalResultsnumberTotal matching label records in the dataset
truncatedbooleanTrue when more labels matched than this page returned — page with skip for the rest.

No examples provided.

openfda_lookup_ndc ~540

Look up drugs in the NDC (National Drug Code) Directory. Identify drug products by NDC code, find active ingredients, packaging details, or manufacturer info. Pair with openfda_get_drug_label using the returned brand_name or set_id to read the package insert.

NameTypeReqDescription
canvas_idstringDataCanvas session id from a prior call. Passing one stages this lookup onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.
limitnumberMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized b…
searchstringyesopenFDA search query. Examples: product_ndc:"0363-0218", brand_name:"aspirin", generic_name:"metformin", openfda.manufacturer_name:"walgreen", active_ingredients.name:"ASPIRIN". Double quotes, parent…
skipnumberNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortstringSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: listing_expiration_date:desc. Field paths take only letters, digits, underscores,…
stagebooleanStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a can…
NameTypeReqDescription
canvas_idstringDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the s…
canvas_tablestringCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
effectiveQuerystringSearch filter applied to the NDC lookup, as submitted to openFDA
errorobjectPresent when the call failed. Absent on success.
metaobjectResponse metadata
noticestringCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty — how to broade…
page_bytesnumberSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
page_omittednumberRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of record…
resultsarrayNDC directory records — product_ndc, brand_name, generic_name, labeler_name, dosage_form, route, marketing_category, active_ingredients[], packaging[], listing_expiration_date.
spilledbooleanTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
staged_rowsnumberRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
totalResultsnumberTotal matching NDC records in the dataset
truncatedbooleanTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.

No examples provided.

openfda_search_adverse_events ~572

Search adverse event reports across drugs, food, and devices. Use to investigate safety signals, find reports for a specific product, or explore reactions by demographics.

NameTypeReqDescription
canvas_idstringDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.
categorystringyesProduct category — each has different field schemas in the response
limitnumberMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized b…
searchstringopenFDA search query. Examples: patient.drug.medicinalproduct:"aspirin", patient.reaction.reactionmeddrapt:"nausea" AND serious:"1". Omit to browse recent. Double quotes, parentheses, and range brack…
skipnumberNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortstringSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Field paths take only letters, digits, underscores, and dots; anything else is rejected bef…
stagebooleanStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a can…
NameTypeReqDescription
canvas_idstringDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the s…
canvas_tablestringCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
effectiveQuerystringSearch filter applied to the query, as submitted to openFDA
errorobjectPresent when the call failed. Absent on success.
metaobjectResponse metadata
noticestringCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty or paging overs…
page_bytesnumberSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
page_omittednumberRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of record…
resultsarrayAdverse event records — fields vary by category (drug: patient/reactions/drugs, device: device details/event type, food: products/outcomes)
spilledbooleanTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
staged_rowsnumberRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
totalResultsnumberTotal matching adverse event records in the dataset
truncatedbooleanTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.

No examples provided.

openfda_search_animal_events ~525

Search adverse event reports for veterinary drugs and devices submitted to the FDA Center for Veterinary Medicine. Records include animal species, breed, age, weight, drug name and route, adverse reactions (using VeDDRA terminology), and outcome. Use to investigate safety signals for veterinary products, find reports by animal species or drug, or explore reaction patterns.

NameTypeReqDescription
canvas_idstringDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.
limitnumberMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized b…
searchstringopenFDA search query using field:value syntax. Examples: animal.species:"Dog", drug.brand_name:"Bravecto", reaction.veddra_term_name:"Vomiting", serious_ae:"true". Omit to browse recent reports. Doub…
skipnumberNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortstringSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: original_receive_date:desc. Field paths take only letters, digits, underscores, an…
stagebooleanStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a can…
NameTypeReqDescription
canvas_idstringDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the s…
canvas_tablestringCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
effectiveQuerystringSearch filter applied to the query, as submitted to openFDA
errorobjectPresent when the call failed. Absent on success.
metaobjectResponse metadata
noticestringCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty or paging overs…
page_bytesnumberSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
page_omittednumberRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of record…
resultsarrayAnimal adverse event records. Key fields: unique_aer_id_number, original_receive_date, serious_ae, animal (species, gender, breed, age, weight), drug[] (brand_name, active_ingredients, route, dose, a…
spilledbooleanTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
staged_rowsnumberRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
totalResultsnumberTotal matching animal adverse event records in the dataset
truncatedbooleanTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.

No examples provided.

openfda_search_device_clearances ~518

Search FDA device premarket notifications — 510(k) clearances and PMA approvals.

NameTypeReqDescription
canvas_idstringDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.
limitnumberMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized b…
pathwaystringyesPremarket pathway. 510(k) is the most common; PMA is for higher-risk devices.
searchstringopenFDA search query. Examples: applicant:"medtronic", advisory_committee_description:"cardiovascular", product_code:"DXN", openfda.device_name:"catheter". Omit to browse recent. Double quotes, paren…
skipnumberNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortstringSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: decision_date:desc. Field paths take only letters, digits, underscores, and dots;…
stagebooleanStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a can…
NameTypeReqDescription
canvas_idstringDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the s…
canvas_tablestringCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
effectiveQuerystringSearch filter applied to the device clearance query, as submitted to openFDA
errorobjectPresent when the call failed. Absent on success.
metaobjectResponse metadata
noticestringCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty — how to broade…
page_bytesnumberSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
page_omittednumberRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of record…
resultsarray510(k) or PMA records — 510(k) carries k_number, device_name, applicant, product_code, decision_date, decision_description, advisory_committee_description; PMA carries pma_number, trade_name, generic…
spilledbooleanTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
staged_rowsnumberRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
totalResultsnumberTotal matching device clearance records in the dataset
truncatedbooleanTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.

No examples provided.

openfda_search_drug_approvals ~579

Search the Drugs@FDA database for drug application approvals (NDAs and ANDAs). Returns application details, sponsor info, and full submission history. Pair with openfda_get_drug_label to read the approved label, or openfda_count_values to aggregate by sponsor_name, product_type, or route.

NameTypeReqDescription
canvas_idstringDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.
limitnumberMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized b…
searchstringopenFDA search query. Examples: openfda.brand_name:"humira", sponsor_name:"PFIZER", submissions.submission_type:"ORIG" AND submissions.review_priority:"PRIORITY". Exact quoted values can be case-sens…
skipnumberNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortstringSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: submissions.submission_status_date:desc. Field paths take only letters, digits, un…
stagebooleanStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a can…
NameTypeReqDescription
canvas_idstringDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the s…
canvas_tablestringCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
effectiveQuerystringSearch filter applied to the Drugs@FDA query, as submitted to openFDA
errorobjectPresent when the call failed. Absent on success.
metaobjectResponse metadata
noticestringCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty — how to broade…
page_bytesnumberSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
page_omittednumberRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of record…
resultsarrayDrug application records — application_number, sponsor_name, openfda block (brand_name, generic_name, route, product_type, substance_name), products[] (active_ingredients, dosage_form, marketing_stat…
spilledbooleanTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
staged_rowsnumberRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
totalResultsnumberTotal matching drug approval records in the dataset
truncatedbooleanTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.

No examples provided.

openfda_search_drug_shortages ~555

Search FDA drug shortage records. Returns per-product shortage status, availability, therapeutic category, dosage form, manufacturer, and dates. Use to check whether a drug is currently in shortage, find all oncology drugs with supply issues, or retrieve the openfda block (brand_name, product_ndc, rxcui) to chain into openfda_get_drug_label or openfda_lookup_ndc.

NameTypeReqDescription
canvas_idstringDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.
limitnumberMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized b…
searchstringopenFDA search query using field:value syntax. Examples: status:"Current", therapeutic_category:"Oncology", generic_name:"carboplatin", company_name:"pfizer". Omit to browse all records. Double quote…
skipnumberNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortstringSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: update_date:desc. Field paths take only letters, digits, underscores, and dots; an…
stagebooleanStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a can…
NameTypeReqDescription
canvas_idstringDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the s…
canvas_tablestringCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
effectiveQuerystringSearch filter applied to the drug/shortages query, as submitted to openFDA
errorobjectPresent when the call failed. Absent on success.
metaobjectResponse metadata
noticestringCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty — how to broade…
page_bytesnumberSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
page_omittednumberRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of record…
resultsarrayDrug shortage records. Key fields: generic_name, status ("Current"/"Resolved"), availability, therapeutic_category, dosage_form, presentation, package_ndc, company_name, contact_info, initial_posting…
spilledbooleanTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
staged_rowsnumberRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
totalResultsnumberTotal matching drug shortage records in the dataset
truncatedbooleanTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.

No examples provided.

openfda_search_recalls ~532

Search enforcement reports and recall actions across drugs, food, and devices.

NameTypeReqDescription
canvas_idstringDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.
categorystringyesProduct category
endpointstringReport type. Default enforcement. The recall endpoint is only available for devices.
limitnumberMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized b…
searchstringopenFDA search query. Examples: classification:"Class I" (also "Class II" or "Class III"), recalling_firm:"pfizer", reason_for_recall:"undeclared allergen". Omit to browse recent. Double quotes, pare…
skipnumberNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortstringSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort (e.g. report_date:desc,status.exact:asc). Field paths take only letters, digits, underscores…
stagebooleanStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a can…
NameTypeReqDescription
canvas_idstringDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the s…
canvas_tablestringCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
effectiveQuerystringSearch filter applied to the recall query, as submitted to openFDA
errorobjectPresent when the call failed. Absent on success.
metaobjectResponse metadata
noticestringCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty — how to broade…
page_bytesnumberSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
page_omittednumberRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of record…
resultsarrayEnforcement or recall records — recall_number, classification, recalling_firm, product_description, reason_for_recall, status, voluntary_mandated, distribution_pattern, report_date. Field set varies…
spilledbooleanTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
staged_rowsnumberRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
totalResultsnumberTotal matching recall/enforcement records in the dataset
truncatedbooleanTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.

No examples provided.

openfda_search_tobacco_reports ~530

Search problem reports submitted to the FDA for tobacco products, including e-cigarettes, vaping products, cigarettes, and smokeless tobacco. Reports capture product type, reported health problems (e.g. seizure, chest pain), product problems (e.g. exploding battery), whether a non-user was affected, and submission date. Use to investigate safety signals, find reports by product type, or analyze health effects.

NameTypeReqDescription
canvas_idstringDataCanvas session id from a prior call. Passing one stages this search onto that canvas (same effect as stage=true) so result sets accumulate for cross-table joins. Omit to stage onto a fresh canvas.
limitnumberMaximum number of records to return (1-1000, default 10). Serialized record size varies by three orders of magnitude across openFDA endpoints, so the page is also bounded by a 24000-byte serialized b…
searchstringopenFDA search query using field:value syntax. Examples: tobacco_products:"Electronic cigarette", reported_health_problems:"Seizure", nonuser_affected:"Yes". Omit to browse recent reports. Double quo…
skipnumberNumber of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error.
sortstringSort expression — a field path optionally suffixed with :asc or :desc; comma-separate for multi-field sort. Example: date_submitted:desc. Field paths take only letters, digits, underscores, and dots;…
stagebooleanStage the matched set on a DataCanvas for SQL analysis with openfda_dataframe_query. Default false — the call returns one page for one upstream request. When true, records are also drained onto a can…
NameTypeReqDescription
canvas_idstringDataCanvas session id for the staged result set. Present when this call staged. Pass to openfda_dataframe_query / openfda_dataframe_describe, or back into this tool to accumulate more tables on the s…
canvas_tablestringCanvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses.
effectiveQuerystringSearch filter applied to the query, as submitted to openFDA
errorobjectPresent when the call failed. Absent on success.
metaobjectResponse metadata
noticestringCanvas staging disclosure when the call staged, the byte-budget disclosure and the routes to the withheld records when the inline page was bounded, and guidance when results are empty or paging overs…
page_bytesnumberSerialized size of results in this response, in bytes. Present only when the 24000-byte inline budget bounded the page; larger than the budget only when a single record exceeds it on its own.
page_omittednumberRecords dropped from the requested limit/skip window so the page fit the inline byte budget. Present only when the page was bounded. Read them by re-calling with skip advanced by the number of record…
resultsarrayTobacco problem report records. Key fields: report_id, date_submitted, tobacco_products[] (product type description), reported_health_problems[] (health effects), reported_product_problems[] (device/…
spilledbooleanTrue when this call staged its matched set on the canvas — use canvas_id with openfda_dataframe_query for SQL. Absent when staging was not requested.
staged_rowsnumberRows written to the canvas table. Compare with meta.total: a smaller value means staging stopped at its size budget and the table holds only the first staged_rows records.
totalResultsnumberTotal matching tobacco problem reports in the dataset
truncatedbooleanTrue when fewer rows reached the canvas than matched upstream — staging stopped at its size budget or openFDA's 25000-row pagination ceiling. Narrow the query (filters, date range) for a complete set.

No examples provided.

Common questions

What is the io.github.cyanheads/openfda-mcp-server server?

io.github.cyanheads/openfda-mcp-server is listed in the public MCP registry as io.github.cyanheads/openfda-mcp-server. Query FDA data on drugs, food, devices, and recalls via openFDA. STDIO or Streamable HTTP. This page covers its hosted endpoint (https://openfda.caseyjhand.com/mcp).

Is the io.github.cyanheads/openfda-mcp-server server safe to use?

io.github.cyanheads/openfda-mcp-server scores 79 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the io.github.cyanheads/openfda-mcp-server server expose?

io.github.cyanheads/openfda-mcp-server exposes 14 tools: openfda_search_adverse_events, openfda_search_animal_events, openfda_search_drug_shortages, openfda_search_recalls, openfda_search_tobacco_reports, and 9 more. Their descriptions and schemas cost roughly 5,777 tokens of context every time the server is loaded.

Does the io.github.cyanheads/openfda-mcp-server server require authentication?

No. We connected to io.github.cyanheads/openfda-mcp-server without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

Is the io.github.cyanheads/openfda-mcp-server server still maintained?

io.github.cyanheads/openfda-mcp-server is still listed as active in the MCP registry. We last reached this channel on 20 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.