Skip to main content
Glama

athenahealth MCP Server

webhook-bridge.tsโ€ข10.7 kB
#!/usr/bin/env node /** * Webhook Bridge Server for n8n Integration * * This server exposes the athenahealth MCP functionality via HTTP endpoints * that can be called from n8n workflows using the HTTP Request node. * * Usage: * npm run webhook-bridge * * Environment Variables: * ATHENA_CLIENT_ID - athenahealth API client ID * ATHENA_CLIENT_SECRET - athenahealth API client secret * ATHENA_PRACTICE_ID - athenahealth practice ID * ATHENA_BASE_URL - athenahealth API base URL (default: preview API) * WEBHOOK_PORT - Port to run the webhook server (default: 3000) */ import express, { Request, Response } from 'express'; import { AthenaHealthClient } from './services/athenahealth-client.js'; import dotenv from 'dotenv'; dotenv.config(); const app = express(); app.use(express.json()); app.use(express.urlencoded({ extended: true })); const PORT = process.env.WEBHOOK_PORT || 3000; // Initialize athenahealth client const client = new AthenaHealthClient({ client_id: process.env.ATHENA_CLIENT_ID!, client_secret: process.env.ATHENA_CLIENT_SECRET!, practice_id: process.env.ATHENA_PRACTICE_ID!, base_url: process.env.ATHENA_BASE_URL || 'https://api.preview.platform.athenahealth.com', version: process.env.ATHENA_VERSION || 'v1', }); // Health check endpoint app.get('/health', (req: Request, res: Response) => { res.json({ status: 'ok', service: 'athenahealth-webhook-bridge' }); }); // List all available endpoints app.get('/', (req: Request, res: Response) => { res.json({ service: 'athenahealth Webhook Bridge for n8n', version: '1.0.0', endpoints: { administrative: [ 'GET /departments - List all departments', 'GET /providers - List all providers', 'POST /patients/search - Search for patients', 'POST /patients - Create a new patient', ], scheduling: [ 'POST /appointments/availability - Check appointment availability', 'POST /appointments - Create an appointment', ], clinical: [ 'GET /patients/:patientId/allergies - Get patient allergies', 'GET /patients/:patientId/prescriptions - Get patient prescriptions', 'GET /patients/:patientId/problems - Get patient problems', 'GET /patients/:patientId/vitals - Get patient vitals', 'GET /patients/:patientId/labs - Get patient lab results', 'GET /patients/:patientId/alerts - Get clinical alerts', 'POST /patients/:patientId/prescriptions - Create prescription', 'POST /patients/:patientId/drug-interactions - Check drug interactions', 'POST /alerts/:alertId/acknowledge - Acknowledge alert', ], encounters: [ 'GET /patients/:patientId/encounters - Get patient encounters', 'GET /encounters/:encounterId - Get specific encounter', 'POST /encounters - Create new encounter', 'PUT /encounters/:encounterId - Update encounter', ], }, }); }); // =========================== // ADMINISTRATIVE ENDPOINTS // =========================== app.get('/departments', async (req: Request, res: Response) => { try { const departments = await client.getDepartments(); res.json({ success: true, data: departments }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.get('/providers', async (req: Request, res: Response) => { try { const { name, specialty, limit } = req.query; const providers = await client.getProviders({ name: name as string, specialty: specialty as string, limit: limit ? parseInt(limit as string) : undefined, }); res.json({ success: true, data: providers }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.post('/patients/search', async (req: Request, res: Response) => { try { const patients = await client.searchPatients(req.body); res.json({ success: true, data: patients }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.post('/patients', async (req: Request, res: Response) => { try { const patient = await client.createPatient(req.body); res.json({ success: true, data: patient }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); // =========================== // SCHEDULING ENDPOINTS // =========================== app.post('/appointments/availability', async (req: Request, res: Response) => { try { const availability = await client.getAppointmentAvailability(req.body); res.json({ success: true, data: availability }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.post('/appointments', async (req: Request, res: Response) => { try { const appointment = await client.createAppointment(req.body); res.json({ success: true, data: appointment }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); // =========================== // CLINICAL ENDPOINTS // =========================== app.get('/patients/:patientId/allergies', async (req: Request, res: Response) => { try { const patientId = req.params.patientId!; const allergies = await client.getPatientAllergies(patientId); res.json({ success: true, data: allergies }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.get('/patients/:patientId/prescriptions', async (req: Request, res: Response) => { try { const patientId = req.params.patientId!; const prescriptions = await client.getPatientPrescriptions(patientId); res.json({ success: true, data: prescriptions }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.get('/patients/:patientId/problems', async (req: Request, res: Response) => { try { const patientId = req.params.patientId!; const problems = await client.getPatientProblems(patientId); res.json({ success: true, data: problems }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.get('/patients/:patientId/vitals', async (req: Request, res: Response) => { try { const patientId = req.params.patientId!; const { startdate, enddate } = req.query; const vitals = await client.getPatientVitals(patientId, { startdate: startdate as string, enddate: enddate as string, }); res.json({ success: true, data: vitals }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.get('/patients/:patientId/labs', async (req: Request, res: Response) => { try { const patientId = req.params.patientId!; const { startdate, enddate } = req.query; const labs = await client.getPatientLabResults(patientId, { startdate: startdate as string, enddate: enddate as string, }); res.json({ success: true, data: labs }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.get('/patients/:patientId/alerts', async (req: Request, res: Response) => { try { const patientId = req.params.patientId!; const alerts = await client.getClinicalAlerts(patientId); res.json({ success: true, data: alerts }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.post('/patients/:patientId/prescriptions', async (req: Request, res: Response) => { try { const patientId = req.params.patientId!; const prescription = await client.createPrescription(patientId, req.body); res.json({ success: true, data: prescription }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.post('/patients/:patientId/drug-interactions', async (req: Request, res: Response) => { try { const patientId = req.params.patientId!; const { medications } = req.body; const interactions = await client.checkDrugInteractions(patientId, medications); res.json({ success: true, data: interactions }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.post('/alerts/:alertId/acknowledge', async (req: Request, res: Response) => { try { const alertId = req.params.alertId!; const { acknowledged_by } = req.body; const result = await client.acknowledgeAlert(alertId, acknowledged_by); res.json({ success: true, data: result }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); // =========================== // ENCOUNTER ENDPOINTS // =========================== app.get('/patients/:patientId/encounters', async (req: Request, res: Response) => { try { const patientId = req.params.patientId!; const { departmentid, startdate, enddate, status } = req.query; const encounters = await client.getPatientEncounters(patientId, { departmentid: departmentid as string, startdate: startdate as string, enddate: enddate as string, status: status as 'OPEN' | 'CLOSED' | 'SIGNED', }); res.json({ success: true, data: encounters }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.get('/encounters/:encounterId', async (req: Request, res: Response) => { try { const encounterId = req.params.encounterId!; const encounter = await client.getEncounter(encounterId); res.json({ success: true, data: encounter }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.post('/encounters', async (req: Request, res: Response) => { try { const encounter = await client.createEncounter(req.body); res.json({ success: true, data: encounter }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); app.put('/encounters/:encounterId', async (req: Request, res: Response) => { try { const encounterId = req.params.encounterId!; const encounter = await client.updateEncounter(encounterId, req.body); res.json({ success: true, data: encounter }); } catch (error: any) { res.status(500).json({ success: false, error: error.message }); } }); // Start server app.listen(PORT, () => { console.log(`\n๐Ÿš€ athenahealth Webhook Bridge running on http://localhost:${PORT}`); console.log(`๐Ÿ“Š Health check: http://localhost:${PORT}/health`); console.log(`๐Ÿ“– API documentation: http://localhost:${PORT}/`); console.log(`\nโœ… Ready to receive requests from n8n workflows!\n`); });

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/ophydami/Athenahealth-MCP'

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