Self-hosted · AGPL-3.0 · single binary

Your training data.
Your server.

Cairn is a self-hosted, multi-source activity tracker. Pull from Strava, Garmin, file uploads and manual entry — then merge every source of the same workout, field by field, under rules you control.

No SaaS lock-in. No data sold. One Go binary serves the API and the web UI; provider workers run as separate processes.

Cairn dashboard — activity feed, training load, and segment leaderboard
Strava Garmin GPX / TCX / FIT Manual entry ActivityPub federation (beta) MCP for agents
Why Cairn exists
Your effort shouldn't be a subscription

Cairn started with a familiar frustration. Years of runs, rides and hikes — your heart rate, your routes, your progress — end up on platforms that treat them as their asset: gated behind logins, rationed through APIs, and increasingly reserved for whichever subscription tier you're willing to pay for this year.

The pattern rarely reverses. Prices climb, features you relied on move up a tier, the product slowly bends away from the people who use it — and switching means leaving your history behind. None of that is surprising anymore. It's just not how your own training story should work.

Cairn is the alternative: an open-source tracker that runs on your hardware. It imports your full history while the doors are open, keeps recording from any device or file you throw at it, and stores everything in a database you can query, back up and export at will. If a platform changes its terms tomorrow, your archive doesn't notice.

No gatekeeping. No tiers. No exit fees. Just your data, on your server.

Everything in one place
One workout, every source — reconciled

Cairn ingests the same activity from multiple providers and merges it per-field under a policy you set. Your edits are always preserved.

Per-field merge engine

Title from one source, GPS from another, power from a third — each field group resolves to the best source via a configurable priority list.

Multi-source import

Strava & Garmin via per-user OAuth; GPX/TCX/FIT uploads; manual entry. Everything funnels through one ingest pipeline.

Segments & best-efforts

PostGIS segment matching with leaderboards and ranks, plus automatic best-effort and personal-record detection.

Training load

CTL / ATL / TSB computed from your full history — fitness, fatigue and form, on charts that stay yours.

Social, your way

Follow, feeds, profiles, kudos, comments, clubs and moderation — plus optional ActivityPub federation across instances.

Federation: beta

You own the data

Streams in TimescaleDB, raw blobs in your object store, export anytime. Self-hosted means self-owned.

Supported today
Platforms & data fields

Four ways in — and every one lands in the same ingest pipeline, so a file upload or manual entry merges exactly like a provider import.

SourceConnectionWhat comes in
Strava Per-user OAuth, webhook-driven sync Activities, sensor streams, laps, segment efforts, photos
Garmin Connect Per-user OAuth through the standalone Garmin worker Activities with full sensor streams and laps
File upload GPX, TCX and FIT files Anything your device or another platform exports
Manual entry Web form The same first-class fields — no recording needed

Summary metrics

Distance, moving & elapsed time, elevation gain and loss, average & max speed, heart rate, power (average, max, normalized), cadence, temperature, calories, TSS & intensity factor, pool lengths & strokes.

Time-series streams

GPS track, altitude, speed, heart rate, power, cadence, grade, temperature, left/right balance, torque effectiveness, pedal smoothness, vertical oscillation, ground contact time, stride length, respiration rate, core temperature.

Computed by Cairn

Segments & leaderboards, best efforts, personal records, training load (CTL / ATL / TSB), laps, start-place geocoding, photos & attachments — across 18 sports with their disciplines.

Roadmap
More providers on the way

Providers are standalone workers that speak a small proto + NATS contract, so a new platform never touches the core. These are next in line — ordered by demand, no dates promised.

Polar Flow

Import via Polar AccessLink for the Vantage, Pacer and Grit X lines.

Planned

Suunto

Watch and dive-computer workouts through the Suunto partner API.

Planned

COROS

Pace, Apex and Vertix activities via the COROS training API.

Planned

Wahoo

Rides and workouts from ELEMNT head units via the Wahoo Cloud API.

Exploring

Apple Health

Apple Watch workouts — likely via companion export, as there is no server-side API.

Exploring

Your provider here

Implement the worker contract in any language and plug it in — the Python Garmin worker is the template.

Contribute

Also watching: Zwift, Fitbit, Whoop, Oura and komoot. Want one sooner? Open an issue — demand decides the order.

New
Connect your agents over MCP

Cairn is an OAuth 2.1 authorization server, so native apps, third-party clients and AI agents all authenticate the same secure way — scoped to a single user.

  • Model Context Protocol server — let an assistant read your activities, stats, training load and segments, scoped to your account.
  • OAuth everywhere it matters — authorization-code + PKCE and dynamic client registration for native iOS/Android and third-party apps.
  • Granular scopes — grant read-only access to an agent without handing over your whole account.
  • Still simple for humans — password, OIDC login and passkeys remain first-class.
# Point your agent at your Cairn instance
mcp connect https://cairn.example/mcp

# OAuth runs automatically (PKCE + DCR),
# scoped read-only to your account:
tools:
  - list_activities
  - get_activity
  - activity_stats
  - personal_records
  - profile
Run it yourself
Up and running in minutes

One distroless binary with the web UI embedded, Postgres + TimescaleDB + PostGIS, NATS, and the provider workers you want. Deploy with Docker Compose or the included Kubernetes manifests.

# Pull the core + the workers you use
docker compose up -d

# core  → API + embedded web UI
# strava worker (Go), garmin worker (Python)
# each a separate, swappable process

→ open https://cairn.example
  • Hexagonal core — a clean domain → port → adapter architecture that's a pleasure to extend.
  • Pluggable providers — workers are standalone repos that speak a proto + NATS contract; write your own.
  • Open source — AGPL-3.0 core, free and yours to fork; the provider contract and workers are Apache-2.0.
About
Who's behind Cairn

Hi, I'm Johannes Küber — sports enthusiast, programmer and security expert. When I'm not building software I'm usually out running, riding or in the mountains, which is exactly where all this data comes from.

A platform like this has lived on my own server in one form or another for years. I've built it, outgrown it and rewritten it several times — as watches changed, providers came and went, and my ideas about training data matured. In 2026 I decided the latest rewrite shouldn't stay private, and Cairn became open source under AGPL-3.0.

The security background shapes the project more than any feature list: OAuth 2.1 with PKCE-only flows, scoped tokens, and a single visibility choke-point for every read aren't add-ons — they're the foundation. Questions, ideas, or war stories about liberating your own data? Say hi at contact@opencairn.org.

Own your training story.

Spin up Cairn on your own hardware and keep every workout for good.