Skip to main content

Overview

Nurse Handoff Helper integrates with AI providers to power intelligent features like handoff note generation and medical image analysis. Currently, the system supports Claude (Anthropic) with the latest Sonnet 4 model.

Supported Providers

Claude (Anthropic)

Claude Sonnet 4

Model: claude-sonnet-4-20250514Capabilities:
  • Text generation for handoff summaries
  • Vision analysis for medical images and whiteboards
  • Structured data extraction
  • Trend analysis and clinical reasoning
Claude is the primary and recommended AI provider for this application. It excels at:

Medical Context

Understanding clinical terminology and medical records

Vision Analysis

Reading handwritten notes and whiteboard images

Structured Output

Generating organized, scannable handoff notes

Safety Focus

Identifying and highlighting critical safety concerns

Configuration

Environment Setup

From ~/workspace/source/server/index.js:8-29:
.env
# Claude/Anthropic API Key
ANTHROPIC_API_KEY=sk-ant-api03-...

# Server Configuration
PORT=3001

# Supabase Configuration (for data persistence)
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
SUPABASE_SERVICE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Keep API Keys Secret - Never commit .env files to version control. The .gitignore file should include .env.

Initialize Client

The backend initializes the Anthropic client at startup:
import Anthropic from "@anthropic-ai/sdk";

const anthropic = process.env.ANTHROPIC_API_KEY
  ? new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })
  : null;
From ~/workspace/source/server/index.js:26-29

Health Check

Verify AI provider configuration with the health endpoint:
curl http://localhost:3001/api/health
From ~/workspace/source/server/index.js:52-60

API Endpoints

Text Generation

Summarize Patient Record

Endpoint: POST /api/summarize-record/claude From ~/workspace/source/server/index.js:145-296:
fetch('http://localhost:3001/api/summarize-record/claude', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    patientData: {
      demographics: { name: "John Doe", age: 65, sex: "M" },
      vitals: { temp: [98.6], heartRate: [72] },
      medications: ["Lisinopril", "Metformin"],
      tasks: [/* task array */]
    },
    previousNotes: "Previous handoff content...",
    imageAnalysis: "Optional image analysis..."
  })
});
Model Configuration:
const message = await anthropic.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 2048,
  messages: [
    {
      role: "user",
      content: promptContent,
    },
  ],
});
The prompt sent to Claude includes:
  1. Role Definition: “You are a clinical nursing assistant”
  2. Task Description: Analyze patient record and create handoff summary
  3. Structure Requirements: 6 key sections (overview, status, labs, meds, tasks, safety)
  4. Emphasis on Trends: “WE CARE A LOT ABOUT TRENDS”
  5. Task Status Details: Total, completed, and outstanding tasks with priorities
  6. Comparison Logic: If previousNotes provided, generate “Changes Since Last Handoff”
  7. Image Integration: If imageAnalysis provided, merge with electronic record
From ~/workspace/source/server/index.js:171-275

Extract Structured Data

Endpoint: POST /api/extract-patient-data/claude Extract structured patient information from unstructured text or analysis. From ~/workspace/source/server/index.js:1020-1103:
fetch('http://localhost:3001/api/extract-patient-data/claude', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    summary: "Patient John Doe, 65M, admitted with chest pain. BP 132/78, HR 72. Allergies: Penicillin. DNR status. On Lisinopril and Metformin."
  })
});

Vision Analysis

Analyze Medical Image

Endpoint: POST /api/analyze-image/claude From ~/workspace/source/server/index.js:63-142:
const formData = new FormData();
formData.append('image', selectedFile);

const response = await fetch(
  'http://localhost:3001/api/analyze-image/claude',
  { method: 'POST', body: formData }
);

const data = await response.json();
Image Processing:
const base64Image = req.file.buffer.toString("base64");
const mediaType = req.file.mimetype;

const message = await anthropic.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 2048,
  messages: [
    {
      role: "user",
      content: [
        {
          type: "image",
          source: {
            type: "base64",
            media_type: mediaType,
            data: base64Image,
          },
        },
        {
          type: "text",
          text: `You are a clinical nursing assistant analyzing a handoff document or whiteboard...`,
        },
      ],
    },
  ],
});
From ~/workspace/source/server/index.js:79-130

Error Handling

Missing Configuration

if (!anthropic) {
  return res.status(503).json({
    error: "Claude API is not configured. Please add ANTHROPIC_API_KEY to .env file.",
  });
}
From ~/workspace/source/server/index.js:68-73 and similar checks throughout

API Errors

{
  "error": "Failed to analyze image with Claude",
  "details": "Invalid API key provided"
}
From ~/workspace/source/server/index.js:134-140 and ~/workspace/source/server/index.js:289-295

Model Details

Claude Sonnet 4

Model ID: claude-sonnet-4-20250514Max Tokens: 2048 (configurable)Input: Text and images (base64 encoded)Vision: Supports image analysis up to 10MBContext Window: Large context for comprehensive patient records

Token Usage

Typical token consumption:

Token Estimates

Handoff Note Generation:
  • Input: 500-1500 tokens (patient data + prompts)
  • Output: 400-800 tokens (handoff summary)
  • Total: ~1000-2300 tokens per generation
Image Analysis:
  • Input: 1000-2000 tokens (image + prompt)
  • Output: 300-600 tokens (analysis)
  • Total: ~1300-2600 tokens per image
Data Extraction:
  • Input: 200-500 tokens
  • Output: 100-300 tokens
  • Total: ~300-800 tokens
Images are processed efficiently using Claude’s vision API. The model automatically handles image encoding and processing.

Rate Limits

Anthropic API rate limits vary by tier. For production use:
1

Monitor Usage

Track API calls and token consumption
2

Implement Caching

Cache generated summaries to reduce redundant calls
3

Upgrade Tier

Consider higher API tiers for busy hospitals

Provider Architecture

The API uses a provider-specific path structure to support potential future AI providers:
// Current implementation
app.post("/api/summarize-record/claude", async (req, res) => {
  // Claude implementation
});

app.post("/api/analyze-image/claude", async (req, res) => {
  // Claude vision implementation
});
The API design allows for future expansion to additional AI providers while maintaining the same interface pattern.

Best Practices

  • Store keys in environment variables only
  • Never commit .env files
  • Use different keys for development and production
  • Rotate keys periodically
  • Monitor for unusual usage patterns
  • Check if client is initialized before API calls
  • Provide clear error messages to users
  • Log errors for debugging
  • Implement retry logic for transient failures
  • Have fallback behavior when AI is unavailable
  • Set appropriate max_tokens limits
  • Cache frequent queries
  • Process images at reasonable resolution
  • Consider batch processing for multiple patients
  • Monitor response times
  • Be specific about desired output format
  • Emphasize critical information (tasks, safety)
  • Provide examples in prompts when needed
  • Use structured prompts for consistency
  • Test prompts with diverse patient scenarios

Troubleshooting

Cause: API key not configuredSolution: Set ANTHROPIC_API_KEY in .env file and restart server
# Check .env file exists
ls -la .env

# Verify key is set
grep ANTHROPIC_API_KEY .env

# Restart server
npm run dev
Cause: Invalid or expired API keySolution: Get a new API key from Anthropic Console
  1. Visit https://console.anthropic.com/
  2. Generate new API key
  3. Update .env file
  4. Restart server
Cause: Too many requests in short timeSolution: Implement rate limiting and caching
  • Add delays between requests
  • Cache generated summaries
  • Upgrade API tier if needed
Cause: Image too large, wrong format, or poor qualitySolution:
  • Ensure image is under 10MB
  • Use supported formats (JPEG, PNG)
  • Check image quality and resolution
  • Verify image is not corrupted

Next Steps

Patient Handoff

Learn how AI generates handoff notes

Image Analysis

Understand vision-based document analysis

Build docs developers (and LLMs) love