Hackathon backend: spoken hospital requests → Cursor SDK agent orchestration → staff notify + accept/decline → dashboard.
API base: http://localhost:3001
Voice demo page: http://localhost:3001/demo
Frontend contract: API.md · Vapi setup: VAPI-SETUP.md
Story: A doctor is busy. They speak one request. Agents handle the rest. Staff act. Dashboard proves it.
- Ops dashboard —
http://localhost:3001/dashboard(polls requests live) - Doctor voice —
http://localhost:3001/demo(Vapi mic)
- Hook — Hospitals drown in radios and sticky notes. We turn a spoken need into routed, trackable work.
- Voice — Doctor: “Urgent — need a bed moved from room 204 to 310.” Request appears:
triaging→open. - Agents — Show type
physical, urgency, routed tostaff. Three agents: voice intake → triage → routing. - Act — Staff notified → accept →
assigned→in_progress→done. - Second request — “Ventilator in ICU bay 3 is broken.” →
equipment→ biomedical staff. - Close — Voice in. Agents orchestrate. Humans accept. Full hospital ops loop.
POST /api/voice/vapi/simulate
Content-Type: application/json
{
"title": "Need bed moved",
"description": "Room 204 to 310",
"location": "Room 204",
"floor": "2",
"createdByName": "Dr. Sarah Chen",
"createdByRole": "doctor"
}Then: GET /api/requests → POST /api/requests/:id/accept with { "staffId": "staff-1" }.
┌─────────────────┐ ┌──────────────────────────────────────────┐
│ Doctor (Vapi) │────►│ Express API :3001 │
│ /demo mic │ │ POST /api/voice/vapi (webhook) │
└─────────────────┘ │ POST /api/requests │
│ POST /api/requests/voice │
┌─────────────────┐ └───────────────┬──────────────────────────┘
│ Dashboard UI │◄──── poll REST ─────┤
│ (separate) │ GET /api/requests│
└─────────────────┘ ▼
┌──────────────────────────────────────────┐
│ Agent orchestration layer │
│ 1. Voice parse (Vapi tool / transcript) │
│ 2. Triage Agent (Cursor SDK) │
│ 3. Router Agent (Cursor SDK) │
│ Fallback: rule-based if no API key │
└───────────────┬──────────────────────────┘
▼
┌──────────────────────────────────────────┐
│ SQLite · Staff seed · Notifications │
│ accept / decline / status updates │
└──────────────────────────────────────────┘
medical · physical · supply · equipment · specialist
triaging → open → assigned → in_progress → done
Doctors, nurses, staff — not patients.
| Layer | Tech |
|---|---|
| API | Node.js, Express, TypeScript |
| DB | SQLite (better-sqlite3), auto-seeded staff |
| Agents | @cursor/sdk (local or cloud) |
| Voice | Vapi (STT/TTS + tool call webhook) |
| Notify | Console log (+ optional Resend email) |
Build a separate dashboard against this API (CORS is open). Poll every 2–3 seconds.
- Request board — list from
GET /api/requests
Show: title, type, urgency, status, location, floor, assigned name, agent summary. - Request detail —
GET /api/requests/:id+ eligible staff. - Staff actions
- Accept:
POST /api/requests/:id/accept{ "staffId": "staff-1" } - Decline:
POST /api/requests/:id/decline{ "staffId": "..." } - Status:
PATCH /api/requests/:id/status{ "status": "in_progress" | "done" | "cancelled" }
- Accept:
- Staff picker —
GET /api/staffor?role=nurse|doctor|staff - Optional create form —
POST /api/requests(typed) or link to voice page/demo
- Color by urgency (
critical/high/normal/low) - Filter chips by status / type
- Live “just created” highlight when a new id appears after poll
- Show
agent_summary+agent_reasoning(proves orchestration)
| Role | IDs |
|---|---|
| Doctors | doc-1, doc-2, doc-3 |
| Nurses | nurse-1 … nurse-4 |
| Staff | staff-1 … staff-5 |
Full endpoint reference: API.md
npm install
cp .env.example .env # add keys when you have them
npm run dev| Variable | Purpose |
|---|---|
CURSOR_API_KEY |
Real Cursor SDK agents (else rule fallback) |
GITHUB_REPO |
owner/repo for cloud agents (optional) |
VAPI_PUBLIC_KEY |
Web widget |
VAPI_ASSISTANT_ID |
Assistant to start on /demo |
RESEND_API_KEY |
Real email (optional) |
Local Vapi webhooks need a public URL: ngrok http 3001 → see VAPI-SETUP.md.
GET /health → { agents, vapi, cloud, email } flags show what’s configured.
src/
agents/orchestrator.ts # Triage + Router (Cursor SDK)
agents/voiceParser.ts # Transcript → structured fields
routes/requests.ts # CRUD + accept/decline + voice
routes/vapi.ts # Vapi webhook + simulate
routes/staff.ts
services/requestPipeline.ts
services/notification.ts
db.ts # SQLite + seed
public/demo-voice.html # Doctor Vapi UI
Backend is demo-ready: REST, orchestration, voice webhook, accept/decline, seeded staff.
Without Cursor/Vapi keys it still runs (rules + simulate). With keys, the live voice + agent path unlocks for the stage demo.