ChronoCare
From scattered data to clinical clarity in seconds.
Inspiration
Every clinician knows the feeling. A patient arrives in the ER. Five years of data sits in the EHR across dozens of visits, three different providers, hundreds of lab results. The chart has the answer. Nobody has time to read the chart.
Electronic health records are excellent at answering one question: what is happening to this patient right now? Today's vitals. Today's labs. Today's medications. The snapshot is detailed and immediate.
But they systematically miss two questions that matter just as much:
What has been happening? A patient's creatinine drifts from 0.9 to 1.3 mg/dL over 36 months. Each individual result is flagged normal, inside the reference range, no alert fires. Three different clinicians saw three different snapshots. None of them saw the slope. The trajectory. The cascade in progress.
What is coming? Hypertension diagnosed in 2019 became Stage 2 CKD by 2022, but no system flagged the cardiometabolic cascade developing across those three years. A 12-minute appointment does not leave time to read hundreds of FHIR resources. The chart has the answer. Nobody has time to read the chart.
Diagnostic errors are the third leading cause of death in the United States. Handoff failures cause 80% of serious medical errors. These are not technology failures. They are information architecture failures. The data exists. The connections do not get made.
ChronoCare was built to make those connections.
What it does
ChronoCare is a clinical reasoning engine that fills the two missing tenses of patient care. It answers four questions no EHR answers today, in a single conversation, in under 15 seconds.
1. What happened to this patient? ChronoCare fetches a patient's complete FHIR record, normalizes every condition, lab, medication, and encounter into a unified chronological timeline, identifies the 3 to 5 clinical turning points that changed the patient's trajectory, and generates a 200 to 300 word clinical narrative written the way an experienced physician would brief an incoming colleague.
2. What is quietly going wrong right now? The silent deterioration detector analyzes recent signals, not one threshold at a time, but holistically across vitals, labs, and clinical notes together. Blood pressure at 138/88 is technically normal. Creatinine at 1.3 is technically normal. Fatigue mentioned twice in recent notes is easy to miss. Together, they tell a different story. ChronoCare reasons across weak signals the way an experienced clinician would, and flags the pattern before any individual alarm fires.
3. Why did this happen? The root cause analyzer correlates events across the patient's timeline, identifies plausible causal pairs with confidence levels and clinical rationale, and synthesizes a causal hypothesis explaining how the patient arrived at their current state.
4. What should we do next? Recommendations are generated as 3 to 5 patient-specific actions cross-checked against ADA, JNC, KDIGO, and ACC/AHA guidelines. Every recommendation cites specific findings from this patient's data. No generic advice.
The full pipeline runs in 14 to 16 seconds on a warm server. The output is a structured clinical brief covering all four layers: narrative, early warning risk score, causal hypothesis, comorbidity map, guideline gaps, and prioritized recommendations.
ChronoCare is accessible through two surfaces. The first is a custom React web app at sriksven.github.io/chronocare where anyone can run a full analysis on any of four synthetic demo patients. The second is the ChronoCore A2A agent on the Prompt Opinion platform, where clinicians can ask for a patient analysis in plain language inside their existing workspace and get the full brief back in chat.
How we built it
ChronoCare is four replaceable layers held together by open standards.
Data layer
All patient data is synthetic. Four demo patients were generated programmatically using hand-crafted FHIR R4 transaction bundles covering distinct clinical archetypes: a 62-year-old male with hypertension progressing to CKD, a 58-year-old female with Type 2 diabetes and early diabetic nephropathy, a 71-year-old male with CHF and cardiorenal syndrome, and a 45-year-old female as a control case with prediabetes caught early. All four patients live on the HAPI public FHIR R4 sandbox. No PHI anywhere in the system.
Reasoning server
The MCP server is Python 3.11 on Railway, built with Starlette and Uvicorn, exposing 14 tools over Streamable HTTP. The pipeline uses a fan-out / fan-in topology where independent reasoning branches run concurrently via asyncio.gather and asyncio.to_thread. This dropped wall-clock latency from a sequential 25 to 35 seconds to a parallel 14 to 16 seconds on warm runs.
Eight LLM calls run per pipeline, routed across two providers based on task type:
| Task | Model | Reason |
|---|---|---|
| Clinical narrative, weak pattern analysis, causal hypothesis, recommendations | GPT-4o | Prose quality and deep reasoning |
| Turning points, warning report, comorbidity map | Llama-3.3-70b via Groq | Fast structured JSON, lower cost |
| Event correlation, guideline matching | GPT-4o-mini | Accuracy without GPT-4o cost |
| Voice synthesis | OpenAI TTS-1 | Existing API key, natural prosody |
Multi-provider routing also provides partial-failure resilience. A transient OpenAI outage does not kill the four Groq-backed tools.
FHIR resources are normalized using local lookup tables for 37 LOINC codes, 32 ICD-10 codes, and 30 RxNorm codes, converting raw clinical codes into human-readable descriptions before they reach any LLM. Patient IDs are SHA-256 hashed before logging so they never appear in Railway logs.
Agent layer
ChronoCore is an A2A agent configured on Prompt Opinion with GPT-4.1 as its model. Its system prompt encodes a 13-step reasoning protocol that calls the MCP tools in deliberate order, building context at each step. When a clinician asks the General Chat agent for a patient analysis, Prompt Opinion matches the skill, hands off to ChronoCore via A2A, ChronoCore executes the full pipeline by calling the MCP tools, and returns the formatted brief in chat. The FHIR context extension injects the workspace FHIR URL and access token into every MCP request automatically via the FHIRContextMiddleware.
Frontend
The React app was built with Vite, TypeScript, Tailwind CSS, and Framer Motion. It has four pages: a landing page, a plain-English explainer of how it works, a live demo runner with animated pipeline trace, and an admin panel for uploading new FHIR bundles. The design system uses a custom clinical aesthetic: cream background, deep navy ink, teal accent, with Source Serif Pro for display text and JetBrains Mono for data. The frontend calls the backend directly via a public /api/demo/analyze endpoint with CORS open, so no authentication is required to run a demo analysis.
Infrastructure
Two independent GitHub Actions pipelines handle CI/CD. The backend pipeline runs 42 pytest tests and three live smoke checks on every push to main. The frontend pipeline runs TypeScript checks, Vite builds, and deploys to GitHub Pages automatically. Backend deploys to Railway are manual via railway up. The full repo is open source.
Challenges we ran into
Prompt Opinion OAuth credentials. The original plan used Prompt Opinion's workspace FHIR server as the data source, which would have allowed the SHARP context extension to inject live workspace credentials into every MCP call. We could not generate valid OAuth client credentials for the workspace FHIR server in time. The pivot to HAPI public R4 sandbox was made late, which required rewriting the FHIR client's auth logic to treat the token as optional, updating the context middleware to fall back gracefully to environment variables, and regenerating all four demo patient bundles against the new endpoint. This cost roughly six hours.
Parallelizing the reasoning pipeline. The initial implementation ran all 13 tools sequentially, which produced correct results but at 25 to 35 seconds of wall-clock latency. The fan-out topology required careful analysis of data dependencies between tools to identify which branches could run concurrently and which needed to wait for upstream outputs. The trace recorder that logs each tool call's result also needed a mutex guard to prevent concurrent branches from racing when appending entries to the shared trace list.
Prompt engineering for clinical specificity. Early versions of the narrative and recommendation prompts produced outputs that sounded clinical but cited no specific data. The prompts went through multiple iterations before reliably producing outputs that reference specific dates, specific lab values, and specific medication changes from the patient's actual record. The key was an explicit anti-hallucination instruction in every reasoning prompt: "Only reference findings present in the data provided. Do not infer information not present."
Cold start latency. Railway's free tier suspends containers after 15 minutes of inactivity. The first request after a cold start takes approximately 30 seconds before any pipeline work begins. For the demo this is acceptable, but it required adding a cold-start warning to the frontend so users are not confused by the delay.
Accomplishments that we are proud of
The parallel pipeline topology. The fan-out / fan-in design that runs five concurrent reasoning branches via asyncio is the piece of engineering we are most proud of. It required understanding the exact data dependencies between all 13 tools and is what makes 14 to 16 second warm latency possible despite 8 LLM calls.
Multi-model routing that actually makes sense. The GPT-4o and Groq Llama-3.3-70b split is not arbitrary. GPT-4o handles the four tasks where output quality directly affects clinical credibility: the narrative, the pattern detection, the causal reasoning, and the recommendations. Llama-3.3-70b handles the four structured JSON extraction tasks where prose quality does not matter and speed does. This produces a pipeline that costs approximately $0.09 per full analysis and runs in under 15 seconds.
Four clinical archetypes that tell different stories. John Doe demonstrates a slow multi-year cardiometabolic cascade. Maria Rodriguez shows diabetes management with emerging nephropathy. Robert Chen presents a complex cardiorenal syndrome with multiple interacting conditions. Sarah Williams is a control case showing that ChronoCare does not over-flag healthy patients. Together they cover the range of scenarios the system was designed for.
A production system, not a demo. ChronoCare is fully live. Both the MCP server and the ChronoCore A2A agent are published to the Prompt Opinion Marketplace and publicly installable. The React frontend is deployed on GitHub Pages. The FHIR data is on a real public FHIR server. All four patients are analyzable right now at the live URL.
What we learned
The "AI Factor" in healthcare is specifically about cross-signal reasoning. Rule-based systems are genuinely good at single-threshold alerts. Where they fail completely is in reasoning across multiple individually-normal signals that together indicate a pattern. That is the specific gap where LLMs add irreplaceable value in clinical settings, and it is where we focused the most prompt engineering effort.
FHIR is both the right standard and a genuinely difficult one. The R4 spec is comprehensive but the real-world data quality on even a reference implementation like HAPI varies significantly. Building a normalizer that handles missing codes, malformed dates, empty resource arrays, and inconsistent reference formats gracefully was more work than expected and is probably the most underestimated part of any real FHIR integration project.
Prompt temperature matters more than model choice for clinical reliability. Using temperature 0.2 for reasoning steps and 0.5 for narrative generation made a larger difference to output consistency than switching between model sizes. The reasoning steps need to be deterministic enough to cite the same data points on repeated runs. The narrative steps need enough variation to not sound like a template.
Open standards make the architecture genuinely replaceable. Because the reasoning server speaks MCP and FHIR R4 with no vendor-specific code, the FHIR backend can be swapped from HAPI public to any Epic or Cerner endpoint by changing one environment variable. The agent layer can be swapped from Prompt Opinion to any A2A-compliant platform. This is not a theoretical benefit, we actually exercised it when we switched FHIR backends mid-build.
What's next for ChronoCare
Live EHR integration. The architecture already supports any FHIR R4 endpoint. The immediate next step is testing against Epic's sandbox environment and Cerner's developer program to validate that the normalizer and client handle real EHR data edge cases correctly.
Specialty-specific reasoning modules. The current pipeline is designed for general medicine with a focus on cardiometabolic conditions. Oncology, psychiatry, and pediatrics each have domain-specific turning points, guideline sets, and deterioration patterns that warrant dedicated reasoning modules.
Streaming brief output. The current pipeline returns the full brief as a single JSON response. Streaming each section as it completes, narrative first, then early warning, then recommendations, would make the latency feel much shorter even if the wall-clock time is the same.
Longitudinal tracking. Right now ChronoCare generates a brief on demand. A scheduled version that runs every 24 hours per patient, diffs the output against the previous brief, and surfaces only what changed would be a materially different product for inpatient monitoring teams.
Federated deployment. The MCP server is designed to run against any FHIR endpoint. A hospital system could deploy ChronoCare inside their own infrastructure, pointed at their internal FHIR server, with no patient data ever leaving their network. The Prompt Opinion marketplace listing makes discovery easy. The open-source codebase makes self-hosting possible.
Log in or sign up for Devpost to join the conversation.