Skip to main content
Glama

get-drugs-by-manufacturer

Find drugs produced by a specific pharmaceutical company. Use this tool to identify manufacturer portfolios or locate alternative medications from the same source.

Instructions

Get all drugs manufactured by a specific company. Useful for finding alternatives or checking manufacturer portfolios.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
manufacturerNameYesManufacturer/company name
limitNoMaximum number of drugs to return

Implementation Reference

  • The handler function for the 'get-drugs-by-manufacturer' tool. It constructs an OpenFDA API query for drugs by manufacturer name, fetches the data, handles errors and empty results, maps the response to a simplified list of drugs (brand_name, generic_name, product_type, route, ndc), and returns formatted text content.
    async ({ manufacturerName, limit }) => { const url = new OpenFDABuilder() .context("label") .search(`openfda.manufacturer_name:"${manufacturerName}"`) .limit(limit) .build(); const { data: drugData, error } = await makeOpenFDARequest<OpenFDAResponse>(url); if (error) { return { content: [{ type: "text", text: `Failed to retrieve drugs for manufacturer "${manufacturerName}": ${error.message}`, }], }; } if (!drugData || !drugData.results || drugData.results.length === 0) { return { content: [{ type: "text", text: `No drugs found for manufacturer "${manufacturerName}".`, }], }; } const drugs = drugData.results.map(drug => ({ brand_name: drug?.openfda.brand_name?.[0] || 'Unknown', generic_name: drug?.openfda.generic_name?.[0] || 'Unknown', product_type: drug?.openfda.product_type?.[0] || 'Unknown', route: drug?.openfda.route || [], ndc: drug?.openfda.product_ndc?.[0] || 'Unknown' })); return { content: [{ type: "text", text: `Found ${drugs.length} drug(s) from manufacturer "${manufacturerName}":\n\n${JSON.stringify(drugs, null, 2)}`, }], }; }
  • Zod input schema for the tool defining parameters: manufacturerName (required string) and limit (optional number, default 20).
    manufacturerName: z.string().describe("Manufacturer/company name"), limit: z.number().optional().default(20).describe("Maximum number of drugs to return") },
  • src/index.ts:262-311 (registration)
    Registration of the 'get-drugs-by-manufacturer' tool using McpServer.tool() method, including name, description, schema, and handler function.
    server.tool( "get-drugs-by-manufacturer", "Get all drugs manufactured by a specific company. Useful for finding alternatives or checking manufacturer portfolios.", { manufacturerName: z.string().describe("Manufacturer/company name"), limit: z.number().optional().default(20).describe("Maximum number of drugs to return") }, async ({ manufacturerName, limit }) => { const url = new OpenFDABuilder() .context("label") .search(`openfda.manufacturer_name:"${manufacturerName}"`) .limit(limit) .build(); const { data: drugData, error } = await makeOpenFDARequest<OpenFDAResponse>(url); if (error) { return { content: [{ type: "text", text: `Failed to retrieve drugs for manufacturer "${manufacturerName}": ${error.message}`, }], }; } if (!drugData || !drugData.results || drugData.results.length === 0) { return { content: [{ type: "text", text: `No drugs found for manufacturer "${manufacturerName}".`, }], }; } const drugs = drugData.results.map(drug => ({ brand_name: drug?.openfda.brand_name?.[0] || 'Unknown', generic_name: drug?.openfda.generic_name?.[0] || 'Unknown', product_type: drug?.openfda.product_type?.[0] || 'Unknown', route: drug?.openfda.route || [], ndc: drug?.openfda.product_ndc?.[0] || 'Unknown' })); return { content: [{ type: "text", text: `Found ${drugs.length} drug(s) from manufacturer "${manufacturerName}":\n\n${JSON.stringify(drugs, null, 2)}`, }], }; } );
  • OpenFDABuilder class used in the handler to construct the OpenFDA API URL with context='label', search='openfda.manufacturer_name:"{name}"', and limit.
    export class OpenFDABuilder { private url = "https://api.fda.gov/drug/"; private params = new Map<string, string | number>(); context(context: ContextType): this { this.params.set("context", context); return this; } search(query: string): this { this.params.set("search", query); return this; } limit(max: number = 1): this { this.params.set("limit", max); return this; } build(): string { const context = this.params.get("context"); const search = this.params.get("search"); const limit = this.params.get("limit"); const apiKey = process.env.OPENFDA_API_KEY; if (!context || !search || !limit) { throw new Error("Missing required parameters: context, search, or limit"); } return `${this.url}${context}.json?api_key=${apiKey}&search=${search}&limit=${limit}`; } }
  • makeOpenFDARequest utility function called in the handler to perform the resilient HTTP fetch to the constructed OpenFDA URL, with comprehensive error handling and retries.
    async function makeOpenFDARequest<T>( url: string, config: RequestConfig = {} ): Promise<{ data: T | null; error: OpenFDAError | null }> { const { maxRetries, retryDelay, timeout } = { ...DEFAULT_CONFIG, ...config }; const headers = { "User-Agent": "@ythalorossy/openfda", Accept: "application/json", }; let lastError: OpenFDAError | null = null; for (let attempt = 0; attempt <= maxRetries!; attempt++) { try { // Create abort controller for timeout handling const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), timeout); console.log( `Making OpenFDA request (attempt ${attempt + 1}/${ maxRetries! + 1 }): ${url}` ); const response = await fetch(url, { headers, signal: controller.signal, }); clearTimeout(timeoutId); // Handle HTTP errors with OpenFDA-specific context if (!response.ok) { const errorText = await response .text() .catch(() => "Unable to read error response"); const httpError: OpenFDAError = { type: "http", message: `HTTP ${response.status}: ${response.statusText}`, status: response.status, details: errorText, }; console.error(`OpenFDA HTTP Error (${response.status}):`, { url, status: response.status, statusText: response.statusText, errorText: errorText.substring(0, 200), // Truncate long error messages }); // OpenFDA-specific status code handling switch (response.status) { case 400: httpError.message = `Bad Request: Invalid search query or parameters`; break; case 401: httpError.message = `Unauthorized: Invalid or missing API key`; break; case 403: httpError.message = `Forbidden: API key may be invalid or quota exceeded`; break; case 404: httpError.message = `Not Found: No results found for the specified query`; break; case 429: httpError.message = `Rate Limited: Too many requests. Retrying...`; break; case 500: httpError.message = `Server Error: OpenFDA service is experiencing issues`; break; default: httpError.message = `HTTP Error ${response.status}: ${response.statusText}`; } lastError = httpError; // Don't retry client errors (4xx) except rate limiting if ( response.status >= 400 && response.status < 500 && response.status !== 429 ) { break; } // Retry server errors and rate limits if ( attempt < maxRetries! && isRetryableError({ status: response.status }) ) { const delay = retryDelay! * Math.pow(2, attempt); // Exponential backoff console.log(`Retrying in ${delay}ms...`); await sleep(delay); continue; } break; } // Parse JSON response let parsedData: any; try { parsedData = await response.json(); } catch (parseError) { const parsingError: OpenFDAError = { type: "parsing", message: `Failed to parse JSON response: ${ parseError instanceof Error ? parseError.message : "Unknown parsing error" }`, details: parseError, }; console.error("OpenFDA JSON Parsing Error:", { url, parseError: parseError instanceof Error ? parseError.message : parseError, }); lastError = parsingError; break; // Don't retry parsing errors } // Check for empty response if (!parsedData) { const emptyError: OpenFDAError = { type: "empty_response", message: "Received empty response from OpenFDA API", }; lastError = emptyError; break; } console.log(`OpenFDA request successful on attempt ${attempt + 1}`); return { data: parsedData as T, error: null }; } catch (error: any) { // Handle network errors, timeouts, and other fetch errors let networkError: OpenFDAError; if (error.name === "AbortError") { networkError = { type: "timeout", message: `Request timeout after ${timeout}ms`, details: error, }; } else if ( error instanceof TypeError && error.message.includes("fetch") ) { networkError = { type: "network", message: `Network error: Unable to connect to OpenFDA API`, details: error.message, }; } else { networkError = { type: "unknown", message: `Unexpected error: ${ error.message || "Unknown error occurred" }`, details: error, }; } console.error(`OpenFDA Request Error (attempt ${attempt + 1}):`, { url, error: error.message, type: error.name, }); lastError = networkError; // Retry network errors and timeouts if (attempt < maxRetries! && isRetryableError(error)) { const delay = retryDelay! * Math.pow(2, attempt); // Exponential backoff console.log(`Network error, retrying in ${delay}ms...`); await sleep(delay); continue; } break; } } return { data: null, error: lastError }; }

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