Skip to main content
ClaudeWave
StuMason avatar
StuMason

polar-flow-server

View on GitHub

Self-hosted health analytics for Polar devices — sync everything, keep it forever, and let your AI read it over MCP

MCP ServersOfficial Registry22 stars3 forksPythonUpdated today
ClaudeWave Trust Score
70/100
· OK
Passed
  • Actively maintained (<30d)
  • Clear description
  • Topics declared
  • Documented (README)
Flags
  • !No standard license detected
Last scanned: 9/11/2026
Install in Claude Code / Claude Desktop
Method: UVX (Python) · polar-flow-server
Claude Code CLI
claude mcp add polar-flow-server -- uvx polar-flow-server
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "polar-flow-server": {
      "command": "uvx",
      "args": ["polar-flow-server"]
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
💡 Package name inferred from the repository name. Verify it exists on PyPI, or clone https://github.com/StuMason/polar-flow-server and follow its README.
Use cases

MCP Servers overview

# polar-flow-server

Self-hosted health analytics for Polar devices — own your data, analyze it against your own baselines, and let your AI assistant read it.

[![Tests](https://github.com/StuMason/polar-flow-server/actions/workflows/tests.yml/badge.svg)](https://github.com/StuMason/polar-flow-server/actions/workflows/tests.yml)
[![Docs](https://img.shields.io/badge/docs-mkdocs-blue)](https://stumason.github.io/polar-flow-server/)
[![Docker](https://img.shields.io/docker/v/stumason/polar-flow-server?label=docker)](https://hub.docker.com/r/stumason/polar-flow-server)
[![MCP](https://img.shields.io/badge/MCP-2026--07--28-6549d5)](https://stumason.github.io/polar-flow-server/mcp-server/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

![Dashboard](docs/assets/dashboard-today.png)

**[Full Documentation](https://stumason.github.io/polar-flow-server/)** · [MCP Server](https://stumason.github.io/polar-flow-server/mcp-server/) · [Integration Guide](https://stumason.github.io/polar-flow-server/integration/) · [API Reference](https://stumason.github.io/polar-flow-server/api/overview/)

## What This Does

Your watch knows more about you than you do — and Polar's API only lets you see the last 28-30 days of it. This server syncs everything, keeps it forever, and turns it into answers:

1. Syncs all **13 Polar API endpoints** automatically — sleep, HRV, activity, workouts, SpO2, ECG, skin temperature, the lot
2. Stores everything in PostgreSQL. Your data, your server, no cloud between you and it
3. Computes **personal baselines** (rolling averages, IQR anomaly bounds) so "is this normal?" means normal *for you*
4. Ships a **built-in MCP server with OAuth sign-in** — ask Claude "should I train hard today?" and it answers from your overnight HRV vs your baseline
5. Admin dashboard (HTMX), REST API, per-user API keys, multi-user ready

## Ask Your AI About Your Body (MCP)

A built-in [Model Context Protocol](https://modelcontextprotocol.io) server — protocol revision **2026-07-28**, streamable HTTP — runs inside the main server at `/mcp`. Ten curated tools cover the one-shot health assessment, sleep, recovery, activity, workouts, seven biosensing streams, personal baselines, patterns/anomalies, and sync control.

In clients that render [MCP Apps](https://modelcontextprotocol.io/extensions/apps/overview) (claude.ai, Claude Desktop, VS Code), asking "how am I doing?" draws an actual card in the conversation:

![MCP Apps card](docs/assets/mcp-apps-card.png)

**Connecting is a sign-in, not a paste.** With `BASE_URL` set, the server is its own OAuth 2.1 authorization server: add `https://your-server/mcp` as a custom connector in Claude Desktop or claude.ai, click **Connect**, log in on *your* server, approve the consent screen. Tokens are user-scoped, expire hourly, refresh automatically, and every connected app is revocable from Settings. API keys still work for headless clients:

```bash
claude mcp add polar-health https://your-server.example.com/mcp \
  --transport http \
  --header "X-API-Key: pfk_your_key_here"
```

Full setup in the [MCP docs](https://stumason.github.io/polar-flow-server/mcp-server/).

## Architecture

```
Polar API → polar-flow SDK → Sync Service → PostgreSQL
                                                  ↓
                                           Admin Dashboard (HTMX)
                                                  ↓
                                             REST API
```

**Stack:**
- Litestar (async web framework)
- SQLAlchemy 2.0 (async ORM)
- PostgreSQL
- HTMX + Tailwind (admin UI)
- polar-flow SDK v1.5.0

> **Don't fancy running a server?** A hosted version is in the works — [join the waitlist](https://pulse.stumason.dev). Self-hosting stays free forever.

## Quick Start

### Option 1: Docker (Recommended)

```bash
# Pull and run
curl -O https://raw.githubusercontent.com/StuMason/polar-flow-server/main/docker-compose.prod.yml
docker-compose -f docker-compose.prod.yml up -d

# That's it. Open http://localhost:8000/admin
```

### Option 2: From Source

```bash
git clone https://github.com/StuMason/polar-flow-server.git
cd polar-flow-server
docker-compose up -d
```

### Setup

1. Open http://localhost:8000/admin
2. Get Polar credentials from [admin.polaraccesslink.com](https://admin.polaraccesslink.com) (set redirect URI to `http://localhost:8000/admin/oauth/callback`)
3. Enter credentials and click "Connect with Polar"
4. Hit "Sync Now" to pull your data

The server syncs data every hour automatically.

## Dashboard

The admin panel at `/admin/dashboard` is organised into tabs (with a
floating tab bar on mobile):

- **Overview** - stat tiles (HRV, resting HR, SpO2, skin temp, steps, strain,
  sleep score, alertness...), Today's Readiness recommendations, and
  "Today at a Glance" mini-charts (sleep stages, heart rate, steps)
- **Trends & Baselines** - personal baselines and detected patterns
- **Sleep** - sleep score and stage-duration charts
- **Heart Rate** - daily HR, HRV and ANS charge charts, biosensing panel
- **Training Load** - activity and cardio load charts

![Trends and baselines](docs/assets/dashboard-trends.png)

Charts have a selectable 7/14/30-day range and CSV export. API keys are
managed from the settings page, with rate limit tracking. All frontend
assets are vendored - the dashboard works offline and on a LAN with no
CDNs.

## Data Synced (13 Endpoints)

| Endpoint | Data |
|----------|------|
| **Sleep** | Score, stages (light/deep/REM), duration |
| **Nightly Recharge** | HRV, ANS charge, recovery status |
| **Daily Activity** | Steps, distance, calories, active time |
| **Exercises** | Sport, duration, HR zones, training load |
| **Cardio Load** | Strain, tolerance, load ratio, status |
| **SleepWise Alertness** | Hourly alertness predictions |
| **SleepWise Bedtime** | Optimal sleep timing recommendations |
| **Activity Samples** | Minute-by-minute step data |
| **Continuous HR** | All-day heart rate (5-min intervals) |
| **SpO2** | Blood oxygen tests (compatible devices) |
| **ECG** | Electrocardiogram tests (compatible devices) |
| **Body Temperature** | Continuous body temperature |
| **Skin Temperature** | Nightly skin temperature with baseline deviation |

## Configuration

### Required Environment Variables

| Variable | Description | Required |
|----------|-------------|----------|
| `DATABASE_URL` | PostgreSQL connection string | Yes |
| `ENCRYPTION_KEY` | 32-byte Fernet key for token encryption | **Yes (production)** |

Generate an encryption key:
```bash
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
```

### Optional Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `DEPLOYMENT_MODE` | `self_hosted` or `saas` | `self_hosted` |
| `SYNC_INTERVAL_HOURS` | Auto-sync frequency | `1` |
| `SYNC_ON_STARTUP` | Sync when server starts | `false` |
| `SYNC_DAYS_LOOKBACK` | Days of history to sync | `28` |
| `LOG_LEVEL` | Logging verbosity | `INFO` |
| `API_KEY` | Master API key (bypasses rate limits) | None |

## API Authentication

**API endpoints require authentication.** Health data should never be publicly accessible.

### Authentication Methods

1. **Per-User API Keys** (recommended) - Create from the admin dashboard or via OAuth flow
2. **Master API Key** - Set `API_KEY` env var for full access (bypasses rate limits)

### Using API Keys

```bash
# With per-user API key (includes rate limit headers)
curl -H "X-API-Key: pfk_your_api_key_here" \
  http://localhost:8000/api/v1/users/{user_id}/sleep?days=7

# Response headers include:
# X-RateLimit-Limit: 1000
# X-RateLimit-Remaining: 999
# X-RateLimit-Reset: 1704067200
```

### Rate Limiting

- Default: 1000 requests per hour per API key
- Rate limits reset hourly
- Master API key (`API_KEY` env var) bypasses rate limiting
- Rate limit info returned in response headers

## OAuth Integration (SaaS / Multi-User)

For applications that need to integrate with polar-flow-server (e.g., Laravel, mobile apps, web frontends).

This allows **any Polar user** to connect their account to your application.

### OAuth Flow

```
┌─────────────────┐     ┌─────────────────────┐     ┌─────────────────┐
│  Your App       │────▶│  polar-flow-server  │────▶│  Polar Flow     │
│  (Laravel etc)  │     │                     │     │  (OAuth)        │
│                 │◀────│                     │◀────│                 │
└─────────────────┘     └─────────────────────┘     └─────────────────┘
```

**Step 1: Redirect user to start OAuth**

```
GET /oauth/start?callback_url=https://yourapp.com/callback&client_id=your-app-name
```

| Parameter | Required | Description |
|-----------|----------|-------------|
| `callback_url` | Yes | Where to redirect after OAuth (your app's callback endpoint) |
| `client_id` | No | Identifier for your app (validated during exchange) |

**Step 2: User authorizes on Polar**

User is redirected to Polar, logs in with their credentials, and authorizes your app.

**Step 3: User redirected to your callback**

```
https://yourapp.com/callback?code=TEMP_CODE_HERE
```

**Step 4: Exchange temp code for API key (server-to-server)**

```bash
POST /oauth/exchange
Content-Type: application/json

{
  "code": "TEMP_CODE_HERE",
  "client_id": "your-app-name"
}
```

Response:
```json
{
  "api_key": "pfk_abc123...",
  "polar_user_id": "12345678",
  "expires_at": null
}
```

**Step 5: Store and use the API key**

Store `api_key` and `polar_user_id` for this user. Use the API key for all data requests:

```bash
curl -H "X-API-Key: pfk_abc123..." \
  "https://your-polar-server.com/api/v1/users/12345678/sleep?days=7"
```

### Polar Admin Setup

In [admin.polaraccesslink.com](https://admin.polaraccesslink.com), set your app's redirect URI to:

```
https://your-polar-server.com/oauth/callback
```

### Key Management

```bash
# Get key info
GET /api/v1/users/{user_id}/api-key/info
X-API-K
analyticsclaudefitnesshealthhrvhtmxmcpmodel-context-protocolpolarpostgresqlpythonself-hosted

What people ask about polar-flow-server

What is StuMason/polar-flow-server?

+

StuMason/polar-flow-server is mcp servers for the Claude AI ecosystem. Self-hosted health analytics for Polar devices — sync everything, keep it forever, and let your AI read it over MCP It has 22 GitHub stars and its last recorded update is dated 2026-09-10.

How do I install polar-flow-server?

+

You can install polar-flow-server by cloning the repository (https://github.com/StuMason/polar-flow-server) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is StuMason/polar-flow-server safe to use?

+

Our security agent has analyzed StuMason/polar-flow-server and assigned a Trust Score of 70/100 (tier: OK). See the full breakdown of passed checks and flags on this page.

Who maintains StuMason/polar-flow-server?

+

StuMason/polar-flow-server is maintained by StuMason. The last recorded GitHub activity is dated 2026-09-10, with 9 open issues.

Are there alternatives to polar-flow-server?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy polar-flow-server to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: StuMason/polar-flow-server
[![Featured on ClaudeWave](https://claudewave.com/api/badge/stumason-polar-flow-server)](https://claudewave.com/repo/stumason-polar-flow-server)
<a href="https://claudewave.com/repo/stumason-polar-flow-server"><img src="https://claudewave.com/api/badge/stumason-polar-flow-server" alt="Featured on ClaudeWave: StuMason/polar-flow-server" width="320" height="64" /></a>

More MCP Servers

polar-flow-server alternatives