openfda-mcp-server 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,6 +7,8 @@ An MCP (Model Context Protocol) server that provides access to U.S. FDA public d
7
7
  - **10 FDA Tools**: Query drug and device databases through a standardized MCP interface
8
8
  - **Drug Tools**: Adverse events (FAERS), labels, NDC directory, recalls, Drugs@FDA, shortages
9
9
  - **Device Tools**: 510(k) clearances, classifications, adverse events (MDR), recalls
10
+ - **Individual Record Lookup**: Retrieve specific reports by ID (safety report ID, set ID, MDR report number)
11
+ - **Advanced Filtering**: Filter drug labels by boxed warnings, request specific label sections
10
12
  - **Rate Limit Aware**: Supports authenticated requests for higher rate limits (120k/hour vs 1k/hour)
11
13
  - **TypeScript**: Fully typed with Zod schema validation
12
14
 
@@ -52,23 +54,69 @@ Get a free API key at: https://open.fda.gov/apis/authentication/
52
54
 
53
55
  ### Drug Tools
54
56
 
55
- | Tool | Description |
56
- | ---------------------------- | -------------------------------------------- |
57
- | `search_drug_adverse_events` | Search FAERS for drug safety reports |
58
- | `search_drug_labels` | Search drug labeling/prescribing information |
59
- | `search_drug_ndc` | Search the National Drug Code directory |
60
- | `search_drug_recalls` | Search drug recall enforcement reports |
61
- | `search_drugs_at_fda` | Search approved drug applications |
62
- | `search_drug_shortages` | Search current and resolved drug shortages |
57
+ | Tool | Description |
58
+ | ---------------------------- | ------------------------------------------------------------------------------------------------------ |
59
+ | `search_drug_adverse_events` | Search FAERS for drug safety reports. Retrieve specific report by `safetyReportId`. |
60
+ | `search_drug_labels` | Search drug labeling/prescribing info. Get by `setId`, filter by `hasBoxedWarning`, select `sections`. |
61
+ | `search_drug_ndc` | Search the National Drug Code directory |
62
+ | `search_drug_recalls` | Search drug recall enforcement reports |
63
+ | `search_drugs_at_fda` | Search approved drug applications |
64
+ | `search_drug_shortages` | Search current and resolved drug shortages |
63
65
 
64
66
  ### Device Tools
65
67
 
66
- | Tool | Description |
67
- | ------------------------------- | ---------------------------------------- |
68
- | `search_device_510k` | Search 510(k) premarket notifications |
69
- | `search_device_classifications` | Search device classification database |
70
- | `search_device_adverse_events` | Search MDR adverse event reports |
71
- | `search_device_recalls` | Search device recall enforcement reports |
68
+ | Tool | Description |
69
+ | ------------------------------- | ----------------------------------------------------------------------------- |
70
+ | `search_device_510k` | Search 510(k) premarket notifications |
71
+ | `search_device_classifications` | Search device classification database |
72
+ | `search_device_adverse_events` | Search MDR adverse event reports. Retrieve specific report by `reportNumber`. |
73
+ | `search_device_recalls` | Search device recall enforcement reports |
74
+
75
+ ## Tool Parameters
76
+
77
+ ### search_drug_labels
78
+
79
+ | Parameter | Type | Description |
80
+ | ------------------ | -------- | ------------------------------------------------------------ |
81
+ | `setId` | string | Retrieve a specific label by its unique set_id |
82
+ | `drugName` | string | Drug brand or generic name |
83
+ | `indication` | string | Medical indication or use case |
84
+ | `activeIngredient` | string | Active ingredient/substance name |
85
+ | `route` | string | Route of administration (e.g., 'oral', 'intravenous') |
86
+ | `hasBoxedWarning` | boolean | Filter for drugs with boxed warnings (most serious warnings) |
87
+ | `sections` | string[] | Specific label sections to return (see below) |
88
+ | `limit` | number | Maximum results (1-100) |
89
+ | `skip` | number | Number of results to skip for pagination |
90
+
91
+ **Available sections**: `indications_and_usage`, `dosage_and_administration`, `contraindications`, `warnings`, `warnings_and_cautions`, `adverse_reactions`, `drug_interactions`, `clinical_pharmacology`, `mechanism_of_action`, `pharmacokinetics`, `overdosage`, `description`, `how_supplied`, `storage_and_handling`, `boxed_warning`
92
+
93
+ ### search_drug_adverse_events
94
+
95
+ | Parameter | Type | Description |
96
+ | ---------------- | ------- | -------------------------------------------------- |
97
+ | `safetyReportId` | string | Retrieve a specific FAERS report by its 8-digit ID |
98
+ | `drugName` | string | Drug or product name to search |
99
+ | `reaction` | string | Adverse reaction (e.g., 'headache', 'nausea') |
100
+ | `manufacturer` | string | Drug manufacturer name |
101
+ | `serious` | boolean | Filter for serious adverse events only |
102
+ | `dateFrom` | string | Start date (YYYY-MM-DD) |
103
+ | `dateTo` | string | End date (YYYY-MM-DD) |
104
+ | `limit` | number | Maximum results (1-100) |
105
+ | `skip` | number | Number of results to skip for pagination |
106
+
107
+ ### search_device_adverse_events
108
+
109
+ | Parameter | Type | Description |
110
+ | ------------------ | ------ | ----------------------------------------------- |
111
+ | `reportNumber` | string | Retrieve a specific MDR report by report number |
112
+ | `deviceName` | string | Device generic name |
113
+ | `brandName` | string | Device brand name |
114
+ | `manufacturerName` | string | Device manufacturer name |
115
+ | `eventType` | string | Type: 'Injury', 'Malfunction', 'Death', 'Other' |
116
+ | `dateFrom` | string | Start date (YYYY-MM-DD) |
117
+ | `dateTo` | string | End date (YYYY-MM-DD) |
118
+ | `limit` | number | Maximum results (1-100) |
119
+ | `skip` | number | Number of results to skip for pagination |
72
120
 
73
121
  ## Usage Examples
74
122
 
@@ -78,6 +126,24 @@ Get a free API key at: https://open.fda.gov/apis/authentication/
78
126
  Find adverse events for aspirin in the last year that were serious
79
127
  ```
80
128
 
129
+ ### Get a specific adverse event report
130
+
131
+ ```
132
+ Retrieve FAERS report with safety report ID 10003641
133
+ ```
134
+
135
+ ### Search for drugs with boxed warnings
136
+
137
+ ```
138
+ Find all drugs with boxed warnings related to cardiovascular risks
139
+ ```
140
+
141
+ ### Get specific label sections
142
+
143
+ ```
144
+ Get the boxed_warning and contraindications sections for warfarin
145
+ ```
146
+
81
147
  ### Search for drug recalls
82
148
 
83
149
  ```
@@ -90,6 +156,12 @@ Search for Class I drug recalls from Pfizer
90
156
  Find 510(k) clearances for cardiac pacemakers
91
157
  ```
92
158
 
159
+ ### Get a specific device adverse event report
160
+
161
+ ```
162
+ Retrieve MDR report number 2649622-2020-08294
163
+ ```
164
+
93
165
  ### Search for device adverse events
94
166
 
95
167
  ```
@@ -164,7 +236,7 @@ pnpm build
164
236
  ## Programmatic Usage
165
237
 
166
238
  ```typescript
167
- import { createOpenFDAServer, handleSearchDrugAdverseEvents } from "openfda-mcp-server/lib"
239
+ import { createOpenFDAServer, handleSearchDrugAdverseEvents, handleSearchDrugLabels } from "openfda-mcp-server/lib"
168
240
 
169
241
  // Create a custom server
170
242
  const server = createOpenFDAServer({
@@ -172,12 +244,29 @@ const server = createOpenFDAServer({
172
244
  version: "1.0.0",
173
245
  })
174
246
 
175
- // Or use handlers directly
176
- const result = await handleSearchDrugAdverseEvents({
247
+ // Search for adverse events
248
+ const adverseEvents = await handleSearchDrugAdverseEvents({
177
249
  drugName: "aspirin",
178
250
  serious: true,
179
251
  limit: 10,
180
252
  })
253
+
254
+ // Get a specific adverse event by ID
255
+ const specificReport = await handleSearchDrugAdverseEvents({
256
+ safetyReportId: "10003641",
257
+ })
258
+
259
+ // Search for drugs with boxed warnings
260
+ const boxedWarningDrugs = await handleSearchDrugLabels({
261
+ hasBoxedWarning: true,
262
+ limit: 10,
263
+ })
264
+
265
+ // Get specific sections of a drug label
266
+ const warfarinLabel = await handleSearchDrugLabels({
267
+ setId: "0cbce382-9c88-4f58-ae0f-532a841e8f95",
268
+ sections: ["boxed_warning", "contraindications", "adverse_reactions"],
269
+ })
181
270
  ```
182
271
 
183
272
  ## API Rate Limits
@@ -194,5 +283,7 @@ MIT
194
283
  ## Acknowledgments
195
284
 
196
285
  - [OpenFDA](https://open.fda.gov/) - FDA open data API
197
- - [FastMCP](https://github.com/jordanburke/fastmcp) - MCP server framework
198
- - Based on [OpenFDA-MCP-Server](https://github.com/Augmented-Nature/OpenFDA-MCP-Server) concept
286
+
287
+ ---
288
+
289
+ **Sponsored by <a href="https://sapientsai.com/"><img src="https://sapientsai.com/images/logo.svg" alt="SapientsAI" width="20" style="vertical-align: middle;"> SapientsAI</a>** — Building agentic AI for businesses
@@ -1,2 +1,2 @@
1
- import{loggers as e}from"./utils/logger.js";import{n as t}from"./api-client-BGnUXMwX.js";function n(e,t,n){if(!(!t&&!n))return`${e}:[${t?.replace(/-/g,``)??`*`}+TO+${n?.replace(/-/g,``)??`*`}]`}function r(e){return e.replace(/[+\-&|!(){}[\]^"~*?:\\]/g,`\\$&`).replace(/\s+/g,`+`)}function i(e){let t=e.filter(e=>e.value!==void 0&&e.value.trim()!==``);return t.length===0?``:t.map(e=>`${e.field}:"${r(e.value)}"`).join(`+AND+`)}function a(e,t=200){if(e)return e.length>t?e.substring(0,t)+`...`:e}function o(e){return{kNumber:e.k_number,deviceName:e.device_name??e.openfda?.device_name,applicant:e.applicant,productCode:e.product_code,clearanceType:e.clearance_type,decisionCode:e.decision_code,decisionDescription:e.decision_description,decisionDate:e.decision_date,dateReceived:e.date_received,city:e.city,state:e.state,country:e.country_code}}async function s(r){e.tools(`searchDevice510K`,r);try{let e={search:[i([{field:`device_name`,value:r.deviceName},{field:`applicant`,value:r.applicant},{field:`product_code`,value:r.productCode},{field:`clearance_type`,value:r.clearanceType}]),n(`decision_date`,r.decisionDateFrom,r.decisionDateTo)].filter(Boolean).join(`+AND+`)||void 0,limit:r.limit,skip:r.skip},a=await t.searchDevice510K(e),s=a.results??[];return{success:!0,data:s.map(o),totalResults:a.meta?.results?.total,displayedResults:s.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function c(e){return{deviceName:e.device_name,deviceClass:e.device_class,definition:a(e.definition),medicalSpecialty:e.medical_specialty,medicalSpecialtyDescription:e.medical_specialty_description,productCode:e.product_code,regulationNumber:e.regulation_number,gmpExempt:e.gmp_exempt_flag===`Y`,implant:e.implant_flag===`Y`,lifeSustaining:e.life_sustain_support_flag===`Y`}}async function l(n){e.tools(`searchDeviceClassifications`,n);try{let e={search:i([{field:`device_name`,value:n.deviceName},{field:`device_class`,value:n.deviceClass},{field:`medical_specialty`,value:n.medicalSpecialty},{field:`product_code`,value:n.productCode},{field:`regulation_number`,value:n.regulationNumber}])||void 0,limit:n.limit,skip:n.skip},r=await t.searchDeviceClassifications(e),a=r.results??[];return{success:!0,data:a.map(c),totalResults:r.meta?.results?.total,displayedResults:a.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function u(e){return{reportNumber:e.report_number,dateOfEvent:e.date_of_event,dateReceived:e.date_received,eventType:e.event_type,adverseEventFlag:e.adverse_event_flag===`Y`,productProblemFlag:e.product_problem_flag===`Y`,devices:e.device?.slice(0,3).map(e=>({brandName:e.brand_name,genericName:e.generic_name,manufacturerName:e.manufacturer_d_name,modelNumber:e.model_number,productCode:e.device_report_product_code,deviceClass:e.openfda?.device_class}))??[],mdrText:e.mdr_text?.slice(0,2).map(e=>({textType:e.text_type_code,text:a(e.text,300)}))??[]}}async function d(r){e.tools(`searchDeviceAdverseEvents`,r);try{let e={search:[i([{field:`device.generic_name`,value:r.deviceName},{field:`device.brand_name`,value:r.brandName},{field:`device.manufacturer_d_name`,value:r.manufacturerName},{field:`event_type`,value:r.eventType}]),n(`date_received`,r.dateFrom,r.dateTo)].filter(Boolean).join(`+AND+`)||void 0,limit:r.limit,skip:r.skip},a=await t.searchDeviceAdverseEvents(e),o=a.results??[];return{success:!0,data:o.map(u),totalResults:a.meta?.results?.total,displayedResults:o.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function f(e){return{recallNumber:e.recall_number,recallingFirm:e.recalling_firm,classification:e.classification,status:e.status,productDescription:a(e.product_description),reasonForRecall:a(e.reason_for_recall),recallInitiationDate:e.recall_initiation_date,distributionPattern:a(e.distribution_pattern),city:e.city,state:e.state,deviceName:e.openfda?.device_name,deviceClass:e.openfda?.device_class}}async function p(r){e.tools(`searchDeviceEnforcement`,r);try{let e={search:[i([{field:`recalling_firm`,value:r.recallingFirm},{field:`product_description`,value:r.productDescription},{field:`classification`,value:r.classification},{field:`status`,value:r.status}]),n(`recall_initiation_date`,r.dateFrom,r.dateTo)].filter(Boolean).join(`+AND+`)||void 0,limit:r.limit,skip:r.skip},a=await t.searchDeviceEnforcement(e),o=a.results??[];return{success:!0,data:o.map(f),totalResults:a.meta?.results?.total,displayedResults:o.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}export{p as i,d as n,l as r,s as t};
2
- //# sourceMappingURL=device-handlers-D01LfIJk.js.map
1
+ import{loggers as e}from"./utils/logger.js";import{n as t}from"./api-client-BGnUXMwX.js";function n(e,t,n){if(!(!t&&!n))return`${e}:[${t?.replace(/-/g,``)??`*`}+TO+${n?.replace(/-/g,``)??`*`}]`}function r(e){return e.replace(/[+\-&|!(){}[\]^"~*?:\\]/g,`\\$&`).replace(/\s+/g,`+`)}function i(e){let t=e.filter(e=>e.value!==void 0&&e.value.trim()!==``);return t.length===0?``:t.map(e=>`${e.field}:"${r(e.value)}"`).join(`+AND+`)}function a(e,t=200){if(e)return e.length>t?e.substring(0,t)+`...`:e}function o(e){return{kNumber:e.k_number,deviceName:e.device_name??e.openfda?.device_name,applicant:e.applicant,productCode:e.product_code,clearanceType:e.clearance_type,decisionCode:e.decision_code,decisionDescription:e.decision_description,decisionDate:e.decision_date,dateReceived:e.date_received,city:e.city,state:e.state,country:e.country_code}}async function s(r){e.tools(`searchDevice510K`,r);try{let e={search:[i([{field:`device_name`,value:r.deviceName},{field:`applicant`,value:r.applicant},{field:`product_code`,value:r.productCode},{field:`clearance_type`,value:r.clearanceType}]),n(`decision_date`,r.decisionDateFrom,r.decisionDateTo)].filter(Boolean).join(`+AND+`)||void 0,limit:r.limit,skip:r.skip},a=await t.searchDevice510K(e),s=a.results??[];return{success:!0,data:s.map(o),totalResults:a.meta?.results?.total,displayedResults:s.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function c(e){return{deviceName:e.device_name,deviceClass:e.device_class,definition:a(e.definition),medicalSpecialty:e.medical_specialty,medicalSpecialtyDescription:e.medical_specialty_description,productCode:e.product_code,regulationNumber:e.regulation_number,gmpExempt:e.gmp_exempt_flag===`Y`,implant:e.implant_flag===`Y`,lifeSustaining:e.life_sustain_support_flag===`Y`}}async function l(n){e.tools(`searchDeviceClassifications`,n);try{let e={search:i([{field:`device_name`,value:n.deviceName},{field:`device_class`,value:n.deviceClass},{field:`medical_specialty`,value:n.medicalSpecialty},{field:`product_code`,value:n.productCode},{field:`regulation_number`,value:n.regulationNumber}])||void 0,limit:n.limit,skip:n.skip},r=await t.searchDeviceClassifications(e),a=r.results??[];return{success:!0,data:a.map(c),totalResults:r.meta?.results?.total,displayedResults:a.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function u(e){return{reportNumber:e.report_number,dateOfEvent:e.date_of_event,dateReceived:e.date_received,eventType:e.event_type,adverseEventFlag:e.adverse_event_flag===`Y`,productProblemFlag:e.product_problem_flag===`Y`,devices:e.device?.slice(0,3).map(e=>({brandName:e.brand_name,genericName:e.generic_name,manufacturerName:e.manufacturer_d_name,modelNumber:e.model_number,productCode:e.device_report_product_code,deviceClass:e.openfda?.device_class}))??[],mdrText:e.mdr_text?.slice(0,2).map(e=>({textType:e.text_type_code,text:a(e.text,300)}))??[]}}async function d(a){e.tools(`searchDeviceAdverseEvents`,a);try{if(a.reportNumber){let e={search:`report_number:"${r(a.reportNumber)}"`,limit:1},n=await t.searchDeviceAdverseEvents(e),i=n.results??[];return{success:!0,data:i.map(u),totalResults:n.meta?.results?.total,displayedResults:i.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}let e={search:[i([{field:`device.generic_name`,value:a.deviceName},{field:`device.brand_name`,value:a.brandName},{field:`device.manufacturer_d_name`,value:a.manufacturerName},{field:`event_type`,value:a.eventType}]),n(`date_received`,a.dateFrom,a.dateTo)].filter(Boolean).join(`+AND+`)||void 0,limit:a.limit,skip:a.skip},o=await t.searchDeviceAdverseEvents(e),s=o.results??[];return{success:!0,data:s.map(u),totalResults:o.meta?.results?.total,displayedResults:s.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function f(e){return{recallNumber:e.recall_number,recallingFirm:e.recalling_firm,classification:e.classification,status:e.status,productDescription:a(e.product_description),reasonForRecall:a(e.reason_for_recall),recallInitiationDate:e.recall_initiation_date,distributionPattern:a(e.distribution_pattern),city:e.city,state:e.state,deviceName:e.openfda?.device_name,deviceClass:e.openfda?.device_class}}async function p(r){e.tools(`searchDeviceEnforcement`,r);try{let e={search:[i([{field:`recalling_firm`,value:r.recallingFirm},{field:`product_description`,value:r.productDescription},{field:`classification`,value:r.classification},{field:`status`,value:r.status}]),n(`recall_initiation_date`,r.dateFrom,r.dateTo)].filter(Boolean).join(`+AND+`)||void 0,limit:r.limit,skip:r.skip},a=await t.searchDeviceEnforcement(e),o=a.results??[];return{success:!0,data:o.map(f),totalResults:a.meta?.results?.total,displayedResults:o.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}export{p as i,d as n,l as r,s as t};
2
+ //# sourceMappingURL=device-handlers-D8AD5oIk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-handlers-D8AD5oIk.js","names":["searchParams: SearchParams","response","searchParams","results"],"sources":["../src/handlers/device-handlers.ts"],"sourcesContent":["/**\n * Device Handlers\n * Query handlers for FDA device-related endpoints\n */\n\nimport type {\n Device510K,\n DeviceAdverseEvent,\n DeviceClassification,\n DeviceEnforcement,\n FDAToolResponse,\n SearchParams,\n} from \"../types/fda.js\"\nimport { fdaAPIClient } from \"../utils/api-client.js\"\nimport { loggers } from \"../utils/logger.js\"\n\n// Helper to build date range query\nfunction buildDateQuery(field: string, dateFrom?: string, dateTo?: string): string | undefined {\n if (!dateFrom && !dateTo) return undefined\n\n // FDA date format is YYYYMMDD\n const from = dateFrom?.replace(/-/g, \"\") ?? \"*\"\n const to = dateTo?.replace(/-/g, \"\") ?? \"*\"\n\n return `${field}:[${from}+TO+${to}]`\n}\n\n// Helper to escape special characters in search terms\nfunction escapeSearchTerm(term: string): string {\n return term.replace(/[+\\-&|!(){}[\\]^\"~*?:\\\\]/g, \"\\\\$&\").replace(/\\s+/g, \"+\")\n}\n\n// Helper to build a search query from multiple terms\nfunction buildSearchQuery(terms: Array<{ field: string; value?: string }>): string {\n const validTerms = terms.filter((t) => t.value !== undefined && t.value.trim() !== \"\")\n if (validTerms.length === 0) return \"\"\n\n return validTerms.map((t) => `${t.field}:\"${escapeSearchTerm(t.value!)}\"`).join(\"+AND+\")\n}\n\n// Format truncated text\nfunction truncateText(text: string | undefined, maxLength = 200): string | undefined {\n if (!text) return undefined\n return text.length > maxLength ? text.substring(0, maxLength) + \"...\" : text\n}\n\n// Device 510(k) Handler\nexport type Device510KParams = {\n deviceName?: string\n applicant?: string\n productCode?: string\n clearanceType?: string\n decisionDateFrom?: string\n decisionDateTo?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDevice510K = {\n kNumber: string | undefined\n deviceName: string | undefined\n applicant: string | undefined\n productCode: string | undefined\n clearanceType: string | undefined\n decisionCode: string | undefined\n decisionDescription: string | undefined\n decisionDate: string | undefined\n dateReceived: string | undefined\n city: string | undefined\n state: string | undefined\n country: string | undefined\n}\n\nfunction formatDevice510K(device: Device510K): FormattedDevice510K {\n return {\n kNumber: device.k_number,\n deviceName: device.device_name ?? device.openfda?.device_name,\n applicant: device.applicant,\n productCode: device.product_code,\n clearanceType: device.clearance_type,\n decisionCode: device.decision_code,\n decisionDescription: device.decision_description,\n decisionDate: device.decision_date,\n dateReceived: device.date_received,\n city: device.city,\n state: device.state,\n country: device.country_code,\n }\n}\n\nexport async function handleSearchDevice510K(\n params: Device510KParams,\n): Promise<FDAToolResponse<FormattedDevice510K[]>> {\n loggers.tools(\"searchDevice510K\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"device_name\", value: params.deviceName },\n { field: \"applicant\", value: params.applicant },\n { field: \"product_code\", value: params.productCode },\n { field: \"clearance_type\", value: params.clearanceType },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n const dateQuery = buildDateQuery(\"decision_date\", params.decisionDateFrom, params.decisionDateTo)\n const fullQuery = [searchQuery, dateQuery].filter(Boolean).join(\"+AND+\")\n\n const searchParams: SearchParams = {\n search: fullQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDevice510K(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDevice510K),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Device Classification Handler\nexport type DeviceClassificationParams = {\n deviceName?: string\n deviceClass?: \"1\" | \"2\" | \"3\"\n medicalSpecialty?: string\n productCode?: string\n regulationNumber?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDeviceClassification = {\n deviceName: string | undefined\n deviceClass: string | undefined\n definition: string | undefined\n medicalSpecialty: string | undefined\n medicalSpecialtyDescription: string | undefined\n productCode: string | undefined\n regulationNumber: string | undefined\n gmpExempt: boolean\n implant: boolean\n lifeSustaining: boolean\n}\n\nfunction formatDeviceClassification(classification: DeviceClassification): FormattedDeviceClassification {\n return {\n deviceName: classification.device_name,\n deviceClass: classification.device_class,\n definition: truncateText(classification.definition),\n medicalSpecialty: classification.medical_specialty,\n medicalSpecialtyDescription: classification.medical_specialty_description,\n productCode: classification.product_code,\n regulationNumber: classification.regulation_number,\n gmpExempt: classification.gmp_exempt_flag === \"Y\",\n implant: classification.implant_flag === \"Y\",\n lifeSustaining: classification.life_sustain_support_flag === \"Y\",\n }\n}\n\nexport async function handleSearchDeviceClassifications(\n params: DeviceClassificationParams,\n): Promise<FDAToolResponse<FormattedDeviceClassification[]>> {\n loggers.tools(\"searchDeviceClassifications\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"device_name\", value: params.deviceName },\n { field: \"device_class\", value: params.deviceClass },\n { field: \"medical_specialty\", value: params.medicalSpecialty },\n { field: \"product_code\", value: params.productCode },\n { field: \"regulation_number\", value: params.regulationNumber },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n\n const searchParams: SearchParams = {\n search: searchQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDeviceClassifications(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDeviceClassification),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Device Adverse Events (MDR) Handler\nexport type DeviceAdverseEventsParams = {\n reportNumber?: string\n deviceName?: string\n brandName?: string\n manufacturerName?: string\n eventType?: \"Injury\" | \"Malfunction\" | \"Death\" | \"Other\"\n dateFrom?: string\n dateTo?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDeviceAdverseEvent = {\n reportNumber: string | undefined\n dateOfEvent: string | undefined\n dateReceived: string | undefined\n eventType: string | undefined\n adverseEventFlag: boolean\n productProblemFlag: boolean\n devices: Array<{\n brandName: string | undefined\n genericName: string | undefined\n manufacturerName: string | undefined\n modelNumber: string | undefined\n productCode: string | undefined\n deviceClass: string | undefined\n }>\n mdrText: Array<{\n textType: string | undefined\n text: string | undefined\n }>\n}\n\nfunction formatDeviceAdverseEvent(event: DeviceAdverseEvent): FormattedDeviceAdverseEvent {\n return {\n reportNumber: event.report_number,\n dateOfEvent: event.date_of_event,\n dateReceived: event.date_received,\n eventType: event.event_type,\n adverseEventFlag: event.adverse_event_flag === \"Y\",\n productProblemFlag: event.product_problem_flag === \"Y\",\n devices:\n event.device?.slice(0, 3).map((d) => ({\n brandName: d.brand_name,\n genericName: d.generic_name,\n manufacturerName: d.manufacturer_d_name,\n modelNumber: d.model_number,\n productCode: d.device_report_product_code,\n deviceClass: d.openfda?.device_class,\n })) ?? [],\n mdrText:\n event.mdr_text?.slice(0, 2).map((t) => ({\n textType: t.text_type_code,\n text: truncateText(t.text, 300),\n })) ?? [],\n }\n}\n\nexport async function handleSearchDeviceAdverseEvents(\n params: DeviceAdverseEventsParams,\n): Promise<FDAToolResponse<FormattedDeviceAdverseEvent[]>> {\n loggers.tools(\"searchDeviceAdverseEvents\", params)\n\n try {\n // If reportNumber is provided, do a direct lookup\n if (params.reportNumber) {\n const searchParams: SearchParams = {\n search: `report_number:\"${escapeSearchTerm(params.reportNumber)}\"`,\n limit: 1,\n }\n\n const response = await fdaAPIClient.searchDeviceAdverseEvents(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDeviceAdverseEvent),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n }\n\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"device.generic_name\", value: params.deviceName },\n { field: \"device.brand_name\", value: params.brandName },\n { field: \"device.manufacturer_d_name\", value: params.manufacturerName },\n { field: \"event_type\", value: params.eventType },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n const dateQuery = buildDateQuery(\"date_received\", params.dateFrom, params.dateTo)\n const fullQuery = [searchQuery, dateQuery].filter(Boolean).join(\"+AND+\")\n\n const searchParams: SearchParams = {\n search: fullQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDeviceAdverseEvents(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDeviceAdverseEvent),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Device Enforcement (Recalls) Handler\nexport type DeviceEnforcementParams = {\n recallingFirm?: string\n productDescription?: string\n classification?: \"Class I\" | \"Class II\" | \"Class III\"\n status?: \"Ongoing\" | \"Completed\" | \"Terminated\" | \"Pending\"\n dateFrom?: string\n dateTo?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDeviceEnforcement = {\n recallNumber: string | undefined\n recallingFirm: string | undefined\n classification: string | undefined\n status: string | undefined\n productDescription: string | undefined\n reasonForRecall: string | undefined\n recallInitiationDate: string | undefined\n distributionPattern: string | undefined\n city: string | undefined\n state: string | undefined\n deviceName: string | undefined\n deviceClass: string | undefined\n}\n\nfunction formatDeviceEnforcement(recall: DeviceEnforcement): FormattedDeviceEnforcement {\n return {\n recallNumber: recall.recall_number,\n recallingFirm: recall.recalling_firm,\n classification: recall.classification,\n status: recall.status,\n productDescription: truncateText(recall.product_description),\n reasonForRecall: truncateText(recall.reason_for_recall),\n recallInitiationDate: recall.recall_initiation_date,\n distributionPattern: truncateText(recall.distribution_pattern),\n city: recall.city,\n state: recall.state,\n deviceName: recall.openfda?.device_name,\n deviceClass: recall.openfda?.device_class,\n }\n}\n\nexport async function handleSearchDeviceEnforcement(\n params: DeviceEnforcementParams,\n): Promise<FDAToolResponse<FormattedDeviceEnforcement[]>> {\n loggers.tools(\"searchDeviceEnforcement\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"recalling_firm\", value: params.recallingFirm },\n { field: \"product_description\", value: params.productDescription },\n { field: \"classification\", value: params.classification },\n { field: \"status\", value: params.status },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n const dateQuery = buildDateQuery(\"recall_initiation_date\", params.dateFrom, params.dateTo)\n const fullQuery = [searchQuery, dateQuery].filter(Boolean).join(\"+AND+\")\n\n const searchParams: SearchParams = {\n search: fullQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDeviceEnforcement(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDeviceEnforcement),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n"],"mappings":"yFAiBA,SAAS,EAAe,EAAe,EAAmB,EAAqC,CACzF,MAAC,GAAY,CAAC,GAMlB,MAAO,GAAG,EAAM,IAHH,GAAU,QAAQ,KAAM,GAAG,EAAI,IAGnB,MAFd,GAAQ,QAAQ,KAAM,GAAG,EAAI,IAEN,GAIpC,SAAS,EAAiB,EAAsB,CAC9C,OAAO,EAAK,QAAQ,2BAA4B,OAAO,CAAC,QAAQ,OAAQ,IAAI,CAI9E,SAAS,EAAiB,EAAyD,CACjF,IAAM,EAAa,EAAM,OAAQ,GAAM,EAAE,QAAU,IAAA,IAAa,EAAE,MAAM,MAAM,GAAK,GAAG,CAGtF,OAFI,EAAW,SAAW,EAAU,GAE7B,EAAW,IAAK,GAAM,GAAG,EAAE,MAAM,IAAI,EAAiB,EAAE,MAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,CAI1F,SAAS,EAAa,EAA0B,EAAY,IAAyB,CAC9E,KACL,OAAO,EAAK,OAAS,EAAY,EAAK,UAAU,EAAG,EAAU,CAAG,MAAQ,EA8B1E,SAAS,EAAiB,EAAyC,CACjE,MAAO,CACL,QAAS,EAAO,SAChB,WAAY,EAAO,aAAe,EAAO,SAAS,YAClD,UAAW,EAAO,UAClB,YAAa,EAAO,aACpB,cAAe,EAAO,eACtB,aAAc,EAAO,cACrB,oBAAqB,EAAO,qBAC5B,aAAc,EAAO,cACrB,aAAc,EAAO,cACrB,KAAM,EAAO,KACb,MAAO,EAAO,MACd,QAAS,EAAO,aACjB,CAGH,eAAsB,EACpB,EACiD,CACjD,EAAQ,MAAM,mBAAoB,EAAO,CAEzC,GAAI,CAYF,IAAMA,EAA6B,CACjC,OAHgB,CAFE,EAP0C,CAC5D,CAAE,MAAO,cAAe,MAAO,EAAO,WAAY,CAClD,CAAE,MAAO,YAAa,MAAO,EAAO,UAAW,CAC/C,CAAE,MAAO,eAAgB,MAAO,EAAO,YAAa,CACpD,CAAE,MAAO,iBAAkB,MAAO,EAAO,cAAe,CACzD,CAEgD,CAC/B,EAAe,gBAAiB,EAAO,iBAAkB,EAAO,eAAe,CACvD,CAAC,OAAO,QAAQ,CAAC,KAAK,QAAQ,EAGjD,IAAA,GACrB,MAAO,EAAO,MACd,KAAM,EAAO,KACd,CAEK,EAAW,MAAM,EAAa,iBAAiB,EAAa,CAC5D,EAAU,EAAS,SAAW,EAAE,CAEtC,MAAO,CACL,QAAS,GACT,KAAM,EAAQ,IAAI,EAAiB,CACnC,aAAc,EAAS,MAAM,SAAS,MACtC,iBAAkB,EAAQ,OAC1B,eACA,SAAU,EAAa,kBAAkB,CAC1C,OACM,EAAO,CACd,MAAO,CACL,QAAS,GACT,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAC9D,EA4BL,SAAS,EAA2B,EAAqE,CACvG,MAAO,CACL,WAAY,EAAe,YAC3B,YAAa,EAAe,aAC5B,WAAY,EAAa,EAAe,WAAW,CACnD,iBAAkB,EAAe,kBACjC,4BAA6B,EAAe,8BAC5C,YAAa,EAAe,aAC5B,iBAAkB,EAAe,kBACjC,UAAW,EAAe,kBAAoB,IAC9C,QAAS,EAAe,eAAiB,IACzC,eAAgB,EAAe,4BAA8B,IAC9D,CAGH,eAAsB,EACpB,EAC2D,CAC3D,EAAQ,MAAM,8BAA+B,EAAO,CAEpD,GAAI,CAWF,IAAMA,EAA6B,CACjC,OAHkB,EAR0C,CAC5D,CAAE,MAAO,cAAe,MAAO,EAAO,WAAY,CAClD,CAAE,MAAO,eAAgB,MAAO,EAAO,YAAa,CACpD,CAAE,MAAO,oBAAqB,MAAO,EAAO,iBAAkB,CAC9D,CAAE,MAAO,eAAgB,MAAO,EAAO,YAAa,CACpD,CAAE,MAAO,oBAAqB,MAAO,EAAO,iBAAkB,CAC/D,CAEgD,EAGxB,IAAA,GACvB,MAAO,EAAO,MACd,KAAM,EAAO,KACd,CAEK,EAAW,MAAM,EAAa,4BAA4B,EAAa,CACvE,EAAU,EAAS,SAAW,EAAE,CAEtC,MAAO,CACL,QAAS,GACT,KAAM,EAAQ,IAAI,EAA2B,CAC7C,aAAc,EAAS,MAAM,SAAS,MACtC,iBAAkB,EAAQ,OAC1B,eACA,SAAU,EAAa,kBAAkB,CAC1C,OACM,EAAO,CACd,MAAO,CACL,QAAS,GACT,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAC9D,EAsCL,SAAS,EAAyB,EAAwD,CACxF,MAAO,CACL,aAAc,EAAM,cACpB,YAAa,EAAM,cACnB,aAAc,EAAM,cACpB,UAAW,EAAM,WACjB,iBAAkB,EAAM,qBAAuB,IAC/C,mBAAoB,EAAM,uBAAyB,IACnD,QACE,EAAM,QAAQ,MAAM,EAAG,EAAE,CAAC,IAAK,IAAO,CACpC,UAAW,EAAE,WACb,YAAa,EAAE,aACf,iBAAkB,EAAE,oBACpB,YAAa,EAAE,aACf,YAAa,EAAE,2BACf,YAAa,EAAE,SAAS,aACzB,EAAE,EAAI,EAAE,CACX,QACE,EAAM,UAAU,MAAM,EAAG,EAAE,CAAC,IAAK,IAAO,CACtC,SAAU,EAAE,eACZ,KAAM,EAAa,EAAE,KAAM,IAAI,CAChC,EAAE,EAAI,EAAE,CACZ,CAGH,eAAsB,EACpB,EACyD,CACzD,EAAQ,MAAM,4BAA6B,EAAO,CAElD,GAAI,CAEF,GAAI,EAAO,aAAc,CACvB,IAAMA,EAA6B,CACjC,OAAQ,kBAAkB,EAAiB,EAAO,aAAa,CAAC,GAChE,MAAO,EACR,CAEKC,EAAW,MAAM,EAAa,0BAA0BC,EAAa,CACrEC,EAAUF,EAAS,SAAW,EAAE,CAEtC,MAAO,CACL,QAAS,GACT,KAAME,EAAQ,IAAI,EAAyB,CAC3C,aAAcF,EAAS,MAAM,SAAS,MACtC,iBAAkBE,EAAQ,OAC1B,aAAA,EACA,SAAU,EAAa,kBAAkB,CAC1C,CAcH,IAAMH,EAA6B,CACjC,OAHgB,CAFE,EAP0C,CAC5D,CAAE,MAAO,sBAAuB,MAAO,EAAO,WAAY,CAC1D,CAAE,MAAO,oBAAqB,MAAO,EAAO,UAAW,CACvD,CAAE,MAAO,6BAA8B,MAAO,EAAO,iBAAkB,CACvE,CAAE,MAAO,aAAc,MAAO,EAAO,UAAW,CACjD,CAEgD,CAC/B,EAAe,gBAAiB,EAAO,SAAU,EAAO,OAAO,CACvC,CAAC,OAAO,QAAQ,CAAC,KAAK,QAAQ,EAGjD,IAAA,GACrB,MAAO,EAAO,MACd,KAAM,EAAO,KACd,CAEK,EAAW,MAAM,EAAa,0BAA0B,EAAa,CACrE,EAAU,EAAS,SAAW,EAAE,CAEtC,MAAO,CACL,QAAS,GACT,KAAM,EAAQ,IAAI,EAAyB,CAC3C,aAAc,EAAS,MAAM,SAAS,MACtC,iBAAkB,EAAQ,OAC1B,eACA,SAAU,EAAa,kBAAkB,CAC1C,OACM,EAAO,CACd,MAAO,CACL,QAAS,GACT,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAC9D,EA+BL,SAAS,EAAwB,EAAuD,CACtF,MAAO,CACL,aAAc,EAAO,cACrB,cAAe,EAAO,eACtB,eAAgB,EAAO,eACvB,OAAQ,EAAO,OACf,mBAAoB,EAAa,EAAO,oBAAoB,CAC5D,gBAAiB,EAAa,EAAO,kBAAkB,CACvD,qBAAsB,EAAO,uBAC7B,oBAAqB,EAAa,EAAO,qBAAqB,CAC9D,KAAM,EAAO,KACb,MAAO,EAAO,MACd,WAAY,EAAO,SAAS,YAC5B,YAAa,EAAO,SAAS,aAC9B,CAGH,eAAsB,EACpB,EACwD,CACxD,EAAQ,MAAM,0BAA2B,EAAO,CAEhD,GAAI,CAYF,IAAMA,EAA6B,CACjC,OAHgB,CAFE,EAP0C,CAC5D,CAAE,MAAO,iBAAkB,MAAO,EAAO,cAAe,CACxD,CAAE,MAAO,sBAAuB,MAAO,EAAO,mBAAoB,CAClE,CAAE,MAAO,iBAAkB,MAAO,EAAO,eAAgB,CACzD,CAAE,MAAO,SAAU,MAAO,EAAO,OAAQ,CAC1C,CAEgD,CAC/B,EAAe,yBAA0B,EAAO,SAAU,EAAO,OAAO,CAChD,CAAC,OAAO,QAAQ,CAAC,KAAK,QAAQ,EAGjD,IAAA,GACrB,MAAO,EAAO,MACd,KAAM,EAAO,KACd,CAEK,EAAW,MAAM,EAAa,wBAAwB,EAAa,CACnE,EAAU,EAAS,SAAW,EAAE,CAEtC,MAAO,CACL,QAAS,GACT,KAAM,EAAQ,IAAI,EAAwB,CAC1C,aAAc,EAAS,MAAM,SAAS,MACtC,iBAAkB,EAAQ,OAC1B,eACA,SAAU,EAAa,kBAAkB,CAC1C,OACM,EAAO,CACd,MAAO,CACL,QAAS,GACT,MAAO,aAAiB,MAAQ,EAAM,QAAU,OAAO,EAAM,CAC9D"}
@@ -0,0 +1,2 @@
1
+ import{loggers as e}from"./utils/logger.js";import{n as t}from"./api-client-BGnUXMwX.js";function n(e,t,n){if(!(!t&&!n))return`${e}:[${t?.replace(/-/g,``)??`*`}+TO+${n?.replace(/-/g,``)??`*`}]`}function r(e){return e.replace(/[+\-&|!(){}[\]^"~*?:\\]/g,`\\$&`).replace(/\s+/g,`+`)}function i(e){let t=e.filter(e=>e.value!==void 0&&e.value.trim()!==``);return t.length===0?``:t.map(e=>`${e.field}:"${r(e.value)}"`).join(`+AND+`)}function a(e,t=200){if(e)return e.length>t?e.substring(0,t)+`...`:e}function o(e){return{reportId:e.safetyreportid,receiveDate:e.receivedate,serious:e.serious===`1`,drugs:e.patient?.drug?.slice(0,3).map(e=>({name:e.medicinalproduct??e.activesubstance?.activesubstancename,indication:e.drugindication,route:e.drugadministrationroute}))??[],reactions:e.patient?.reaction?.slice(0,3).map(e=>({reaction:e.reactionmeddrapt,outcome:e.reactionoutcome}))??[],patient:{age:e.patient?.patientonsetage?`${e.patient.patientonsetage} ${e.patient.patientonsetageunit??``}`:void 0,sex:e.patient?.patientsex===`1`?`Male`:e.patient?.patientsex===`2`?`Female`:void 0,weight:e.patient?.patientweight?`${e.patient.patientweight} kg`:void 0}}}async function s(a){e.tools(`searchDrugAdverseEvents`,a);try{if(a.safetyReportId){let e={search:`safetyreportid:"${r(a.safetyReportId)}"`,limit:1},n=await t.searchDrugAdverseEvents(e),i=n.results??[];return{success:!0,data:i.map(o),totalResults:n.meta?.results?.total,displayedResults:i.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}let e=[{field:`patient.drug.medicinalproduct`,value:a.drugName},{field:`patient.reaction.reactionmeddrapt`,value:a.reaction},{field:`patient.drug.openfda.manufacturer_name`,value:a.manufacturer}];a.serious!==void 0&&e.push({field:`serious`,value:a.serious?`1`:`2`});let s={search:[i(e),n(`receivedate`,a.dateFrom,a.dateTo)].filter(Boolean).join(`+AND+`)||void 0,limit:a.limit,skip:a.skip},c=await t.searchDrugAdverseEvents(s),l=c.results??[];return{success:!0,data:l.map(o),totalResults:c.meta?.results?.total,displayedResults:l.length,searchParams:s,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function c(e,t){let n=e=>!t||t.includes(e);return{setId:e.set_id,brandName:e.openfda?.brand_name?.[0],genericName:e.openfda?.generic_name?.[0],manufacturer:e.openfda?.manufacturer_name?.[0],activeIngredients:e.openfda?.substance_name?.slice(0,5)??[],boxedWarning:n(`boxed_warning`)?a(e.boxed_warning?.[0],500):void 0,indications:n(`indications_and_usage`)?a(e.indications_and_usage?.[0]):void 0,warnings:n(`warnings`)?a(e.warnings?.[0]):void 0,contraindications:n(`contraindications`)?a(e.contraindications?.[0]):void 0,adverseReactions:n(`adverse_reactions`)?a(e.adverse_reactions?.[0]):void 0,drugInteractions:n(`drug_interactions`)?a(e.drug_interactions?.[0]):void 0,dosageAndAdministration:n(`dosage_and_administration`)?a(e.dosage_and_administration?.[0]):void 0,clinicalPharmacology:n(`clinical_pharmacology`)?a(e.clinical_pharmacology?.[0]):void 0,mechanismOfAction:n(`mechanism_of_action`)?a(e.mechanism_of_action?.[0]):void 0,pharmacokinetics:n(`pharmacokinetics`)?a(e.pharmacokinetics?.[0]):void 0,overdosage:n(`overdosage`)?a(e.overdosage?.[0]):void 0,description:n(`description`)?a(e.description?.[0]):void 0,howSupplied:n(`how_supplied`)?a(e.how_supplied?.[0]):void 0,storageAndHandling:n(`storage_and_handling`)?a(e.storage_and_handling?.[0]):void 0,route:e.openfda?.route?.slice(0,3)??[]}}async function l(n){e.tools(`searchDrugLabels`,n);try{if(n.setId){let e={search:`set_id:"${r(n.setId)}"`,limit:1},i=await t.searchDrugLabels(e),a=i.results??[];return{success:!0,data:a.map(e=>c(e,n.sections)),totalResults:i.meta?.results?.total,displayedResults:a.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}let e={search:[i([{field:`openfda.brand_name`,value:n.drugName},{field:`indications_and_usage`,value:n.indication},{field:`openfda.substance_name`,value:n.activeIngredient},{field:`openfda.route`,value:n.route}]),n.hasBoxedWarning?`_exists_:boxed_warning`:void 0].filter(Boolean).join(`+AND+`)||void 0,limit:n.limit,skip:n.skip},a=await t.searchDrugLabels(e),o=a.results??[];return{success:!0,data:o.map(e=>c(e,n.sections)),totalResults:a.meta?.results?.total,displayedResults:o.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function u(e){return{productNdc:e.product_ndc,brandName:e.brand_name,genericName:e.generic_name,labelerName:e.labeler_name,dosageForm:e.dosage_form,route:e.route??[],activeIngredients:e.active_ingredients?.slice(0,3).map(e=>({name:e.name,strength:e.strength}))??[],marketingStartDate:e.marketing_start_date,productType:e.product_type}}async function d(n){e.tools(`searchDrugNDC`,n);try{let e={search:i([{field:`product_ndc`,value:n.productNdc},{field:`brand_name`,value:n.brandName},{field:`generic_name`,value:n.genericName},{field:`labeler_name`,value:n.labelerName},{field:`dosage_form`,value:n.dosageForm},{field:`route`,value:n.route}])||void 0,limit:n.limit,skip:n.skip},r=await t.searchDrugNDC(e),a=r.results??[];return{success:!0,data:a.map(u),totalResults:r.meta?.results?.total,displayedResults:a.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function f(e){return{recallNumber:e.recall_number,recallingFirm:e.recalling_firm,classification:e.classification,status:e.status,productDescription:a(e.product_description),reasonForRecall:a(e.reason_for_recall),recallInitiationDate:e.recall_initiation_date,distributionPattern:a(e.distribution_pattern),city:e.city,state:e.state}}async function p(r){e.tools(`searchDrugEnforcement`,r);try{let e={search:[i([{field:`recalling_firm`,value:r.recallingFirm},{field:`classification`,value:r.classification},{field:`status`,value:r.status},{field:`state`,value:r.state}]),n(`recall_initiation_date`,r.dateFrom,r.dateTo)].filter(Boolean).join(`+AND+`)||void 0,limit:r.limit,skip:r.skip},a=await t.searchDrugEnforcement(e),o=a.results??[];return{success:!0,data:o.map(f),totalResults:a.meta?.results?.total,displayedResults:o.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function m(e){let t=e.submissions?.[0];return{applicationNumber:e.application_number,sponsorName:e.sponsor_name,products:e.products?.slice(0,3).map(e=>({brandName:e.brand_name,dosageForm:e.dosage_form,route:e.route,marketingStatus:e.marketing_status,activeIngredients:e.active_ingredients?.slice(0,3).map(e=>({name:e.name,strength:e.strength}))??[]}))??[],latestSubmission:t?{type:t.submission_type,status:t.submission_status,statusDate:t.submission_status_date}:void 0}}async function h(n){e.tools(`searchDrugsFDA`,n);try{let e={search:i([{field:`sponsor_name`,value:n.sponsorName},{field:`application_number`,value:n.applicationNumber},{field:`products.brand_name`,value:n.brandName},{field:`products.marketing_status`,value:n.marketingStatus}])||void 0,limit:n.limit,skip:n.skip},r=await t.searchDrugsFDA(e),a=r.results??[];return{success:!0,data:a.map(m),totalResults:r.meta?.results?.total,displayedResults:a.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function g(e){return{genericName:e.generic_name,proprietaryName:e.proprietary_name,status:e.status,description:a(e.description),initialPostingDate:e.initial_posting_date,resolvedShortageDate:e.resolved_shortage_date}}async function _(n){e.tools(`searchDrugShortages`,n);try{let e={search:i([{field:`generic_name`,value:n.genericName},{field:`status`,value:n.status}])||void 0,limit:n.limit,skip:n.skip},r=await t.searchDrugShortages(e),a=r.results??[];return{success:!0,data:a.map(g),totalResults:r.meta?.results?.total,displayedResults:a.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}export{_ as a,d as i,p as n,h as o,l as r,s as t};
2
+ //# sourceMappingURL=drug-handlers-D5VxbBCL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drug-handlers-D5VxbBCL.js","names":["searchParams: SearchParams","response","searchParams","results","searchTerms: Array<{ field: string; value?: string }>"],"sources":["../src/handlers/drug-handlers.ts"],"sourcesContent":["/**\n * Drug Handlers\n * Query handlers for FDA drug-related endpoints\n */\n\nimport type {\n DrugAdverseEvent,\n DrugEnforcement,\n DrugLabel,\n DrugNDC,\n DrugsFDA,\n DrugShortage,\n FDAToolResponse,\n SearchParams,\n} from \"../types/fda.js\"\nimport { fdaAPIClient } from \"../utils/api-client.js\"\nimport { loggers } from \"../utils/logger.js\"\n\n// Helper to build date range query\nfunction buildDateQuery(field: string, dateFrom?: string, dateTo?: string): string | undefined {\n if (!dateFrom && !dateTo) return undefined\n\n // FDA date format is YYYYMMDD\n const from = dateFrom?.replace(/-/g, \"\") ?? \"*\"\n const to = dateTo?.replace(/-/g, \"\") ?? \"*\"\n\n return `${field}:[${from}+TO+${to}]`\n}\n\n// Helper to escape special characters in search terms\nfunction escapeSearchTerm(term: string): string {\n // Escape special characters that have meaning in FDA's search syntax\n return term.replace(/[+\\-&|!(){}[\\]^\"~*?:\\\\]/g, \"\\\\$&\").replace(/\\s+/g, \"+\")\n}\n\n// Helper to build a search query from multiple terms\nfunction buildSearchQuery(terms: Array<{ field: string; value?: string }>): string {\n const validTerms = terms.filter((t) => t.value !== undefined && t.value.trim() !== \"\")\n if (validTerms.length === 0) return \"\"\n\n return validTerms.map((t) => `${t.field}:\"${escapeSearchTerm(t.value!)}\"`).join(\"+AND+\")\n}\n\n// Format truncated text\nfunction truncateText(text: string | undefined, maxLength = 200): string | undefined {\n if (!text) return undefined\n return text.length > maxLength ? text.substring(0, maxLength) + \"...\" : text\n}\n\n// Drug Adverse Events Handler\nexport type DrugAdverseEventsParams = {\n safetyReportId?: string\n drugName?: string\n reaction?: string\n manufacturer?: string\n serious?: boolean\n dateFrom?: string\n dateTo?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDrugAdverseEvent = {\n reportId: string | undefined\n receiveDate: string | undefined\n serious: boolean\n drugs: Array<{\n name: string | undefined\n indication: string | undefined\n route: string | undefined\n }>\n reactions: Array<{\n reaction: string | undefined\n outcome: string | undefined\n }>\n patient: {\n age: string | undefined\n sex: string | undefined\n weight: string | undefined\n }\n}\n\nfunction formatDrugAdverseEvent(event: DrugAdverseEvent): FormattedDrugAdverseEvent {\n return {\n reportId: event.safetyreportid,\n receiveDate: event.receivedate,\n serious: event.serious === \"1\",\n drugs:\n event.patient?.drug?.slice(0, 3).map((d) => ({\n name: d.medicinalproduct ?? d.activesubstance?.activesubstancename,\n indication: d.drugindication,\n route: d.drugadministrationroute,\n })) ?? [],\n reactions:\n event.patient?.reaction?.slice(0, 3).map((r) => ({\n reaction: r.reactionmeddrapt,\n outcome: r.reactionoutcome,\n })) ?? [],\n patient: {\n age: event.patient?.patientonsetage\n ? `${event.patient.patientonsetage} ${event.patient.patientonsetageunit ?? \"\"}`\n : undefined,\n sex: event.patient?.patientsex === \"1\" ? \"Male\" : event.patient?.patientsex === \"2\" ? \"Female\" : undefined,\n weight: event.patient?.patientweight ? `${event.patient.patientweight} kg` : undefined,\n },\n }\n}\n\nexport async function handleSearchDrugAdverseEvents(\n params: DrugAdverseEventsParams,\n): Promise<FDAToolResponse<FormattedDrugAdverseEvent[]>> {\n loggers.tools(\"searchDrugAdverseEvents\", params)\n\n try {\n // If safetyReportId is provided, do a direct lookup\n if (params.safetyReportId) {\n const searchParams: SearchParams = {\n search: `safetyreportid:\"${escapeSearchTerm(params.safetyReportId)}\"`,\n limit: 1,\n }\n\n const response = await fdaAPIClient.searchDrugAdverseEvents(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDrugAdverseEvent),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n }\n\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"patient.drug.medicinalproduct\", value: params.drugName },\n { field: \"patient.reaction.reactionmeddrapt\", value: params.reaction },\n { field: \"patient.drug.openfda.manufacturer_name\", value: params.manufacturer },\n ]\n\n if (params.serious !== undefined) {\n searchTerms.push({ field: \"serious\", value: params.serious ? \"1\" : \"2\" })\n }\n\n const searchQuery = buildSearchQuery(searchTerms)\n const dateQuery = buildDateQuery(\"receivedate\", params.dateFrom, params.dateTo)\n const fullQuery = [searchQuery, dateQuery].filter(Boolean).join(\"+AND+\")\n\n const searchParams: SearchParams = {\n search: fullQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDrugAdverseEvents(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDrugAdverseEvent),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Drug Labels Handler\nexport type DrugLabelsParams = {\n setId?: string\n drugName?: string\n indication?: string\n activeIngredient?: string\n route?: string\n hasBoxedWarning?: boolean\n sections?: string[]\n limit?: number\n skip?: number\n}\n\ntype FormattedDrugLabel = {\n setId: string | undefined\n brandName: string | undefined\n genericName: string | undefined\n manufacturer: string | undefined\n activeIngredients: string[]\n boxedWarning: string | undefined\n indications: string | undefined\n warnings: string | undefined\n contraindications: string | undefined\n adverseReactions: string | undefined\n drugInteractions: string | undefined\n dosageAndAdministration: string | undefined\n clinicalPharmacology: string | undefined\n mechanismOfAction: string | undefined\n pharmacokinetics: string | undefined\n overdosage: string | undefined\n description: string | undefined\n howSupplied: string | undefined\n storageAndHandling: string | undefined\n route: string[]\n}\n\nfunction formatDrugLabel(label: DrugLabel, sections?: string[]): FormattedDrugLabel {\n // Helper to conditionally include section based on sections filter\n const includeSection = (sectionName: string) => !sections || sections.includes(sectionName)\n\n return {\n setId: label.set_id,\n brandName: label.openfda?.brand_name?.[0],\n genericName: label.openfda?.generic_name?.[0],\n manufacturer: label.openfda?.manufacturer_name?.[0],\n activeIngredients: label.openfda?.substance_name?.slice(0, 5) ?? [],\n boxedWarning: includeSection(\"boxed_warning\") ? truncateText(label.boxed_warning?.[0], 500) : undefined,\n indications: includeSection(\"indications_and_usage\") ? truncateText(label.indications_and_usage?.[0]) : undefined,\n warnings: includeSection(\"warnings\") ? truncateText(label.warnings?.[0]) : undefined,\n contraindications: includeSection(\"contraindications\") ? truncateText(label.contraindications?.[0]) : undefined,\n adverseReactions: includeSection(\"adverse_reactions\") ? truncateText(label.adverse_reactions?.[0]) : undefined,\n drugInteractions: includeSection(\"drug_interactions\") ? truncateText(label.drug_interactions?.[0]) : undefined,\n dosageAndAdministration: includeSection(\"dosage_and_administration\")\n ? truncateText(label.dosage_and_administration?.[0])\n : undefined,\n clinicalPharmacology: includeSection(\"clinical_pharmacology\")\n ? truncateText(label.clinical_pharmacology?.[0])\n : undefined,\n mechanismOfAction: includeSection(\"mechanism_of_action\") ? truncateText(label.mechanism_of_action?.[0]) : undefined,\n pharmacokinetics: includeSection(\"pharmacokinetics\") ? truncateText(label.pharmacokinetics?.[0]) : undefined,\n overdosage: includeSection(\"overdosage\") ? truncateText(label.overdosage?.[0]) : undefined,\n description: includeSection(\"description\") ? truncateText(label.description?.[0]) : undefined,\n howSupplied: includeSection(\"how_supplied\") ? truncateText(label.how_supplied?.[0]) : undefined,\n storageAndHandling: includeSection(\"storage_and_handling\")\n ? truncateText(label.storage_and_handling?.[0])\n : undefined,\n route: label.openfda?.route?.slice(0, 3) ?? [],\n }\n}\n\nexport async function handleSearchDrugLabels(params: DrugLabelsParams): Promise<FDAToolResponse<FormattedDrugLabel[]>> {\n loggers.tools(\"searchDrugLabels\", params)\n\n try {\n // If setId is provided, do a direct lookup\n if (params.setId) {\n const searchParams: SearchParams = {\n search: `set_id:\"${escapeSearchTerm(params.setId)}\"`,\n limit: 1,\n }\n\n const response = await fdaAPIClient.searchDrugLabels(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map((label) => formatDrugLabel(label, params.sections)),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n }\n\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"openfda.brand_name\", value: params.drugName },\n { field: \"indications_and_usage\", value: params.indication },\n { field: \"openfda.substance_name\", value: params.activeIngredient },\n { field: \"openfda.route\", value: params.route },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n\n // Build boxed warning existence query\n const boxedWarningQuery = params.hasBoxedWarning ? \"_exists_:boxed_warning\" : undefined\n\n const fullQuery = [searchQuery, boxedWarningQuery].filter(Boolean).join(\"+AND+\")\n\n const searchParams: SearchParams = {\n search: fullQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDrugLabels(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map((label) => formatDrugLabel(label, params.sections)),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Drug NDC Handler\nexport type DrugNDCParams = {\n productNdc?: string\n brandName?: string\n genericName?: string\n labelerName?: string\n dosageForm?: string\n route?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDrugNDC = {\n productNdc: string | undefined\n brandName: string | undefined\n genericName: string | undefined\n labelerName: string | undefined\n dosageForm: string | undefined\n route: string[]\n activeIngredients: Array<{ name: string | undefined; strength: string | undefined }>\n marketingStartDate: string | undefined\n productType: string | undefined\n}\n\nfunction formatDrugNDC(ndc: DrugNDC): FormattedDrugNDC {\n return {\n productNdc: ndc.product_ndc,\n brandName: ndc.brand_name,\n genericName: ndc.generic_name,\n labelerName: ndc.labeler_name,\n dosageForm: ndc.dosage_form,\n route: ndc.route ?? [],\n activeIngredients:\n ndc.active_ingredients?.slice(0, 3).map((ai) => ({\n name: ai.name,\n strength: ai.strength,\n })) ?? [],\n marketingStartDate: ndc.marketing_start_date,\n productType: ndc.product_type,\n }\n}\n\nexport async function handleSearchDrugNDC(params: DrugNDCParams): Promise<FDAToolResponse<FormattedDrugNDC[]>> {\n loggers.tools(\"searchDrugNDC\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"product_ndc\", value: params.productNdc },\n { field: \"brand_name\", value: params.brandName },\n { field: \"generic_name\", value: params.genericName },\n { field: \"labeler_name\", value: params.labelerName },\n { field: \"dosage_form\", value: params.dosageForm },\n { field: \"route\", value: params.route },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n\n const searchParams: SearchParams = {\n search: searchQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDrugNDC(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDrugNDC),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Drug Enforcement (Recalls) Handler\nexport type DrugEnforcementParams = {\n recallingFirm?: string\n classification?: \"Class I\" | \"Class II\" | \"Class III\"\n status?: \"Ongoing\" | \"Completed\" | \"Terminated\" | \"Pending\"\n state?: string\n dateFrom?: string\n dateTo?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDrugEnforcement = {\n recallNumber: string | undefined\n recallingFirm: string | undefined\n classification: string | undefined\n status: string | undefined\n productDescription: string | undefined\n reasonForRecall: string | undefined\n recallInitiationDate: string | undefined\n distributionPattern: string | undefined\n city: string | undefined\n state: string | undefined\n}\n\nfunction formatDrugEnforcement(recall: DrugEnforcement): FormattedDrugEnforcement {\n return {\n recallNumber: recall.recall_number,\n recallingFirm: recall.recalling_firm,\n classification: recall.classification,\n status: recall.status,\n productDescription: truncateText(recall.product_description),\n reasonForRecall: truncateText(recall.reason_for_recall),\n recallInitiationDate: recall.recall_initiation_date,\n distributionPattern: truncateText(recall.distribution_pattern),\n city: recall.city,\n state: recall.state,\n }\n}\n\nexport async function handleSearchDrugEnforcement(\n params: DrugEnforcementParams,\n): Promise<FDAToolResponse<FormattedDrugEnforcement[]>> {\n loggers.tools(\"searchDrugEnforcement\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"recalling_firm\", value: params.recallingFirm },\n { field: \"classification\", value: params.classification },\n { field: \"status\", value: params.status },\n { field: \"state\", value: params.state },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n const dateQuery = buildDateQuery(\"recall_initiation_date\", params.dateFrom, params.dateTo)\n const fullQuery = [searchQuery, dateQuery].filter(Boolean).join(\"+AND+\")\n\n const searchParams: SearchParams = {\n search: fullQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDrugEnforcement(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDrugEnforcement),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Drugs@FDA Handler\nexport type DrugsFDAParams = {\n sponsorName?: string\n applicationNumber?: string\n brandName?: string\n marketingStatus?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDrugsFDA = {\n applicationNumber: string | undefined\n sponsorName: string | undefined\n products: Array<{\n brandName: string | undefined\n dosageForm: string | undefined\n route: string | undefined\n marketingStatus: string | undefined\n activeIngredients: Array<{ name: string | undefined; strength: string | undefined }>\n }>\n latestSubmission:\n | {\n type: string | undefined\n status: string | undefined\n statusDate: string | undefined\n }\n | undefined\n}\n\nfunction formatDrugsFDA(drug: DrugsFDA): FormattedDrugsFDA {\n const latestSubmission = drug.submissions?.[0]\n\n return {\n applicationNumber: drug.application_number,\n sponsorName: drug.sponsor_name,\n products:\n drug.products?.slice(0, 3).map((p) => ({\n brandName: p.brand_name,\n dosageForm: p.dosage_form,\n route: p.route,\n marketingStatus: p.marketing_status,\n activeIngredients:\n p.active_ingredients?.slice(0, 3).map((ai) => ({\n name: ai.name,\n strength: ai.strength,\n })) ?? [],\n })) ?? [],\n latestSubmission: latestSubmission\n ? {\n type: latestSubmission.submission_type,\n status: latestSubmission.submission_status,\n statusDate: latestSubmission.submission_status_date,\n }\n : undefined,\n }\n}\n\nexport async function handleSearchDrugsFDA(params: DrugsFDAParams): Promise<FDAToolResponse<FormattedDrugsFDA[]>> {\n loggers.tools(\"searchDrugsFDA\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"sponsor_name\", value: params.sponsorName },\n { field: \"application_number\", value: params.applicationNumber },\n { field: \"products.brand_name\", value: params.brandName },\n { field: \"products.marketing_status\", value: params.marketingStatus },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n\n const searchParams: SearchParams = {\n search: searchQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDrugsFDA(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDrugsFDA),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Drug Shortages Handler\nexport type DrugShortagesParams = {\n genericName?: string\n status?: \"Current\" | \"Resolved\"\n limit?: number\n skip?: number\n}\n\ntype FormattedDrugShortage = {\n genericName: string | undefined\n proprietaryName: string | undefined\n status: string | undefined\n description: string | undefined\n initialPostingDate: string | undefined\n resolvedShortageDate: string | undefined\n}\n\nfunction formatDrugShortage(shortage: DrugShortage): FormattedDrugShortage {\n return {\n genericName: shortage.generic_name,\n proprietaryName: shortage.proprietary_name,\n status: shortage.status,\n description: truncateText(shortage.description),\n initialPostingDate: shortage.initial_posting_date,\n resolvedShortageDate: shortage.resolved_shortage_date,\n }\n}\n\nexport async function handleSearchDrugShortages(\n params: DrugShortagesParams,\n): Promise<FDAToolResponse<FormattedDrugShortage[]>> {\n loggers.tools(\"searchDrugShortages\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"generic_name\", value: params.genericName },\n { field: \"status\", value: params.status },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n\n const searchParams: SearchParams = {\n search: searchQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDrugShortages(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDrugShortage),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n"],"mappings":"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"}
@@ -50,6 +50,7 @@ type FormattedDeviceClassification = {
50
50
  };
51
51
  declare function handleSearchDeviceClassifications(params: DeviceClassificationParams): Promise<FDAToolResponse<FormattedDeviceClassification[]>>;
52
52
  type DeviceAdverseEventsParams = {
53
+ reportNumber?: string;
53
54
  deviceName?: string;
54
55
  brandName?: string;
55
56
  manufacturerName?: string;
@@ -1 +1 @@
1
- import"../utils/logger.js";import"../api-client-BGnUXMwX.js";import{i as e,n as t,r as n,t as r}from"../device-handlers-D01LfIJk.js";export{r as handleSearchDevice510K,t as handleSearchDeviceAdverseEvents,n as handleSearchDeviceClassifications,e as handleSearchDeviceEnforcement};
1
+ import"../utils/logger.js";import"../api-client-BGnUXMwX.js";import{i as e,n as t,r as n,t as r}from"../device-handlers-D8AD5oIk.js";export{r as handleSearchDevice510K,t as handleSearchDeviceAdverseEvents,n as handleSearchDeviceClassifications,e as handleSearchDeviceEnforcement};
@@ -3,6 +3,7 @@ import { FDAToolResponse } from "../types/fda.js";
3
3
  //#region src/handlers/drug-handlers.d.ts
4
4
 
5
5
  type DrugAdverseEventsParams = {
6
+ safetyReportId?: string;
6
7
  drugName?: string;
7
8
  reaction?: string;
8
9
  manufacturer?: string;
@@ -33,21 +34,36 @@ type FormattedDrugAdverseEvent = {
33
34
  };
34
35
  declare function handleSearchDrugAdverseEvents(params: DrugAdverseEventsParams): Promise<FDAToolResponse<FormattedDrugAdverseEvent[]>>;
35
36
  type DrugLabelsParams = {
37
+ setId?: string;
36
38
  drugName?: string;
37
39
  indication?: string;
38
40
  activeIngredient?: string;
39
41
  route?: string;
42
+ hasBoxedWarning?: boolean;
43
+ sections?: string[];
40
44
  limit?: number;
41
45
  skip?: number;
42
46
  };
43
47
  type FormattedDrugLabel = {
48
+ setId: string | undefined;
44
49
  brandName: string | undefined;
45
50
  genericName: string | undefined;
46
51
  manufacturer: string | undefined;
47
52
  activeIngredients: string[];
53
+ boxedWarning: string | undefined;
48
54
  indications: string | undefined;
49
55
  warnings: string | undefined;
56
+ contraindications: string | undefined;
57
+ adverseReactions: string | undefined;
58
+ drugInteractions: string | undefined;
50
59
  dosageAndAdministration: string | undefined;
60
+ clinicalPharmacology: string | undefined;
61
+ mechanismOfAction: string | undefined;
62
+ pharmacokinetics: string | undefined;
63
+ overdosage: string | undefined;
64
+ description: string | undefined;
65
+ howSupplied: string | undefined;
66
+ storageAndHandling: string | undefined;
51
67
  route: string[];
52
68
  };
53
69
  declare function handleSearchDrugLabels(params: DrugLabelsParams): Promise<FDAToolResponse<FormattedDrugLabel[]>>;
@@ -1 +1 @@
1
- import"../utils/logger.js";import"../api-client-BGnUXMwX.js";import{a as e,i as t,n,o as r,r as i,t as a}from"../drug-handlers-Fz_6NLl5.js";export{a as handleSearchDrugAdverseEvents,n as handleSearchDrugEnforcement,i as handleSearchDrugLabels,t as handleSearchDrugNDC,e as handleSearchDrugShortages,r as handleSearchDrugsFDA};
1
+ import"../utils/logger.js";import"../api-client-BGnUXMwX.js";import{a as e,i as t,n,o as r,r as i,t as a}from"../drug-handlers-D5VxbBCL.js";export{a as handleSearchDrugAdverseEvents,n as handleSearchDrugEnforcement,i as handleSearchDrugLabels,t as handleSearchDrugNDC,e as handleSearchDrugShortages,r as handleSearchDrugsFDA};
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import{loggers as e}from"./utils/logger.js";import"./api-client-BGnUXMwX.js";import"./device-handlers-D01LfIJk.js";import"./drug-handlers-Fz_6NLl5.js";import"./tools-Bh3wjIRH.js";import{createOpenFDAServer as t}from"./server.js";import{Command as n}from"commander";const r=new n;r.name(`openfda-mcp-server`).description(`MCP server for querying U.S. FDA public datasets`).version(`0.1.0`).option(`-t, --transport <type>`,`Transport type (stdio or http)`,`stdio`).option(`-p, --port <number>`,`Port for HTTP transport`,`3000`).option(`--host <host>`,`Host for HTTP transport`,`localhost`).action(async n=>{let{transport:r,port:i,host:a}=n;e.main(`Starting OpenFDA MCP server with transport: ${r}`);let o=t({name:`openfda-mcp-server`,version:`0.1.0`});try{if(r===`http`){let t=parseInt(i,10);e.main(`Starting HTTP server on ${a}:${t}`),await o.start({transportType:`httpStream`,httpStream:{endpoint:`/mcp`,port:t}}),console.error(`OpenFDA MCP server running at http://${a}:${t}/mcp`)}else e.main(`Starting stdio server`),await o.start({transportType:`stdio`})}catch(e){console.error(`Failed to start server:`,e),process.exit(1)}}),r.parse();export{};
2
+ import{loggers as e}from"./utils/logger.js";import"./api-client-BGnUXMwX.js";import"./device-handlers-D8AD5oIk.js";import"./drug-handlers-D5VxbBCL.js";import"./tools-3M3lSxQv.js";import{createOpenFDAServer as t}from"./server.js";import{Command as n}from"commander";const r=new n;r.name(`openfda-mcp-server`).description(`MCP server for querying U.S. FDA public datasets`).version(`0.1.0`).option(`-t, --transport <type>`,`Transport type (stdio or http)`,`stdio`).option(`-p, --port <number>`,`Port for HTTP transport`,`3000`).option(`--host <host>`,`Host for HTTP transport`,`localhost`).action(async n=>{let{transport:r,port:i,host:a}=n;e.main(`Starting OpenFDA MCP server with transport: ${r}`);let o=t({name:`openfda-mcp-server`,version:`0.1.0`});try{if(r===`http`){let t=parseInt(i,10);e.main(`Starting HTTP server on ${a}:${t}`),await o.start({transportType:`httpStream`,httpStream:{endpoint:`/mcp`,port:t}}),console.error(`OpenFDA MCP server running at http://${a}:${t}/mcp`)}else e.main(`Starting stdio server`),await o.start({transportType:`stdio`})}catch(e){console.error(`Failed to start server:`,e),process.exit(1)}}),r.parse();export{};
3
3
  //# sourceMappingURL=index.js.map
package/dist/lib.js CHANGED
@@ -1 +1 @@
1
- import{loggers as e}from"./utils/logger.js";import{n as t,t as n}from"./api-client-BGnUXMwX.js";import{i as r,n as i,r as a,t as o}from"./device-handlers-D01LfIJk.js";import{a as s,i as c,n as l,o as u,r as d,t as f}from"./drug-handlers-Fz_6NLl5.js";import{d as p}from"./tools-Bh3wjIRH.js";import{createOpenFDAServer as m}from"./server.js";export{n as FDAAPIClient,m as createOpenFDAServer,t as fdaAPIClient,o as handleSearchDevice510K,i as handleSearchDeviceAdverseEvents,a as handleSearchDeviceClassifications,r as handleSearchDeviceEnforcement,f as handleSearchDrugAdverseEvents,l as handleSearchDrugEnforcement,d as handleSearchDrugLabels,c as handleSearchDrugNDC,s as handleSearchDrugShortages,u as handleSearchDrugsFDA,e as loggers,p as toolSchemas};
1
+ import{loggers as e}from"./utils/logger.js";import{n as t,t as n}from"./api-client-BGnUXMwX.js";import{i as r,n as i,r as a,t as o}from"./device-handlers-D8AD5oIk.js";import{a as s,i as c,n as l,o as u,r as d,t as f}from"./drug-handlers-D5VxbBCL.js";import{f as p}from"./tools-3M3lSxQv.js";import{createOpenFDAServer as m}from"./server.js";export{n as FDAAPIClient,m as createOpenFDAServer,t as fdaAPIClient,o as handleSearchDevice510K,i as handleSearchDeviceAdverseEvents,a as handleSearchDeviceClassifications,r as handleSearchDeviceEnforcement,f as handleSearchDrugAdverseEvents,l as handleSearchDrugEnforcement,d as handleSearchDrugLabels,c as handleSearchDrugNDC,s as handleSearchDrugShortages,u as handleSearchDrugsFDA,e as loggers,p as toolSchemas};
package/dist/server.js CHANGED
@@ -1,2 +1,2 @@
1
- import{loggers as e}from"./utils/logger.js";import"./api-client-BGnUXMwX.js";import{i as t,n,r,t as i}from"./device-handlers-D01LfIJk.js";import{a,i as o,n as s,o as c,r as l,t as u}from"./drug-handlers-Fz_6NLl5.js";import{a as d,c as f,i as p,l as m,n as h,o as g,r as _,s as v,t as y,u as b}from"./tools-Bh3wjIRH.js";import{FastMCP as x}from"@jordanburke/fastmcp";function S(S={}){let{name:C=`openfda-mcp-server`,version:w=`0.1.0`}=S;e.core(`Creating OpenFDA MCP server: ${C} v${w}`);let T=new x({name:C,version:w});return T.addTool({name:`search_drug_adverse_events`,description:`Search FDA Adverse Event Reporting System (FAERS) for drug safety reports. Find adverse events by drug name, reaction type, manufacturer, date range, and seriousness. Returns patient demographics, drug details, and reported reactions.`,parameters:d,execute:async t=>{e.tools(`Executing search_drug_adverse_events`,t);let n=await u(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_drug_labels`,description:`Search FDA drug labeling (SPL) information including prescribing information, indications, warnings, dosage, and active ingredients. Find label information by drug name, indication, ingredient, or route.`,parameters:v,execute:async t=>{e.tools(`Executing search_drug_labels`,t);let n=await l(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_drug_ndc`,description:`Search the National Drug Code (NDC) Directory for drug product identification. Find drugs by NDC, brand name, generic name, labeler, dosage form, or route. Returns product details, active ingredients, and packaging information.`,parameters:f,execute:async t=>{e.tools(`Executing search_drug_ndc`,t);let n=await o(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_drug_recalls`,description:`Search FDA drug recall and enforcement reports. Find recalls by company, classification (I-III), status, state, and date range. Class I is most serious (may cause death), Class III is least serious.`,parameters:g,execute:async t=>{e.tools(`Executing search_drug_recalls`,t);let n=await s(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_drugs_at_fda`,description:`Search the Drugs@FDA database for approved drug applications. Find approved drugs by sponsor, application number, brand name, or marketing status. Returns application details, products, and submission history.`,parameters:b,execute:async t=>{e.tools(`Executing search_drugs_at_fda`,t);let n=await c(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_drug_shortages`,description:`Search the FDA Drug Shortage Database for current and resolved drug shortages. Find shortages by generic drug name or status (Current/Resolved). Returns shortage details, posting dates, and resolution information.`,parameters:m,execute:async t=>{e.tools(`Executing search_drug_shortages`,t);let n=await a(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_device_510k`,description:`Search FDA 510(k) premarket notification database for medical device clearances. Find device clearances by device name, applicant, product code, clearance type, or decision date. Returns clearance decisions and device classification details.`,parameters:y,execute:async t=>{e.tools(`Executing search_device_510k`,t);let n=await i(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_device_classifications`,description:`Search FDA medical device classification database. Find devices by name, class (1-3), medical specialty, product code, or regulation number. Class 1 is lowest risk, Class 3 is highest risk (implants, life-sustaining).`,parameters:_,execute:async t=>{e.tools(`Executing search_device_classifications`,t);let n=await r(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_device_adverse_events`,description:`Search FDA Medical Device Report (MDR) database for device adverse events. Find adverse events by device name, brand, manufacturer, event type (Injury/Death/Malfunction), and date. Returns device details, event descriptions, and patient outcomes.`,parameters:h,execute:async t=>{e.tools(`Executing search_device_adverse_events`,t);let r=await n(t);return JSON.stringify(r,null,2)}}),T.addTool({name:`search_device_recalls`,description:`Search FDA medical device recall and enforcement reports. Find recalls by company, product description, classification (I-III), status, and date. Class I is most serious (may cause death), Class III is least serious.`,parameters:p,execute:async n=>{e.tools(`Executing search_device_recalls`,n);let r=await t(n);return JSON.stringify(r,null,2)}}),e.core(`OpenFDA MCP server configured with 10 tools`),T}export{S as createOpenFDAServer};
1
+ import{loggers as e}from"./utils/logger.js";import"./api-client-BGnUXMwX.js";import{i as t,n,r,t as i}from"./device-handlers-D8AD5oIk.js";import{a,i as o,n as s,o as c,r as l,t as u}from"./drug-handlers-D5VxbBCL.js";import{a as d,c as f,d as p,i as m,l as h,n as g,o as _,r as v,s as y,u as b}from"./tools-3M3lSxQv.js";import{FastMCP as x}from"@jordanburke/fastmcp";function S(S={}){let{name:C=`openfda-mcp-server`,version:w=`0.1.0`}=S;e.core(`Creating OpenFDA MCP server: ${C} v${w}`);let T=new x({name:C,version:w});return T.addTool({name:`search_drug_adverse_events`,description:`Search FDA Adverse Event Reporting System (FAERS) for drug safety reports. Find adverse events by drug name, reaction type, manufacturer, date range, and seriousness. Retrieve a specific report by safetyReportId. Returns patient demographics, drug details, and reported reactions.`,parameters:_,execute:async t=>{e.tools(`Executing search_drug_adverse_events`,t);let n=await u(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_drug_labels`,description:`Search FDA drug labeling (SPL) information including prescribing information, indications, warnings, boxed warnings, dosage, and active ingredients. Retrieve a specific label by setId. Filter for drugs with boxed warnings using hasBoxedWarning. Request specific sections (e.g., indications_and_usage, adverse_reactions, boxed_warning) to limit response.`,parameters:f,execute:async t=>{e.tools(`Executing search_drug_labels`,t);let n=await l(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_drug_ndc`,description:`Search the National Drug Code (NDC) Directory for drug product identification. Find drugs by NDC, brand name, generic name, labeler, dosage form, or route. Returns product details, active ingredients, and packaging information.`,parameters:h,execute:async t=>{e.tools(`Executing search_drug_ndc`,t);let n=await o(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_drug_recalls`,description:`Search FDA drug recall and enforcement reports. Find recalls by company, classification (I-III), status, state, and date range. Class I is most serious (may cause death), Class III is least serious.`,parameters:y,execute:async t=>{e.tools(`Executing search_drug_recalls`,t);let n=await s(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_drugs_at_fda`,description:`Search the Drugs@FDA database for approved drug applications. Find approved drugs by sponsor, application number, brand name, or marketing status. Returns application details, products, and submission history.`,parameters:p,execute:async t=>{e.tools(`Executing search_drugs_at_fda`,t);let n=await c(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_drug_shortages`,description:`Search the FDA Drug Shortage Database for current and resolved drug shortages. Find shortages by generic drug name or status (Current/Resolved). Returns shortage details, posting dates, and resolution information.`,parameters:b,execute:async t=>{e.tools(`Executing search_drug_shortages`,t);let n=await a(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_device_510k`,description:`Search FDA 510(k) premarket notification database for medical device clearances. Find device clearances by device name, applicant, product code, clearance type, or decision date. Returns clearance decisions and device classification details.`,parameters:g,execute:async t=>{e.tools(`Executing search_device_510k`,t);let n=await i(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_device_classifications`,description:`Search FDA medical device classification database. Find devices by name, class (1-3), medical specialty, product code, or regulation number. Class 1 is lowest risk, Class 3 is highest risk (implants, life-sustaining).`,parameters:m,execute:async t=>{e.tools(`Executing search_device_classifications`,t);let n=await r(t);return JSON.stringify(n,null,2)}}),T.addTool({name:`search_device_adverse_events`,description:`Search FDA Medical Device Report (MDR) database for device adverse events. Find adverse events by device name, brand, manufacturer, event type (Injury/Death/Malfunction), and date. Retrieve a specific MDR report by reportNumber. Returns device details, event descriptions, and patient outcomes.`,parameters:v,execute:async t=>{e.tools(`Executing search_device_adverse_events`,t);let r=await n(t);return JSON.stringify(r,null,2)}}),T.addTool({name:`search_device_recalls`,description:`Search FDA medical device recall and enforcement reports. Find recalls by company, product description, classification (I-III), status, and date. Class I is most serious (may cause death), Class III is least serious.`,parameters:d,execute:async n=>{e.tools(`Executing search_device_recalls`,n);let r=await t(n);return JSON.stringify(r,null,2)}}),e.core(`OpenFDA MCP server configured with 10 tools`),T}export{S as createOpenFDAServer};
2
2
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","names":[],"sources":["../src/server.ts"],"sourcesContent":["/**\n * OpenFDA MCP Server\n * FastMCP server implementation with FDA tools\n */\n\nimport { FastMCP } from \"@jordanburke/fastmcp\"\n\nimport {\n handleSearchDevice510K,\n handleSearchDeviceAdverseEvents,\n handleSearchDeviceClassifications,\n handleSearchDeviceEnforcement,\n} from \"./handlers/device-handlers.js\"\nimport {\n handleSearchDrugAdverseEvents,\n handleSearchDrugEnforcement,\n handleSearchDrugLabels,\n handleSearchDrugNDC,\n handleSearchDrugsFDA,\n handleSearchDrugShortages,\n} from \"./handlers/drug-handlers.js\"\nimport {\n searchDevice510KSchema,\n searchDeviceAdverseEventsSchema,\n searchDeviceClassificationsSchema,\n searchDeviceEnforcementSchema,\n searchDrugAdverseEventsSchema,\n searchDrugEnforcementSchema,\n searchDrugLabelsSchema,\n searchDrugNDCSchema,\n searchDrugsFDASchema,\n searchDrugShortagesSchema,\n} from \"./tools/index.js\"\nimport { loggers } from \"./utils/logger.js\"\n\nexport type ServerOptions = {\n name?: string\n version?: `${number}.${number}.${number}`\n}\n\n/**\n * Create and configure the OpenFDA MCP server\n */\nexport function createOpenFDAServer(options: ServerOptions = {}): FastMCP {\n const { name = \"openfda-mcp-server\", version = \"0.1.0\" as `${number}.${number}.${number}` } = options\n\n loggers.core(`Creating OpenFDA MCP server: ${name} v${version}`)\n\n const server = new FastMCP({\n name,\n version,\n })\n\n // Register Drug Tools\n\n server.addTool({\n name: \"search_drug_adverse_events\",\n description:\n \"Search FDA Adverse Event Reporting System (FAERS) for drug safety reports. \" +\n \"Find adverse events by drug name, reaction type, manufacturer, date range, and seriousness. \" +\n \"Returns patient demographics, drug details, and reported reactions.\",\n parameters: searchDrugAdverseEventsSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_drug_adverse_events\", args)\n const result = await handleSearchDrugAdverseEvents(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_drug_labels\",\n description:\n \"Search FDA drug labeling (SPL) information including prescribing information, \" +\n \"indications, warnings, dosage, and active ingredients. \" +\n \"Find label information by drug name, indication, ingredient, or route.\",\n parameters: searchDrugLabelsSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_drug_labels\", args)\n const result = await handleSearchDrugLabels(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_drug_ndc\",\n description:\n \"Search the National Drug Code (NDC) Directory for drug product identification. \" +\n \"Find drugs by NDC, brand name, generic name, labeler, dosage form, or route. \" +\n \"Returns product details, active ingredients, and packaging information.\",\n parameters: searchDrugNDCSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_drug_ndc\", args)\n const result = await handleSearchDrugNDC(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_drug_recalls\",\n description:\n \"Search FDA drug recall and enforcement reports. \" +\n \"Find recalls by company, classification (I-III), status, state, and date range. \" +\n \"Class I is most serious (may cause death), Class III is least serious.\",\n parameters: searchDrugEnforcementSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_drug_recalls\", args)\n const result = await handleSearchDrugEnforcement(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_drugs_at_fda\",\n description:\n \"Search the Drugs@FDA database for approved drug applications. \" +\n \"Find approved drugs by sponsor, application number, brand name, or marketing status. \" +\n \"Returns application details, products, and submission history.\",\n parameters: searchDrugsFDASchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_drugs_at_fda\", args)\n const result = await handleSearchDrugsFDA(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_drug_shortages\",\n description:\n \"Search the FDA Drug Shortage Database for current and resolved drug shortages. \" +\n \"Find shortages by generic drug name or status (Current/Resolved). \" +\n \"Returns shortage details, posting dates, and resolution information.\",\n parameters: searchDrugShortagesSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_drug_shortages\", args)\n const result = await handleSearchDrugShortages(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n // Register Device Tools\n\n server.addTool({\n name: \"search_device_510k\",\n description:\n \"Search FDA 510(k) premarket notification database for medical device clearances. \" +\n \"Find device clearances by device name, applicant, product code, clearance type, or decision date. \" +\n \"Returns clearance decisions and device classification details.\",\n parameters: searchDevice510KSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_device_510k\", args)\n const result = await handleSearchDevice510K(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_device_classifications\",\n description:\n \"Search FDA medical device classification database. \" +\n \"Find devices by name, class (1-3), medical specialty, product code, or regulation number. \" +\n \"Class 1 is lowest risk, Class 3 is highest risk (implants, life-sustaining).\",\n parameters: searchDeviceClassificationsSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_device_classifications\", args)\n const result = await handleSearchDeviceClassifications(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_device_adverse_events\",\n description:\n \"Search FDA Medical Device Report (MDR) database for device adverse events. \" +\n \"Find adverse events by device name, brand, manufacturer, event type (Injury/Death/Malfunction), and date. \" +\n \"Returns device details, event descriptions, and patient outcomes.\",\n parameters: searchDeviceAdverseEventsSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_device_adverse_events\", args)\n const result = await handleSearchDeviceAdverseEvents(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_device_recalls\",\n description:\n \"Search FDA medical device recall and enforcement reports. \" +\n \"Find recalls by company, product description, classification (I-III), status, and date. \" +\n \"Class I is most serious (may cause death), Class III is least serious.\",\n parameters: searchDeviceEnforcementSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_device_recalls\", args)\n const result = await handleSearchDeviceEnforcement(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n loggers.core(\"OpenFDA MCP server configured with 10 tools\")\n\n return server\n}\n"],"mappings":"8WA2CA,SAAgB,EAAoB,EAAyB,EAAE,CAAW,CACxE,GAAM,CAAE,OAAO,qBAAsB,UAAU,SAA+C,EAE9F,EAAQ,KAAK,gCAAgC,EAAK,IAAI,IAAU,CAEhE,IAAM,EAAS,IAAI,EAAQ,CACzB,OACA,UACD,CAAC,CAoJF,OAhJA,EAAO,QAAQ,CACb,KAAM,6BACN,YACE,6OAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,uCAAwC,EAAK,CAC3D,IAAM,EAAS,MAAM,EAA8B,EAAK,CACxD,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,qBACN,YACE,8MAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,+BAAgC,EAAK,CACnD,IAAM,EAAS,MAAM,EAAuB,EAAK,CACjD,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,kBACN,YACE,sOAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,4BAA6B,EAAK,CAChD,IAAM,EAAS,MAAM,EAAoB,EAAK,CAC9C,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,sBACN,YACE,yMAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,gCAAiC,EAAK,CACpD,IAAM,EAAS,MAAM,EAA4B,EAAK,CACtD,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,sBACN,YACE,oNAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,gCAAiC,EAAK,CACpD,IAAM,EAAS,MAAM,EAAqB,EAAK,CAC/C,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,wBACN,YACE,wNAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,kCAAmC,EAAK,CACtD,IAAM,EAAS,MAAM,EAA0B,EAAK,CACpD,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAIF,EAAO,QAAQ,CACb,KAAM,qBACN,YACE,oPAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,+BAAgC,EAAK,CACnD,IAAM,EAAS,MAAM,EAAuB,EAAK,CACjD,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,gCACN,YACE,4NAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,0CAA2C,EAAK,CAC9D,IAAM,EAAS,MAAM,EAAkC,EAAK,CAC5D,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,+BACN,YACE,yPAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,yCAA0C,EAAK,CAC7D,IAAM,EAAS,MAAM,EAAgC,EAAK,CAC1D,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,wBACN,YACE,2NAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,kCAAmC,EAAK,CACtD,IAAM,EAAS,MAAM,EAA8B,EAAK,CACxD,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAQ,KAAK,8CAA8C,CAEpD"}
1
+ {"version":3,"file":"server.js","names":[],"sources":["../src/server.ts"],"sourcesContent":["/**\n * OpenFDA MCP Server\n * FastMCP server implementation with FDA tools\n */\n\nimport { FastMCP } from \"@jordanburke/fastmcp\"\n\nimport {\n handleSearchDevice510K,\n handleSearchDeviceAdverseEvents,\n handleSearchDeviceClassifications,\n handleSearchDeviceEnforcement,\n} from \"./handlers/device-handlers.js\"\nimport {\n handleSearchDrugAdverseEvents,\n handleSearchDrugEnforcement,\n handleSearchDrugLabels,\n handleSearchDrugNDC,\n handleSearchDrugsFDA,\n handleSearchDrugShortages,\n} from \"./handlers/drug-handlers.js\"\nimport {\n searchDevice510KSchema,\n searchDeviceAdverseEventsSchema,\n searchDeviceClassificationsSchema,\n searchDeviceEnforcementSchema,\n searchDrugAdverseEventsSchema,\n searchDrugEnforcementSchema,\n searchDrugLabelsSchema,\n searchDrugNDCSchema,\n searchDrugsFDASchema,\n searchDrugShortagesSchema,\n} from \"./tools/index.js\"\nimport { loggers } from \"./utils/logger.js\"\n\nexport type ServerOptions = {\n name?: string\n version?: `${number}.${number}.${number}`\n}\n\n/**\n * Create and configure the OpenFDA MCP server\n */\nexport function createOpenFDAServer(options: ServerOptions = {}): FastMCP {\n const { name = \"openfda-mcp-server\", version = \"0.1.0\" as `${number}.${number}.${number}` } = options\n\n loggers.core(`Creating OpenFDA MCP server: ${name} v${version}`)\n\n const server = new FastMCP({\n name,\n version,\n })\n\n // Register Drug Tools\n\n server.addTool({\n name: \"search_drug_adverse_events\",\n description:\n \"Search FDA Adverse Event Reporting System (FAERS) for drug safety reports. \" +\n \"Find adverse events by drug name, reaction type, manufacturer, date range, and seriousness. \" +\n \"Retrieve a specific report by safetyReportId. \" +\n \"Returns patient demographics, drug details, and reported reactions.\",\n parameters: searchDrugAdverseEventsSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_drug_adverse_events\", args)\n const result = await handleSearchDrugAdverseEvents(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_drug_labels\",\n description:\n \"Search FDA drug labeling (SPL) information including prescribing information, \" +\n \"indications, warnings, boxed warnings, dosage, and active ingredients. \" +\n \"Retrieve a specific label by setId. Filter for drugs with boxed warnings using hasBoxedWarning. \" +\n \"Request specific sections (e.g., indications_and_usage, adverse_reactions, boxed_warning) to limit response.\",\n parameters: searchDrugLabelsSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_drug_labels\", args)\n const result = await handleSearchDrugLabels(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_drug_ndc\",\n description:\n \"Search the National Drug Code (NDC) Directory for drug product identification. \" +\n \"Find drugs by NDC, brand name, generic name, labeler, dosage form, or route. \" +\n \"Returns product details, active ingredients, and packaging information.\",\n parameters: searchDrugNDCSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_drug_ndc\", args)\n const result = await handleSearchDrugNDC(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_drug_recalls\",\n description:\n \"Search FDA drug recall and enforcement reports. \" +\n \"Find recalls by company, classification (I-III), status, state, and date range. \" +\n \"Class I is most serious (may cause death), Class III is least serious.\",\n parameters: searchDrugEnforcementSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_drug_recalls\", args)\n const result = await handleSearchDrugEnforcement(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_drugs_at_fda\",\n description:\n \"Search the Drugs@FDA database for approved drug applications. \" +\n \"Find approved drugs by sponsor, application number, brand name, or marketing status. \" +\n \"Returns application details, products, and submission history.\",\n parameters: searchDrugsFDASchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_drugs_at_fda\", args)\n const result = await handleSearchDrugsFDA(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_drug_shortages\",\n description:\n \"Search the FDA Drug Shortage Database for current and resolved drug shortages. \" +\n \"Find shortages by generic drug name or status (Current/Resolved). \" +\n \"Returns shortage details, posting dates, and resolution information.\",\n parameters: searchDrugShortagesSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_drug_shortages\", args)\n const result = await handleSearchDrugShortages(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n // Register Device Tools\n\n server.addTool({\n name: \"search_device_510k\",\n description:\n \"Search FDA 510(k) premarket notification database for medical device clearances. \" +\n \"Find device clearances by device name, applicant, product code, clearance type, or decision date. \" +\n \"Returns clearance decisions and device classification details.\",\n parameters: searchDevice510KSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_device_510k\", args)\n const result = await handleSearchDevice510K(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_device_classifications\",\n description:\n \"Search FDA medical device classification database. \" +\n \"Find devices by name, class (1-3), medical specialty, product code, or regulation number. \" +\n \"Class 1 is lowest risk, Class 3 is highest risk (implants, life-sustaining).\",\n parameters: searchDeviceClassificationsSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_device_classifications\", args)\n const result = await handleSearchDeviceClassifications(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_device_adverse_events\",\n description:\n \"Search FDA Medical Device Report (MDR) database for device adverse events. \" +\n \"Find adverse events by device name, brand, manufacturer, event type (Injury/Death/Malfunction), and date. \" +\n \"Retrieve a specific MDR report by reportNumber. \" +\n \"Returns device details, event descriptions, and patient outcomes.\",\n parameters: searchDeviceAdverseEventsSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_device_adverse_events\", args)\n const result = await handleSearchDeviceAdverseEvents(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n server.addTool({\n name: \"search_device_recalls\",\n description:\n \"Search FDA medical device recall and enforcement reports. \" +\n \"Find recalls by company, product description, classification (I-III), status, and date. \" +\n \"Class I is most serious (may cause death), Class III is least serious.\",\n parameters: searchDeviceEnforcementSchema,\n execute: async (args) => {\n loggers.tools(\"Executing search_device_recalls\", args)\n const result = await handleSearchDeviceEnforcement(args)\n return JSON.stringify(result, null, 2)\n },\n })\n\n loggers.core(\"OpenFDA MCP server configured with 10 tools\")\n\n return server\n}\n"],"mappings":"8WA2CA,SAAgB,EAAoB,EAAyB,EAAE,CAAW,CACxE,GAAM,CAAE,OAAO,qBAAsB,UAAU,SAA+C,EAE9F,EAAQ,KAAK,gCAAgC,EAAK,IAAI,IAAU,CAEhE,IAAM,EAAS,IAAI,EAAQ,CACzB,OACA,UACD,CAAC,CAuJF,OAnJA,EAAO,QAAQ,CACb,KAAM,6BACN,YACE,2RAIF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,uCAAwC,EAAK,CAC3D,IAAM,EAAS,MAAM,EAA8B,EAAK,CACxD,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,qBACN,YACE,oWAIF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,+BAAgC,EAAK,CACnD,IAAM,EAAS,MAAM,EAAuB,EAAK,CACjD,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,kBACN,YACE,sOAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,4BAA6B,EAAK,CAChD,IAAM,EAAS,MAAM,EAAoB,EAAK,CAC9C,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,sBACN,YACE,yMAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,gCAAiC,EAAK,CACpD,IAAM,EAAS,MAAM,EAA4B,EAAK,CACtD,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,sBACN,YACE,oNAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,gCAAiC,EAAK,CACpD,IAAM,EAAS,MAAM,EAAqB,EAAK,CAC/C,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,wBACN,YACE,wNAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,kCAAmC,EAAK,CACtD,IAAM,EAAS,MAAM,EAA0B,EAAK,CACpD,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAIF,EAAO,QAAQ,CACb,KAAM,qBACN,YACE,oPAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,+BAAgC,EAAK,CACnD,IAAM,EAAS,MAAM,EAAuB,EAAK,CACjD,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,gCACN,YACE,4NAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,0CAA2C,EAAK,CAC9D,IAAM,EAAS,MAAM,EAAkC,EAAK,CAC5D,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,+BACN,YACE,ySAIF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,yCAA0C,EAAK,CAC7D,IAAM,EAAS,MAAM,EAAgC,EAAK,CAC1D,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAO,QAAQ,CACb,KAAM,wBACN,YACE,2NAGF,WAAY,EACZ,QAAS,KAAO,IAAS,CACvB,EAAQ,MAAM,kCAAmC,EAAK,CACtD,IAAM,EAAS,MAAM,EAA8B,EAAK,CACxD,OAAO,KAAK,UAAU,EAAQ,KAAM,EAAE,EAEzC,CAAC,CAEF,EAAQ,KAAK,8CAA8C,CAEpD"}
@@ -7,11 +7,13 @@ declare const searchDrugAdverseEventsSchema: z.ZodObject<{
7
7
  skip: z.ZodOptional<z.ZodNumber>;
8
8
  dateFrom: z.ZodOptional<z.ZodString>;
9
9
  dateTo: z.ZodOptional<z.ZodString>;
10
+ safetyReportId: z.ZodOptional<z.ZodString>;
10
11
  drugName: z.ZodOptional<z.ZodString>;
11
12
  reaction: z.ZodOptional<z.ZodString>;
12
13
  manufacturer: z.ZodOptional<z.ZodString>;
13
14
  serious: z.ZodOptional<z.ZodBoolean>;
14
15
  }, "strip", z.ZodTypeAny, {
16
+ safetyReportId?: string | undefined;
15
17
  drugName?: string | undefined;
16
18
  reaction?: string | undefined;
17
19
  manufacturer?: string | undefined;
@@ -21,6 +23,7 @@ declare const searchDrugAdverseEventsSchema: z.ZodObject<{
21
23
  dateFrom?: string | undefined;
22
24
  dateTo?: string | undefined;
23
25
  }, {
26
+ safetyReportId?: string | undefined;
24
27
  drugName?: string | undefined;
25
28
  reaction?: string | undefined;
26
29
  manufacturer?: string | undefined;
@@ -30,27 +33,37 @@ declare const searchDrugAdverseEventsSchema: z.ZodObject<{
30
33
  dateFrom?: string | undefined;
31
34
  dateTo?: string | undefined;
32
35
  }>;
36
+ declare const labelSections: readonly ["indications_and_usage", "dosage_and_administration", "contraindications", "warnings", "warnings_and_cautions", "adverse_reactions", "drug_interactions", "clinical_pharmacology", "mechanism_of_action", "pharmacokinetics", "overdosage", "description", "how_supplied", "storage_and_handling", "boxed_warning"];
33
37
  declare const searchDrugLabelsSchema: z.ZodObject<{
34
38
  limit: z.ZodOptional<z.ZodNumber>;
35
39
  skip: z.ZodOptional<z.ZodNumber>;
40
+ setId: z.ZodOptional<z.ZodString>;
36
41
  drugName: z.ZodOptional<z.ZodString>;
37
42
  indication: z.ZodOptional<z.ZodString>;
38
43
  activeIngredient: z.ZodOptional<z.ZodString>;
39
44
  route: z.ZodOptional<z.ZodString>;
45
+ hasBoxedWarning: z.ZodOptional<z.ZodBoolean>;
46
+ sections: z.ZodOptional<z.ZodArray<z.ZodEnum<["indications_and_usage", "dosage_and_administration", "contraindications", "warnings", "warnings_and_cautions", "adverse_reactions", "drug_interactions", "clinical_pharmacology", "mechanism_of_action", "pharmacokinetics", "overdosage", "description", "how_supplied", "storage_and_handling", "boxed_warning"]>, "many">>;
40
47
  }, "strip", z.ZodTypeAny, {
41
48
  drugName?: string | undefined;
42
49
  limit?: number | undefined;
43
50
  skip?: number | undefined;
51
+ setId?: string | undefined;
44
52
  indication?: string | undefined;
45
53
  activeIngredient?: string | undefined;
46
54
  route?: string | undefined;
55
+ hasBoxedWarning?: boolean | undefined;
56
+ sections?: ("indications_and_usage" | "dosage_and_administration" | "contraindications" | "warnings" | "warnings_and_cautions" | "adverse_reactions" | "drug_interactions" | "clinical_pharmacology" | "mechanism_of_action" | "pharmacokinetics" | "overdosage" | "description" | "how_supplied" | "storage_and_handling" | "boxed_warning")[] | undefined;
47
57
  }, {
48
58
  drugName?: string | undefined;
49
59
  limit?: number | undefined;
50
60
  skip?: number | undefined;
61
+ setId?: string | undefined;
51
62
  indication?: string | undefined;
52
63
  activeIngredient?: string | undefined;
53
64
  route?: string | undefined;
65
+ hasBoxedWarning?: boolean | undefined;
66
+ sections?: ("indications_and_usage" | "dosage_and_administration" | "contraindications" | "warnings" | "warnings_and_cautions" | "adverse_reactions" | "drug_interactions" | "clinical_pharmacology" | "mechanism_of_action" | "pharmacokinetics" | "overdosage" | "description" | "how_supplied" | "storage_and_handling" | "boxed_warning")[] | undefined;
54
67
  }>;
55
68
  declare const searchDrugNDCSchema: z.ZodObject<{
56
69
  limit: z.ZodOptional<z.ZodNumber>;
@@ -204,6 +217,7 @@ declare const searchDeviceAdverseEventsSchema: z.ZodObject<{
204
217
  skip: z.ZodOptional<z.ZodNumber>;
205
218
  dateFrom: z.ZodOptional<z.ZodString>;
206
219
  dateTo: z.ZodOptional<z.ZodString>;
220
+ reportNumber: z.ZodOptional<z.ZodString>;
207
221
  deviceName: z.ZodOptional<z.ZodString>;
208
222
  brandName: z.ZodOptional<z.ZodString>;
209
223
  manufacturerName: z.ZodOptional<z.ZodString>;
@@ -215,6 +229,7 @@ declare const searchDeviceAdverseEventsSchema: z.ZodObject<{
215
229
  dateTo?: string | undefined;
216
230
  brandName?: string | undefined;
217
231
  deviceName?: string | undefined;
232
+ reportNumber?: string | undefined;
218
233
  manufacturerName?: string | undefined;
219
234
  eventType?: "Injury" | "Malfunction" | "Death" | "Other" | undefined;
220
235
  }, {
@@ -224,6 +239,7 @@ declare const searchDeviceAdverseEventsSchema: z.ZodObject<{
224
239
  dateTo?: string | undefined;
225
240
  brandName?: string | undefined;
226
241
  deviceName?: string | undefined;
242
+ reportNumber?: string | undefined;
227
243
  manufacturerName?: string | undefined;
228
244
  eventType?: "Injury" | "Malfunction" | "Death" | "Other" | undefined;
229
245
  }>;
@@ -261,11 +277,13 @@ declare const toolSchemas: {
261
277
  skip: z.ZodOptional<z.ZodNumber>;
262
278
  dateFrom: z.ZodOptional<z.ZodString>;
263
279
  dateTo: z.ZodOptional<z.ZodString>;
280
+ safetyReportId: z.ZodOptional<z.ZodString>;
264
281
  drugName: z.ZodOptional<z.ZodString>;
265
282
  reaction: z.ZodOptional<z.ZodString>;
266
283
  manufacturer: z.ZodOptional<z.ZodString>;
267
284
  serious: z.ZodOptional<z.ZodBoolean>;
268
285
  }, "strip", z.ZodTypeAny, {
286
+ safetyReportId?: string | undefined;
269
287
  drugName?: string | undefined;
270
288
  reaction?: string | undefined;
271
289
  manufacturer?: string | undefined;
@@ -275,6 +293,7 @@ declare const toolSchemas: {
275
293
  dateFrom?: string | undefined;
276
294
  dateTo?: string | undefined;
277
295
  }, {
296
+ safetyReportId?: string | undefined;
278
297
  drugName?: string | undefined;
279
298
  reaction?: string | undefined;
280
299
  manufacturer?: string | undefined;
@@ -287,24 +306,33 @@ declare const toolSchemas: {
287
306
  searchDrugLabels: z.ZodObject<{
288
307
  limit: z.ZodOptional<z.ZodNumber>;
289
308
  skip: z.ZodOptional<z.ZodNumber>;
309
+ setId: z.ZodOptional<z.ZodString>;
290
310
  drugName: z.ZodOptional<z.ZodString>;
291
311
  indication: z.ZodOptional<z.ZodString>;
292
312
  activeIngredient: z.ZodOptional<z.ZodString>;
293
313
  route: z.ZodOptional<z.ZodString>;
314
+ hasBoxedWarning: z.ZodOptional<z.ZodBoolean>;
315
+ sections: z.ZodOptional<z.ZodArray<z.ZodEnum<["indications_and_usage", "dosage_and_administration", "contraindications", "warnings", "warnings_and_cautions", "adverse_reactions", "drug_interactions", "clinical_pharmacology", "mechanism_of_action", "pharmacokinetics", "overdosage", "description", "how_supplied", "storage_and_handling", "boxed_warning"]>, "many">>;
294
316
  }, "strip", z.ZodTypeAny, {
295
317
  drugName?: string | undefined;
296
318
  limit?: number | undefined;
297
319
  skip?: number | undefined;
320
+ setId?: string | undefined;
298
321
  indication?: string | undefined;
299
322
  activeIngredient?: string | undefined;
300
323
  route?: string | undefined;
324
+ hasBoxedWarning?: boolean | undefined;
325
+ sections?: ("indications_and_usage" | "dosage_and_administration" | "contraindications" | "warnings" | "warnings_and_cautions" | "adverse_reactions" | "drug_interactions" | "clinical_pharmacology" | "mechanism_of_action" | "pharmacokinetics" | "overdosage" | "description" | "how_supplied" | "storage_and_handling" | "boxed_warning")[] | undefined;
301
326
  }, {
302
327
  drugName?: string | undefined;
303
328
  limit?: number | undefined;
304
329
  skip?: number | undefined;
330
+ setId?: string | undefined;
305
331
  indication?: string | undefined;
306
332
  activeIngredient?: string | undefined;
307
333
  route?: string | undefined;
334
+ hasBoxedWarning?: boolean | undefined;
335
+ sections?: ("indications_and_usage" | "dosage_and_administration" | "contraindications" | "warnings" | "warnings_and_cautions" | "adverse_reactions" | "drug_interactions" | "clinical_pharmacology" | "mechanism_of_action" | "pharmacokinetics" | "overdosage" | "description" | "how_supplied" | "storage_and_handling" | "boxed_warning")[] | undefined;
308
336
  }>;
309
337
  searchDrugNDC: z.ZodObject<{
310
338
  limit: z.ZodOptional<z.ZodNumber>;
@@ -458,6 +486,7 @@ declare const toolSchemas: {
458
486
  skip: z.ZodOptional<z.ZodNumber>;
459
487
  dateFrom: z.ZodOptional<z.ZodString>;
460
488
  dateTo: z.ZodOptional<z.ZodString>;
489
+ reportNumber: z.ZodOptional<z.ZodString>;
461
490
  deviceName: z.ZodOptional<z.ZodString>;
462
491
  brandName: z.ZodOptional<z.ZodString>;
463
492
  manufacturerName: z.ZodOptional<z.ZodString>;
@@ -469,6 +498,7 @@ declare const toolSchemas: {
469
498
  dateTo?: string | undefined;
470
499
  brandName?: string | undefined;
471
500
  deviceName?: string | undefined;
501
+ reportNumber?: string | undefined;
472
502
  manufacturerName?: string | undefined;
473
503
  eventType?: "Injury" | "Malfunction" | "Death" | "Other" | undefined;
474
504
  }, {
@@ -478,6 +508,7 @@ declare const toolSchemas: {
478
508
  dateTo?: string | undefined;
479
509
  brandName?: string | undefined;
480
510
  deviceName?: string | undefined;
511
+ reportNumber?: string | undefined;
481
512
  manufacturerName?: string | undefined;
482
513
  eventType?: "Injury" | "Malfunction" | "Death" | "Other" | undefined;
483
514
  }>;
@@ -520,6 +551,7 @@ type SearchDevice510KParams = z.infer<typeof searchDevice510KSchema>;
520
551
  type SearchDeviceClassificationsParams = z.infer<typeof searchDeviceClassificationsSchema>;
521
552
  type SearchDeviceAdverseEventsParams = z.infer<typeof searchDeviceAdverseEventsSchema>;
522
553
  type SearchDeviceEnforcementParams = z.infer<typeof searchDeviceEnforcementSchema>;
554
+ type LabelSection = (typeof labelSections)[number];
523
555
  //#endregion
524
- export { SearchDevice510KParams, SearchDeviceAdverseEventsParams, SearchDeviceClassificationsParams, SearchDeviceEnforcementParams, SearchDrugAdverseEventsParams, SearchDrugEnforcementParams, SearchDrugLabelsParams, SearchDrugNDCParams, SearchDrugShortagesParams, SearchDrugsFDAParams, searchDevice510KSchema, searchDeviceAdverseEventsSchema, searchDeviceClassificationsSchema, searchDeviceEnforcementSchema, searchDrugAdverseEventsSchema, searchDrugEnforcementSchema, searchDrugLabelsSchema, searchDrugNDCSchema, searchDrugShortagesSchema, searchDrugsFDASchema, toolSchemas };
556
+ export { LabelSection, SearchDevice510KParams, SearchDeviceAdverseEventsParams, SearchDeviceClassificationsParams, SearchDeviceEnforcementParams, SearchDrugAdverseEventsParams, SearchDrugEnforcementParams, SearchDrugLabelsParams, SearchDrugNDCParams, SearchDrugShortagesParams, SearchDrugsFDAParams, labelSections, searchDevice510KSchema, searchDeviceAdverseEventsSchema, searchDeviceClassificationsSchema, searchDeviceEnforcementSchema, searchDrugAdverseEventsSchema, searchDrugEnforcementSchema, searchDrugLabelsSchema, searchDrugNDCSchema, searchDrugShortagesSchema, searchDrugsFDASchema, toolSchemas };
525
557
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- import{a as e,c as t,d as n,i as r,l as i,n as a,o,r as s,s as c,t as l,u}from"../tools-Bh3wjIRH.js";export{l as searchDevice510KSchema,a as searchDeviceAdverseEventsSchema,s as searchDeviceClassificationsSchema,r as searchDeviceEnforcementSchema,e as searchDrugAdverseEventsSchema,o as searchDrugEnforcementSchema,c as searchDrugLabelsSchema,t as searchDrugNDCSchema,i as searchDrugShortagesSchema,u as searchDrugsFDASchema,n as toolSchemas};
1
+ import{a as e,c as t,d as n,f as r,i,l as a,n as o,o as s,r as c,s as l,t as u,u as d}from"../tools-3M3lSxQv.js";export{u as labelSections,o as searchDevice510KSchema,c as searchDeviceAdverseEventsSchema,i as searchDeviceClassificationsSchema,e as searchDeviceEnforcementSchema,s as searchDrugAdverseEventsSchema,l as searchDrugEnforcementSchema,t as searchDrugLabelsSchema,a as searchDrugNDCSchema,d as searchDrugShortagesSchema,n as searchDrugsFDASchema,r as toolSchemas};
@@ -0,0 +1,2 @@
1
+ import{z as e}from"zod";const t={limit:e.number().int().min(1).max(100).optional().describe(`Maximum results to return (1-100, default 10)`),skip:e.number().int().min(0).optional().describe(`Number of results to skip for pagination`)},n={dateFrom:e.string().optional().describe(`Start date (YYYY-MM-DD or YYYYMMDD format)`),dateTo:e.string().optional().describe(`End date (YYYY-MM-DD or YYYYMMDD format)`)},r=e.object({safetyReportId:e.string().optional().describe(`Unique safety report ID for retrieving a specific adverse event report`),drugName:e.string().optional().describe(`Drug or product name to search`),reaction:e.string().optional().describe(`Adverse reaction to search (e.g., 'headache', 'nausea')`),manufacturer:e.string().optional().describe(`Drug manufacturer name`),serious:e.boolean().optional().describe(`Filter for serious adverse events only`),...n,...t}),i=[`indications_and_usage`,`dosage_and_administration`,`contraindications`,`warnings`,`warnings_and_cautions`,`adverse_reactions`,`drug_interactions`,`clinical_pharmacology`,`mechanism_of_action`,`pharmacokinetics`,`overdosage`,`description`,`how_supplied`,`storage_and_handling`,`boxed_warning`],a=e.object({setId:e.string().optional().describe(`Unique label identifier (set_id) for retrieving a specific drug label`),drugName:e.string().optional().describe(`Drug brand or generic name`),indication:e.string().optional().describe(`Medical indication or use case`),activeIngredient:e.string().optional().describe(`Active ingredient/substance name`),route:e.string().optional().describe(`Route of administration (e.g., 'oral', 'intravenous')`),hasBoxedWarning:e.boolean().optional().describe(`Filter for drugs with boxed warnings (most serious safety warnings)`),sections:e.array(e.enum(i)).optional().describe(`Specific label sections to return (e.g., ['indications_and_usage', 'warnings', 'adverse_reactions'])`),...t}),o=e.object({productNdc:e.string().optional().describe(`National Drug Code (NDC)`),brandName:e.string().optional().describe(`Drug brand name`),genericName:e.string().optional().describe(`Drug generic name`),labelerName:e.string().optional().describe(`Drug labeler/manufacturer name`),dosageForm:e.string().optional().describe(`Dosage form (e.g., 'tablet', 'capsule', 'injection')`),route:e.string().optional().describe(`Route of administration`),...t}),s=e.object({recallingFirm:e.string().optional().describe(`Name of the recalling company`),classification:e.enum([`Class I`,`Class II`,`Class III`]).optional().describe(`Recall classification (I=most serious, III=least)`),status:e.enum([`Ongoing`,`Completed`,`Terminated`,`Pending`]).optional().describe(`Recall status`),state:e.string().optional().describe(`US state code (e.g., 'CA', 'NY')`),...n,...t}),c=e.object({sponsorName:e.string().optional().describe(`Drug sponsor/company name`),applicationNumber:e.string().optional().describe(`FDA application number (e.g., 'NDA012345')`),brandName:e.string().optional().describe(`Drug brand name`),marketingStatus:e.string().optional().describe(`Marketing status (e.g., 'Prescription', 'OTC')`),...t}),l=e.object({genericName:e.string().optional().describe(`Generic drug name`),status:e.enum([`Current`,`Resolved`]).optional().describe(`Shortage status`),...t}),u=e.object({deviceName:e.string().optional().describe(`Device name to search`),applicant:e.string().optional().describe(`Applicant/company name`),productCode:e.string().optional().describe(`FDA product code`),clearanceType:e.string().optional().describe(`Clearance type (e.g., 'Traditional', 'Special')`),decisionDateFrom:e.string().optional().describe(`Decision date range start (YYYY-MM-DD)`),decisionDateTo:e.string().optional().describe(`Decision date range end (YYYY-MM-DD)`),...t}),d=e.object({deviceName:e.string().optional().describe(`Device name to search`),deviceClass:e.enum([`1`,`2`,`3`]).optional().describe(`Device class (1=lowest risk, 3=highest)`),medicalSpecialty:e.string().optional().describe(`Medical specialty code`),productCode:e.string().optional().describe(`FDA product code`),regulationNumber:e.string().optional().describe(`CFR regulation number`),...t}),f=e.object({reportNumber:e.string().optional().describe(`MDR report number for retrieving a specific device adverse event report`),deviceName:e.string().optional().describe(`Device generic name`),brandName:e.string().optional().describe(`Device brand name`),manufacturerName:e.string().optional().describe(`Device manufacturer name`),eventType:e.enum([`Injury`,`Malfunction`,`Death`,`Other`]).optional().describe(`Type of adverse event`),...n,...t}),p=e.object({recallingFirm:e.string().optional().describe(`Name of the recalling company`),productDescription:e.string().optional().describe(`Product description keywords`),classification:e.enum([`Class I`,`Class II`,`Class III`]).optional().describe(`Recall classification (I=most serious)`),status:e.enum([`Ongoing`,`Completed`,`Terminated`,`Pending`]).optional().describe(`Recall status`),...n,...t}),m={searchDrugAdverseEvents:r,searchDrugLabels:a,searchDrugNDC:o,searchDrugEnforcement:s,searchDrugsFDA:c,searchDrugShortages:l,searchDevice510K:u,searchDeviceClassifications:d,searchDeviceAdverseEvents:f,searchDeviceEnforcement:p};export{p as a,a as c,c as d,m as f,d as i,o as l,u as n,r as o,f as r,s,i as t,l as u};
2
+ //# sourceMappingURL=tools-3M3lSxQv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools-3M3lSxQv.js","names":[],"sources":["../src/tools/index.ts"],"sourcesContent":["/**\n * MCP Tool Definitions\n * Zod schemas for all FDA MCP tools\n */\n\nimport { z } from \"zod\"\n\n// Common pagination schema\nconst paginationSchema = {\n limit: z.number().int().min(1).max(100).optional().describe(\"Maximum results to return (1-100, default 10)\"),\n skip: z.number().int().min(0).optional().describe(\"Number of results to skip for pagination\"),\n}\n\n// Date range schema\nconst dateRangeSchema = {\n dateFrom: z.string().optional().describe(\"Start date (YYYY-MM-DD or YYYYMMDD format)\"),\n dateTo: z.string().optional().describe(\"End date (YYYY-MM-DD or YYYYMMDD format)\"),\n}\n\n// Drug Tool Schemas\n\nexport const searchDrugAdverseEventsSchema = z.object({\n safetyReportId: z\n .string()\n .optional()\n .describe(\"Unique safety report ID for retrieving a specific adverse event report\"),\n drugName: z.string().optional().describe(\"Drug or product name to search\"),\n reaction: z.string().optional().describe(\"Adverse reaction to search (e.g., 'headache', 'nausea')\"),\n manufacturer: z.string().optional().describe(\"Drug manufacturer name\"),\n serious: z.boolean().optional().describe(\"Filter for serious adverse events only\"),\n ...dateRangeSchema,\n ...paginationSchema,\n})\n\n// Available label sections for filtering\nexport const labelSections = [\n \"indications_and_usage\",\n \"dosage_and_administration\",\n \"contraindications\",\n \"warnings\",\n \"warnings_and_cautions\",\n \"adverse_reactions\",\n \"drug_interactions\",\n \"clinical_pharmacology\",\n \"mechanism_of_action\",\n \"pharmacokinetics\",\n \"overdosage\",\n \"description\",\n \"how_supplied\",\n \"storage_and_handling\",\n \"boxed_warning\",\n] as const\n\nexport const searchDrugLabelsSchema = z.object({\n setId: z.string().optional().describe(\"Unique label identifier (set_id) for retrieving a specific drug label\"),\n drugName: z.string().optional().describe(\"Drug brand or generic name\"),\n indication: z.string().optional().describe(\"Medical indication or use case\"),\n activeIngredient: z.string().optional().describe(\"Active ingredient/substance name\"),\n route: z.string().optional().describe(\"Route of administration (e.g., 'oral', 'intravenous')\"),\n hasBoxedWarning: z\n .boolean()\n .optional()\n .describe(\"Filter for drugs with boxed warnings (most serious safety warnings)\"),\n sections: z\n .array(z.enum(labelSections))\n .optional()\n .describe(\"Specific label sections to return (e.g., ['indications_and_usage', 'warnings', 'adverse_reactions'])\"),\n ...paginationSchema,\n})\n\nexport const searchDrugNDCSchema = z.object({\n productNdc: z.string().optional().describe(\"National Drug Code (NDC)\"),\n brandName: z.string().optional().describe(\"Drug brand name\"),\n genericName: z.string().optional().describe(\"Drug generic name\"),\n labelerName: z.string().optional().describe(\"Drug labeler/manufacturer name\"),\n dosageForm: z.string().optional().describe(\"Dosage form (e.g., 'tablet', 'capsule', 'injection')\"),\n route: z.string().optional().describe(\"Route of administration\"),\n ...paginationSchema,\n})\n\nexport const searchDrugEnforcementSchema = z.object({\n recallingFirm: z.string().optional().describe(\"Name of the recalling company\"),\n classification: z\n .enum([\"Class I\", \"Class II\", \"Class III\"])\n .optional()\n .describe(\"Recall classification (I=most serious, III=least)\"),\n status: z.enum([\"Ongoing\", \"Completed\", \"Terminated\", \"Pending\"]).optional().describe(\"Recall status\"),\n state: z.string().optional().describe(\"US state code (e.g., 'CA', 'NY')\"),\n ...dateRangeSchema,\n ...paginationSchema,\n})\n\nexport const searchDrugsFDASchema = z.object({\n sponsorName: z.string().optional().describe(\"Drug sponsor/company name\"),\n applicationNumber: z.string().optional().describe(\"FDA application number (e.g., 'NDA012345')\"),\n brandName: z.string().optional().describe(\"Drug brand name\"),\n marketingStatus: z.string().optional().describe(\"Marketing status (e.g., 'Prescription', 'OTC')\"),\n ...paginationSchema,\n})\n\nexport const searchDrugShortagesSchema = z.object({\n genericName: z.string().optional().describe(\"Generic drug name\"),\n status: z.enum([\"Current\", \"Resolved\"]).optional().describe(\"Shortage status\"),\n ...paginationSchema,\n})\n\n// Device Tool Schemas\n\nexport const searchDevice510KSchema = z.object({\n deviceName: z.string().optional().describe(\"Device name to search\"),\n applicant: z.string().optional().describe(\"Applicant/company name\"),\n productCode: z.string().optional().describe(\"FDA product code\"),\n clearanceType: z.string().optional().describe(\"Clearance type (e.g., 'Traditional', 'Special')\"),\n decisionDateFrom: z.string().optional().describe(\"Decision date range start (YYYY-MM-DD)\"),\n decisionDateTo: z.string().optional().describe(\"Decision date range end (YYYY-MM-DD)\"),\n ...paginationSchema,\n})\n\nexport const searchDeviceClassificationsSchema = z.object({\n deviceName: z.string().optional().describe(\"Device name to search\"),\n deviceClass: z.enum([\"1\", \"2\", \"3\"]).optional().describe(\"Device class (1=lowest risk, 3=highest)\"),\n medicalSpecialty: z.string().optional().describe(\"Medical specialty code\"),\n productCode: z.string().optional().describe(\"FDA product code\"),\n regulationNumber: z.string().optional().describe(\"CFR regulation number\"),\n ...paginationSchema,\n})\n\nexport const searchDeviceAdverseEventsSchema = z.object({\n reportNumber: z\n .string()\n .optional()\n .describe(\"MDR report number for retrieving a specific device adverse event report\"),\n deviceName: z.string().optional().describe(\"Device generic name\"),\n brandName: z.string().optional().describe(\"Device brand name\"),\n manufacturerName: z.string().optional().describe(\"Device manufacturer name\"),\n eventType: z.enum([\"Injury\", \"Malfunction\", \"Death\", \"Other\"]).optional().describe(\"Type of adverse event\"),\n ...dateRangeSchema,\n ...paginationSchema,\n})\n\nexport const searchDeviceEnforcementSchema = z.object({\n recallingFirm: z.string().optional().describe(\"Name of the recalling company\"),\n productDescription: z.string().optional().describe(\"Product description keywords\"),\n classification: z\n .enum([\"Class I\", \"Class II\", \"Class III\"])\n .optional()\n .describe(\"Recall classification (I=most serious)\"),\n status: z.enum([\"Ongoing\", \"Completed\", \"Terminated\", \"Pending\"]).optional().describe(\"Recall status\"),\n ...dateRangeSchema,\n ...paginationSchema,\n})\n\n// Export all schemas for use in tool registration\nexport const toolSchemas = {\n searchDrugAdverseEvents: searchDrugAdverseEventsSchema,\n searchDrugLabels: searchDrugLabelsSchema,\n searchDrugNDC: searchDrugNDCSchema,\n searchDrugEnforcement: searchDrugEnforcementSchema,\n searchDrugsFDA: searchDrugsFDASchema,\n searchDrugShortages: searchDrugShortagesSchema,\n searchDevice510K: searchDevice510KSchema,\n searchDeviceClassifications: searchDeviceClassificationsSchema,\n searchDeviceAdverseEvents: searchDeviceAdverseEventsSchema,\n searchDeviceEnforcement: searchDeviceEnforcementSchema,\n}\n\n// Export inferred types\nexport type SearchDrugAdverseEventsParams = z.infer<typeof searchDrugAdverseEventsSchema>\nexport type SearchDrugLabelsParams = z.infer<typeof searchDrugLabelsSchema>\nexport type SearchDrugNDCParams = z.infer<typeof searchDrugNDCSchema>\nexport type SearchDrugEnforcementParams = z.infer<typeof searchDrugEnforcementSchema>\nexport type SearchDrugsFDAParams = z.infer<typeof searchDrugsFDASchema>\nexport type SearchDrugShortagesParams = z.infer<typeof searchDrugShortagesSchema>\nexport type SearchDevice510KParams = z.infer<typeof searchDevice510KSchema>\nexport type SearchDeviceClassificationsParams = z.infer<typeof searchDeviceClassificationsSchema>\nexport type SearchDeviceAdverseEventsParams = z.infer<typeof searchDeviceAdverseEventsSchema>\nexport type SearchDeviceEnforcementParams = z.infer<typeof searchDeviceEnforcementSchema>\nexport type LabelSection = (typeof labelSections)[number]\n"],"mappings":"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"}
@@ -130,6 +130,7 @@ type DrugLabel = {
130
130
  purpose?: string[];
131
131
  indications_and_usage?: string[];
132
132
  warnings?: string[];
133
+ boxed_warning?: string[];
133
134
  do_not_use?: string[];
134
135
  ask_doctor?: string[];
135
136
  ask_doctor_or_pharmacist?: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openfda-mcp-server",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "MCP server for querying U.S. FDA public datasets - drugs, devices, adverse events, recalls, and more",
5
5
  "keywords": [
6
6
  "mcp",
@@ -13,10 +13,10 @@
13
13
  ],
14
14
  "author": "jordan.burke@gmail.com",
15
15
  "license": "MIT",
16
- "homepage": "https://github.com/jordanburke/openfda-mcp-server",
16
+ "homepage": "https://github.com/sapientsai/openfda-mcp-server",
17
17
  "repository": {
18
18
  "type": "git",
19
- "url": "https://github.com/jordanburke/openfda-mcp-server"
19
+ "url": "https://github.com/sapientsai/openfda-mcp-server"
20
20
  },
21
21
  "dependencies": {
22
22
  "@jordanburke/fastmcp": "^3.26.700",
@@ -1 +0,0 @@
1
- {"version":3,"file":"device-handlers-D01LfIJk.js","names":["searchParams: SearchParams"],"sources":["../src/handlers/device-handlers.ts"],"sourcesContent":["/**\n * Device Handlers\n * Query handlers for FDA device-related endpoints\n */\n\nimport type {\n Device510K,\n DeviceAdverseEvent,\n DeviceClassification,\n DeviceEnforcement,\n FDAToolResponse,\n SearchParams,\n} from \"../types/fda.js\"\nimport { fdaAPIClient } from \"../utils/api-client.js\"\nimport { loggers } from \"../utils/logger.js\"\n\n// Helper to build date range query\nfunction buildDateQuery(field: string, dateFrom?: string, dateTo?: string): string | undefined {\n if (!dateFrom && !dateTo) return undefined\n\n // FDA date format is YYYYMMDD\n const from = dateFrom?.replace(/-/g, \"\") ?? \"*\"\n const to = dateTo?.replace(/-/g, \"\") ?? \"*\"\n\n return `${field}:[${from}+TO+${to}]`\n}\n\n// Helper to escape special characters in search terms\nfunction escapeSearchTerm(term: string): string {\n return term.replace(/[+\\-&|!(){}[\\]^\"~*?:\\\\]/g, \"\\\\$&\").replace(/\\s+/g, \"+\")\n}\n\n// Helper to build a search query from multiple terms\nfunction buildSearchQuery(terms: Array<{ field: string; value?: string }>): string {\n const validTerms = terms.filter((t) => t.value !== undefined && t.value.trim() !== \"\")\n if (validTerms.length === 0) return \"\"\n\n return validTerms.map((t) => `${t.field}:\"${escapeSearchTerm(t.value!)}\"`).join(\"+AND+\")\n}\n\n// Format truncated text\nfunction truncateText(text: string | undefined, maxLength = 200): string | undefined {\n if (!text) return undefined\n return text.length > maxLength ? text.substring(0, maxLength) + \"...\" : text\n}\n\n// Device 510(k) Handler\nexport type Device510KParams = {\n deviceName?: string\n applicant?: string\n productCode?: string\n clearanceType?: string\n decisionDateFrom?: string\n decisionDateTo?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDevice510K = {\n kNumber: string | undefined\n deviceName: string | undefined\n applicant: string | undefined\n productCode: string | undefined\n clearanceType: string | undefined\n decisionCode: string | undefined\n decisionDescription: string | undefined\n decisionDate: string | undefined\n dateReceived: string | undefined\n city: string | undefined\n state: string | undefined\n country: string | undefined\n}\n\nfunction formatDevice510K(device: Device510K): FormattedDevice510K {\n return {\n kNumber: device.k_number,\n deviceName: device.device_name ?? device.openfda?.device_name,\n applicant: device.applicant,\n productCode: device.product_code,\n clearanceType: device.clearance_type,\n decisionCode: device.decision_code,\n decisionDescription: device.decision_description,\n decisionDate: device.decision_date,\n dateReceived: device.date_received,\n city: device.city,\n state: device.state,\n country: device.country_code,\n }\n}\n\nexport async function handleSearchDevice510K(\n params: Device510KParams,\n): Promise<FDAToolResponse<FormattedDevice510K[]>> {\n loggers.tools(\"searchDevice510K\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"device_name\", value: params.deviceName },\n { field: \"applicant\", value: params.applicant },\n { field: \"product_code\", value: params.productCode },\n { field: \"clearance_type\", value: params.clearanceType },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n const dateQuery = buildDateQuery(\"decision_date\", params.decisionDateFrom, params.decisionDateTo)\n const fullQuery = [searchQuery, dateQuery].filter(Boolean).join(\"+AND+\")\n\n const searchParams: SearchParams = {\n search: fullQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDevice510K(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDevice510K),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Device Classification Handler\nexport type DeviceClassificationParams = {\n deviceName?: string\n deviceClass?: \"1\" | \"2\" | \"3\"\n medicalSpecialty?: string\n productCode?: string\n regulationNumber?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDeviceClassification = {\n deviceName: string | undefined\n deviceClass: string | undefined\n definition: string | undefined\n medicalSpecialty: string | undefined\n medicalSpecialtyDescription: string | undefined\n productCode: string | undefined\n regulationNumber: string | undefined\n gmpExempt: boolean\n implant: boolean\n lifeSustaining: boolean\n}\n\nfunction formatDeviceClassification(classification: DeviceClassification): FormattedDeviceClassification {\n return {\n deviceName: classification.device_name,\n deviceClass: classification.device_class,\n definition: truncateText(classification.definition),\n medicalSpecialty: classification.medical_specialty,\n medicalSpecialtyDescription: classification.medical_specialty_description,\n productCode: classification.product_code,\n regulationNumber: classification.regulation_number,\n gmpExempt: classification.gmp_exempt_flag === \"Y\",\n implant: classification.implant_flag === \"Y\",\n lifeSustaining: classification.life_sustain_support_flag === \"Y\",\n }\n}\n\nexport async function handleSearchDeviceClassifications(\n params: DeviceClassificationParams,\n): Promise<FDAToolResponse<FormattedDeviceClassification[]>> {\n loggers.tools(\"searchDeviceClassifications\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"device_name\", value: params.deviceName },\n { field: \"device_class\", value: params.deviceClass },\n { field: \"medical_specialty\", value: params.medicalSpecialty },\n { field: \"product_code\", value: params.productCode },\n { field: \"regulation_number\", value: params.regulationNumber },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n\n const searchParams: SearchParams = {\n search: searchQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDeviceClassifications(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDeviceClassification),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Device Adverse Events (MDR) Handler\nexport type DeviceAdverseEventsParams = {\n deviceName?: string\n brandName?: string\n manufacturerName?: string\n eventType?: \"Injury\" | \"Malfunction\" | \"Death\" | \"Other\"\n dateFrom?: string\n dateTo?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDeviceAdverseEvent = {\n reportNumber: string | undefined\n dateOfEvent: string | undefined\n dateReceived: string | undefined\n eventType: string | undefined\n adverseEventFlag: boolean\n productProblemFlag: boolean\n devices: Array<{\n brandName: string | undefined\n genericName: string | undefined\n manufacturerName: string | undefined\n modelNumber: string | undefined\n productCode: string | undefined\n deviceClass: string | undefined\n }>\n mdrText: Array<{\n textType: string | undefined\n text: string | undefined\n }>\n}\n\nfunction formatDeviceAdverseEvent(event: DeviceAdverseEvent): FormattedDeviceAdverseEvent {\n return {\n reportNumber: event.report_number,\n dateOfEvent: event.date_of_event,\n dateReceived: event.date_received,\n eventType: event.event_type,\n adverseEventFlag: event.adverse_event_flag === \"Y\",\n productProblemFlag: event.product_problem_flag === \"Y\",\n devices:\n event.device?.slice(0, 3).map((d) => ({\n brandName: d.brand_name,\n genericName: d.generic_name,\n manufacturerName: d.manufacturer_d_name,\n modelNumber: d.model_number,\n productCode: d.device_report_product_code,\n deviceClass: d.openfda?.device_class,\n })) ?? [],\n mdrText:\n event.mdr_text?.slice(0, 2).map((t) => ({\n textType: t.text_type_code,\n text: truncateText(t.text, 300),\n })) ?? [],\n }\n}\n\nexport async function handleSearchDeviceAdverseEvents(\n params: DeviceAdverseEventsParams,\n): Promise<FDAToolResponse<FormattedDeviceAdverseEvent[]>> {\n loggers.tools(\"searchDeviceAdverseEvents\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"device.generic_name\", value: params.deviceName },\n { field: \"device.brand_name\", value: params.brandName },\n { field: \"device.manufacturer_d_name\", value: params.manufacturerName },\n { field: \"event_type\", value: params.eventType },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n const dateQuery = buildDateQuery(\"date_received\", params.dateFrom, params.dateTo)\n const fullQuery = [searchQuery, dateQuery].filter(Boolean).join(\"+AND+\")\n\n const searchParams: SearchParams = {\n search: fullQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDeviceAdverseEvents(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDeviceAdverseEvent),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Device Enforcement (Recalls) Handler\nexport type DeviceEnforcementParams = {\n recallingFirm?: string\n productDescription?: string\n classification?: \"Class I\" | \"Class II\" | \"Class III\"\n status?: \"Ongoing\" | \"Completed\" | \"Terminated\" | \"Pending\"\n dateFrom?: string\n dateTo?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDeviceEnforcement = {\n recallNumber: string | undefined\n recallingFirm: string | undefined\n classification: string | undefined\n status: string | undefined\n productDescription: string | undefined\n reasonForRecall: string | undefined\n recallInitiationDate: string | undefined\n distributionPattern: string | undefined\n city: string | undefined\n state: string | undefined\n deviceName: string | undefined\n deviceClass: string | undefined\n}\n\nfunction formatDeviceEnforcement(recall: DeviceEnforcement): FormattedDeviceEnforcement {\n return {\n recallNumber: recall.recall_number,\n recallingFirm: recall.recalling_firm,\n classification: recall.classification,\n status: recall.status,\n productDescription: truncateText(recall.product_description),\n reasonForRecall: truncateText(recall.reason_for_recall),\n recallInitiationDate: recall.recall_initiation_date,\n distributionPattern: truncateText(recall.distribution_pattern),\n city: recall.city,\n state: recall.state,\n deviceName: recall.openfda?.device_name,\n deviceClass: recall.openfda?.device_class,\n }\n}\n\nexport async function handleSearchDeviceEnforcement(\n params: DeviceEnforcementParams,\n): Promise<FDAToolResponse<FormattedDeviceEnforcement[]>> {\n loggers.tools(\"searchDeviceEnforcement\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"recalling_firm\", value: params.recallingFirm },\n { field: \"product_description\", value: params.productDescription },\n { field: \"classification\", value: params.classification },\n { field: \"status\", value: params.status },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n const dateQuery = buildDateQuery(\"recall_initiation_date\", params.dateFrom, params.dateTo)\n const fullQuery = [searchQuery, dateQuery].filter(Boolean).join(\"+AND+\")\n\n const searchParams: SearchParams = {\n search: fullQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDeviceEnforcement(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDeviceEnforcement),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{loggers as e}from"./utils/logger.js";import{n as t}from"./api-client-BGnUXMwX.js";function n(e,t,n){if(!(!t&&!n))return`${e}:[${t?.replace(/-/g,``)??`*`}+TO+${n?.replace(/-/g,``)??`*`}]`}function r(e){return e.replace(/[+\-&|!(){}[\]^"~*?:\\]/g,`\\$&`).replace(/\s+/g,`+`)}function i(e){let t=e.filter(e=>e.value!==void 0&&e.value.trim()!==``);return t.length===0?``:t.map(e=>`${e.field}:"${r(e.value)}"`).join(`+AND+`)}function a(e,t=200){if(e)return e.length>t?e.substring(0,t)+`...`:e}function o(e){return{reportId:e.safetyreportid,receiveDate:e.receivedate,serious:e.serious===`1`,drugs:e.patient?.drug?.slice(0,3).map(e=>({name:e.medicinalproduct??e.activesubstance?.activesubstancename,indication:e.drugindication,route:e.drugadministrationroute}))??[],reactions:e.patient?.reaction?.slice(0,3).map(e=>({reaction:e.reactionmeddrapt,outcome:e.reactionoutcome}))??[],patient:{age:e.patient?.patientonsetage?`${e.patient.patientonsetage} ${e.patient.patientonsetageunit??``}`:void 0,sex:e.patient?.patientsex===`1`?`Male`:e.patient?.patientsex===`2`?`Female`:void 0,weight:e.patient?.patientweight?`${e.patient.patientweight} kg`:void 0}}}async function s(r){e.tools(`searchDrugAdverseEvents`,r);try{let e=[{field:`patient.drug.medicinalproduct`,value:r.drugName},{field:`patient.reaction.reactionmeddrapt`,value:r.reaction},{field:`patient.drug.openfda.manufacturer_name`,value:r.manufacturer}];r.serious!==void 0&&e.push({field:`serious`,value:r.serious?`1`:`2`});let a={search:[i(e),n(`receivedate`,r.dateFrom,r.dateTo)].filter(Boolean).join(`+AND+`)||void 0,limit:r.limit,skip:r.skip},s=await t.searchDrugAdverseEvents(a),c=s.results??[];return{success:!0,data:c.map(o),totalResults:s.meta?.results?.total,displayedResults:c.length,searchParams:a,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function c(e){return{brandName:e.openfda?.brand_name?.[0],genericName:e.openfda?.generic_name?.[0],manufacturer:e.openfda?.manufacturer_name?.[0],activeIngredients:e.openfda?.substance_name?.slice(0,5)??[],indications:a(e.indications_and_usage?.[0]),warnings:a(e.warnings?.[0]),dosageAndAdministration:a(e.dosage_and_administration?.[0]),route:e.openfda?.route?.slice(0,3)??[]}}async function l(n){e.tools(`searchDrugLabels`,n);try{let e={search:i([{field:`openfda.brand_name`,value:n.drugName},{field:`indications_and_usage`,value:n.indication},{field:`openfda.substance_name`,value:n.activeIngredient},{field:`openfda.route`,value:n.route}])||void 0,limit:n.limit,skip:n.skip},r=await t.searchDrugLabels(e),a=r.results??[];return{success:!0,data:a.map(c),totalResults:r.meta?.results?.total,displayedResults:a.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function u(e){return{productNdc:e.product_ndc,brandName:e.brand_name,genericName:e.generic_name,labelerName:e.labeler_name,dosageForm:e.dosage_form,route:e.route??[],activeIngredients:e.active_ingredients?.slice(0,3).map(e=>({name:e.name,strength:e.strength}))??[],marketingStartDate:e.marketing_start_date,productType:e.product_type}}async function d(n){e.tools(`searchDrugNDC`,n);try{let e={search:i([{field:`product_ndc`,value:n.productNdc},{field:`brand_name`,value:n.brandName},{field:`generic_name`,value:n.genericName},{field:`labeler_name`,value:n.labelerName},{field:`dosage_form`,value:n.dosageForm},{field:`route`,value:n.route}])||void 0,limit:n.limit,skip:n.skip},r=await t.searchDrugNDC(e),a=r.results??[];return{success:!0,data:a.map(u),totalResults:r.meta?.results?.total,displayedResults:a.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function f(e){return{recallNumber:e.recall_number,recallingFirm:e.recalling_firm,classification:e.classification,status:e.status,productDescription:a(e.product_description),reasonForRecall:a(e.reason_for_recall),recallInitiationDate:e.recall_initiation_date,distributionPattern:a(e.distribution_pattern),city:e.city,state:e.state}}async function p(r){e.tools(`searchDrugEnforcement`,r);try{let e={search:[i([{field:`recalling_firm`,value:r.recallingFirm},{field:`classification`,value:r.classification},{field:`status`,value:r.status},{field:`state`,value:r.state}]),n(`recall_initiation_date`,r.dateFrom,r.dateTo)].filter(Boolean).join(`+AND+`)||void 0,limit:r.limit,skip:r.skip},a=await t.searchDrugEnforcement(e),o=a.results??[];return{success:!0,data:o.map(f),totalResults:a.meta?.results?.total,displayedResults:o.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function m(e){let t=e.submissions?.[0];return{applicationNumber:e.application_number,sponsorName:e.sponsor_name,products:e.products?.slice(0,3).map(e=>({brandName:e.brand_name,dosageForm:e.dosage_form,route:e.route,marketingStatus:e.marketing_status,activeIngredients:e.active_ingredients?.slice(0,3).map(e=>({name:e.name,strength:e.strength}))??[]}))??[],latestSubmission:t?{type:t.submission_type,status:t.submission_status,statusDate:t.submission_status_date}:void 0}}async function h(n){e.tools(`searchDrugsFDA`,n);try{let e={search:i([{field:`sponsor_name`,value:n.sponsorName},{field:`application_number`,value:n.applicationNumber},{field:`products.brand_name`,value:n.brandName},{field:`products.marketing_status`,value:n.marketingStatus}])||void 0,limit:n.limit,skip:n.skip},r=await t.searchDrugsFDA(e),a=r.results??[];return{success:!0,data:a.map(m),totalResults:r.meta?.results?.total,displayedResults:a.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}function g(e){return{genericName:e.generic_name,proprietaryName:e.proprietary_name,status:e.status,description:a(e.description),initialPostingDate:e.initial_posting_date,resolvedShortageDate:e.resolved_shortage_date}}async function _(n){e.tools(`searchDrugShortages`,n);try{let e={search:i([{field:`generic_name`,value:n.genericName},{field:`status`,value:n.status}])||void 0,limit:n.limit,skip:n.skip},r=await t.searchDrugShortages(e),a=r.results??[];return{success:!0,data:a.map(g),totalResults:r.meta?.results?.total,displayedResults:a.length,searchParams:e,apiUsage:t.getRateLimitInfo()}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}export{_ as a,d as i,p as n,h as o,l as r,s as t};
2
- //# sourceMappingURL=drug-handlers-Fz_6NLl5.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"drug-handlers-Fz_6NLl5.js","names":["searchTerms: Array<{ field: string; value?: string }>","searchParams: SearchParams"],"sources":["../src/handlers/drug-handlers.ts"],"sourcesContent":["/**\n * Drug Handlers\n * Query handlers for FDA drug-related endpoints\n */\n\nimport type {\n DrugAdverseEvent,\n DrugEnforcement,\n DrugLabel,\n DrugNDC,\n DrugsFDA,\n DrugShortage,\n FDAToolResponse,\n SearchParams,\n} from \"../types/fda.js\"\nimport { fdaAPIClient } from \"../utils/api-client.js\"\nimport { loggers } from \"../utils/logger.js\"\n\n// Helper to build date range query\nfunction buildDateQuery(field: string, dateFrom?: string, dateTo?: string): string | undefined {\n if (!dateFrom && !dateTo) return undefined\n\n // FDA date format is YYYYMMDD\n const from = dateFrom?.replace(/-/g, \"\") ?? \"*\"\n const to = dateTo?.replace(/-/g, \"\") ?? \"*\"\n\n return `${field}:[${from}+TO+${to}]`\n}\n\n// Helper to escape special characters in search terms\nfunction escapeSearchTerm(term: string): string {\n // Escape special characters that have meaning in FDA's search syntax\n return term.replace(/[+\\-&|!(){}[\\]^\"~*?:\\\\]/g, \"\\\\$&\").replace(/\\s+/g, \"+\")\n}\n\n// Helper to build a search query from multiple terms\nfunction buildSearchQuery(terms: Array<{ field: string; value?: string }>): string {\n const validTerms = terms.filter((t) => t.value !== undefined && t.value.trim() !== \"\")\n if (validTerms.length === 0) return \"\"\n\n return validTerms.map((t) => `${t.field}:\"${escapeSearchTerm(t.value!)}\"`).join(\"+AND+\")\n}\n\n// Format truncated text\nfunction truncateText(text: string | undefined, maxLength = 200): string | undefined {\n if (!text) return undefined\n return text.length > maxLength ? text.substring(0, maxLength) + \"...\" : text\n}\n\n// Drug Adverse Events Handler\nexport type DrugAdverseEventsParams = {\n drugName?: string\n reaction?: string\n manufacturer?: string\n serious?: boolean\n dateFrom?: string\n dateTo?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDrugAdverseEvent = {\n reportId: string | undefined\n receiveDate: string | undefined\n serious: boolean\n drugs: Array<{\n name: string | undefined\n indication: string | undefined\n route: string | undefined\n }>\n reactions: Array<{\n reaction: string | undefined\n outcome: string | undefined\n }>\n patient: {\n age: string | undefined\n sex: string | undefined\n weight: string | undefined\n }\n}\n\nfunction formatDrugAdverseEvent(event: DrugAdverseEvent): FormattedDrugAdverseEvent {\n return {\n reportId: event.safetyreportid,\n receiveDate: event.receivedate,\n serious: event.serious === \"1\",\n drugs:\n event.patient?.drug?.slice(0, 3).map((d) => ({\n name: d.medicinalproduct ?? d.activesubstance?.activesubstancename,\n indication: d.drugindication,\n route: d.drugadministrationroute,\n })) ?? [],\n reactions:\n event.patient?.reaction?.slice(0, 3).map((r) => ({\n reaction: r.reactionmeddrapt,\n outcome: r.reactionoutcome,\n })) ?? [],\n patient: {\n age: event.patient?.patientonsetage\n ? `${event.patient.patientonsetage} ${event.patient.patientonsetageunit ?? \"\"}`\n : undefined,\n sex: event.patient?.patientsex === \"1\" ? \"Male\" : event.patient?.patientsex === \"2\" ? \"Female\" : undefined,\n weight: event.patient?.patientweight ? `${event.patient.patientweight} kg` : undefined,\n },\n }\n}\n\nexport async function handleSearchDrugAdverseEvents(\n params: DrugAdverseEventsParams,\n): Promise<FDAToolResponse<FormattedDrugAdverseEvent[]>> {\n loggers.tools(\"searchDrugAdverseEvents\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"patient.drug.medicinalproduct\", value: params.drugName },\n { field: \"patient.reaction.reactionmeddrapt\", value: params.reaction },\n { field: \"patient.drug.openfda.manufacturer_name\", value: params.manufacturer },\n ]\n\n if (params.serious !== undefined) {\n searchTerms.push({ field: \"serious\", value: params.serious ? \"1\" : \"2\" })\n }\n\n const searchQuery = buildSearchQuery(searchTerms)\n const dateQuery = buildDateQuery(\"receivedate\", params.dateFrom, params.dateTo)\n const fullQuery = [searchQuery, dateQuery].filter(Boolean).join(\"+AND+\")\n\n const searchParams: SearchParams = {\n search: fullQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDrugAdverseEvents(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDrugAdverseEvent),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Drug Labels Handler\nexport type DrugLabelsParams = {\n drugName?: string\n indication?: string\n activeIngredient?: string\n route?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDrugLabel = {\n brandName: string | undefined\n genericName: string | undefined\n manufacturer: string | undefined\n activeIngredients: string[]\n indications: string | undefined\n warnings: string | undefined\n dosageAndAdministration: string | undefined\n route: string[]\n}\n\nfunction formatDrugLabel(label: DrugLabel): FormattedDrugLabel {\n return {\n brandName: label.openfda?.brand_name?.[0],\n genericName: label.openfda?.generic_name?.[0],\n manufacturer: label.openfda?.manufacturer_name?.[0],\n activeIngredients: label.openfda?.substance_name?.slice(0, 5) ?? [],\n indications: truncateText(label.indications_and_usage?.[0]),\n warnings: truncateText(label.warnings?.[0]),\n dosageAndAdministration: truncateText(label.dosage_and_administration?.[0]),\n route: label.openfda?.route?.slice(0, 3) ?? [],\n }\n}\n\nexport async function handleSearchDrugLabels(params: DrugLabelsParams): Promise<FDAToolResponse<FormattedDrugLabel[]>> {\n loggers.tools(\"searchDrugLabels\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"openfda.brand_name\", value: params.drugName },\n { field: \"indications_and_usage\", value: params.indication },\n { field: \"openfda.substance_name\", value: params.activeIngredient },\n { field: \"openfda.route\", value: params.route },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n\n const searchParams: SearchParams = {\n search: searchQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDrugLabels(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDrugLabel),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Drug NDC Handler\nexport type DrugNDCParams = {\n productNdc?: string\n brandName?: string\n genericName?: string\n labelerName?: string\n dosageForm?: string\n route?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDrugNDC = {\n productNdc: string | undefined\n brandName: string | undefined\n genericName: string | undefined\n labelerName: string | undefined\n dosageForm: string | undefined\n route: string[]\n activeIngredients: Array<{ name: string | undefined; strength: string | undefined }>\n marketingStartDate: string | undefined\n productType: string | undefined\n}\n\nfunction formatDrugNDC(ndc: DrugNDC): FormattedDrugNDC {\n return {\n productNdc: ndc.product_ndc,\n brandName: ndc.brand_name,\n genericName: ndc.generic_name,\n labelerName: ndc.labeler_name,\n dosageForm: ndc.dosage_form,\n route: ndc.route ?? [],\n activeIngredients:\n ndc.active_ingredients?.slice(0, 3).map((ai) => ({\n name: ai.name,\n strength: ai.strength,\n })) ?? [],\n marketingStartDate: ndc.marketing_start_date,\n productType: ndc.product_type,\n }\n}\n\nexport async function handleSearchDrugNDC(params: DrugNDCParams): Promise<FDAToolResponse<FormattedDrugNDC[]>> {\n loggers.tools(\"searchDrugNDC\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"product_ndc\", value: params.productNdc },\n { field: \"brand_name\", value: params.brandName },\n { field: \"generic_name\", value: params.genericName },\n { field: \"labeler_name\", value: params.labelerName },\n { field: \"dosage_form\", value: params.dosageForm },\n { field: \"route\", value: params.route },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n\n const searchParams: SearchParams = {\n search: searchQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDrugNDC(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDrugNDC),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Drug Enforcement (Recalls) Handler\nexport type DrugEnforcementParams = {\n recallingFirm?: string\n classification?: \"Class I\" | \"Class II\" | \"Class III\"\n status?: \"Ongoing\" | \"Completed\" | \"Terminated\" | \"Pending\"\n state?: string\n dateFrom?: string\n dateTo?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDrugEnforcement = {\n recallNumber: string | undefined\n recallingFirm: string | undefined\n classification: string | undefined\n status: string | undefined\n productDescription: string | undefined\n reasonForRecall: string | undefined\n recallInitiationDate: string | undefined\n distributionPattern: string | undefined\n city: string | undefined\n state: string | undefined\n}\n\nfunction formatDrugEnforcement(recall: DrugEnforcement): FormattedDrugEnforcement {\n return {\n recallNumber: recall.recall_number,\n recallingFirm: recall.recalling_firm,\n classification: recall.classification,\n status: recall.status,\n productDescription: truncateText(recall.product_description),\n reasonForRecall: truncateText(recall.reason_for_recall),\n recallInitiationDate: recall.recall_initiation_date,\n distributionPattern: truncateText(recall.distribution_pattern),\n city: recall.city,\n state: recall.state,\n }\n}\n\nexport async function handleSearchDrugEnforcement(\n params: DrugEnforcementParams,\n): Promise<FDAToolResponse<FormattedDrugEnforcement[]>> {\n loggers.tools(\"searchDrugEnforcement\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"recalling_firm\", value: params.recallingFirm },\n { field: \"classification\", value: params.classification },\n { field: \"status\", value: params.status },\n { field: \"state\", value: params.state },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n const dateQuery = buildDateQuery(\"recall_initiation_date\", params.dateFrom, params.dateTo)\n const fullQuery = [searchQuery, dateQuery].filter(Boolean).join(\"+AND+\")\n\n const searchParams: SearchParams = {\n search: fullQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDrugEnforcement(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDrugEnforcement),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Drugs@FDA Handler\nexport type DrugsFDAParams = {\n sponsorName?: string\n applicationNumber?: string\n brandName?: string\n marketingStatus?: string\n limit?: number\n skip?: number\n}\n\ntype FormattedDrugsFDA = {\n applicationNumber: string | undefined\n sponsorName: string | undefined\n products: Array<{\n brandName: string | undefined\n dosageForm: string | undefined\n route: string | undefined\n marketingStatus: string | undefined\n activeIngredients: Array<{ name: string | undefined; strength: string | undefined }>\n }>\n latestSubmission:\n | {\n type: string | undefined\n status: string | undefined\n statusDate: string | undefined\n }\n | undefined\n}\n\nfunction formatDrugsFDA(drug: DrugsFDA): FormattedDrugsFDA {\n const latestSubmission = drug.submissions?.[0]\n\n return {\n applicationNumber: drug.application_number,\n sponsorName: drug.sponsor_name,\n products:\n drug.products?.slice(0, 3).map((p) => ({\n brandName: p.brand_name,\n dosageForm: p.dosage_form,\n route: p.route,\n marketingStatus: p.marketing_status,\n activeIngredients:\n p.active_ingredients?.slice(0, 3).map((ai) => ({\n name: ai.name,\n strength: ai.strength,\n })) ?? [],\n })) ?? [],\n latestSubmission: latestSubmission\n ? {\n type: latestSubmission.submission_type,\n status: latestSubmission.submission_status,\n statusDate: latestSubmission.submission_status_date,\n }\n : undefined,\n }\n}\n\nexport async function handleSearchDrugsFDA(params: DrugsFDAParams): Promise<FDAToolResponse<FormattedDrugsFDA[]>> {\n loggers.tools(\"searchDrugsFDA\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"sponsor_name\", value: params.sponsorName },\n { field: \"application_number\", value: params.applicationNumber },\n { field: \"products.brand_name\", value: params.brandName },\n { field: \"products.marketing_status\", value: params.marketingStatus },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n\n const searchParams: SearchParams = {\n search: searchQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDrugsFDA(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDrugsFDA),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n\n// Drug Shortages Handler\nexport type DrugShortagesParams = {\n genericName?: string\n status?: \"Current\" | \"Resolved\"\n limit?: number\n skip?: number\n}\n\ntype FormattedDrugShortage = {\n genericName: string | undefined\n proprietaryName: string | undefined\n status: string | undefined\n description: string | undefined\n initialPostingDate: string | undefined\n resolvedShortageDate: string | undefined\n}\n\nfunction formatDrugShortage(shortage: DrugShortage): FormattedDrugShortage {\n return {\n genericName: shortage.generic_name,\n proprietaryName: shortage.proprietary_name,\n status: shortage.status,\n description: truncateText(shortage.description),\n initialPostingDate: shortage.initial_posting_date,\n resolvedShortageDate: shortage.resolved_shortage_date,\n }\n}\n\nexport async function handleSearchDrugShortages(\n params: DrugShortagesParams,\n): Promise<FDAToolResponse<FormattedDrugShortage[]>> {\n loggers.tools(\"searchDrugShortages\", params)\n\n try {\n const searchTerms: Array<{ field: string; value?: string }> = [\n { field: \"generic_name\", value: params.genericName },\n { field: \"status\", value: params.status },\n ]\n\n const searchQuery = buildSearchQuery(searchTerms)\n\n const searchParams: SearchParams = {\n search: searchQuery || undefined,\n limit: params.limit,\n skip: params.skip,\n }\n\n const response = await fdaAPIClient.searchDrugShortages(searchParams)\n const results = response.results ?? []\n\n return {\n success: true,\n data: results.map(formatDrugShortage),\n totalResults: response.meta?.results?.total,\n displayedResults: results.length,\n searchParams,\n apiUsage: fdaAPIClient.getRateLimitInfo(),\n }\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : String(error),\n }\n }\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{z as e}from"zod";const t={limit:e.number().int().min(1).max(100).optional().describe(`Maximum results to return (1-100, default 10)`),skip:e.number().int().min(0).optional().describe(`Number of results to skip for pagination`)},n={dateFrom:e.string().optional().describe(`Start date (YYYY-MM-DD or YYYYMMDD format)`),dateTo:e.string().optional().describe(`End date (YYYY-MM-DD or YYYYMMDD format)`)},r=e.object({drugName:e.string().optional().describe(`Drug or product name to search`),reaction:e.string().optional().describe(`Adverse reaction to search (e.g., 'headache', 'nausea')`),manufacturer:e.string().optional().describe(`Drug manufacturer name`),serious:e.boolean().optional().describe(`Filter for serious adverse events only`),...n,...t}),i=e.object({drugName:e.string().optional().describe(`Drug brand or generic name`),indication:e.string().optional().describe(`Medical indication or use case`),activeIngredient:e.string().optional().describe(`Active ingredient/substance name`),route:e.string().optional().describe(`Route of administration (e.g., 'oral', 'intravenous')`),...t}),a=e.object({productNdc:e.string().optional().describe(`National Drug Code (NDC)`),brandName:e.string().optional().describe(`Drug brand name`),genericName:e.string().optional().describe(`Drug generic name`),labelerName:e.string().optional().describe(`Drug labeler/manufacturer name`),dosageForm:e.string().optional().describe(`Dosage form (e.g., 'tablet', 'capsule', 'injection')`),route:e.string().optional().describe(`Route of administration`),...t}),o=e.object({recallingFirm:e.string().optional().describe(`Name of the recalling company`),classification:e.enum([`Class I`,`Class II`,`Class III`]).optional().describe(`Recall classification (I=most serious, III=least)`),status:e.enum([`Ongoing`,`Completed`,`Terminated`,`Pending`]).optional().describe(`Recall status`),state:e.string().optional().describe(`US state code (e.g., 'CA', 'NY')`),...n,...t}),s=e.object({sponsorName:e.string().optional().describe(`Drug sponsor/company name`),applicationNumber:e.string().optional().describe(`FDA application number (e.g., 'NDA012345')`),brandName:e.string().optional().describe(`Drug brand name`),marketingStatus:e.string().optional().describe(`Marketing status (e.g., 'Prescription', 'OTC')`),...t}),c=e.object({genericName:e.string().optional().describe(`Generic drug name`),status:e.enum([`Current`,`Resolved`]).optional().describe(`Shortage status`),...t}),l=e.object({deviceName:e.string().optional().describe(`Device name to search`),applicant:e.string().optional().describe(`Applicant/company name`),productCode:e.string().optional().describe(`FDA product code`),clearanceType:e.string().optional().describe(`Clearance type (e.g., 'Traditional', 'Special')`),decisionDateFrom:e.string().optional().describe(`Decision date range start (YYYY-MM-DD)`),decisionDateTo:e.string().optional().describe(`Decision date range end (YYYY-MM-DD)`),...t}),u=e.object({deviceName:e.string().optional().describe(`Device name to search`),deviceClass:e.enum([`1`,`2`,`3`]).optional().describe(`Device class (1=lowest risk, 3=highest)`),medicalSpecialty:e.string().optional().describe(`Medical specialty code`),productCode:e.string().optional().describe(`FDA product code`),regulationNumber:e.string().optional().describe(`CFR regulation number`),...t}),d=e.object({deviceName:e.string().optional().describe(`Device generic name`),brandName:e.string().optional().describe(`Device brand name`),manufacturerName:e.string().optional().describe(`Device manufacturer name`),eventType:e.enum([`Injury`,`Malfunction`,`Death`,`Other`]).optional().describe(`Type of adverse event`),...n,...t}),f=e.object({recallingFirm:e.string().optional().describe(`Name of the recalling company`),productDescription:e.string().optional().describe(`Product description keywords`),classification:e.enum([`Class I`,`Class II`,`Class III`]).optional().describe(`Recall classification (I=most serious)`),status:e.enum([`Ongoing`,`Completed`,`Terminated`,`Pending`]).optional().describe(`Recall status`),...n,...t}),p={searchDrugAdverseEvents:r,searchDrugLabels:i,searchDrugNDC:a,searchDrugEnforcement:o,searchDrugsFDA:s,searchDrugShortages:c,searchDevice510K:l,searchDeviceClassifications:u,searchDeviceAdverseEvents:d,searchDeviceEnforcement:f};export{r as a,a as c,p as d,f as i,c as l,d as n,o,u as r,i as s,l as t,s as u};
2
- //# sourceMappingURL=tools-Bh3wjIRH.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tools-Bh3wjIRH.js","names":[],"sources":["../src/tools/index.ts"],"sourcesContent":["/**\n * MCP Tool Definitions\n * Zod schemas for all FDA MCP tools\n */\n\nimport { z } from \"zod\"\n\n// Common pagination schema\nconst paginationSchema = {\n limit: z.number().int().min(1).max(100).optional().describe(\"Maximum results to return (1-100, default 10)\"),\n skip: z.number().int().min(0).optional().describe(\"Number of results to skip for pagination\"),\n}\n\n// Date range schema\nconst dateRangeSchema = {\n dateFrom: z.string().optional().describe(\"Start date (YYYY-MM-DD or YYYYMMDD format)\"),\n dateTo: z.string().optional().describe(\"End date (YYYY-MM-DD or YYYYMMDD format)\"),\n}\n\n// Drug Tool Schemas\n\nexport const searchDrugAdverseEventsSchema = z.object({\n drugName: z.string().optional().describe(\"Drug or product name to search\"),\n reaction: z.string().optional().describe(\"Adverse reaction to search (e.g., 'headache', 'nausea')\"),\n manufacturer: z.string().optional().describe(\"Drug manufacturer name\"),\n serious: z.boolean().optional().describe(\"Filter for serious adverse events only\"),\n ...dateRangeSchema,\n ...paginationSchema,\n})\n\nexport const searchDrugLabelsSchema = z.object({\n drugName: z.string().optional().describe(\"Drug brand or generic name\"),\n indication: z.string().optional().describe(\"Medical indication or use case\"),\n activeIngredient: z.string().optional().describe(\"Active ingredient/substance name\"),\n route: z.string().optional().describe(\"Route of administration (e.g., 'oral', 'intravenous')\"),\n ...paginationSchema,\n})\n\nexport const searchDrugNDCSchema = z.object({\n productNdc: z.string().optional().describe(\"National Drug Code (NDC)\"),\n brandName: z.string().optional().describe(\"Drug brand name\"),\n genericName: z.string().optional().describe(\"Drug generic name\"),\n labelerName: z.string().optional().describe(\"Drug labeler/manufacturer name\"),\n dosageForm: z.string().optional().describe(\"Dosage form (e.g., 'tablet', 'capsule', 'injection')\"),\n route: z.string().optional().describe(\"Route of administration\"),\n ...paginationSchema,\n})\n\nexport const searchDrugEnforcementSchema = z.object({\n recallingFirm: z.string().optional().describe(\"Name of the recalling company\"),\n classification: z\n .enum([\"Class I\", \"Class II\", \"Class III\"])\n .optional()\n .describe(\"Recall classification (I=most serious, III=least)\"),\n status: z.enum([\"Ongoing\", \"Completed\", \"Terminated\", \"Pending\"]).optional().describe(\"Recall status\"),\n state: z.string().optional().describe(\"US state code (e.g., 'CA', 'NY')\"),\n ...dateRangeSchema,\n ...paginationSchema,\n})\n\nexport const searchDrugsFDASchema = z.object({\n sponsorName: z.string().optional().describe(\"Drug sponsor/company name\"),\n applicationNumber: z.string().optional().describe(\"FDA application number (e.g., 'NDA012345')\"),\n brandName: z.string().optional().describe(\"Drug brand name\"),\n marketingStatus: z.string().optional().describe(\"Marketing status (e.g., 'Prescription', 'OTC')\"),\n ...paginationSchema,\n})\n\nexport const searchDrugShortagesSchema = z.object({\n genericName: z.string().optional().describe(\"Generic drug name\"),\n status: z.enum([\"Current\", \"Resolved\"]).optional().describe(\"Shortage status\"),\n ...paginationSchema,\n})\n\n// Device Tool Schemas\n\nexport const searchDevice510KSchema = z.object({\n deviceName: z.string().optional().describe(\"Device name to search\"),\n applicant: z.string().optional().describe(\"Applicant/company name\"),\n productCode: z.string().optional().describe(\"FDA product code\"),\n clearanceType: z.string().optional().describe(\"Clearance type (e.g., 'Traditional', 'Special')\"),\n decisionDateFrom: z.string().optional().describe(\"Decision date range start (YYYY-MM-DD)\"),\n decisionDateTo: z.string().optional().describe(\"Decision date range end (YYYY-MM-DD)\"),\n ...paginationSchema,\n})\n\nexport const searchDeviceClassificationsSchema = z.object({\n deviceName: z.string().optional().describe(\"Device name to search\"),\n deviceClass: z.enum([\"1\", \"2\", \"3\"]).optional().describe(\"Device class (1=lowest risk, 3=highest)\"),\n medicalSpecialty: z.string().optional().describe(\"Medical specialty code\"),\n productCode: z.string().optional().describe(\"FDA product code\"),\n regulationNumber: z.string().optional().describe(\"CFR regulation number\"),\n ...paginationSchema,\n})\n\nexport const searchDeviceAdverseEventsSchema = z.object({\n deviceName: z.string().optional().describe(\"Device generic name\"),\n brandName: z.string().optional().describe(\"Device brand name\"),\n manufacturerName: z.string().optional().describe(\"Device manufacturer name\"),\n eventType: z.enum([\"Injury\", \"Malfunction\", \"Death\", \"Other\"]).optional().describe(\"Type of adverse event\"),\n ...dateRangeSchema,\n ...paginationSchema,\n})\n\nexport const searchDeviceEnforcementSchema = z.object({\n recallingFirm: z.string().optional().describe(\"Name of the recalling company\"),\n productDescription: z.string().optional().describe(\"Product description keywords\"),\n classification: z\n .enum([\"Class I\", \"Class II\", \"Class III\"])\n .optional()\n .describe(\"Recall classification (I=most serious)\"),\n status: z.enum([\"Ongoing\", \"Completed\", \"Terminated\", \"Pending\"]).optional().describe(\"Recall status\"),\n ...dateRangeSchema,\n ...paginationSchema,\n})\n\n// Export all schemas for use in tool registration\nexport const toolSchemas = {\n searchDrugAdverseEvents: searchDrugAdverseEventsSchema,\n searchDrugLabels: searchDrugLabelsSchema,\n searchDrugNDC: searchDrugNDCSchema,\n searchDrugEnforcement: searchDrugEnforcementSchema,\n searchDrugsFDA: searchDrugsFDASchema,\n searchDrugShortages: searchDrugShortagesSchema,\n searchDevice510K: searchDevice510KSchema,\n searchDeviceClassifications: searchDeviceClassificationsSchema,\n searchDeviceAdverseEvents: searchDeviceAdverseEventsSchema,\n searchDeviceEnforcement: searchDeviceEnforcementSchema,\n}\n\n// Export inferred types\nexport type SearchDrugAdverseEventsParams = z.infer<typeof searchDrugAdverseEventsSchema>\nexport type SearchDrugLabelsParams = z.infer<typeof searchDrugLabelsSchema>\nexport type SearchDrugNDCParams = z.infer<typeof searchDrugNDCSchema>\nexport type SearchDrugEnforcementParams = z.infer<typeof searchDrugEnforcementSchema>\nexport type SearchDrugsFDAParams = z.infer<typeof searchDrugsFDASchema>\nexport type SearchDrugShortagesParams = z.infer<typeof searchDrugShortagesSchema>\nexport type SearchDevice510KParams = z.infer<typeof searchDevice510KSchema>\nexport type SearchDeviceClassificationsParams = z.infer<typeof searchDeviceClassificationsSchema>\nexport type SearchDeviceAdverseEventsParams = z.infer<typeof searchDeviceAdverseEventsSchema>\nexport type SearchDeviceEnforcementParams = z.infer<typeof searchDeviceEnforcementSchema>\n"],"mappings":"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"}