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 +110 -19
- package/dist/{device-handlers-D01LfIJk.js → device-handlers-D8AD5oIk.js} +2 -2
- package/dist/device-handlers-D8AD5oIk.js.map +1 -0
- package/dist/drug-handlers-D5VxbBCL.js +2 -0
- package/dist/drug-handlers-D5VxbBCL.js.map +1 -0
- package/dist/handlers/device-handlers.d.ts +1 -0
- package/dist/handlers/device-handlers.js +1 -1
- package/dist/handlers/drug-handlers.d.ts +16 -0
- package/dist/handlers/drug-handlers.js +1 -1
- package/dist/index.js +1 -1
- package/dist/lib.js +1 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/index.d.ts +33 -1
- package/dist/tools/index.js +1 -1
- package/dist/tools-3M3lSxQv.js +2 -0
- package/dist/tools-3M3lSxQv.js.map +1 -0
- package/dist/types/fda.d.ts +1 -0
- package/package.json +3 -3
- package/dist/device-handlers-D01LfIJk.js.map +0 -1
- package/dist/drug-handlers-Fz_6NLl5.js +0 -2
- package/dist/drug-handlers-Fz_6NLl5.js.map +0 -1
- package/dist/tools-Bh3wjIRH.js +0 -2
- package/dist/tools-Bh3wjIRH.js.map +0 -1
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
|
|
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
|
-
//
|
|
176
|
-
const
|
|
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
|
-
|
|
198
|
-
|
|
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(
|
|
2
|
-
//# sourceMappingURL=device-handlers-
|
|
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":"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"}
|
|
@@ -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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
package/dist/server.js.map
CHANGED
|
@@ -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 \"
|
|
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"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -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
|
package/dist/tools/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,c as t,d as n,
|
|
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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"}
|
package/dist/types/fda.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openfda-mcp-server",
|
|
3
|
-
"version": "1.
|
|
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/
|
|
16
|
+
"homepage": "https://github.com/sapientsai/openfda-mcp-server",
|
|
17
17
|
"repository": {
|
|
18
18
|
"type": "git",
|
|
19
|
-
"url": "https://github.com/
|
|
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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"}
|
package/dist/tools-Bh3wjIRH.js
DELETED
|
@@ -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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"}
|