Architecture¶
System Overview¶
Cadence is a Python application built on FastMCP that serves two interfaces:
- MCP server (stdio) — for AI clients like Claude Desktop
- 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 tokens —
Authorization: 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.