Daash
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| GARMIN_EMAIL | No | Garmin account email address, used for unattended re-authentication when the cached session expires. | |
| GARMIN_PASSWORD | No | Garmin account password, used for unattended re-authentication when the cached session expires. Can be omitted in favor of running scripts/login.sh manually. |
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
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_daily_summaryA | Daily health summary: steps, calories, resting heart rate, body battery and stress. With what charged or drained Body Battery and the longest stressful spells: "why is my Body Battery low", "when was I stressed". Args: date: Day to report on. YYYY-MM-DD, 'today', 'yesterday' or an offset like '-3'. Defaults to today. |
| get_heart_rateA | Heart rate through a day or night, from the watch's all-day readings. For "was there a gap overnight", "when did my heart rate settle", "how low did it go". Answers with gaps (no reading for 10+ min), blocks with low, average and high, and the lowest and highest readings. A run's heart rate is get_activity_details. Args: date: The day the window starts. Defaults to today; last night is yesterday with an evening start. start: Local start time, HH:MM. Defaults to midnight. end: Local end time, HH:MM. Before start runs into the next day. |
| get_sleep_dataA | Sleep stages and sleep score for a night, with overnight breathing rate and SpO2 against usual. Args: date: The date you woke up on. YYYY-MM-DD, 'today', 'yesterday' or an offset like '-3'. Defaults to today. |
| get_activitiesA | List recent runs, rides, swims and workouts with distance, duration, pace and HR zones. Swims come with pace per 100 m, pool length, SWOLF and stroke rate instead of pace per km. Args: limit: Maximum activities to return (1-50). Defaults to 10. start_date: Optional first day of a date range, YYYY-MM-DD. end_date: Optional last day of a date range. Defaults to today when start_date is given. |
| get_activity_detailsA | Splits and heart-rate detail for one activity. Args: activity_id: The activityId from get_activities. For a run, also returns the weather during it (temperature, dew point, wind, and what that does to pace), the shoes worn, the terrain (climbs, pace on uphill, flat and downhill, the pace the effort was worth on the flat, heart-rate decoupling and where it faded) and earlier runs of the same route with their pace and heart rate. Use these to explain a run rather than guessing why it was slow or hard. For a ride: normalised, average and max power, intensity factor and training stress against FTP, best efforts from 5 seconds to an hour, variability, time in power zones, climbs with speed, VAM and power, the weather during it, and earlier rides of the same route. For a swim: pace per 100 m, pool length, SWOLF, stroke rate and strokes, and the set as swum, each interval with its pace, stroke and the rest after it. Talk about a swim in those terms, never pace per km. |
| list_workoutsA | List structured workouts saved in the Garmin account. Args: limit: Maximum workouts to return (1-100). Defaults to 20. |
| get_workoutA | The steps of one workout, saved or scheduled: each step with its distance or time and target. Use it for any question about what a session involves ("what's the pace for Wednesday's workout", "how long is the cool-down", "what are the recoveries"), with the workout_id from get_plan's sessions or from list_workouts. Never guess a workout's paces, recoveries or warm-up from other sessions: read them here. Repeats keep their structure, e.g. 8 x [1 km at a target, 60 s recovery]. Args: workout_id: The workout's id, from get_plan or list_workouts. |
| create_workoutA | Create a structured workout in Garmin Connect: always a new one, never an edit. schedule_workout then puts it on a date so it syncs to the watch. Args: name: Shown in Garmin Connect and on the watch. steps: Ordered steps, each with "type" (warmup, interval, recovery, rest, cooldown or repeat) and exactly one of "duration_seconds", "distance_meters" or "until_lap": true (ends on the lap button: a walk recovery between strides, a warm-up by feel, a rep to a landmark; still its own lap, so recoveries stay out of the rep splits). A repeat is {"type": "repeat", "times": 5, "steps": [...]} and can't contain another repeat. Optional target: "pace" ("4:05" or ["4:00", "4:10"], min/km), "hr" ([150, 165] bpm, or their Garmin zone: "z2", "z3-z4") or "power" (watts, 250 or [240, 260]; a share of the FTP set in Garmin, "95%" or ["88%", "94%"]; or a power zone, "z3"). By default only the work reps carry a target, pace for a run; warm-ups, cool-downs and recoveries carry none, so the watch stays quiet, and the chat and the workout's description say what easy pace to run them at: marathon pace plus 45-75 s/km, from get_fitness. The watch beeps off target, so a pace target is never narrower than 5 s/km either side ("4:00" becomes 3:55-4:05; tighter is widened around its middle): about 5 either side for reps, 10 for tempo and threshold, 15-20 for steady and long runs, or heart rate for easy running. A ride uses power on the work steps when the rider has a power meter or smart trainer (power shows on rides in get_activities) and an FTP (get_fitness): sweet spot 88-94%, threshold 95-105%, VO2 max 106-120%, endurance 56-75%. One value becomes a range 5% either side. Without a power meter, heart rate. Example, 15 min warm-up, 5 x 1 km at 4:05 with 90 s recoveries, 10 min cool-down: [{"type": "warmup", "duration_seconds": 900}, {"type": "repeat", "times": 5, "steps": [{"type": "interval", "distance_meters": 1000, "pace": "4:05"}, {"type": "recovery", "duration_seconds": 90}]}, {"type": "cooldown", "duration_seconds": 600}] sport: running (default), cycling, swimming, walking or hiking. description: Optional note stored with the workout. pool_length_meters: For a swim, 25 (default) or 50; the watch counts lengths with it. A swim's steps are whole pool lengths (100, 200...), each with an optional "stroke": freestyle, backstroke, breaststroke, butterfly, im, drill or any. "pace" is per 100 m ("1:45") and shows on the step as a note, not a beeping target. A "rest" with no duration waits for the lap button, as swimmers rest at the wall; "duration_seconds" fixes it. A "note" (e.g. "kick with board") shows on the step. Set paces from recent swims (get_activities, per 100 m) or their CSS. Example, 8 x 100 free at 1:45 with 15 s rest: [{"type": "warmup", "distance_meters": 400, "stroke": "any"}, {"type": "repeat", "times": 8, "steps": [{"type": "interval", "distance_meters": 100, "stroke": "freestyle", "pace": "1:45"}, {"type": "rest", "duration_seconds": 15}]}, {"type": "cooldown", "distance_meters": 200, "stroke": "any"}] |
| update_workoutA | Change an existing workout in place: its name, its steps, or both. The workout keeps its id, so any dates it is already scheduled on stay
scheduled and the watch picks up the new version at the next sync. This is
how a plan adapts: retune the paces on next week's sessions rather than
deleting and recreating them. Give New steps replace the old list entirely, so to change part of a workout (one pace, the recoveries, the cool-down) read it with get_workout first and send back every step, changing only what the user asked for. The answer carries the steps it replaced, so say exactly what changed. Args: workout_id: The workoutId from get_plan, list_workouts or create_workout. name: New name. Omit to keep the current one. steps: New step list, replacing the old one entirely. Omit to keep it. sport: Only needed with steps, and only to change the sport. description: New note. Omit to keep the current one. pool_length_meters: For a swim, a new pool length. Omit to keep it. |
| find_exercisesA | Search Garmin's exercise catalogue by name. Use this before create_strength_workout when unsure what an exercise is called, or when it reports that a name was ambiguous. Matching ignores hyphens and spacing, so "pull up" and "pull-up" both work. Args: query: Part of an exercise name, e.g. "bench press" or "row". limit: How many matches to return. Defaults to 25. |
| create_strength_workoutA | Create a strength training workout in Garmin Connect. Adds a new workout; it never edits or replaces an existing one. Use schedule_workout afterwards to put it on a date so it syncs to the watch. Exercise names come from Garmin's own catalogue. Common names usually work as typed; if one is ambiguous this says so and lists the candidates rather than guessing, since a wrong guess is the wrong movement on a watch. Call find_exercises to search. Args: name: Name shown in Garmin Connect and on the watch. exercises: Ordered list of blocks. Each block is an object: - "exercise": catalogue name, e.g. "Barbell Bench Press" - "sets": number of sets (default 3) - "reps": repetitions per set (default 10) - "rest_seconds": rest after each set (default 90) - "weight_kg": optional target weight Example — a push day: [{"exercise": "Barbell Bench Press", "sets": 4, "reps": 8, "rest_seconds": 120, "weight_kg": 70}, {"exercise": "Barbell Overhead Press", "sets": 3, "reps": 10, "rest_seconds": 90}, {"exercise": "Cable Triceps Pushdown", "sets": 3, "reps": 12, "rest_seconds": 60}] description: Optional note stored with the workout. |
| schedule_workoutA | Put an existing workout on a date in the Garmin calendar. Scheduling is what makes a workout sync to the watch. Args: workout_id: Id from create_workout or list_workouts. date: The day to schedule it on. YYYY-MM-DD, 'today', 'tomorrow', or an offset like '+3'. |
| unschedule_workoutA | Take a workout off a day in the Garmin calendar. This is the reversible one: the workout itself is kept and can be scheduled again. Use it to clear a session the watch should no longer show. Deleting the workout outright is delete_workout. Args: date: The day to clear. YYYY-MM-DD, 'today', 'tomorrow', or an offset like '+3'. If more than one workout sits on that day, they are listed back rather than guessed between. schedule_id: Remove one specific entry, from a previous listing or from what schedule_workout returned. Takes precedence over date. |
| delete_workoutA | Delete a workout from the Garmin account. Permanent. This asks before it acts, and the check is real rather than advisory: the
first call never deletes. It reads the workout back and returns its name,
and only a second call passing that name as Recorded activities are untouchable here. This removes a workout from the workout library — a plan for a session, not a session you ran. Args: workout_id: Id from list_workouts or create_workout. confirm: The workout's exact name, which the first call returns. |
| get_progressA | Which planned sessions actually got done, week by week. Answers "am I keeping up" rather than "what did I run". A session counts if it happened within a day either side of its scheduled day and ran at least roughly as long as planned — people move sessions around, and a week where everything got done on shifted days is a good week, not a failed one. Each completed session carries a plain-English reason. Read those back when something looks wrong: a mismatch is visible there rather than hidden. Effort is not judged here. This says whether a session happened; whether it was run at the right intensity is yours to assess from get_activity_details. Args: weeks: How many weeks back to report, including this one (1-12). Its result is drawn for the user as an interactive plan card, so there is no need to draw the weeks yourself, and calling it again draws the card again: fetch it fresh only when a session may have been done since. For "how is my plan going", get_plan is the better first call, and once it has been shown this is rarely needed too. |
| get_profileA | Fitness profile: VO2 max and personal records. Use this instead of asking the user for their PBs. Note that Garmin only knows records it has recorded itself — a race run without the watch, or before they owned it, will be missing. |
| create_planA | Create a whole training block at once: every session built and put on its date. You design the plan, from the user's goal, current fitness (get_fitness), readiness, history and a methodology; this builds each session as a structured workout and schedules it, so the whole block is on the watch in one go. Show the user the plan and get their agreement first: it writes to their real calendar. It answers with the new block drawn as a card, the same as get_plan, so no other call is needed to show it. Each workout is named with a short plan code after a middle dot, "Threshold 5x1k · HM", which is how get_plan finds the block; nothing is stored outside Garmin. Every session is checked before anything is created, so a mistake in session 40 leaves no half plan behind. Args: goal: What the block is for, e.g. "Half marathon, 1:40, 15 November". sessions: One per session, any order: "date" (YYYY-MM-DD, today to 30 weeks out), "name" (short, as on the watch: "Long run 18k"), "steps" (as for create_workout), and optional "sport" (running by default), "description", "pool_length_meters" for a swim (25 by default) and "phase": one short word such as "Base", "Build", "Peak" or "Taper", the same for every session in that phase; the card bands the weeks by it. Rest days are days with no session. At most 150. label: 2 or 3 letters or digits for the plan code, short because it ends every workout name: "HM", "10K", "MAR", "B1" for a base block. From the goal when omitted. name: A short name for the block, as the card's title: "Base block", "Marathon build". Two or three words, not the goal. method: The methodology in a few words, shown under the name: "Norwegian singles", "80/20", "Pfitzinger 18/55". milestones: Up to 4 points on the way to the goal, drawn as a timeline: {"label": "Half check", "date": "2026-11-29", "target": "1:22"}, date and target optional. The goal race is usually last. |
| get_planA | How the user's training is going, drawn as an interactive plan card: their plan week by week, each session done, missed or ahead, and the next one; with nothing scheduled, their recent weeks of running and riding. Call it first for any general question about training or a plan ("how's my training going", "how am I doing", "this week", "show my plan", "what's next", "today's session", "am I on track"), wherever the plan came from: a coach, an app, Garmin Coach or create_plan. Call it alone: its situation says where the user is (a block under way, about to start or just done; a race ahead with nothing scheduled; regular running; or getting going) and offers one next step. Recovery, readiness or fitness follow only when asked, or when the user takes up that offer. Without a create_plan plan it reads the calendar around this week. Sessions carry workout_id and schedule_id for moving or retuning; the next one carries its steps and target paces. For any other session's steps, paces, recoveries or cool-down, call get_workout with its workout_id: never guess them. Done means run within a day either side of its date, or any day that week if started from its workout on the watch. A strength session counts if any strength activity is recorded in its own week, early included, never another week's. Off its own day it shows as moved. When the user says they have just done a session, call this before saying whether Garmin has it: don't guess. A strength activity is the session done even if it was logged in a gym app; the sets and weights aren't needed to count it. If a session isn't in Garmin but the user says they did it, trust them and suggest recording it on the watch next time. If what they did matters for what comes next and they haven't said, ask for a line. After a hard or long session in the last two days, ask once, in one short line, how it felt, and use the answer; not after an easy run. The card draws the plan, so don't list it: add what it can't say, such as how the week is going. Each call draws it again, so answer follow-ups from that result; call again only when something may have changed (a session done, a workout moved or added, a new day) or the user asks to see it again: runs sync through the day, so after any of those the earlier answer goes stale. Don't call it for a specific question about a run, sleep, readiness, recovery, fitness or shoes. Args: label: The code of a plan made with create_plan, e.g. "HM". Omit it for the plan running now, or the calendar. |
| remove_planA | Take the rest of a plan off the calendar and out of the workout library. For starting again or abandoning a block. Only sessions from today onward are removed; past ones stay, so the record of what was planned against what was run is kept. The first call only reports what would go. Removing it needs a second call with confirm set to the plan code, after the user has agreed. Args: label: The plan code, e.g. "HM". confirm: The plan code again, to go ahead. |
| get_readinessA | Whether the user should train hard today or hold back. For that question, and for checking today before prescribing a hard session. Not for reviewing a week, a run or how training is going: get_plan and the activity tools answer those. Has Garmin's readiness score and its factors, training status (productive, strained, recovery...), acute against chronic load and the four-week load focus ("too much intensity?"), with last night's sleep, HRV against baseline, body battery, stress and resting heart rate, so get_sleep_data and get_daily_summary aren't needed with it. Args: date: YYYY-MM-DD, 'today', 'yesterday' or an offset like '-1'. Defaults to today. |
| get_fitnessA | Garmin's read on the user's current fitness, as markers rather than history. VO2 max and fitness age, predicted race times for 5k to marathon, lactate threshold heart rate and pace, endurance score, hill score and running tolerance, each with its own classification where Garmin gives one. Use it to set goals and training paces from evidence: "Garmin thinks you are a 1:42 half today" is a better starting point than asking. Also the heart rate and power zones set in Garmin, which workouts can target as "z2". Also returns the cycling FTP set in Garmin, with watts per kilo when the user's weight is set. For a general "how's my training going", get_plan is the first call; this adds the fitness markers. For whether they are improving over months, get_fitness_trends. |
| get_fitness_trendsA | Whether the user is getting fitter: Garmin's fitness markers month by month. VO2 max, predicted 5k, 10k, half and marathon times, lactate threshold pace and heart rate, endurance and hill score, and cycling FTP, each as a value per month with the change from the first month to now and whether that is improving, steady or declining. Alongside them, weight by month from the weigh-ins logged in Garmin Connect, with body fat and muscle where a scale records them. Use it for "am I getting fitter", "how's my fitness trending", "is my VO2 max going up", "has my half prediction come down" or "was I faster when I was lighter", and answer in writing: name the markers that moved and by how much, in plain terms. For weight, line the months up and say how the markers moved as weight changed, as a pattern rather than a cause. With no weigh-ins logged, say so and that weighing in through Garmin Connect or a Garmin scale is what fills it. For where they stand today, get_fitness is enough; for whether recovery is keeping up, get_recovery_trends. Args: months: Months to look back, including this one (1-12). Defaults to 6. |
| get_recovery_trendsA | How the user is recovering across weeks, beside the training that caused it. Week by week: overnight HRV, resting heart rate, sleep hours and score, Body Battery peak and stress, next to training load, run km and sessions, plus the last two weeks day by day and any marker that has moved off its usual range (resting HR up, HRV down, short sleep, a jump in load). Use it for "am I recovering well", "is this block too much" or "why do I feel flat". For whether to train hard today, get_readiness is the one. Args: weeks: Weeks to look back, including this one (1-12). Defaults to 4. For a general "how's my training going", get_plan is the first call; this adds how recovery is keeping up with it. |
| update_activityA | Change a recorded run or ride: its name, notes, shoes or type. Pass only what changes; the answer says what each was. Args: activity_id: From get_activities. name: The new title. notes: Replaces the notes; read them with get_activity_details to add to them. shoes: A pair's name from get_shoes, replacing any on it; "none" takes them off. activity_type: e.g. trail_running, treadmill_running, track_running, indoor_cycling, walking. |
| get_shoesA | The user's running shoes and how far each pair has gone. For each active pair: km so far, runs, the limit set in Garmin (or a typical 650 km when none is set) and km left, km in the last four weeks, when it was last worn, and whether Garmin adds it to new runs by default. Pairs near the end of their life are flagged. Retired pairs are listed by name and km. Use it for "do I need new shoes" or "which shoes do I run in most". |
| get_connection_statusA | Check whether the server is logged in to Garmin Connect. Reports which credentials are present and whether the cached session is usable. Never returns the password or the cached token itself. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| plan_view | The training plan as an interactive view: progress, the next session, and each week's days. |
| crew_view | A Daash crew's week as an interactive view: who runs when, and which runs to do together. |
TDQS
Scored across 26 tools
Most tools target clearly distinct resources and the descriptions explicitly steer between overlapping calls such as get_plan, get_progress, and get_readiness. However, get_profile overlaps with get_fitness on VO2 max and records, and several recovery/health tools surface related signals, creating some risk of misselection.
Names consistently follow a snake_case verb_noun pattern: get_*, list_*, create_*, update_*, delete_*, schedule_*, and unschedule_*. The few noun-like names such as get_heart_rate and get_connection_status still fit the same predictable convention.
At 26 tools, the surface is heavy for a single assistant, though the broad Garmin training, health, workout, and plan domain justifies many of them. Some tools feel padded or duplicative, especially get_profile versus get_fitness, get_progress versus get_plan, and multiple overlapping health-read tools.
Coverage is broad: workouts can be created, read, updated, scheduled, unscheduled, and deleted; plans can be created, read, and removed; activities can be listed, inspected, and updated; and health, recovery, fitness, shoes, and connection status are covered. Minor gaps remain, such as deleting activities, managing shoes or goals directly, and editing a plan other than through individual workouts or full removal.