Skip to main content
Glama
mayankgupta-bluebash

Healthcare Appointment Scheduling MCP Server

Healthcare Appointment Scheduling MCP Server

Local mock Model Context Protocol (MCP) server for healthcare appointment scheduling. Designed for development and testing with Retell AI.

All data is stored in local JSON files. There are no real EHR, calendar, or database integrations.

Features

  • Official @modelcontextprotocol/sdk with Streamable HTTP transport

  • Zod-validated tool inputs

  • Persistent local JSON storage (data/)

  • Health endpoint for uptime checks

  • Structured JSON tool responses for voice agents

  • Request/response logging for debugging Retell tool calls

Related MCP server: Health Claims MCP Server

Requirements

  • Node.js 20+

  • npm 9+

Installation

cd mcp
cp .env.example .env
npm install

Run locally

Development (auto-reload):

npm run dev

Production build:

npm run build
npm start

Server URLs (default):

Endpoint

URL

Health

http://localhost:3000/health

MCP

http://localhost:3000/mcp

Health response:

{
  "status": "ok",
  "service": "healthcare-mcp-server"
}

Environment variables

Copy .env.example to .env:

PORT=3000
HOST=0.0.0.0
  • PORT — HTTP port

  • HOST — bind address (0.0.0.0 required when exposing via ngrok / Cloudflare Tunnel)

Expose with ngrok

Retell AI needs a public HTTPS URL.

  1. Start the MCP server locally (npm run dev).

  2. In another terminal:

ngrok http 3000
  1. Copy the HTTPS forwarding URL, for example:

https://abc123.ngrok-free.app
  1. MCP endpoint for Retell:

https://abc123.ngrok-free.app/mcp

Cloudflare Tunnel (alternative)

cloudflared tunnel --url http://localhost:3000

Use the generated HTTPS URL + /mcp.

Connect to Retell AI

  1. Open your Retell AI agent / MCP settings.

  2. Add a custom MCP server URL pointing to:

https://<your-public-host>/mcp
  1. Save and refresh tools so Retell can call tools/list.

  2. Confirm the agent can see all eight tools listed below.

  3. Place a test call and watch local server logs for [MCP] TOOL CALL / TOOL RESPONSE.

This server uses Streamable HTTP with session IDs (Mcp-Session-Id) and JSON responses (enableJsonResponse: true), which works with standard MCP HTTP clients.

Available MCP tools

Tool

Purpose

search_patients

Find patients by first/last name, DOB, phone, or email

create_patient

Create a patient (with duplicate checks)

get_providers

List active providers (optional specialty/name filter)

get_appointment_types

List active appointment types / durations

get_available_slots

List open slots for provider + type + date

get_appointments

List a patient's future scheduled appointments by patient_id

create_appointment

Book an appointment (prevents double booking)

update_appointment

Reschedule / update an appointment

cancel_appointment

Soft-cancel (status=cancelled, record kept)

request_prescription_refill

Request a prescription refill for a patient

Example inputs and outputs

search_patients

Input:

{
  "first_name": "John",
  "last_name": "Doe"
}

Output:

{
  "success": true,
  "count": 1,
  "patients": [
    {
      "id": "patient_001",
      "first_name": "John",
      "last_name": "Doe",
      "full_name": "John Doe",
      "date_of_birth": "1990-01-15",
      "phone_number": "5551234567",
      "email": "john.doe@example.com"
    }
  ]
}

create_patient

Input:

{
  "first_name": "Alex",
  "last_name": "Rivera",
  "date_of_birth": "1993-04-02",
  "phone_number": "5559998888",
  "email": "alex.rivera@example.com"
}

get_available_slots

Input:

{
  "provider_id": "provider_001",
  "appointment_type_id": "appt_type_002",
  "date": "2026-09-10"
}

Notes:

  • Provider hours: Monday–Friday 09:00–17:00

  • Duration comes from the appointment type

  • Existing scheduled appointments are excluded

get_appointments

Input:

{
  "patient_id": "patient_001"
}

Output:

{
  "success": true,
  "patient_id": "patient_001",
  "count": 1,
  "appointments": [
    {
      "id": "appointment_001",
      "patient_id": "patient_001",
      "provider_id": "provider_001",
      "appointment_type_id": "appt_type_002",
      "date": "2026-09-10",
      "start_time": "10:00",
      "end_time": "10:15",
      "status": "scheduled",
      "notes": "Follow-up for blood pressure check"
    }
  ]
}

Past and cancelled appointments are excluded.

create_appointment

Input:

{
  "patient_id": "patient_001",
  "provider_id": "provider_001",
  "appointment_type_id": "appt_type_002",
  "date": "2026-09-10",
  "start_time": "09:00",
  "notes": "Blood pressure follow-up"
}

Error response shape

{
  "success": false,
  "error": {
    "code": "SLOT_NOT_AVAILABLE",
    "message": "The requested appointment slot is not available..."
  }
}

Common codes: PATIENT_NOT_FOUND, PATIENT_ALREADY_EXISTS, PROVIDER_NOT_FOUND, APPOINTMENT_TYPE_NOT_FOUND, APPOINTMENT_NOT_FOUND, SLOT_NOT_AVAILABLE, INVALID_DATE, INVALID_INPUT.

JSON data files

Located under data/:

File

Contents

patients.json

Patient demographics

providers.json

Providers (active/inactive)

appointment-types.json

Visit types and durations

appointments.json

Scheduled / cancelled appointments

prescription-refills.json

Prescription refill requests

Behavior:

  • Tools read and write these files dynamically

  • Missing files are created as []

  • Writes use a temp file + rename to reduce corruption risk

  • Changes survive server restarts

Seed data includes 12 patients, 7 providers (6 active), 7 appointment types (6 active), and several sample appointments.

Project structure

src/
  index.ts          # HTTP server + Streamable HTTP transport
  server.ts         # MCP server + tool registration
  tools/            # MCP tool definitions
  services/         # Business logic
  utils/            # JSON storage, IDs, dates, responses
  types/            # Shared TypeScript types
data/               # Persistent mock JSON data

Inspecting logs (Retell debugging)

When Retell calls a tool, the server prints:

[MCP] Incoming POST /mcp ...
[MCP] TOOL CALL search_patients {...}
[MCP] TOOL RESPONSE search_patients {...}

Tips:

  1. Keep npm run dev in a visible terminal while testing Retell.

  2. Confirm /health is reachable through the tunnel before configuring Retell.

  3. If tools are missing, verify the MCP URL ends with /mcp.

  4. If sessions fail, ensure the client preserves Mcp-Session-Id after initialize.

Manual smoke test (curl)

Initialize:

curl -s http://localhost:3000/health

List tools (after starting a session with an MCP client) is easiest with the SDK client. A quick end-to-end check (server must already be running):

npm run test:smoke

Troubleshooting

Issue

Fix

Port already in use

Change PORT in .env

Retell cannot reach server

Confirm ngrok is running and URL uses /mcp

Empty tool list

Restart server, re-add MCP URL in Retell, check initialize logs

Double booking allowed?

Should not happen — check appointments.json status is scheduled

Weekend slots empty

Expected — only Mon–Fri 09:00–17:00

Duplicate patient created

Duplicate phone or name+DOB returns PATIENT_ALREADY_EXISTS

Data reset

Re-copy seed JSON from git or restore data/*.json

License

MIT

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables access to mock Epic patient data through 15 MCP tools with two-tier access (list summaries, then fetch details) and LLM-powered natural language search across allergies, medications, conditions, clinical notes, labs, vitals, and procedures.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides a mock interface for managing health insurance operations, including claims processing, benefit inquiries, provider searches, and prior authorization requests. It enables developers to test healthcare workflows using synthetic data through the Model Context Protocol.
    Apache 2.0
  • F
    license
    Not graded
    quality
    C
    maintenance
    Simulates a third-party appointment booking agent, enabling your AI platform to check availability and book appointments via MCP interoperability.
    -