Ask a language model for evidence and you get some. Whether the study exists is another question.
The second part was about how the watch data reaches the model. That closes the first gap from part 1: the model no longer has to guess how much load someone is carrying. The second gap is harder. Even with all the numbers it needs knowledge to put them in context, and it has that knowledge from its training data. Unevenly, mixed with forum wisdom and without a reference.
You don't notice this in the answers, which all sound good. You notice it when you ask back. "Where does that come from?" leads to a study with a plausible title and plausible authors that can't be found. Or to a rule of thumb dressed up as a finding.
The compendium
So training mcp brings its own knowledge: a compendium of 2,080 cards in 13 areas, from periodisation through load and recovery to nutrition and psychology. Each card records exactly one finding, with evidence strength, scope and source. The header of a card looks like this:
id: even-pacing-beats-going-out-too-fast
title:
de: Gleichmäßiges Tempo schlägt den zu schnellen Start
statement: >
In distance racing the most common and most costly mistake is
going out too fast early. ...
evidence:
strength: moderate
basis: narrative-review
scope:
sports: [running, triathlon, cycling]
training_status: [recreational, well-trained, elite]
target_group_transfer: direct
sources:
- slug: 2013-roelands-pacing-central-fatigue
kind: study
read_level: full-text
locator: "..."
Below that comes the text in fixed sections: finding, numbers, scope, application, limits, sources. The body is in English because the sources are in English and the search works with technical terms. Titles and example questions also exist in German.
The field that matters is strength. Of the 2,080 cards, 39 are listed as strong evidence, 575 as moderate and 1,466 as weak. At first glance that looks like a weak collection. But it reflects what a lot of training theory rests on: quite a few statements found in common training plans go back to a single small study or a textbook model. The model should know that and say so, instead of presenting everything with the same certainty.
Then there is contested. 197 cards contradict another card, for example on ACWR as a predictor of injuries. In that case the model is supposed to show both sides.
Where the cards come from
The cards are made in two steps, both as skills for Claude Code. A study radar searches PubMed for new papers in the compendium's areas and compares them against what is already there. The full texts come from open sources: PubMed Central, Unpaywall, Semantic Scholar, OpenAlex. Shadow libraries are excluded.
From a full text, the second skill extracts the individual findings and writes them in the fixed format. Full text is the default. A card based only on an abstract is marked as an exception, because the numbers and limitations are usually in the methods section. If a new finding contradicts an old one, both cards get the note.
A check script keeps the collection consistent: valid YAML, ID matching the file name, no dead references between cards. Whether a finding reproduces the study correctly is something it doesn't check. That remains reading work, and it isn't done for all cards yet.
The model has to want to look
A compendium on its own changes little. A language model answers from its own memory first, and it only calls a search tool when it sees a reason to. When it does search, it tends to phrase the query the way it already expects the answer to look. So the compendium has several entry points that give the model a reason at different points in the conversation.
compendium-map returns the table of contents: areas, subtopics, number of cards and typical questions. After that the model knows what exists at all and searches in a targeted way.
compendium-search searches and weights by what is known about the user. Sports come from their sessions, age from the account, volume from the last few weeks. A card that only has evidence for elite cyclists drops down the list for a recreational runner and carries the note does_not_fit. A general RAG system can't do that, because it doesn't know the user's data.
The data tools point to cards on their own. training-load names the card on injury prediction next to ACWR, along with the note "contested". The mapping is maintained by hand and not searched. That way the model comes across evidence without asking for it.
And the instructions to the model are explicit. Before any recommendation on volume, intensity, recovery, nutrition or strength it is supposed to search. Every recommendation on load, recovery or nutrition it is supposed to back with a card, in a fixed form:
[even-pacing-beats-going-out-too-fast · moderate · narrative-review]
If there is no matching card, it is supposed to say so instead of inventing one. It is not supposed to present rules of thumb as findings.
The search
The first version of the search was plain full text. With English technical terms that worked reasonably well, with a German user question like "Warum breche ich in der zweiten Rennhälfte so ein?" ("Why do I fall apart in the second half of the race?") hardly at all: only for 37 percent of the questions was a matching card among the first five.
Today it is a hybrid search in Meilisearch, full text and vectors mixed, with a weight of 0.6 for the vectors. The vectors are computed by bge-m3 in a separate Ollama container on the same server. No search query leaves the system, and there are no per-query costs. The model may send up to four phrasings in one call, for example the user's question, a short English form and the technical term. The hits are merged using Reciprocal Rank Fusion.
This is measured against a fixed set of 126 questions across all 13 areas. For the German user question, an expected card is now among the first five in 92.9 percent of cases, and with all phrasings in 99.2 percent. The measurement runs weekly, so that a new batch of cards can't make the search worse without anyone noticing.
What the server calculates instead of asking the model
The second source of invented content is numbers a model derives by itself. Is today's HRV below the normal range? Has volume gone up too quickly? A model likes to work that out in its head, and sometimes it is right, sometimes not.
In training mcp the server calculates this. The hints from readiness and hints follow named rules with a version, currently 2026-10-05. Each hint carries its input values, the rule and the result. From the code:
A hint can be recalculated: input values, rule including version, result. It doesn't judge. "HRV 30 ms, normal range 41 ± 4, below range" is a hint; whether that is to be expected is decided in the conversation.
The assessment stays with the model, and it is good at that. After a race the day before, a low HRV is to be expected, after a quiet week it isn't. The model can clarify that in the conversation if it asks. It shouldn't have to invent the number itself.
The same applies to training load. training-load returns CTL, ATL, TSB and ACWR with method and thresholds including where they come from, and with the sentence "These are model values, not measurements" in the description.
Conclusion
The model can still invent things with a compendium. It does so less often, and what it makes up is more likely to stand out. When the model refers to [even-pacing-beats-going-out-too-fast · moderate · narrative-review], you can look up what it says, how strong the evidence is and whether it applies to you.
Writing the cards was the smaller part of the work. What took longer were the paths to them: the table of contents, the weighting by profile, the references from the data, and instructions the model actually follows.
The fourth part is about what doesn't belong in the chat: analytics over weeks and months.
Call to Action
training mcp is in beta with a small group of users, the public launch is in early November. Twelve sample findings with numbers and sources are public at https://training-mcp.app.
If you are working on a similar knowledge base for another field and are interested in how the search is measured, get in touch.
