Skip to main content
Glama
README.md
# Polar MCP

This repository implements the boundaries in
[ADR 0001](docs/architecture/adr/0001-python-core-with-mcp-and-agent-adapters.md): a reusable
Python Polar core, with thin read-only adapters for local MCP and the Claude Agent SDK.

The implementation is intentionally v4-first. It provides:

- automatic AccessLink v4 token refresh;
- isolated v4 and complementary v3 clients;
- bounded, exclusive-end date ranges and automatic v4 request chunking;
- normalized response envelopes with API provenance and units;
- recursive credential, user/device identifier, and precise-location redaction;
- bounded nested time series and top-level results;
- an in-memory TTL cache that never persists health data;
- MCP and Agent SDK tools that can only read sanitized data;
- a separate authentication CLI with an owner-only local token file.

## Install

Python 3.11 or later is required.

```bash
python -m venv .venv
source .venv/bin/activate
pip install -e '.[mcp]'
```

Register an application in Polar AccessLink, then set server-side credentials. Do not put these
values in an MCP configuration file that a model can read.

```bash
export POLAR_CLIENT_ID='...'
export POLAR_CLIENT_SECRET='...'
```

Generate an authorization URL with a state value that your callback verifies:

```bash
polar-auth authorization-url \
  --redirect-uri 'http://127.0.0.1:8787/callback' \
  --state "$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
```

After approving access, exchange the returned code. Omitting `--code` reads it without echoing it
or placing it in shell history.

```bash
polar-auth exchange --redirect-uri 'http://127.0.0.1:8787/callback'
polar-auth status
```

Tokens default to the platform configuration directory and are rejected if their file is readable
by anyone except its owner. Override the location with `POLAR_TOKEN_FILE`.

## Run local MCP

```bash
polar-mcp
```

The server uses `stdio`; it does not open a network listener. It exposes only:

- `polar_get_activity`
- `polar_get_sleep`
- `polar_get_recovery`
- `polar_get_training_sessions`
- `polar_get_heart_rate`

All `end_date` values are exclusive. The tool schemas deliberately have no raw-data or location
flags. Code outside an agent may use `PolarService.query` with an explicit `DisclosureGrant`, but
the grant requires a separately recorded user confirmation and responses remain size-bounded.

## Test

The tests use only the standard-library test runner and mocked HTTP transports:

```bash
PYTHONPATH=src python -m unittest discover -s tests -v
```

No test requires Polar credentials or sends health data over the network.

## Current validation status

This code implements the durable architecture, but it does not claim the real-device proof of
concept required to accept ADR 0001. The ADR remains `Proposed` until the documented live Polar
Pacer checks are completed.

Maintenance

ActivityMaintained
ResponsivenessNo issues