@thenextrace/tnr
v0.15.1
Published
CLI and MCP server for thenextrace.app — plan races and training from your terminal and from AI agents.
Maintainers
Readme
tnr — thenextrace CLI & MCP server
Plan races and training from your terminal — and from AI agents (Claude Code, Cursor, Claude Desktop).
npm install -g @thenextrace/tnr
tnr loginTwo ways to connect
Remote MCP (no install). thenextrace hosts an MCP server at
https://thenextrace.app/mcp. Point any client that supports remote MCP at that
URL and sign in with OAuth — nothing to install, nothing to update.
agent ── HTTP + OAuth ──► https://thenextrace.app/mcpLocal MCP + CLI (this package). tnr mcp runs as a stdio MCP server —
Claude Desktop / Cursor / Claude Code spawn the tnr binary as a child process
and talk to it over stdin/stdout. It runs on your machine and makes
authenticated HTTPS calls to https://www.thenextrace.app/api/v1. This is the
same model GitHub MCP, filesystem MCP, and most other MCP servers use — your
token never leaves your machine, and the agent never sees it. Installing the
package also gives you the tnr CLI.
agent ── stdio ──► tnr (your machine) ── HTTPS + Bearer ──► thenextrace.appUse with AI agents
The MCP server exposes 32 tools. Each carries detailed instructions for the agent (preconditions, enums, friendly aliases like ironman → tri) and read-only / destructive / idempotent annotations so clients can warn before anything permanent:
- Discovery (read-only) —
whoami,list_races,get_race,list_plans,get_plan,list_library_workouts,get_library_workout,list_plan_workouts,get_scheduled_workout,list_activities,get_activity,get_profile,get_weather_forecast,get_fitness_summary,suggest_links,list_workout_comments - Races —
create_race,update_race,delete_race - Plans —
create_training_plan,update_plan,delete_plan - Library workouts —
create_library_workout,update_library_workout,delete_library_workout - Scheduling (planned workouts inside a plan) —
schedule_workout,update_scheduled_workout,remove_scheduled_workout(link actual activities viaupdate_scheduled_workout'slinked_activity_id, or in bulk withsuggest_links+bulk_link_activities) - Activities —
update_activity - Comments (coach ↔ athlete) —
add_workout_comment - Profile —
update_profile
It also ships prompts that clients surface as slash-commands: plan_my_week, how_am_i_doing, race_week_checklist.
Remote MCP (no install)
For clients that support remote MCP, skip the install entirely and point them at the hosted server — you'll be sent through an OAuth sign-in the first time:
claude mcp add --transport http tnr https://thenextrace.app/mcpThe sections below are for the local tnr mcp server (this npm package).
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"tnr": { "command": "tnr", "args": ["mcp"] }
}
}Restart Claude Desktop. Try: "What races do I have planned in thenextrace?"
Claude Code
claude mcp add tnr -- tnr mcpCursor
Edit ~/.cursor/mcp.json (or the project-local .cursor/mcp.json):
{
"mcpServers": {
"tnr": { "command": "tnr", "args": ["mcp"] }
}
}Sign in
- Generate a token at thenextrace.app — sign in, open the Settings dialog → API Tokens → Generate token. Copy the
tnr_…string immediately; it's shown only once. - Run
tnr loginand paste it (ortnr login --token tnr_…in scripts).
Tokens are stored in your OS config dir (~/Library/Application Support/tnr on macOS, ~/.config/tnr on Linux, %APPDATA%\tnr on Windows). Revoke any token at any time from the same Settings page.
CLI
Every command supports --json for machine-readable output to stdout. Status messages go to stderr. Exit codes follow standard conventions.
tnr login [--token <token>] Save your API token
tnr logout Clear stored credentials
tnr whoami Show the current user
tnr status Show auth state, API host, token location, data freshness
tnr open [plan|athlete] [id] Open a plan/athlete (or the app home) in the browser
tnr completion <bash|zsh|fish> Print a shell completion script
tnr race list [--upcoming] List races
tnr race show <id> Show a single race
tnr race create --title <t> --date <YYYY-MM-DD>
[--plan <id>] [--type <type>] [--location <l>] [--description <d>]
tnr race update <id> [--title <t>] [--date <d>] [--plan <id>] [--type <t>]
[--location <l>] [--description <d>]
[--completed | --not-completed]
tnr race delete <id> [-y] Delete a race
tnr plan list List training plans
tnr plan show <id> Show a single training plan
tnr plan create --title <t> Create an empty plan
tnr plan update <id> [--title <t>] [--public | --no-public] [--access view|comment|edit]
[--allow-duplication | --no-allow-duplication]
tnr plan delete <id> [-y] Delete a plan (cascades to its races)
tnr workout list [--sport <s>] List library workouts
tnr workout show <id> Show a single library workout
tnr workout create --title <t> --sport <s>
[--type <type>] [--description <d>]
tnr workout update <id> [--title <t>] [--sport <s>] [--type <t>]
[--description <d>] [--distance <d>] [--duration <d>] [--pace <p>]
tnr workout delete <id> [-y] Delete a library workout (unless locked)
tnr schedule list <planId> [--from <d>] [--to <d>] List planned workouts in a plan
tnr schedule show <planId> <scheduledId> Show a planned workout
tnr schedule add <planId> --title <t> --sport <s>
[--date <YYYY-MM-DD>] [--week <n>] [--day <0-6>]
[--type <t>] [--description <d>]
tnr schedule update <planId> <scheduledId> [--title <t>] [--date <d>]
[--sport <s>] [--type <t>]
[--description <d>]
[--completed | --not-completed]
tnr schedule remove <planId> <scheduledId> [-y] Remove a planned workout
tnr schedule link <planId> <scheduledId> --activity <activityId>
tnr schedule unlink <planId> <scheduledId>
tnr schedule suggest <planId> [--from <d>] [--to <d>] Suggest activity→workout links
tnr schedule auto-link <planId> [--from <d>] [--to <d>] [-y] Apply unambiguous suggestions
tnr schedule comments <planId> <scheduledId> List workout comments
tnr schedule comment <planId> <scheduledId> --body <text> Add a workout comment
tnr activity list [--from <d>] [--to <d>] [--sport <s>] [--source <src>]
[--unlinked] [--limit <n>]
tnr activity show <id> Show a single activity with full detail
tnr activity update <id> [--title <t>] [--description <d>] [--sport <s>] [--type <t>]
tnr fitness summary [--weeks <n>] Weekly load + Δ vs the prior window
tnr weather [--from <d>] [--to <d>] Daily forecast for your home location
tnr profile show Show profile and physiology
tnr profile set [--ftp <w>] [--threshold-pace <mm:ss>] [--max-hr <bpm>]
[--resting-hr <bpm>] [--weight <kg>] [--css <mm:ss>]
[--vo2max <v>]
tnr mcp Run as an MCP server over stdio (local)Planned workouts vs activities. Planned workouts (tnr schedule …) live inside a training plan — they're sessions the athlete is supposed to do. Activities (tnr activity …) are what the athlete actually did — uploaded manually or imported from Strava. Link an activity to a planned workout with tnr schedule link.
Race types are: run, tri, swim, bike, custom. Friendly aliases (marathon, ironman, 70.3, 5k, half_marathon, ultra, olympic, sprint, duathlon, aquathlon, gravel, mtb, pool, open_water, virtual) are accepted and normalized.
Configuration
| Variable | Default | Purpose |
|---|---|---|
| THENEXTRACE_API_URL | https://www.thenextrace.app/api/v1 | Override the API host (e.g. for staging) |
Examples
# What races do I have coming up?
tnr race list --upcoming
# Pipe to jq for scripting
tnr --json race list --upcoming | jq '.[] | .title'
# Quick race entry
tnr race create \
--title "Berlin Marathon" \
--date 2026-09-27 \
--plan 123 \
--type marathon \
--location Berlin
# Update your zones
tnr profile set --ftp 285 --threshold-pace 4:05 --max-hr 188Releasing
npm version patch # or minor / major
git push --follow-tags # GitHub Actions publishes to npmCI runs on every v* tag (.github/workflows/release.yml).
License
MIT
