Skip to content

Architecture

System Overview

Cadence is a Python application built on FastMCP that serves two interfaces:

  1. MCP server (stdio) — for AI clients like Claude Desktop
  2. Web application (HTTP) — dashboard, chat, admin panel
┌──────────────────┐     ┌──────────────────────────────────────────┐
│  Claude Desktop   │     │              Cadence Server               │
│  (MCP client)     │────▶│                                          │
└──────────────────┘     │  ┌──────────┐  ┌────────┐  ┌─────────┐  │
                         │  │ MCP Tools │  │ Web UI │  │ REST API│  │
┌──────────────────┐     │  │ (75 tools)│  │ (HTML) │  │ (/api/) │  │
│  Web Browser      │     │  └─────┬────┘  └───┬────┘  └────┬────┘  │
│  (Dashboard/Chat) │────▶│        │           │            │        │
└──────────────────┘     │  ┌─────▼───────────▼────────────▼─────┐  │
                         │  │            Services Layer            │  │
                         │  │  garmin · whoop · strava · analytics│  │
                         │  │  cache · auth · chatbot              │  │
                         │  └─────┬───────────┬────────────┬─────┘  │
                         │        │           │            │        │
                         │  ┌─────▼────┐ ┌───▼────┐ ┌────▼─────┐  │
                         │  │ Database  │ │ Device │ │   LLM    │  │
                         │  │ SQLite/PG │ │  APIs  │ │ Providers│  │
                         │  └──────────┘ └────────┘ └──────────┘  │
                         └──────────────────────────────────────────┘

Project Structure

server.py              # FastMCP server, web routes, ASGI app
config.py              # Environment config & feature flag registry
auth/
  oauth_provider.py    # MCP OAuth2 provider (in-memory + DB-backed)
chatbot/
  api.py               # Streaming chat with agentic tool loop
  setup.py             # LLM provider configuration (LiteLLM)
  tool_runner.py       # Tool executor for chat-initiated tool calls
db/
  models.py            # Database operations (SQLite + PostgreSQL)
  migrations.py        # Schema migrations (25 migrations)
services/
  garmin.py            # Garmin Connect API client
  whoop.py             # WHOOP API client with OAuth
  strava.py            # Strava API client with OAuth
  analytics.py         # Statistical analysis (correlations, ACWR, patterns)
  cache.py             # In-memory TTL cache
  auth.py              # Password hashing, token management, RBAC
  device_config.py     # Dynamic prompt builders based on connected devices
  posthog.py           # Event tracking
tools/
  activity_tools.py    # Unified activity views across devices
  body_tools.py        # Body composition, resting HR, stress
  briefing_tools.py    # Daily briefings and readiness
  chart_tools.py       # Chart rendering for chat UI
  cross_platform_tools.py  # Intelligent multi-device coaching tools
  garmin_tools.py      # Garmin-specific tools (19 tools)
  whoop_tools.py       # WHOOP-specific tools (11 tools)
  strava_tools.py      # Strava-specific tools (4 tools)
  recovery_tools.py    # Recovery scores and HRV trends
  running_tools.py     # Running analytics (volume, VO2max)
  sleep_tools.py       # Sleep data and trends
  strength_tools.py    # Workout logging, PRs, progression
  training_load_tools.py   # Strain, injury risk, week comparison
  workout_tools.py     # Database workout storage
  review_tools.py      # Weekly summaries and goal tracking
  zone_tools.py        # HR and power training zones
  helpers.py           # Shared utilities
prompts/
  coaching.py          # MCP prompt definitions (10 prompts)
templates/             # Jinja2 HTML templates
tests/                 # Test suite

Database

Cadence supports both SQLite (development) and PostgreSQL (production). The database layer auto-detects based on the DATABASE_URL environment variable.

Key Tables

Table Purpose
users User accounts with roles, feature flags, preferences
credentials Encrypted OAuth tokens per device per user
workouts / exercises Strength training data
exercise_library Canonical exercise names per user
conversations / messages Chat history
ai_models Available LLM models
token_usage LLM token consumption tracking
oauth_clients / oauth_tokens MCP OAuth2 state
invite_codes Signup gating
audit_log Security audit trail
email_verification_tokens Email verification
password_reset_tokens Password resets
server_config Auto-generated secrets

Migrations

The db/migrations.py module runs 25 sequential migrations on startup. Each migration is idempotent and supports both SQLite and PostgreSQL syntax.

Authentication

The auth system supports multiple flows:

  • Web sessions — cookie-based (sid=) with HMAC-SHA256 signed tokens (24h TTL)
  • API tokensAuthorization: Bearer <token> for REST API clients
  • MCP OAuth2 — full OAuth2 provider for MCP clients with auth codes, access tokens, and refresh tokens
  • Device OAuth — WHOOP and Strava use standard OAuth2 with encrypted token storage

Passwords are hashed with PBKDF2-HMAC-SHA256 (260,000 iterations). Stored credentials (device tokens, API keys) are encrypted with Fernet.

Caching

An in-memory TTL cache reduces redundant API calls during a session. Cache keys are scoped per-user and per-metric (e.g., garmin:{uid}:vo2max:{date}). Default TTL is 300 seconds.

Feature Flags

Feature flags gate tools, UI sections, and device integrations. They cascade: per-user DB override > global admin setting > env var default. The registry is defined in config.py and automatically reflected in the admin panel and MCP tool gating.