@cyanheads/openfda-mcp-server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@cyanheads/openfda-mcp-serversearch for adverse events for aspirin"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Public Hosted Server: https://openfda.caseyjhand.com/mcp
Tools
Twelve tools for querying FDA data across drugs, food, devices, animal/veterinary products, and recalls:
Tool | Description |
| One drug name → consolidated FDA profile: identity, label, adverse events, recalls, approval, shortage |
| Search adverse event reports across drugs, food, and devices |
| Search adverse event reports for veterinary drugs and devices |
| Search FDA drug shortage records — status, availability, therapeutic category, manufacturer |
| Search problem reports for tobacco products, e-cigarettes, and vaping devices |
| Search enforcement reports and recall actions across drugs, food, and devices |
| Aggregate and tally unique values for any field across any openFDA endpoint |
| Return searchable field paths for an openFDA endpoint, grouped by category |
| Look up FDA drug labeling (package inserts / SPL documents) |
| Search the Drugs@FDA database for NDA/ANDA application approvals |
| Search FDA device premarket notifications — 510(k) clearances and PMA approvals |
| Look up drugs in the NDC (National Drug Code) Directory |
openfda_drug_profile
Resolve one drug name to its FDA identity, then return a consolidated profile in a single call — replacing four or five chained lookups.
Resolves a brand or generic name to canonical FDA identifiers once (generic name, NDC, RxCUI, SPL set ID), then keys every sub-query off that identity to avoid the identifier drift that breaks naive tool chaining
Single-ingredient resolution: a single-drug query won't resolve to a combination product
Sections: label highlights, adverse-event summary (top reactions, serious count), recall history, Drugs@FDA approval, and current shortage status
Best-effort — a miss on any section returns
nullrather than failing the whole call; use the dedicated tool for a deep dive into any area
openfda_search_adverse_events
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.
Category selection:
drug,food, ordevice— each returns different field schemasElasticsearch query syntax for filtering by product, reaction, seriousness, date range
Pagination via
limit(up to 1000) andskip(up to 25000)Formatted output includes report ID, seriousness, patient demographics, reactions, drugs with characterization/indication/route, and all remaining fields
openfda_count
Aggregate and tally unique values for any field across any openFDA endpoint. Returns ranked term-count pairs sorted by count descending.
Works across all 20 openFDA endpoints (drugs, food, devices, animal/veterinary, tobacco, other)
Use
.exactsuffix on field names for whole-phrase countingOptional
searchfilter to scope the aggregationReturns up to 1000 terms per query
openfda_search_recalls
Search enforcement reports and recall actions across drugs, food, and devices.
Supports
enforcement(all categories) andrecall(devices only) endpointsFilter by classification (Class I/II/III), recalling firm, reason, status
Formatted output includes recall number, classification, product description, reason, distribution pattern
openfda_search_device_clearances
Search FDA device premarket notifications — 510(k) clearances and PMA approvals.
Two pathways:
510k(174K+ records, most common) andpma(higher-risk devices)Filter by applicant, product code, advisory committee, device name
Formatted output adapts to pathway: 510(k) shows K-number/clearance type, PMA shows supplement info
openfda_get_drug_label
Look up FDA drug labeling (package inserts / SPL documents). Check indications, warnings, dosage, contraindications, active ingredients, or any structured label section.
Search by brand name, generic name, manufacturer, or set ID
Formatted output dynamically renders all label sections and openfda metadata present in the record
Large sections are automatically truncated to keep output readable
Default limit of 5 — labels are large documents
openfda_search_drug_approvals
Search the Drugs@FDA database for drug application approvals (NDAs and ANDAs). Returns application details, sponsor info, and full submission history.
Filter by brand name, sponsor, submission type, review priority
Formatted output includes products with active ingredients, dosage forms, routes, and marketing status
Full submission history with type, status, date, and review priority
Pagination via
limit(up to 1000) andskip(up to 25000)
openfda_lookup_ndc
Look up drugs in the NDC (National Drug Code) Directory. Identify drug products by NDC code, find active ingredients, packaging details, or manufacturer info.
Search by product NDC, brand name, generic name, manufacturer, or active ingredient
Returns product details, active ingredients with strengths, and packaging information
Sortable by listing expiration date or other fields
openfda_search_animal_events
Search adverse event reports for veterinary drugs and devices submitted to the FDA Center for Veterinary Medicine (1.3M+ records).
Filter by animal species, breed, drug name, VeDDRA reaction term, or seriousness
Records include animal details (species, gender, age, weight), administered drugs, reactions, and outcomes
Formatted output surfaces key clinical fields; remaining fields rendered via catch-all
openfda_search_tobacco_reports
Search problem reports submitted to the FDA for tobacco products, including e-cigarettes, vaping products, cigarettes, and smokeless tobacco.
Filter by product type, reported health problems (e.g. seizure, chest pain), product problems (e.g. battery explosion), or non-user involvement
Formatted output surfaces products, health effects, product defects, and report counts
openfda_search_drug_shortages
Search FDA drug shortage records (1,700+ entries, refreshed daily). Returns shortage status, availability notes, therapeutic category, dosage form, manufacturer, and timeline.
Filter by status (
Current,Resolved), therapeutic category, generic name, or manufacturerThe
openfdablock carriesbrand_name,product_ndc, andrxcuifor chaining intoopenfda_get_drug_labeloropenfda_lookup_ndcPagination via
limit(up to 1000) andskip(up to 25000)
openfda_describe_fields
Return the searchable field paths for an openFDA endpoint, grouped by category with type and description. Use before constructing a search query to discover the correct dotted field paths.
Covers all major endpoints:
drug/event,drug/label,drug/shortages,drug/drugsfda,drug/ndc,drug/enforcement,food/event,food/enforcement,device/event,device/510k,device/pma,device/recall,device/enforcement,animalandveterinary/event,tobacco/problemReturns fields grouped by category (identifiers, dates, clinical fields, etc.) with data type and one-line description
Complements the reactive field hints that appear in
noticeenrichment when a search returns empty
Features
Built on @cyanheads/mcp-ts-core:
Declarative tool definitions — single file per tool, framework handles registration and validation
Unified error handling across all tools
Pluggable auth (
none,jwt,oauth)Swappable storage backends:
in-memory,filesystem,Supabase,Cloudflare KV/R2/D1Structured logging with optional OpenTelemetry tracing
Runs locally (stdio/HTTP) or on Cloudflare Workers from the same codebase
openFDA-specific:
Generic API client for all openFDA endpoints with retry (exponential backoff) and rate-limit awareness
Automatic error normalization — 404 returns empty results, 429/5xx retries, 400 provides actionable messages
Optional API key support — works without a key (1K requests/day), increases to 120K/day with a free key
Getting Started
Public Hosted Instance
A public instance is available at https://openfda.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"openfda-mcp-server": {
"type": "streamable-http",
"url": "https://openfda.caseyjhand.com/mcp"
}
}
}Via bunx (no install)
Add to your MCP client config:
{
"mcpServers": {
"openfda-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/openfda-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"OPENFDA_API_KEY": "your-key-here"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"openfda-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/openfda-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"OPENFDA_API_KEY": "your-key-here"
}
}
}
}Or with Docker:
{
"mcpServers": {
"openfda-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/openfda-mcp-server:latest"]
}
}
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Bun v1.3.0 or higher.
Optional: openFDA API key for higher rate limits (120K requests/day vs 1K/day).
Installation
Clone the repository:
git clone https://github.com/cyanheads/openfda-mcp-server.gitNavigate into the directory:
cd openfda-mcp-serverInstall dependencies:
bun installConfiguration
All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:
Variable | Description | Default |
| Transport: |
|
| HTTP server port |
|
| Authentication: |
|
| Log level ( |
|
| Directory for log files (Node.js only). |
|
| Storage backend: |
|
| Free API key from open.fda.gov. Increases daily limit from 1K to 120K requests. | none |
| Base URL override for testing against a proxy or mock. |
|
| Enable OpenTelemetry |
|
Running the Server
Local Development
Build and run the production version:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdioRun checks and tests:
bun run devcheck # Lints, formats, type-checks, and more bun run test # Runs the test suite
Project Structure
Directory | Purpose |
| Entry point — |
| Server-specific env var parsing and validation with Zod. |
| openFDA API client with retry, rate-limit handling, and error normalization. |
| Tool definitions ( |
Development Guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor request-scoped loggingRegister new tools in
src/mcp-server/tools/definitions/index.ts
Contributing
Issues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
This server cannot be installed
Maintenance
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/cyanheads/openfda-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server