目录 / Blocks
MCP
鉴权未知
未评级
已上架
Blocks
AI-native training platform for cyclists and runners. Your agent reads your training calendar, synced rides and runs from Strava or intervals.icu, sleep and HRV, and a sourced sports-science base with evidence levels, then plans and adjusts your week. Every write asks first. Free, no subscription. Setup guide: https://blocks.zone/ai
该来源不提供完整文件导出(国内平台多为平台内托管),仅存元数据与原链
接入信息
- 传输形态
- http
- 鉴权方式
- 鉴权未知
- 端点
https://blocks--blocks.run.tools
鉴权方式未标注,请核对官方文档后再接入——不要直接使用以下片段
{
"mcpServers": {
"Blocks": {
"url": "https://blocks--blocks.run.tools"
}
}
}
能力清单
| 工具 | 说明 |
|---|---|
| search_knowledge | Search the curated endurance-science knowledge base (studies + syntheses on physiology, training, nutrition, recovery, heat, women's health, strength, masters, injury, etc.). Returns ranked COMPACT CARDS — each is refId · title · evidence level · athlete Tier · sport · DOI · ▶ actionable bottom-line, plus `finding` (what the study measured) and, on a framework, `decision` (its rule) — usually enough to answer AND cite directly. Call get_knowledge(refId) only when you need the full protocol/mechanism/limitations of a specific entry (optionally get_knowledge(refId, section) for just one part). Always ground science answers in these entries and cite refId + level; give the DOI only when the reader asks for the source itself, or when you are writing somewhere they can click it. |
| get_knowledge | Read an entry by refId (REF-001 / SYNTH-04). Default returns a COMPACT DIGEST (key findings + practical application + limitations) — usually all you need beyond the search card. Pass `section` for one specific part (e.g. 'Protocol', 'Mechanism', 'Cross-References') when you need depth. Prefer answering from the search card first; only call this when the card is insufficient. Cite refId + level, and the DOI only if the reader asks for the source itself or can click it; weight advice by evidence level. |
| get_related | List the entries cross-referenced by a given refId (traverse the citation graph). |
| list_sections | List all knowledge-base sections with entry counts (the topic map). |
| get_athlete_profile | Read the athlete's profile: FTP, threshold pace, max/threshold HR, the resolved zone model, AND the `athlete` block (age, sex, height, weight, W/kg, weekly training hours, available weekdays, experience level) — use those to right-size volume, ramps and fuelling. Call this first when planning. `effective` shows the bounds the app actually uses (auto presets resolved) plus absolute watt/pace/HR targets per zone and the athlete block; `raw` is the stored profile incl. the auto/manual flags you'd pass to update_athlete_profile. |
| get_context | THE WHOLE PICTURE IN ONE CALL — start a conversation with this. Returns the athlete's date and weekday (so you do not also need get_today), then everything the Blocks app itself puts in front of its own assistant on every turn: the plan from yesterday to +7 days with a done / NOT-done verdict ALREADY COMPUTED per planned session, today's readiness with its baselines and confounders, thresholds and the resolved zone tops (watts, pace and bpm, so you never compute one), recent activities with the athlete's own notes, 14 days of planned-vs-done, 12 weeks of weekly load, upcoming events, what their own twelve weeks say about how they respond, and the facts they have recorded. Pass `question` — the athlete's own words, in any language — and the knowledge base is ALSO searched for you before you answer, so the evidence is in your hands without you having to guess the right query; it does not answer the question, it only decides what to retrieve, and without `question` nothing is searched. WHEN TO CALL: as the first tool call of a conversation, and again only after a long gap or when the athlete says something has changed since (a ride synced, a check-in logged, a threshold set). A second call in the same conversation almost always returns what you are already holding — use get_plan, list_activities, get_readiness_today, list_facts or search_knowledge for the one thing it did not cover. Read-only: it writes nothing. |
| get_today | Today's date on the athlete's Blocks account: ISO date, weekday, and ISO week. Call this to anchor any relative reasoning — 'today', 'tomorrow', 'this week', 'the weekend', 'in 3 days' — and to pass the correct `date` to other tools. The date is server-derived (UTC-based); if you have reason to think the athlete is in a timezone where it's already a different calendar day, say so and confirm rather than assume. |
| update_athlete_profile | Edit the athlete's profile — FTP (watts), running threshold pace, max/threshold HR, power/pace/HR zone boundaries, AND the about-you fields (birthdate, sex, heightCm, weightKg, weeklyHours, availableDays 0=Mon..6=Sun, experience). Every field is OPTIONAL: pass only what changes; everything else is preserved (safe partial update). Confirm new numbers with the athlete before writing (a changed FTP/weight moves every target). To set custom zones pass a sport's `zoneBounds` (5 strictly-ascending upper bounds) — that flips it to Manual; pass `autoZones:true` to revert. Same for `hrZoneBounds`/`autoHrZones`. Setting birthdate refreshes the age-based HRmax estimate unless maxHr was set manually — writing a sport's maxHr marks it manual, and autoMaxHr:true hands it back to the estimate. Server-validated; rejects an invalid edit instead of writing a broken profile. Only touches the profile, never the calendar or library. Read with get_athlete_profile first. |
| get_metric_history | The HISTORY of a measured number — FTP, threshold pace, LTHR, max HR, weight, VO2max, MAP, LT1/LT2, lactate, ferritin, haemoglobin, RHR, HRV. The profile carries the CURRENT value and only that (it is overwritten in place), so this is the only way to answer "is it moving": weight trend, FTP across a season, LT2 between two lab tests, a falling ferritin. Rows carry `source` — profile | lab | field-test | estimate | self-report — and a lab number and a field estimate are NOT the same measurement twice: say which you are comparing. Deliberately not in the turn snapshot; call it when the question is about a trend, not about today. |
| log_metric | Record a MEASUREMENT with its date — a lab test (LT1, LT2, MAP, VO2max, a lactate draw), a blood panel (ferritin, haemoglobin), a weigh-in, a field-test result. One call takes several rows, so a whole lab report lands as one card. This is history, not the profile: it does NOT change what the app plans against — if the test says the threshold moved, propose update_athlete_profile as well and say so. Date the MEASUREMENT, never today-because-that-is-when-they-told-you. `note` is where the test came from ("Trisystems СПб, step test to exhaustion"), never an interpretation of the athlete. |
| list_facts | Everything you know about this athlete, as separate facts with how long each is true. The ACTIVE ones already ride in every turn's snapshot — call this when you need the rest: what has lapsed, what is asleep out of season, retired history, or a specific area in full. Each fact carries `state`: live (applies now) · lapsed (an `until` whose date has passed — it stops applying, and its OPPOSITE does not start applying: ask before taking the freed space) · stale (a `recheck` come due, or a pattern nobody has seen in half a year — still the best we have, no longer trustworthy) · asleep (a seasonal rule outside its window: the plan simply stops obeying it, this is not a question) · retired (someone decided it was done). |
| add_fact | Record ONE thing you now know about the athlete, with how long it is true. This is the assistant's memory: it is NOT a copy of the snapshot and NOT a training log. Three tests, all must pass — (1) it is not already handed to you every turn (age, weight, hours, available days, thresholds, zones, race dates, the plan, load, readiness, response_profile), (2) no tool computes it (get_metric_history, get_records, get_activity), (3) it outlives this session — the verdict on one workout goes on that workout with set_activity_notes. AREA decides what survives when context is tight: "health" and "constraint" are never cut, "pattern" is the only capped area. Nuance goes in `tags`, which are free. CONSTRAINTS ARE THE ONES NOBODY VOLUNTEERS, so ask: a fixed commitment on a day the profile calls free (tennis every Friday, the school run) · another coach's remit · an injury to plan around · and EQUIPMENT, tagged `equipment`. Kit is the constraint that makes a prescription IMPOSSIBLE rather than merely wrong — an athlete with 9 kg dumbbells at home cannot do the 10 kg you wrote, and they read it as an instruction. Record what they actually have, in their words ("гантели 2×9 кг, турник, резинки; штанги нет" · "зал с полной стойкой" · "станок дома + шоссе + гревел, мощемер только на шоссе"), and give it a horizon like anything else: a gym membership is an `until`, a turbo in the hallway is often a `season`. HORIZON is required and there is no "unknown": if you cannot say how long it holds, ASK before writing. "stands" = until they say otherwise. "until" + dueDate = it ends (a race, an arrangement); when the date passes the fact stops applying and its opposite does NOT start applying. "recheck" + dueDate = it does not become false, it becomes untrustworthy (a threshold, a blood value, weekly hours). "season" + seasonFrom/seasonTo = true only part of the year (months, may wrap: 11-03 is November to March). "pattern" = an observation; set confirmations as you see it again. `dueAction` is the line between a date that becomes a CALENDAR item and a date that is merely a question. Set it only when the due date carries something the athlete DOES ("сдать ферритин", "перемерить порог 30-мин тестом") — that is proposed as a calendar entry on the date itself. Leave it empty for "ask whether this still holds": no calendar clutter for a conversation. Silent when the athlete just told you the fact. A CARD when it carries a dueAction (it will put something in their calendar), when it is a pattern (that is your inference about them, not their words), or when it `replaces` a fact already on their page. ONE IDEA, ONE LINE. If a live fact of the same area already says something like this, the call is HELD and you get those facts back with their ids: answer with `new:true` (genuinely different — both stay, and a different day, date, trip or measurement IS different however alike the wording), `replaces:<id>` (this supersedes it — the old one is retired as this is written), or `confirms:<id>` (literally the same thing — that fact is bumped and your line is discarded). Every fact in your snapshot already ends with its #id, so a pattern you see again is confirm_fact on that id, not a second add_fact. |
| update_fact | Change ONE fact — its text, its horizon, its date, its tags. Use it when the athlete corrects something or when a horizon is answered ("tennis holds through the winter" → move the recheck). Always a card: this edits something already on their Profile page, and often something they wrote. To only bump a pattern's strength use confirm_fact, which is silent. |
| confirm_fact | You saw a pattern happen again. Bumps its confirmations and stamps today, which is what makes it outrank weaker patterns when context is tight — and what stops it decaying out of the snapshot after six months unobserved. Silent, no card: counting an observation is not a claim about the athlete. Use it instead of writing the same pattern twice. |
| retire_fact | This is no longer true, or never was. Always a card: retiring is how the athlete's own words leave their page, and they get to see it go. The fact is kept and marked retired rather than deleted — a retired fact is out of your context and still visible to them, because "we stopped believing it" is not "it never happened". A LAPSED fact is NOT automatically retired: its date passing means you no longer know, so ask first. |
| get_athlete_file | Everything you know about this athlete, rendered as one document — the same content the athlete reads on their Profile page under "What I know about you". Kept for readers that want it in one piece; `list_facts` is the structured form and the one to use when you need ids, states or a single area. The `grade` block (sport / level / populations) is machine-read and scopes every knowledge-base search. |
| update_athlete_file | Set the athlete's GRADE — the machine-read classification that scopes every knowledge-base search: `- sport: <primary>[, others]`, `- level: recreational|trained|competitive|elite`, `- populations: <any of female-health, masters, youth, para — or —>`. That is ALL this tool writes now. Everything the assistant remembers about the athlete moved to separate facts on 2026-08-24 (add_fact / update_fact / confirm_fact / retire_fact), because a fact needs a horizon and free prose cannot carry one: three cancelled-race sections went on steering plans for a month. Grade is the exception on purpose — a classification has no expiry date, so it is the one thing left here. |
| search_catalog | Search workouts: the Blocks catalog, coach collections AND the athlete's own saved workouts (source: mine). Reuse an existing workout before inventing one — this is how you find it by keyword, by a rep interior, or among the athlete's own saved workouts, which are deliberately not in the catalog map. Filter by sport, target zone, and a duration window; returns id, title, zone, duration, TSS, IF, source. Pass a returned id to plan_workouts as workoutId. |
| get_catalog_workout | Read the full block structure of one workout by id — catalog, collection or the athlete's own library (to inspect before scheduling or adapting). |
| get_plan | Read what is already scheduled on the athlete's calendar in a date range (so you don't double-book and can balance weekly load). Returns per-day workouts with duration + TSS + any note, plus day notes. `key:true` marks a KEY session — the one the week is built around, declared in advance. Read it before you move anything: under a bad readiness or a lost evening you reshape the week around the key sessions, moving a key one rather than dropping it, and you sacrifice the non-key work first. Pass structure:true to also get each workout's full interval structure (compact, e.g. "6' @55% + 3×(12' @90% / 4' @55%)"); for raw blocks of ONE entry use get_plan_workout. |
| get_plan_workout | Read ONE scheduled workout in full detail: compact interval structure, raw blocks (zones, %intensities, durations, labels, cadence), totals and notes. Use the iid from get_plan / the athlete snapshot. This is how you inspect exactly what the athlete is supposed to do before advising on or editing a session. |
| update_plan_workout | Edit ONE scheduled workout in place (keeps its position and identity on the calendar): replace its interval blocks (bike/run) or strength items (gym), and/or title and/or note. Use for structural coaching edits — a better warm-up, changed rep count, adjusted intensities — instead of remove+re-add. Read it first with get_plan_workout. blocks/strength fully REPLACE the old content (same format as plan_workouts custom workouts; validated server-side). |
| get_strength_log | What the athlete actually DID in a planned gym session — set by set — and what they changed in the plan before starting it. A strength session has no TSS and no duration, so this is the only record of how it went: sets done against sets prescribed, load and reps per set, the RPE they were actually taken at, and the athlete's reason when something diverged. TWO LAYERS, and they answer different questions: `amended before the session` is a DECISION taken in advance (by the athlete, or by you — the line says which), while a set line is what the body did on the day. An athlete who drops the load every Monday morning and one who fails the last set every Monday need opposite advice. Read this before prescribing the next gym session, and before judging whether the last one was completed — the calendar alone cannot tell you. |
| get_interval_progression | The same rep family across sessions — the interval ledger. Families are what an athlete would say: 3′ @ threshold, 30″ @ vo2, 20′ @ threshold (a sustained effort is a set of one), read by DURATION for rides and runs alike so a planned 1 km rep and its execution land in one family. Per session, newest first: reps × the watts they were ridden at (or pace where the file had metres) and the % of threshold at import, heart rate over the first rep against the last (HR a→b — the drift, from the stream), the sRPE they gave the session, the lactate they logged, and what they wrote. THIS IS WHERE A TARGET COMES FROM: before writing watts, a pace or a % into a rep session, read interval_progression in the snapshot (the families the week ahead needs, the last three each) or this for the longer arc and every family. The same watts at a lower sRPE and HR is the athlete getting fitter; more watts at sRPE 9 is not a step up. Arithmetic over stored structure, nothing to cite. `family` is a substring of the label ("3′", "threshold"); `zone` filters; `weeks` looks back (default 12, max 52). |
| get_strength_progression | One exercise across sessions — the lift history. For every exercise the athlete has logged (or the one you name; substring match on their own exercise names, so "присед" finds both squats), the last sessions newest first: the heaviest set actually done (kg×reps; seconds or metres for timed/distance work; bw = bodyweight), sets done against sets planned, the RPE it was taken at against the target, the plan where it differed from what was done, and what the athlete wrote about that session. THIS IS WHERE A WEIGHT COMES FROM: read it before writing a kg into a gym session — the snapshot's strength_progression holds the last three per exercise for the sessions in view, this holds the longer arc and every exercise. Reads the frozen prescription each session was logged against, so it survives a replaced or deleted calendar card. Arithmetic over the log, nothing to cite. |
| plan_workouts | Add one or more workouts to the athlete's training calendar (the days appear in Blocks). WORKFLOW per day: prefer an existing workout and pass its id as `workoutId` — from the catalog map already in your context if you have one, otherwise via search_catalog. Only when nothing suitable exists, pass a custom `workout` (validated server-side; also saved to the athlete's library). Optionally attach a short `note` per item, and set `key:true` on the one or two sessions the week is built around (you may set at most 2 per week yourself — the athlete has no such limit — declare them FIRST and fill the rest of the week around them, which is also the order a week is planned in). Batch the whole block (e.g. 3 weeks) in one call. Returns per-item result with the new iid, duration and TSS. |
| remove_from_plan | Remove a single scheduled workout (by iid) from a date, or clear the whole day when iid is omitted. |
| copy_workouts | Copy planned work from one day to other days — the athlete's own Copy/Paste, as a tool. Pass `iid` to copy ONE scheduled session (from get_plan), or omit it to copy everything planned on that day. Reach for this instead of re-writing the session with plan_workouts whenever they want the SAME thing again — a repeated Tuesday, last week's long ride, the gym session that worked: it carries the exact structure, the note, the context tags and the key star, and it invents nothing. The copies are independent entries — editing one later changes nothing else, and no series links them. A copy ADDS to the target day; to replace what is there, call remove_from_plan for that day first and say so. |
| copy_week | Copy a whole training week onto other weeks, weekday by weekday — Monday's work lands on Monday. `from` and each entry in `to` may be ANY date inside the week you mean; the week is taken from it. Day notes travel too, but only onto days that have none. This is the tool for «повтори прошлую неделю», for repeating a base week before it steps up, and for laying the same block out three times — it is one call instead of a dozen plan_workouts items, and it reproduces the week exactly. It ADDS to the target weeks: days that already hold work keep it, so a week you mean to REPLACE has to be emptied first with remove_from_plan, day by day, which the athlete will see you do. |
| set_day_note | ADD a SHORT note to a calendar day — a few words capturing the key thought (e.g. "easy week, watch sleep"), NOT an essay. A day holds SEVERAL notes; this appends one and never touches the athlete's own notes on that day. Max 1000 chars, but keep yours brief; the athlete uses the long form for their own impressions of the day. For a LIST they will tick off (race kit, the evening before a test) use add_checklist, not this. Pass an empty string to clear ALL notes on that day. Optional colour tags the note — the athlete assigns the meaning of each colour themselves, so only set it when they've told you what a colour means, or reuse a colour already on that day. |
| add_checklist | Put a CHECKLIST on a calendar day, or ADD ITEMS to the one already there — a day note whose items the athlete ticks off in the calendar, desktop and phone. Use it when they want a list to work through, not advice to read: a race kit, the evening before a test or a race, a travel bag. Title + items; a list with the same title on that day is EXTENDED (ticks kept, duplicates skipped). Items are concrete things to do or take, a few words each — not advice, not training (that is plan_workouts). One day per call; it does not repeat. Saved on return, no card. Read it back in the day's notes: "[x] …" is ticked, "[ ] …" still open — say what is left instead of asking. You cannot tick for them. |
| set_workout_note | Write a SHORT note on one scheduled workout (iid from get_plan / plan_workouts) — a few words, the key thought (e.g. "key session, commit" or "legs flat — cut a set"). Max 140 chars. Empty string clears it. |
| list_activities | List the athlete's recent COMPLETED activities (actual rides/runs/etc. imported from Strava) with id, date, sport, name, duration, distance, TSS, IF, NP, avg/max power & HR, kJ, elevation, meaningful-effort count (sustained work efforts, not raw segments), and any existing notes. Use this to find an activity id before writing a summary with set_activity_notes, and to base that summary on the real numbers. Defaults to the 30 most RECENT activities — a row count, not a date window, so for a three-a-week athlete that is ten weeks and for a daily one it is a month. Whenever the answer depends on how much time a stretch covers — a ramp, a stall, consistency, a block review — pass explicit from/to and read the dates you get back. On a row, `coachNote` is the VERDICT line of your own earlier review of that session (an excerpt — `coachNoteChars` is the full length; get_activity returns it whole) and `note` is the athlete's words, cut at 300 characters. |
| get_activity | Read ONE completed activity in full detail: all stats (NP, IF, TSS, avg/max power & HR, cadence, elevation, kJ, sRPE/load), aerobic decoupling (decouplingPct — Pw:Hr drift, measured over the WORK: heart rate at the same power from the first rep to the last on a session with reps, or across the halves of one sustained effort. `decouplingBasis` names which; when the number is absent, `decouplingNote` says why. Never quote it as drift without reading the basis — the whole-file version it replaced called a two-beat session 6.9%). `work_reps` lists each sustained rep in order with the power it was ridden at and its heart rate as `hr` (mean), `hrStart`, `hrEnd` and `hrMax` — this is the athlete's own heart-rate graph as numbers, so read it instead of asking them for a screenshot of one. Read the SHAPE, not the mean: a rep that climbs and settles and one that climbs and keeps climbing average the same, as do a rep the athlete eased off and one he did not. Rising hrEnd at unchanged watts across reps is drift; flat is an aerobically clean session whatever any percentage says, the interval structure and the device LAP structure if the file had laps, plus both notes. WHICH structure to read the session by is stated by `structure_read_by`: when the athlete has set this session to Laps on the card, `structure`/`blocks` ARE the file's laps and the detection travels alongside as `structure_auto_detected` — read the version they are looking at and don't re-cut the session into intervals they rejected. Otherwise it is our detection, as `structure_detected`/`blocks_detected`, with any laps as `structure_laps` — and when both are present, NEVER report a prescribed element as not done, cut short, or skipped on the strength of its absence from the detection alone: the detection reads the trace and can miss real work, while the laps are the athlete's own thumb on the button, so check both and grade on the laps when they disagree. Each detected block carries its own CADENCE and TERRAIN — `92rpm` and `-62m/11.4km` mean the block lost 62 m over 11.4 km, i.e. a descent. Read them before attributing a power drop to fatigue: falling watts at a high cadence on a losing gradient is a rider out of gears, not a tiring one, and terrain is shown only where the net change exceeds 10 m. Use the id from list_activities. This is how you analyze how a session was actually executed (interval powers, rep consistency) before writing a coach read or adjusting the plan. Returns BOTH zone splits when the file supports them: `time_in_zone_min` is the stored measure and `time_in_zone_basis` names which quantity it is (%FTP, %threshold pace, or %maxHR) — read it before comparing this session's zone minutes with another's, because the same key is not the same quantity across activities. Two more preconditions travel with their numbers: `tss_basis` says whether a run's rTSS was grade-adjusted or read off raw pace (no altitude in the file), and `np_caveat` appears when the ride is too short for a 30-second rolling average to be stable and `hr_time_in_zone_min` is the heart-rate split, which the stored column never holds for a run — use it to tell a real physiological excursion from pace running ahead of a stale threshold mark. Its `ref` field names the maxHR the percentages are taken from; when that says it is a default rather than the athlete's measured maximum, say so instead of quoting the zones as precise. `description` is what the athlete (or the app that recorded the session) wrote on Strava / intervals.icu — on a gym session pushed from an app like Motra it holds every exercise, set, rep and weight, and since such a file carries neither power nor distance it is not a remark ABOUT the session, it IS the session: read it as the content and grade against it. list_activities flags its presence as `hasDescription`. |
| set_activity_notes | Write a coach summary / opinion on one completed activity — the athlete sees it in the activity card in Blocks (labelled “Coach read”). Pass the activity `id` from list_activities. By default it REPLACES the coach note; pass append:true to add. Optionally set a post-session `grade` (A..E) for how the session was EXECUTED vs the plan — it shows as a colored badge on the ride card (A=nailed it, B=solid/minor deviations, C=partial/mixed, D=undercooked/well off target, E=missed/abandoned; a smart bail on a genuine bad day is NOT automatically E — grade the execution + judgement, not the athlete). Ground the read in the real numbers (duration, TSS, IF, NP, HR, zones, intervals from list_activities/get_activity), the athlete profile and the knowledge base — concrete and useful, not generic praise. Markdown renders in the app — keep it airy: a few short `##` sub-headings with normal-weight prose (or short `-` bullets), `**bold**` only on a key number or the verdict, and don't restate the ride name or the grade (they're shown separately above the note and as a badge). Separate from the athlete's own note. |
| tag_activity | Set CONTEXT tags on one completed activity (full-array write; empty array clears). Tags describe how the session should be READ, not what it contained: workout (a plain training session — read it against the plan), heat (hot conditions — HR inflated, output depressed, expected), altitude (ridden high — hypoxic shift, lower power is normal), indoor (turbo trainer, treadmill or a virtual platform — still air means HR climbs through the session at unchanged power, so drift is expected and is not a fitness signal; speed, distance and pace are the platform's invention, so judge power, HR and RPE and never km or min/km, and never compare them with outdoor numbers), race (max effort by design — grade vs the race goal, not the plan), test (FTP/lactate/field test — peak efforts deliberate; consider estimate_thresholds after), group (group ride — surging, structure deviations expected), commute (transport volume, not training intent). Use when the athlete tells you the context ('вчера была жара', 'это была гонка') or when you infer it and they confirm. Immediate write — the tag chips appear on the activity card. |
| rename_activity | Give one completed activity the athlete's own title, e.g. 'FTP test' or 'Гонка Царь Грейдер'. Pass an empty string to clear it and fall back to the name the provider gave. This does NOT touch the source: the provider's own name is kept separately and rewritten on every sync, so a rename here survives Sync now. Use when the athlete asks for it or when a generic 'Ride' hides what the session actually was — never rename on your own initiative. |
| edit_activity | Correct the MEASURED numbers on one completed activity when the recording got them wrong — jammed GPS, a dropped sensor, a computer left running. Three modes, and picking the right one is the whole job: • `extend` — part of the session DIDN'T RECORD and the athlete says it was like the rest ('первые полчаса не записались, ехал так же'). Pass the new TOTAL `movingTime` in seconds. Volume scales, intensity is kept, and the personal bests stand. Pass `distance` too if they know the real total (their usual loop); otherwise it follows the duration. • `correct` — a recorded number is FALSE ('Страва посчитала 42 км, а я пробежал 10'). Pass the corrected absolute values. Correcting the distance REMOVES this session's distance records — they were computed from the wrong track and the true splits can't be recovered — so tell the athlete that before they apply. • `revert` — undo an earlier correction and put the provider's original numbers back ('верни как было'). No values needed. All values are absolute NEW totals (seconds, metres), never deltas. You do NOT compute the consequences: the server recomputes TSS, IF, work and time-in-zone and the confirmation card shows every before→after. Ask for whatever you're missing rather than guessing a number — and get_activity first, so you are correcting the real values. Once corrected, the session is the athlete's: syncs from Strava/intervals stop overwriting its measured fields, and it counts as corrected in the week, the load history and the Records tab. |
| log_readiness | Record the athlete's daily readiness — one entry per date, idempotent MERGE-upsert: only the fields you send are updated, existing fields survive. Accepts a BATCH (up to 90 items) so you can backfill history from an export (e.g. months of HRV/RHR/sleep) in a few calls. Subjective core (McLean 1-5, 5=best: fatigue, sleep_quality, soreness, stress, mood) + prs (0-10) is the primary signal; objective fields (rhr bpm, hrv_rmssd ms, sleep_total_min, deep_sleep_min) are optional manual values from the athlete's wearable. Confounder flags (late_meal, alcohol, hookah, smoking, life_stress, illness, injury, poor_sleep_external, travel, underfuelled, long_day, heat, meds) record WHY a day might look off. Record them as ticked; never fold a confounder into the numbers themselves. Values are range-checked (e.g. rhr 25-110) so a typo can't poison the baselines. |
| get_readiness_today | The athlete's readiness picture for one morning: today's entry (subjective 1-5 + PRS + confounder flags + any manual objective values) PLUS per-metric aggregates from their own history — baseline_7d, baseline_28d (personal normal), sd_28d, z_today, rolling_3d (key subjective trend signal), delta_vs_baseline, and n28 (datapoints in the window — judge maturity before trusting z-scores). Blocks deliberately computes NO verdict: interpret the trend yourself (within-athlete shift, not absolutes; a 2-point drop on any item OR a 1-point rolling-3d shift is meaningful), weigh confounders, then adjust the plan via plan_workouts / remove_from_plan / set_day_note. Pass `date` (athlete-local) — server UTC may differ from the athlete's morning. |
| get_readiness | Raw readiness entries for a date range (subjective + confounders + manual objective values per day), plus per-metric aggregates anchored at the range end. Use for trend review ('how has the athlete slept the last two weeks?'), before/after a training block, or to check what history exists before backfilling with log_readiness. |
| get_readiness_baseline | The athlete's current per-metric baselines (7d/28d mean, 28d SD, rolling-3d, sample size) — their personal 'normal' for every readiness metric. Compare today's values against THESE, never against population absolutes. |
| log_session_rpe | Attach the athlete's session RPE (Borg CR-10, 0-10, ~30 min post-session) to a completed activity from list_activities. Blocks computes load_au = sRPE × duration_min (Foster). Works for ANY sport including gym/tennis where there's no power meter — it's the universal load currency alongside TSS. |
| get_activity_series | The ride's own CHART as a table: time-bucketed average power, heart rate, cadence and altitude across a completed activity, as CSV. This is what the app draws in the activity card, in numbers. Call it when a summary is not enough and you need to SEE the session — where heart rate crossed a level, whether it plateaued inside a rep or kept climbing, what a valley actually looked like, where the terrain turned. Buckets are chosen so any ride comes back near 150 rows. To ZOOM into one rep or one climb, pass `fromSec`/`toSec` (seconds on the moving clock — the same clock as a block's `start` in get_activity and a lactate sample's `t`) with a small `bucketSec`; a fine bucket over the whole ride is widened to fit ~300 rows and the header says so. Prefer this over asking the athlete for a screenshot of their own graph: they are reading the same data you can, less precisely. |
| log_lactate | Record the athlete's blood-lactate samples on a completed activity (their own meter readings — e.g. "lactate was 3.4 after the second rep"). Each sample: t = seconds into the session on the MOVING clock (estimate from the interval structure if the athlete says "after rep 2"), mmol = the reading. Appends to existing samples by default; replace:true overwrites the whole set. The samples appear as markers on the activity chart, and get_activity returns them for your session analysis. Store raw values only — put your interpretation in set_activity_notes, not here. |
| get_load_summary | sRPE training load (Foster AU = sRPE × minutes) summed per day and per ISO week for a date range, from activities that have sRPE logged. Complements TSS: use it to reason about total load including non-metered sports, monotony and ramp. |
| get_records | The athlete's BESTS, for one sport, in two windows at once: the last 90 days and all time. Cycling returns best average watts over 18 windows (5s…3h); running returns the fastest time over 12 distances (400m…50km) with the pace. Each row names the session it came from, and a 90-day row is marked either as still being the all-time best or with how far short it fell — that gap is the honest read on current form, far better than an absolute number. Use it to anchor threshold estimates in real efforts, to spot a decayed top end (short windows down, long ones intact), to size interval targets off what the athlete has actually held, and to tell a genuine PR from a good day. Bests come from the full-resolution stream at import, so they match what the athlete's head unit reported. `pending` > 0 means some older sessions haven't been scored yet (they get scored a few per sync) — say so rather than calling a number final. ALSO RETURNS THE THREE READINGS THE RECORDS PAGE SHOWS THE ATHLETE, off these same peaks, so you and the page can never quote different numbers: `threshold` (cp lo-hi + the anchor efforts), `battery` (W') and `fade` (the power law). When the athlete asks about their records, read all three rather than the threshold alone — a reply that discusses FTP and ignores the other two answers a third of what is on their screen. The result carries the same `howToRead` block as estimate_thresholds; follow it. |
| estimate_thresholds | Estimate the athlete's cycling FTP, LTHR and max HR from their ACTUAL synced rides over a window (default 90 days), by building the mean-maximal power curve from stored ride streams and fitting a Critical Power model on it. Returns `recommended` values, a CP range with the efforts behind it, W', a power-law fade estimate, and `confidence` with `reasons`. CYCLING ONLY — running threshold pace is NOT supported here, so for a runner use a recent race result or a 30-min field test instead. Asked to recompute an anchor from recent riding, call this and answer from what it returns: that request is what the tool is for, not a reason to send them to a test. The result carries a `howToRead` block — the estimates are FLOORS and `confidence` gates whether you may propose an update, so read it before you quote a single number. |
| list_events | List the athlete's events (races, key rides, FTP tests, camps they're preparing for) with id, date, name, location, map + event-page URLs, route distance/elevation, the athlete's logistics notes, and the current coach notes. Use this to find an event id before writing fueling/pacing guidance with set_event_notes. Defaults to upcoming events. |
| set_event_notes | Write the EXTENDED prep notes on one event (fueling, hydration, pacing, taper, kit, strategy). This fills the event's coach-notes section in Blocks. Pass the event `id` from list_events. By default it REPLACES the coach notes; pass append:true to add to them. Base fueling/pacing on the route distance/elevation + the athlete profile + the knowledge base, and keep it concrete (carbs g/h, fluid, sodium, caffeine timing, power targets). Markdown is fine. |
| create_event | Create an event the athlete is preparing for (race, key ride, FTP test) on their Blocks calendar. Use when the athlete describes one in chat. Requires name + date (YYYY-MM-DD). Optional: description, location, map/event-page URLs, logistics notes, and prep (coach) notes. The GPX route is added by the athlete in the app. Event-day weather is fetched automatically when within ~16 days. Returns the new event id (pass it to set_event_notes to add detailed prep). |
| update_event | Edit an existing event's fields (name, date, description, location, URLs, logistics notes) — every field optional, only what you pass changes. Use when the race date shifts, the venue changes, or details firm up. Weather re-resolves automatically when date or location changes. For the coach-notes section use set_event_notes; for prep content changes don't touch this. |
| delete_event | Delete an event from the athlete's calendar (it was cancelled or added by mistake). This removes the event AND its prep notes permanently — prefer update_event when only details changed. |
| list_commitments | Everything you have already asked THIS athlete to do that is still open — your own instructions from earlier turns, with ids. The open ones already ride in the snapshot; call this to see closed ones too, or to check what you told them about a specific date before you say it again. |
| close_commitment | Judge one of your own earlier instructions once the day it applied to has passed and the session is in the data: kept, missed, or dropped (you changed your mind, or it stopped being relevant). Say what actually happened in one line. An instruction nobody ever checks teaches the athlete that none of them matter — this is how you close that loop. |
| get_response_profile | How THIS athlete actually responds, computed from their own last 12 weeks: whether quality sessions land where they are aimed, whether their sRPE separates hard days from easy ones, whether low morning readiness has actually predicted a poor session, and which weekday the plan leaks on. Arithmetic over their own history — no literature, so nothing here needs a citation and nothing can be out of scope. Silent where the sample is too small; an empty answer means there is genuinely nothing to say yet. |
| get_progression | Whether the athlete's BLOCK is progressing or repeating, per quality family (tempo/threshold/vo2/sprint), read off their own calendar: the shape prescribed each week, the working minutes behind it, and whether any axis moved — duration, density or intensity. Names the case where only the target climbed on an unchanged shape, which looks like progress and is not. Arithmetic over the plan, so nothing here needs a citation. It reads the prescription AND what was executed (time at the family's zone or harder, from the synced activities), and reports the two separately — including the case where the plan grew and the work did not arrive, and the case where the athlete is outrunning a flat plan. Silent below three weeks of history, and easy families are deliberately never reported (repeating the same endurance ride weekly is correct training). |
纠错与举报(发现条目失效、署名有误或涉及侵权?)
提交举报 / 纠错
侵权举报经核验成立后,我们会即时下线该条目并删除已存的内容副本。