Skip to content

Healthcare Scribe Walkthrough

Build a HIPAA-compliant medical transcription agent.

Overview

This walkthrough demonstrates building an ambient medical scribe that:

  • Transcribes patient encounters
  • Extracts clinical information
  • Detects and handles PHI
  • Generates structured clinical notes

Prerequisites

  • GateFlow account with HIPAA BAA
  • Admin API key for agent creation
  • Audio recording capability

Step 1: Create the Agent

Create a HIPAA-compliant agent with appropriate permissions:

bash
curl -X POST https://api.gateflow.ai/v1/mcp/agents \
  -H "Authorization: Bearer gw_prod_admin_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Medical Scribe",
    "description": "HIPAA-compliant medical transcription agent",
    "permissions": {
      "tools": [
        "voice/pipeline",
        "llm/chat"
      ],
      "models": [
        "whisper-1",
        "gpt-5.2"
      ],
      "pipelines": [
        "ambient-scribe"
      ],
      "data_classification": [
        "phi"
      ]
    },
    "limits": {
      "audio_minutes_daily": 480,
      "cost_daily": 500.00
    },
    "compliance": {
      "hipaa": true,
      "audit_level": "full",
      "data_retention_days": 2555
    }
  }'

Save the returned agent_id and api_key.

Step 2: Set Up the Client

python
from gateflow_mcp import MCPClient
import base64

# Initialize client
client = MCPClient(
    agent_id="agent_medical_scribe",
    api_key="gf-agent-xyz789..."
)

# Verify HIPAA compliance
whoami = client.call_tool("self_inspect/whoami", {})
assert whoami["compliance"]["hipaa"] == True
print(f"HIPAA-compliant agent: {whoami['name']}")

Step 3: Process a Patient Encounter

python
def process_encounter(audio_file: str, encounter_metadata: dict):
    """Process an audio recording of a patient encounter."""

    # Read and encode audio
    with open(audio_file, "rb") as f:
        audio_b64 = base64.b64encode(f.read()).decode()

    # Process through ambient-scribe pipeline
    result = client.call_tool(
        name="voice/pipeline",
        arguments={
            "audio": audio_b64,
            "template": "ambient-scribe",
            "context": {
                "encounter_type": encounter_metadata.get("type", "office_visit"),
                "specialty": encounter_metadata.get("specialty", "general"),
                "patient_id": encounter_metadata.get("patient_id"),  # For audit
                "provider_id": encounter_metadata.get("provider_id")
            }
        }
    )

    return result

# Usage
result = process_encounter(
    "patient_visit.mp3",
    {
        "type": "office_visit",
        "specialty": "internal_medicine",
        "patient_id": "PAT-12345",
        "provider_id": "DR-67890"
    }
)

Step 4: Handle the Response

python
def process_scribe_result(result):
    """Process and display scribe results."""

    # Raw transcription
    print("=== Transcription ===")
    print(result["transcription"])
    print()

    # Extracted clinical information
    print("=== Clinical Summary ===")
    clinical = result["structured_note"]

    print(f"Chief Complaint: {clinical.get('chief_complaint', 'N/A')}")
    print(f"Duration: {clinical.get('duration', 'N/A')}")

    print("\nSymptoms:")
    for symptom in clinical.get("symptoms", []):
        print(f"  - {symptom}")

    print("\nMedications Discussed:")
    for med in clinical.get("medications_mentioned", []):
        print(f"  - {med}")

    print("\nAllergies Noted:")
    for allergy in clinical.get("allergies_mentioned", []):
        print(f"  - {allergy}")

    # PHI Detection
    print("\n=== PHI Detection ===")
    for finding in result.get("pii_detected", []):
        print(f"  - {finding['type']}: {finding.get('redacted_value', '[REDACTED]')}")

    # Compliance
    print("\n=== Compliance ===")
    print(f"Audit ID: {result['audit_id']}")
    print(f"HIPAA Compliant: {result['compliance']['hipaa']}")

    return clinical

clinical_data = process_scribe_result(result)

Step 5: Generate Clinical Note

python
def generate_soap_note(clinical_data: dict, transcription: str):
    """Generate a SOAP note from clinical data."""

    result = client.call_tool(
        name="llm/chat",
        arguments={
            "model": "gpt-5.2",
            "messages": [
                {
                    "role": "system",
                    "content": """You are a medical documentation assistant.
Generate a properly formatted SOAP note from the clinical data.
Use standard medical terminology and abbreviations.
Do not include any PHI in identifiable form."""
                },
                {
                    "role": "user",
                    "content": f"""Generate a SOAP note from this data:

Clinical Summary:
{json.dumps(clinical_data, indent=2)}

Original Transcription:
{transcription[:2000]}"""
                }
            ],
            "temperature": 0.3
        }
    )

    return result["content"]

soap_note = generate_soap_note(clinical_data, result["transcription"])
print(soap_note)

Example Output:

SOAP NOTE

SUBJECTIVE:
Patient presents with chief complaint of headache x 3 days. Patient
describes pain as throbbing, located in bilateral temples, rated 6/10.
Associated symptoms include fatigue and mild photophobia. Patient reports
taking ibuprofen with minimal relief.

OBJECTIVE:
[To be completed by provider]

ASSESSMENT:
1. Tension-type headache, likely
2. Rule out migraine

PLAN:
1. Continue ibuprofen 400mg q6h PRN
2. Increase hydration
3. Consider migraine prophylaxis if headaches persist
4. Return in 2 weeks or sooner if symptoms worsen

Step 6: Integration with EHR

python
def export_to_ehr(encounter_id: str, soap_note: str, clinical_data: dict):
    """Export to electronic health record."""

    # Format for EHR system (example: HL7 FHIR)
    fhir_resource = {
        "resourceType": "DocumentReference",
        "status": "current",
        "type": {
            "coding": [{
                "system": "http://loinc.org",
                "code": "34117-2",
                "display": "History and physical note"
            }]
        },
        "content": [{
            "attachment": {
                "contentType": "text/plain",
                "data": base64.b64encode(soap_note.encode()).decode()
            }
        }],
        "context": {
            "encounter": [{
                "reference": f"Encounter/{encounter_id}"
            }]
        }
    }

    # Also store structured data
    structured_resource = {
        "resourceType": "Observation",
        "code": {
            "text": "Clinical extraction"
        },
        "valueString": json.dumps(clinical_data)
    }

    return fhir_resource, structured_resource

Step 7: Audit Trail

python
def get_encounter_audit(encounter_id: str):
    """Retrieve audit trail for an encounter."""

    # Query audit logs
    response = requests.get(
        f"https://api.gateflow.ai/v1/mcp/agents/{client.agent_id}/audit-log",
        headers={"Authorization": f"Bearer {admin_key}"},
        params={
            "context.patient_id": encounter_id,
            "start_date": "2026-02-01",
            "end_date": "2026-02-16"
        }
    )

    audit_entries = response.json()["entries"]

    print(f"Audit trail for {encounter_id}:")
    for entry in audit_entries:
        print(f"  {entry['timestamp']}: {entry['action']}")
        print(f"    Tool: {entry['tool']}")
        print(f"    Cost: ${entry['cost']:.4f}")

    return audit_entries

Complete Example

python
import json
import base64
from gateflow_mcp import MCPClient

def run_medical_scribe(audio_file: str, metadata: dict):
    """Complete medical scribe workflow."""

    client = MCPClient(
        agent_id="agent_medical_scribe",
        api_key="gf-agent-xyz789..."
    )

    # 1. Process audio
    with open(audio_file, "rb") as f:
        audio_b64 = base64.b64encode(f.read()).decode()

    result = client.call_tool(
        name="voice/pipeline",
        arguments={
            "audio": audio_b64,
            "template": "ambient-scribe",
            "context": metadata
        }
    )

    # 2. Generate SOAP note
    soap_note = client.call_tool(
        name="llm/chat",
        arguments={
            "model": "gpt-5.2",
            "messages": [{
                "role": "system",
                "content": "Generate a SOAP note from this clinical data."
            }, {
                "role": "user",
                "content": json.dumps(result["structured_note"])
            }],
            "temperature": 0.3
        }
    )

    # 3. Return complete result
    return {
        "transcription": result["transcription"],
        "clinical_summary": result["structured_note"],
        "soap_note": soap_note["content"],
        "phi_detected": result.get("pii_detected", []),
        "audit_id": result["audit_id"],
        "cost": result["usage"]
    }

# Run the scribe
output = run_medical_scribe(
    "patient_encounter.mp3",
    {"patient_id": "PAT-12345", "provider_id": "DR-67890"}
)

print(json.dumps(output, indent=2))

Security Considerations

  1. HIPAA BAA Required - Ensure BAA is in place
  2. PHI Handling - Never log or display unredacted PHI
  3. Access Control - Limit agent access to authorized staff
  4. Audit Everything - Maintain complete audit trail
  5. Data Retention - Follow HIPAA retention requirements
  6. Encryption - All data encrypted in transit and at rest

Next Steps

Built with reliability in mind.