drug-safety-mcp
Click on "Deploy 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., "@drug-safety-mcpIs it safe to take ibuprofen with warfarin? Cite the sources."
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.
drug-safety-mcp
A Model Context Protocol (MCP) server that gives any AI assistant grounded access to FDA drug-safety data, plus a LangGraph agent that finds and uses its tools at runtime.
Plug it into Claude Desktop, Claude Code, Cursor, or your own agent and ask questions like "Is it safe to take ibuprofen with warfarin?" The model answers from the FDA label and FAERS report data and cites where each fact came from, rather than answering from memory.
flowchart LR
U[User] --> A
subgraph Agent [LangGraph agent]
A[agent<br/>LLM + bound tools] -- tool calls --> T[ToolNode] --> C[count_round<br/>budget guard] --> A
A -- done / budget hit --> F[finalize<br/>tools used + disclaimer]
end
T <-- MCP stdio / streamable HTTP --> S[drug-safety MCP server]
D[Claude Desktop · Cursor · Claude Code] <-- MCP --> S
S --> O[(openFDA<br/>labels · FAERS · recalls)]Tools
tool | what it returns | openFDA endpoint |
| brand/generic names, manufacturer, boxed-warning flag, selected label sections (boxed warning, indications, contraindications, warnings, adverse reactions, drug interactions) |
|
| most-reported MedDRA reactions, report counts, total reports, and a causation caveat |
|
| recall number, class, status, reason, product |
|
| whether either label mentions the other drug (by generic or brand name), with section-tagged excerpts |
|
The server also exposes a resource (drug-safety://about, a data-provenance disclaimer) and a prompt (safety_brief(drug), a cited one-page brief template).
Engineering details
Structured output. Every tool returns a pydantic model, so MCP clients receive an
outputSchemaandstructuredContent, not just free text.Query-injection safe. Drug names are sanitised before they go into openFDA's Lucene query syntax, so input like
metformin" OR x:"*can't change the query.Resilient client. Async httpx with retry and exponential backoff on 429/5xx, and a TTL cache. openFDA's "404 = no matches" is mapped to
found: falseinstead of an error. The API key is sent but kept out of cache keys.Agent guardrails. A tool-round budget stops runaway loops, a
finalizenode appends the tools used and the disclaimer, and tool errors go back to the model instead of crashing the graph.Two transports. stdio for desktop clients, and streamable HTTP (
/mcp) for remote or containerised deployment.
Related MCP server: OpenFDA FastMCP Server
Use it from Claude Desktop
Add to claude_desktop_config.json (see examples/):
{
"mcpServers": {
"drug-safety": {
"command": "uvx",
"args": ["--from", "git+https://github.com/gopipamulapati/drug-safety-mcp", "drug-safety-mcp"]
}
}
}Run the agent
pip install -e ".[agent]"
export OPENAI_API_KEY=... # any OpenAI-compatible endpoint; see .env.example
drug-safety-agent --trace "Can I take ibuprofen with warfarin?"Example trace (the exact calls depend on the model):
-> check_interaction({'drug_a': 'ibuprofen', 'drug_b': 'warfarin'})
-> get_drug_label({'drug': 'warfarin', 'sections': ['boxed_warning', 'drug_interactions']})
...No network? --offline (or DRUG_SAFETY_OFFLINE=1) serves a small illustrative bundled sample for warfarin, ibuprofen, and metformin. Its text is paraphrased and its counts are made up, so it's only for demos and tests.
Serve over HTTP / Docker
docker build -t drug-safety-mcp . && docker run -p 8000:8000 drug-safety-mcp
# MCP endpoint: http://localhost:8000/mcpTests
pip install -e ".[dev]"
pytest -q # 17 tests, ~5 s, no networkClient: sanitisation, retry on 429, 404 → not found, cache TTL/eviction, API key kept out of cache keys.
Server: every tool, the resource, and the prompt are called through a real MCP client session (in-memory transport), including brand-name resolution, tool errors, and structured output schemas.
Agent: the LangGraph graph talks to the MCP server as a real stdio subprocess, driven by a scripted chat model. This checks that data flows back from the tools, that the final answer cites the tools used, and that the tool budget stops a model that keeps calling tools.
Layout
src/drug_safety_mcp/
server.py FastMCP server: 4 tools, 1 resource, 1 prompt, stdio/HTTP entrypoint
openfda.py async client: sanitising, retries, TTL cache
agent.py LangGraph StateGraph agent using langchain-mcp-adapters
offline.py httpx MockTransport serving bundled sample data
examples/ Claude Desktop configData comes from openFDA. FAERS counts are spontaneous reports, not incidence rates, and don't establish causation. This is not medical advice.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Search FDA safety data: drug adverse events, recalls, and device events.
Search and export FDA drug labels by brand name, generic ingredient, or UNII code.
Official FDA recalls, drug labels, adverse events and clinical trials, with cited sources.
Search DailyMed drug labels, SPLs, NDCs and packaging.
Related MCP Servers
- AlicenseBqualityDmaintenanceProvides access to the official FDA DailyMed database for comprehensive drug information, including drug labels, NDC codes, RxNorm mappings, pharmacologic classifications, and FDA application numbers through natural language queries.283MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to query and analyze FDA adverse events, drug labels, medical device clearances, and other public health datasets through natural language commands.14-
- AlicenseAqualityDmaintenanceEnables LLMs to search FDA drug labels and adverse event data via the OpenFDA API, supporting natural language queries for drug safety information.2MIT
- AlicenseBqualityDmaintenanceEnables querying FDA drug label information including adverse reactions, warnings, and indications through natural language.516 npmGPL 3.0