search-clinical-guidelines
Find clinical guidelines and practice recommendations from medical organizations to support evidence-based medical decision making.
Instructions
Search for clinical guidelines and practice recommendations from medical organizations
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Medical condition or topic to search for guidelines | |
| organization | No | Specific medical organization to filter by (e.g., 'American Heart Association', 'WHO') |
Implementation Reference
- src/utils.ts:1592-1815 (handler)Core handler function that implements the search-clinical-guidelines tool by querying PubMed for guideline-related articles, filtering them based on keywords, extracting metadata, and categorizing results.export async function searchClinicalGuidelines( query: string, organization?: string, ): Promise<ClinicalGuideline[]> { try { // Enhanced search strategy with broader terms and specific guideline databases const searchTerms = [ `guidelines ${query}`, `recommendations ${query}`, `consensus ${query}`, `position statement ${query}`, `evidence-based ${query}`, `best practice ${query}`, `American Heart Association ${query}`, `American College of Cardiology ${query}`, `American Diabetes Association ${query}`, `American College of Physicians ${query}`, `WHO guidelines ${query}`, `CDC guidelines ${query}`, ]; const allGuidelines: ClinicalGuideline[] = []; for (const searchTerm of searchTerms) { try { const searchRes = await superagent .get(`${PUBMED_API_BASE}/esearch.fcgi`) .query({ db: "pubmed", term: searchTerm, retmode: "json", retmax: 10, // Increased from 5 }) .set("User-Agent", USER_AGENT); const idList = searchRes.body.esearchresult?.idlist || []; if (idList.length === 0) continue; // Fetch article details const fetchRes = await superagent .get(`${PUBMED_API_BASE}/efetch.fcgi`) .query({ db: "pubmed", id: idList.join(","), retmode: "xml", }) .set("User-Agent", USER_AGENT); const articles = parsePubMedXML(fetchRes.text); for (const article of articles) { // More flexible guideline detection const title = article.title.toLowerCase(); const abstract = (article.abstract || "").toLowerCase(); const isGuideline = title.includes("guideline") || title.includes("recommendation") || title.includes("consensus") || title.includes("position statement") || title.includes("expert consensus") || title.includes("best practice") || title.includes("evidence-based") || abstract.includes("guideline") || abstract.includes("recommendation") || abstract.includes("consensus") || abstract.includes("position statement"); if (isGuideline) { // Extract organization from journal, abstract, or title let org = "Unknown Organization"; // Try to extract from journal first if (article.journal) { org = article.journal; } // Try to extract from abstract if (article.abstract) { const orgPatterns = [ /([A-Z][a-z]+ [A-Z][a-z]+ (?:Society|Association|College|Institute|Foundation|Organization|Committee|Academy))/, /(American [A-Z][a-z]+ (?:Society|Association|College|Institute|Foundation|Organization|Committee|Academy))/, /(World Health Organization|WHO)/, /(Centers for Disease Control|CDC)/, /(National [A-Z][a-z]+ (?:Institute|Institute of Health|Academy))/, ]; for (const pattern of orgPatterns) { const match = article.abstract.match(pattern); if (match) { org = match[1]; break; } } } // Try to extract from title if (org === "Unknown Organization") { const titleOrgPatterns = [ /(American [A-Z][a-z]+ (?:Society|Association|College|Institute|Foundation|Organization|Committee|Academy))/, /(World Health Organization|WHO)/, /(Centers for Disease Control|CDC)/, ]; for (const pattern of titleOrgPatterns) { const match = article.title.match(pattern); if (match) { org = match[1]; break; } } } // Skip if organization filter is specified and doesn't match if ( organization && !org.toLowerCase().includes(organization.toLowerCase()) && !article.title.toLowerCase().includes(organization.toLowerCase()) ) { continue; } // Extract year const yearMatch = article.publication_date.match(/(\d{4})/); const year = yearMatch ? yearMatch[1] : "Unknown"; // Determine category based on content let category = "General"; if ( title.includes("cardiology") || abstract.includes("cardiac") || abstract.includes("heart") ) category = "Cardiology"; else if ( title.includes("oncology") || abstract.includes("cancer") || abstract.includes("tumor") ) category = "Oncology"; else if ( title.includes("diabetes") || abstract.includes("diabetes") ) category = "Endocrinology"; else if ( title.includes("hypertension") || abstract.includes("hypertension") || abstract.includes("blood pressure") ) category = "Cardiology"; else if ( title.includes("infectious") || abstract.includes("infection") || abstract.includes("infectious") ) category = "Infectious Diseases"; else if ( title.includes("pediatric") || abstract.includes("pediatric") || abstract.includes("children") ) category = "Pediatrics"; else if ( title.includes("mental") || abstract.includes("mental") || abstract.includes("psychiatric") ) category = "Psychiatry"; // Determine evidence level let evidenceLevel = "Systematic Review/Consensus"; if ( title.includes("meta-analysis") || abstract.includes("meta-analysis") ) evidenceLevel = "Meta-analysis"; else if ( title.includes("systematic review") || abstract.includes("systematic review") ) evidenceLevel = "Systematic Review"; else if ( title.includes("randomized") || abstract.includes("randomized") ) evidenceLevel = "Randomized Controlled Trial"; allGuidelines.push({ title: article.title, organization: org, year: year, url: `https://pubmed.ncbi.nlm.nih.gov/${article.pmid}/`, description: (article.abstract || "").substring(0, 200) + "...", category: category, evidence_level: evidenceLevel, }); } } } catch (error) { console.error( `Error searching for guidelines with term: ${searchTerm}`, error instanceof Error ? error.message : String(error), ); } } // Remove duplicates based on title similarity const uniqueGuidelines = allGuidelines.filter( (guideline, index, self) => index === self.findIndex( (g) => g.title.toLowerCase().replace(/[^\w\s]/g, "") === guideline.title.toLowerCase().replace(/[^\w\s]/g, ""), ), ); return uniqueGuidelines.slice(0, 15); // Increased limit to 15 results } catch (error) { console.error("Error searching clinical guidelines:", error); return []; } }
- src/index.ts:191-213 (registration)MCP tool registration including name, description, input schema, and thin handler wrapper that calls the core implementation.server.tool( "search-clinical-guidelines", "Search for clinical guidelines and practice recommendations from medical organizations", { query: z .string() .describe("Medical condition or topic to search for guidelines"), organization: z .string() .optional() .describe( "Specific medical organization to filter by (e.g., 'American Heart Association', 'WHO')", ), }, async ({ query, organization }) => { try { const guidelines = await searchClinicalGuidelines(query, organization); return formatClinicalGuidelines(guidelines, query, organization); } catch (error: any) { return createErrorResponse("searching clinical guidelines", error); } }, );
- src/index.ts:194-204 (schema)Zod input schema validation for the tool parameters: query (required string) and organization (optional string).{ query: z .string() .describe("Medical condition or topic to search for guidelines"), organization: z .string() .optional() .describe( "Specific medical organization to filter by (e.g., 'American Heart Association', 'WHO')", ), },
- src/utils.ts:698-728 (helper)Helper function to format the search results into a structured MCP response with numbered list of guidelines including title, organization, year, category, evidence level, and URL.export function formatClinicalGuidelines( guidelines: any[], query: string, organization?: string, ) { if (guidelines.length === 0) { return createMCPResponse( `No clinical guidelines found for "${query}"${organization ? ` from ${organization}` : ""}. Try a different search term or check if the condition has established guidelines.`, ); } let result = `**Clinical Guidelines Search: "${query}"**\n\n`; if (organization) { result += `Organization Filter: ${organization}\n`; } result += `Found ${guidelines.length} guideline(s)\n\n`; guidelines.forEach((guideline, index) => { result += `${index + 1}. **${guideline.title}**\n`; result += ` Organization: ${guideline.organization}\n`; result += ` Year: ${guideline.year}\n`; result += ` Category: ${guideline.category}\n`; result += ` Evidence Level: ${guideline.evidence_level}\n`; if (guideline.description) { result += ` Description: ${guideline.description}\n`; } result += ` URL: ${guideline.url}\n\n`; }); return createMCPResponse(result); }
- src/types.ts:71-79 (schema)TypeScript type definition for ClinicalGuideline, defining the output structure of the tool.export type ClinicalGuideline = { title: string; organization: string; year: string; url: string; description?: string; category?: string; evidence_level?: string; };