Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
RUNCOACH_TZNoIANA zone for 'which day was this run'system zone
RUNCOACH_LOGNoLog level — set INFO or DEBUG to watch a sync. INFO and DEBUG also log every HTTP request of the web appWARNING
RUNCOACH_HOMENoData directory~/.runcoach
RUNCOACH_MODELNoModel for coach cardsCLI default
RUNCOACH_TOKENNoRequired for --host 0.0.0.0 (phone in your home network)
RUNCOACH_QUOTA_WAIT_SNoHow long a job waits for subscription quota3600
RUNCOACH_GARMIN_TOKENSNoReuse an existing python-garminconnect token dir~/.runcoach/garmin
RUNCOACH_JOB_TIMEOUT_SNoHard timeout for a single coach job600
RUNCOACH_LT_HISTORY_DAYSNoHow far back the lactate-threshold history is fetched180
RUNCOACH_ACTIVITY_BACKFILL_DAYSNoMinimum window of workouts a sync fetches (the ACWR fallback needs ~28 days)35

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
get_training_readinessA

Today's readiness verdict GO / EASY / REST with the signals behind it (HRV status, sleep score, Body Battery, resting HR vs 27-day baseline, ACWR, days since the last hard workout). Rule-based and conservative. START HERE for "should I train today?". Flags stale data explicitly.

get_recovery_summaryA

Averages of sleep, HRV, resting HR, stress, Body Battery and steps over the last N days plus a snapshot of the latest day. Use for "how has my recovery been?". Aggregates only — never a day-by-day list.

get_daily_metricsA

Every recorded recovery value for ONE day (default: latest day with data). Use when a single night/day is in question, not for trends.

get_trendA

Weekly averages of ONE recovery metric over the last N days — for "is my HRV / resting HR / sleep trending up or down?".

get_training_loadA

Training-load picture: ACWR with its SOURCE (Garmin's EWMA ratio, or a self-computed fallback that is less reliable), Garmin training status, VO2max with change, and weekly load buckets. VO2max change is only reported when the value actually varied (Garmin carries the last value forward).

get_recent_activitiesA

Workout digest: totals per sport plus the latest workouts, each run classified Quality / Long Run / Easy (from training effect and duration). Use to see what was actually trained before recommending the next session.

get_intensity_distributionA

Time in heart-rate zones across all runs (easy Z1-2 / moderate Z3 / hard Z4-5 / Z5) with percentages — the basis for the 80/20 polarisation question. States how many runs have zone detail, so an incomplete picture is visible.

analyze_workoutA

Deep dive into ONE run: time in each HR zone, interval structure (rep count, rep length, work vs recovery HR), weather, performance condition, plus rule-based notes. Default: the latest run with detail. The interval structure is Garmin's auto-detection — if the athlete states a different structure, the athlete is right.

get_vo2max_historyA

VO2max over the last 8 weeks as STEPS (only the days the value really changed — Garmin carries it forward in between) plus a descriptive comparison of the last 28 days with the 28 before (distance, Z5 minutes, easy share, temperature). Use for "why is my VO2max moving?". Descriptive, not causal.

sync_garminA

Pull the latest days and workouts from Garmin Connect NOW. Call this first when today's run or last night's sleep is missing. Takes 10-40 s. Read-only towards Garmin; writes only to the local database.

propose_workoutA

Build a structured session for the athlete's route or time budget and file it as a PROPOSAL - warm-up, work reps with targets, recovery jogs, cool-down - sized so the whole thing adds up to the route. Targets come from the athlete's own Garmin zones; anything not measured is listed as an assumption. Use when the athlete asks for a workout ("plan me intervals for my 10 km", "an easy 45 minutes", "a threshold session") or when the readiness verdict calls for a different session than the one on the calendar. Kinds: easy/long (one capped step), threshold (Z4 reps), vo2max (Z5 reps), steady (>= 12 min even effort at threshold - the only shape Garmin measures VO2max from). day defaults to today. Returns the preview and a proposal id. NOTHING is written to Garmin: show the preview, and only if the athlete says yes call apply_workout with the id. On an impossible request (route too short) returns why, not a session.

propose_weekA

Build a polarised training week and file it as ONE proposal: a VO2max session and a threshold session 48 h apart, the long run on its weekday, easy runs between, nothing hard the day before or after the long run, at least one rest day. Sizes come from defaults (50/55/45/90 min), targets from the athlete's own zones. Use when the athlete asks for their week ("plan my week", "what should next week look like"). What the calendar already holds in that week is listed - the package ADDS to it. Returns the preview of every session and one proposal id; apply_workout with that id puts the whole week on Garmin after the athlete's yes. Nothing is written here.

apply_workoutA

WRITE a proposed session to the athlete's Garmin account: upload the workout, schedule it on the proposal's day, push it to the watch, then read it back and verify structure and targets. Call ONLY after the athlete has seen the preview and explicitly agreed - a request ("plan me 10 km") is not agreement, "yes, put it on the watch" is. Not available to the app's own card runs; there the athlete clicks. Returns what is now on Garmin, with any warning (not pushed because the watch is offline; a mismatch found on read-back). A proposal can be applied once; an unknown or used id says so and lists the open ones.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A4.4/5.0

Scored across 13 tools

Disambiguation5/5

Each tool serves a distinct purpose: specific metric retrievals (vo2max, trend, load, activities, intensity, daily, readiness, recovery), a workout deep-dive, two proposal generators, one apply action, and a sync function. There is no meaningful overlap; even similar 'get' tools focus on different data slices (e.g., single metric trend vs. multi-metric summary).

Naming Consistency5/5

All tool names follow a consistent snake_case pattern with a clear verb prefix (get_, sync_, analyze_, propose_, apply_) and a descriptive noun. The verbs map cleanly to actions (get for reads, propose for plans, apply for writes), making the API predictable and self-documenting.

Tool Count5/5

With 13 tools, the server covers the full coaching lifecycle without bloat. Each tool addresses a distinct piece of the workflow—data ingestion, metrics retrieval, analysis, planning, and execution—so the count feels appropriate for the stated domain.

Completeness5/5

The tool surface covers the entire coaching loop: syncing data, reading all key metrics and trends, analyzing individual workouts, generating single-session and weekly proposals, and applying them to Garmin. No obvious gaps exist for a personal coaching use case, including readiness and recovery checks that guide recommendations.

Maintenance

ActivityMaintained
ResponsivenessNo issues