Skip to content

matthdm/erx-platform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

eRx Platform

HIPAA-compliant multi-agent electronic prescribing platform. Nine domain MCP servers orchestrated by a LangGraph StateGraph, backed by MongoDB. Built with FastAPI, FastMCP, and Claude AI agents.


Prerequisites

Tool Minimum version Check
Docker Desktop (or Engine + Compose plugin) 24.x docker --version
Docker Compose plugin v2 docker compose version
Python 3.12+ python3 --version
mongosh (optional) any mongosh --version

Apple Silicon (M1/M2/M3): Docker Desktop works out of the box. No extra steps needed.

Podman users: Set CONTAINER_ENGINE=podman in your shell before running any make or scripts/ commands.

You will also need an Anthropic API key (sk-ant-...) for the LLM agent nodes. Get one at console.anthropic.com.


Quick Start — Full Stack (recommended)

This runs all 13 containers (MongoDB, nginx, gateway, orchestrator, 9 MCP agents) with a single script.

# 1. Clone and enter the repo
git clone <repo-url> erx-platform
cd erx-platform

# 2. Run the installer (checks prereqs, generates keys, builds image, seeds DB)
chmod +x scripts/install.sh
./scripts/install.sh

# 3. Open the UI
open http://localhost        # macOS
xdg-open http://localhost    # Linux
# Windows: browse to http://localhost

Login: admin / erx_test_2026

That's it. The installer takes 3–5 minutes on first run (Docker image build).


What the Installer Does

scripts/install.sh performs every first-time step automatically:

  1. Checks that Docker and Python 3.12 are available
  2. Copies .env.example.env (skipped if .env already exists)
  3. Generates PHI_ENCRYPTION_KEY and SECRET_KEY and writes them into .env
  4. Prompts for your ANTHROPIC_API_KEY and writes it into .env
  5. Builds the shared Docker image (erx-platform:latest)
  6. Starts all 13 containers (infra/podman-compose.yml)
  7. Waits for MongoDB and the gateway to become healthy
  8. Initialises all 11 MongoDB collections and their indexes
  9. Seeds reference data: patients, drugs, prescribers, providers, pharmacies, SOPs
  10. Prints the URL, credentials, and demo instructions

Resetting / Wiping the Environment

To tear everything down and start completely fresh (wipes the MongoDB volume):

./scripts/reset.sh            # clean slate — reference data only (good for demos)
./scripts/reset.sh --full     # also load 80 historical orders
./scripts/reset.sh --edge     # also load 17 edge-case test scenarios

reset.sh is safe to run at any time. It stops all containers, removes the data volume, starts fresh, and re-seeds.


Running Demo Scenarios

After a fresh reset the database has reference data (patients, drugs, prescribers) but no orders. Use the demo controller to submit named scenarios one at a time:

python scripts/demo.py list                    # show all available scenarios

python scripts/demo.py submit routine-non-cs   # statin — fastest path to APPROVED
python scripts/demo.py submit routine          # OxyContin CII, FL patient
python scripts/demo.py submit controlled-tx    # cross-state CII (FL prescriber → TX patient)
python scripts/demo.py submit rems             # Fentora — REMS workflow
python scripts/demo.py submit prior-auth       # Revlimid — PA required
python scripts/demo.py submit clozapine        # Clozaril — REMS + ANC monitoring
python scripts/demo.py submit denial-candidate # OIG-excluded prescriber → DENIED

python scripts/demo.py submit bulk             # submit all 7 at once
python scripts/demo.py clear                   # wipe all orders for a clean slate

Each submit prints the order ID and a direct link: http://localhost/orders/<id>

The demo script connects directly to MongoDB — no JWT token needed. By default it assumes mongodb://localhost:27017. Inside the container network use --uri mongodb://erx-mongodb:27017.


Local Development Mode (no Docker for services)

If you prefer to run Python services directly on your machine (faster iteration, debugger support):

# 1. Start only MongoDB in Docker
make mongo

# 2. Install Python dependencies
make install          # pip install -e .[dev]

# 3. Generate keys and set up .env
make gen-keys         # prints PHI_ENCRYPTION_KEY and SECRET_KEY
cp .env.example .env  # then paste the keys in

# 4. Init the database
make init-db          # creates collections + indexes
make seed             # seeds all domain data

# 5. Start services in separate terminals
python -m agents.patient.server        # port 8101
python -m agents.provider.server       # port 8102
python -m agents.prescriber.server     # port 8103
python -m agents.orders.server         # port 8104
python -m agents.drug.server           # port 8105
python -m agents.sig.server            # port 8106
python -m agents.pharmacy.server       # port 8107
python -m agents.eligibility.server    # port 8108
python -m agents.prior_auth.server     # port 8109
python -m orchestrator.main            # Change Stream watcher
uvicorn services.gateway.main:app --reload --port 8000

The UI is then at http://localhost:8000 (no nginx proxy in this mode).


Make Command Reference

make help           Show all commands

# Full stack
make build          Build the Docker image (required before make dev)
make dev            Start all 13 containers
make dev-down       Stop all containers
make setup          First-time full-stack setup (build + start + init-db + seed)
make reset          Tear down + wipe + reseed (calls scripts/reset.sh)

# Database (local mode — Python running on host)
make init-db        Create collections + indexes
make seed           Seed all domain data
make seed-edge      Seed 17 edge-case scenarios
make seed-fresh     Drop + reseed from scratch
make verify-seed    Print document counts for all collections

# Database (full-stack mode — runs inside gateway container)
make init-db-full   Create collections + indexes (via container exec)
make seed-full      Seed all domain data (via container exec)

# Logs
make logs           Tail gateway + orchestrator logs
make logs-all       Tail all container logs
make logs-gateway   Tail a specific service (replace 'gateway' with any service name)

# Quality
make lint           ruff + mypy + bandit
make fmt            Auto-fix formatting
make test           pytest
make test-cov       pytest with HTML coverage report (htmlcov/index.html)

# Setup helpers
make gen-keys       Generate PHI_ENCRYPTION_KEY and SECRET_KEY
make install        pip install -e .[dev]

Environment Variables

Copy .env.example to .env and fill in these required values:

Variable Required Description
ANTHROPIC_API_KEY Yes Claude API key — powers all LLM agent nodes
PHI_ENCRYPTION_KEY Yes Fernet key for PHI field encryption. Generate: make gen-keys
SECRET_KEY Yes JWT signing key. Generate: make gen-keys
MONGODB_URL No Default: mongodb://localhost:27017 (local) or mongodb://erx-mongodb:27017 (container)
LOG_FORMAT No console (dev, default) or json (production)

All other variables have sensible defaults. The full list is in .env.example.


Architecture Overview

Browser
  └─ nginx :80
       └─ FastAPI Gateway :8000
            ├─ /auth/*     JWT token endpoint
            ├─ /api/*      REST JSON (Bearer-protected)
            └─ /           HTMX UI (Jinja2 templates)

Gateway → LangGraph Orchestrator
  └─ StateGraph processes each PrescriptionOrder through 9 domain nodes:
       patient → provider → prescriber → drug → sig → eligibility → prior_auth → pharmacy → complete

Each node calls its domain MCP server via SSE:
  mcp-patient    :8101    Patient lookup + PHI validation
  mcp-provider   :8102    Provider credentialing
  mcp-prescriber :8103    DEA/state license + OIG exclusion check
  mcp-drug       :8104    NDC lookup, schedule, REMS flag
  mcp-sig        :8105    Sig parsing + clinical validation
  mcp-eligibility :8106   PBM eligibility + formulary (mock NCPDP D.0)
  mcp-prior-auth :8107    PA submission + status tracking (mock payer)
  mcp-pharmacy   :8108    Pharmacy routing + SureScripts check

MongoDB (11 collections):
  patients, providers, prescribers, drugs, sigs, orders,
  pharmacies, eligibility_checks, prior_auths,
  state_sop_modules, audit_log

All SOP rules live in state_sop_modules — nothing hardcoded. To add or update a rule: insert a new document (version+1, status=ACTIVE), set the old one to SUPERSEDED. No deploy needed.


Troubleshooting

"Gateway not ready" during install/reset

The gateway takes 15–30 s to start on first run because it connects to all 9 MCP servers. If it times out, check:

make logs-gateway    # look for errors

Then re-run ./scripts/reset.sh — it's idempotent.

"Workspace still starting" or MongoDB connection refused

MongoDB needs ~10 s after container start. The install/reset scripts wait for it automatically. If you're running commands manually, wait for:

docker compose -f infra/podman-compose.yml ps   # all services should show "healthy" or "running"

init-db or seed fail with "Connection refused"

In full-stack mode, use the container-aware targets:

make init-db-full
make seed-full

The bare make init-db / make seed connect to localhost:27017 and only work in local dev mode.

PHI fields show as encrypted strings in the UI

The PHI_ENCRYPTION_KEY in .env doesn't match the key used to encrypt the seed data. Run a fresh reset:

./scripts/reset.sh

This drops the database and re-seeds with the current key.

Port 80 already in use

Something else is using port 80 (Apache, another nginx). Stop it, or change the nginx port in infra/podman-compose.yml and update the health check URLs in scripts/.

Podman instead of Docker

export CONTAINER_ENGINE=podman
./scripts/install.sh      # or reset.sh — both honour CONTAINER_ENGINE
make dev                  # Makefile also honours it

Credentials

What Value
UI login admin / erx_test_2026
MongoDB (local mode) mongodb://localhost:27017 (no auth)
MongoDB (full-stack) mongodb://erx-mongodb:27017 (internal network, no auth in dev)

File Layout

erx-platform/
├── agents/          9 FastMCP domain servers (one per domain)
├── orchestrator/    LangGraph StateGraph + node functions
├── services/gateway FastAPI gateway — REST API + HTMX UI
├── shared/          db.py, logging.py, security.py, audit.py
├── schemas/         canonical_schemas.py — all Beanie models
├── sops/            sop_injection.py — DB-driven SOP prompt assembly
├── db/              Seed data, init scripts, edge-case scenarios
├── infra/           podman-compose.yml, nginx config, mongo init
├── scripts/
│   ├── install.sh   First-time setup
│   ├── reset.sh     Full teardown + reseed
│   └── demo.py      Demo order controller
├── .env.example     Environment variable template
├── Makefile         Developer commands
└── README.md        ← you are here

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors