fda-mcp
README.md
# fda-mcp
Local MCP server exposing FDA medical-device intelligence tools. All data
sources are public and keyless: openFDA (`api.fda.gov`), the fda.gov
warning-letter endpoint (not in openFDA), and 510(k) summary PDFs from
`accessdata.fda.gov` (parsed via `pdftotext`).
The server has no LLM inside — it is the toolbox. Your AI client (opencode,
Claude Code, Claude Desktop, Cursor, VS Code Copilot) supplies the model and
decides when to call the tools.
## Requirements
- [Bun](https://bun.sh) (tested with 1.4.x)
- `pdftotext` (poppler-utils) on PATH — only needed for `get_510k_summary`
## Run
```sh
bun src/index.ts # speaks MCP over stdio; clients spawn this themselves
```
## Tools
| Tool | What it does |
|---|---|
| `lookup_classification` | Plain-English description or product code → product codes, device class, regulation |
| `search_510k` | 510(k) clearances by code/applicant/device name/date range |
| `get_510k_summary` | One clearance + its summary PDF parsed, indications statement extracted |
| `search_maude` | MAUDE adverse events; list mode or `count_by` aggregation (e.g. top problem codes) |
| `search_recalls` | Device recalls by code/firm/product keyword |
| `search_warning_letters` | fda.gov warning letters, optionally CDRH-only (dataset absent from openFDA) |
| `check_postmarket_health` | Recalls + MAUDE volume + warning letters for a brand/company — predicate due diligence |
| `search_pma` | PMA approvals/supplements (Class III devices) by code/applicant/date |
| `search_registrations` | Establishment Registration & Listing — who makes/sterilizes what under a code (competitor/supplier discovery) |
| `lookup_udi` | GUDID/UDI records — resolve brand → legal company name, enumerate models/versions |
| `search_enforcement` | Recall enforcement reports with Class I/II/III severity (complements `search_recalls`) |
| `get_query_guide` | Full query guide (syntax quirks, endpoint cheat sheets, recipes) — read before `fda_fetch` |
| `fda_fetch` | Guarded raw GET against FDA hosts only — escape hatch for query shapes the typed tools miss |
Most search tools accept `count_by` for aggregations (e.g. `search_510k` with
`count_by: "applicant.exact"` = who files most under a product code).
## Skill (for shell-capable agents — no server needed)
`skills/fda-device-intel/SKILL.md` teaches an agent with shell access (Claude
Code, opencode, Codex CLI, Copilot agent mode) to query the same endpoints
directly with curl — no process, no install beyond the markdown file:
One-liner install (Claude Code / any agent reading `~/.claude/skills/`):
```sh
mkdir -p ~/.claude/skills/fda-device-intel && curl -fsSL -o ~/.claude/skills/fda-device-intel/SKILL.md https://raw.githubusercontent.com/happylemonprogramming/fda-mcp/main/skills/fda-device-intel/SKILL.md
```
Or paste the skill straight into any agent that can fetch URLs:
> Fetch https://raw.githubusercontent.com/happylemonprogramming/fda-mcp/main/skills/fda-device-intel/SKILL.md and follow it to answer FDA medical-device questions.
Skill and MCP server share one knowledge source: `get_query_guide` serves the
skill's body to MCP clients, so remote no-shell clients (Claude Desktop,
ChatGPT, Teams/Copilot Studio) get the same guidance driving `fda_fetch`.
## Connect a client
### opencode
Add to `opencode.json` (project) or `~/.config/opencode/opencode.json`:
```json
{
"mcp": {
"fda": {
"type": "local",
"command": ["bun", "/home/lemon/Projects/fda-mcp/src/index.ts"],
"enabled": true
}
}
}
```
### Claude Code
```sh
claude mcp add fda -- bun /home/lemon/Projects/fda-mcp/src/index.ts
```
or in `.mcp.json`:
```json
{
"mcpServers": {
"fda": {
"command": "bun",
"args": ["/home/lemon/Projects/fda-mcp/src/index.ts"]
}
}
}
```
### Claude Desktop
`~/.config/Claude/claude_desktop_config.json` → same `mcpServers` block as
Claude Code above.
## Example prompts to try
- "Look up the product code for a bipolar laparoscopic coagulation device,
then show me the 5 newest clearances under it."
- "Run a postmarket health check on POWERSEAL by Olympus."
- "Get the indications statement from K213042's summary PDF."
- "Any CDRH warning letters mentioning Medtronic?"
## Caveats
- MAUDE data lags months behind real time.
- The warning-letter endpoint is an undocumented fda.gov internal API; it can
change without notice. Keep request volume low.
- Name matching is keyword-based; brand/company collisions happen (a "Voyant"
query matches an unrelated contact lens). Every tool output says so.
- Informational only, not regulatory advice; see https://open.fda.gov/terms/.