Skip to main content
Glama

get-drug-by-ndc

Retrieve detailed drug information from the OpenFDA database by entering a National Drug Code (NDC) in any standard format.

Instructions

Get drug information by National Drug Code (NDC). Accepts both product NDC (XXXXX-XXXX) and package NDC (XXXXX-XXXX-XX) formats. Also accepts NDC codes without dashes.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
ndcCodeYesNational Drug Code (NDC) - accepts formats: XXXXX-XXXX, XXXXX-XXXX-XX, or without dashes

Implementation Reference

  • The handler function that implements the core logic of the 'get-drug-by-ndc' tool. It normalizes the input NDC code, constructs an OpenFDA API query using product and/or package NDC, fetches the data, processes the results to extract relevant drug information and matching NDCs, and returns a formatted text response.
    async ({ ndcCode }) => { const { productNDC, packageNDC, isValid } = normalizeNDC(ndcCode); if (!isValid) { return { content: [{ type: "text", text: `Invalid NDC format: "${ndcCode}"\n\n✅ Accepted formats:\n• Product NDC: 12345-1234\n• Package NDC: 12345-1234-01\n• Without dashes: 123451234 or 12345123401`, }], }; } console.log(`Searching for NDC: input="${ndcCode}", productNDC="${productNDC}", packageNDC="${packageNDC}"`); // Try searching by product NDC first (most flexible) let searchQuery = `openfda.product_ndc:"${productNDC}"`; // If a specific package was requested, also search package NDC if (packageNDC) { searchQuery += `+OR+openfda.package_ndc:"${packageNDC}"`; } const url = new OpenFDABuilder() .context("label") .search(searchQuery) .limit(10) // Get multiple results since product NDC might have multiple packages .build(); const { data: drugData, error } = await makeOpenFDARequest<OpenFDAResponse>(url); if (error) { return { content: [{ type: "text", text: `Failed to retrieve drug data for NDC "${ndcCode}": ${error.message}`, }], }; } if (!drugData || !drugData.results || drugData.results.length === 0) { return { content: [{ type: "text", text: `No drug found with NDC "${ndcCode}" (product: ${productNDC}).\n\n💡 Tips:\n• Verify the NDC format\n• Try without the package suffix (e.g., use 12345-1234 instead of 12345-1234-01)\n• Check if this is an FDA-approved product`, }], }; } // Process results and group by product const results = drugData.results.map(drug => { const matchingProductNDCs = drug.openfda.product_ndc?.filter(ndc => ndc === productNDC ) || []; const matchingPackageNDCs = drug.openfda.package_ndc?.filter(ndc => packageNDC ? ndc === packageNDC : ndc.startsWith(productNDC) ) || []; return { // Basic drug information brand_name: drug.openfda.brand_name || [], generic_name: drug.openfda.generic_name || [], manufacturer_name: drug.openfda.manufacturer_name || [], product_type: drug.openfda.product_type || [], route: drug.openfda.route || [], substance_name: drug.openfda.substance_name || [], // NDC information matching_product_ndc: matchingProductNDCs, matching_package_ndc: matchingPackageNDCs, all_product_ndc: drug.openfda.product_ndc || [], all_package_ndc: drug.openfda.package_ndc || [], // Additional product details dosage_and_administration: drug.dosage_and_administration || [], package_label_principal_display_panel: drug.package_label_principal_display_panel || [], active_ingredient: drug.active_ingredient || [], purpose: drug.purpose || [] }; }); // Summary information const totalPackages = results.reduce((sum, result) => sum + result.matching_package_ndc.length, 0 ); const searchSummary = packageNDC ? `Searched for specific package NDC: ${packageNDC}` : `Searched for product NDC: ${productNDC} (all packages)`; return { content: [{ type: "text", text: `✅ Found ${results.length} drug(s) with ${totalPackages} package(s) for NDC "${ndcCode}"\n\n${searchSummary}\n\n${JSON.stringify(results, null, 2)}`, }], }; }
  • Zod input schema defining the 'ndcCode' parameter for the tool.
    { ndcCode: z.string().describe("National Drug Code (NDC) - accepts formats: XXXXX-XXXX, XXXXX-XXXX-XX, or without dashes") },
  • src/index.ts:371-474 (registration)
    Registration of the 'get-drug-by-ndc' tool with McpServer using server.tool(), including name, description, input schema, and inline handler function.
    server.tool( "get-drug-by-ndc", "Get drug information by National Drug Code (NDC). Accepts both product NDC (XXXXX-XXXX) and package NDC (XXXXX-XXXX-XX) formats. Also accepts NDC codes without dashes.", { ndcCode: z.string().describe("National Drug Code (NDC) - accepts formats: XXXXX-XXXX, XXXXX-XXXX-XX, or without dashes") }, async ({ ndcCode }) => { const { productNDC, packageNDC, isValid } = normalizeNDC(ndcCode); if (!isValid) { return { content: [{ type: "text", text: `Invalid NDC format: "${ndcCode}"\n\n✅ Accepted formats:\n• Product NDC: 12345-1234\n• Package NDC: 12345-1234-01\n• Without dashes: 123451234 or 12345123401`, }], }; } console.log(`Searching for NDC: input="${ndcCode}", productNDC="${productNDC}", packageNDC="${packageNDC}"`); // Try searching by product NDC first (most flexible) let searchQuery = `openfda.product_ndc:"${productNDC}"`; // If a specific package was requested, also search package NDC if (packageNDC) { searchQuery += `+OR+openfda.package_ndc:"${packageNDC}"`; } const url = new OpenFDABuilder() .context("label") .search(searchQuery) .limit(10) // Get multiple results since product NDC might have multiple packages .build(); const { data: drugData, error } = await makeOpenFDARequest<OpenFDAResponse>(url); if (error) { return { content: [{ type: "text", text: `Failed to retrieve drug data for NDC "${ndcCode}": ${error.message}`, }], }; } if (!drugData || !drugData.results || drugData.results.length === 0) { return { content: [{ type: "text", text: `No drug found with NDC "${ndcCode}" (product: ${productNDC}).\n\n💡 Tips:\n• Verify the NDC format\n• Try without the package suffix (e.g., use 12345-1234 instead of 12345-1234-01)\n• Check if this is an FDA-approved product`, }], }; } // Process results and group by product const results = drugData.results.map(drug => { const matchingProductNDCs = drug.openfda.product_ndc?.filter(ndc => ndc === productNDC ) || []; const matchingPackageNDCs = drug.openfda.package_ndc?.filter(ndc => packageNDC ? ndc === packageNDC : ndc.startsWith(productNDC) ) || []; return { // Basic drug information brand_name: drug.openfda.brand_name || [], generic_name: drug.openfda.generic_name || [], manufacturer_name: drug.openfda.manufacturer_name || [], product_type: drug.openfda.product_type || [], route: drug.openfda.route || [], substance_name: drug.openfda.substance_name || [], // NDC information matching_product_ndc: matchingProductNDCs, matching_package_ndc: matchingPackageNDCs, all_product_ndc: drug.openfda.product_ndc || [], all_package_ndc: drug.openfda.package_ndc || [], // Additional product details dosage_and_administration: drug.dosage_and_administration || [], package_label_principal_display_panel: drug.package_label_principal_display_panel || [], active_ingredient: drug.active_ingredient || [], purpose: drug.purpose || [] }; }); // Summary information const totalPackages = results.reduce((sum, result) => sum + result.matching_package_ndc.length, 0 ); const searchSummary = packageNDC ? `Searched for specific package NDC: ${packageNDC}` : `Searched for product NDC: ${productNDC} (all packages)`; return { content: [{ type: "text", text: `✅ Found ${results.length} drug(s) with ${totalPackages} package(s) for NDC "${ndcCode}"\n\n${searchSummary}\n\n${JSON.stringify(results, null, 2)}`, }], }; } );
  • Helper function to normalize various NDC input formats (with/without dashes, product/package) into standardized productNDC and optional packageNDC, with format validation. Used by the get-drug-by-ndc handler.
    // Helper function to normalize and validate NDC format function normalizeNDC(ndc: string): { productNDC: string; packageNDC: string | null; isValid: boolean } { // Remove spaces and convert to uppercase const cleanNDC = ndc.trim().toUpperCase(); // Check for different NDC formats: // 1. XXXXX-XXXX (product NDC) // 2. XXXXX-XXXX-XX (package NDC) // 3. XXXXXXXXXXX (11-digit without dashes) // 4. XXXXXXXXX (9-digit without dashes - product only) let productNDC: string; let packageNDC: string | null = null; if (cleanNDC.includes('-')) { const parts = cleanNDC.split('-'); if (parts.length === 2) { // Format: XXXXX-XXXX (product NDC) productNDC = cleanNDC; packageNDC = null; } else if (parts.length === 3) { // Format: XXXXX-XXXX-XX (package NDC) productNDC = `${parts[0]}-${parts[1]}`; packageNDC = cleanNDC; } else { return { productNDC: cleanNDC, packageNDC: null, isValid: false }; } } else { // No dashes - need to format based on length if (cleanNDC.length === 11) { // 11-digit package NDC: XXXXXYYYYZZ -> XXXXX-YYYY-ZZ productNDC = `${cleanNDC.substring(0, 5)}-${cleanNDC.substring(5, 9)}`; packageNDC = `${cleanNDC.substring(0, 5)}-${cleanNDC.substring(5, 9)}-${cleanNDC.substring(9, 11)}`; } else if (cleanNDC.length === 9) { // 9-digit product NDC: XXXXXXXXX -> XXXXX-XXXX productNDC = `${cleanNDC.substring(0, 5)}-${cleanNDC.substring(5, 9)}`; packageNDC = null; } else { return { productNDC: cleanNDC, packageNDC: null, isValid: false }; } } // Basic validation const isValid = /^\d{5}-\d{4}$/.test(productNDC); return { productNDC, packageNDC, isValid }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ythalorossy/openfda'

If you have feedback or need assistance with the MCP directory API, please join our Discord server