openfda_adverse_searcher
Search FDA Adverse Event Reporting System (FAERS) to identify drug side effects, serious reactions, and safety signals across patient populations. Use to gather insights from voluntary reports on adverse drug events.
Instructions
Search FDA adverse event reports (FAERS) for drug safety information.
⚠️ PREREQUISITE: Use the 'think' tool FIRST to plan your research strategy!
Searches FDA's Adverse Event Reporting System for:
- Drug side effects and adverse reactions
- Serious event reports (death, hospitalization, disability)
- Safety signal patterns across patient populations
Note: These reports do not establish causation - they are voluntary reports
that may contain incomplete or unverified information.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| api_key | No | Optional OpenFDA API key (overrides OPENFDA_API_KEY env var) | |
| drug | No | Drug name to search for adverse events | |
| limit | No | Maximum number of results | |
| page | No | Page number (1-based) | |
| reaction | No | Adverse reaction term to search for | |
| serious | No | Filter for serious events only |
Implementation Reference
- src/biomcp/individual_tools.py:1273-1326 (handler)MCP tool handler for 'openfda_adverse_searcher'. Registers the tool with @mcp_app.tool(), defines input schema via Annotated Fields, and implements logic by calling the OpenFDA search helper.@mcp_app.tool() @track_performance("biomcp.openfda_adverse_searcher") async def openfda_adverse_searcher( drug: Annotated[ str | None, Field(description="Drug name to search for adverse events"), ] = None, reaction: Annotated[ str | None, Field(description="Adverse reaction term to search for"), ] = None, serious: Annotated[ bool | None, Field(description="Filter for serious events only"), ] = None, limit: Annotated[ int, Field(description="Maximum number of results", ge=1, le=100), ] = 25, page: Annotated[ int, Field(description="Page number (1-based)", ge=1), ] = 1, api_key: Annotated[ str | None, Field( description="Optional OpenFDA API key (overrides OPENFDA_API_KEY env var)" ), ] = None, ) -> str: """Search FDA adverse event reports (FAERS) for drug safety information. ⚠️ PREREQUISITE: Use the 'think' tool FIRST to plan your research strategy! Searches FDA's Adverse Event Reporting System for: - Drug side effects and adverse reactions - Serious event reports (death, hospitalization, disability) - Safety signal patterns across patient populations Note: These reports do not establish causation - they are voluntary reports that may contain incomplete or unverified information. """ from biomcp.openfda import search_adverse_events skip = (page - 1) * limit return await search_adverse_events( drug=drug, reaction=reaction, serious=serious, limit=limit, skip=skip, api_key=api_key, )
- Core helper function implementing the OpenFDA adverse events search logic: query building, API request, error handling, and response formatting.async def search_adverse_events( # noqa: C901 drug: str | None = None, reaction: str | None = None, serious: bool | None = None, limit: int = OPENFDA_DEFAULT_LIMIT, skip: int = 0, api_key: str | None = None, ) -> str: """ Search FDA adverse event reports (FAERS). Args: drug: Drug name to search for reaction: Adverse reaction term to search for serious: Filter for serious events only limit: Maximum number of results skip: Number of results to skip api_key: Optional OpenFDA API key (overrides OPENFDA_API_KEY env var) Returns: Formatted string with adverse event information """ if not drug and not reaction: return ( "⚠️ Please specify either a drug name or reaction term to search " "adverse events.\n\n" "Examples:\n" "- Search by drug: --drug 'imatinib'\n" "- Search by reaction: --reaction 'nausea'\n" "- Both: --drug 'imatinib' --reaction 'nausea'" ) # Build and execute search search_query = _build_search_query(drug, reaction, serious) params = { "search": search_query, "limit": min(limit, OPENFDA_MAX_LIMIT), "skip": skip, } try: response, error = await make_openfda_request( OPENFDA_DRUG_EVENTS_URL, params, "openfda_adverse_events", api_key ) except OpenFDARateLimitError: return ( "⚠️ **FDA API Rate Limit Exceeded**\n\n" "You've exceeded the FDA's rate limit. Options:\n" "• Wait a moment and try again\n" "• Provide an FDA API key for higher limits (240/min vs 40/min)\n" "• Get a free key at: https://open.fda.gov/apis/authentication/" ) except OpenFDATimeoutError: return ( "⏱️ **Request Timeout**\n\n" "The FDA API is taking too long to respond. This may be due to:\n" "• High server load\n" "• Complex query\n" "• Network issues\n\n" "Please try again in a moment." ) except OpenFDAConnectionError as e: return ( "🔌 **Connection Error**\n\n" f"Unable to connect to FDA API: {e}\n\n" "Please check your internet connection and try again." ) if error: return f"⚠️ Error searching adverse events: {error}" if not response or not response.get("results"): search_desc = [] if drug: search_desc.append(f"drug '{drug}'") if reaction: search_desc.append(f"reaction '{reaction}'") return ( f"No adverse event reports found for {' and '.join(search_desc)}." ) results = response["results"] total = ( response.get("meta", {}).get("results", {}).get("total", len(results)) ) # Build output output = ["## FDA Adverse Event Reports\n"] output.extend(format_search_summary(drug, reaction, serious, total)) # Add top reactions if searching by drug if drug and not reaction: output.extend(format_top_reactions(results)) # Add sample reports output.append( f"### Sample Reports (showing {min(len(results), 3)} of {total}):\n" ) for i, result in enumerate(results[:3], 1): output.extend(format_report_summary(result, i)) output.append(f"\n{OPENFDA_DISCLAIMER}") return "\n".join(output)
- src/biomcp/individual_tools.py:1273-1274 (registration)Tool registration via MCP app decorator and performance tracking.@mcp_app.tool() @track_performance("biomcp.openfda_adverse_searcher")