Skip to main content
Glama
README.md
# Real-World Evidence & Clinical Feasibility MCP Server

**Repository:** [Krv-Labs/how-to-train-your-dragon](https://github.com/Krv-Labs/how-to-train-your-dragon)

Ranks US healthcare organizations by **expected randomized subjects per 12 months** for a Graves' disease protocol (NCT07570316) from longitudinal claims (Komodo) and public registries (ClinicalTrials.gov), exposed as an interactive **Model Context Protocol (MCP) server** for AI agents.

The Python package is `httyd`; the MCP server registers as **`real-world-mcp`**. CLI entry points: `httyd`, `realworld-mcp`, and `how-to-train-your-dragon`.

> **Why the name?** Built on Komodo Health claims data — taming and training the Komodo dragon into actionable feasibility models.

---

## 1. Architecture & Package Structure

```
how-to-train-your-dragon/
├── httyd/                          # Main Python package
│   ├── models/                     # L1–L5 parameters, provenance registry, recruitment math
│   ├── analysis/                   # Scoring pipeline, catchment, accrual, site linkage
│   ├── data/                       # Dataset catalog, loaders, CTG fetch
│   ├── evaluations/                # Temporal holdout validation
│   ├── auth/                       # Kubernetes token auth & scope enforcement
│   ├── engine.py                   # In-memory FeasibilityEngine singleton
│   ├── cache.py                    # Precomputed site/geo cache loader
│   └── server.py                   # MCP server (16 tools, 4 resources, 2 prompts)
├── ui/                             # Local observation dashboard (offline HTML)
│   ├── build_dashboard.py
│   └── (writes to output/site_feasibility.html)
├── data/                           # Claims & registry assets (not committed — see below)
├── docs/                           # Methodology, scoring review, evidence
├── deploy/helm/httyd/      # GKE Helm chart
├── scripts/precompute.py           # Build startup cache (Docker + local dev)
├── tests/
├── pyproject.toml
└── README.md
```

**Data note:** Komodo claims CSVs are gitignored. Only `data/nct07570316_sites.json` (ground-truth fixture) is committed. Place licensed data files in `data/` locally before running the engine.

Methodology and validation evidence: [docs/README.md](docs/README.md).

---

## 2. Quickstart

### Install

```bash
uv sync
```

### Precompute cache (recommended)

A full national score rebuild takes ~90s. Precompute once and reuse:

```bash
uv run python scripts/precompute.py
export REALWORLD_CACHE_DIR=./cache   # optional; defaults to ./cache when present
```

### Run tests

```bash
REALWORLD_CACHE_DIR=./cache uv run pytest
```

Some tests (sensitivity rescore, validation) trigger a full rebuild and take ~2 minutes total.

### Start the MCP server

```bash
# stdio transport (default — Claude Desktop, Cursor)
uv run httyd

# streamable-http (local dev)
AUTH_ENABLED=false REALWORLD_CACHE_DIR=./cache uv run httyd streamable-http
curl http://localhost:8080/health
```

### Generate local preview dashboard

```bash
uv run python ui/build_dashboard.py
open output/site_feasibility.html
```

---

## 3. MCP Tool Surface

`real-world-mcp` exposes **16 tools** across 6 areas:

### A. Dataset Discovery & Inspection
- `list_datasets`, `describe_dataset`, `get_cohort_summary`

### B. Model Registry & Provenance
- `list_models`, `get_provenance`

### C. Site Search & Deep-Dive
- `search_and_score_sites`, `get_site_details`, `explain_site_score`

### D. Spatial Catchment & Basket Optimization
- `compute_basket_catchment`, `find_nearby_competitors`

### E. Accrual Forecasting & Sensitivity
- `simulate_accrual_timeline`, `update_interim_accrual`, `compute_sensitivity_rescore`, `match_trial_facility`

### F. Validation & Limitations
- `run_model_validation`, `get_model_limitations`

---

## 4. MCP Agent Configuration

```json
{
  "mcpServers": {
    "real-world-mcp": {
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/how-to-train-your-dragon",
        "run",
        "httyd"
      ],
      "env": {
        "REALWORLD_CACHE_DIR": "/path/to/how-to-train-your-dragon/cache"
      }
    }
  }
}
```

---

## 5. GKE Internal Deployment

Deploy as an internal **ClusterIP** MCP service. Subagent pods authenticate with **Kubernetes ServiceAccount tokens** validated via the TokenReview API.

### Architecture

- **Transport:** `streamable-http` on port 8080 at `/mcp`
- **Auth:** Bearer token = projected ServiceAccount token (`audience: httyd`)
- **Authorization:** ConfigMap maps `system:serviceaccount:<ns>:<name>` → scopes
- **Network:** NetworkPolicy allows ingress only from namespaces labeled `httyd-client: "true"`

| Scope | Access |
|-------|--------|
| `feasibility:read` | Discovery, search, explain, provenance tools |
| `feasibility:simulate` | Accrual simulation, sensitivity rescore, basket catchment |

### Build and deploy

```bash
docker build -t httyd:0.1.0 .

helm upgrade --install httyd deploy/helm/httyd \
  -n realworld --create-namespace \
  --set image.repository=REGION-docker.pkg.dev/PROJECT/REPO/httyd \
  --set image.tag=0.1.0
```

Register subagent ServiceAccounts in [`deploy/helm/httyd/scopes.yaml`](deploy/helm/httyd/scopes.yaml) before deploying.

### Subagent pod configuration

```bash
kubectl label namespace app httyd-client=true
```

```yaml
serviceAccountName: subagent-feasibility-reader
volumes:
  - name: mcp-token
    projected:
      sources:
        - serviceAccountToken:
            audience: httyd
            expirationSeconds: 3600
            path: token
volumeMounts:
  - name: mcp-token
    mountPath: /var/run/secrets/tokens
    readOnly: true
env:
  - name: HTTYD_MCP_URL
    value: "http://httyd.httyd.svc:8080/mcp"
  - name: HTTYD_MCP_TOKEN_FILE
    value: "/var/run/secrets/tokens/token"
```

### Environment variables

| Variable | Default | Purpose |
|----------|---------|---------|
| `AUTH_ENABLED` | `false` (local) / `true` (container) | Enable K8s token auth |
| `MCP_RESOURCE_URL` | `http://httyd.httyd.svc:8080` | OAuth resource identifier |
| `MCP_SCOPE_CONFIG` | `/etc/mcp/scopes.yaml` | SA → scope mapping |
| `MCP_TOKEN_AUDIENCE` | `httyd` | Expected token audience |
| `REALWORLD_CACHE_DIR` | `./cache` | Precomputed sites/geo JSON |
| `PORT` | `8080` | HTTP listen port |
| `HOST` | `0.0.0.0` | HTTP bind address |
| `STATELESS_HTTP` | `true` | Stateless MCP sessions (recommended for K8s) |