The right protocol for your jurisdiction, in two seconds.
A national EMS protocol library with jurisdiction-aware AI retrieval. Built for paramedics, EMTs, and field providers who can't afford to be paging through a PDF on a code.
EMS protocols are not national. They are set by Local Emergency Medical Services Agencies (LEMSAs), state EMS offices, and regional medical directors. A paramedic in Los Angeles County follows different standing orders than one in San Bernardino, even though both are 60 miles apart in the same state.
Today, most providers carry their agency's protocols as a 200-page PDF, a binder in the rig, or a dog-eared cheat sheet. Looking up a pediatric epinephrine dose during a code means flipping pages — or guessing — under time pressure that punishes both. Existing reference apps either ignore jurisdiction entirely (national averages, useless) or lock you into a single agency (every move means a new app).
Protocol Guide solves the actual workflow: enter your county, ask in plain English, get back the exact protocol your medical director approved, with a citation, in under two seconds. No flipping. No guessing. No app switching when you cross a county line.
- Paramedics and EMTs in the field who need fast, jurisdiction-correct protocol lookups
- Field training officers who need to verify what their service actually authorizes
- EMS educators who need a single tool that works across the agencies their students will hire into
- Medical directors and QA officers who need to push protocol updates without rebuilding an app
┌──────────────────────────────────────────┐
│ Provider asks: "epi dose for cardiac arrest" │
└─────────────────┬────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ EMS Query Normalizer │
│ ─ Expands 150+ abbreviations (epi → epinephrine) │
│ ─ Classifies intent (medication_dosing) │
│ ─ Detects emergent indicators (cardiac arrest) │
└─────────────────┬────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Jurisdiction Scoping │
│ user.county → county_agency_mapping → agency_id │
└─────────────────┬────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Vector Search (pgvector, agency-scoped) │
│ ─ Cosine similarity, threshold 0.38 for meds │
│ ─ Multi-query fusion + RRF for safety-critical │
└─────────────────┬────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Re-ranking │
│ ─ Term frequency, synonym matching, context boost │
│ ─ +15 agency match, +5 state match │
└─────────────────┬────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Claude RAG (retrieval-only, mandatory citation) │
│ ─ Free + Pro simple → Haiku 4.5 │
│ ─ Pro complex → Sonnet 4.6 │
└─────────────────┬────────────────────────────────────┘
│
▼
"Epinephrine 1mg IV/IO q3-5min [Protocol 4.2]"
The model never invents content. Retrieval is constrained to the user's agency, and citation is mandatory at the prompt level. If the protocol doesn't exist for the agency, the answer says so — it doesn't substitute a national average.
| Metric | Value |
|---|---|
| Protocol chunks | 58,000+ (vector-embedded, searchable) |
| EMS agencies | 2,738 across 53 states and territories |
| California LEMSAs | 33 of 33 (100% coverage) |
| U.S. counties mapped | 2,713 |
| Embedding dimensions | 1,536 (Gemini Embedding 2 Preview) |
United States
└─ State (53 states + territories)
└─ LEMSA / Agency (2,738 protocol-issuing authorities)
└─ County (one agency may cover multiple counties)
└─ Protocol Chunks (58,000+ embedded segments)
California is the launch market with full LEMSA coverage. The architecture supports national expansion — state_code, agency_id, and county_agency_mapping already span all 50 states plus territories.
Full domain model and ingestion pipeline: docs/EMS_ARCHITECTURE.md.
Medication dosing, contraindication checks, and emergent indicators (cardiac arrest, anaphylaxis, airway obstruction) trigger enhanced processing regardless of subscription tier. Free users get the same accuracy mode as Pro users on these query classes.
| Trigger | Behavior |
|---|---|
| Medication dosing | Multi-query fusion (3 variants), Reciprocal Rank Fusion merge, 0.38 similarity floor |
| Contraindication check | Highest priority weighting (100), enhanced accuracy mode |
| Pediatric + medication | Weight-based dosing alerts, enhanced regardless of tier |
| Emergent patterns | Always enhanced, never falls back to fast-path |
Every Claude response includes a persistent disclaimer: "Consult medical direction / follow your agency's protocols." This is not a footer — it's surfaced in-line at the response level.
| Layer | Technology |
|---|---|
| Frontend | Expo 54, React Native Web, Expo Router, NativeWind (Tailwind) |
| Backend | Express + tRPC 11.7 (end-to-end typesafe) |
| Database | Supabase PostgreSQL + pgvector |
| Models | Claude Haiku 4.5 / Sonnet 4.6 (Anthropic) |
| Embeddings | Gemini Embedding 2 Preview (1536 dim) |
| Auth | Supabase Auth (Google + Apple OAuth) |
| Payments | Stripe (subscriptions; iOS via SFSafariViewController deep-link per Epic v. Apple) |
| Hosting | Netlify (PWA) + Railway (API) |
| Caching | Upstash Redis (query cache + rate limits) |
Voyage AI was removed 2026-03-24. The 1536-dim embedding space is now Gemini exclusively.
| Tier | Price | Quota | Models |
|---|---|---|---|
| Free | $0 | 5 queries/day, 1 agency | Haiku 4.5 |
| Pro | $9.99/mo or $89/yr | Unlimited, all agencies, voice, offline | Haiku 4.5 + Sonnet 4.6 (complex) |
| Department | $5.99–$7.99/seat/mo | Per-seat, agency dashboard | Pro + admin |
| Enterprise | Custom | Custom SOW | All capabilities |
Cost per query: ~$0.0003 on Haiku, ~$0.003 on Sonnet. Margin holds well into the unlimited tier at typical user query volumes.
git clone https://github.com/thefiredev-cloud/Protocol-Guide.git
cd Protocol-Guide
pnpm install
cp .env.example .env.local # add API keys (see below)
pnpm db:push # apply migrations
pnpm dev # server :3001 + web :8081Prerequisites: Node 20+, pnpm 9+, PostgreSQL (local or Supabase).
DATABASE_URL=postgresql://user:pass@localhost:5432/protocol_guide
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
ANTHROPIC_API_KEY=sk-ant-api03-...
GOOGLE_API_KEY=AIza... # Gemini Embedding 2 Preview
STRIPE_SECRET_KEY=sk_test_... # optional for dev
STRIPE_WEBHOOK_SECRET=whsec_... # optional for dev
UPSTASH_REDIS_REST_URL=https://... # optional
UPSTASH_REDIS_REST_TOKEN=... # optional| Convention | Rationale |
|---|---|
| Files ≤ 500 lines | Forces clean module boundaries; non-negotiable |
TypeScript strict, no any |
Catch errors at compile time, not at 3 AM in production |
| Zod for runtime validation | Trust nothing crossing the network |
[Protocol #XXX] mandatory citation |
Prompt-level constraint; the model literally cannot answer without it |
| Gold Q&A regression set | Required pass before any RAG or prompt change ships |
pnpm check && pnpm lint && pnpm test && pnpm test:integration |
Required before every EAS build |
Protocol-Guide/
├── app/ Expo Router (file-based routing)
│ ├── (tabs)/index.tsx Search interface
│ ├── (tabs)/profile.tsx Agency selection, subscription
│ ├── admin/ Agency dashboard (protocols, users, analytics)
│ ├── tools/ EMS field tools (arrest timer, dosing calculator)
│ └── oauth/ OAuth callbacks
├── server/ tRPC backend
│ ├── _core/
│ │ ├── rag/ RAG pipeline
│ │ ├── embeddings/ Gemini + pgvector
│ │ ├── claude.ts Model selection + system prompts
│ │ ├── ems-query-normalizer.ts 150+ abbreviation expansion
│ │ └── protocol-chunker.ts Semantic chunking (400–1800 chars)
│ ├── routers/ search, query, voice, auth, subscription, user
│ └── webhooks/ Stripe
├── scripts/ Protocol ingestion pipeline (LEMSA crawl → embed → insert)
├── drizzle/ Schema + migrations
├── shared/ Cross-stack types
├── hooks/ React hooks (search, auth, offline, voice)
├── components/ UI components
└── docs/ Architecture, deployment, EMS domain
| Document | Contents |
|---|---|
docs/EMS_ARCHITECTURE.md |
Jurisdiction model, ingestion pipeline, search pipeline, EMS terminology |
docs/DATABASE.md |
Schema, indexes, RLS, vector search |
docs/BACKEND.md |
tRPC routers, RAG pipeline, auth, middleware |
docs/FRONTEND.md |
Expo Router, NativeWind, jurisdiction UI |
CLAUDE.md |
AI agent configuration, code standards, operational rules |
CONTRIBUTING.md |
Code style, testing, PR process |
DEPLOYMENT.md |
Production deployment procedures |
The non-negotiables, all documented in CLAUDE.md:
- Not a regulated medical device. Protocol Guide surfaces agency-authored protocols; it does not diagnose, monitor, or treat. App Store regulated-medical-device declaration is "No."
- Not HIPAA-regulated today, but
query_analytics_logis treated as potentially sensitive because paramedics can free-text search. Scrub direct identifiers / PHI-shaped patterns before storage and do not advertise a fixed raw-query retention window until purge/anonymization automation is verified. - No "HIPAA compliant" claims without a signed BAA. Use "HIPAA-aligned" or "designed with a privacy-first architecture."
- iOS payments via Stripe
SFSafariViewControllerper Guideline 3.1.1(a) (Epic v. Apple, 9th Cir. 2025-12-11 affirmed). Never embed Stripe inWKWebView— triggers 4.2 rejection. - Persistent medical disclaimer on every response screen.
- Agency citation on every protocol chunk in the UI (Guideline 1.4.1 accuracy defense).
- Vendor BAAs deferred until first enterprise agency contract: Supabase Team + HIPAA add-on, Railway Enterprise, Anthropic sales-assisted.
| Surface | Platform | Trigger |
|---|---|---|
| PWA / web | Netlify | Auto-deploy from main |
| API | Railway (numReplicas=2, region=us-west1) |
Auto-deploy from main |
| iOS | EAS → TestFlight → App Store | Manual eas build after gate chain passes |
| Database | Supabase (managed) | pnpm db:push |
pnpm docker:prod brings the whole stack up locally (API + web + Postgres + Redis). See docs/deployment/DOCKER-ALL-IN-ONE.md.
- California LEMSA coverage at 33/33 (done)
- Stripe-only billing via SFSafariViewController (per Epic v. Apple)
- TestFlight beta with paramedic feedback loop
- App Store submission with regulated-medical-device declaration "No"
- Top 10 states by EMS provider population
- Department dashboard (per-seat billing, agency admin, usage analytics)
- RevenueCat + StoreKit 2 for international expansion (replaces SafariViewController for non-US storefronts)
- Protocol versioning and change tracking
- QA dashboard (query patterns, knowledge gaps)
- Direct-from-agency protocol updates without app re-review (Supabase remote-config kill-switch)
Proprietary. All rights reserved.
Protocol Guide — built by Fire Dev LLC for the people who run toward the call.