Quantified Self MCP Server
A local-first MCP server that lets AI agents read, log, and analyze personal health data with built-in privacy and evidence/provenance.
Read daily health metrics, raw measurements, workout sessions, and metric history.
Log daily metrics, raw measurements, and workout sessions; clear individual metrics.
Analyze metrics: baselines, trends, anomalies, period comparisons, correlations, recent changes, and explained metric changes.
Preview source-priority aggregation and inspect per-source provenance.
Export health data to CSV locally.
Enforce privacy via HEALTH_PRIVATE_FIELDS and attach evidence/claim quality to analytics.
(Per README) Check data/import status and import CSV/Apple Health data.
Allows importing health data from Apple Health export files (XML) into the local database, as well as reading and logging daily health metrics.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Quantified Self MCP ServerWhat was my average sleep and steps last week?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Quantified Self MCP
Your health data. Your AI. Your machine.
A local-first MCP server that gives AI agents access to your personal health data โ with privacy, provenance, and evidence built in.
What is it?
Quantified Self MCP gives an AI agent a local, structured interface to your own health history.
Instead of another health dashboard, you can ask your AI questions like:
Why did my HRV change recently?
How has my sleep changed over the last 30 days?
What happened to my resting heart rate after my workouts increased?
What patterns do you see across my recent health data?
Which metrics changed the most this month?The AI retrieves the relevant data through MCP and analyzes it.
The goal isn't another health dashboard.
It's a trustworthy interface between your health history and your AI.
Related MCP server: apple-health-mcp
Why is it different?
๐ Local-first
Your health database runs locally in SQLite.
You control where your data goes.
You can use a completely local AI stack:
Health Data
โ
Local SQLite
โ
Quantified Self MCP
โ
MCP Agent
โ
Local LLMCloud models are also supported. In that configuration, the MCP database remains local, but data returned by MCP tools may be sent to the model provider.
๐ค AI-native
Built specifically for MCP-compatible AI agents, rather than another standalone health application.
๐ Evidence & provenance
Analytics can be traced back to the underlying health data and its provenance.
The goal is not simply:
HRV โ 24%but understanding:
What data produced this result?
Where did it come from?
What period was analyzed?
How strong is the evidence, and how strongly may it be claimed?Concretely, every trend, baseline, anomaly, comparison, correlation, recent change, and explained metric carries a claim alongside its numbers โ not just descriptive coverage, but an explicit, machine-checkable statement of how strongly the result may be reported:
Analysis result
โ
claim: ClaimEvidence
โโโ evidence โ what data was actually observed (coverage, gaps, freshness)
โโโ profile โ how much evaluative evidence exists, per dimension
โ (sample, temporal, missingness, ...)
โโโ decision โ what claim strength is justified: insufficient,
suggestive, detectable_not_meaningful, or supported โ
plus the specific caveats that must be statedevidence is descriptive: it reports the coverage a result rests on (how many days were logged, how large any gaps are, how fresh the data is). profile evaluates that coverage along several independent dimensions rather than collapsing it into one number. decision is the authoritative output: the only field that says how strongly the result may actually be claimed, and it is derived exclusively from the assessed dimensions in profile โ never from a raw coverage number by itself. Composite results (like explaining a metric change, which combines a headline claim, a trend claim, and any correlations) roll their component decisions up into a single overall_decision, which is never stronger than the weakest component.
Without evidence:
Your HRV decreased 24% over the last 30 days.
With evidence:
Your HRV decreased 24% over the last 30 days โ but HRV was only logged on 71% of those days, so treat this trend cautiously rather than as a settled pattern.
The second answer is what calculate_metric_trend (and every other analytics tool) is designed to make possible: the tool returns the 24% figure and a claim.decision alongside it (e.g. tier: "suggestive", with must_state naming the specific gaps and low-coverage days behind that tier), and each tool's own description tells the calling model to report that tier and those caveats rather than stating the number as if it came from a complete series.
๐ Longitudinal
Analyze health history across days, weeks, months, and years:
trends
baselines
anomalies
period comparisons
correlations
recent changes
metric explanations
๐ฅ Import existing data
Bring your existing health history into the local database.
Supported imports include:
CSV
Apple Health exports
See the import documentation.
What can your AI do?
Read
Health metrics
Metric history
Raw measurements
Workout sessions
Data provenance
Analyze
Baselines
Trends
Anomalies
Period comparisons
Correlations
Explain
Recent changes
Metric changes
Supporting evidence
Data provenance
The MCP currently exposes 20 tools across data access, measurements, workouts, analytics, personal intelligence, and data freshness (get_data_status, get_import_status).
See the tool reference for the complete list.
Supported data
Currently supported metrics include:
๐ Steps
๐ด Sleep
โค๏ธ Heart rate
โค๏ธ Resting heart rate
๐ HRV
โ๏ธ Weight
๐๏ธ Workout minutes
๐ Mood
๐ง Water
The data model is extensible, so you can keep only the metrics you actually use.
Quick start
Install
pip install quantified-self-mcpImport your data
CSV:
quantified-self-init-db your-health-data.csvApple Health:
quantified-self-init-db export.xmlConnect an MCP client
Configure your preferred MCP-compatible client to run:
quantified-self-mcpClient-specific setup guides are available in docs/clients/.
Ask your AI
How has my sleep changed over the last 30 days?That's it.
Privacy
Health data is sensitive.
Quantified Self MCP is designed around local ownership:
Your database stays on your machine.
No proprietary health-data cloud is required.
You choose the AI model.
You can run the entire stack locally.
Private metrics can be excluded from AI access.
For example:
HEALTH_PRIVATE_FIELDS=weight_kg,moodPrivate fields remain stored locally but are excluded from MCP read and analytical operations.
See SECURITY.md for security considerations.
Architecture
AI Agent
โ
MCP Protocol
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโ
โ Quantified Self MCP โ
โ โ
โ Data ยท Analytics โ
โ Evidence โ
โโโโโโโโโโโโฌโโโโโโโโโโโ
โ
โผ
Local SQLite
โ
โผ
Your Health DataThe MCP server is the bridge between your health history and your AI.
Documentation
Detailed documentation lives outside the README:
Open source
Quantified Self MCP is open source and built for the wider MCP ecosystem.
Contributions are welcome โ especially around:
health-data imports
analytics
evidence and data quality
privacy
MCP client integrations
documentation
See CONTRIBUTING.md.
License
MIT
Your health data. Your AI. Your machine.
Local data. Open protocol. AI-powered insight.
Available Tools
20 toolsaggregate_measurementsPreview a source-priority resolution of a day's measurementsARead-onlyIdempotent
Preview what one day's raw measurements would roll up to if a conflicting metric were resolved using source_priority, alongside that day's actual current daily_metrics values.
daily_metrics is a database-maintained projection (see db/schema.sql): every log_measurement/import automatically keeps it in sync the moment it's written, using each metric's fixed aggregation method (sum/mean/last โ see aggregation_rules, or get_baseline's "method" field). When a metric has measurements from more than one source on a day, the projection uses only one source's observations โ never a blend of devices. It takes the highest-ranked present source in the stored source priority list (manual log_daily_metric entries rank first by default); if none is ranked, the source that observed the most hours of that day, then the one with the latest observation, then by name. This tool writes nothing: "aggregated" previews what the source_priority you pass would produce; "row" is the real, currently-stored value, which differs from "aggregated" whenever the stored priority differs from the one you pass.
If a metric has measurements from more than one source that day (e.g. an Apple Watch and a Garmin both logging resting_heart_rate), use get_metric_provenance first to see whether they actually disagree.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | The day to preview, formatted YYYY-MM-DD. | |
| source_priority | No | Ordered list of source names, e.g. ["Apple Watch", "Garmin"]. For any metric with more than one source that day, the first name in this list that's actually present wins in "aggregated" and the other source's readings for that metric are dropped from that preview. Omit to use the stored priority list and the same fallback the stored projection uses. Never affects "row" โ see above. |
Output Schema
| Name | Required | Description |
|---|---|---|
| row | Yes | |
| date | Yes | |
| aggregated | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the annotations' readOnlyHint/destructiveHint by explaining that the tool writes nothing, how the stored daily_metrics projection is maintained, the full source-selection fallback algorithm, how 'aggregated' differs from 'row', and a privacy caveat about data entering the conversation. This is rich behavioral context that an agent genuinely needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and structured into clear paragraphs covering mechanics, edge-case guidance, and privacy. It is somewhat long for a two-parameter read-only tool, and a small amount of content overlaps with the schema descriptions, but it is dense and every section earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the output schema exists, and the annotations already cover read-only/idempotent safety, the description supplies everything an agent needs: the exact computation semantics, the fallback ranking logic, the distinction between hypothetical and actual values, a cross-tool precondition, and a privacy note. No critical context is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% parameter coverage, including detailed descriptions of date format, source_priority ordering, omission behavior, and the fact that source_priority never affects 'row'. The tool description adds surrounding conceptual context about the stored priority list but does not need to add parameter syntax. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb and resource: 'Preview what one day's raw measurements would roll up to if a conflicting metric were resolved using source_priority, alongside that day's *actual* current daily_metrics values.' It clearly separates the hypothetical 'aggregated' result from the real stored 'row' value, making the tool's unique role unmistakable among the many metric-reading siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete conditional guidance: if a metric has measurements from more than one source, 'use get_metric_provenance first to see whether they actually disagree.' This tells the agent when to check another tool before invoking this one. It does not exhaustively enumerate when not to use the tool or name all alternative tools, but the provided workflow is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
calculate_metric_trendCalculate metric trendARead-onlyIdempotent
Fit a simple straight-line trend to one metric over a window and report its direction, slope (change per day), and r_squared (how well a straight line actually fits โ low r_squared means "noisy," not "flat").
Use this tool when:
the user asks whether one metric is trending up/down/flat over a continuous window (e.g. "is my weight trending down?", "how has my HRV changed?").
Do not use this tool when:
the user wants two specific, separately-defined ranges compared (e.g. "this month vs last month") rather than a single continuous slope -> use
compare_metric_periodsinstead.the user asks what's typical/normal rather than which direction it's moving -> use
get_baselineinstead.the user asks about isolated unusual days rather than an overall direction -> use
detect_metric_anomaliesinstead.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| metric | Yes | One of steps, sleep_hours, resting_heart_rate, weight_kg, workout_minutes, mood, water_ml, heart_rate, hrv_ms. | |
| end_date | No | Last day to include, formatted YYYY-MM-DD. Defaults to today. | |
| start_date | No | First day to include, formatted YYYY-MM-DD. Defaults to 30 days before end_date. |
Output Schema
| Name | Required | Description |
|---|---|---|
| claim | Yes | Evidence and decision for the trend claim; read claim.decision before reporting it. |
| range | Yes | |
| trend | Yes | |
| metric | Yes | |
| evidence | Yes | DEPRECATED: identical to claim.evidence. Use claim.decision, not evidence.confidence. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, non-destructive behavior, and the description adds genuinely new context on top: how to interpret r_squared (low = noisy, not flat) and an explicit privacy disclosure that local data becomes part of the conversation sent to the calling client's model. That privacy/egress caveat is behavioral information no structured field provides.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and its outputs, then structured into scannable when/when-not bullets. The privacy paragraph is longer than the rest but earns its place by flagging a non-obvious data-handling consequence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite an output schema existing (so return values need not be explained), the description still clarifies the meaning of the key returned statistic. Combined with the branching guidance and privacy note, an agent has everything needed to select and call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including the enumerated metric values and the start/end date defaults, so the schema carries the parameter burden. The description only restates 'one metric over a window' without adding format or edge-case detail beyond the schema, which is the baseline-3 case.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('fit a simple straight-line trend to one metric over a window') and enumerates the exact outputs (direction, slope per day, r_squared). It also disambiguates itself from three named siblings, so an agent can distinguish it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'use this tool when' and 'do not use this tool when' sections, each routing to a concrete alternative (compare_metric_periods, get_baseline, detect_metric_anomalies) with the exact user phrasing that selects each one. Nothing about tool selection is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clear_metricClear a single metricADestructiveIdempotent
Blank out (set to null) a single metric for a single day, without touching that day's other metrics. The counterpart to log_daily_metric for undoing a bad value โ e.g. a mood logged for the wrong day, or a weight entered with the wrong units. Clears everything recorded for that metric/day โ including individual log_measurement readings or imported rows, not just a value log_daily_metric wrote directly โ so the metric genuinely goes back to "nothing recorded" rather than falling back to a blended value from whatever else is left.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | The day to clear a field for, formatted YYYY-MM-DD. | |
| field | Yes | Which metric to blank out. One of: steps, sleep_hours, resting_heart_rate, weight_kg, workout_minutes, mood, water_ml, heart_rate, hrv_ms. |
Output Schema
| Name | Required | Description |
|---|---|---|
| row | No | |
| note | No | |
| cleared | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the annotations' destructiveHint by detailing the full scope of destruction: it clears everything recorded for that metric/day, including individual log_measurement readings and imported rows, not just values written by log_daily_metric. It also adds a privacy note about data becoming part of the conversation sent to a model, which annotations do not cover.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The main behavioral statement is front-loaded and precise, and the extra detail about clearing all related rows is necessary for a destructive tool. The privacy note adds relevant context but is somewhat tangential to invocation, keeping this from a perfect score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter destructive operation, the description fully covers what the tool does, the scope of the destruction, and a privacy consideration. The output schema exists, so return-value details are not the description's responsibility.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already fully documents both parameters. The description reinforces the behavior ('set to null', 'single metric', 'single day') but does not add meaning beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a precise verb ('blank out / set to null') and identifies the exact resource ('a single metric for a single day'), making the operation unmistakable. It also distinguishes itself from the sibling log_daily_metric by explicitly naming it as the counterpart for undoing a bad value.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly explains when to use this tool: for undoing a bad value, with concrete examples like a mood logged for the wrong day or weight entered with wrong units. It does not enumerate explicit when-not-to-use cases or alternative tools, but the context is clear enough for an agent to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compare_metric_periodsCompare two periodsARead-onlyIdempotent
Compare one metric's average between two date ranges โ e.g. "this month vs. last month" or "since starting a new medication vs. before." The two ranges may be any length and need not be adjacent or equal in size; each is summarized with its own baseline first.
Use this tool when:
the user names or implies two distinct date ranges to weigh against each other (e.g. "compare my average steps this month to last month", "since starting a new medication vs. before").
Do not use this tool when:
there's only one continuous window and the question is about direction over time, not two discrete ranges -> use
calculate_metric_trendinstead.the user wants "what's normal" for a single window, not a before/after comparison -> use
get_baselineinstead.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| metric | Yes | One of steps, sleep_hours, resting_heart_rate, weight_kg, workout_minutes, mood, water_ml, heart_rate, hrv_ms. | |
| period_a_end | Yes | ||
| period_b_end | Yes | ||
| period_a_start | Yes | ||
| period_b_start | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| claim | Yes | Evidence and decision for the period comparison claim; read claim.decision before reporting it. |
| delta | No | |
| metric | Yes | |
| period_a | Yes | |
| period_b | Yes | |
| pct_change | No | |
| period_a_stats | Yes | |
| period_b_stats | Yes | |
| period_a_evidence | Yes | DEPRECATED: identical to claim.evidence_a. Use claim.decision, not a standalone confidence field. |
| period_b_evidence | Yes | DEPRECATED: identical to claim.evidence_b. Use claim.decision, not a standalone confidence field. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed world), yet the description adds genuinely new behavioral context: each range is summarized with its own baseline first, and a privacy note explains that returned data flows to the calling client's model. It stops short of documenting the date format or any limits on range size.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then cleanly bulleted when/when-not routing, then the privacy caveat last. The privacy paragraph is long but is a genuine disclosure rather than filler; overall the structure earns its length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the routing plus privacy coverage make the definition self-sufficient for selection. The only missing piece an agent still needs is the required date format for the four period parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 20%: the four period_*_start/end parameters have no schema descriptions at all, and the description does not give a date format or syntax for them. It does add useful semantics (ranges may be any length and need not be adjacent or equal, each gets its own baseline) and the metric enum is documented, but the undocumented date params leave a real gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence gives a specific verb (compare) and resource (one metric's average) plus the exact scope (two date ranges), with concrete examples. It is immediately distinguishable from siblings like calculate_metric_trend and get_baseline.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use this tool when' and 'Do not use this tool when' sections that name the alternative sibling for each exclusion (calculate_metric_trend for one continuous window, get_baseline for single-window norms). Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
detect_metric_anomaliesDetect metric anomaliesARead-onlyIdempotent
Flag days where one metric deviated sharply from its own baseline over the window, using a median/MAD-based modified z-score rather than a mean/stdev z-score โ more robust for short, noisy personal-health series, where the mean/stdev version is easily dragged around by the very outliers it's supposed to catch.
Use this tool when:
the user asks whether anything looked unusual/off/weird on particular days for one metric (e.g. "was there anything unusual about my sleep last month?").
Do not use this tool when:
the user wants a general sense of what's typical, with no interest in flagging specific days -> use
get_baselineinstead.the user asks about a steady increase/decrease over time rather than isolated spikes/dips -> use
calculate_metric_trendinstead.the user already has one specific date in mind and wants the full "why" behind it (baseline, anomaly, trend, and correlations together) -> use
explain_metric_changeinstead.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| metric | Yes | One of steps, sleep_hours, resting_heart_rate, weight_kg, workout_minutes, mood, water_ml, heart_rate, hrv_ms. | |
| end_date | No | Last day to include, formatted YYYY-MM-DD. Defaults to today. | |
| threshold | No | Modified z-score cutoff. 3.5 (the default, Iglewicz & Hoaglin's standard value) flags only clear outliers; lower it (e.g. 2.5) to see more borderline days. | |
| start_date | No | First day to include, formatted YYYY-MM-DD. Defaults to 90 days before end_date. |
Output Schema
| Name | Required | Description |
|---|---|---|
| claim | Yes | Evidence and decision for the anomaly claim; read claim.decision before reporting it. |
| range | Yes | |
| metric | Yes | |
| evidence | Yes | DEPRECATED: identical to claim.evidence. Use claim.decision, not evidence.confidence. |
| anomalies | Yes | |
| threshold | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive, and closed-world traits, so the description is not obligated to restate safety. It adds real value beyond that by explaining why the method is robust for short noisy series and by disclosing a privacy consequence (returned data enters the conversation sent to the client's model). It does not mention handling of missing/short series, which would round this out.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well front-loaded: what it does and why, then when/when-not, then the privacy caveat. Every section earns its place, though the privacy note is lengthy and could be tightened without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need no explanation, annotations carry the safety profile, and all four parameters are fully documented in the schema. Combined with the routing guidance, an agent has everything required to select and call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents every parameter thoroughly, including the allowed metric values, date formats, and the Iglewicz & Hoaglin rationale for the 3.5 threshold default. The description adds no parameter-level detail beyond that, so the baseline 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and scope ('Flag days where one metric deviated sharply from its own baseline over the window') and even names the statistical method (median/MAD modified z-score). An agent can distinguish this from get_baseline, calculate_metric_trend, and explain_metric_change without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use this tool when' and 'Do not use this tool when' blocks, with three named alternatives (get_baseline, calculate_metric_trend, explain_metric_change) and the exact user-intent condition that selects each. Includes a concrete example query. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
explain_metric_changeExplain a metric changeARead-onlyIdempotent
Build an evidence bundle for "why did my look like that on ?": that day's value against a 90-day baseline, whether it qualifies as an anomaly, the trend leading into it, and any other metric that correlates with it strongly enough to be worth mentioning. Returns facts, not an explanation โ turning "sleep was 2.6 stdev below baseline and resting heart rate correlates at r=0.71" into an actual answer for the person is what the calling model should do with these facts, not something this tool guesses at itself.
Do not use this tool when:
scanning across many metrics for what changed lately, without a specific metric/date in mind -> use
get_recent_changesinstead.you only need one piece of this bundle (just the baseline, just the trend, just anomalies, or just a correlation) rather than the full why-explanation -> use
get_baseline,calculate_metric_trend,detect_metric_anomalies, orfind_metric_correlationdirectly instead.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | The day to explain, formatted YYYY-MM-DD. | |
| metric | Yes | One of steps, sleep_hours, resting_heart_rate, weight_kg, workout_minutes, mood, water_ml, heart_rate, hrv_ms. |
Output Schema
| Name | Required | Description |
|---|---|---|
| date | Yes | |
| trend | Yes | |
| value | No | |
| metric | Yes | |
| baseline | Yes | |
| sessions | No | |
| is_anomaly | Yes | |
| trend_claim | Yes | Evidence and decision for the 30-day trend leading into this day, assessed separately from the headline claim. Read trend_claim.decision before reporting it. |
| baseline_claim | Yes | Evidence and decision for the 90-day baseline statistics reported in "baseline" (and quoted in narrative_facts). Read baseline_claim.decision before stating what is typical for this metric; it is one of the components overall_decision is the weakest of. |
| baseline_range | Yes | |
| headline_claim | Yes | Evidence and decision for the headline claim: this day's value against its 90-day baseline. Read headline_claim.decision before reporting it. |
| narrative_facts | Yes | |
| conflicting_days | No | |
| modified_z_score | No | |
| overall_decision | Yes | The single decision governing this whole result: weakest-of-N over the headline claim (headline_claim.decision), the trend (trend_claim.decision), and every surfaced correlation's own decision. If any component is insufficient/suggestive, the composite is too โ report overall_decision.tier and must_state rather than treating the headline claim as though the trend and correlations couldn't drag it down. |
| correlated_metrics | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only/idempotent/no-destruction, and the description adds behavior the annotations cannot: it declares the output contract ('Returns facts, not an explanation') so the caller knows to synthesize, and adds a privacy disclosure about locally-stored data being sent to a cloud model. Neither is derivable from structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose, then cleanly sectioned into when-not and privacy. Every part earns its place, though the closing sentence elaborating on the 'facts not explanation' point is somewhat wordy and restates the earlier contract.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given complex aggregation behavior, two fully-documented params, and an existing output schema (so return values need no explanation), the description covers purpose, boundaries, output semantics, and privacy. Nothing an agent needs to invoke this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% โ the metric enum values and the YYYY-MM-DD date format are fully documented in the schema. The description adds no parameter syntax or format detail beyond that, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('build an evidence bundle') and resource (metric/day bundle), and enumerates exactly what the bundle contains: value vs 90-day baseline, anomaly qualification, leading trend, and correlated metrics. It also names the siblings it is not (get_recent_changes, get_baseline, etc.), so an agent can distinguish it without opening another schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Do not use this tool when' section gives two concrete exclusion conditions and routes each to the correct alternative tool by name (get_recent_changes for scanning; the four single-purpose tools for partial needs). This is as clear as when/when-not guidance gets.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_health_data_csvExport health data to CSVADestructiveIdempotent
Write daily health metrics for a date range to a CSV file on disk, next to the database, instead of returning every row through this tool's own result.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
Unlike read_health_data, this is not capped at MAX_ROWS_RETURNED and the row values themselves are not included in this tool's response โ only the resulting file's path and a row count are. That means a long-range export doesn't have to pass through a cloud LLM's context just to produce a file you can open yourself (in a spreadsheet, a notebook, another tool, etc.). Any metric listed in HEALTH_PRIVATE_FIELDS is still written as an empty cell in the file, since those fields shouldn't leave the database at all, not just stay out of the model's context.
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | No | Last day to include, formatted YYYY-MM-DD. Defaults to today. | |
| start_date | No | First day to include, formatted YYYY-MM-DD. Defaults to 30 days before end_date. Ranges over ~10 years are rejected. |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | Yes | |
| range | Yes | |
| rows_exported | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations mark destructiveHint=true and readOnlyHint=false, and the description fully supports this: it states it writes to disk, does not return row values, and only provides file path and row count. It goes beyond annotations by disclosing the privacy implication (data becomes part of the conversation) and the handling of HEALTH_PRIVATE_FIELDS as empty cells. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is somewhat long but each paragraph earns its place: purpose, privacy note, and comparison with read_health_data. It is front-loaded with the main action and uses structured paragraphs. Slightly verbose but not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool that writes to disk and has privacy implications, the description covers all necessary aspects: side effects, return value (path and row count), difference from read_health_data, private field behavior, and privacy guidance. The output schema exists, so return format is already specified. An agent has everything needed to decide and call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage: both start_date and end_date have clear descriptions with formatting and defaults. The description adds no new semantic detail about the parameters beyond 'date range', so it stays at the baseline for well-covered schemas.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair: 'Write daily health metrics for a date range to a CSV file on disk, next to the database.' It clearly distinguishes itself from read_health_data by contrasting the output (file path vs. rows) and the row cap. An agent immediately knows what this tool does and how it differs from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly names the alternative (read_health_data) and explains the differentiator: this tool is not capped at MAX_ROWS_RETURNED and avoids passing data through the model context. It also advises treating the export like pasting into a chat if the model is cloud-based. This gives the agent clear conditions for choosing this tool over alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_metric_correlationFind correlation between two metricsARead-onlyIdempotent
Compute the Pearson correlation between two metrics over the same window, joined by date. Correlation, not causation: a strong r just means the two moved together, not that one caused the other.
Use this tool when:
the user names or implies two different metrics and asks whether they move together (e.g. "does my sleep affect my mood?", "did my HRV change after I increased my workouts?").
Do not use this tool when:
only one metric is in question -> use
get_baseline,calculate_metric_trend, ordetect_metric_anomaliesinstead, depending on what's being asked about that one metric.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | No | Last day to include, formatted YYYY-MM-DD. Defaults to today. | |
| lag_days | No | Shift metric_b this many days later before joining โ 1 tests whether metric_a today predicts metric_b tomorrow (e.g. "does poor sleep tonight predict lower steps tomorrow?"). 0 (default) compares same-day values. | |
| metric_a | Yes | ||
| metric_b | Yes | ||
| start_date | No | First day to include, formatted YYYY-MM-DD. Defaults to 90 days before end_date. |
Output Schema
| Name | Required | Description |
|---|---|---|
| n | Yes | |
| r | No | |
| note | No | |
| claim | Yes | Evidence and decision for the correlation claim; read claim.decision before reporting it. |
| lag_days | Yes | |
| metric_a | Yes | |
| metric_b | Yes | |
| evidence_a | Yes | DEPRECATED: identical to claim.evidence_a. Use claim.decision, not a standalone confidence field. |
| evidence_b | Yes | DEPRECATED: identical to claim.evidence_b. Use claim.decision, not a standalone confidence field. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (read-only, idempotent, non-destructive), and the description adds genuinely non-obvious context: the local SQLite file vs. cloud-model egress caveat, and the correlation-vs-causation interpretation warning. These are behavioral traits no structured field conveys.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the operation, then cleanly partitioned into use / do-not-use / privacy blocks. Slightly lengthy because of the multi-sentence privacy paragraph, but every block carries actionable information and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need no explanation, and the alternatives, interpretation caveat, and privacy implications are all covered. The one remaining gap is the metric identifier format for the two required parameters, which an agent must guess.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 60%: lag_days and the date bounds are well documented in the schema itself. However, metric_a and metric_b carry no schema description, and the description does not explain the expected metric identifier format or how invalid/unknown metric names are handled, so it only partially compensates for the gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific operation (Pearson correlation), the resources (two metrics), and the join semantics (same window, joined by date). It also explicitly disambiguates from siblings get_baseline, calculate_metric_trend, and detect_metric_anomalies, so an agent can route without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use criteria (two different named or implied metrics moving together) and explicit when-not-to-use criteria (single-metric questions) with named replacement tools. This is the strongest form of routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_baselineGet metric baselineARead-onlyIdempotent
Compute "what's normal" for one metric over a window: mean, median, and standard deviation. This is the number every other analytics tool below measures against, so a wider window (60-90+ days) gives a more stable baseline than the 30-day default read_health_data uses.
Use this tool when:
the user asks what's normal/typical/usual for one metric (e.g. "what's normal for my resting heart rate?"), with no particular day or direction of change in mind.
Do not use this tool when:
the user asks whether a metric is going up/down over time -> use
calculate_metric_trendinstead.the user asks whether specific days looked unusual -> use
detect_metric_anomaliesinstead.the user wants two ranges compared against each other -> use
compare_metric_periodsinstead.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| metric | Yes | One of steps, sleep_hours, resting_heart_rate, weight_kg, workout_minutes, mood, water_ml, heart_rate, hrv_ms. | |
| end_date | No | Last day to include, formatted YYYY-MM-DD. Defaults to today. | |
| start_date | No | First day to include, formatted YYYY-MM-DD. Defaults to 90 days before end_date. |
Output Schema
| Name | Required | Description |
|---|---|---|
| claim | Yes | Evidence and decision for the "what's normal" claim; read claim.decision before reporting it. |
| range | Yes | |
| metric | Yes | |
| baseline | Yes | |
| evidence | Yes | DEPRECATED: identical to claim.evidence. Use claim.decision, not evidence.confidence. |
| data_health | No | Whether the data behind this baseline is complete, current and trustworthy. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), but the description adds genuinely non-obvious behavior: the window-stability tradeoff (60-90+ days recommended vs. the 30-day default elsewhere) and a privacy disclosure that returned data enters the conversation sent to a possibly cloud-hosted model. These go well beyond structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then cleanly organized into when/when-not bullets and a separate privacy note. The privacy paragraph is longer than strictly needed for tool selection, but it is clearly delineated and earns its place given the data-sensitivity stakes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the description instead covers what is missing elsewhere: selection criteria, sibling routing, window-stability behavior, and privacy implications for a local data server. Nothing an agent needs in order to call this correctly is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the parameters are documented, giving a baseline of 3. The description adds real semantic guidance about window sizing ('a wider window (60-90+ days) gives a more stable baseline'), which informs how to set start/end dates beyond their bare format descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a precise verb and resource ('Compute "what's normal" for one metric over a window') and names the exact statistics computed (mean, median, standard deviation). It explicitly positions itself relative to siblings by noting it is 'the number every other analytics tool below measures against' and contrasts its default window with read_health_data's 30-day default.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Contains explicit 'Use this tool when' and 'Do not use this tool when' sections with a concrete user-phrasing example ('what's normal for my resting heart rate?'). Each exclusion routes to a named alternative (calculate_metric_trend, detect_metric_anomalies, compare_metric_periods), so selection between siblings is fully determined.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_data_statusCheck how current the data isARead-onlyIdempotent
Report how current and complete the database is: latest data date, coverage window, gaps, last successful import, and an overall status of CURRENT, STALE, INCOMPLETE, NO_DATA or IMPORT_FAILED. Check this before drawing conclusions from any analysis, and say so when the status is anything other than CURRENT.
Use this tool when:
the user asks how up to date their data is, or whether an import is needed.
you are about to interpret recent data and want to know whether it is fresh enough to trust.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| stale_after_days | No | How many days the latest data may trail today before the status becomes STALE. Defaults to 2. |
Output Schema
| Name | Required | Description |
|---|---|---|
| gaps | Yes | |
| as_of | Yes | |
| action | No | |
| reason | No | |
| source | No | |
| status | Yes | |
| coverage | Yes | |
| gap_count | Yes | |
| days_behind | No | |
| latest_data | No | |
| missing_days | Yes | |
| latest_import | No | |
| days_with_data | Yes | |
| stale_after_days | Yes | |
| last_successful_import | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/non-open-world, and the description adds value beyond them: the privacy note explains that returned data becomes part of the cloud conversation, which is a real behavioral consequence the schema cannot express. The enumerated status values (CURRENT/STALE/INCOMPLETE/NO_DATA/IMPORT_FAILED) also tell the agent how to interpret results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the payload of returned fields, then a scannable bulleted when-to-use list. The privacy paragraph is longer than strictly needed for tool selection, but it is purposeful and clearly separated, so the structure holds up.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Annotations cover the safety profile and an output schema exists, so return shape need not be described. The description fully covers purpose, usage, and the privacy caveat; the only gap is failing to situate itself relative to the overlapping sibling get_import_status.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so stale_after_days is fully documented in the schema with its default and semantics. The description mentions STALE status but never references or explains the parameter, adding nothing beyond what the schema already provides. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource ('Report how current and complete the database is') with the returned fields and the exact status enum values spelled out, so an agent knows precisely what it gets back. It does not, however, differentiate itself from the sibling get_import_status, which overlaps on the 'last successful import' dimension.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use this tool when:' bullets cover the two main triggers (user asks about freshness; about to interpret recent data) plus the instruction to check before drawing conclusions. Strong context, but no exclusion or explicit routing away from get_import_status, which an agent must disambiguate on its own.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_import_statusList recent importsARead-onlyIdempotent
List the most recent import runs, newest first: which importer, the source file's name and SHA-256, whether the run succeeded, failed or was interrupted, and how many rows were loaded, skipped and written.
Use this tool when:
the user asks what was imported and when, or why an import did not go through.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many import runs to return (1-50). Defaults to 5. |
Output Schema
| Name | Required | Description |
|---|---|---|
| imports | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, closed-world and non-destructive, so the safety profile is covered. The description goes well beyond them with a privacy disclosure that the local SQLite data will be transmitted into the conversation and to whatever model the client uses, which is exactly the kind of non-obvious behavioral trait annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The return fields are front-loaded and the trigger conditions follow in a scannable bullet. Slightly marked down because enumerating return fields overlaps with the existing output schema, and the privacy paragraph, while valuable, is the longest block in the text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter read tool with full schema coverage, rich annotations, and an output schema, the description covers everything an agent needs: what it returns, when to call it, and the data-handling caveat. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single 'limit' parameter already documents its 1-50 range and default of 5 in the schema. The description adds no additional meaning about the parameter, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (list) and resource (recent import runs) and enumerates the exact fields returned: importer, source file name/SHA-256, run outcome, and row counts. No sibling tool covers imports, so there is no ambiguity to resolve, and the ordering ('newest first') is stated up front.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
An explicit 'Use this tool when' clause names two concrete triggers: asking what was imported and when, or diagnosing why an import did not go through. No exclusions or alternatives are named, but no competing import tool exists among the siblings, so the routing is effectively complete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_metric_historyGet metric historyARead-onlyIdempotent
Read one metric's day-by-day values, without the other six metrics read_health_data always includes. Use this when you only care about a single metric (e.g. before calling get_baseline or calculate_metric_trend yourself) and don't need the full multi-metric payload.
Use this tool when:
the user wants one specific metric's history/trend over time (e.g. "show my weight over the last 30 days", "how has resting heart rate changed this month").
Do not use this tool when:
the request is broad/general, across multiple metrics at once -> use
read_health_datainstead.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| metric | Yes | One of steps, sleep_hours, resting_heart_rate, weight_kg, workout_minutes, mood, water_ml, heart_rate, hrv_ms. Rejected if configured as private via HEALTH_PRIVATE_FIELDS. | |
| end_date | No | Last day to include, formatted YYYY-MM-DD. Defaults to today. | |
| start_date | No | First day to include, formatted YYYY-MM-DD. Defaults to 30 days before end_date. |
Output Schema
| Name | Required | Description |
|---|---|---|
| range | Yes | |
| metric | Yes | |
| points | Yes | |
| evidence | Yes | Coverage/quality of the data a single-metric analytical result is based on. See evidence.build_evidence for how each field is computed. |
| data_health | No | Whether this history is complete, current and trustworthy; see DataHealth. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description adds genuinely non-redundant context: a privacy note that returned data enters the conversation with the calling model, and that a metric configured via HEALTH_PRIVATE_FIELDS is rejected. This is meaningful behavioral disclosure beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded and the when/when-not structure is skimmable. The privacy paragraph is longer than the rest and could be tightened, but it earns its place by disclosing non-obvious data-flow behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, so return-shape explanation is unnecessary, and the description covers selection criteria, scope, and privacy caveats. Nothing an agent needs to call this read-only tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the metric enumeration, format, and default windows for start_date/end_date are already documented in the schema. The description reinforces the single-metric framing but adds no syntax or format detail beyond the schema, so the baseline 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb and resource ('Read one metric's day-by-day values') and immediately contrasts scope with the sibling read_health_data, which always returns all metrics. An agent can distinguish this tool from read_health_data and the trend/baseline siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use this tool when' section with concrete user-phrasing examples ('show my weight over the last 30 days') and an explicit 'Do not use this tool when' clause routing broad multi-metric requests to read_health_data. Alternatives and conditions are named, not inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_metric_provenanceBreak a metric down by sourceARead-onlyIdempotent
Show one metric's raw measurements for one day, broken down by which source reported them โ answers "which one is correct?" when e.g. an Apple Watch and a Garmin disagree on resting heart rate, instead of silently averaging two different devices into one number.
Do not use this tool when:
the user just wants a plain day-by-day history for the metric, with no need to see the per-source breakdown -> use
get_metric_historyinstead.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | The day to inspect, formatted YYYY-MM-DD. | |
| metric | Yes | Name of the metric to inspect, e.g. "resting_heart_rate". |
Output Schema
| Name | Required | Description |
|---|---|---|
| date | Yes | |
| metric | Yes | |
| sources | Yes | |
| conflict | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive behavior, and the description adds meaningful context beyond that: it explains the data becomes part of the conversation and may be sent to a cloud model. This is a real behavioral disclosure about data flow and privacy that an agent could not infer from the schema or annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well structured: purpose leads, a do-not-use block clearly distinguishes the sibling tool, and the privacy note is placed at the end. It is longer than strictly necessary because of the privacy explanation, but each paragraph earns its place and the key information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple two-parameter input, full schema coverage, output schema presence, and complete annotations, the description covers what an agent needs to call this tool correctly. The only minor gap is that it does not spell out the exact return shape or whether source values are normalized, but the output schema covers that burden.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers 100% of the two parameters, including formats and examples for `date` and `metric`. The description does not add much beyond the schema, but the terms 'one day' and 'metric' reinforce the single-day, single-metric scope. The schema does the heavy lifting, so a baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a concrete action and resource: 'Show one metric's raw measurements for one day, broken down by which source reported them.' It directly distinguishes the tool from the sibling `get_metric_history` by emphasizing the per-source breakdown and the 'which one is correct?' use case. The verb and scope are specific enough that an agent can tell what it is for.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly names the alternative: 'Do not use this tool when... use `get_metric_history` instead.' It also gives a concrete triggering scenario (e.g., Apple Watch and Garmin disagreeing on resting heart rate), making both when-to-use and when-not-to-use clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recent_changesGet recent changesARead-onlyIdempotent
Scan every (non-private) metric for what's changed lately: a recent period vs. the four-times-as-long period before it (period-over-period shift), any anomalies inside the recent period, and a trend over it. The single best tool to start a "how have I been doing?" conversation with โ it does the scanning across all metrics that would otherwise take one get_baseline/detect_metric_anomalies/calculate_metric_trend call per metric.
Do not use this tool when:
the user already named a specific metric and wants the full why-bundle for it (value, baseline, anomaly flag, trend, correlated metrics) -> use
explain_metric_changeinstead.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Length of the "recent" window in days (default 7). The comparison baseline is the 4x-as-long period immediately before it, so a 7-day recent window compares against the preceding 28 days. |
Output Schema
| Name | Required | Description |
|---|---|---|
| changes | Yes | |
| recent_range | Yes | |
| baseline_range | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly, idempotent, non-destructive, and closed-world, so the safety profile needs no restating. The description adds real value beyond them: a privacy disclosure that returned data enters the conversation sent to the configured model, and the all-metrics scope that would otherwise require N per-metric calls. It does not discuss cost or latency for the broad scan, which is the only notable omission.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with what it scans, then the alternative, then the privacy note in that order of importance. The privacy paragraph is comparatively long for a local-only tool, but it is actionable and not redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation. With purpose, routing, scope, and the privacy caveat all covered, an agent has everything needed to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single 'days' parameter is fully documented in the schema, including the 4x comparison window. The description restates the period-over-period relationship but adds no syntax or constraints beyond it, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with explicit scope: it scans every non-private metric for period-over-period shift, anomalies in the recent window, and a trend. It names the sibling tools it replaces (get_baseline/detect_metric_anomalies/calculate_metric_trend), so an agent can distinguish it without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly frames itself as the entry point for a 'how have I been doing?' conversation, then gives a concrete when-not-to-use rule: if the user named a specific metric and wants the full why-bundle, route to explain_metric_change. Both the trigger and the alternative are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
log_daily_metricLog a daily metricADestructiveIdempotent
Record one or more health metrics for a single day, creating that day's row if it doesn't already have one.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
Only the metrics you pass are written โ anything left as null is not touched, so logging just today's mood doesn't erase today's steps if they were set earlier. To undo a value logged by mistake, use clear_metric rather than trying to overwrite it with a placeholder.
Use this tool when:
the user is recording a simple day-level value for one of the nine fixed metrics below (e.g. "log my weight as 82 kg", "I walked 8,000 steps today").
Do not use this tool when:
the observation needs its own timestamp/source, or the day may have more than one reading of the same metric -> use
log_measurementinstead.it's a workout/exercise session -> use
log_workout_sessioninstead (workout_minutes here is just the daily total, not the session itself).
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | The day to log, formatted YYYY-MM-DD. | |
| mood | No | Mood rating on a 1-10 scale. | |
| steps | No | Step count for the day. 0-200,000. | |
| hrv_ms | No | Heart rate variability in milliseconds. 0-300. | |
| water_ml | No | Water intake in millilitres. 0-10,000. | |
| weight_kg | No | Body weight in kilograms. 1-500. | |
| heart_rate | No | Non-resting heart rate reading in bpm. 20-250. | |
| sleep_hours | No | Hours of sleep. 0-24. | |
| workout_minutes | No | Minutes of exercise. 0-1,440. | |
| resting_heart_rate | No | Resting heart rate in bpm. 20-250. |
Output Schema
| Name | Required | Description |
|---|---|---|
| row | Yes | |
| logged | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses the crucial merge behavior: null metrics are untouched and only passed metrics are written. It also adds a privacy note about data becoming part of the conversation and suggests clear_metric for undo. These are meaningful behavioral details that do not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a front-loaded core statement, a privacy section, a merge-behavior section, and explicit usage conditions. Despite its length, every section addresses a real agent decision and no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutating tool with 10 parameters, the description covers sibling selection, partial-update semantics, privacy implications, and recovery via clear_metric. An output schema exists, so return-value details are not necessary. The tool is fully specified for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes all 10 parameters with units and ranges, so the baseline is 3. The description adds context like 'workout_minutes here is just the daily total' and the null-not-touched rule, but does not need to repeat the schema's per-parameter details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Record one or more health metrics for a single day', and explains the row-creation behavior. It also explicitly distinguishes itself from siblings like log_measurement and log_workout_session, so an agent can tell them apart without inspecting schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description has clear 'Use this tool when' and 'Do not use this tool when' sections with concrete conditions and named alternatives. It routes timestamped readings to log_measurement and workout sessions to log_workout_session, leaving no ambiguity about selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
log_measurementLog a raw measurementA
Record a single raw observation โ one metric, one value, one point in time โ rather than a whole day's summary. Use this instead of log_daily_metric when the source, exact time, or the fact that there were multiple readings that day matters (e.g. three separate workouts, or a wearable's periodic heart-rate samples).
Use this tool when:
recording one timestamped observation where the exact time, source, or possibility of multiple same-day readings matters (e.g. "record my blood pressure reading from my cuff at 7am").
Do not use this tool when:
it's just a single end-of-day value for a fixed metric -> use
log_daily_metricinstead.it's a workout/exercise session -> use
log_workout_sessioninstead.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| unit | No | Unit the value is in, e.g. "bpm", "kg". Optional. | |
| value | Yes | The numeric reading. | |
| metric | Yes | Name of the metric, e.g. "resting_heart_rate", "steps". Not free-form: must already have an entry in the aggregation_rules table (steps, sleep_hours, resting_heart_rate, weight_kg, workout_minutes, mood, water_ml, heart_rate, hrv_ms, out of the box) โ daily_metrics is a database-maintained projection over measurements (see db/schema.sql), so every metric written to it needs a known aggregation method (sum/mean/last) or there would be nothing telling the projection how to roll same-day readings up. metrics_schema lists the current set. | |
| source | No | Where this came from, e.g. "Apple Watch", "manual". Optional. | |
| timestamp | Yes | When the observation was taken, YYYY-MM-DD or a full ISO 8601 timestamp (YYYY-MM-DDTHH:MM:SS). | |
| source_type | No | Category of source, e.g. "wearable", "manual", "app". Optional. |
Output Schema
| Name | Required | Description |
|---|---|---|
| measurement | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safety profile (readOnlyHint=false, idempotentHint=false, openWorldHint=false), so the bar is lower. The description still adds genuinely non-obvious context the annotations cannot carry: the privacy disclosure that returned data enters the conversation sent to the calling client's model. It does not, however, discuss duplicate/repeat handling, which the idempotentHint=false annotation implies is a real concern for a timestamped-observation writer.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose and the sibling contrast, and the when/when-not bullets are scannable. The 'Use this tool when' bullet largely restates the opening paragraph, and the multi-sentence privacy note, while valuable, is disproportionately long for a logging tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists, return values need not be explained. The description covers selection criteria, exclusions, sibling routing, the metric-name constraint, and a privacy caveat โ everything an agent needs to invoke this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (unit, value, metric, source, timestamp, source_type) is already documented in the schema, including the aggregation_rules constraint on metric. The description adds no format or constraint detail beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Record a single raw observation โ one metric, one value, one point in time') and immediately contrasts it with the daily-summary alternative. An agent can distinguish it from log_daily_metric and log_workout_session without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit 'Use this tool when' and 'Do not use this tool when' sections, each with concrete examples ('three separate workouts', 'record my blood pressure reading from my cuff at 7am') and named alternatives (log_daily_metric, log_workout_session). This is about as complete as routing guidance gets.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
log_workout_sessionLog a workout sessionA
Record one workout as a structured event โ activity, timing, intensity, and heart-rate response โ rather than folding it into the day's workout_minutes total. Use this alongside (not instead of) log_daily_metric/log_measurement for workout_minutes: this is what lets explain_metric_change say what the workout was, not just how long it ran. A day can have more than one session; each call adds a new row.
Use this tool when:
the user describes an actual workout/exercise session (e.g. "I went running for 40 minutes", "log today's strength workout").
Do not use this tool when:
the user only wants to record the day's total exercise minutes as a single number, with no activity type/timing/intensity -> use
log_daily_metric(workout_minutes) orlog_measurementinstead.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | The day the workout happened, YYYY-MM-DD. | |
| notes | No | Free-text notes, e.g. route or how it felt. Optional. | |
| source | No | Where this came from, e.g. "Apple Watch", "manual". Optional. | |
| intensity | No | One of "low", "moderate", "high". Optional. | |
| start_time | No | When it started, HH:MM (24-hour) or a full ISO timestamp. Optional. | |
| activity_type | Yes | What kind of workout, e.g. "running", "cycling", "strength". Free-form. | |
| avg_heart_rate | No | Average heart rate during the workout, bpm. Optional. | |
| max_heart_rate | No | Peak heart rate during the workout, bpm. Optional. | |
| duration_minutes | Yes | How long it lasted, in minutes. |
Output Schema
| Name | Required | Description |
|---|---|---|
| session | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false, idempotentHint=false, etc., but the description adds important behavior: 'each call adds a new row' clarifies non-idempotence specifics, and the privacy note about data becoming part of the conversation sent to the model is unique contextual disclosure. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a strong first sentence, followed by structured usage guidance and a privacy note. It is longer than the minimal two-sentence example, but every section contributes value given the tool's complexity and need to disambiguate from siblings. The explicitly labeled sections compensate for length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete enough for a 9-parameter tool with 100% schema coverage and an output schema. It covers when to use, when not, privacy implications, and multi-session behavior. No significant context is missing for an agent to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema coverage is 100%, so the schema fully documents each of the 9 parameters. The description adds a high-level grouping ('activity, timing, intensity, heart-rate response') but does not provide parameter-level semantics beyond the schema. Baseline of 3 applies since schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: 'Record one workout as a structured event โ activity, timing, intensity, and heart-rate response.' It explicitly contrasts with log_daily_metric/log_measurement for workout_minutes and explains the relationship to explain_metric_change, distinguishing it from siblings without the need to open schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit 'Use this tool when' and 'Do not use this tool when' sections with concrete examples ('I went running for 40 minutes') and names the exact alternatives (log_daily_metric / log_measurement) for the excluded cases. This goes beyond mere context to actionable selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_health_dataRead health dataARead-onlyIdempotent
Read daily health metrics from the local database: steps, sleep hours, resting heart rate, weight (kg), workout minutes, mood, and water intake (ml).
Use this tool when:
the request is broad/general, across multiple metrics at once (e.g. "what health data do I have?", "overview of this week").
Do not use this tool when:
the user wants one specific metric's history/trend over time -> use
get_metric_historyinstead.the user wants raw/individual measurement rows (timestamp, source) -> use
read_measurementsinstead.the user wants workout sessions specifically -> use
read_workout_sessionsinstead.the user is asking why something changed, or wants a trend, anomaly, comparison, or correlation -> use
explain_metric_change(one metric, one date) orget_recent_changes(scan across all metrics) instead.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | No | Last day to include, formatted YYYY-MM-DD. Defaults to today. | |
| start_date | No | First day to include, formatted YYYY-MM-DD. Defaults to 30 days before end_date. Ranges over ~10 years are rejected. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | Yes | |
| range | Yes | |
| summary | Yes | |
| coverage | Yes | Multi-metric coverage for a Layer-1 result spanning several metrics at once. See evidence.build_coverage_summary for how each field is computed; unlike Evidence (one metric, gaps/freshness/recent_gap), this reports a coverage_percent per metric side by side. |
| truncated | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is established. The description adds meaningful context beyond that: the data returned is daily aggregated metrics (not raw rows), the database is a local SQLite file, and returned data may be sent to the configured model โ a privacy-relevant behavior an agent should weigh before invoking.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average but every section earns its place: a front-loaded metrics list, explicit routing rules, and a privacy note. The use of bullets under 'Use when' and 'Do not use when' makes the guidance scannable for an agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the crowded sibling set (17 tools), the description fully disambiguates this tool from get_metric_history, read_measurements, read_workout_sessions, explain_metric_change, and get_recent_changes. Combined with rich annotations, full schema coverage, and an output schema, nothing needed to select or invoke the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already documents start_date and end_date with defaults and formatting. The description adds no new parameter-level detail, but under high schema coverage the baseline of 3 applies; no compensation is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Read daily health metrics from the local database,' and lists the exact metrics covered (steps, sleep, heart rate, etc.). It also distinguishes itself from closely related siblings (get_metric_history, read_measurements, read_workout_sessions), so an agent knows exactly what this tool does and does not cover.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Use this tool when' section explicitly directs broad/general multi-metric requests to this tool, and the 'Do not use this tool when' section names four alternatives with the exact conditions that should route elsewhere. This is the strongest possible usage guidance โ no inference is required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_measurementsRead raw measurementsARead-onlyIdempotent
Read individual measurement rows (not the daily_metrics aggregate), most recent first. Use this to see exactly when and where each reading came from, rather than just a day's summarized value.
Use this tool when:
the user wants raw/individual observations (e.g. "what measurements have I recorded?"), including their timestamp or source.
Do not use this tool when:
the user wants a broad, multi-metric overview -> use
read_health_datainstead.the user wants one metric's day-by-day history -> use
get_metric_historyinstead.the user wants workout sessions -> use
read_workout_sessionsinstead.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum rows to return (default 200). | |
| metric | No | Only return this metric. Omit for all metrics. | |
| source | No | Only return rows from this source, e.g. "Apple Watch". Omit for all sources. | |
| end_date | No | Only return rows on/before this date (YYYY-MM-DD). Omit for no upper bound. | |
| start_date | No | Only return rows on/after this date (YYYY-MM-DD). Omit for no lower bound. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| measurements | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), and the description adds genuinely non-obvious context: results are ordered most-recent-first, and the privacy note discloses that returned data becomes part of the conversation sent to the configured model, which is a data-egress trait not conveyed by any annotation or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and scope are front-loaded in the first sentence, and the when/when-not lists are scannable. The privacy note is several lines long but earns its place by disclosing a real behavioral risk; overall slightly verbose but well organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained, and the description still covers ordering, scope, filtering intent, alternatives, and a privacy caveat. Nothing an agent needs to invoke this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all five parameters (limit, metric, source, start_date, end_date) are already documented in the schema with defaults and formats. The description adds only the ordering ('most recent first') and the raw-vs-aggregate scope, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a precise verb and resource ('read individual measurement rows') and immediately distinguishes the output from the daily_metrics aggregate, contrasting raw rows against summarized values. An agent can tell this apart from sibling tools without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides an explicit 'Use this tool when' section and a 'Do not use this tool when' section that names three specific alternatives (read_health_data, get_metric_history, read_workout_sessions) with the condition that selects each. Routing is fully specified with no inference required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_workout_sessionsRead workout sessionsARead-onlyIdempotent
Read individual workout sessions (not the daily_metrics workout_minutes total), most recent day first. Use this to see what each workout actually was โ activity, timing, intensity, heart rate โ rather than just a day's summed minutes.
Use this tool when:
the user asks about workouts/exercise sessions specifically (e.g. "what workouts did I do this week?", "show my recent gym sessions").
Do not use this tool when:
the user just wants the daily workout_minutes total, not individual sessions -> use
read_health_dataorget_metric_historyinstead.
Privacy note: this server and its SQLite file are entirely local, but the data returned by this tool becomes part of the conversation sent to whatever model the calling client is configured with. If that model runs in the cloud rather than on your machine, treat this the same as pasting the data into a chat with that provider.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum rows to return (default 200). | |
| end_date | No | Only return sessions on/before this date (YYYY-MM-DD). Omit for no upper bound. | |
| start_date | No | Only return sessions on/after this date (YYYY-MM-DD). Omit for no lower bound. | |
| activity_type | No | Only return sessions of this activity type. Omit for all types. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| sessions | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnly, idempotent, non-destructive), the description adds genuinely useful behavioral context: ordering is 'most recent day first,' the tool returns session-level detail rather than daily totals, and it discloses a privacy implication about data becoming part of the conversation. These are meaningful traits not captured by the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core definition, followed by structured usage guidance and a relevant privacy note. Every section earns its place: the first sentence states the tool's scope, the bullets give actionable routing rules, and the privacy note is important for local-vs-cloud model contexts. No filler is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the rich annotations, full parameter schema coverage, and presence of an output schema, the description supplies all remaining context an agent needs: when to use it, when not to, how results are ordered, and what data is returned. The alternative tools are explicitly named, so the surrounding tool ecosystem is adequately addressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents limit, start_date, end_date, and activity_type fully. The description reinforces the overall intent but does not add parameter-specific detail beyond what the input schema provides, matching the baseline for full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb and resource: 'Read individual workout sessions,' and immediately disambiguates from the daily_metrics workout_minutes total. It also enumerates the meaningful fields returned (activity, timing, intensity, heart rate) and contrast with daily aggregates, making the tool's purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit 'Use this tool when' and 'Do not use this tool when' sections with concrete example queries and names the alternatives (read_health_data, get_metric_history). An agent can confidently route between this tool and its siblings without further inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v1.0.29- Changed
get_baseline1 field changed- added
Output schema / properties / data_healthAdded value: +{ + "anyOf": [ + { + "description": "Data-quality state behind one result (not a medical or statistical confidence score). status is one of\nVALID, VALID_WITH_GAPS, INSUFFICIENT_DATA, STALE, IMPORT_INCOMPLETE; reasons lists every condition that\napplies. See data_health.compose_data_health for how it is decided.", + "properties": { + "completeness": { + "properties": { + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + } + }, + "required": [ + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days" + ], + "type": "object" + }, + "coverage": { + "properties": { + "end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + }, + "start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "requested_start", + "requested_end" + ], + "type": "object" + }, + "freshness": { + "properties": { + "age_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Days from the latest observation to the end of the requested window." + }, + "dataset_days_behind": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Days from the dataset's latest data (any metric) to today." + }, + "latest_data": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "type": "object" + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "last_import": { + "anyOf": [ + { + "properties": { + "finished_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "importer": { + "type": "string" + }, + "source_file": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "status": { + "type": "string" + } + }, + "required": [ + "importer", + "status" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null + }, + "last_successful_import": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observations": { + "description": "Number of daily values the result is computed from.", + "type": "integer" + }, + "reasons": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "type": "string" + } + }, + "required": [ + "status", + "reasons", + "freshness", + "coverage", + "completeness", + "gaps", + "observations" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Whether the data behind this baseline is complete, current and trustworthy." +}
- Added
get_data_status - Added
get_import_status - Changed
get_metric_history1 field changed- added
Output schema / properties / data_healthAdded value: +{ + "anyOf": [ + { + "description": "Data-quality state behind one result (not a medical or statistical confidence score). status is one of\nVALID, VALID_WITH_GAPS, INSUFFICIENT_DATA, STALE, IMPORT_INCOMPLETE; reasons lists every condition that\napplies. See data_health.compose_data_health for how it is decided.", + "properties": { + "completeness": { + "properties": { + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + } + }, + "required": [ + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days" + ], + "type": "object" + }, + "coverage": { + "properties": { + "end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + }, + "start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "requested_start", + "requested_end" + ], + "type": "object" + }, + "freshness": { + "properties": { + "age_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Days from the latest observation to the end of the requested window." + }, + "dataset_days_behind": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Days from the dataset's latest data (any metric) to today." + }, + "latest_data": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "type": "object" + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "last_import": { + "anyOf": [ + { + "properties": { + "finished_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "importer": { + "type": "string" + }, + "source_file": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "status": { + "type": "string" + } + }, + "required": [ + "importer", + "status" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null + }, + "last_successful_import": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observations": { + "description": "Number of daily values the result is computed from.", + "type": "integer" + }, + "reasons": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "type": "string" + } + }, + "required": [ + "status", + "reasons", + "freshness", + "coverage", + "completeness", + "gaps", + "observations" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Whether this history is complete, current and trustworthy; see DataHealth." +}
- Changed
log_measurement2 fields changed- added
Output schema / properties / measurement / properties / value / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Output schema / properties / measurement / properties / value / typeRemoved value: -"number"
- Changed
read_measurements2 fields changed- added
Output schema / properties / measurements / items / properties / value / anyOfAdded value: +[ + { + "type": "number" + }, + { + "type": "null" + } +] - removed
Output schema / properties / measurements / items / properties / value / typeRemoved value: -"number"
6 tool updates
v1.0.28- Changed
calculate_metric_trend3 fields changed- removed
Output schema / properties / claim_decisionRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to claim.decision. Use claim.decision instead.", - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" -} - removed
Output schema / properties / evidence_profileRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to claim.profile. Use claim.decision instead.", - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" -} - changed
Output schema / requiredPrevious value: -[ - "metric", - "range", - "trend", - "claim", - "evidence", - "evidence_profile", - "claim_decision" -]New value: +[ + "metric", + "range", + "trend", + "claim", + "evidence" +]
- Changed
compare_metric_periods3 fields changed- removed
Output schema / properties / claim_decisionRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to claim.decision. Use claim.decision instead.", - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" -} - removed
Output schema / properties / evidence_profileRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to claim.profile. Use claim.decision instead.", - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" -} - changed
Output schema / requiredPrevious value: -[ - "metric", - "period_a", - "period_b", - "period_a_stats", - "period_b_stats", - "claim", - "period_a_evidence", - "period_b_evidence", - "evidence_profile", - "claim_decision" -]New value: +[ + "metric", + "period_a", + "period_b", + "period_a_stats", + "period_b_stats", + "claim", + "period_a_evidence", + "period_b_evidence" +]
- Changed
detect_metric_anomalies3 fields changed- removed
Output schema / properties / claim_decisionRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to claim.decision. Use claim.decision instead.", - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" -} - removed
Output schema / properties / evidence_profileRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to claim.profile. Use claim.decision instead.", - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" -} - changed
Output schema / requiredPrevious value: -[ - "metric", - "range", - "threshold", - "anomalies", - "claim", - "evidence", - "evidence_profile", - "claim_decision" -]New value: +[ + "metric", + "range", + "threshold", + "anomalies", + "claim", + "evidence" +]
- Changed
explain_metric_change8 fields changed- removed
Output schema / properties / claim_decisionRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to headline_claim.decision. Use headline_claim.decision instead.", - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" -} - removed
Output schema / properties / correlated_metrics / items / properties / claim_decisionRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to claim.decision. Use claim.decision instead.", - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" -} - removed
Output schema / properties / correlated_metrics / items / properties / evidence_profileRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to claim.profile. Use claim.decision instead.", - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" -} - changed
Output schema / properties / correlated_metrics / items / requiredPrevious value: -[ - "metric_a", - "metric_b", - "lag_days", - "n", - "claim", - "evidence_a", - "evidence_b", - "evidence_profile", - "claim_decision" -]New value: +[ + "metric_a", + "metric_b", + "lag_days", + "n", + "claim", + "evidence_a", + "evidence_b" +] - removed
Output schema / properties / evidence_profileRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to headline_claim.profile. Use headline_claim.decision instead.", - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" -} - removed
Output schema / properties / trend_claim_decisionRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to trend_claim.decision. Use trend_claim.decision instead.", - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" -} - removed
Output schema / properties / trend_evidence_profileRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to trend_claim.profile. Use trend_claim.decision instead.", - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" -} - changed
Output schema / requiredPrevious value: -[ - "metric", - "date", - "baseline_range", - "baseline", - "is_anomaly", - "trend", - "correlated_metrics", - "narrative_facts", - "baseline_claim", - "headline_claim", - "trend_claim", - "evidence_profile", - "claim_decision", - "trend_evidence_profile", - "trend_claim_decision", - "overall_decision" -]New value: +[ + "metric", + "date", + "baseline_range", + "baseline", + "is_anomaly", + "trend", + "correlated_metrics", + "narrative_facts", + "baseline_claim", + "headline_claim", + "trend_claim", + "overall_decision" +]
- Changed
find_metric_correlation3 fields changed- removed
Output schema / properties / claim_decisionRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to claim.decision. Use claim.decision instead.", - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" -} - removed
Output schema / properties / evidence_profileRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to claim.profile. Use claim.decision instead.", - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" -} - changed
Output schema / requiredPrevious value: -[ - "metric_a", - "metric_b", - "lag_days", - "n", - "claim", - "evidence_a", - "evidence_b", - "evidence_profile", - "claim_decision" -]New value: +[ + "metric_a", + "metric_b", + "lag_days", + "n", + "claim", + "evidence_a", + "evidence_b" +]
- Changed
get_recent_changes3 fields changed- removed
Output schema / properties / changes / items / properties / claim_decisionRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to claim.decision. Use claim.decision instead.", - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" -} - removed
Output schema / properties / changes / items / properties / evidence_profileRemoved value: -{ - "deprecated": true, - "description": "DEPRECATED: identical to claim.profile. Use claim.decision instead.", - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" -} - changed
Output schema / properties / changes / items / requiredPrevious value: -[ - "metric", - "kind", - "detail", - "claim", - "evidence", - "evidence_profile", - "claim_decision" -]New value: +[ + "metric", + "kind", + "detail", + "claim", + "evidence" +]
2 tool updates
v1.0.27- Changed
explain_metric_change2 fields changed- added
Output schema / properties / baseline_claimAdded value: +{ + "description": "Evidence and decision for the 90-day baseline statistics reported in \"baseline\" (and quoted in narrative_facts). Read baseline_claim.decision before stating what is typical for this metric; it is one of the components overall_decision is the weakest of.", + "properties": { + "decision": { + "description": "How strongly this claim may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it.", + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + "evidence": { + "description": "Descriptive data coverage behind this claim.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + "profile": { + "description": "Per-dimension evidence quality behind this claim (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate.", + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + } + }, + "required": [ + "evidence", + "profile", + "decision" + ], + "type": "object" +} - changed
Output schema / requiredPrevious value: -[ - "metric", - "date", - "baseline_range", - "baseline", - "is_anomaly", - "trend", - "correlated_metrics", - "narrative_facts", - "headline_claim", - "trend_claim", - "evidence_profile", - "claim_decision", - "trend_evidence_profile", - "trend_claim_decision", - "overall_decision" -]New value: +[ + "metric", + "date", + "baseline_range", + "baseline", + "is_anomaly", + "trend", + "correlated_metrics", + "narrative_facts", + "baseline_claim", + "headline_claim", + "trend_claim", + "evidence_profile", + "claim_decision", + "trend_evidence_profile", + "trend_claim_decision", + "overall_decision" +]
- Changed
get_recent_changes8 fields changed- added
Output schema / properties / changes / items / properties / claimAdded value: +{ + "description": "Evidence and decision for this change note's claim; read claim.decision before reporting it.", + "properties": { + "decision": { + "description": "How strongly this claim may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it.", + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + "evidence": { + "description": "Descriptive data coverage behind this claim.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + "profile": { + "description": "Per-dimension evidence quality behind this claim (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate.", + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + } + }, + "required": [ + "evidence", + "profile", + "decision" + ], + "type": "object" +} - added
Output schema / properties / changes / items / properties / claim_decision / deprecatedAdded value: +true - changed
Output schema / properties / changes / items / properties / claim_decision / descriptionPrevious value: -"How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it."New value: +"DEPRECATED: identical to claim.decision. Use claim.decision instead." - added
Output schema / properties / changes / items / properties / evidence / deprecatedAdded value: +true - changed
Output schema / properties / changes / items / properties / evidence / descriptionPrevious value: -"Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed."New value: +"DEPRECATED: identical to claim.evidence. Use claim.decision, not evidence.confidence." - added
Output schema / properties / changes / items / properties / evidence_profile / deprecatedAdded value: +true - changed
Output schema / properties / changes / items / properties / evidence_profile / descriptionPrevious value: -"Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate."New value: +"DEPRECATED: identical to claim.profile. Use claim.decision instead." - changed
Output schema / properties / changes / items / requiredPrevious value: -[ - "evidence_profile", - "claim_decision", - "metric", - "kind", - "detail", - "evidence" -]New value: +[ + "metric", + "kind", + "detail", + "claim", + "evidence", + "evidence_profile", + "claim_decision" +]
5 tool updates
v1.0.26- Changed
calculate_metric_trend8 fields changed- added
Output schema / properties / claimAdded value: +{ + "description": "Evidence and decision for the trend claim; read claim.decision before reporting it.", + "properties": { + "decision": { + "description": "How strongly this claim may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it.", + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + "evidence": { + "description": "Descriptive data coverage behind this claim.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + "profile": { + "description": "Per-dimension evidence quality behind this claim (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate.", + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + } + }, + "required": [ + "evidence", + "profile", + "decision" + ], + "type": "object" +} - added
Output schema / properties / claim_decision / deprecatedAdded value: +true - changed
Output schema / properties / claim_decision / descriptionPrevious value: -"How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it."New value: +"DEPRECATED: identical to claim.decision. Use claim.decision instead." - added
Output schema / properties / evidence / deprecatedAdded value: +true - changed
Output schema / properties / evidence / descriptionPrevious value: -"Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed."New value: +"DEPRECATED: identical to claim.evidence. Use claim.decision, not evidence.confidence." - added
Output schema / properties / evidence_profile / deprecatedAdded value: +true - changed
Output schema / properties / evidence_profile / descriptionPrevious value: -"Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate."New value: +"DEPRECATED: identical to claim.profile. Use claim.decision instead." - changed
Output schema / requiredPrevious value: -[ - "evidence_profile", - "claim_decision", - "metric", - "range", - "trend", - "evidence" -]New value: +[ + "metric", + "range", + "trend", + "claim", + "evidence", + "evidence_profile", + "claim_decision" +]
- Changed
compare_metric_periods10 fields changed- added
Output schema / properties / claimAdded value: +{ + "description": "Evidence and decision for the period comparison claim; read claim.decision before reporting it.", + "properties": { + "decision": { + "description": "How strongly this claim may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it.", + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + "evidence_a": { + "description": "Descriptive data coverage behind the first source.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + "evidence_b": { + "description": "Descriptive data coverage behind the second source.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + "profile": { + "description": "Per-dimension evidence quality behind this claim (sample, temporal, missingness, ...), assessed jointly across both sources where relevant. Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate.", + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + } + }, + "required": [ + "evidence_a", + "evidence_b", + "profile", + "decision" + ], + "type": "object" +} - added
Output schema / properties / claim_decision / deprecatedAdded value: +true - changed
Output schema / properties / claim_decision / descriptionPrevious value: -"How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it."New value: +"DEPRECATED: identical to claim.decision. Use claim.decision instead." - added
Output schema / properties / evidence_profile / deprecatedAdded value: +true - changed
Output schema / properties / evidence_profile / descriptionPrevious value: -"Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate."New value: +"DEPRECATED: identical to claim.profile. Use claim.decision instead." - added
Output schema / properties / period_a_evidence / deprecatedAdded value: +true - changed
Output schema / properties / period_a_evidence / descriptionPrevious value: -"Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed."New value: +"DEPRECATED: identical to claim.evidence_a. Use claim.decision, not a standalone confidence field." - added
Output schema / properties / period_b_evidence / deprecatedAdded value: +true - changed
Output schema / properties / period_b_evidence / descriptionPrevious value: -"Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed."New value: +"DEPRECATED: identical to claim.evidence_b. Use claim.decision, not a standalone confidence field." - changed
Output schema / requiredPrevious value: -[ - "evidence_profile", - "claim_decision", - "metric", - "period_a", - "period_b", - "period_a_stats", - "period_b_stats", - "period_a_evidence", - "period_b_evidence" -]New value: +[ + "metric", + "period_a", + "period_b", + "period_a_stats", + "period_b_stats", + "claim", + "period_a_evidence", + "period_b_evidence", + "evidence_profile", + "claim_decision" +]
- Changed
detect_metric_anomalies8 fields changed- added
Output schema / properties / claimAdded value: +{ + "description": "Evidence and decision for the anomaly claim; read claim.decision before reporting it.", + "properties": { + "decision": { + "description": "How strongly this claim may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it.", + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + "evidence": { + "description": "Descriptive data coverage behind this claim.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + "profile": { + "description": "Per-dimension evidence quality behind this claim (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate.", + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + } + }, + "required": [ + "evidence", + "profile", + "decision" + ], + "type": "object" +} - added
Output schema / properties / claim_decision / deprecatedAdded value: +true - changed
Output schema / properties / claim_decision / descriptionPrevious value: -"How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it."New value: +"DEPRECATED: identical to claim.decision. Use claim.decision instead." - added
Output schema / properties / evidence / deprecatedAdded value: +true - changed
Output schema / properties / evidence / descriptionPrevious value: -"Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed."New value: +"DEPRECATED: identical to claim.evidence. Use claim.decision, not evidence.confidence." - added
Output schema / properties / evidence_profile / deprecatedAdded value: +true - changed
Output schema / properties / evidence_profile / descriptionPrevious value: -"Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate."New value: +"DEPRECATED: identical to claim.profile. Use claim.decision instead." - changed
Output schema / requiredPrevious value: -[ - "evidence_profile", - "claim_decision", - "metric", - "range", - "threshold", - "anomalies", - "evidence" -]New value: +[ + "metric", + "range", + "threshold", + "anomalies", + "claim", + "evidence", + "evidence_profile", + "claim_decision" +]
- Changed
explain_metric_change35 fields changed- removed
Output schema / properties / baseline_evidenceRemoved value: -{ - "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", - "properties": { - "confidence": { - "type": "string" - }, - "coverage_ratio": { - "type": "number" - }, - "expected_days": { - "type": "integer" - }, - "freshness_days": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "gaps": { - "items": { - "properties": { - "days": { - "type": "integer" - }, - "end": { - "type": "string" - }, - "start": { - "type": "string" - } - }, - "required": [ - "start", - "end", - "days" - ], - "type": "object" - }, - "type": "array" - }, - "measurement_count": { - "type": "integer" - }, - "missing_days": { - "type": "integer" - }, - "observed_days": { - "type": "integer" - }, - "observed_end": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "observed_start": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "recent_gap_days": { - "type": "integer" - }, - "requested_end": { - "type": "string" - }, - "requested_start": { - "type": "string" - } - }, - "required": [ - "requested_start", - "requested_end", - "expected_days", - "observed_days", - "coverage_ratio", - "missing_days", - "measurement_count", - "gaps", - "recent_gap_days", - "confidence" - ], - "type": "object" -} - added
Output schema / properties / claim_decision / deprecatedAdded value: +true - changed
Output schema / properties / claim_decision / descriptionPrevious value: -"How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it."New value: +"DEPRECATED: identical to headline_claim.decision. Use headline_claim.decision instead." - added
Output schema / properties / correlated_metrics / items / properties / claimAdded value: +{ + "description": "Evidence and decision for the correlation claim; read claim.decision before reporting it.", + "properties": { + "decision": { + "description": "How strongly this claim may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it.", + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + "evidence_a": { + "description": "Descriptive data coverage behind the first source.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + "evidence_b": { + "description": "Descriptive data coverage behind the second source.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + "profile": { + "description": "Per-dimension evidence quality behind this claim (sample, temporal, missingness, ...), assessed jointly across both sources where relevant. Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate.", + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + } + }, + "required": [ + "evidence_a", + "evidence_b", + "profile", + "decision" + ], + "type": "object" +} - added
Output schema / properties / correlated_metrics / items / properties / claim_decision / deprecatedAdded value: +true - changed
Output schema / properties / correlated_metrics / items / properties / claim_decision / descriptionPrevious value: -"How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it."New value: +"DEPRECATED: identical to claim.decision. Use claim.decision instead." - removed
Output schema / properties / correlated_metrics / items / properties / evidence_a / anyOfRemoved value: -[ - { - "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", - "properties": { - "confidence": { - "type": "string" - }, - "coverage_ratio": { - "type": "number" - }, - "expected_days": { - "type": "integer" - }, - "freshness_days": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "gaps": { - "items": { - "properties": { - "days": { - "type": "integer" - }, - "end": { - "type": "string" - }, - "start": { - "type": "string" - } - }, - "required": [ - "start", - "end", - "days" - ], - "type": "object" - }, - "type": "array" - }, - "measurement_count": { - "type": "integer" - }, - "missing_days": { - "type": "integer" - }, - "observed_days": { - "type": "integer" - }, - "observed_end": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "observed_start": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "recent_gap_days": { - "type": "integer" - }, - "requested_end": { - "type": "string" - }, - "requested_start": { - "type": "string" - } - }, - "required": [ - "requested_start", - "requested_end", - "expected_days", - "observed_days", - "coverage_ratio", - "missing_days", - "measurement_count", - "gaps", - "recent_gap_days", - "confidence" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / correlated_metrics / items / properties / evidence_a / defaultRemoved value: -null - added
Output schema / properties / correlated_metrics / items / properties / evidence_a / deprecatedAdded value: +true - added
Output schema / properties / correlated_metrics / items / properties / evidence_a / descriptionAdded value: +"DEPRECATED: identical to claim.evidence_a. Use claim.decision, not a standalone confidence field." - added
Output schema / properties / correlated_metrics / items / properties / evidence_a / propertiesAdded value: +{ + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } +} - added
Output schema / properties / correlated_metrics / items / properties / evidence_a / requiredAdded value: +[ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" +] - added
Output schema / properties / correlated_metrics / items / properties / evidence_a / typeAdded value: +"object" - removed
Output schema / properties / correlated_metrics / items / properties / evidence_b / anyOfRemoved value: -[ - { - "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", - "properties": { - "confidence": { - "type": "string" - }, - "coverage_ratio": { - "type": "number" - }, - "expected_days": { - "type": "integer" - }, - "freshness_days": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "gaps": { - "items": { - "properties": { - "days": { - "type": "integer" - }, - "end": { - "type": "string" - }, - "start": { - "type": "string" - } - }, - "required": [ - "start", - "end", - "days" - ], - "type": "object" - }, - "type": "array" - }, - "measurement_count": { - "type": "integer" - }, - "missing_days": { - "type": "integer" - }, - "observed_days": { - "type": "integer" - }, - "observed_end": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "observed_start": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "recent_gap_days": { - "type": "integer" - }, - "requested_end": { - "type": "string" - }, - "requested_start": { - "type": "string" - } - }, - "required": [ - "requested_start", - "requested_end", - "expected_days", - "observed_days", - "coverage_ratio", - "missing_days", - "measurement_count", - "gaps", - "recent_gap_days", - "confidence" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / correlated_metrics / items / properties / evidence_b / defaultRemoved value: -null - added
Output schema / properties / correlated_metrics / items / properties / evidence_b / deprecatedAdded value: +true - added
Output schema / properties / correlated_metrics / items / properties / evidence_b / descriptionAdded value: +"DEPRECATED: identical to claim.evidence_b. Use claim.decision, not a standalone confidence field." - added
Output schema / properties / correlated_metrics / items / properties / evidence_b / propertiesAdded value: +{ + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } +} - added
Output schema / properties / correlated_metrics / items / properties / evidence_b / requiredAdded value: +[ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" +] - added
Output schema / properties / correlated_metrics / items / properties / evidence_b / typeAdded value: +"object" - added
Output schema / properties / correlated_metrics / items / properties / evidence_profile / deprecatedAdded value: +true - changed
Output schema / properties / correlated_metrics / items / properties / evidence_profile / descriptionPrevious value: -"Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate."New value: +"DEPRECATED: identical to claim.profile. Use claim.decision instead." - removed
Output schema / properties / correlated_metrics / items / properties / sample_confidenceRemoved value: -{ - "type": "string" -} - changed
Output schema / properties / correlated_metrics / items / requiredPrevious value: -[ - "evidence_profile", - "claim_decision", - "metric_a", - "metric_b", - "lag_days", - "n", - "sample_confidence" -]New value: +[ + "metric_a", + "metric_b", + "lag_days", + "n", + "claim", + "evidence_a", + "evidence_b", + "evidence_profile", + "claim_decision" +] - added
Output schema / properties / evidence_profile / deprecatedAdded value: +true - changed
Output schema / properties / evidence_profile / descriptionPrevious value: -"Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate."New value: +"DEPRECATED: identical to headline_claim.profile. Use headline_claim.decision instead." - added
Output schema / properties / headline_claimAdded value: +{ + "description": "Evidence and decision for the headline claim: this day's value against its 90-day baseline. Read headline_claim.decision before reporting it.", + "properties": { + "decision": { + "description": "How strongly this claim may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it.", + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + "evidence": { + "description": "Descriptive data coverage behind this claim.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + "profile": { + "description": "Per-dimension evidence quality behind this claim (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate.", + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + } + }, + "required": [ + "evidence", + "profile", + "decision" + ], + "type": "object" +} - added
Output schema / properties / overall_decisionAdded value: +{ + "description": "The single decision governing this whole result: weakest-of-N over the headline claim (headline_claim.decision), the trend (trend_claim.decision), and every surfaced correlation's own decision. If any component is insufficient/suggestive, the composite is too โ report overall_decision.tier and must_state rather than treating the headline claim as though the trend and correlations couldn't drag it down.", + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" +} - added
Output schema / properties / trend_claimAdded value: +{ + "description": "Evidence and decision for the 30-day trend leading into this day, assessed separately from the headline claim. Read trend_claim.decision before reporting it.", + "properties": { + "decision": { + "description": "How strongly this claim may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it.", + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + "evidence": { + "description": "Descriptive data coverage behind this claim.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + "profile": { + "description": "Per-dimension evidence quality behind this claim (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate.", + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + } + }, + "required": [ + "evidence", + "profile", + "decision" + ], + "type": "object" +} - added
Output schema / properties / trend_claim_decision / deprecatedAdded value: +true - added
Output schema / properties / trend_claim_decision / descriptionAdded value: +"DEPRECATED: identical to trend_claim.decision. Use trend_claim.decision instead." - removed
Output schema / properties / trend_evidenceRemoved value: -{ - "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", - "properties": { - "confidence": { - "type": "string" - }, - "coverage_ratio": { - "type": "number" - }, - "expected_days": { - "type": "integer" - }, - "freshness_days": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "gaps": { - "items": { - "properties": { - "days": { - "type": "integer" - }, - "end": { - "type": "string" - }, - "start": { - "type": "string" - } - }, - "required": [ - "start", - "end", - "days" - ], - "type": "object" - }, - "type": "array" - }, - "measurement_count": { - "type": "integer" - }, - "missing_days": { - "type": "integer" - }, - "observed_days": { - "type": "integer" - }, - "observed_end": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "observed_start": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "recent_gap_days": { - "type": "integer" - }, - "requested_end": { - "type": "string" - }, - "requested_start": { - "type": "string" - } - }, - "required": [ - "requested_start", - "requested_end", - "expected_days", - "observed_days", - "coverage_ratio", - "missing_days", - "measurement_count", - "gaps", - "recent_gap_days", - "confidence" - ], - "type": "object" -} - added
Output schema / properties / trend_evidence_profile / deprecatedAdded value: +true - added
Output schema / properties / trend_evidence_profile / descriptionAdded value: +"DEPRECATED: identical to trend_claim.profile. Use trend_claim.decision instead." - changed
Output schema / requiredPrevious value: -[ - "evidence_profile", - "claim_decision", - "metric", - "date", - "baseline_range", - "baseline", - "is_anomaly", - "trend", - "correlated_metrics", - "narrative_facts", - "baseline_evidence", - "trend_evidence", - "trend_evidence_profile", - "trend_claim_decision" -]New value: +[ + "metric", + "date", + "baseline_range", + "baseline", + "is_anomaly", + "trend", + "correlated_metrics", + "narrative_facts", + "headline_claim", + "trend_claim", + "evidence_profile", + "claim_decision", + "trend_evidence_profile", + "trend_claim_decision", + "overall_decision" +]
- Changed
find_metric_correlation21 fields changed- added
Output schema / properties / claimAdded value: +{ + "description": "Evidence and decision for the correlation claim; read claim.decision before reporting it.", + "properties": { + "decision": { + "description": "How strongly this claim may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it.", + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + "evidence_a": { + "description": "Descriptive data coverage behind the first source.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + "evidence_b": { + "description": "Descriptive data coverage behind the second source.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + "profile": { + "description": "Per-dimension evidence quality behind this claim (sample, temporal, missingness, ...), assessed jointly across both sources where relevant. Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate.", + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + } + }, + "required": [ + "evidence_a", + "evidence_b", + "profile", + "decision" + ], + "type": "object" +} - added
Output schema / properties / claim_decision / deprecatedAdded value: +true - changed
Output schema / properties / claim_decision / descriptionPrevious value: -"How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it."New value: +"DEPRECATED: identical to claim.decision. Use claim.decision instead." - removed
Output schema / properties / evidence_a / anyOfRemoved value: -[ - { - "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", - "properties": { - "confidence": { - "type": "string" - }, - "coverage_ratio": { - "type": "number" - }, - "expected_days": { - "type": "integer" - }, - "freshness_days": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "gaps": { - "items": { - "properties": { - "days": { - "type": "integer" - }, - "end": { - "type": "string" - }, - "start": { - "type": "string" - } - }, - "required": [ - "start", - "end", - "days" - ], - "type": "object" - }, - "type": "array" - }, - "measurement_count": { - "type": "integer" - }, - "missing_days": { - "type": "integer" - }, - "observed_days": { - "type": "integer" - }, - "observed_end": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "observed_start": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "recent_gap_days": { - "type": "integer" - }, - "requested_end": { - "type": "string" - }, - "requested_start": { - "type": "string" - } - }, - "required": [ - "requested_start", - "requested_end", - "expected_days", - "observed_days", - "coverage_ratio", - "missing_days", - "measurement_count", - "gaps", - "recent_gap_days", - "confidence" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / evidence_a / defaultRemoved value: -null - added
Output schema / properties / evidence_a / deprecatedAdded value: +true - added
Output schema / properties / evidence_a / descriptionAdded value: +"DEPRECATED: identical to claim.evidence_a. Use claim.decision, not a standalone confidence field." - added
Output schema / properties / evidence_a / propertiesAdded value: +{ + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } +} - added
Output schema / properties / evidence_a / requiredAdded value: +[ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" +] - added
Output schema / properties / evidence_a / typeAdded value: +"object" - removed
Output schema / properties / evidence_b / anyOfRemoved value: -[ - { - "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", - "properties": { - "confidence": { - "type": "string" - }, - "coverage_ratio": { - "type": "number" - }, - "expected_days": { - "type": "integer" - }, - "freshness_days": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "gaps": { - "items": { - "properties": { - "days": { - "type": "integer" - }, - "end": { - "type": "string" - }, - "start": { - "type": "string" - } - }, - "required": [ - "start", - "end", - "days" - ], - "type": "object" - }, - "type": "array" - }, - "measurement_count": { - "type": "integer" - }, - "missing_days": { - "type": "integer" - }, - "observed_days": { - "type": "integer" - }, - "observed_end": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "observed_start": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "recent_gap_days": { - "type": "integer" - }, - "requested_end": { - "type": "string" - }, - "requested_start": { - "type": "string" - } - }, - "required": [ - "requested_start", - "requested_end", - "expected_days", - "observed_days", - "coverage_ratio", - "missing_days", - "measurement_count", - "gaps", - "recent_gap_days", - "confidence" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / evidence_b / defaultRemoved value: -null - added
Output schema / properties / evidence_b / deprecatedAdded value: +true - added
Output schema / properties / evidence_b / descriptionAdded value: +"DEPRECATED: identical to claim.evidence_b. Use claim.decision, not a standalone confidence field." - added
Output schema / properties / evidence_b / propertiesAdded value: +{ + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } +} - added
Output schema / properties / evidence_b / requiredAdded value: +[ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" +] - added
Output schema / properties / evidence_b / typeAdded value: +"object" - added
Output schema / properties / evidence_profile / deprecatedAdded value: +true - changed
Output schema / properties / evidence_profile / descriptionPrevious value: -"Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate."New value: +"DEPRECATED: identical to claim.profile. Use claim.decision instead." - removed
Output schema / properties / sample_confidenceRemoved value: -{ - "type": "string" -} - changed
Output schema / requiredPrevious value: -[ - "evidence_profile", - "claim_decision", - "metric_a", - "metric_b", - "lag_days", - "n", - "sample_confidence" -]New value: +[ + "metric_a", + "metric_b", + "lag_days", + "n", + "claim", + "evidence_a", + "evidence_b", + "evidence_profile", + "claim_decision" +]
1 tool update
v1.0.24- Changed
get_baseline4 fields changed- added
Output schema / properties / claimAdded value: +{ + "description": "Evidence and decision for the \"what's normal\" claim; read claim.decision before reporting it.", + "properties": { + "decision": { + "description": "How strongly this claim may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it.", + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + "evidence": { + "description": "Descriptive data coverage behind this claim.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + "profile": { + "description": "Per-dimension evidence quality behind this claim (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate.", + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + } + }, + "required": [ + "evidence", + "profile", + "decision" + ], + "type": "object" +} - added
Output schema / properties / evidence / deprecatedAdded value: +true - changed
Output schema / properties / evidence / descriptionPrevious value: -"Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed."New value: +"DEPRECATED: identical to claim.evidence. Use claim.decision, not evidence.confidence." - changed
Output schema / requiredPrevious value: -[ - "metric", - "range", - "baseline", - "evidence" -]New value: +[ + "metric", + "range", + "baseline", + "claim", + "evidence" +]
7 tool updates
v1.0.23- Changed
aggregate_measurements1 field changed- changed
Input schema / properties / source_priority / descriptionPrevious value: -"Ordered list of source names, e.g. [\"Apple\nWatch\", \"Garmin\"]. For any metric with more than one source\nthat day, the first name in this list that's actually present\nwins in \"aggregated\" and the other source's readings for that\nmetric are dropped from that preview. Omit to fall back to\nwhichever source was imported most recently. Never affects\n\"row\" โ see above."New value: +"Ordered list of source names, e.g. [\"Apple\nWatch\", \"Garmin\"]. For any metric with more than one source\nthat day, the first name in this list that's actually present\nwins in \"aggregated\" and the other source's readings for that\nmetric are dropped from that preview. Omit to use the stored\npriority list and the same fallback the stored projection\nuses. Never affects \"row\" โ see above."
- Changed
calculate_metric_trend11 fields changed- removed
Output schema / properties / claim_decision / anyOfRemoved value: -[ - { - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / claim_decision / defaultRemoved value: -null - added
Output schema / properties / claim_decision / propertiesAdded value: +{ + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } +} - added
Output schema / properties / claim_decision / requiredAdded value: +[ + "tier", + "permitted_phrasing_class", + "must_state", + "template" +] - added
Output schema / properties / claim_decision / typeAdded value: +"object" - removed
Output schema / properties / evidence_profile / anyOfRemoved value: -[ - { - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / evidence_profile / defaultRemoved value: -null - added
Output schema / properties / evidence_profile / propertiesAdded value: +{ + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } +} - added
Output schema / properties / evidence_profile / requiredAdded value: +[ + "metric", + "analysis", + "dimensions" +] - added
Output schema / properties / evidence_profile / typeAdded value: +"object" - changed
Output schema / requiredPrevious value: -[ - "metric", - "range", - "trend", - "evidence" -]New value: +[ + "evidence_profile", + "claim_decision", + "metric", + "range", + "trend", + "evidence" +]
- Changed
compare_metric_periods11 fields changed- removed
Output schema / properties / claim_decision / anyOfRemoved value: -[ - { - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / claim_decision / defaultRemoved value: -null - added
Output schema / properties / claim_decision / propertiesAdded value: +{ + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } +} - added
Output schema / properties / claim_decision / requiredAdded value: +[ + "tier", + "permitted_phrasing_class", + "must_state", + "template" +] - added
Output schema / properties / claim_decision / typeAdded value: +"object" - removed
Output schema / properties / evidence_profile / anyOfRemoved value: -[ - { - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / evidence_profile / defaultRemoved value: -null - added
Output schema / properties / evidence_profile / propertiesAdded value: +{ + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } +} - added
Output schema / properties / evidence_profile / requiredAdded value: +[ + "metric", + "analysis", + "dimensions" +] - added
Output schema / properties / evidence_profile / typeAdded value: +"object" - changed
Output schema / requiredPrevious value: -[ - "metric", - "period_a", - "period_b", - "period_a_stats", - "period_b_stats", - "period_a_evidence", - "period_b_evidence" -]New value: +[ + "evidence_profile", + "claim_decision", + "metric", + "period_a", + "period_b", + "period_a_stats", + "period_b_stats", + "period_a_evidence", + "period_b_evidence" +]
- Changed
detect_metric_anomalies11 fields changed- removed
Output schema / properties / claim_decision / anyOfRemoved value: -[ - { - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / claim_decision / defaultRemoved value: -null - added
Output schema / properties / claim_decision / propertiesAdded value: +{ + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } +} - added
Output schema / properties / claim_decision / requiredAdded value: +[ + "tier", + "permitted_phrasing_class", + "must_state", + "template" +] - added
Output schema / properties / claim_decision / typeAdded value: +"object" - removed
Output schema / properties / evidence_profile / anyOfRemoved value: -[ - { - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / evidence_profile / defaultRemoved value: -null - added
Output schema / properties / evidence_profile / propertiesAdded value: +{ + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } +} - added
Output schema / properties / evidence_profile / requiredAdded value: +[ + "metric", + "analysis", + "dimensions" +] - added
Output schema / properties / evidence_profile / typeAdded value: +"object" - changed
Output schema / requiredPrevious value: -[ - "metric", - "range", - "threshold", - "anomalies", - "evidence" -]New value: +[ + "evidence_profile", + "claim_decision", + "metric", + "range", + "threshold", + "anomalies", + "evidence" +]
- Changed
explain_metric_change32 fields changed- removed
Output schema / properties / claim_decision / anyOfRemoved value: -[ - { - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / claim_decision / defaultRemoved value: -null - added
Output schema / properties / claim_decision / propertiesAdded value: +{ + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } +} - added
Output schema / properties / claim_decision / requiredAdded value: +[ + "tier", + "permitted_phrasing_class", + "must_state", + "template" +] - added
Output schema / properties / claim_decision / typeAdded value: +"object" - removed
Output schema / properties / correlated_metrics / items / properties / claim_decision / anyOfRemoved value: -[ - { - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / correlated_metrics / items / properties / claim_decision / defaultRemoved value: -null - added
Output schema / properties / correlated_metrics / items / properties / claim_decision / propertiesAdded value: +{ + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } +} - added
Output schema / properties / correlated_metrics / items / properties / claim_decision / requiredAdded value: +[ + "tier", + "permitted_phrasing_class", + "must_state", + "template" +] - added
Output schema / properties / correlated_metrics / items / properties / claim_decision / typeAdded value: +"object" - removed
Output schema / properties / correlated_metrics / items / properties / evidence_profile / anyOfRemoved value: -[ - { - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / correlated_metrics / items / properties / evidence_profile / defaultRemoved value: -null - added
Output schema / properties / correlated_metrics / items / properties / evidence_profile / propertiesAdded value: +{ + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } +} - added
Output schema / properties / correlated_metrics / items / properties / evidence_profile / requiredAdded value: +[ + "metric", + "analysis", + "dimensions" +] - added
Output schema / properties / correlated_metrics / items / properties / evidence_profile / typeAdded value: +"object" - changed
Output schema / properties / correlated_metrics / items / requiredPrevious value: -[ - "metric_a", - "metric_b", - "lag_days", - "n", - "sample_confidence" -]New value: +[ + "evidence_profile", + "claim_decision", + "metric_a", + "metric_b", + "lag_days", + "n", + "sample_confidence" +] - removed
Output schema / properties / evidence_profile / anyOfRemoved value: -[ - { - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / evidence_profile / defaultRemoved value: -null - added
Output schema / properties / evidence_profile / propertiesAdded value: +{ + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } +} - added
Output schema / properties / evidence_profile / requiredAdded value: +[ + "metric", + "analysis", + "dimensions" +] - added
Output schema / properties / evidence_profile / typeAdded value: +"object" - removed
Output schema / properties / trend_claim_decision / anyOfRemoved value: -[ - { - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / trend_claim_decision / defaultRemoved value: -null - added
Output schema / properties / trend_claim_decision / propertiesAdded value: +{ + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } +} - added
Output schema / properties / trend_claim_decision / requiredAdded value: +[ + "tier", + "permitted_phrasing_class", + "must_state", + "template" +] - added
Output schema / properties / trend_claim_decision / typeAdded value: +"object" - removed
Output schema / properties / trend_evidence_profile / anyOfRemoved value: -[ - { - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / trend_evidence_profile / defaultRemoved value: -null - added
Output schema / properties / trend_evidence_profile / propertiesAdded value: +{ + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } +} - added
Output schema / properties / trend_evidence_profile / requiredAdded value: +[ + "metric", + "analysis", + "dimensions" +] - added
Output schema / properties / trend_evidence_profile / typeAdded value: +"object" - changed
Output schema / requiredPrevious value: -[ - "metric", - "date", - "baseline_range", - "baseline", - "is_anomaly", - "trend", - "correlated_metrics", - "narrative_facts", - "baseline_evidence", - "trend_evidence" -]New value: +[ + "evidence_profile", + "claim_decision", + "metric", + "date", + "baseline_range", + "baseline", + "is_anomaly", + "trend", + "correlated_metrics", + "narrative_facts", + "baseline_evidence", + "trend_evidence", + "trend_evidence_profile", + "trend_claim_decision" +]
- Changed
find_metric_correlation11 fields changed- removed
Output schema / properties / claim_decision / anyOfRemoved value: -[ - { - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / claim_decision / defaultRemoved value: -null - added
Output schema / properties / claim_decision / propertiesAdded value: +{ + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } +} - added
Output schema / properties / claim_decision / requiredAdded value: +[ + "tier", + "permitted_phrasing_class", + "must_state", + "template" +] - added
Output schema / properties / claim_decision / typeAdded value: +"object" - removed
Output schema / properties / evidence_profile / anyOfRemoved value: -[ - { - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / evidence_profile / defaultRemoved value: -null - added
Output schema / properties / evidence_profile / propertiesAdded value: +{ + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } +} - added
Output schema / properties / evidence_profile / requiredAdded value: +[ + "metric", + "analysis", + "dimensions" +] - added
Output schema / properties / evidence_profile / typeAdded value: +"object" - changed
Output schema / requiredPrevious value: -[ - "metric_a", - "metric_b", - "lag_days", - "n", - "sample_confidence" -]New value: +[ + "evidence_profile", + "claim_decision", + "metric_a", + "metric_b", + "lag_days", + "n", + "sample_confidence" +]
- Changed
get_recent_changes11 fields changed- removed
Output schema / properties / changes / items / properties / claim_decision / anyOfRemoved value: -[ - { - "properties": { - "must_state": { - "items": { - "type": "string" - }, - "type": "array" - }, - "permitted_phrasing_class": { - "type": "string" - }, - "template": { - "type": "string" - }, - "tier": { - "type": "string" - } - }, - "required": [ - "tier", - "permitted_phrasing_class", - "must_state", - "template" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / changes / items / properties / claim_decision / defaultRemoved value: -null - added
Output schema / properties / changes / items / properties / claim_decision / propertiesAdded value: +{ + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } +} - added
Output schema / properties / changes / items / properties / claim_decision / requiredAdded value: +[ + "tier", + "permitted_phrasing_class", + "must_state", + "template" +] - added
Output schema / properties / changes / items / properties / claim_decision / typeAdded value: +"object" - removed
Output schema / properties / changes / items / properties / evidence_profile / anyOfRemoved value: -[ - { - "properties": { - "analysis": { - "type": "string" - }, - "dimensions": { - "items": { - "properties": { - "can_block": { - "default": true, - "type": "boolean" - }, - "details": { - "additionalProperties": true, - "type": "object" - }, - "dimension": { - "enum": [ - "sample", - "temporal", - "robustness", - "missingness", - "practical", - "measurement_validity", - "provenance" - ], - "type": "string" - }, - "reason_codes": { - "items": { - "type": "string" - }, - "type": "array" - }, - "status": { - "enum": [ - "adequate", - "negligible", - "not_assessed", - "weak", - "concern", - "blocking" - ], - "type": "string" - } - }, - "required": [ - "dimension", - "status" - ], - "type": "object" - }, - "type": "array" - }, - "effect": { - "additionalProperties": true, - "type": "object" - }, - "metric": { - "type": "string" - } - }, - "required": [ - "metric", - "analysis", - "dimensions" - ], - "type": "object" - }, - { - "type": "null" - } -] - removed
Output schema / properties / changes / items / properties / evidence_profile / defaultRemoved value: -null - added
Output schema / properties / changes / items / properties / evidence_profile / propertiesAdded value: +{ + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } +} - added
Output schema / properties / changes / items / properties / evidence_profile / requiredAdded value: +[ + "metric", + "analysis", + "dimensions" +] - added
Output schema / properties / changes / items / properties / evidence_profile / typeAdded value: +"object" - changed
Output schema / properties / changes / items / requiredPrevious value: -[ - "metric", - "kind", - "detail", - "evidence" -]New value: +[ + "evidence_profile", + "claim_decision", + "metric", + "kind", + "detail", + "evidence" +]
6 tool updates
v1.0.20- Changed
calculate_metric_trend2 fields changed- added
Output schema / properties / claim_decisionAdded value: +{ + "anyOf": [ + { + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it." +} - added
Output schema / properties / evidence_profileAdded value: +{ + "anyOf": [ + { + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate." +}
- Changed
compare_metric_periods2 fields changed- added
Output schema / properties / claim_decisionAdded value: +{ + "anyOf": [ + { + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it." +} - added
Output schema / properties / evidence_profileAdded value: +{ + "anyOf": [ + { + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate." +}
- Changed
detect_metric_anomalies2 fields changed- added
Output schema / properties / claim_decisionAdded value: +{ + "anyOf": [ + { + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it." +} - added
Output schema / properties / evidence_profileAdded value: +{ + "anyOf": [ + { + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate." +}
- Changed
explain_metric_change6 fields changed- added
Output schema / properties / claim_decisionAdded value: +{ + "anyOf": [ + { + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it." +} - added
Output schema / properties / correlated_metrics / items / properties / claim_decisionAdded value: +{ + "anyOf": [ + { + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it." +} - added
Output schema / properties / correlated_metrics / items / properties / evidence_profileAdded value: +{ + "anyOf": [ + { + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate." +} - added
Output schema / properties / evidence_profileAdded value: +{ + "anyOf": [ + { + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate." +} - added
Output schema / properties / trend_claim_decisionAdded value: +{ + "anyOf": [ + { + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / properties / trend_evidence_profileAdded value: +{ + "anyOf": [ + { + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
find_metric_correlation2 fields changed- added
Output schema / properties / claim_decisionAdded value: +{ + "anyOf": [ + { + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it." +} - added
Output schema / properties / evidence_profileAdded value: +{ + "anyOf": [ + { + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate." +}
- Changed
get_recent_changes2 fields changed- added
Output schema / properties / changes / items / properties / claim_decisionAdded value: +{ + "anyOf": [ + { + "properties": { + "must_state": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permitted_phrasing_class": { + "type": "string" + }, + "template": { + "type": "string" + }, + "tier": { + "type": "string" + } + }, + "required": [ + "tier", + "permitted_phrasing_class", + "must_state", + "template" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "How strongly this result may be stated. tier is insufficient, suggestive, detectable_not_meaningful or supported; every entry in must_state has to be mentioned when reporting it." +} - added
Output schema / properties / changes / items / properties / evidence_profileAdded value: +{ + "anyOf": [ + { + "properties": { + "analysis": { + "type": "string" + }, + "dimensions": { + "items": { + "properties": { + "can_block": { + "default": true, + "type": "boolean" + }, + "details": { + "additionalProperties": true, + "type": "object" + }, + "dimension": { + "enum": [ + "sample", + "temporal", + "robustness", + "missingness", + "practical", + "measurement_validity", + "provenance" + ], + "type": "string" + }, + "reason_codes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "status": { + "enum": [ + "adequate", + "negligible", + "not_assessed", + "weak", + "concern", + "blocking" + ], + "type": "string" + } + }, + "required": [ + "dimension", + "status" + ], + "type": "object" + }, + "type": "array" + }, + "effect": { + "additionalProperties": true, + "type": "object" + }, + "metric": { + "type": "string" + } + }, + "required": [ + "metric", + "analysis", + "dimensions" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Per-dimension evidence quality behind this result (sample, temporal, missingness, ...). Dimensions without an evaluator yet are 'not_assessed' and cap the claim, never count as adequate." +}
4 tool updates
v1.0.19- Changed
aggregate_measurements2 fields changed- changed
Input schema / properties / date / descriptionPrevious value: -"The day to aggregate, formatted YYYY-MM-DD."New value: +"The day to preview, formatted YYYY-MM-DD." - changed
Input schema / properties / source_priority / descriptionPrevious value: -"Ordered list of source names, e.g. [\"Apple\nWatch\", \"Garmin\"]. For any metric with more than one source\nthat day, the first name in this list that's actually present\nwins and the other source's readings for that metric are\ndropped from the aggregate. Omit to fall back to whichever\nsource was imported most recently."New value: +"Ordered list of source names, e.g. [\"Apple\nWatch\", \"Garmin\"]. For any metric with more than one source\nthat day, the first name in this list that's actually present\nwins in \"aggregated\" and the other source's readings for that\nmetric are dropped from that preview. Omit to fall back to\nwhichever source was imported most recently. Never affects\n\"row\" โ see above."
- Changed
explain_metric_change3 fields changed- added
Output schema / properties / conflicting_daysAdded value: +{ + "default": 0, + "type": "integer" +} - added
Output schema / properties / correlated_metrics / items / properties / sample_confidenceAdded value: +{ + "type": "string" +} - changed
Output schema / properties / correlated_metrics / items / requiredPrevious value: -[ - "metric_a", - "metric_b", - "lag_days", - "n" -]New value: +[ + "metric_a", + "metric_b", + "lag_days", + "n", + "sample_confidence" +]
- Changed
find_metric_correlation2 fields changed- added
Output schema / properties / sample_confidenceAdded value: +{ + "type": "string" +} - changed
Output schema / requiredPrevious value: -[ - "metric_a", - "metric_b", - "lag_days", - "n" -]New value: +[ + "metric_a", + "metric_b", + "lag_days", + "n", + "sample_confidence" +]
- Changed
log_measurement1 field changed- changed
Input schema / properties / metric / descriptionPrevious value: -"Name of the metric, e.g. \"resting_heart_rate\", \"steps\".\nFree-form โ not limited to daily_metrics' fixed columns."New value: +"Name of the metric, e.g. \"resting_heart_rate\", \"steps\".\nNot free-form: must already have an entry in the\naggregation_rules table (steps, sleep_hours,\nresting_heart_rate, weight_kg, workout_minutes, mood,\nwater_ml, heart_rate, hrv_ms, out of the box) โ daily_metrics\nis a database-maintained projection over measurements (see\ndb/schema.sql), so every metric written to it needs a known\naggregation method (sum/mean/last) or there would be nothing\ntelling the projection how to roll same-day readings up.\nmetrics_schema lists the current set."
4 tool updates
v1.0.17- Changed
calculate_metric_trend1 field changed- added
Output schema / properties / trend / properties / span_daysAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
explain_metric_change1 field changed- added
Output schema / properties / trend / properties / span_daysAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
get_recent_changes2 fields changed- added
Output schema / properties / changes / items / properties / evidenceAdded value: +{ + "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" +} - changed
Output schema / properties / changes / items / requiredPrevious value: -[ - "metric", - "kind", - "detail" -]New value: +[ + "metric", + "kind", + "detail", + "evidence" +]
- Changed
read_health_data2 fields changed- added
Output schema / properties / coverageAdded value: +{ + "description": "Multi-metric coverage for a Layer-1 result spanning several metrics\nat once. See evidence.build_coverage_summary for how each field is\ncomputed; unlike Evidence (one metric, gaps/freshness/recent_gap),\nthis reports a coverage_percent per metric side by side.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_percent": { + "type": "number" + }, + "days_expected": { + "type": "integer" + }, + "days_with_data": { + "type": "integer" + }, + "metrics": { + "additionalProperties": { + "type": "number" + }, + "type": "object" + }, + "missing_days": { + "type": "integer" + }, + "period": { + "type": "string" + } + }, + "required": [ + "period", + "days_expected", + "days_with_data", + "coverage_percent", + "missing_days", + "metrics", + "confidence" + ], + "type": "object" +} - changed
Output schema / requiredPrevious value: -[ - "range", - "rows", - "truncated", - "summary" -]New value: +[ + "range", + "rows", + "truncated", + "summary", + "coverage" +]
7 tool updates
- Changed
calculate_metric_trend2 fields changed- added
Output schema / properties / evidenceAdded value: +{ + "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" +} - changed
Output schema / requiredPrevious value: -[ - "metric", - "range", - "trend" -]New value: +[ + "metric", + "range", + "trend", + "evidence" +]
- Changed
compare_metric_periods3 fields changed- added
Output schema / properties / period_a_evidenceAdded value: +{ + "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" +} - added
Output schema / properties / period_b_evidenceAdded value: +{ + "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" +} - changed
Output schema / requiredPrevious value: -[ - "metric", - "period_a", - "period_b", - "period_a_stats", - "period_b_stats" -]New value: +[ + "metric", + "period_a", + "period_b", + "period_a_stats", + "period_b_stats", + "period_a_evidence", + "period_b_evidence" +]
- Changed
detect_metric_anomalies2 fields changed- added
Output schema / properties / evidenceAdded value: +{ + "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" +} - changed
Output schema / requiredPrevious value: -[ - "metric", - "range", - "threshold", - "anomalies" -]New value: +[ + "metric", + "range", + "threshold", + "anomalies", + "evidence" +]
- Changed
explain_metric_change5 fields changed- added
Output schema / properties / baseline_evidenceAdded value: +{ + "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" +} - added
Output schema / properties / correlated_metrics / items / properties / evidence_aAdded value: +{ + "anyOf": [ + { + "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / properties / correlated_metrics / items / properties / evidence_bAdded value: +{ + "anyOf": [ + { + "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / properties / trend_evidenceAdded value: +{ + "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" +} - changed
Output schema / requiredPrevious value: -[ - "metric", - "date", - "baseline_range", - "baseline", - "is_anomaly", - "trend", - "correlated_metrics", - "narrative_facts" -]New value: +[ + "metric", + "date", + "baseline_range", + "baseline", + "is_anomaly", + "trend", + "correlated_metrics", + "narrative_facts", + "baseline_evidence", + "trend_evidence" +]
- Changed
find_metric_correlation2 fields changed- added
Output schema / properties / evidence_aAdded value: +{ + "anyOf": [ + { + "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / properties / evidence_bAdded value: +{ + "anyOf": [ + { + "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
get_baseline2 fields changed- added
Output schema / properties / evidenceAdded value: +{ + "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" +} - changed
Output schema / requiredPrevious value: -[ - "metric", - "range", - "baseline" -]New value: +[ + "metric", + "range", + "baseline", + "evidence" +]
- Changed
get_metric_history2 fields changed- added
Output schema / properties / evidenceAdded value: +{ + "description": "Coverage/quality of the data a single-metric analytical result is\nbased on. See evidence.build_evidence for how each field is computed.", + "properties": { + "confidence": { + "type": "string" + }, + "coverage_ratio": { + "type": "number" + }, + "expected_days": { + "type": "integer" + }, + "freshness_days": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "gaps": { + "items": { + "properties": { + "days": { + "type": "integer" + }, + "end": { + "type": "string" + }, + "start": { + "type": "string" + } + }, + "required": [ + "start", + "end", + "days" + ], + "type": "object" + }, + "type": "array" + }, + "measurement_count": { + "type": "integer" + }, + "missing_days": { + "type": "integer" + }, + "observed_days": { + "type": "integer" + }, + "observed_end": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "observed_start": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "recent_gap_days": { + "type": "integer" + }, + "requested_end": { + "type": "string" + }, + "requested_start": { + "type": "string" + } + }, + "required": [ + "requested_start", + "requested_end", + "expected_days", + "observed_days", + "coverage_ratio", + "missing_days", + "measurement_count", + "gaps", + "recent_gap_days", + "confidence" + ], + "type": "object" +} - changed
Output schema / requiredPrevious value: -[ - "metric", - "range", - "points" -]New value: +[ + "metric", + "range", + "points", + "evidence" +]
27 tool updates
v1.0.16- Added
aggregate_measurements - Added
calculate_metric_trend - Removed
clear_daily_metric - Removed
clear_daily_metrics_range - Added
clear_metric - Added
compare_metric_periods - Removed
delete_measurement - Removed
delete_workout - Added
detect_metric_anomalies - Added
explain_metric_change - Added
export_health_data_csv - Added
find_metric_correlation - Added
get_baseline - Added
get_metric_history - Added
get_metric_provenance - Added
get_recent_changes - Changed
log_daily_metric15 fields changed- added
Input schema / properties / date / descriptionAdded value: +"The day to log, formatted YYYY-MM-DD." - added
Input schema / properties / heart_rateAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Non-resting heart rate reading in bpm. 20-250." +} - added
Input schema / properties / hrv_msAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Heart rate variability in milliseconds. 0-300." +} - added
Input schema / properties / moodAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Mood rating on a 1-10 scale." +} - added
Input schema / properties / resting_heart_rate / descriptionAdded value: +"Resting heart rate in bpm. 20-250." - added
Input schema / properties / sleep_hours / descriptionAdded value: +"Hours of sleep. 0-24." - added
Input schema / properties / steps / descriptionAdded value: +"Step count for the day. 0-200,000." - added
Input schema / properties / water_mlAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Water intake in millilitres. 0-10,000." +} - added
Input schema / properties / weight_kgAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Body weight in kilograms. 1-500." +} - added
Input schema / properties / workout_minutesAdded value: +{ + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Minutes of exercise. 0-1,440." +} - added
Output schema / properties / loggedAdded value: +{ + "additionalProperties": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "number" + } + ] + }, + "type": "object" +} - removed
Output schema / properties / resultRemoved value: -{ - "type": "string" -} - added
Output schema / properties / rowAdded value: +{ + "properties": { + "date": { + "type": "string" + }, + "heart_rate": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "hrv_ms": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "mood": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "resting_heart_rate": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "sleep_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "steps": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "water_ml": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "weight_kg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "workout_minutes": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "date" + ], + "type": "object" +} - changed
Output schema / requiredPrevious value: -[ - "result" -]New value: +[ + "logged", + "row" +] - removed
Output schema / x-fastmcp-wrap-resultRemoved value: -true
- Changed
log_measurement14 fields changed- removed
Input schema / properties / dateRemoved value: -{ - "type": "string" -} - added
Input schema / properties / metricAdded value: +{ + "description": "Name of the metric, e.g. \"resting_heart_rate\", \"steps\".\nFree-form โ not limited to daily_metrics' fixed columns.", + "type": "string" +} - removed
Input schema / properties / metric_nameRemoved value: -{ - "type": "string" -} - removed
Input schema / properties / notesRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null -} - added
Input schema / properties / sourceAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Where this came from, e.g. \"Apple Watch\", \"manual\". Optional." +} - added
Input schema / properties / source_typeAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Category of source, e.g. \"wearable\", \"manual\", \"app\". Optional." +} - added
Input schema / properties / timestampAdded value: +{ + "description": "When the observation was taken, YYYY-MM-DD or a full\nISO 8601 timestamp (YYYY-MM-DDTHH:MM:SS).", + "type": "string" +} - added
Input schema / properties / unit / descriptionAdded value: +"Unit the value is in, e.g. \"bpm\", \"kg\". Optional." - added
Input schema / properties / value / descriptionAdded value: +"The numeric reading." - changed
Input schema / requiredPrevious value: -[ - "date", - "metric_name", - "value" -]New value: +[ + "timestamp", + "metric", + "value" +] - added
Output schema / properties / measurementAdded value: +{ + "properties": { + "created_at": { + "type": "string" + }, + "id": { + "type": "integer" + }, + "metric": { + "type": "string" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "source_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "timestamp": { + "type": "string" + }, + "unit": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "value": { + "type": "number" + } + }, + "required": [ + "id", + "timestamp", + "metric", + "value", + "created_at" + ], + "type": "object" +} - removed
Output schema / properties / resultRemoved value: -{ - "type": "string" -} - changed
Output schema / requiredPrevious value: -[ - "result" -]New value: +[ + "measurement" +] - removed
Output schema / x-fastmcp-wrap-resultRemoved value: -true
- Removed
log_workout - Added
log_workout_session - Removed
read_finance_data - Changed
read_health_data9 fields changed- added
Input schema / properties / end_date / descriptionAdded value: +"Last day to include, formatted YYYY-MM-DD. Defaults to today." - added
Input schema / properties / start_date / descriptionAdded value: +"First day to include, formatted YYYY-MM-DD.\nDefaults to 30 days before end_date. Ranges over ~10 years are rejected." - added
Output schema / properties / rangeAdded value: +{ + "properties": { + "end_date": { + "type": "string" + }, + "start_date": { + "type": "string" + } + }, + "required": [ + "start_date", + "end_date" + ], + "type": "object" +} - removed
Output schema / properties / resultRemoved value: -{ - "type": "string" -} - added
Output schema / properties / rowsAdded value: +{ + "items": { + "properties": { + "date": { + "type": "string" + }, + "heart_rate": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "hrv_ms": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "mood": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "resting_heart_rate": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "sleep_hours": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "steps": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "water_ml": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "weight_kg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "workout_minutes": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "date" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / summaryAdded value: +{ + "properties": { + "days_with_data": { + "type": "integer" + }, + "heart_rate": { + "properties": { + "avg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "max": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "min": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "type": "object" + }, + "hrv_ms": { + "properties": { + "avg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "max": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "min": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "type": "object" + }, + "mood": { + "properties": { + "avg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "max": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "min": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "type": "object" + }, + "resting_heart_rate": { + "properties": { + "avg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "max": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "min": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "type": "object" + }, + "sleep_hours": { + "properties": { + "avg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "max": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "min": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "type": "object" + }, + "steps": { + "properties": { + "avg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "max": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "min": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "type": "object" + }, + "water_ml": { + "properties": { + "avg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "max": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "min": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "type": "object" + }, + "weight_kg": { + "properties": { + "avg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "max": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "min": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "type": "object" + }, + "workout_minutes": { + "properties": { + "avg": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "max": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + }, + "min": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "type": "object" + } + }, + "required": [ + "days_with_data", + "steps", + "sleep_hours", + "resting_heart_rate", + "weight_kg", + "workout_minutes", + "mood", + "water_ml", + "heart_rate", + "hrv_ms" + ], + "type": "object" +} - added
Output schema / properties / truncatedAdded value: +{ + "type": "boolean" +} - changed
Output schema / requiredPrevious value: -[ - "result" -]New value: +[ + "range", + "rows", + "truncated", + "summary" +] - removed
Output schema / x-fastmcp-wrap-resultRemoved value: -true
- Added
read_measurements - Added
read_workout_sessions - Removed
update_daily_metric - Removed
update_measurement - Removed
update_workout
27 tool updates
v1.0.15- Removed
aggregate_measurements - Removed
calculate_metric_trend - Added
clear_daily_metric - Added
clear_daily_metrics_range - Removed
clear_metric - Removed
compare_metric_periods - Added
delete_measurement - Added
delete_workout - Removed
detect_metric_anomalies - Removed
explain_metric_change - Removed
export_health_data_csv - Removed
find_metric_correlation - Removed
get_baseline - Removed
get_metric_history - Removed
get_metric_provenance - Removed
get_recent_changes - Changed
log_daily_metric15 fields changed- removed
Input schema / properties / date / descriptionRemoved value: -"The day to log, formatted YYYY-MM-DD." - removed
Input schema / properties / heart_rateRemoved value: -{ - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Non-resting heart rate reading in bpm. 20-250." -} - removed
Input schema / properties / hrv_msRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Heart rate variability in milliseconds. 0-300." -} - removed
Input schema / properties / moodRemoved value: -{ - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Mood rating on a 1-10 scale." -} - removed
Input schema / properties / resting_heart_rate / descriptionRemoved value: -"Resting heart rate in bpm. 20-250." - removed
Input schema / properties / sleep_hours / descriptionRemoved value: -"Hours of sleep. 0-24." - removed
Input schema / properties / steps / descriptionRemoved value: -"Step count for the day. 0-200,000." - removed
Input schema / properties / water_mlRemoved value: -{ - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Water intake in millilitres. 0-10,000." -} - removed
Input schema / properties / weight_kgRemoved value: -{ - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Body weight in kilograms. 1-500." -} - removed
Input schema / properties / workout_minutesRemoved value: -{ - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Minutes of exercise. 0-1,440." -} - removed
Output schema / properties / loggedRemoved value: -{ - "additionalProperties": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "number" - } - ] - }, - "type": "object" -} - added
Output schema / properties / resultAdded value: +{ + "type": "string" +} - removed
Output schema / properties / rowRemoved value: -{ - "properties": { - "date": { - "type": "string" - }, - "heart_rate": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "hrv_ms": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "mood": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "resting_heart_rate": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "sleep_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "steps": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "water_ml": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "weight_kg": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "workout_minutes": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "required": [ - "date" - ], - "type": "object" -} - changed
Output schema / requiredPrevious value: -[ - "logged", - "row" -]New value: +[ + "result" +] - added
Output schema / x-fastmcp-wrap-resultAdded value: +true
- Changed
log_measurement14 fields changed- added
Input schema / properties / dateAdded value: +{ + "type": "string" +} - removed
Input schema / properties / metricRemoved value: -{ - "description": "Name of the metric, e.g. \"resting_heart_rate\", \"steps\".\nFree-form โ not limited to daily_metrics' fixed columns.", - "type": "string" -} - added
Input schema / properties / metric_nameAdded value: +{ + "type": "string" +} - added
Input schema / properties / notesAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - removed
Input schema / properties / sourceRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Where this came from, e.g. \"Apple Watch\", \"manual\". Optional." -} - removed
Input schema / properties / source_typeRemoved value: -{ - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "description": "Category of source, e.g. \"wearable\", \"manual\", \"app\". Optional." -} - removed
Input schema / properties / timestampRemoved value: -{ - "description": "When the observation was taken, YYYY-MM-DD or a full\nISO 8601 timestamp (YYYY-MM-DDTHH:MM:SS).", - "type": "string" -} - removed
Input schema / properties / unit / descriptionRemoved value: -"Unit the value is in, e.g. \"bpm\", \"kg\". Optional." - removed
Input schema / properties / value / descriptionRemoved value: -"The numeric reading." - changed
Input schema / requiredPrevious value: -[ - "timestamp", - "metric", - "value" -]New value: +[ + "date", + "metric_name", + "value" +] - removed
Output schema / properties / measurementRemoved value: -{ - "properties": { - "created_at": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "metric": { - "type": "string" - }, - "source": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "source_type": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "timestamp": { - "type": "string" - }, - "unit": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null - }, - "value": { - "type": "number" - } - }, - "required": [ - "id", - "timestamp", - "metric", - "value", - "created_at" - ], - "type": "object" -} - added
Output schema / properties / resultAdded value: +{ + "type": "string" +} - changed
Output schema / requiredPrevious value: -[ - "measurement" -]New value: +[ + "result" +] - added
Output schema / x-fastmcp-wrap-resultAdded value: +true
- Added
log_workout - Removed
log_workout_session - Added
read_finance_data - Changed
read_health_data9 fields changed- removed
Input schema / properties / end_date / descriptionRemoved value: -"Last day to include, formatted YYYY-MM-DD. Defaults to today." - removed
Input schema / properties / start_date / descriptionRemoved value: -"First day to include, formatted YYYY-MM-DD.\nDefaults to 30 days before end_date. Ranges over ~10 years are rejected." - removed
Output schema / properties / rangeRemoved value: -{ - "properties": { - "end_date": { - "type": "string" - }, - "start_date": { - "type": "string" - } - }, - "required": [ - "start_date", - "end_date" - ], - "type": "object" -} - added
Output schema / properties / resultAdded value: +{ + "type": "string" +} - removed
Output schema / properties / rowsRemoved value: -{ - "items": { - "properties": { - "date": { - "type": "string" - }, - "heart_rate": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "hrv_ms": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "mood": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "resting_heart_rate": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "sleep_hours": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "steps": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "water_ml": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - }, - "weight_kg": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "workout_minutes": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "required": [ - "date" - ], - "type": "object" - }, - "type": "array" -} - removed
Output schema / properties / summaryRemoved value: -{ - "properties": { - "days_with_data": { - "type": "integer" - }, - "heart_rate": { - "properties": { - "avg": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "max": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "min": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "type": "object" - }, - "hrv_ms": { - "properties": { - "avg": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "max": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "min": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "type": "object" - }, - "mood": { - "properties": { - "avg": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "max": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "min": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "type": "object" - }, - "resting_heart_rate": { - "properties": { - "avg": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "max": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "min": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "type": "object" - }, - "sleep_hours": { - "properties": { - "avg": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "max": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "min": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "type": "object" - }, - "steps": { - "properties": { - "avg": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "max": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "min": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "type": "object" - }, - "water_ml": { - "properties": { - "avg": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "max": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "min": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "type": "object" - }, - "weight_kg": { - "properties": { - "avg": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "max": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "min": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "type": "object" - }, - "workout_minutes": { - "properties": { - "avg": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "max": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - }, - "min": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ], - "default": null - } - }, - "type": "object" - } - }, - "required": [ - "days_with_data", - "steps", - "sleep_hours", - "resting_heart_rate", - "weight_kg", - "workout_minutes", - "mood", - "water_ml", - "heart_rate", - "hrv_ms" - ], - "type": "object" -} - removed
Output schema / properties / truncatedRemoved value: -{ - "type": "boolean" -} - changed
Output schema / requiredPrevious value: -[ - "range", - "rows", - "truncated", - "summary" -]New value: +[ + "result" +] - added
Output schema / x-fastmcp-wrap-resultAdded value: +true
- Removed
read_measurements - Removed
read_workout_sessions - Added
update_daily_metric - Added
update_measurement - Added
update_workout
3 tool updates
v0.3.0- Changed
explain_metric_change1 field changed- added
Output schema / properties / sessionsAdded value: +{ + "default": [], + "items": { + "properties": { + "activity_type": { + "type": "string" + }, + "avg_heart_rate": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "created_at": { + "type": "string" + }, + "date": { + "type": "string" + }, + "duration_minutes": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "intensity": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "max_heart_rate": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "notes": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "start_time": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "id", + "date", + "activity_type", + "duration_minutes", + "created_at" + ], + "type": "object" + }, + "type": "array" +}
- Added
log_workout_session - Added
read_workout_sessions
TDQS
Scored across 20 tools
Every tool carries explicit 'use this when' and 'do not use this when' guidance that routes overlapping analytics tools to one another, so the boundaries between get_baseline, detect_metric_anomalies, calculate_metric_trend, compare_metric_periods, get_recent_changes, and explain_metric_change are unambiguous. Read paths (read_health_data vs get_metric_history vs read_measurements) and write paths (log_measurement vs log_daily_metric vs log_workout_session) are similarly well-separated.
All 20 tools use lower_snake_case with a clear verb_noun shape (get_*, read_*, log_*, calculate_*, detect_*, compare_*, find_*, export_*, clear_*), plus one consistent naming of the aggregate. There are no camelCase/naming aberrations or vague single-word verbs, so the pattern is highly predictable.
At 20 tools this is on the heavier end, but the domain genuinely spans raw observations, daily aggregates, workouts, imports, exports, and a layered analytics stack, and each tool earns its place. It sits just below the 'heavy' 16-25 range boundary, so it is slightly over but reasonable.
The surface covers ingestion (raw and daily), clearing/undo, multi-source provenance, freshness and import monitoring, CSV export, and a full analytics suite, which is near-complete for a quantified-self domain. Minor gaps exist, such as no explicit update/edit for an already-logged workout session (only day-level clear_metric), which an agent can work around.
Maintenance
Related MCP Connectors
- Era ContextOAuthapp.era
Personal finance, bank account, and shared memory connector for Claude, ChatGPT, Gemini Spark & more
Query 40 databases from Claude, ChatGPT, or Cursor โ on any device. Read-only, encrypted, audited.
Your personal data for AI โ Telegram, bank, courses, Zoom & more, scoped to you.
- HutchDBOAuthcom.hutchdb
Store, query, and update structured data from any AI agent
Related MCP Servers
- AlicenseAqualityAmaintenanceAn MCP server that allows users to query and analyze their Apple Health data using SQL and natural language, utilizing DuckDB for fast and efficient health data analysis.3145 npm571MIT
- AlicenseNot gradedqualityCmaintenanceLoads Apple Health export data into a local SQLite database and exposes tools to query health metrics and workout records via natural language.22 PyPI3MIT
- AlicenseNot gradedqualityDmaintenanceEnables querying personal data synced from services like Lunch Money and Strava using SQL via Claude.3 npm1MIT
- AlicenseBqualityDmaintenanceEnables AI agents to interact with local SQLite databases with full CRUD, schema introspection, foreign key relations, generated columns, and multi-format import/export (CSV, JSON, XLSX) through natural language.266 npmMIT