drug_lookup
Retrieve drug label data, adverse events, and diagnosis codes using brand or generic names from OpenFDA.
Instructions
Look up drug information including label data, adverse events, and related diagnosis codes. Source: OpenFDA (public domain).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| drugName | Yes | Drug name (brand, generic, or substance — min 2 chars) | |
| searchField | No | Search field (default: brand_name) |
Implementation Reference
- src/tools.js:113-123 (schema)Zod schema and configuration for the 'drug_lookup' tool. Defines input parameters (drugName string, optional searchField enum), the OpenFDA endpoint '/agent/v1/drugs/lookup', description, and per-call price of $0.01.
// --- Drug Intelligence (OpenFDA — free, no license) --- { name: 'drug_lookup', description: 'Look up drug information including label data, adverse events, and related diagnosis codes. Source: OpenFDA (public domain).', price: '$0.01', endpoint: '/agent/v1/drugs/lookup', schema: { drugName: z.string().describe('Drug name (brand, generic, or substance — min 2 chars)'), searchField: z.enum(['brand_name', 'generic_name', 'product_ndc', 'substance_name']).optional().describe('Search field (default: brand_name)'), }, }, - src/index.js:19-61 (registration)The generic tool registration loop in createMcpServer(). For each MCP_TOOLS entry (including drug_lookup), it registers an MCP tool via s.tool(...) with a dynamic handler that POSTs request params to the tool's endpoint URL. This is where 'drug_lookup' gets registered with the MCP server.
for (const tool of MCP_TOOLS) { s.tool(tool.name, tool.description, tool.schema, async (params) => { const toolDef = getToolByName(tool.name); if (!toolDef) { return { content: [{ type: 'text', text: `Unknown tool: ${tool.name}` }], isError: true }; } try { const response = await fetch(`${API_BASE_URL}${toolDef.endpoint}`, { method: 'POST', headers: { 'Content-Type': 'application/json', ...(API_KEY && { 'X-API-Key': API_KEY }), 'X-Agent-ID': 'mcp-client', 'User-Agent': '@mymedi-ai/mcp-server/1.2.1', }, body: JSON.stringify(params), }); if (response.status === 402) { const paymentInfo = await response.json(); return { content: [{ type: 'text', text: JSON.stringify({ error: 'payment_required', message: `This tool costs ${toolDef.price} per call. Register at ${API_BASE_URL}/bot-marketplace/register for an API key with 10 free starter credits, or pay per call with on-chain USDC (no signup) via the x402 protocol.`, price: toolDef.price, register: `${API_BASE_URL}/bot-marketplace/register`, ...paymentInfo, }, null, 2) }], isError: true, }; } if (!response.ok) { const error = await response.json().catch(() => ({ message: response.statusText })); return { content: [{ type: 'text', text: JSON.stringify({ error: true, status: response.status, ...error }, null, 2) }], isError: true }; } const data = await response.json(); const creditsSpent = response.headers.get('X-Credits-Spent'); const creditsRemaining = response.headers.get('X-Credits-Remaining'); if (creditsSpent) { data._billing = { creditsSpent: parseInt(creditsSpent, 10), creditsRemaining: creditsRemaining ? parseInt(creditsRemaining, 10) : undefined, priceUSD: toolDef.price }; } return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] }; } catch (err) { return { content: [{ type: 'text', text: JSON.stringify({ error: true, message: err.message, hint: 'Ensure MCP_API_BASE_URL and MCP_API_KEY environment variables are set.' }, null, 2) }], isError: true }; } }); }