Skip to content

URSA-OSCAR

Self-hosted CPAP analytics with optional AI-assisted interpretation. A modernized workflow companion to OSCAR.

License: GPL v3 Docker Release

URSA-OSCAR reads ResMed AirSense CPAP data and provides:

  • Browser-based daily and trend analysis
  • Multivariate statistical analysis (partial correlation, lag analysis)
  • Predictive modeling with explicit confidence intervals
  • Provider-ready PDF reports with methodology disclosure
  • Optional AI assistant (Claude, OpenAI, Gemini, OpenRouter, Groq, local LLMs) grounded in your data via MCP tools

It does this as a self-hosted Docker stack. Your CPAP data never leaves your hardware unless you point an external AI provider at it.


Why URSA-OSCAR exists

OSCAR is the gold standard for desktop CPAP analysis. URSA-OSCAR isn't a replacement — it addresses different workflow needs: 24/7 automated ingestion, longitudinal statistical analysis beyond OSCAR's scope, conversational query interface, and clinician-ready report generation.

If you're satisfied with OSCAR's desktop workflow, you don't need URSA-OSCAR. If you want web access, automation, AI integration, or analytical capabilities OSCAR doesn't provide, URSA-OSCAR is built for that.


Screenshots

All screenshots below are captured from a live URSA-OSCAR 1.1.x stack against real CPAP data. The architecture diagram is a hand-authored SVG of the actual four-container topology.

Architecture overview — four containers, one /data volume

Daily View Trends page
Daily View — per-night detail with EventRug timeline + time-series charts Trends — single-metric regression, correlations, lag analysis, predictions
AI assistant Reports
AI chat panel — conversational queries, grounded in your data via MCP tools Reports — provider-ready PDF templates with methodology disclosure
Help system Settings → AI
Help system — 37 in-app topics across 7 sections, AI-assistant accessible AI provider configuration — bring your own key, encrypted at rest

Quick start

New to Docker? Don't start here. Go to INSTALL.md for a full sequential walkthrough — your platform's guide explains every step, including a "what is Docker?" concepts page if you want to understand what you're doing.

Familiar with Docker? Three commands:

# Get the compose file
curl -fsSL https://raw.githubusercontent.com/burrellka/URSA-OSCAR/main/infra/docker-compose.production.yml -o docker-compose.yml

# Edit the two volumes: blocks (api + watcher) to point at your data folder
# and CPAP backup folder. The comment block at the top of the file has
# per-OS path examples (Windows / macOS / Linux).

docker compose pull && docker compose up -d

Then visit http://localhost:5063. First visit lands on /setup — pick an operator password (≥12 chars, no recovery, store in a password manager). The api container auto-generates its own Fernet master key, JWT signing secret, and service tokens on first boot. No manual key ceremony.

Per-platform walkthroughs (sequential, with what-success-looks-like at each step):

Platform Guide
Windows 11 + Docker Desktop Docs/install/windows.md
macOS + Docker Desktop Docs/install/macos.md
Linux + Docker Engine Docs/install/linux.md
TrueNAS SCALE + Dockge Docs/install/truenas.md
Synology / QNAP NAS Docs/install/synology.md
Troubleshooting Docs/install/troubleshooting.md
Concepts (what is Docker / a container / a bind mount) Docs/install/concepts.md

Optional second-day add-on — connect claude.ai or Claude Code as an external AI client via MCP + OAuth: Docs/install/mcp-optional-addon.md. Set it up after the analytics stack is running. The default compose has it commented out; you opt in.

Once URSA-OSCAR is running, the in-app /help page has 37 topics covering every feature in detail.


Architecture

Four containers sharing a single /data volume:

  • api — FastAPI backend, DuckDB analytics, AI proxy, PDF generation, sole writer of the database (per ADR-004)
  • web — nginx + React 18 + uPlot UI
  • mcp — Model Context Protocol server (FastMCP + SSE + OAuth 2.1 + PKCE), exposes 17 analytical tools to AI assistants
  • watcher — auto-import daemon that polls a bind-mounted CPAP source and triggers async imports

Single-tenant by design. See frontend/src/help/content/arch-single-tenant.md for the trust boundary discussion.

The full architecture deep-dive lives in Docs/30-developer-guide.md and the in-app Help → Architecture and deployment section.


Documentation

Everything URSA-OSCAR does is documented in-app at /help. 37 topics across 7 sections:

Section Topics Browse on GitHub
Getting started 4 frontend/src/help/content/
Using URSA-OSCAR 8 feature-by-feature guides
Understanding the data 5 what AHI / pressure / leak metrics mean
Methodology 6 every statistical method, verbatim with PDF reports
Architecture and deployment 5 single-tenant, network security, multi-instance, deployment
Troubleshooting 5 import, watcher, AI chat, MCP, password recovery
About URSA-OSCAR 4 credits, license, version, future direction

The same Help content is queryable by AI assistants via the get_help_topic MCP tool — they can read URSA-OSCAR's own documentation when answering questions about it.

Maintainer-facing docs:


How URSA enables AI-native CPAP management

URSA was built around a specific problem: CPAP therapy generates structured data nightly, but turning that data into sustained understanding (what is working, what is not, what to try next) requires consistent interpretation that most patients can't do alone. Sleep clinics see patients briefly every few months. The patient lives with the therapy every night. URSA closes that gap by making the data continuously available to an AI conversation the patient drives.

The primary use case: AI as informed thinking partner

URSA's data layer is exposed through the Model Context Protocol. Any MCP-capable AI client (Claude, Claude Code, or other compatible clients) can connect to a URSA deployment and read the operator's nightly data, sleep studies, treatment history, and manual logs in real time. The operator typically configures a dedicated AI conversation with a focused system prompt describing their condition, history, and goals, plus relevant clinical artifacts (sleep study reports, titration data, equipment specifications). That conversation then serves as an ongoing informed thinking partner: interpreting trends, flagging anomalies, helping the operator prepare for sleep clinic appointments, and explaining what the data is actually showing.

The conversation is not a replacement for clinical care. It is a specialized AI surface with sustained access to the operator's own data, doing what the operator alone cannot reliably do every morning without help: synthesize last night's numbers against the prior weeks, notice patterns, and translate raw data into questions worth asking a clinician.

This is the use case that motivated the project. The operator built URSA after years of intermittent CPAP success, multiple machines and masks, periods of giving up entirely, with OSCAR providing the data but no path to consistent interpretation. With URSA connected to a properly-prompted Claude conversation, that interpretation became sustained and routine, and the therapy started working.

The secondary use case: in-app AI assistant

Not every deployment can expose a public MCP endpoint. Some users run URSA on a home network behind NAT, without Cloudflare Tunnel or equivalent, and have no easy way to connect an external AI client.

For those deployments, URSA includes a built-in AI assistant accessible from the web UI. The assistant uses any compatible LLM provider (Anthropic, OpenAI-compatible cloud providers, or a local model running via LM Studio, Ollama, or any OpenAI-compatible local endpoint). The assistant has access to the same data the external client would have access to through MCP, so the in-app experience is functionally equivalent.

The in-app assistant is the fallback path. The external MCP-connected conversation is the primary path. Both work; the external path delivers more capability because external clients (particularly Claude with project knowledge and longer context windows) can carry richer operator-specific context than the in-app surface can hold.

What this enables in practice

The pattern lets a CPAP patient operate as their own informed advocate. Sleep clinics see patients for fifteen minutes every six months. The patient lives with the therapy every night. URSA plus a properly configured AI conversation closes the asymmetry: the patient walks into their appointment with weeks of synthesized data, specific questions about specific nights, and a clear sense of what they've already tried.

The architectural pattern that enables this, MCP-exposed analytical data accessible to specialized AI conversations, is documented as a reusable template at github.com/burrellka/mcp-server-template. URSA is the reference implementation of that pattern for sleep apnea therapy.


What URSA-OSCAR isn't

  • A medical device. Not FDA / CE / TGA-cleared. Not a substitute for clinical judgment. Not a diagnostic tool.
  • A multi-tenant system. Single operator, single instance. Households with multiple CPAP users run multiple instances (documented pattern).
  • A cloud service. Self-hosted only. No cloud sync, no SaaS option.
  • A replacement for OSCAR. Different workflow, different audience.

Attribution

URSA-OSCAR is built on the file-format work of the OSCAR project — the open-source CPAP data viewer that figured out how to read ResMed's proprietary SD card format. Without OSCAR, this wouldn't exist. The "OSCAR" in URSA-OSCAR is that attribution.

URSA-OSCAR is independent of the OSCAR project — different codebase, different deployment model (self-hosted server vs. desktop application), different feature scope. URSA-OSCAR is downstream of OSCAR's file-format work, not a fork or replacement.

GPL-3.0 license matches OSCAR's, preserving the copyleft.


License

URSA-OSCAR is licensed under GNU GPL-3.0-or-later. The full license text is in LICENSE; the project copyright notice and OSCAR-project acknowledgement is in COPYRIGHT.


Contributing

URSA-OSCAR is currently maintained by a single developer. Contributions are welcome but should align with the architectural posture documented in frontend/src/help/content/arch-overview.md and the ADRs.

Pull requests should reference an issue first for anything beyond a typo or clear bug fix. The developer guide is the easiest entry point for understanding how a change spans the four containers.


Acknowledgments

  • The OSCAR community for showing what CPAP analytics could be, and for years of reverse-engineering ResMed's SD card format
  • Anthropic for Claude, used heavily as a development collaborator during URSA-OSCAR's construction
  • The open-source ecosystem URSA-OSCAR builds on: Python, FastAPI, DuckDB, pyedflib, MNE, NumPy / SciPy / pandas / scikit-learn, WeasyPrint, FastMCP, React 18, Vite, TypeScript, uPlot, lucide-react, react-markdown + KaTeX + highlight.js, passlib + python-jose, httpx, the Anthropic and OpenAI Python SDKs

Not affiliated with ResMed, the OSCAR project, Anthropic, OpenAI, Google, or any other entity referenced in URSA-OSCAR's code or documentation.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages