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.
Available components
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
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
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
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
claude mcp add --transport http cyanheads-openfda-mcp-server 'https://openfda.caseyjhand.com/mcp'
{
"mcpServers": {
"cyanheads-openfda-mcp-server": {
"url": "https://openfda.caseyjhand.com/mcp"
}
}
} {
"servers": {
"cyanheads-openfda-mcp-server": {
"type": "http",
"url": "https://openfda.caseyjhand.com/mcp"
}
}
} [mcp_servers.cyanheads-openfda-mcp-server] url = "https://openfda.caseyjhand.com/mcp"
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"cyanheads-openfda-mcp-server": {
"type": "remote",
"url": "https://openfda.caseyjhand.com/mcp",
"enabled": true
}
}
} openclaw mcp add cyanheads-openfda-mcp-server --url 'https://openfda.caseyjhand.com/mcp' --transport streamable-http
mcp_servers:
cyanheads-openfda-mcp-server:
url: "https://openfda.caseyjhand.com/mcp" {
"McpServers": {
"cyanheads-openfda-mcp-server": {
"Transport": "http",
"Url": "https://openfda.caseyjhand.com/mcp"
}
}
} assistant mcp add cyanheads-openfda-mcp-server -t streamable-http -u 'https://openfda.caseyjhand.com/mcp'
{
"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.
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
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 |
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 →
openfda_count_values 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.
| Name | Type | Req | Description |
|---|---|---|---|
| count | string | yes | Field 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… |
| endpoint | string | yes | Full openFDA endpoint path (e.g. "drug/event", "device/classification") |
| limit | number | – | Number of top terms to return (default 100, max 1000) |
| search | string | – | Filter 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… |
| Name | Type | Req | Description |
|---|---|---|---|
| cap | number | – | The limit applied to the term list. |
| error | object | – | Present when the call failed. Absent on success. |
| meta | object | – | Response metadata |
| notice | string | – | Guidance when no terms matched — how to verify the field name or adjust the count expression. Absent when terms are returned. |
| results | array | – | Term-count pairs sorted by count descending |
| shown | number | – | Number of terms returned in this response. |
| termCount | number | – | Number of distinct terms returned |
| truncated | boolean | – | True when the term list was capped at the limit — more distinct terms may exist. |
| truncationCeiling | number | – | Count of the lowest-ranked term returned — omitted terms fall at or below it. |
No examples provided.
openfda_dataframe_describe 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.
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | yes | Canvas ID from an openFDA search tool response (present when the search ran with stage=true). |
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | Canvas ID that was described — pass to openfda_dataframe_query. |
| error | object | – | Present when the call failed. Absent on success. |
| tables | array | – | All tables and views available on this canvas. |
No examples provided.
openfda_dataframe_query 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.
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | yes | Canvas ID from an openFDA search tool response (the canvas_id field, present when the search ran with stage=true). |
| query | string | yes | SQL 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". |
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | Canvas ID that was queried — reuse for follow-up queries. |
| error | object | – | Present when the call failed. Absent on success. |
| row_count | number | – | Number of rows in this response. Equals the canvas row limit when truncated is true. |
| rows | array | – | Rows returned by the query (capped at the canvas row limit). |
| truncated | boolean | – | True 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 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.
| Name | Type | Req | Description |
|---|---|---|---|
| endpoint | string | yes | openFDA endpoint to describe (e.g. "drug/event", "drug/shortages", "device/510k"). Must be one of the cataloged endpoints. |
| Name | Type | Req | Description |
|---|---|---|---|
| endpoint | string | – | The endpoint these fields apply to |
| error | object | – | Present when the call failed. Absent on success. |
| groups | array | – | Field groups for this endpoint |
| queryTips | string | – | openFDA query syntax reminders relevant to this endpoint |
No examples provided.
openfda_drug_profile 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.
| Name | Type | Req | Description |
|---|---|---|---|
| drug | string | yes | Drug name to profile — brand or generic (e.g. "metformin", "Humira", "Glucophage"). Resolved once to canonical FDA identifiers, which then key every sub-query. |
| Name | Type | Req | Description |
|---|---|---|---|
| adverse_events | – | – | Adverse-event summary aggregated over drug/event, or null when unavailable. |
| approval | – | – | Drugs@FDA approval summary, or null when no application matched. |
| degraded | array | – | Sub-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. |
| error | object | – | Present when the call failed. Absent on success. |
| identity | object | – | Identity resolved once and reused across every sub-query to avoid identifier drift. |
| label | – | – | Label highlights from drug/label, or null when no label matched. |
| meta | object | – | Request metadata. |
| notice | string | – | Guidance when the drug could not be resolved or upstream errors degraded the profile. Absent on a fully populated profile. |
| recalls | array | – | Recent drug/enforcement recall actions (may be empty). |
| sectionsFound | number | – | How many profile sections (label, adverse_events, recalls, approval, shortage) returned data. |
| shortage | – | – | Current or most-recent drug shortage status, or null when none on record. |
No examples provided.
openfda_get_drug_label 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.
| Name | Type | Req | Description |
|---|---|---|---|
| limit | number | – | Maximum 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… |
| search | string | yes | Query 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… |
| sections | array | – | Label 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… |
| skip | number | – | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. |
| sort | string | – | Sort 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;… |
| Name | Type | Req | Description |
|---|---|---|---|
| cap | number | – | The limit applied to this page. |
| effectiveQuery | string | – | Search filter applied to the drug label query, as submitted to openFDA |
| error | object | – | Present when the call failed. Absent on success. |
| kind | string | – | Whether this response carries label records ("full") or only the section outline of a page too large to inline ("outline"). |
| meta | object | – | Pagination and freshness metadata. |
| notice | string | – | Guidance 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… |
| outline | array | – | Section 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. |
| results | array | – | Drug 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… |
| shown | number | – | Number of labels returned in this response. |
| totalResults | number | – | Total matching label records in the dataset |
| truncated | boolean | – | True when more labels matched than this page returned — page with skip for the rest. |
No examples provided.
openfda_lookup_ndc 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.
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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. |
| limit | number | – | Maximum 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… |
| search | string | yes | openFDA search query. Examples: product_ndc:"0363-0218", brand_name:"aspirin", generic_name:"metformin", openfda.manufacturer_name:"walgreen", active_ingredients.name:"ASPIRIN". Double quotes, parent… |
| skip | number | – | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. |
| sort | string | – | Sort 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,… |
| stage | boolean | – | Stage 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… |
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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_table | string | – | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| effectiveQuery | string | – | Search filter applied to the NDC lookup, as submitted to openFDA |
| error | object | – | Present when the call failed. Absent on success. |
| meta | object | – | Response metadata |
| notice | string | – | Canvas 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_bytes | number | – | Serialized 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_omitted | number | – | Records 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… |
| results | array | – | NDC directory records — product_ndc, brand_name, generic_name, labeler_name, dosage_form, route, marketing_category, active_ingredients[], packaging[], listing_expiration_date. |
| spilled | boolean | – | True 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_rows | number | – | Rows 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. |
| totalResults | number | – | Total matching NDC records in the dataset |
| truncated | boolean | – | True 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 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.
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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. |
| category | string | yes | Product category — each has different field schemas in the response |
| limit | number | – | Maximum 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… |
| search | string | – | openFDA search query. Examples: patient.drug.medicinalproduct:"aspirin", patient.reaction.reactionmeddrapt:"nausea" AND serious:"1". Omit to browse recent. Double quotes, parentheses, and range brack… |
| skip | number | – | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. |
| sort | string | – | Sort 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… |
| stage | boolean | – | Stage 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… |
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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_table | string | – | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| effectiveQuery | string | – | Search filter applied to the query, as submitted to openFDA |
| error | object | – | Present when the call failed. Absent on success. |
| meta | object | – | Response metadata |
| notice | string | – | Canvas 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_bytes | number | – | Serialized 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_omitted | number | – | Records 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… |
| results | array | – | Adverse event records — fields vary by category (drug: patient/reactions/drugs, device: device details/event type, food: products/outcomes) |
| spilled | boolean | – | True 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_rows | number | – | Rows 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. |
| totalResults | number | – | Total matching adverse event records in the dataset |
| truncated | boolean | – | True 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 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.
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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. |
| limit | number | – | Maximum 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… |
| search | string | – | openFDA 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… |
| skip | number | – | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. |
| sort | string | – | Sort 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… |
| stage | boolean | – | Stage 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… |
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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_table | string | – | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| effectiveQuery | string | – | Search filter applied to the query, as submitted to openFDA |
| error | object | – | Present when the call failed. Absent on success. |
| meta | object | – | Response metadata |
| notice | string | – | Canvas 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_bytes | number | – | Serialized 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_omitted | number | – | Records 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… |
| results | array | – | Animal 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… |
| spilled | boolean | – | True 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_rows | number | – | Rows 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. |
| totalResults | number | – | Total matching animal adverse event records in the dataset |
| truncated | boolean | – | True 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 Openfda Search Device Clearances ~518
Search FDA device premarket notifications — 510(k) clearances and PMA approvals.
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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. |
| limit | number | – | Maximum 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… |
| pathway | string | yes | Premarket pathway. 510(k) is the most common; PMA is for higher-risk devices. |
| search | string | – | openFDA search query. Examples: applicant:"medtronic", advisory_committee_description:"cardiovascular", product_code:"DXN", openfda.device_name:"catheter". Omit to browse recent. Double quotes, paren… |
| skip | number | – | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. |
| sort | string | – | Sort 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;… |
| stage | boolean | – | Stage 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… |
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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_table | string | – | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| effectiveQuery | string | – | Search filter applied to the device clearance query, as submitted to openFDA |
| error | object | – | Present when the call failed. Absent on success. |
| meta | object | – | Response metadata |
| notice | string | – | Canvas 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_bytes | number | – | Serialized 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_omitted | number | – | Records 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… |
| results | array | – | 510(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… |
| spilled | boolean | – | True 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_rows | number | – | Rows 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. |
| totalResults | number | – | Total matching device clearance records in the dataset |
| truncated | boolean | – | True 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 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.
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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. |
| limit | number | – | Maximum 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… |
| search | string | – | openFDA 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… |
| skip | number | – | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. |
| sort | string | – | Sort 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… |
| stage | boolean | – | Stage 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… |
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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_table | string | – | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| effectiveQuery | string | – | Search filter applied to the Drugs@FDA query, as submitted to openFDA |
| error | object | – | Present when the call failed. Absent on success. |
| meta | object | – | Response metadata |
| notice | string | – | Canvas 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_bytes | number | – | Serialized 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_omitted | number | – | Records 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… |
| results | array | – | Drug application records — application_number, sponsor_name, openfda block (brand_name, generic_name, route, product_type, substance_name), products[] (active_ingredients, dosage_form, marketing_stat… |
| spilled | boolean | – | True 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_rows | number | – | Rows 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. |
| totalResults | number | – | Total matching drug approval records in the dataset |
| truncated | boolean | – | True 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 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.
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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. |
| limit | number | – | Maximum 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… |
| search | string | – | openFDA 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… |
| skip | number | – | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. |
| sort | string | – | Sort 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… |
| stage | boolean | – | Stage 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… |
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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_table | string | – | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| effectiveQuery | string | – | Search filter applied to the drug/shortages query, as submitted to openFDA |
| error | object | – | Present when the call failed. Absent on success. |
| meta | object | – | Response metadata |
| notice | string | – | Canvas 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_bytes | number | – | Serialized 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_omitted | number | – | Records 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… |
| results | array | – | Drug shortage records. Key fields: generic_name, status ("Current"/"Resolved"), availability, therapeutic_category, dosage_form, presentation, package_ndc, company_name, contact_info, initial_posting… |
| spilled | boolean | – | True 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_rows | number | – | Rows 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. |
| totalResults | number | – | Total matching drug shortage records in the dataset |
| truncated | boolean | – | True 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 Openfda Search Recalls ~532
Search enforcement reports and recall actions across drugs, food, and devices.
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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. |
| category | string | yes | Product category |
| endpoint | string | – | Report type. Default enforcement. The recall endpoint is only available for devices. |
| limit | number | – | Maximum 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… |
| search | string | – | openFDA 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… |
| skip | number | – | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. |
| sort | string | – | Sort 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… |
| stage | boolean | – | Stage 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… |
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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_table | string | – | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| effectiveQuery | string | – | Search filter applied to the recall query, as submitted to openFDA |
| error | object | – | Present when the call failed. Absent on success. |
| meta | object | – | Response metadata |
| notice | string | – | Canvas 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_bytes | number | – | Serialized 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_omitted | number | – | Records 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… |
| results | array | – | Enforcement or recall records — recall_number, classification, recalling_firm, product_description, reason_for_recall, status, voluntary_mandated, distribution_pattern, report_date. Field set varies… |
| spilled | boolean | – | True 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_rows | number | – | Rows 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. |
| totalResults | number | – | Total matching recall/enforcement records in the dataset |
| truncated | boolean | – | True 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 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.
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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. |
| limit | number | – | Maximum 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… |
| search | string | – | openFDA 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… |
| skip | number | – | Number of records to skip for pagination (default 0). openFDA caps pagination at 25000 records; a higher value returns a pagination_limit_reached error. |
| sort | string | – | Sort 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;… |
| stage | boolean | – | Stage 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… |
| Name | Type | Req | Description |
|---|---|---|---|
| canvas_id | string | – | DataCanvas 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_table | string | – | Canvas table holding the staged rows. Present when rows were staged; reference it in SQL FROM clauses. |
| effectiveQuery | string | – | Search filter applied to the query, as submitted to openFDA |
| error | object | – | Present when the call failed. Absent on success. |
| meta | object | – | Response metadata |
| notice | string | – | Canvas 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_bytes | number | – | Serialized 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_omitted | number | – | Records 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… |
| results | array | – | Tobacco problem report records. Key fields: report_id, date_submitted, tobacco_products[] (product type description), reported_health_problems[] (health effects), reported_product_problems[] (device/… |
| spilled | boolean | – | True 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_rows | number | – | Rows 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. |
| totalResults | number | – | Total matching tobacco problem reports in the dataset |
| truncated | boolean | – | True 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.
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.