coros-mcp
Health Gecti
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 67 GitHub stars
Code Gecti
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
MCP server for AI assistants to read and manage Coros fitness data: sleep, HRV, daily metrics, activities, and structured workouts via the unofficial Coros API
coros-mcp
A Model Context Protocol (MCP) server that fetches sleep, HRV, and training data from the unofficial Coros API and exposes them to AI assistants like Claude.
No API key required. This server authenticates directly with your Coros Training Hub credentials. Your token is stored securely in your system keyring (or an encrypted local file as fallback), never transmitted anywhere except to Coros.
What You Can Do
Ask your AI assistant questions like:
- "How much deep sleep and REM did I get last week?"
- "What was my HRV trend over the last 4 weeks?"
- "Show me my resting heart rate and training load for last week"
- "How many steps did I average per day this month?"
- "List my rides from last month"
- "Show me the details of my last long ride"
- "Create a 90-minute sweet spot workout for me"
- "What's on my training calendar next week?"
- "Schedule my VO2 workout for Thursday"
- "Create a 20-minute strength circuit with squats, lunges, and planks"
Features
| Tool | Description |
|---|---|
authenticate_coros |
Log in with email and password — token stored securely in keyring |
authenticate_coros_mobile |
Log in to the mobile API only (useful for sleep data troubleshooting) |
check_coros_auth |
Check whether a valid auth token is present |
get_daily_metrics |
Fetch daily metrics (HRV, resting HR, training load, VO2max, stamina, and more) for n weeks (default: 4) |
get_sleep_data |
Fetch nightly sleep stages (deep, light, REM, awake) and sleep HR for n weeks (default: 4) |
list_activities |
List activities for a date range with summary metrics |
get_activity_detail |
Fetch full detail for a single activity (laps, HR zones, power zones) |
list_workouts |
List all saved structured workout programs |
create_workout |
Create a new structured workout with named steps and power targets |
delete_workout |
Delete a workout program from the library |
list_planned_activities |
List planned workouts from the Coros training calendar |
schedule_workout |
Schedule an existing workout on a calendar day |
remove_scheduled_workout |
Remove a scheduled workout from the calendar |
create_strength_workout |
Create a structured strength workout with sets, reps, or timed exercises |
list_exercises |
Browse the Coros exercise catalogue, especially for strength workouts |
sync_coros_data |
Backfill all data into the local SQLite cache for a date range |
get_cache_status |
Show coverage (record counts and date ranges) of the local cache |
Setup
Option A: Auto-Setup with Claude Code
If you have Claude Code, paste this prompt:
Set up the Coros MCP server from https://github.com/cygnusb/coros-mcp — clone it, create a venv, install it with pip install -e ., add it to my MCP config, then tell me to run 'coros-mcp auth' in my terminal to authenticate.
Claude will handle the installation and guide you through configuration.
Option B: Manual Setup
Step 1: Install
git clone https://github.com/cygnusb/coros-mcp.git
cd coros-mcp
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e .
Or with uv:
uv pip install -e .
Step 2: Add to Claude Code
claude mcp add coros -- /path/to/coros-mcp/.venv/bin/coros-mcp serve
To limit the MCP to a specific project only (recommended):
cd /path/to/your/project
claude mcp add --scope project coros -- /path/to/coros-mcp/.venv/bin/coros-mcp serve
Or add to Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"coros": {
"command": "/path/to/coros-mcp/.venv/bin/coros-mcp",
"args": ["serve"]
}
}
}
Step 3: Authenticate
Option A — .env file (recommended for project-scoped setups):
Create a .env file in your project directory:
[email protected]
COROS_PASSWORD=yourpassword
COROS_REGION=eu
The server authenticates automatically on the first request and re-authenticates transparently whenever the token expires. No manual auth step needed.
Option B — Manual authentication:
Run the following command in your terminal — outside of any Claude session:
coros-mcp auth
You will be prompted for your email, password, and region (eu, us, or asia). This stores both the Training Hub web token and the mobile API token (used for sleep data). Your credentials are sent directly to Coros and the tokens are stored securely in your system keyring (or an encrypted local file as fallback). You only need to do this once — the tokens persist across restarts.
Note: The mobile login (
apieu.coros.com) will log you out of the Coros mobile app on your phone. If you want to avoid this, usecoros-mcp auth-webinstead — it stores only the web token, and the mobile token will be obtained automatically when you first request sleep data.
Other auth commands:
coros-mcp serve # Start the MCP server (used by Claude Code / Claude Desktop)
coros-mcp auth-web # Web API only — skips mobile login (sleep data obtained lazily)
coros-mcp auth-mobile # Mobile API only (sleep data)
coros-mcp auth-status # Check if authenticated
coros-mcp auth-clear # Remove stored tokens
Tool Reference
authenticate_coros
Log in with your Coros credentials. The auth token is stored securely in your system keyring (or an encrypted file as fallback).
{ "email": "[email protected]", "password": "yourpassword", "region": "eu" }
Returns: authenticated, user_id, region, message
authenticate_coros_mobile
Authenticate with the Coros mobile API only. This is mainly useful if you need to restore sleep-data access without redoing full web authentication.
{ "email": "[email protected]", "password": "yourpassword", "region": "eu" }
Returns: authenticated, user_id, region, message
check_coros_auth
Check whether valid web and mobile tokens are stored and how long the web token remains valid.
{}
Returns: authenticated, user_id, region, expires_in_hours, mobile_authenticated, mobile_token_status
get_daily_metrics
Fetch daily metrics for a configurable number of weeks (default: 4).
{ "weeks": 4 }
Returns: records (list), count, date_range
Each record includes:
| Field | Source | Description |
|---|---|---|
date |
— | Date (YYYYMMDD) |
avg_sleep_hrv |
dayDetail | Nightly HRV (RMSSD ms) |
baseline |
dayDetail | HRV rolling baseline |
rhr |
dayDetail | Resting heart rate (bpm) |
training_load |
dayDetail | Daily training load |
training_load_ratio |
dayDetail | Acute/chronic training load ratio |
tired_rate |
dayDetail | Fatigue rate |
ati / cti |
dayDetail | Acute / chronic training index |
distance / duration |
dayDetail | Distance (m) / duration (s) |
vo2max |
analyse (merge) | VO2 Max (last ~28 days) |
lthr |
analyse (merge) | Lactate threshold heart rate (bpm) |
ltsp |
analyse (merge) | Lactate threshold pace (s/km) |
stamina_level |
analyse (merge) | Base fitness level |
stamina_level_7d |
analyse (merge) | 7-day fitness trend |
get_sleep_data
Fetch nightly sleep stage data for a configurable number of weeks (default: 4).
{ "weeks": 4 }
Returns: records (list), count, date_range
Each record includes:
| Field | Description |
|---|---|
date |
Date (YYYYMMDD) — the morning after the sleep |
total_duration_minutes |
Total sleep in minutes |
phases.deep_minutes |
Deep sleep |
phases.light_minutes |
Light sleep |
phases.rem_minutes |
REM sleep |
phases.awake_minutes |
Time awake during the night |
phases.nap_minutes |
Daytime nap time (null if none) |
avg_hr |
Average heart rate during sleep |
min_hr |
Minimum heart rate during sleep |
max_hr |
Maximum heart rate during sleep |
quality_score |
Sleep quality score (null if not computed) |
Note: Sleep data is fetched from the Coros mobile API (
apieu.coros.com), which uses a separate token from the Training Hub web API.coros-mcp authobtains both tokens, but doing so logs you out of the Coros mobile app. Usecoros-mcp auth-webto skip mobile login — the mobile token is then obtained automatically on the first sleep data request. The token expires after ~1 hour but refreshes automatically on subsequent requests.
list_activities
List activities for a date range.
{ "start_day": "20260101", "end_day": "20260305", "page": 1, "size": 30 }
Returns: activities (list), total_count, page
Each activity includes: activity_id, name, sport_type, sport_name, start_time, end_time, duration_seconds, distance_meters, avg_hr, max_hr, calories (in cal — divide by 1000 for kcal), training_load, avg_power, normalized_power, elevation_gain
get_activity_detail
Fetch full detail for a single activity. Requires the sport_type from list_activities.
{ "activity_id": "469901014965714948", "sport_type": 200 }
Returns full activity data including laps, HR zones, power zones, and all sport-specific metrics.
Note: Large time-series arrays (
graphList,frequencyList,gpsLightDuration) are stripped from the response to keep it manageable.
list_workouts
List all saved structured workout programs.
{}
Returns: workouts (list), count
Each workout includes: id, name, sport_type, sport_name, estimated_time_seconds, exercise_count, exercises (list of steps with name, duration_seconds, intensity_low, intensity_high, sets)
create_workout
Create a new structured workout. Workouts appear in the Coros app and can be synced to the watch. Steps can be plain steps or repeat groups for intervals.
Plain steps:
{
"name": "Sweet Spot 90min",
"sport_type": 2,
"steps": [
{"name": "15:00 Warmup", "duration_minutes": 15, "intensity_low": 148, "intensity_high": 192},
{"name": "20:00 Sweet Spot", "duration_minutes": 20, "intensity_low": 260, "intensity_high": 275},
{"name": "5:00 Rest", "duration_minutes": 5, "intensity_low": 100, "intensity_high": 150},
{"name": "20:00 Sweet Spot", "duration_minutes": 20, "intensity_low": 260, "intensity_high": 275},
{"name": "30:00 Cooldown", "duration_minutes": 30, "intensity_low": 100, "intensity_high": 192}
]
}
With repeat groups (intervals):
{
"name": "3×10min Sweet Spot",
"sport_type": 2,
"steps": [
{"name": "Warmup", "duration_minutes": 10, "intensity_low": 150, "intensity_high": 200},
{"repeat": 3, "steps": [
{"name": "Sweet Spot", "duration_minutes": 10, "intensity_low": 265, "intensity_high": 285},
{"name": "Recovery", "duration_minutes": 3, "intensity_low": 150, "intensity_high": 175}
]},
{"name": "Cooldown", "duration_minutes": 11, "intensity_low": 150, "intensity_high": 200}
]
}
sport_type: 2 = Indoor Cycling (default), 200 = Road Bike
Returns: workout_id, name, total_minutes, steps_count, message
delete_workout
Delete a workout program from the Coros account.
{ "workout_id": "476023839273435149" }
The workout_id comes from list_workouts.
Returns: deleted, workout_id, message
list_planned_activities
List planned activities from the Coros training calendar.
{ "start_day": "20260309", "end_day": "20260316" }
Returns: schedule (dict with entities and programs sub-lists), count (number of scheduled entities), date_range
schedule_workout
Add an existing workout from your library to the Coros training calendar.
{ "workout_id": "1234567890", "happen_day": "20260312", "sort_no": 1 }
Returns: scheduled, workout_id, happen_day
remove_scheduled_workout
Remove a scheduled workout from the Coros training calendar.
{
"plan_id": "987654321",
"id_in_plan": "1234567890",
"plan_program_id": "1234567890"
}
plan_id, id_in_plan, and plan_program_id come from list_planned_activities. If plan_program_id is missing, you can usually reuse id_in_plan.
Returns: removed, plan_id, id_in_plan
create_strength_workout
Create a structured strength workout with repeated sets. Exercises must come from the Coros exercise catalogue.
{
"name": "Leg Circuit",
"sets": 3,
"exercises": [
{
"origin_id": "54",
"name": "T1061",
"overview": "sid_strength_squats",
"target_type": 3,
"target_value": 12,
"rest_seconds": 45,
"sets": 3
},
{
"origin_id": "130",
"name": "T1176",
"overview": "sid_strength_plank",
"target_type": 2,
"target_value": 60,
"rest_seconds": 30
}
]
}
target_type: 2 = time in seconds, 3 = reps
sets (per exercise, optional): consecutive sets of that exercise before moving on. Use this instead of duplicating the exercise entry. Defaults to 1.
sets (top-level): full-circuit repetitions — repeats the entire exercise list. Defaults to 1.
Returns: workout_id, name, sets, exercise_count
list_exercises
List the Coros exercise catalogue for a sport type. Default sport_type=4 returns strength exercises.
{ "sport_type": 4 }
Returns: exercises (list), count, sport_type
sync_coros_data
Backfill all data into the local SQLite cache for a date range. After the first full sync, get_daily_metrics, get_sleep_data, and list_activities serve historical data from cache and only fetch the incremental tail from the API.
{ "start_day": "20230101", "end_day": "20260514" }
Both parameters are optional and default to two years ago / today respectively. For large ranges (> 6 months) prefer the CLI:
coros-mcp sync --from 20230101
Returns: daily (records synced), sleep (records synced), activities (records synced), errors (list), cache (coverage summary)
get_cache_status
Show what data is currently stored in the local SQLite cache.
{}
Returns per data type: count, from (earliest date), to (latest date). Also includes db_path.
Requirements
- Python ≥ 3.11
- A Coros account (Training Hub)
Project Structure
coros-mcp/
├── server.py # MCP server with tool definitions
├── coros_api.py # Coros API client (auth, requests, parsers)
├── models.py # Pydantic data models
├── cli.py # CLI entry point (serve, auth, sync, cache-status, …)
├── auth/ # Token storage (keyring + encrypted file fallback)
├── cache/ # SQLite cache layer (store, sync, utils)
├── tests/ # pytest test suite
├── pyproject.toml # Project metadata & dependencies
└── docs/
└── mobile-token.md # Mobile API token background (legacy reference)
Dependencies
- fastmcp — MCP framework
- httpx — Async HTTP client
- pydantic — Data validation
- pycryptodome — AES encryption for mobile API auth
- keyring — Secure token storage
- python-dotenv —
.envsupport
Disclaimer
This project uses the unofficial Coros Training Hub API. The API may change at any time without notice. Use at your own risk.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi