Skip to main content
Glama
josh747jr

Doctor Appointment MCP Server

by josh747jr
README.md
# Doctor Appointment MCP Server

A Python-based **Model Context Protocol (MCP) server** for managing doctor appointments through an external appointment REST API.

The server exposes appointment-management operations as MCP tools so an MCP-compatible AI agent or client can create, find, retrieve, cancel, and reschedule appointments.

## What It Does

The server provides five MCP tools:

| Tool | Description |
|---|---|
| `create_appointment` | Creates a new doctor appointment. |
| `find_appointments` | Finds appointments by patient name, doctor name, and/or appointment date. |
| `check_appointment_status` | Retrieves appointment details and status by appointment ID. |
| `cancel_appointment` | Cancels an appointment by changing its status to `cancelled`. |
| `reschedule_appointment` | Changes the date and time of an existing appointment. |

The server also includes:

- Streamable HTTP MCP endpoint at `/mcp`
- Health endpoints at `/` and `/health`
- Optional custom HTTP-header authentication
- An external REST API backend configured through `APPOINTMENTS_API`
- Async HTTP requests using `httpx`

## Architecture

```text
AI Agent / MCP Client
          |
          | Model Context Protocol
          v
      /mcp endpoint
          |
          v
       Uvicorn
          |
          v
      Starlette
          |
          v
       FastMCP
          |
   +------+------+------+------+------+
   |      |      |      |      |
   v      v      v      v      v
 Create  Find   Check  Cancel Reschedule
   |      |      |      |      |
   +------+------+------+------+------+
                 |
                 v
            HTTPX Client
                 |
                 | REST API
                 v
        Appointment Backend
         (MockAPI by default)
```

## Project Structure

```text
doctor-appointment-mcp/
├── server.py
├── requirements.txt
├── start.sh
├── run.sh
├── README.md
├── .gitignore
└── .gitattributes
```

## Requirements

- Python 3.11 or newer recommended
- `pip`
- An appointment REST API endpoint

Python dependencies are defined in `requirements.txt`:

```text
fastmcp>=3.0
uvicorn[standard]>=0.30
httpx>=0.27
```

## Local Setup

### 1. Clone the repository

```bash
git clone https://github.com/josh747jr/doctor-appointment-mcp.git
cd doctor-appointment-mcp
```

### 2. Create a virtual environment

Windows PowerShell:

```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
```

Linux/macOS/WSL:

```bash
python3 -m venv .venv
source .venv/bin/activate
```

### 3. Install dependencies

```bash
pip install -r requirements.txt
```

### 4. Configure the appointment API

Set `APPOINTMENTS_API` to the REST endpoint that stores appointment records.

Windows PowerShell:

```powershell
$env:APPOINTMENTS_API="https://YOUR-API-ENDPOINT/appointments"
```

Linux/macOS/WSL:

```bash
export APPOINTMENTS_API="https://YOUR-API-ENDPOINT/appointments"
```

If `APPOINTMENTS_API` is not set, the current `server.py` uses its configured MockAPI endpoint.

> Do not commit API keys, credentials, or other secrets to the repository.

## Run the Server Locally

Start Uvicorn:

```bash
python -m uvicorn server:app --host 127.0.0.1 --port 8000
```

The MCP endpoint will be:

```text
http://127.0.0.1:8000/mcp
```

The health endpoint will be:

```text
http://127.0.0.1:8000/health
```

A successful health check returns:

```text
ok
```

## MCP Tools

### 1. `create_appointment`

Creates a new doctor appointment.

Inputs:

- `patient_name`
- `doctor_name`
- `appointment_date`
- `appointment_time`
- `reason` — optional

Example tool arguments:

```json
{
  "patient_name": "John Doe",
  "doctor_name": "Dr. Mike",
  "appointment_date": "2026-09-18",
  "appointment_time": "2:00 PM",
  "reason": "Annual physical"
}
```

New appointments are stored with a status of `scheduled`.

Example user request:

```text
Schedule an appointment for John Doe with Dr. Mike on September 18, 2026
at 2:00 PM for an annual physical.
```

### 2. `find_appointments`

Finds one or more existing appointments when the appointment ID is not known.

Search inputs:

- `patient_name` — optional
- `doctor_name` — optional
- `appointment_date` — optional
- `include_cancelled` — optional boolean, defaults to `false`

At least one of `patient_name`, `doctor_name`, or `appointment_date` must be provided.

Find appointments for a patient:

```json
{
  "patient_name": "John Doe"
}
```

Find appointments for a patient and doctor:

```json
{
  "patient_name": "John Doe",
  "doctor_name": "Dr. Mike"
}
```

Find appointments on a particular date:

```json
{
  "appointment_date": "2026-09-18"
}
```

The tool sends the supplied search fields as query parameters to the appointment REST API and returns the matching appointment records.

A successful result includes:

```json
{
  "success": true,
  "message": "Found 1 matching appointment(s).",
  "count": 1,
  "appointments": [
    {
      "id": "12",
      "patientName": "John Doe",
      "doctorName": "Dr. Mike",
      "appointmentDate": "2026-09-18",
      "appointmentTime": "2:00 PM",
      "reason": "Annual physical",
      "status": "scheduled"
    }
  ]
}
```

If no records match, the tool returns a successful response with `count` set to `0` and an empty `appointments` array.

Example user requests:

```text
Find my appointment with Dr. Mike.
```

```text
What appointments does John Doe have?
```

```text
Find John Doe's appointment on September 18, 2026.
```

### 3. `check_appointment_status`

Retrieves an appointment by its ID.

Input:

- `appointment_id`

Example:

```json
{
  "appointment_id": "12"
}
```

A successful response includes the patient, doctor, appointment date, appointment time, reason, and status.

Example user request:

```text
What is the status of appointment 12?
```

### 4. `cancel_appointment`

Cancels an existing appointment.

Input:

- `appointment_id`

Example:

```json
{
  "appointment_id": "12"
}
```

Cancellation does **not** delete the appointment record. The server changes its status to:

```text
cancelled
```

Keeping the record preserves appointment history.

Example user request:

```text
Cancel appointment 12.
```

### 5. `reschedule_appointment`

Changes the date and time of an existing appointment.

Inputs:

- `appointment_id`
- `new_appointment_date`
- `new_appointment_time`

Example:

```json
{
  "appointment_id": "12",
  "new_appointment_date": "2026-09-21",
  "new_appointment_time": "10:00 AM"
}
```

Cancelled appointments cannot be rescheduled by the current implementation.

Example user request:

```text
Move appointment 12 to September 21, 2026 at 10:00 AM.
```

## Appointment Data Model

The REST backend is expected to store records similar to:

```json
{
  "id": "12",
  "patientName": "John Doe",
  "doctorName": "Dr. Mike",
  "appointmentDate": "2026-09-18",
  "appointmentTime": "2:00 PM",
  "reason": "Annual physical",
  "status": "scheduled"
}
```

The server uses REST operations equivalent to:

```text
POST /appointments
GET  /appointments
GET  /appointments/{id}
PUT  /appointments/{id}
```

`find_appointments` uses `GET /appointments` with query parameters such as:

```text
patientName
doctorName
appointmentDate
```

## Example Agent Workflow

A user may first ask:

```text
Find my appointment with Dr. Mike.
```

The MCP client can invoke:

```text
find_appointments(patient_name="John Doe", doctor_name="Dr. Mike")
```

After the matching record and appointment ID are found, the user can say:

```text
Move that appointment to September 21 at 10 AM.
```

The MCP client can then invoke:

```text
reschedule_appointment(
    appointment_id="12",
    new_appointment_date="2026-09-21",
    new_appointment_time="10:00 AM"
)
```

This allows an AI agent to locate an appointment first instead of requiring the user to know the appointment ID.

## Optional MCP Header Authentication

The server supports optional custom-header authentication through the `MCP_REQUEST_HEADERS` environment variable.

If the variable is not configured, custom-header authentication is disabled.

### Simple header

Windows PowerShell:

```powershell
$env:MCP_REQUEST_HEADERS="my-secret"
```

Linux/macOS/WSL:

```bash
export MCP_REQUEST_HEADERS="my-secret"
```

This configuration expects MCP requests to include a header named:

```text
MCP_REQUEST_HEADERS
```

with the configured value.

### Custom header name

The variable can also contain JSON:

```bash
export MCP_REQUEST_HEADERS='{"X-API-Key":"my-secret"}'
```

The MCP client must then send:

```text
X-API-Key: my-secret
```

The `/` and `/health` endpoints remain available without this custom authentication.

> **Security note:** This project is a demonstration/learning implementation. A real healthcare application requires substantially stronger authentication, authorization, privacy controls, audit logging, secret management, data protection, and regulatory review before storing real patient information.

## Deployment

The repository contains:

```text
start.sh
run.sh
```

These scripts can be used for a Linux-based deployment.

`start.sh` installs the required Python packages into the deployment dependency directory.

`run.sh` starts the application with Uvicorn and listens on the `PORT` environment variable, defaulting to port `8080`.

Required deployment environment variable:

```text
APPOINTMENTS_API=https://YOUR-API-ENDPOINT/appointments
```

Optional authentication:

```text
MCP_REQUEST_HEADERS=your-secret
```

After deployment, the MCP endpoint will typically be:

```text
https://YOUR-SERVER/mcp
```

and the health endpoint:

```text
https://YOUR-SERVER/health
```

## Testing the Server

Start the application:

```bash
python -m uvicorn server:app --host 127.0.0.1 --port 8000
```

Test the health endpoint:

```bash
curl http://127.0.0.1:8000/health
```

Expected response:

```text
ok
```

Then configure an MCP-compatible client to connect to:

```text
http://127.0.0.1:8000/mcp
```

The client should discover these five tools:

```text
create_appointment
find_appointments
check_appointment_status
cancel_appointment
reschedule_appointment
```

## Planned Improvements

Useful next steps include:

- Add doctor availability and time-slot lookup
- Prevent conflicting or double-booked appointments
- Add stronger date and time validation
- Add a production database
- Add OAuth or another production-grade authentication mechanism
- Add automated tests
- Add structured audit logging
- Integrate with a real calendar or scheduling provider
- Add production-grade patient identity and authorization controls

## Development Status

This project is intended as an MCP development and learning project. The current appointment backend can later be replaced with a production scheduling service or database while preserving the MCP-facing tool interface.

## Security and Healthcare Data

Do not use real patient information or protected health information (PHI) with an unsecured demonstration backend.

A production healthcare application may be subject to privacy, security, compliance, and data-retention requirements such as HIPAA in the United States.

## Repository

https://github.com/josh747jr/doctor-appointment-mcp

## License

No license has been specified for this repository yet. Add a `LICENSE` file before distributing or reusing the project under specific licensing terms.

Maintenance

ActivityMaintained
ResponsivenessNo issues