Skip to main content
Glama
zkorczyc

hcp-engagement

by zkorczyc
README.md
# HCP Engagement × Supabase × MCP (mock pharma demo)

**Model Context Protocol** server for simulated Healthcare Professional (HCP) engagement data — reps, visits/calls/emails, consent status, and prescribing trends — from **Supabase**.

All data is synthetic (`example-pharma.com` reps, fictional drug names like `Cardiozin`, sequential NPIs). This is **not** real provider or prescribing data.

Shares the same Supabase project as the separate [Frescopa MCP](https://github.com/zkorczyc/Frescopa-stock) repo, but lives in its own table namespace (`hcps`, `hcp_reps`, `hcp_products`, `hcp_interactions`, `hcp_interaction_products`, `hcp_prescribing_trends`, `hcp_consents`) — no foreign keys, joins, or code shared between the two.

| Mode | Use case |
|------|----------|
| **stdio** (`npm start`) | Cursor, Claude Desktop on your Mac |
| **HTTP** (`npm run start:http`) | Adobe AI Assistant, any remote app — public URL |

## Repo layout

| Path | Purpose |
|------|---------|
| `../supabase/migrations/20260831000000_hcp_engagement_init.sql` | Tables, RLS (`anon`/`authenticated` read-only), seed data, views |
| `src/index.ts` | MCP stdio entry |
| `src/http.ts` | MCP HTTP entry (`POST /mcp`) |
| `src/create-server.ts` | Shared tools |
| `.env.example` | Env template |

## Supabase setup

1. **SQL**: Dashboard → **SQL Editor** → paste `../supabase/migrations/20260831000000_hcp_engagement_init.sql` → **Run**. Safe to re-run (uses `on conflict do nothing` / `create or replace view`).
2. **API**: reuse the same `SUPABASE_URL` and `SUPABASE_ANON_KEY` from the Frescopa `.env` — same project, read-only anon key.

## Local build

```bash
cd /Users/zkorczyc/Projects/Frescopa/hcp-mcp
cp .env.example .env   # skip if .env already exists
npm install
npm run build
```

## Cursor `mcp.json` snippet

```json
{
  "mcpServers": {
    "hcp-engagement": {
      "command": "node",
      "args": ["/Users/zkorczyc/Projects/Frescopa/hcp-mcp/dist/index.js"],
      "env": {
        "SUPABASE_URL": "https://uxlccvzhuwzwzrmqunml.supabase.co",
        "SUPABASE_ANON_KEY": "eyJ..."
      }
    }
  }
}
```

## MCP tools

| Tool | Role |
|------|------|
| `hcp_list_hcps` | List HCPs; filter `specialty`, `tier` (`A`\|`B`\|`C`), `region`, `state` |
| `hcp_search` | Search HCPs by name, NPI, or institution |
| `hcp_get_profile` | Full profile by NPI — demographics, consent status per channel, engagement summary |
| `hcp_list_interactions` | Visits/calls/emails — filter by NPI, region, specialty, rep name, interaction type, days back |
| `hcp_engagement_summary` | **Analytics:** interaction counts, recency, sentiment score, samples per HCP — find engagement gaps |
| `hcp_prescribing_trends` | Monthly new/total Rx and market share % for **one HCP**, optionally scoped to one product |
| `hcp_prescribing_trend_by_segment` | **Analytics:** quarterly Rx trend for one product, broken out by region/specialty (`segment_rollup`) plus per-HCP quarterly rows (`hcp_quarterly`) for drill-down |
| `hcp_visit_frequency_by_segment` | **Analytics:** quarterly interaction/visit frequency by region/specialty — pairs with `hcp_prescribing_trend_by_segment` for side-by-side comparison |
| `hcp_rep_activity` | **Analytics:** per-rep territory summary — HCPs engaged, interaction volume (30d/90d), avg sentiment |

### Example questions this enables

- "Which Tier A cardiologists haven't been visited in 90+ days?" → `hcp_engagement_summary` (filter `tier: A`, `specialty: Cardiology`), then check `last_interaction_at`.
- "Can I drop samples with Dr. Reyes?" → `hcp_get_profile` → check `consents` for `sample_drop`.
- "Summarize my last 3 interactions with Dr. Nguyen." → `hcp_list_interactions` (filter by `npi`).
- "Which reps have the most positive-sentiment interactions?" → `hcp_rep_activity`.

### Demo narrative: "declining Rx despite steady engagement" (coverage-problem hook)

A 4-step chain that ties prescribing trend + rep engagement together to surface a "clinical demand exists, something's blocking it" story — useful for framing a payer/access-coverage narrative rather than a pure sales-execution one:

1. **Baseline, side by side** — "Show me Oncovarin prescribing trends by region and specialty over the last 2 quarters, alongside HCP visit frequency for each region."
   → `hcp_prescribing_trend_by_segment` (`brand_name: Oncovarin`) + `hcp_visit_frequency_by_segment`, both grouped by region/specialty/quarter so they line up.
2. **Isolate the signal** — "Which regions/specialties show declining Oncovarin prescribing despite stable or increasing visit frequency?" → compare the two `segment_rollup` outputs quarter-over-quarter (reasoning step, no new tool needed).
3. **Rule out physician sentiment** — "For HCPs in [flagged region] with declining trends, what's the interaction sentiment from recent visits?" → `hcp_prescribing_trend_by_segment`'s `hcp_quarterly` (filtered to the flagged region) to find the specific decliners, then `hcp_list_interactions` (filter by `npi`, or by `region`+`specialty`) to check sentiment.
4. **Territory context** — "Summarize rep/territory performance in [flagged region] this quarter." → `hcp_rep_activity` (filter `region`).

The seed data has one segment deliberately built to produce this exact pattern: **South region, Oncology, Oncovarin** — prescribing drops sharply in the latest quarter while visit frequency stays comparatively steady and sentiment trends more positive, not less. Everything else in the dataset is pseudo-random (deterministic per NPI, but not hand-tuned), so other region/specialty combinations may or may not show a similar pattern.

## Remote MCP URL (HTTP)

Same pattern as Frescopa — see [`../README.md`](../README.md#remote-mcp-url-http) for the full walkthrough (build → `start:http` → deploy → register URL). This server defaults to **port 3100** (vs. Frescopa's 3000) so both can run locally at once.

## Security

- Do not commit `.env` or **service role** keys.
- Demo is safe with **anon** + RLS limited to `SELECT`.
- Data is synthetic — do not populate with real patient, prescriber, or PHI/PII data.
- **HTTP:** always set `MCP_API_KEY` on public deploy.

TDQS

A3.8/5.0

Scored across 9 tools

Disambiguation4/5

Most tools target distinct resources or views: search/list/get HCPs, raw interactions, rep summaries, engagement analytics, and prescribing trends. The overlaps between hcp_list_hcps and hcp_search, and between the segment rollup tools, are manageable because descriptions specify different filters and metrics.

Naming Consistency4/5

All tools share a consistent hcp_ prefix and descriptive names. However, the set mixes verb-led names like hcp_list_hcps and hcp_get_profile with noun-phrase names like hcp_rep_activity and hcp_engagement_summary, so the pattern is not perfectly uniform.

Tool Count5/5

Nine tools is well-scoped for an HCP engagement analytics domain. Each tool covers a meaningful capability, from individual HCP lookup and interaction history to rep-level activity and segment-level prescribing trends, without unnecessary redundancy.

Completeness4/5

The tool set covers the core read-only engagement workflow: finding HCPs, viewing profiles, inspecting interactions, and aggregating engagement and prescribing trends at both individual and segment levels. Minor gaps exist, such as no dedicated rep directory or HCP/consent update capability, but agents can work around these with existing tools.

Maintenance

ActivityMaintained
ResponsivenessNo issues