A national EMS protocol library with jurisdiction-aware AI retrieval. Find the right protocol for your agency in 2 seconds.
protocol-guide.com | GitHub | Report Issue
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 follows different standing orders than one in San Diego, even though both are in California.
Protocol Guide ingests the actual clinical protocols from these jurisdictions, chunks and embeds them with Voyage AI, and serves them through a RAG pipeline powered by Claude. When a user asks "epi dose for cardiac arrest," the system:
- Resolves their jurisdiction — County selection maps to the correct LEMSA/agency via
county_agency_mapping - Scopes the search — Vector similarity search runs only against that agency's protocol chunks
- Generates a cited answer — Claude responds using only the retrieved protocols, citing
[Protocol #XXX]
The result: jurisdiction-accurate protocol answers in under 2 seconds.
| 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 | 2,713 mapped to agencies |
| Embedding Dimensions | 1,536 (Voyage AI voyage-large-2) |
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.
See docs/EMS_ARCHITECTURE.md for the complete domain model, ingestion pipeline, and jurisdiction mapping.
"epi dose for cardiac arrest"
│
▼
┌─────────────────────┐
│ EMS Query Normalizer │ Expands abbreviations (epi → epinephrine)
│ │ Classifies intent (medication_dosing)
│ │ Detects emergent indicators
└─────────┬───────────┘
▼
┌─────────────────────┐
│ Jurisdiction Scoping │ county_id → agency_id → scoped search
└─────────┬───────────┘
▼
┌─────────────────────┐
│ Vector Search │ pgvector cosine similarity
│ (Supabase) │ WHERE agency_id = user's agency
└─────────┬───────────┘
▼
┌─────────────────────┐
│ Re-ranking │ Term frequency, synonym matching,
│ │ protocol number matching, context boost
└─────────┬───────────┘
▼
┌─────────────────────┐
│ Claude RAG │ Retrieval-only (no training data generation)
│ │ Mandatory citation: [Protocol #XXX]
│ │ Model: Haiku (free) / Sonnet (pro complex)
└─────────┬───────────┘
▼
"Epinephrine 1mg IV/IO q3-5min [Protocol 4.2]"
Medication dosing, contraindication checks, and emergent queries (cardiac arrest, anaphylaxis, airway obstruction) trigger enhanced processing:
- Multi-query fusion — 3 query variations merged via Reciprocal Rank Fusion
- Higher precision thresholds — 0.38 similarity minimum for medication queries
- Pediatric alerts — Weight-based dosing flagged automatically
| Tier | Simple Query | Complex Query | Cost |
|---|---|---|---|
| Free | Haiku 4.5 | Haiku 4.5 | ~$0.0003/query |
| Pro | Haiku 4.5 | Sonnet 4.6 | ~$0.003/query |
Complexity triggers: differential diagnosis, multi-condition interactions, pediatric edge cases, explanation requests.
- Natural language search — Ask in plain English or EMS shorthand ("VFib protocol," "peds seizure dose")
- Jurisdiction-aware — Results scoped to your LEMSA/agency's protocols
- Voice input — Hands-free search with EMS terminology recognition
- Offline mode — Service worker caches protocols for field use without connectivity
- PWA — Install to home screen, no app store required
- Bookmarks and history — Save frequently-used protocols
- Admin dashboard — Agency-level protocol management, user analytics, team management
| 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 for vector search |
| AI Models | Claude Haiku 4.5 / Sonnet 4.6 (Anthropic) |
| Embeddings | Voyage AI voyage-large-2 (1536 dimensions) |
| Auth | Supabase Auth (Google/Apple OAuth) |
| Payments | Stripe (subscription management) |
| Hosting | Netlify (auto-deploy from main) |
| Caching | Upstash Redis (query cache, rate limits) |
- Node.js 20+
- pnpm 9+
- PostgreSQL (or Supabase hosted)
git clone https://github.com/thefiredev-cloud/Protocol-Guide.git
cd Protocol-Guide
pnpm install
cp .env.example .env.local
# Edit .env.local with API keys (see below)
pnpm db:push
pnpm dev
# Server: http://localhost:3001 | Web: http://localhost:8081# Database
DATABASE_URL=postgresql://user:pass@localhost:5432/protocol_guide
# Supabase (Auth + Vector Search)
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
# AI/ML
ANTHROPIC_API_KEY=sk-ant-api03-...
VOYAGE_API_KEY=voyage-...
# Payments (optional for dev)
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# Caching (optional)
UPSTASH_REDIS_REST_URL=https://...
UPSTASH_REDIS_REST_TOKEN=...app/ # Expo Router (file-based routing)
├── (tabs)/ # Tab navigation
│ ├── index.tsx # Search tab — jurisdiction-scoped protocol search
│ └── profile.tsx # Profile — agency selection, subscription
├── admin/ # Agency admin dashboard
│ ├── protocols/ # Protocol management (upload, status, versioning)
│ ├── users/ # Team management (enterprise tier)
│ └── analytics/ # Search analytics, usage metrics
├── tools/ # EMS tools (arrest timer, dosing calculator)
└── oauth/ # OAuth callbacks
server/ # tRPC Backend
├── routers/
│ ├── search.ts # Jurisdiction-scoped semantic search
│ ├── query.ts # Protocol RAG query (Claude + vector search)
│ ├── voice.ts # Voice transcription (EMS terminology)
│ ├── auth.ts # Authentication (Supabase)
│ ├── subscription.ts # Stripe billing
│ └── user.ts # Profile, county/agency selection
├── _core/
│ ├── rag/ # RAG pipeline (search, re-rank, model routing)
│ ├── embeddings/ # Voyage AI + pgvector search
│ ├── claude.ts # Claude SDK (system prompts, model selection)
│ ├── ems-query-normalizer.ts # 150+ EMS abbreviation expansion
│ └── protocol-chunker.ts # Semantic chunking (400-1800 chars)
└── webhooks/ # Stripe webhooks
scripts/ # Protocol ingestion pipeline
├── ingest-ca-protocols.ts # California LEMSA ingestion orchestrator
└── lib/
├── pdf-url-discoverer.ts # LEMSA website crawling
├── pdf-downloader.ts # PDF download with retry + caching
└── protocol-extractor.ts # PDF text extraction + parsing
drizzle/ # Database schema + migrations
shared/ # Cross-stack types and constants
hooks/ # React hooks (search, auth, offline, voice)
components/ # UI components
lib/ # Client utilities
| Script | Description |
|---|---|
pnpm dev |
Start server (3001) + web client (8081) |
pnpm dev:server |
Backend only |
pnpm dev:metro |
Frontend only |
pnpm build |
Build server bundle |
pnpm build:web |
Build PWA for deployment |
pnpm db:push |
Generate and apply Drizzle migrations |
pnpm test |
Unit tests (Vitest) |
pnpm test:e2e |
E2E tests (Playwright) |
pnpm check |
TypeScript type checking |
pnpm lint |
ESLint |
pnpm docker:prod |
All-in-one: API + web + Postgres + Redis (see docs/deployment/DOCKER-ALL-IN-ONE.md) |
| Document | Contents |
|---|---|
| docs/EMS_ARCHITECTURE.md | Jurisdiction model, LEMSA definition, ingestion pipeline, search pipeline, EMS terminology |
| docs/DATABASE.md | Schema documentation, tables, indexes, RLS, vector search |
| docs/BACKEND.md | tRPC routers, RAG pipeline, authentication, middleware |
| docs/FRONTEND.md | Expo Router, NativeWind, jurisdiction UI components |
| CLAUDE.md | AI agent configuration, architecture, code standards |
| CONTRIBUTING.md | Code style, testing, PR process |
| CHANGELOG.md | Release history |
- Netlify + Railway: Auto-deploy from
main; frontend (PWA) on Netlify, API on Railway. - Docker all-in-one:
pnpm docker:prod— single stack (API + web + Postgres + Redis). See docs/deployment/DOCKER-ALL-IN-ONE.md.
PWA capabilities:
- Offline protocol access via service worker
- Install to home screen (no app store)
- Standalone mode (no browser chrome)
- Background sync for queued searches
See CONTRIBUTING.md for code style, testing requirements, and PR process.
Proprietary software. All rights reserved.
Protocol Guide — Jurisdiction-accurate protocol retrieval for EMS professionals.