@cyanheads/openfda-mcp-server 0.1.6
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/CLAUDE.md +248 -0
- package/Dockerfile +99 -0
- package/LICENSE +190 -0
- package/README.md +281 -0
- package/dist/config/server-config.d.ts +14 -0
- package/dist/config/server-config.d.ts.map +1 -0
- package/dist/config/server-config.js +22 -0
- package/dist/config/server-config.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/count.tool.d.ts +42 -0
- package/dist/mcp-server/tools/definitions/count.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/count.tool.js +106 -0
- package/dist/mcp-server/tools/definitions/count.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/get-drug-label.tool.d.ts +21 -0
- package/dist/mcp-server/tools/definitions/get-drug-label.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/get-drug-label.tool.js +102 -0
- package/dist/mcp-server/tools/definitions/get-drug-label.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/index.d.ts +68 -0
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/index.js +21 -0
- package/dist/mcp-server/tools/definitions/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/lookup-ndc.tool.d.ts +21 -0
- package/dist/mcp-server/tools/definitions/lookup-ndc.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/lookup-ndc.tool.js +101 -0
- package/dist/mcp-server/tools/definitions/lookup-ndc.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-adverse-events.tool.d.ts +26 -0
- package/dist/mcp-server/tools/definitions/search-adverse-events.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-adverse-events.tool.js +147 -0
- package/dist/mcp-server/tools/definitions/search-adverse-events.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-device-clearances.tool.d.ts +25 -0
- package/dist/mcp-server/tools/definitions/search-device-clearances.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-device-clearances.tool.js +108 -0
- package/dist/mcp-server/tools/definitions/search-device-clearances.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-drug-approvals.tool.d.ts +23 -0
- package/dist/mcp-server/tools/definitions/search-drug-approvals.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-drug-approvals.tool.js +136 -0
- package/dist/mcp-server/tools/definitions/search-drug-approvals.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/search-recalls.tool.d.ts +30 -0
- package/dist/mcp-server/tools/definitions/search-recalls.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/search-recalls.tool.js +105 -0
- package/dist/mcp-server/tools/definitions/search-recalls.tool.js.map +1 -0
- package/dist/services/openfda/openfda-service.d.ts +25 -0
- package/dist/services/openfda/openfda-service.d.ts.map +1 -0
- package/dist/services/openfda/openfda-service.js +111 -0
- package/dist/services/openfda/openfda-service.js.map +1 -0
- package/dist/services/openfda/types.d.ts +30 -0
- package/dist/services/openfda/types.d.ts.map +1 -0
- package/dist/services/openfda/types.js +6 -0
- package/dist/services/openfda/types.js.map +1 -0
- package/package.json +88 -0
- package/server.json +98 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Barrel export for all openFDA tool definitions.
|
|
3
|
+
* @module mcp-server/tools/definitions
|
|
4
|
+
*/
|
|
5
|
+
export declare const allToolDefinitions: (import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
6
|
+
endpoint: import("zod").ZodEnum<{
|
|
7
|
+
"drug/event": "drug/event";
|
|
8
|
+
"drug/label": "drug/label";
|
|
9
|
+
"drug/enforcement": "drug/enforcement";
|
|
10
|
+
"drug/ndc": "drug/ndc";
|
|
11
|
+
"drug/drugsfda": "drug/drugsfda";
|
|
12
|
+
"drug/shortages": "drug/shortages";
|
|
13
|
+
"food/event": "food/event";
|
|
14
|
+
"food/enforcement": "food/enforcement";
|
|
15
|
+
"device/event": "device/event";
|
|
16
|
+
"device/510k": "device/510k";
|
|
17
|
+
"device/pma": "device/pma";
|
|
18
|
+
"device/recall": "device/recall";
|
|
19
|
+
"device/enforcement": "device/enforcement";
|
|
20
|
+
"device/classification": "device/classification";
|
|
21
|
+
"device/registrationlisting": "device/registrationlisting";
|
|
22
|
+
"device/udi": "device/udi";
|
|
23
|
+
"device/covid19serology": "device/covid19serology";
|
|
24
|
+
"animalandveterinary/event": "animalandveterinary/event";
|
|
25
|
+
"other/substance": "other/substance";
|
|
26
|
+
}>;
|
|
27
|
+
count: import("zod").ZodString;
|
|
28
|
+
search: import("zod").ZodOptional<import("zod").ZodString>;
|
|
29
|
+
limit: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
30
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
31
|
+
meta: import("zod").ZodObject<{
|
|
32
|
+
lastUpdated: import("zod").ZodString;
|
|
33
|
+
}, import("zod/v4/core").$strip>;
|
|
34
|
+
results: import("zod").ZodArray<import("zod").ZodObject<{
|
|
35
|
+
term: import("zod").ZodString;
|
|
36
|
+
count: import("zod").ZodNumber;
|
|
37
|
+
}, import("zod/v4/core").$strip>>;
|
|
38
|
+
message: import("zod").ZodOptional<import("zod").ZodString>;
|
|
39
|
+
}, import("zod/v4/core").$strip>> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
40
|
+
search: import("zod").ZodString;
|
|
41
|
+
sort: import("zod").ZodOptional<import("zod").ZodString>;
|
|
42
|
+
limit: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
43
|
+
skip: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
44
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
45
|
+
meta: import("zod").ZodObject<{
|
|
46
|
+
total: import("zod").ZodNumber;
|
|
47
|
+
skip: import("zod").ZodNumber;
|
|
48
|
+
limit: import("zod").ZodNumber;
|
|
49
|
+
lastUpdated: import("zod").ZodString;
|
|
50
|
+
}, import("zod/v4/core").$strip>;
|
|
51
|
+
results: import("zod").ZodArray<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>>;
|
|
52
|
+
message: import("zod").ZodOptional<import("zod").ZodString>;
|
|
53
|
+
}, import("zod/v4/core").$strip>> | import("@cyanheads/mcp-ts-core").ToolDefinition<import("zod").ZodObject<{
|
|
54
|
+
search: import("zod").ZodOptional<import("zod").ZodString>;
|
|
55
|
+
sort: import("zod").ZodOptional<import("zod").ZodString>;
|
|
56
|
+
limit: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
57
|
+
skip: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
58
|
+
}, import("zod/v4/core").$strip>, import("zod").ZodObject<{
|
|
59
|
+
meta: import("zod").ZodObject<{
|
|
60
|
+
total: import("zod").ZodNumber;
|
|
61
|
+
skip: import("zod").ZodNumber;
|
|
62
|
+
limit: import("zod").ZodNumber;
|
|
63
|
+
lastUpdated: import("zod").ZodString;
|
|
64
|
+
}, import("zod/v4/core").$strip>;
|
|
65
|
+
results: import("zod").ZodArray<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>>;
|
|
66
|
+
message: import("zod").ZodOptional<import("zod").ZodString>;
|
|
67
|
+
}, import("zod/v4/core").$strip>>)[];
|
|
68
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oCAQ9B,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Barrel export for all openFDA tool definitions.
|
|
3
|
+
* @module mcp-server/tools/definitions
|
|
4
|
+
*/
|
|
5
|
+
import { countTool } from './count.tool.js';
|
|
6
|
+
import { getDrugLabelTool } from './get-drug-label.tool.js';
|
|
7
|
+
import { lookupNdcTool } from './lookup-ndc.tool.js';
|
|
8
|
+
import { searchAdverseEventsTool } from './search-adverse-events.tool.js';
|
|
9
|
+
import { searchDeviceClearancesTool } from './search-device-clearances.tool.js';
|
|
10
|
+
import { searchDrugApprovalsTool } from './search-drug-approvals.tool.js';
|
|
11
|
+
import { searchRecallsTool } from './search-recalls.tool.js';
|
|
12
|
+
export const allToolDefinitions = [
|
|
13
|
+
searchAdverseEventsTool,
|
|
14
|
+
searchRecallsTool,
|
|
15
|
+
countTool,
|
|
16
|
+
getDrugLabelTool,
|
|
17
|
+
searchDrugApprovalsTool,
|
|
18
|
+
searchDeviceClearancesTool,
|
|
19
|
+
lookupNdcTool,
|
|
20
|
+
];
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAChF,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,uBAAuB;IACvB,iBAAiB;IACjB,SAAS;IACT,gBAAgB;IAChB,uBAAuB;IACvB,0BAA0B;IAC1B,aAAa;CACd,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview MCP tool for looking up drugs in the openFDA NDC (National Drug Code) Directory.
|
|
3
|
+
* @module mcp-server/tools/definitions/lookup-ndc
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
export declare const lookupNdcTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
7
|
+
search: z.ZodString;
|
|
8
|
+
sort: z.ZodOptional<z.ZodString>;
|
|
9
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
10
|
+
skip: z.ZodDefault<z.ZodNumber>;
|
|
11
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
12
|
+
meta: z.ZodObject<{
|
|
13
|
+
total: z.ZodNumber;
|
|
14
|
+
skip: z.ZodNumber;
|
|
15
|
+
limit: z.ZodNumber;
|
|
16
|
+
lastUpdated: z.ZodString;
|
|
17
|
+
}, z.core.$strip>;
|
|
18
|
+
results: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
19
|
+
message: z.ZodOptional<z.ZodString>;
|
|
20
|
+
}, z.core.$strip>>;
|
|
21
|
+
//# sourceMappingURL=lookup-ndc.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup-ndc.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/lookup-ndc.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAGjD,eAAO,MAAM,aAAa;;;;;;;;;;;;;;kBA8GxB,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview MCP tool for looking up drugs in the openFDA NDC (National Drug Code) Directory.
|
|
3
|
+
* @module mcp-server/tools/definitions/lookup-ndc
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { getOpenFdaService } from '../../../services/openfda/openfda-service.js';
|
|
7
|
+
export const lookupNdcTool = tool('openfda_lookup_ndc', {
|
|
8
|
+
description: 'Look up drugs in the NDC (National Drug Code) Directory. Identify drug products by NDC code, find active ingredients, packaging details, or manufacturer info.',
|
|
9
|
+
annotations: { readOnlyHint: true },
|
|
10
|
+
input: z.object({
|
|
11
|
+
search: z
|
|
12
|
+
.string()
|
|
13
|
+
.describe('openFDA search query. Examples: product_ndc:"0363-0218", brand_name:"aspirin", generic_name:"metformin", openfda.manufacturer_name:"walgreen", active_ingredients.name:"ASPIRIN"'),
|
|
14
|
+
sort: z
|
|
15
|
+
.string()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe('Sort field and direction. Example: listing_expiration_date:desc'),
|
|
18
|
+
limit: z
|
|
19
|
+
.number()
|
|
20
|
+
.min(1)
|
|
21
|
+
.max(1000)
|
|
22
|
+
.default(10)
|
|
23
|
+
.describe('Maximum number of records to return (1-1000, default 10)'),
|
|
24
|
+
skip: z
|
|
25
|
+
.number()
|
|
26
|
+
.min(0)
|
|
27
|
+
.max(25000)
|
|
28
|
+
.default(0)
|
|
29
|
+
.describe('Number of records to skip for pagination (0-25000, default 0)'),
|
|
30
|
+
}),
|
|
31
|
+
output: z.object({
|
|
32
|
+
meta: z
|
|
33
|
+
.object({
|
|
34
|
+
total: z.number().describe('Total matching records'),
|
|
35
|
+
skip: z.number().describe('Pagination offset'),
|
|
36
|
+
limit: z.number().describe('Records returned'),
|
|
37
|
+
lastUpdated: z.string().describe('Dataset last updated date'),
|
|
38
|
+
})
|
|
39
|
+
.describe('Response metadata'),
|
|
40
|
+
results: z
|
|
41
|
+
.array(z.record(z.string(), z.any()))
|
|
42
|
+
.describe('NDC directory records with product and packaging details'),
|
|
43
|
+
message: z
|
|
44
|
+
.string()
|
|
45
|
+
.optional()
|
|
46
|
+
.describe('Guidance when results are empty or search can be refined'),
|
|
47
|
+
}),
|
|
48
|
+
async handler(input, ctx) {
|
|
49
|
+
const service = getOpenFdaService();
|
|
50
|
+
const response = await service.query('drug/ndc', input, ctx);
|
|
51
|
+
ctx.log.info('NDC lookup completed', {
|
|
52
|
+
search: input.search,
|
|
53
|
+
total: response.meta.total,
|
|
54
|
+
returned: response.results.length,
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
meta: response.meta,
|
|
58
|
+
results: response.results,
|
|
59
|
+
message: response.results.length === 0
|
|
60
|
+
? 'No NDC records matched the query. Try broadening the search — use brand_name, generic_name, or active_ingredients.name fields.'
|
|
61
|
+
: undefined,
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
format: (result) => {
|
|
65
|
+
if (result.results.length === 0) {
|
|
66
|
+
return [{ type: 'text', text: result.message ?? 'No NDC records found.' }];
|
|
67
|
+
}
|
|
68
|
+
const lines = [
|
|
69
|
+
`**${result.meta.total.toLocaleString()} total results** (showing ${result.results.length}, skip: ${result.meta.skip}) | Data updated: ${result.meta.lastUpdated}\n`,
|
|
70
|
+
];
|
|
71
|
+
for (const r of result.results) {
|
|
72
|
+
const title = r.brand_name ?? r.generic_name ?? r.product_ndc ?? 'Unknown';
|
|
73
|
+
lines.push(`### ${title}`);
|
|
74
|
+
lines.push(`**NDC:** ${r.product_ndc ?? 'N/A'} | **Labeler:** ${r.labeler_name ?? 'N/A'}`);
|
|
75
|
+
if (r.generic_name && r.brand_name)
|
|
76
|
+
lines.push(`**Generic:** ${r.generic_name}`);
|
|
77
|
+
if (r.dosage_form)
|
|
78
|
+
lines.push(`**Form:** ${r.dosage_form}${r.route ? ` | **Route:** ${(Array.isArray(r.route) ? r.route : [r.route]).join(', ')}` : ''}`);
|
|
79
|
+
if (r.marketing_category)
|
|
80
|
+
lines.push(`**Category:** ${r.marketing_category}`);
|
|
81
|
+
const ingredients = r.active_ingredients ?? [];
|
|
82
|
+
if (ingredients.length > 0) {
|
|
83
|
+
lines.push(`**Active ingredients:** ${ingredients.map((i) => `${i.name}${i.strength ? ` (${i.strength})` : ''}`).join(', ')}`);
|
|
84
|
+
}
|
|
85
|
+
const packaging = r.packaging ?? [];
|
|
86
|
+
if (packaging.length > 0) {
|
|
87
|
+
lines.push(`**Packaging:**`);
|
|
88
|
+
for (const p of packaging.slice(0, 5)) {
|
|
89
|
+
lines.push(`- ${p.package_ndc ?? ''}: ${p.description ?? 'N/A'}`);
|
|
90
|
+
}
|
|
91
|
+
if (packaging.length > 5)
|
|
92
|
+
lines.push(`- ... and ${packaging.length - 5} more`);
|
|
93
|
+
}
|
|
94
|
+
if (r.listing_expiration_date)
|
|
95
|
+
lines.push(`**Listing expires:** ${r.listing_expiration_date}`);
|
|
96
|
+
lines.push('');
|
|
97
|
+
}
|
|
98
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=lookup-ndc.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup-ndc.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/lookup-ndc.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool definition for searching openFDA adverse event reports across drugs, food, and devices.
|
|
3
|
+
* @module mcp-server/tools/definitions/search-adverse-events
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
export declare const searchAdverseEventsTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
7
|
+
category: z.ZodEnum<{
|
|
8
|
+
drug: "drug";
|
|
9
|
+
food: "food";
|
|
10
|
+
device: "device";
|
|
11
|
+
}>;
|
|
12
|
+
search: z.ZodOptional<z.ZodString>;
|
|
13
|
+
sort: z.ZodOptional<z.ZodString>;
|
|
14
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
15
|
+
skip: z.ZodDefault<z.ZodNumber>;
|
|
16
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
17
|
+
meta: z.ZodObject<{
|
|
18
|
+
total: z.ZodNumber;
|
|
19
|
+
skip: z.ZodNumber;
|
|
20
|
+
limit: z.ZodNumber;
|
|
21
|
+
lastUpdated: z.ZodString;
|
|
22
|
+
}, z.core.$strip>;
|
|
23
|
+
results: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
24
|
+
message: z.ZodOptional<z.ZodString>;
|
|
25
|
+
}, z.core.$strip>>;
|
|
26
|
+
//# sourceMappingURL=search-adverse-events.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-adverse-events.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-adverse-events.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAGjD,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;kBAuKlC,CAAC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool definition for searching openFDA adverse event reports across drugs, food, and devices.
|
|
3
|
+
* @module mcp-server/tools/definitions/search-adverse-events
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { getOpenFdaService } from '../../../services/openfda/openfda-service.js';
|
|
7
|
+
export const searchAdverseEventsTool = tool('openfda_search_adverse_events', {
|
|
8
|
+
description: 'Search adverse event reports across drugs, food, and devices. Use to investigate safety signals, find reports for a specific product, or explore reactions by demographics.',
|
|
9
|
+
annotations: { readOnlyHint: true },
|
|
10
|
+
input: z.object({
|
|
11
|
+
category: z
|
|
12
|
+
.enum(['drug', 'food', 'device'])
|
|
13
|
+
.describe('Product category — each has different field schemas in the response'),
|
|
14
|
+
search: z
|
|
15
|
+
.string()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe('Elasticsearch query string. Examples: patient.drug.medicinalproduct:"aspirin", patient.reaction.reactionmeddrapt:"nausea" AND serious:"1". Omit to browse recent.'),
|
|
18
|
+
sort: z.string().optional().describe('Sort field and direction. Example: receivedate:desc'),
|
|
19
|
+
limit: z
|
|
20
|
+
.number()
|
|
21
|
+
.min(1)
|
|
22
|
+
.max(1000)
|
|
23
|
+
.default(10)
|
|
24
|
+
.describe('Maximum number of records to return (1-1000, default 10)'),
|
|
25
|
+
skip: z
|
|
26
|
+
.number()
|
|
27
|
+
.min(0)
|
|
28
|
+
.max(25000)
|
|
29
|
+
.default(0)
|
|
30
|
+
.describe('Number of records to skip for pagination (0-25000, default 0)'),
|
|
31
|
+
}),
|
|
32
|
+
output: z.object({
|
|
33
|
+
meta: z
|
|
34
|
+
.object({
|
|
35
|
+
total: z.number().describe('Total matching records in the database'),
|
|
36
|
+
skip: z.number().describe('Pagination offset'),
|
|
37
|
+
limit: z.number().describe('Records returned in this response'),
|
|
38
|
+
lastUpdated: z.string().describe('Dataset last updated date'),
|
|
39
|
+
})
|
|
40
|
+
.describe('Response metadata'),
|
|
41
|
+
results: z
|
|
42
|
+
.array(z.record(z.string(), z.any()))
|
|
43
|
+
.describe('Adverse event records — fields vary by category (drug: patient/reactions/drugs, device: device details/event type, food: products/outcomes)'),
|
|
44
|
+
message: z
|
|
45
|
+
.string()
|
|
46
|
+
.optional()
|
|
47
|
+
.describe('Guidance when results are empty or search can be refined'),
|
|
48
|
+
}),
|
|
49
|
+
async handler(input, ctx) {
|
|
50
|
+
const svc = getOpenFdaService();
|
|
51
|
+
const endpoint = `${input.category}/event`;
|
|
52
|
+
const response = await svc.query(endpoint, {
|
|
53
|
+
search: input.search,
|
|
54
|
+
sort: input.sort,
|
|
55
|
+
limit: input.limit,
|
|
56
|
+
skip: input.skip,
|
|
57
|
+
}, ctx);
|
|
58
|
+
ctx.log.info('Adverse event search completed', {
|
|
59
|
+
category: input.category,
|
|
60
|
+
total: response.meta.total,
|
|
61
|
+
returned: response.results.length,
|
|
62
|
+
});
|
|
63
|
+
if (response.results.length === 0) {
|
|
64
|
+
return {
|
|
65
|
+
...response,
|
|
66
|
+
message: `No adverse event reports matched${input.search ? ` search: ${input.search}` : ''} in ${input.category}/event. Try broadening filters, checking field names (use openfda.brand_name for product searches), or removing date constraints.`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return response;
|
|
70
|
+
},
|
|
71
|
+
format: (result) => {
|
|
72
|
+
if (result.results.length === 0) {
|
|
73
|
+
return [{ type: 'text', text: result.message ?? 'No results found.' }];
|
|
74
|
+
}
|
|
75
|
+
const lines = [
|
|
76
|
+
`**${result.meta.total.toLocaleString()} total results** (showing ${result.results.length}, skip: ${result.meta.skip}) | Data updated: ${result.meta.lastUpdated}\n`,
|
|
77
|
+
];
|
|
78
|
+
for (const r of result.results) {
|
|
79
|
+
// Drug adverse events
|
|
80
|
+
if (r.patient) {
|
|
81
|
+
const patient = r.patient;
|
|
82
|
+
const reactions = (patient.reaction ?? [])
|
|
83
|
+
.map((rx) => rx.reactionmeddrapt)
|
|
84
|
+
.filter(Boolean)
|
|
85
|
+
.join(', ');
|
|
86
|
+
const drugs = (patient.drug ?? [])
|
|
87
|
+
.map((d) => {
|
|
88
|
+
const char = d.drugcharacterization === '1'
|
|
89
|
+
? 'Suspect'
|
|
90
|
+
: d.drugcharacterization === '2'
|
|
91
|
+
? 'Concomitant'
|
|
92
|
+
: d.drugcharacterization === '3'
|
|
93
|
+
? 'Interacting'
|
|
94
|
+
: '';
|
|
95
|
+
return `${d.medicinalproduct ?? 'Unknown'}${char ? ` (${char})` : ''}`;
|
|
96
|
+
})
|
|
97
|
+
.join(', ');
|
|
98
|
+
lines.push(`### Report ${r.safetyreportid ?? 'N/A'}`);
|
|
99
|
+
lines.push(`**Date:** ${r.receivedate ?? 'N/A'} | **Serious:** ${r.serious === '1' ? 'Yes' : r.serious === '2' ? 'No' : (r.serious ?? 'N/A')}`);
|
|
100
|
+
if (patient.patientsex)
|
|
101
|
+
lines.push(`**Patient:** Sex ${patient.patientsex === '1' ? 'Male' : patient.patientsex === '2' ? 'Female' : patient.patientsex}`);
|
|
102
|
+
if (reactions)
|
|
103
|
+
lines.push(`**Reactions:** ${reactions}`);
|
|
104
|
+
if (drugs)
|
|
105
|
+
lines.push(`**Drugs:** ${drugs}`);
|
|
106
|
+
}
|
|
107
|
+
// Device adverse events
|
|
108
|
+
else if (r.device) {
|
|
109
|
+
lines.push(`### Report ${r.report_number ?? r.mdr_report_key ?? 'N/A'}`);
|
|
110
|
+
if (r.event_type)
|
|
111
|
+
lines.push(`**Event type:** ${r.event_type}`);
|
|
112
|
+
for (const d of Array.isArray(r.device) ? r.device : []) {
|
|
113
|
+
lines.push(`**Device:** ${d.brand_name ?? d.generic_name ?? 'Unknown'}${d.manufacturer_d_name ? ` by ${d.manufacturer_d_name}` : ''}`);
|
|
114
|
+
}
|
|
115
|
+
const texts = (r.mdr_text ?? [])
|
|
116
|
+
.slice(0, 2)
|
|
117
|
+
.map((t) => t.text)
|
|
118
|
+
.filter(Boolean);
|
|
119
|
+
if (texts.length) {
|
|
120
|
+
const narrative = texts.join(' ');
|
|
121
|
+
lines.push(`**Narrative:** ${narrative.length > 500 ? `${narrative.slice(0, 500)}...` : narrative}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Food adverse events
|
|
125
|
+
else if (r.products || r.reactions) {
|
|
126
|
+
lines.push(`### Report ${r.report_number ?? 'N/A'}`);
|
|
127
|
+
if (r.reactions)
|
|
128
|
+
lines.push(`**Reactions:** ${(Array.isArray(r.reactions) ? r.reactions : [r.reactions]).join(', ')}`);
|
|
129
|
+
if (r.outcomes)
|
|
130
|
+
lines.push(`**Outcomes:** ${(Array.isArray(r.outcomes) ? r.outcomes : [r.outcomes]).join(', ')}`);
|
|
131
|
+
const products = (r.products ?? [])
|
|
132
|
+
.map((p) => p.name_brand ?? p.industry_name ?? 'Unknown')
|
|
133
|
+
.join(', ');
|
|
134
|
+
if (products)
|
|
135
|
+
lines.push(`**Products:** ${products}`);
|
|
136
|
+
}
|
|
137
|
+
// Fallback
|
|
138
|
+
else {
|
|
139
|
+
lines.push(`### Record`);
|
|
140
|
+
lines.push(`\`\`\`json\n${JSON.stringify(r, null, 2).slice(0, 500)}\n\`\`\``);
|
|
141
|
+
}
|
|
142
|
+
lines.push('');
|
|
143
|
+
}
|
|
144
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
//# sourceMappingURL=search-adverse-events.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-adverse-events.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-adverse-events.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool for searching FDA device premarket notifications (510(k) clearances and PMA approvals).
|
|
3
|
+
* @module mcp-server/tools/definitions/search-device-clearances
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
export declare const searchDeviceClearancesTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
7
|
+
pathway: z.ZodEnum<{
|
|
8
|
+
"510k": "510k";
|
|
9
|
+
pma: "pma";
|
|
10
|
+
}>;
|
|
11
|
+
search: z.ZodOptional<z.ZodString>;
|
|
12
|
+
sort: z.ZodOptional<z.ZodString>;
|
|
13
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
14
|
+
skip: z.ZodDefault<z.ZodNumber>;
|
|
15
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
16
|
+
meta: z.ZodObject<{
|
|
17
|
+
total: z.ZodNumber;
|
|
18
|
+
skip: z.ZodNumber;
|
|
19
|
+
limit: z.ZodNumber;
|
|
20
|
+
lastUpdated: z.ZodString;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
results: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
23
|
+
message: z.ZodOptional<z.ZodString>;
|
|
24
|
+
}, z.core.$strip>>;
|
|
25
|
+
//# sourceMappingURL=search-device-clearances.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-device-clearances.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-device-clearances.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAGjD,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;kBA4HrC,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool for searching FDA device premarket notifications (510(k) clearances and PMA approvals).
|
|
3
|
+
* @module mcp-server/tools/definitions/search-device-clearances
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { getOpenFdaService } from '../../../services/openfda/openfda-service.js';
|
|
7
|
+
export const searchDeviceClearancesTool = tool('openfda_search_device_clearances', {
|
|
8
|
+
description: 'Search FDA device premarket notifications — 510(k) clearances and PMA approvals.',
|
|
9
|
+
annotations: { readOnlyHint: true },
|
|
10
|
+
input: z.object({
|
|
11
|
+
pathway: z
|
|
12
|
+
.enum(['510k', 'pma'])
|
|
13
|
+
.describe('Premarket pathway. 510(k) is most common (174K+ records). PMA is for higher-risk devices.'),
|
|
14
|
+
search: z
|
|
15
|
+
.string()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe('openFDA search query. Examples: applicant:"medtronic", advisory_committee_description:"cardiovascular", product_code:"DXN", openfda.device_name:"catheter". Omit to browse recent.'),
|
|
18
|
+
sort: z.string().optional().describe('Sort expression. Example: decision_date:desc.'),
|
|
19
|
+
limit: z
|
|
20
|
+
.number()
|
|
21
|
+
.min(1)
|
|
22
|
+
.max(1000)
|
|
23
|
+
.default(10)
|
|
24
|
+
.describe('Maximum number of records to return (1-1000).'),
|
|
25
|
+
skip: z.number().min(0).max(25000).default(0).describe('Pagination offset (0-25000).'),
|
|
26
|
+
}),
|
|
27
|
+
output: z.object({
|
|
28
|
+
meta: z
|
|
29
|
+
.object({
|
|
30
|
+
total: z.number().describe('Total matching records'),
|
|
31
|
+
skip: z.number().describe('Pagination offset'),
|
|
32
|
+
limit: z.number().describe('Records returned'),
|
|
33
|
+
lastUpdated: z.string().describe('Dataset last updated date'),
|
|
34
|
+
})
|
|
35
|
+
.describe('Response metadata'),
|
|
36
|
+
results: z
|
|
37
|
+
.array(z.record(z.string(), z.any()))
|
|
38
|
+
.describe('510(k) clearance or PMA approval records'),
|
|
39
|
+
message: z
|
|
40
|
+
.string()
|
|
41
|
+
.optional()
|
|
42
|
+
.describe('Guidance when results are empty or search can be refined'),
|
|
43
|
+
}),
|
|
44
|
+
async handler(input, ctx) {
|
|
45
|
+
const service = getOpenFdaService();
|
|
46
|
+
const response = await service.query(`device/${input.pathway}`, {
|
|
47
|
+
search: input.search,
|
|
48
|
+
sort: input.sort,
|
|
49
|
+
limit: input.limit,
|
|
50
|
+
skip: input.skip,
|
|
51
|
+
}, ctx);
|
|
52
|
+
ctx.log.info('Device clearance search completed', {
|
|
53
|
+
pathway: input.pathway,
|
|
54
|
+
total: response.meta.total,
|
|
55
|
+
returned: response.results.length,
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
meta: response.meta,
|
|
59
|
+
results: response.results,
|
|
60
|
+
message: response.results.length === 0
|
|
61
|
+
? 'No matching device clearances found. Try broadening the search — use applicant, product_code, advisory_committee_description, or openfda.device_name fields.'
|
|
62
|
+
: undefined,
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
format: (result) => {
|
|
66
|
+
if (result.results.length === 0) {
|
|
67
|
+
return [{ type: 'text', text: result.message ?? 'No device clearances found.' }];
|
|
68
|
+
}
|
|
69
|
+
const lines = [
|
|
70
|
+
`**${result.meta.total.toLocaleString()} total results** (showing ${result.results.length}, skip: ${result.meta.skip}) | Data updated: ${result.meta.lastUpdated}\n`,
|
|
71
|
+
];
|
|
72
|
+
for (const r of result.results) {
|
|
73
|
+
// 510(k)
|
|
74
|
+
if (r.k_number) {
|
|
75
|
+
lines.push(`### ${r.k_number}: ${r.device_name ?? 'Unknown device'}`);
|
|
76
|
+
lines.push(`**Applicant:** ${r.applicant ?? 'N/A'} | **Product code:** ${r.product_code ?? 'N/A'}`);
|
|
77
|
+
lines.push(`**Decision:** ${r.decision_description ?? 'N/A'} (${r.decision_date ?? 'N/A'})`);
|
|
78
|
+
if (r.advisory_committee_description)
|
|
79
|
+
lines.push(`**Advisory committee:** ${r.advisory_committee_description}`);
|
|
80
|
+
if (r.clearance_type)
|
|
81
|
+
lines.push(`**Clearance type:** ${r.clearance_type}`);
|
|
82
|
+
if (r.statement_or_summary) {
|
|
83
|
+
const text = String(r.statement_or_summary);
|
|
84
|
+
lines.push(`**Summary:** ${text.length > 500 ? `${text.slice(0, 500)}...` : text}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// PMA
|
|
88
|
+
else if (r.pma_number) {
|
|
89
|
+
const deviceLabel = r.trade_name ?? r.generic_name ?? '';
|
|
90
|
+
lines.push(`### ${r.pma_number}${deviceLabel ? `: ${deviceLabel}` : ''}`);
|
|
91
|
+
lines.push(`**Applicant:** ${r.applicant ?? 'N/A'} | **Product code:** ${r.product_code ?? 'N/A'}`);
|
|
92
|
+
lines.push(`**Decision:** ${r.decision_description ?? r.decision_code ?? 'N/A'} (${r.decision_date ?? 'N/A'})`);
|
|
93
|
+
if (r.advisory_committee_description)
|
|
94
|
+
lines.push(`**Advisory committee:** ${r.advisory_committee_description}`);
|
|
95
|
+
if (r.supplement_number)
|
|
96
|
+
lines.push(`**Supplement:** ${r.supplement_number}`);
|
|
97
|
+
}
|
|
98
|
+
// Fallback
|
|
99
|
+
else {
|
|
100
|
+
lines.push(`### Record`);
|
|
101
|
+
lines.push(`\`\`\`json\n${JSON.stringify(r, null, 2).slice(0, 500)}\n\`\`\``);
|
|
102
|
+
}
|
|
103
|
+
lines.push('');
|
|
104
|
+
}
|
|
105
|
+
return [{ type: 'text', text: lines.join('\n') }];
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=search-device-clearances.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-device-clearances.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-device-clearances.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tool for searching FDA drug application approvals (NDAs and ANDAs)
|
|
3
|
+
* via the Drugs@FDA endpoint.
|
|
4
|
+
* @module mcp-server/tools/definitions/search-drug-approvals
|
|
5
|
+
*/
|
|
6
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
7
|
+
/** Exported tool definition for searching drug approvals. */
|
|
8
|
+
export declare const searchDrugApprovalsTool: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
9
|
+
search: z.ZodOptional<z.ZodString>;
|
|
10
|
+
sort: z.ZodOptional<z.ZodString>;
|
|
11
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
12
|
+
skip: z.ZodDefault<z.ZodNumber>;
|
|
13
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
14
|
+
meta: z.ZodObject<{
|
|
15
|
+
total: z.ZodNumber;
|
|
16
|
+
skip: z.ZodNumber;
|
|
17
|
+
limit: z.ZodNumber;
|
|
18
|
+
lastUpdated: z.ZodString;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
results: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
|
21
|
+
message: z.ZodOptional<z.ZodString>;
|
|
22
|
+
}, z.core.$strip>>;
|
|
23
|
+
//# sourceMappingURL=search-drug-approvals.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-drug-approvals.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/search-drug-approvals.tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAGjD,6DAA6D;AAC7D,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;kBAoJlC,CAAC"}
|