Polar MCP
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.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues