Skip to main content
Glama

Healthcare MCP Server

http-server.js7 kB
#!/usr/bin/env node import http from 'http'; import { randomUUID } from 'crypto'; import { URL } from 'url'; import { CacheService } from './cache-service.js'; import { FDATool } from './fda-tool.js'; import { PubMedTool } from './pubmed-tool.js'; import { HealthTopicsTool } from './health-topics-tool.js'; import { ClinicalTrialsTool } from './clinical-trials-tool.js'; import { MedicalTerminologyTool } from './medical-terminology-tool.js'; import { MedRxivTool } from './medrxiv-tool.js'; import { MedicalCalculatorTool } from './medical-calculator-tool.js'; import { NcbiBookshelfTool } from './ncbi-bookshelf-tool.js'; import { DicomTool } from './dicom-tool.js'; import { UsageService } from './usage-service.js'; const PORT = parseInt(process.env.PORT || '3000', 10); const sessionId = randomUUID(); const cacheService = new CacheService(parseInt(process.env.CACHE_TTL) || 86400); const usageService = new UsageService(); const fdaTool = new FDATool(cacheService); const pubmedTool = new PubMedTool(cacheService); const healthTopicsTool = new HealthTopicsTool(cacheService); const clinicalTrialsTool = new ClinicalTrialsTool(cacheService); const medicalTerminologyTool = new MedicalTerminologyTool(cacheService); const medrxivTool = new MedRxivTool(cacheService); const medicalCalculatorTool = new MedicalCalculatorTool(cacheService); const ncbiBookshelfTool = new NcbiBookshelfTool(cacheService); const dicomTool = new DicomTool(cacheService); function writeJson(res, statusCode, body) { res.statusCode = statusCode; res.setHeader('Content-Type', 'application/json'); // Basic CORS support res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.end(JSON.stringify(body)); } async function handleCallTool(name, args) { usageService.recordUsage(sessionId, name); switch (name) { case 'fda_drug_lookup': return fdaTool.lookupDrug(args.drug_name, args.search_type); case 'pubmed_search': return pubmedTool.searchLiterature(args.query, args.max_results, args.date_range, args.open_access); case 'medrxiv_search': return medrxivTool.search(args.query, args.max_results); case 'calculate_bmi': return medicalCalculatorTool.calculateBmi(args.height_meters, args.weight_kg); case 'ncbi_bookshelf_search': return ncbiBookshelfTool.search(args.query, args.max_results); case 'extract_dicom_metadata': return dicomTool.extractMetadata(args.file_path); case 'health_topics': return healthTopicsTool.getHealthTopics(args.topic, args.language); case 'clinical_trials_search': return clinicalTrialsTool.searchTrials(args.condition, args.status, args.max_results); case 'lookup_icd_code': return medicalTerminologyTool.lookupICDCode(args.code, args.description, args.max_results); case 'get_usage_stats': return usageService.getSessionUsage(sessionId); case 'get_all_usage_stats': return usageService.getAllUsageStats(); default: return { status: 'error', error_message: `Unknown tool: ${name}` }; } } const server = http.createServer(async (req, res) => { // Handle CORS preflight if (req.method === 'OPTIONS') { res.statusCode = 204; res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); return res.end(); } const url = new URL(req.url, `http://${req.headers.host}`); const pathname = url.pathname; try { if (req.method === 'GET' && pathname === '/health') { return writeJson(res, 200, { status: 'ok', session_id: sessionId, cache_ttl_seconds: cacheService.cache.options.stdTTL, uptime_seconds: Math.floor(process.uptime()), timestamp: new Date().toISOString() }); } if (req.method === 'GET' && pathname === '/api/fda') { const drugName = url.searchParams.get('drug_name') || ''; const searchType = url.searchParams.get('search_type') || 'general'; const result = await fdaTool.lookupDrug(drugName, searchType); return writeJson(res, 200, result); } if (req.method === 'GET' && pathname === '/api/pubmed') { const query = url.searchParams.get('query') || ''; const maxResults = url.searchParams.get('max_results') || 5; const dateRange = url.searchParams.get('date_range') || ''; const openAccess = (url.searchParams.get('open_access') || 'false') === 'true'; const result = await pubmedTool.searchLiterature(query, maxResults, dateRange, openAccess); return writeJson(res, 200, result); } if (req.method === 'GET' && pathname === '/api/health_finder') { const topic = url.searchParams.get('topic') || ''; const language = url.searchParams.get('language') || 'en'; const result = await healthTopicsTool.getHealthTopics(topic, language); return writeJson(res, 200, result); } if (req.method === 'GET' && pathname === '/api/clinical_trials') { const condition = url.searchParams.get('condition') || ''; const status = url.searchParams.get('status') || 'recruiting'; const maxResults = url.searchParams.get('max_results') || 10; const result = await clinicalTrialsTool.searchTrials(condition, status, maxResults); return writeJson(res, 200, result); } if (req.method === 'GET' && pathname === '/api/medical_terminology') { const code = url.searchParams.get('code') || ''; const description = url.searchParams.get('description') || ''; const maxResults = url.searchParams.get('max_results') || 10; const result = await medicalTerminologyTool.lookupICDCode(code, description, maxResults); return writeJson(res, 200, result); } if (req.method === 'POST' && pathname === '/mcp/call-tool') { let body = ''; req.on('data', chunk => { body += chunk; }); req.on('end', async () => { try { const parsed = JSON.parse(body || '{}'); const name = parsed.name; const args = parsed.arguments || {}; const result = await handleCallTool(name, args); return writeJson(res, 200, result); } catch (err) { return writeJson(res, 400, { status: 'error', error_message: `Invalid JSON body: ${err.message}` }); } }); return; } writeJson(res, 404, { status: 'error', error_message: 'Not Found' }); } catch (error) { console.error('HTTP handler error:', error); writeJson(res, 500, { status: 'error', error_message: error.message }); } }); server.listen(PORT, () => { console.error(`Healthcare MCP HTTP server listening on http://localhost:${PORT}`); console.error(`Session ID: ${sessionId}`); console.error(`Cache TTL: ${cacheService.cache.options.stdTTL} seconds`); });

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/Cicatriiz/healthcare-mcp-public'

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