Skip to main content
Glama

Server Details

Live snow reports, SNOTEL measurements, webcams and powder rankings for 150 ski resorts.

If you are the author of this connector, you can claim ownership by verifying the domain or GitHub account it belongs to. Claimed connector authors can inspect health checks, view analytics, and manage their listing.
Status
Healthy
Uptime
100.0% over 20 days
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL
Repository
jaredschueler07/peakcam
GitHub Stars
0
ChatGPT
–
Claude
–

TDQS

A4/5.0

Scored across 21 tools

Disambiguation4/5

Most tools have clearly distinct purposes, and the descriptions explicitly disambiguate close pairs like get_resort_conditions vs get_stations vs get_snow_history. However, the `ask` router overlaps with every query tool, and there is some conceptual overlap among conditions, stations, and score/ranking tools, which could cause hesitation.

Naming Consistency4/5

Names are almost entirely snake_case verb_noun patterns (get_*, compare_*, find_*, list_*, search_*), making the set highly predictable. The only minor deviation is `ask`, which is a bare verb rather than a verb_noun pair.

Tool Count4/5

21 tools is on the heavy side, but the domain is broad (resorts, snow conditions, forecasts, models, cams, alerts, rankings, history). Each tool covers a distinct query type, so the count is slightly over but reasonable for the scope.

Completeness4/5

The surface is extensive for a read-only snow-data domain, covering discovery, conditions, forecasts, history, rankings, cams, and alerts. Minor gaps include no direct 'list all resorts' tool and no standalone non-snow weather forecast, but agents can work around these with search_resorts, get_forecast, and get_stations.

Available Tools

21 tools
askAsk PeakCamA
Read-onlyIdempotent
Inspect

One natural-language question in, one tool result out, deterministically: the router resolves the resort by name or nickname, picks an intent from the wording (snow, open/closed, forecast, cams, history, compare, where did it snow, percent of normal, profile, regions, alerts) and calls the matching tool. Returns the tool's data, the resort, citation URLs and a dated sentence to quote. Answers answerable: false with suggestions rather than guessing. No language model is involved.

NameRequiredDescriptionDefault
questionYesThe question as the user asked it, up to 300 characters, e.g. "is Alta open" or "where did it snow most in Colorado".

Output Schema

NameRequiredDescription
asOfYesISO instant of the newest report the sentence used; null when it used none.
dataYesThe tool's structured result (its documented `outputSchema`), or null.
toolYesThe PeakCam MCP tool whose result is in `data`.
placeYes
intentYes
resortYesThe resort the question named (the first, for a comparison).
licenseYes
resortsYesEvery resort the question named, in order.
questionYes
sentenceYesA dated, source-labelled sentence that can be quoted verbatim.
argumentsYesThe arguments that tool was called with, so the call can be repeated over MCP.
citationsYesPeakCam URLs to cite, the resort page first.
answerableYesFalse when the router found no resort or no intent it could serve; `data` is then null and `suggestions` says what to ask.
attributionYes
generatedAtYes
suggestionsYesQuestions the router can answer, offered when it could not answer this one.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnly, idempotent, non-destructive, closed-world), and the description adds genuinely new behavioral facts: the routing is deterministic, no LLM is involved, the response includes the tool's data plus resort, citation URLs and a dated quotable sentence, and unanswerable questions return `answerable: false` with suggestions rather than a guess. The failure mode disclosure is exactly the kind of context an agent cannot get 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core contract in the first clause, then progressively adds routing detail, return shape, and failure behavior. Dense but every sentence carries information; the long parenthetical intent list is the only slightly heavy element.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although an output schema exists (so return values need not be described), the description still sketches the response shape and the `answerable: false` path, and it covers the deterministic, no-LLM guarantee. Nothing an agent needs to decide whether and how to call this router is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single `question` parameter is well documented with examples and a 300-char limit, so baseline is 3. The description goes further by explaining how the question string is interpreted — resort resolved by name or nickname, intent inferred from wording — which is meaningful semantics the schema cannot express.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource with unusual precision: 'One natural-language question in, one tool result out,' and immediately explains the routing mechanism (resolve resort, pick intent, call matching tool). This clearly distinguishes it from the sibling tools, which each handle a single fixed intent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The enumerated intent list (snow, open/closed, forecast, cams, history, compare, where did it snow, percent of normal, profile, regions, alerts) tells an agent exactly which classes of question belong here and maps them to the sibling tools it will dispatch to. It stops short of explicitly stating when to call this router instead of invoking a specific sibling directly, which is the one remaining routing decision.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_modelsCompare forecast modelsA
Read-onlyIdempotent
Inspect

How each weather model has verified at a resort over the trailing 90 days, graded against measured snow (SNOTEL depth change, clipped at zero), and what each model says for the next 7 days right now. Per model: rank, mean absolute error at day 1/3/7 (cm), bias ratio (total forecast over total measured; above 1 over-forecasts), samples, plus the current 7-day total and horizon. truthBasis and measuredDays say what the grading rested on; a resort with no measured series has no scores. The PeakCam blend is graded by the same rule and appears as blend.

NameRequiredDescriptionDefault
slugYesPeakCam resort slug, lowercase kebab-case, e.g. `breckenridge` or `ski-portillo`. Get it from search_resorts.

Output Schema

NameRequiredDescription
nameYes
noteYes
slugYes
scoresYesRanked; empty until the scorer has measured days.
creditsYes
outlookYesThe newest stored run per model: what each says for the next 7 days.
stationYes
bestModelYes
periodDaysYes
truthBasisYes
accuracyUrlYes
generatedAtYesISO-8601 UTC instant the result was generated.
scoredPointYes
canonicalUrlYes
measuredDaysYes
blendTotal7dInYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the read-only/idempotent/closed-world profile, so the burden is lighter, yet the description adds real behavioral context: how grading is done (SNOTEL depth change clipped at zero), what bias ratio means, and the edge case that a resort with no measured series has no scores. It doesn't cover rate limits or latency, keeping it at a 4.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded in the first clause, and the field-level detail that follows is largely load-bearing. It is dense and slightly list-like, but no sentence is obviously filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present the description need not unpack return values, yet it explains the per-model fields, truthBasis and measuredDays, and the blend entry, making it broadly complete for a single-parameter analytical tool. The main gap is the absence of explicit guidance on when to reach for this versus sibling forecast tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is a single parameter with 100% schema description coverage, so the schema already documents the slug format and its source. The description adds nothing about the slug beyond what structured fields provide, which is the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource and scope: per-model verification at a resort over 90 days plus the current 7-day forecast. An agent can immediately tell this is a model-accuracy comparison and distinguish it from resort-level siblings like compare_resorts or get_forecast.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied — you call it to see which forecast model has verified best at a given resort. There is no explicit statement of when to prefer this over get_forecast or compare_resorts, and no exclusions. The only routing hint is the slug field pointing to search_resorts.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_resortsCompare resortsA
Read-onlyIdempotent
Inspect

Side-by-side latest snow, today's Snow Score (0–100 with a rating; get_score explains it), season status and cam counts for 2–6 resorts. Every slug must resolve; an unknown one returns suggestions.

NameRequiredDescriptionDefault
slugsYes2–6 resort slugs.

Output Schema

NameRequiredDescription
countYes
resortsYes
generatedAtYesISO-8601 UTC instant the result was generated.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly, idempotent and non-destructive semantics, and an output schema exists. The description adds genuinely new behavior: unknown slugs cause failure but return suggestions, which tells the agent how to recover from bad input.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler; the field list and the input/resolution rule are both front-loaded and each clause carries distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering safety, a full output schema covering return values, and a 100%-covered input schema, the description only needs to add field scope and input-resolution behavior — both present. Nothing required to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds validation semantics beyond the schema — 'every slug must resolve' and the suggestion-returning fallback on unknown slugs — which shapes how the agent should supply and vet the slugs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (compare), resource (resorts), a precise scope (2–6), and enumerates the compared fields: latest snow, Snow Score, season status, cam counts. The cardinality and cross-resort nature cleanly separate it from single-resort siblings like get_resort_conditions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the '2–6 resorts / side-by-side' framing, and it points to get_score for Score explanation plus search_resorts (via schema) for slug sourcing. It never explicitly says when to prefer this over get_resort_conditions or get_resort_profile for a single resort.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_powderFind powderA
Read-onlyIdempotent
Inspect

Rank resorts by new snow in the last 24 or 48 hours, optionally within one state/province and above a minimum. Pass sourceOnly="snotel" to answer "where did it snow most, measured only" with station data alone. Resorts with no report are left out; zero inches is a measurement. Each row also carries today's Snow Score (score, 0–100 with a rating) when one is stored; get_score explains it. Sources: snotel = measured at a USDA NRCS SNOTEL station near the resort (station elevation, not the summit), open_meteo = weather-model estimate for resorts without a station.

NameRequiredDescriptionDefault
limitNoRows to return, 1–25.
stateNoUS state or Canadian province code (`CO`, `UT`, `BC`), or for the Andes the country name PeakCam lists (`Chile`, `Argentina`). Case-insensitive.
windowNoWhich window ranks first; the other breaks ties.24h
minInchesNoKeep only resorts with at least this many inches in the window.
sourceOnlyNo`snotel` keeps only station-measured reports and drops model estimates.

Output Schema

NameRequiredDescription
countYes
windowYes
filtersYes
licenseYes
resultsYes
attributionYes
generatedAtYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only/idempotent safety profile, so the description focuses on semantics an agent cannot get from structured fields: resorts with no report are excluded, zero inches counts as a real measurement, each row carries a stored Snow Score, and the two sources differ (station-measured at station elevation vs model estimate for resorts lacking a station). That is exactly the kind of behavioral context that prevents misreading results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core purpose in the first clause, then layers filtering semantics, then source definitions. Every sentence carries information, though the trailing source-definition sentence is dense and could be slightly tighter.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return-shape detail is unnecessary, and the description still supplies the interpretation layer (score meaning, source provenance, exclusion of unreported resorts) that the schema and annotations cannot. Nothing an agent needs to call or read this tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds meaning beyond the schema: why sourceOnly exists (isolate station-measured answers) and how zero inches and missing reports should be interpreted. Window tie-breaking and state format are already in the schema, so this sits just above baseline rather than far above it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: rank resorts by new snow over a 24h/48h window, with optional state and minimum-inch filters. The 'powder' framing plus explicit window and filtering behavior distinguishes it from generic siblings like get_snow_history or get_leaderboard without needing to open a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete usage conditions: pass sourceOnly="snotel" to answer 'where did it snow most, measured only', and points to get_score for interpreting the score field. It does not explicitly route between this tool and similar siblings (get_snow_history, compare_resorts), but the context provided 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.

get_alert_optionsAlert optionsA
Read-onlyIdempotent
Inspect

How to be told when it snows, without this server writing anything: the powder-alert threshold and schedule, the e-mail, webhook (Standard Webhooks, signed), Atom and iCal channels, the per-resort public Atom feed, the webhook payload contract, and the manage page where a person registers a destination. Pass a slug to get that resort's feed URL.

NameRequiredDescriptionDefault
slugNoOptional: a resort slug, to fill in its public Atom feed URL.

Output Schema

NameRequiredDescription
writesYesThis tool never subscribes anyone; it only explains how.
webhookYes
channelsYes
scheduleYes
manageUrlYesWhere a person subscribes and registers webhooks; e-mail verified, no password.
resortFeedYes
generatedAtYesISO-8601 UTC instant the result was generated.
thresholdInchesYesNew snow in 24 h (measured) or storm total (forecast) that fires an alert.

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, and the description reinforces this with 'without this server writing anything.' It goes beyond the annotations by disclosing the webhook signing scheme (Standard Webhooks, signed), the payload contract, supported channel types, the per-resort public Atom feed, and the human-facing manage page. That is substantive behavioral context a caller could not infer from the safety hints alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The single long sentence is a comma-heavy enumeration of channels, contracts, and pages that mixes purpose with a parts list. It is front-loaded toward what the tool covers, but the run-on structure makes it harder to parse than it needs to be. Some listed items (iCal, Atom, manage page) could be trimmed or reorganized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a single optional parameter, rich annotations, and an output schema (so return values need not be described), the description covers enough for correct invocation: what is returned, what the slug does, and that nothing is written. Only explicit sibling routing and any error/none-found behavior are missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents the single optional slug parameter, including that it fills in the public Atom feed URL. The description restates this same effect ('Pass a slug to get that resort's feed URL') without adding format, constraints, or fallback behavior. Baseline 3 is appropriate when the schema carries the parameter burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly frames the resource: the alert threshold/schedule, delivery channels (e-mail, webhook, Atom, iCal), webhook payload contract, and the manage page. The verb is implied rather than stated ('How to be told when it snows'), but an agent can tell this returns alert-configuration information. It is distinguishable from siblings like get_forecast or find_powder, though it never names them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: 'Pass a slug to get that resort's feed URL' tells the agent what the optional parameter accomplishes, and 'without this server writing anything' hints at a non-mutating context. There is no explicit when-to-use-this-vs-alternatives guidance, so the agent must infer that this is the documentation/reference tool rather than a data-lookup tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_cam_timelineCam timelineA
Read-onlyIdempotent
Inspect

Archived still frames for a resort's webcams (or one cam) over the last 1–48 hours, as links with capture times, plus the newest storm frame on tape per cam. Only cams whose operator allows archiving appear; PeakCam captures every 6 hours. Use it for "what did it look like this morning" or "show me the last storm". Frames are never returned inline.

NameRequiredDescriptionDefault
slugYesPeakCam resort slug, lowercase kebab-case, e.g. `breckenridge` or `ski-portillo`. Get it from search_resorts.
camIdNoOptional: one cam's id from get_resort_cams; default is every archived cam at the resort.
hoursNoWindow, 1–48 hours.

Output Schema

NameRequiredDescription
camsYes
nameYes
noteYes
slugYes
hoursYes
camCountYesCams with at least one frame in the result.
lastStormYesNewest storm frame across the resort, any age.
frameCountYes
generatedAtYesISO-8601 UTC instant the result was generated.
canonicalUrlYes
newestCapturedAtYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only, idempotent, non-destructive profile, so the description is not carrying that burden. It adds genuinely useful behavioral facts beyond them: operator-level archiving eligibility, the 6-hour PeakCam capture cadence, and that frames are returned as links rather than inline. It omits pagination/rate-limit behavior, keeping it below a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences with no filler, and the core capability is front-loaded before the usage examples. The "never returned inline" caveat is important but placed last, slightly weakening the front-loading.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is unnecessary, and annotations cover the safety profile. The description supplies the remaining agent-relevant context — archiving eligibility, capture cadence, and time-window bounds — so nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 slug, camId, and hours with formats and defaults. The description restates the 1–48 hour window and the one-cam-vs-all-cams distinction but adds no syntax or semantic detail the schema lacks, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (archived still frames for a resort's webcams), the temporal scope (1–48 hours), and the return form (links with capture times, plus the newest storm frame). It is clearly distinguishable from the sibling get_resort_cams, which covers live cams, without needing to open either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete usage scenarios ("what did it look like this morning", "show me the last storm") and states an availability precondition (only archiving-allowed cams appear). It never explicitly routes the agent to the alternative for live footage, so it stops short of the when-not guidance a 5 would require.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_forecastResort forecastA
Read-onlyIdempotent
Inspect

Fourteen-day blended snow forecast for a resort: per day the median snowfall across the weather models that reach that day (ECMWF IFS, GFS, GEM, ICON, JMA, Météo-France, UKMO; NBM and HRRR added for US points), the 25th/75th percentile band as snowfallLoIn/snowfallHiIn, and modelCount so you can weigh a far-out two-model day against a near-term nine-model one. summary has next 48 h, 7- and 14-day totals and the peak day. US resorts also get the National Weather Service text narrative (periods), with its snow amounts replaced by the blend. Weather data by Open-Meteo.com (CC BY 4.0): quote the credit. available: false when no model run is stored yet.

NameRequiredDescriptionDefault
slugYesPeakCam resort slug, lowercase kebab-case, e.g. `breckenridge` or `ski-portillo`. Get it from search_resorts.
pointNoWhich elevation's blend. Falls back to the other point with a note when the asked one has no runs.summit

Output Schema

NameRequiredDescription
daysYesUp to 14 blended days.
nameYes
noteYes
slugYes
pointYes
modelsYes
creditsYes
periodsYesNWS daily narrative for US resorts (up to 5 days); empty elsewhere or when NWS does not answer.
summaryYes
issuedAtYesNewest model issue instant among the runs blended.
providerYes`blend`: stored multi-model blend; `nws`: NWS narrative only, snow amounts are keyword estimates; `none`: nothing available.
availableYes
modelCountYesModels contributing to the first day.
forecastUrlYesThe REST document with every model run.
generatedAtYesISO-8601 UTC instant the result was generated.
canonicalUrlYes

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly, idempotent and closed-world, but the description adds substantial non-redundant context: the model roster, what modelCount means for weighting confidence, the NWS narrative with amounts replaced by the blend, the required Open-Meteo attribution ('quote the credit'), and the available: false edge case when no run is stored. These are real obligations and failure modes an agent would not learn from 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and horizon are front-loaded in the first clause, and each sentence carries information (blend method, band fields, summary contents, attribution, availability flag). The long parenthetical model enumeration is the only mildly verbose passage, though it does support interpreting modelCount.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the description is not obliged to enumerate return values, yet it still explains the interpretation of the percentile band and modelCount, the summary block, the US-only periods narrative, and the empty-data case. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both slug and point are already documented in the schema, including the enum values and the summit/base fallback. The description adds no additional parameter syntax or format guidance 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.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb, resource and horizon: a fourteen-day blended snow forecast for a resort. It also states the blend methodology (median across named models) and the derived fields, which clearly distinguishes it from get_snow_history, get_monthly_climatology and compare_models without needing the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the resource name: a forecast tool, so an agent can infer it is for upcoming snow rather than history or climatology. There is no explicit when-to-use/when-not statement or named alternative such as get_snow_history or compare_models. The only routing hint is the slug parameter's 'Get it from search_resorts', which is a dependency rather than a selection rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_leaderboardLeaderboardA
Read-onlyIdempotent
Inspect

Resorts ranked on one of four season boards: best-powder-this-week (measured new snow in the last 7 days), season-powder-days (days with ≥ 8 in since Oct 1), deepest-base (latest station or model depth) and season-snowfall (measured new snow since Oct 1), optionally within one state and measured-only. The season boards cover the Northern hemisphere. Answers a dated sentence, the rule in words and rows with source and station. Same data as https://www.peakcam.io/snow-report/{kind}.

NameRequiredDescriptionDefault
kindYesWhich board.
limitNoRows to return, 1–50.
stateNoUS state or Canadian province code (`CO`, `UT`, `BC`), or for the Andes the country name PeakCam lists (`Chile`, `Argentina`). Case-insensitive.
sourceOnlyNo`snotel` keeps only station-measured rows.

Output Schema

NameRequiredDescription
asOfYes
kindYes
poolYesResorts considered after the filters.
ruleYesThe ranking rule in words.
countYes
titleYes
seasonYesThe Northern-hemisphere season the season-bound boards count from.
filtersYes
licenseYes
pageUrlYes
resultsYes
sentenceYesThe dated, quotable summary sentence.
weekStartYesYYYY-MM-DD the 7-day window starts (best-powder-this-week).
attributionYes
descriptionYes
generatedAtYes
unavailableYesTrue when the season aggregates could not be read; `results` is then empty.
totalMatchingYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive/openWorld=false, so safety is covered. The description usefully adds behavior the annotations do not: the coverage restriction ('season boards cover the Northern hemisphere') and the return shape (dated sentence, rule in words, rows with source and station), plus a data-source URL.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the ranked resource and the four boards, and nearly every clause carries distinct information. It is a single dense paragraph, though, and the return-format and URL sentences could be trimmed or separated for faster scanning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

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 spelled out, and the description still summarizes them. It covers board definitions, hemisphere scope, state/source filters, and a reference link, leaving only minor gaps around pagination or ranking ties.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100 percent, so the baseline is 3, but the description genuinely extends `kind` beyond the schema's terse 'Which board' by defining what each board measures (new snow last 7 days, days ≥ 8 in since Oct 1, etc.) and clarifies the measured-only behavior of sourceOnly. It does not add meaning for `limit`.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (resorts ranked on season boards) and enumerates the four `kind` values with their exact measurement rules, so the agent can distinguish it from siblings like compare_resorts or get_season_stats without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the 'answers a dated sentence' framing and the nature of the boards, but no explicit when-to-use or when-not guidance is given, and no sibling tool (e.g. compare_resorts, find_powder) is named as the alternative path.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_monthly_climatologyMonthly climatologyA
Read-onlyIdempotent
Inspect

Average snowfall, snow days (≥ 1 in), depth and the biggest storm per calendar month at the resort's SNOTEL station, over the 30 most recent complete winters and, separately, the 10 most recent, with the recent decade as a percent of the 30-winter figure and a note when they differ by more than 10 %. Use it for "which month is snowiest", "how much does it usually snow in January". Resorts without a station normal answer available: false.

NameRequiredDescriptionDefault
slugYesPeakCam resort slug, lowercase kebab-case, e.g. `breckenridge`. Get it from search_resorts.

Output Schema

NameRequiredDescription
nameYes
noteYes
slugYes
apiUrlYes
monthsYesIn season order (October first in the North).
licenseYes
pageUrlYes
stationYes
availableYesFalse for resorts without a station normal; `months` is then empty.
attributionYes
generatedAtYes
canonicalUrlYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (readOnly, idempotent, non-destructive), so the bar is lower; the description nonetheless adds real behavioral context: the 30-winter vs 10-winter breakdown, the recent-decade-as-percent-of-30 computation, the >10% divergence note, and an explicit no-station failure mode. It does not mention rate limits or data-availability windows, keeping it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the returned metrics and scope, then use cases, with no filler. The first sentence is a dense run-on covering four metrics across two windows, which taxes readability but every clause conveys distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Output schema exists, so return values need not be explained. The description covers what is computed, the comparison semantics, and the failure mode, leaving little an agent needs missing. Minor gaps around data latency are acceptable given the structured output.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Single parameter with 100% schema description coverage, which already documents slug format and how to obtain it via search_resorts. The description adds nothing beyond the schema, so baseline 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (compute/return) and resource (per-calendar-month climatology) with precise scope: snowfall, snow days ≥1in, depth, biggest storm, over 30 complete winters plus the recent 10. An agent can distinguish it from siblings like get_season_stats, get_snow_history, or get_percent_of_normal 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.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete use cases ('which month is snowiest', 'how much does it usually snow in January') and a failure condition ('Resorts without a station normal answer available: false'). No alternatives or siblings are named, so it stops short of full when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_opening_datesOpening datesA
Read-onlyIdempotent
Inspect

Season opening and closing dates with status (open / closed / unknown) for every resort, or those in one state/province, soonest opening first. Confirmed dates come from the resort; projected ones are third-party estimates.

NameRequiredDescriptionDefault
limitNoRows to return, 1–150.
stateNoUS state or Canadian province code (`CO`, `UT`, `BC`), or for the Andes the country name PeakCam lists (`Chile`, `Argentina`). Case-insensitive.

Output Schema

NameRequiredDescription
asOfYesYYYY-MM-DD (US Pacific) the statuses were evaluated for.
countYes
filtersYes
resortsYes
generatedAtYesISO-8601 UTC instant the result was generated.
totalMatchingYesResorts that matched before `limit` was applied.

TDQS

A4/5.0
Behavior4/5

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), so the bar is lower, and the description adds real context beyond them: data provenance distinguishing resort-confirmed dates from third-party projections, plus the possible values of the status field. It still does not state refresh cadence or how stale projected dates can be.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, both load-bearing: the first covers scope, status values and ordering; the second covers data provenance. Nothing is repeated and the most important scope information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return shape need not be described. Between the description (scope, ordering, status vocabulary, data provenance) and the fully documented 2-parameter schema, an agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents both parameters in detail, so the baseline is 3. The description adds the behavior of omitting `state` (returns every resort) and the output ordering ('soonest opening first'), neither of which the schema expresses; only `limit` receives no additional explanation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (opening/closing dates per resort) plus the returned status values and sort order, which is far more than a restatement of the name. It does not explicitly name or contrast any sibling tool, so an agent infers distinctness from the resource alone rather than being routed.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The scope clause ('for every resort, or those in one state/province') implies when to pass `state` versus leaving it out, which is genuine usage guidance. There is no when-not-to-use guidance and no mention of alternatives such as get_resort_conditions or get_forecast when the agent actually wants live status rather than season dates.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_percent_of_normalPercent of normalA
Read-onlyIdempotent
Inspect

SNOTEL-fed resorts ranked by snowpack relative to normal: snow water equivalent against the station's own 1991–2020 median for today's date, deepest first, optionally within one state. Only measured station readings qualify, inside the 10–300 % band and above 2 in of SWE; early-season noise is withheld, not ranked. Same data as https://www.peakcam.io/snow-report/percent-of-normal.

NameRequiredDescriptionDefault
limitNoRows to return, 1–50.
stateNoUS state or Canadian province code (`CO`, `UT`, `BC`), or for the Andes the country name PeakCam lists (`Chile`, `Argentina`). Case-insensitive.

Output Schema

NameRequiredDescription
asOfYesISO instant of the newest report the ranking used.
ruleYesThe publishable-value rule, in words.
countYes
phaseYes`pre-season`/`early`: nothing rankable yet, see `sentence` for why.
filtersYes
pageUrlYes
resultsYes
sentenceYesThe dated, quotable summary sentence.
generatedAtYesISO-8601 UTC instant the result was generated.
totalMatchingYes
stationFedCountYesResorts whose latest report is a SNOTEL reading (the pool).

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, and the description adds substantial context beyond them: data source (SNOTEL station readings), the normal baseline used (1991–2020 median for today's date), inclusion thresholds (10–300% band, >2 in SWE), the sort order, and what is deliberately withheld from the ranking.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and metric definition are front-loaded in the first clause, and the qualification rules are packed efficiently into the second. Dense with semicolons but no clearly wasted sentence; only the trailing marketing URL is dispensable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description needn't explain return values, and the annotations cover the safety profile. What remains an agent needs — metric definition, sort order, filtering thresholds, and geographic scoping — is all present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are already documented in the schema; baseline 3 applies. The description only restates state scoping ('optionally within one state') and says nothing about the limit parameter or its default/ceiling, adding little beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource+ordering: 'SNOTEL-fed resorts ranked by snowpack relative to normal... deepest first, optionally within one state.' The definition of the metric (SWE vs the station's 1991–2020 median for today's date) distinguishes it clearly from siblings like get_snow_history and compare_resorts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear decision context: measurement-based ranking, optional single-state scoping, and explicit exclusion rules ('early-season noise is withheld, not ranked') that tell the agent when results will be thin or empty. It does not name an alternative sibling (e.g. compare_resorts, get_snow_history) or state when-not to use it, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_resort_camsResort webcamsA
Read-onlyIdempotent
Inspect

The resort's webcams as links: PeakCam page URL, the operator's stream or page URL, a still-image URL when one exists, and health (live / down / unchecked, from PeakCam's probe, not proof of a live broadcast). Frames are never returned inline.

NameRequiredDescriptionDefault
slugYesPeakCam resort slug, lowercase kebab-case, e.g. `breckenridge` or `ski-portillo`. Get it from search_resorts.

Output Schema

NameRequiredDescription
camsYes
nameYes
slugYes
licenseYes
updatedAtYes
attributionYes
canonicalUrlYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, so the bar is lower, and the description still adds real value: it defines the health field's domain (live/down/unchecked) and warns it comes from PeakCam's probe and is 'not proof of a live broadcast.' That caveat prevents a real misinterpretation. It stops short of describing caching, refresh cadence, or behavior when a cam is missing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence front-loads the resource and then enumerates the return fields in a compact colon-separated list. Every clause carries information; only the parenthetical health caveat slightly interrupts the flow.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description is not obliged to explain return values, yet it usefully characterizes them anyway and clarifies the health semantics. For a single-parameter read-only lookup, nothing critical is missing; only explicit routing to the timeline/timelapse siblings would improve it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the single slug parameter is fully documented in the schema (kebab-case format plus the search_resorts pointer). The description adds no parameter detail of its own, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource (the resort's webcams) and enumerates exactly what is returned: PeakCam page URL, operator stream/page URL, still-image URL, and a health flag. That specificity lets an agent distinguish it from siblings like get_cam_timeline and get_timelapses, though it never names those alternatives explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied. The clause 'Frames are never returned inline' hints that an agent wanting actual imagery must go elsewhere, but no sibling tool or condition is named. There is no explicit statement of when to prefer this over get_cam_timeline or get_timelapses.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_resort_conditionsResort conditionsA
Read-onlyIdempotent
Inspect

The latest snow report for one resort with provenance, inside the conditions contract v2 envelope: data.status is the derived operating status (OPEN, CLOSED_TODAY, PRE_SEASON, OFF_SEASON or UNKNOWN; OPEN only on a fresh operator lift feed or a resort-confirmed opening date, never by default) with reasons; every field in data (base depth measured and operator-reported, new snow 24 h / 48 h, SWE, percent of normal, lifts and runs open / total, surface, snow quality, temperature, wind, blended 48-hour forecast, season dates) is {value, source, observedAt, confidence, freshness: {tier, ageHours}}; depthDisagreement is set when the station and the operator differ by more than 30 % (quote the measured value); sentence is a dated line to quote. The classic Resort document (snow, season, cams, profile, measuredNow) rides alongside for compatibility. Use it for "is X open today" as well as "what are conditions at X". Sources: snotel = measured at a USDA NRCS SNOTEL station near the resort (station elevation, not the summit), open_meteo = weather-model estimate for resorts without a station.

NameRequiredDescriptionDefault
slugYesPeakCam resort slug, lowercase kebab-case, e.g. `breckenridge` or `ski-portillo`. Get it from search_resorts.

Output Schema

NameRequiredDescription
camsYes
dataYes
metaYes
nameYes
slugYes
snowYesNull when the resort has never had a snow report.
scoreNoToday's 0–100 Snow Score with components (P7). Null when the scorer has not written a row at most 3 days old; absent only when the score table is not served.
apiUrlYes
seasonYes
licenseYesURL of the terms that govern reuse.
profileYes
forecastNoHeadline numbers from the blended 14-day forecast (summit point when one exists). Null when no run is current; absent on list and compare rows. The full daily blend and every model run are at `/resorts/{slug}/forecast`.
locationYes
sentenceYesA dated, source-labelled status sentence that can be quoted verbatim.
stationsNoObservation stations serving the resort, once the station layer is live.
schemaUrlYesThe JSON Schema this document validates against.
updatedAtYesNewest instant among the snow report and cam checks/captures.
websiteUrlYes
attributionYes
measuredNowNoLatest observation per station, once the station layer is live.
canonicalUrlYesThe resort's PeakCam page. Cite this.
schemaVersionYesContract version; the schema file name carries the major.
forecastScoresNoPer-model verification at this resort over 90 days, ranked; empty until the scorer has measured days. Detail at `/resorts/{slug}/forecast-accuracy`.

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish the safe read-only profile, and the description adds substantial behavioral detail beyond them: the OPEN-only-on-fresh-feed rule, the meaning of UNKNOWN, the 30% depthDisagreement trigger, what `sentence` is for, and the distinction between snotel (measured, station elevation not summit) and open_meteo (model estimate) sources.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence front-loads the purpose well, but the body enumerates nearly every field inside `data` and the legacy Resort document even though an output schema exists — that detail is largely duplicated in structured data. Dense parenthetical packing makes it heavier than it needs to be.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter, read-only tool with a full output schema and covering annotations, an agent has everything needed to call it correctly, and the status/source semantics are genuinely useful. It over-delivers on return-value detail rather than leaving gaps, so completeness is high but not perfectly matched to what the schema already provides.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single `slug` parameter is fully documented in the schema (100% coverage) including kebab-case format and where to obtain it. The description adds no parameter-specific guidance, so it relies on the schema baseline of 3; the source-type explanation is about returned data, not the input.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('latest snow report for one resort'), plus the envelope shape it returns (conditions contract v2). It is clearly distinguishable from siblings like get_resort_profile, get_snow_history, or compare_resorts because it is scoped to a single resort's current conditions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names two triggering questions: "is X open today" and "what are conditions at X", and tells the agent where the required slug comes from (search_resorts). It does not name alternative siblings (e.g., get_forecast for future outlook, get_snow_history for past), so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_resort_profileResort profileA
Read-onlyIdempotent
Inspect

Who and where a resort is, without the snow numbers: location and elevations, website and social links, PeakCam's cam page, the SNOTEL station its numbers come from (if any), season status, cam counts, and every URL PeakCam publishes for it (page, JSON, markdown, Atom feed, state hub). Use get_resort_conditions for today's snow.

NameRequiredDescriptionDefault
slugYesPeakCam resort slug, lowercase kebab-case, e.g. `breckenridge` or `ski-portillo`. Get it from search_resorts.

Output Schema

NameRequiredDescription
nameYes
slugYes
urlsYes
seasonYes
socialsYes
stationYesThe NRCS station PeakCam reads for this resort; null means model estimates.
camCountYes
locationYes
camPageUrlYesThe operator's own webcam page, when PeakCam records one.
dataSourceYesSource of the latest snow report, so you know which label to use.
websiteUrlYesThe operator's site.
generatedAtYesISO-8601 UTC instant the result was generated.
canonicalUrlYesThe resort's PeakCam page. Cite this.
liveCamCountYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, non-destructive, and closed-world, so the safety profile is covered. The description adds genuine behavioral context beyond them: it signals that the SNOTEL station may be absent ('if any') and that the response includes a full set of published URL variants. It does not mention auth or rate limits, which is a minor gap for a read tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The scope statement is front-loaded and the routing sentence is short and purposeful. The long mid-sentence enumeration is dense but every listed field is informative for tool selection, so it mostly earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not explain return values, yet it usefully summarizes them for selection purposes. Combined with full annotation coverage and a 100%-documented schema, an agent has everything needed to call it correctly; only operational details like auth or rate limits are absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single slug parameter is fully documented in the schema, including format and the search_resorts sourcing hint. The description adds no parameter-level detail, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource (resort profile) and enumerates exactly what it contains: location, elevations, links, SNOTEL station, season status, cam counts, and published URLs. It explicitly carves out the scope it does NOT cover ('without the snow numbers'), which cleanly separates it from get_resort_conditions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It routes the agent explicitly: 'Use get_resort_conditions for today's snow,' giving both the alternative and the condition that selects it. The negative scoping phrase also tells the agent when not to reach for this tool for snow data, so 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.

get_scoreSnow ScoreA
Read-onlyIdempotent
Inspect

PeakCam's 0–100 Snow Score for one resort, scored once a day by a fixed formula (scoredBy is always algorithmic): today carries the score, its four-tier rating (great ≥ 75, good ≥ 55, fair ≥ 35, else poor; the same words as the conditions rating), a dated tagline to quote and five components, each with points, max, a one-line basis and its source: depth vs the station's 1991–2020 normal (30), new snow over the last 7 days (25), the blended 7-day forecast (20), snow quality from days since snow, the 3-day high and the surface tags (15), and the operating status (10). history is one point per scored day over the last 30 days. Use it for "how good is X right now and why", "score X out of 100", "is X better than last week"; for a ranking use find_powder, compare_resorts or /api/v1/snow-report?sort=score. available: false before the first scoring run.

NameRequiredDescriptionDefault
slugYesPeakCam resort slug, lowercase kebab-case, e.g. `breckenridge` or `ski-portillo`. Get it from search_resorts.

Output Schema

NameRequiredDescription
daysYesThe history window, days.
nameYes
slugYes
todayYesThe newest score at most 3 days old, else null.
apiUrlYesThis document.
ladderYesScore at or above each cutoff earns the label; below `fair` is `poor`.
historyYesOne point per scored day over the trailing window, oldest first.
licenseYes
pageUrlYesWhere the score ring and sparkline render.
versionYes
weightsYes
scoredByYes
sentenceYesThe dated tagline, or why there is no score.
availableYesFalse when the scorer has not written a row for this resort yet (or the table is not served).
attributionYes
generatedAtYes
canonicalUrlYes
methodologyUrlYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this is a safe, idempotent read, and the description adds substantial context beyond them: the daily scoring cadence, fixed formula with scoredBy always 'algorithmic', the tier thresholds, the five weighted components, and the 'available: false before the first scoring run' edge case. That is rich behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core definition, then tier thresholds, component weights, and finally use cases. It is a single dense paragraph but nearly every clause carries distinct information; slightly heavy for the size but not wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description needn't detail return values, yet it usefully previews the score/history structure and the unavailability state. For a one-param read tool, nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a single documented slug parameter, so the schema carries the parameter burden. The description adds no syntax or format detail beyond what the schema provides (kebab-case, from search_resorts), so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: PeakCam's 0–100 Snow Score for one resort, scored once daily by a fixed formula, and explicitly distinguishes itself from ranking tools (find_powder, compare_resorts). An agent can tell exactly what value this returns 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit trigger phrases ('how good is X right now and why', 'score X out of 100', 'is X better than last week') and names the alternatives for a ranking use case (find_powder, compare_resorts, /api/v1/snow-report?sort=score). When-to-use and when-to-use-something-else are both covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_season_statsSeason statsA
Read-onlyIdempotent
Inspect

Season-to-date for one resort from PeakCam's own daily station record: measured snowfall since the season start (daily new snow = the positive change in station depth, a floor on what fell), days measured, snow days, powder days (8 in or more, the alert threshold), current and deepest base, percent of the 30-winter normal to this day and of the recent decade (with a baselineNote when they disagree by more than 10 %), the same day last year, a 7-day trend and a dated sentence to quote. Use it for "how is the season going", "is this a good year", "how does it compare with last year".

NameRequiredDescriptionDefault
slugYesPeakCam resort slug, lowercase kebab-case, e.g. `breckenridge`. Get it from search_resorts.

Output Schema

NameRequiredDescription
asOfYesYYYY-MM-DD of the newest daily reading this season.
nameYes
slugYes
trendYes
apiUrlYes
seasonYes
sourceYes
licenseYes
pageUrlYes
stationYes
lastYearYes
sentenceYesA dated sentence that can be quoted verbatim.
snowDaysYes
availableYes
hemisphereYes
powderDaysYes
attributionYes
dayOfSeasonYes
deepestBaseYes
generatedAtYes
canonicalUrlYes
daysMeasuredYes
currentBaseInYes
seasonToDateInYes
percentOfNormalYes
powderDayThresholdInYes

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (which only establish a safe, idempotent read), the description discloses methodology and caveats: daily new snow is the positive change in station depth and is 'a floor on what fell', powder days use the 8-inch alert threshold, and baselineNote appears when the 30-winter and decade normals disagree by more than 10%. This is exactly the behavioral context an agent needs to interpret the numbers honestly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with what it returns and packed densely; the long enumerative sentence is justified by the many distinct metrics, and the usage sentence is short. It is a run-on, but virtually every clause carries information, so little is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although an output schema exists and return values could be left to it, the description goes further and explains metric definitions, comparison baselines, and the trend/quotable sentence, which is complete for a single-resort read tool with all safety traits already covered by annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is a single slug parameter and schema coverage is 100%, with the schema itself documenting the format and pointing to search_resorts. The description adds no additional parameter meaning, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the exact resource ('Season-to-date for one resort'), the data source ('PeakCam's own daily station record'), and enumerates the specific metrics returned, so an agent knows precisely what it retrieves. It does not, however, explicitly differentiate itself from close siblings such as get_snow_history, get_percent_of_normal, or get_monthly_climatology, leaving the agent to infer the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete trigger questions ('how is the season going', 'is this a good year', 'how does it compare with last year') that map cleanly to intent. It stops short of naming alternatives or exclusions, so the routing against get_percent_of_normal / get_snow_history is not spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_snow_historySnow historyA
Read-onlyIdempotent
Inspect

Daily snow depth, snow water equivalent, precipitation accumulation and temperatures for the last 1–30 days at the resort's station (SNOTEL where there is one, Open-Meteo model otherwise), newest first. Use it for "how has the base changed this week" questions. Pass season (2024-25, or current) for a whole season's daily depth and new-snow rows instead of the last N days; get_season_stats summarises a season.

NameRequiredDescriptionDefault
daysNoDays back, 1–30. Ignored when `season` is set.
slugYesPeakCam resort slug, lowercase kebab-case, e.g. `breckenridge` or `ski-portillo`. Get it from search_resorts.
seasonNoA season label (`2024-25` for the Northern water year, `2026` for an Andes resort) or `current`: returns every daily row of that season, oldest first, with daily new snow.

Output Schema

NameRequiredDescription
daysYes
nameYes
rowsYes
slugYes
countYes
seasonYesThe season label when `season` was asked for; null for a last-N-days read.
sourceYes
stationYes
generatedAtYesISO-8601 UTC instant the result was generated.
canonicalUrlYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, idempotentHint, destructiveHint=false), so the description's added value is the station provenance (SNOTEL where available, otherwise Open-Meteo model) and the ordering difference between the days view (newest first) and the season view (oldest first). These are real behavioral details not derivable from 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but well-structured: the payload is front-loaded, then the usage case, then the parameter/sibling routing. Every sentence earns its place, though the parenthetical source detail and the routing clause make it slightly long for the amount of schema support available.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present (so return values need no prose) and annotations covering the safety profile, the description supplies the remaining essentials: what data, from which source, in what order, and how the season path differs. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description goes further by explaining the days/season interaction (season returns every daily row of the season with new snow, superseding the last-N-days window) rather than merely restating the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (daily snow depth, SWE, precipitation, temperatures) with explicit scope (last 1–30 days at the resort's station), data provenance (SNOTEL vs Open-Meteo model), and ordering (newest first). An agent can distinguish this from get_season_stats and get_forecast 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.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete when-to-use case ("how has the base changed this week") and routes the agent to the right sibling for season summaries (get_season_stats) and to the `season` parameter for whole-season rows. It stops short of an explicit when-not (e.g. vs. get_forecast for future snow), so it is clear but not fully closed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_stationsNearby stationsA
Read-onlyIdempotent
Inspect

What the instruments near one resort measured, by elevation band (summit / mid / base): up to three stations within 25 km with the network named (SNOTEL, GHCN-Daily, NWS, BC ASWS, ECCC), elevation, distance, the time of the reading and its age, snow depth, new snow, SWE, temperature and wind. Daily networks carry depth; hourly ones carry temperature and wind. Use it for "what is it like at the top right now" and "how old is that number" questions; the snow report itself comes from get_resort_conditions.

NameRequiredDescriptionDefault
slugYesPeakCam resort slug, lowercase kebab-case, e.g. `breckenridge` or `ski-portillo`. Get it from search_resorts.

Output Schema

NameRequiredDescription
nameYes
slugYes
countYes
sourcesYes
stationsYes
availableYesFalse when the station layer is not populated for this deployment yet.
generatedAtYesISO-8601 UTC instant the result was generated.
measuredNowYes
canonicalUrlYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only/idempotent/closed-world, so the bar is low, yet the description adds rich operational context: the 3-station and 25 km caps, the elevation-band grouping, the named networks, and the key data-availability rule that daily networks carry depth while hourly ones carry temperature and wind.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core payload (what is measured, scope, bands) before the data-availability rule and usage examples. It is dense but every clause carries operational meaning; slightly long, which keeps it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

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 description covers scope, limits, fields, network behavior, and sibling routing. An agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Single parameter with 100% schema description coverage that fully documents the slug format and its source (search_resorts). The description adds no slug detail beyond the schema, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (what instruments measured) and resource (nearby stations) with precise scope: up to three stations within 25 km, split by elevation band. Explicitly distinguishes itself from get_resort_conditions, so an agent can tell them apart without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names the exact questions it answers ("what is it like at the top right now", "how old is that number") and routes the alternative use case — the snow report — to get_resort_conditions. This is explicit when-to-use plus alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_timelapsesTimelapsesA
Read-onlyIdempotent
Inspect

Rendered timelapse clips for a resort's webcams (or one cam), as links: the rolling 24-hour MP4 per cam (H.264, 7 fps, 720p max, at most 3 MB, re-rendered every 6 hours from PeakCam's still archive) with its poster JPEG and frame bounds, plus storm reels (rendered while the resort's measured 24 h new snow is 8 in or more, from the first frame after the last dry day, capped at 72 h; one per storm day, kept a year). Only cams whose operator allows archiving have clips. Use it for "show me the last 24 hours" or "show me the last storm" questions; get_cam_timeline returns the individual frames. Media is never returned inline.

NameRequiredDescriptionDefault
slugYesPeakCam resort slug, lowercase kebab-case, e.g. `breckenridge` or `ski-portillo`. Get it from search_resorts.
camIdNoOptional: one cam's id from get_resort_cams; default is every cam with a clip.

Output Schema

NameRequiredDescription
camsYesOnly cams with at least one clip, in the resort's cam order.
nameYes
noteYes
slugYes
licenseYes
availableYesFalse when the clip table is not served by this deployment yet.
clipCountYes
lastStormYesThe newest storm reel across the resort's cams.
updatedAtYes
webcamsUrlYesThe resort's webcams page, where the clips play.
attributionYes
canonicalUrlYes
newestRenderedAtYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (readOnly, idempotent, non-destructive), but the description adds substantial behavior beyond them: render cadence (every 6 hours), encoding specs (H.264, 7 fps, 720p, ≤3 MB), storm-reel trigger (>8 in new snow), retention (1 year), the operator-archiving restriction, and the critical note that media is never returned inline.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and the 24-hour clip are front-loaded, and most clauses earn their place (cadence, storm criteria, retention, archiving restriction). The single dense paragraph packs a lot of encoding minutiae (7 fps, 720p, 3 MB) that is useful but borderline for a selection-time description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return-value shape needn't be explained, and the description still covers what a caller needs: links vs. inline media, poster JPEG, frame bounds, and the archiving caveat. Complete for a read-only lookup tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both slug and camId are already documented, including the 'default is every cam' behavior. The description's '(or one cam)' phrasing mirrors the schema without adding new semantics, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Rendered timelapse clips for a resort's webcams') and immediately distinguishes itself from the sibling get_cam_timeline ('returns the individual frames'). An agent can tell the two apart without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit trigger phrases ('show me the last 24 hours' or 'show me the last storm') and names the alternative tool (get_cam_timeline) for the frame-level case. Nothing about when to select this vs. a sibling 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.

list_regionsList regionsA
Read-onlyIdempotent
Inspect

Every state, province and country PeakCam covers, with resort, reporting, measured (SNOTEL) and cam counts and the hub page URL. Call it to learn the valid state values for find_powder, get_opening_dates and get_percent_of_normal, or to answer "where does PeakCam have data".

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
regionsYesMost resorts first.
countriesYes
generatedAtYesISO-8601 UTC instant the result was generated.
totalResortsYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=false and destructiveHint=false, so safety and idempotency are covered structurally. The description adds real context beyond that: the geographic scope (states, provinces, countries) and the specific counts returned, which is what an agent needs to judge whether calling it is worthwhile. It does not restate the annotated safety traits, so no contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with what the tool returns, followed by the concrete reason to call it. Every clause carries information; there is no filler or restatement of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only discovery tool with an output schema, the description supplies everything an agent needs: the scope of the result set, the fields returned, and the downstream tools that consume the returned `state` values. Nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is no per-parameter semantics to explain and the baseline of 4 applies. The description does add meaning about the shape of the result (counts per region plus hub URL) even though the output schema already documents it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (every state, province and country PeakCam covers) and enumerates exactly what it returns: resort, reporting, SNOTEL and cam counts plus the hub page URL. That granularity lets an agent distinguish it from sibling lookups like search_resorts or get_resort_profile 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit trigger ('call it to learn the valid `state` values for find_powder, get_opening_dates and get_percent_of_normal') and a natural-language use case ('where does PeakCam have data'). It names the three dependent siblings by name, so the routing decision is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_resortsSearch resortsA
Read-onlyIdempotent
Inspect

Find PeakCam resorts by name (or part of one, or a region) and get their slugs with a one-line snow summary each. Call this first when the user names a resort; then use the slug with the other tools. Covers about 300 resorts in the US, Canada, Chile and Argentina.

NameRequiredDescriptionDefault
limitNoRows to return, 1–20.
queryYesResort name or fragment, e.g. `vail`, `big sky`, `portillo`, `tahoe`. Also matches region names.
stateNoUS state or Canadian province code (`CO`, `UT`, `BC`), or for the Andes the country name PeakCam lists (`Chile`, `Argentina`). Case-insensitive.
countryNoISO 3166-1 alpha-2 country code: `US`, `CA`, `CL` or `AR`.

Output Schema

NameRequiredDescription
countYes
queryYes
resortsYes
generatedAtYesISO-8601 UTC instant the result was generated.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive, closed-world, so the safety profile is covered. The description adds useful scope context the annotations cannot convey: ~300 resorts and the four countries covered, plus the fact that matching is fuzzy (name fragment or region). No rate-limit or pagination behavior, but little is left ambiguous.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the action and return value, followed by the workflow instruction and the coverage scope. No filler; every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description needn't explain return shape, and it still summarizes the snow-summary payload. Annotations cover safety, schema covers all params, and the description adds scope plus the call-order cue — 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.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters (query, limit, state, country) are already documented with examples and ranges. The description restates the fuzzy-name/region matching that the query param already documents, adding no new syntax or format guidance. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Find PeakCam resorts by name... and get their slugs') plus the returned payload ('one-line snow summary each'). This distinguishes it from siblings like list_regions (browsing) and get_resort_profile (detail by slug).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit sequencing: 'Call this first when the user names a resort; then use the slug with the other tools' — this is real routing guidance for the multi-tool workflow. It doesn't name an alternative for the case where the user does NOT name a resort (list_regions would be the natural fallback), so it stops short of full when/when-not coverage.

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.

  1. 5 tool updates
    • Changedcompare_resorts2 fields changed
      • changedOutput schema / properties / resorts / items / properties / score / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "components": {
        -        "additionalProperties": {
        -          "anyOf": [
        -            {
        -              "type": "number"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ]
        -        },
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "date": {
        -        "description": "YYYY-MM-DD the score is for.",
        -        "type": "string"
        -      },
        -      "rating": {
        -        "anyOf": [
        -          {
        -            "enum": [
        -              "great",
        -              "good",
        -              "fair",
        -              "poor"
        -            ],
        -            "type": "string"
        -          },
        -          {
        -            "type": "null"
        -          }
        -        ]
        -      },
        -      "score": {
        -        "maximum": 100,
        -        "minimum": 0,
        -        "type": "integer"
        -      },
        -      "scoredBy": {
        -        "anyOf": [
        -          {
        -            "type": "string"
        -          },
        -          {
        -            "type": "null"
        -          }
        -        ],
        -        "description": "Scorer version, e.g. `score-v1`."
        -      }
        -    },
        -    "required": [
        -      "date",
        -      "score",
        -      "rating",
        -      "components",
        -      "scoredBy"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "components": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "depthVsNormal": {
        +            "additionalProperties": false,
        +            "description": "30: snowpack against the station's 1991–2020 median (SWE); without a normal, base depth on a fixed scale capped at 27.",
        +            "properties": {
        +              "basis": {
        +                "description": "One line saying what the points rest on, quotable as is.",
        +                "type": "string"
        +              },
        +              "max": {
        +                "description": "The component's weight; the five maximums add to 100.",
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              },
        +              "points": {
        +                "description": "Points earned, one decimal.",
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "source": {
        +                "enum": [
        +                  "snotel",
        +                  "model",
        +                  "operator",
        +                  "profile",
        +                  "derived",
        +                  "none"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "points",
        +              "max",
        +              "basis",
        +              "source"
        +            ],
        +            "type": "object"
        +          },
        +          "forecast7d": {
        +            "additionalProperties": false,
        +            "description": "20: the blended next-7-day forecast total (20 in is full marks).",
        +            "properties": {
        +              "basis": {
        +                "description": "One line saying what the points rest on, quotable as is.",
        +                "type": "string"
        +              },
        +              "max": {
        +                "description": "The component's weight; the five maximums add to 100.",
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              },
        +              "points": {
        +                "description": "Points earned, one decimal.",
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "source": {
        +                "enum": [
        +                  "snotel",
        +                  "model",
        +                  "operator",
        +                  "profile",
        +                  "derived",
        +                  "none"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "points",
        +              "max",
        +              "basis",
        +              "source"
        +            ],
        +            "type": "object"
        +          },
        +          "operatingStatus": {
        +            "additionalProperties": false,
        +            "description": "10: OPEN full, PRE_SEASON and CLOSED_TODAY half, OFF_SEASON and UNKNOWN none.",
        +            "properties": {
        +              "basis": {
        +                "description": "One line saying what the points rest on, quotable as is.",
        +                "type": "string"
        +              },
        +              "max": {
        +                "description": "The component's weight; the five maximums add to 100.",
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              },
        +              "points": {
        +                "description": "Points earned, one decimal.",
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "source": {
        +                "enum": [
        +                  "snotel",
        +                  "model",
        +                  "operator",
        +                  "profile",
        +                  "derived",
        +                  "none"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "points",
        +              "max",
        +              "basis",
        +              "source"
        +            ],
        +            "type": "object"
        +          },
        +          "recentSnow7d": {
        +            "additionalProperties": false,
        +            "description": "25: measured or modelled new snow over the last 7 days (24 in is full marks).",
        +            "properties": {
        +              "basis": {
        +                "description": "One line saying what the points rest on, quotable as is.",
        +                "type": "string"
        +              },
        +              "max": {
        +                "description": "The component's weight; the five maximums add to 100.",
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              },
        +              "points": {
        +                "description": "Points earned, one decimal.",
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "source": {
        +                "enum": [
        +                  "snotel",
        +                  "model",
        +                  "operator",
        +                  "profile",
        +                  "derived",
        +                  "none"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "points",
        +              "max",
        +              "basis",
        +              "source"
        +            ],
        +            "type": "object"
        +          },
        +          "snowQuality": {
        +            "additionalProperties": false,
        +            "description": "15: days since the last snow day × the 3-day high temperature × the engine's surface tags.",
        +            "properties": {
        +              "basis": {
        +                "description": "One line saying what the points rest on, quotable as is.",
        +                "type": "string"
        +              },
        +              "max": {
        +                "description": "The component's weight; the five maximums add to 100.",
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              },
        +              "points": {
        +                "description": "Points earned, one decimal.",
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "source": {
        +                "enum": [
        +                  "snotel",
        +                  "model",
        +                  "operator",
        +                  "profile",
        +                  "derived",
        +                  "none"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "points",
        +              "max",
        +              "basis",
        +              "source"
        +            ],
        +            "type": "object"
        +          }
        +        },
        +        "required": [
        +          "depthVsNormal",
        +          "recentSnow7d",
        +          "forecast7d",
        +          "snowQuality",
        +          "operatingStatus"
        +        ],
        +        "type": "object"
        +      },
        +      "date": {
        +        "description": "YYYY-MM-DD the score is for (Mountain-time day of the scoring run).",
        +        "type": "string"
        +      },
        +      "rating": {
        +        "description": "The score's four-tier label: great ≥ 75, good ≥ 55, fair ≥ 35, else poor.",
        +        "enum": [
        +          "great",
        +          "good",
        +          "fair",
        +          "poor"
        +        ],
        +        "type": "string"
        +      },
        +      "score": {
        +        "maximum": 100,
        +        "minimum": 0,
        +        "type": "integer"
        +      },
        +      "scoredBy": {
        +        "const": "algorithmic",
        +        "description": "Always `algorithmic`: a fixed function of measured and modelled inputs, never an editorial call.",
        +        "type": "string"
        +      },
        +      "tagline": {
        +        "description": "Dated sentence to quote: the score, its rating and the components strongest first.",
        +        "type": "string"
        +      },
        +      "version": {
        +        "description": "Formula version, e.g. `score-v1`; a change re-scores the history.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date",
        +      "score",
        +      "rating",
        +      "tagline",
        +      "components",
        +      "scoredBy",
        +      "version"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / properties / resorts / items / properties / score / description
        Previous value: -"Today's 0–100 score, once the scorer is live."New value: +"Today's 0–100 Snow Score with components (P7). Null when the scorer has not written a row at most 3 days old; absent only when the score table is not served."
    • Changedfind_powder1 field changed
      • addedOutput schema / properties / results / items / properties / score
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": false,
        +      "properties": {
        +        "date": {
        +          "description": "YYYY-MM-DD.",
        +          "type": "string"
        +        },
        +        "rating": {
        +          "enum": [
        +            "great",
        +            "good",
        +            "fair",
        +            "poor"
        +          ],
        +          "type": "string"
        +        },
        +        "score": {
        +          "maximum": 100,
        +          "minimum": 0,
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "date",
        +        "score",
        +        "rating"
        +      ],
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Today's Snow Score (P7), when the caller loaded the score index."
        +}
    • Changedget_resort_conditions2 fields changed
      • changedOutput schema / properties / score / anyOf
        Previous value: -[
        -  {
        -    "additionalProperties": false,
        -    "properties": {
        -      "components": {
        -        "additionalProperties": {
        -          "anyOf": [
        -            {
        -              "type": "number"
        -            },
        -            {
        -              "type": "null"
        -            }
        -          ]
        -        },
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "date": {
        -        "description": "YYYY-MM-DD the score is for.",
        -        "type": "string"
        -      },
        -      "rating": {
        -        "anyOf": [
        -          {
        -            "enum": [
        -              "great",
        -              "good",
        -              "fair",
        -              "poor"
        -            ],
        -            "type": "string"
        -          },
        -          {
        -            "type": "null"
        -          }
        -        ]
        -      },
        -      "score": {
        -        "maximum": 100,
        -        "minimum": 0,
        -        "type": "integer"
        -      },
        -      "scoredBy": {
        -        "anyOf": [
        -          {
        -            "type": "string"
        -          },
        -          {
        -            "type": "null"
        -          }
        -        ],
        -        "description": "Scorer version, e.g. `score-v1`."
        -      }
        -    },
        -    "required": [
        -      "date",
        -      "score",
        -      "rating",
        -      "components",
        -      "scoredBy"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]New value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "components": {
        +        "additionalProperties": false,
        +        "properties": {
        +          "depthVsNormal": {
        +            "additionalProperties": false,
        +            "description": "30: snowpack against the station's 1991–2020 median (SWE); without a normal, base depth on a fixed scale capped at 27.",
        +            "properties": {
        +              "basis": {
        +                "description": "One line saying what the points rest on, quotable as is.",
        +                "type": "string"
        +              },
        +              "max": {
        +                "description": "The component's weight; the five maximums add to 100.",
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              },
        +              "points": {
        +                "description": "Points earned, one decimal.",
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "source": {
        +                "enum": [
        +                  "snotel",
        +                  "model",
        +                  "operator",
        +                  "profile",
        +                  "derived",
        +                  "none"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "points",
        +              "max",
        +              "basis",
        +              "source"
        +            ],
        +            "type": "object"
        +          },
        +          "forecast7d": {
        +            "additionalProperties": false,
        +            "description": "20: the blended next-7-day forecast total (20 in is full marks).",
        +            "properties": {
        +              "basis": {
        +                "description": "One line saying what the points rest on, quotable as is.",
        +                "type": "string"
        +              },
        +              "max": {
        +                "description": "The component's weight; the five maximums add to 100.",
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              },
        +              "points": {
        +                "description": "Points earned, one decimal.",
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "source": {
        +                "enum": [
        +                  "snotel",
        +                  "model",
        +                  "operator",
        +                  "profile",
        +                  "derived",
        +                  "none"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "points",
        +              "max",
        +              "basis",
        +              "source"
        +            ],
        +            "type": "object"
        +          },
        +          "operatingStatus": {
        +            "additionalProperties": false,
        +            "description": "10: OPEN full, PRE_SEASON and CLOSED_TODAY half, OFF_SEASON and UNKNOWN none.",
        +            "properties": {
        +              "basis": {
        +                "description": "One line saying what the points rest on, quotable as is.",
        +                "type": "string"
        +              },
        +              "max": {
        +                "description": "The component's weight; the five maximums add to 100.",
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              },
        +              "points": {
        +                "description": "Points earned, one decimal.",
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "source": {
        +                "enum": [
        +                  "snotel",
        +                  "model",
        +                  "operator",
        +                  "profile",
        +                  "derived",
        +                  "none"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "points",
        +              "max",
        +              "basis",
        +              "source"
        +            ],
        +            "type": "object"
        +          },
        +          "recentSnow7d": {
        +            "additionalProperties": false,
        +            "description": "25: measured or modelled new snow over the last 7 days (24 in is full marks).",
        +            "properties": {
        +              "basis": {
        +                "description": "One line saying what the points rest on, quotable as is.",
        +                "type": "string"
        +              },
        +              "max": {
        +                "description": "The component's weight; the five maximums add to 100.",
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              },
        +              "points": {
        +                "description": "Points earned, one decimal.",
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "source": {
        +                "enum": [
        +                  "snotel",
        +                  "model",
        +                  "operator",
        +                  "profile",
        +                  "derived",
        +                  "none"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "points",
        +              "max",
        +              "basis",
        +              "source"
        +            ],
        +            "type": "object"
        +          },
        +          "snowQuality": {
        +            "additionalProperties": false,
        +            "description": "15: days since the last snow day × the 3-day high temperature × the engine's surface tags.",
        +            "properties": {
        +              "basis": {
        +                "description": "One line saying what the points rest on, quotable as is.",
        +                "type": "string"
        +              },
        +              "max": {
        +                "description": "The component's weight; the five maximums add to 100.",
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              },
        +              "points": {
        +                "description": "Points earned, one decimal.",
        +                "minimum": 0,
        +                "type": "number"
        +              },
        +              "source": {
        +                "enum": [
        +                  "snotel",
        +                  "model",
        +                  "operator",
        +                  "profile",
        +                  "derived",
        +                  "none"
        +                ],
        +                "type": "string"
        +              }
        +            },
        +            "required": [
        +              "points",
        +              "max",
        +              "basis",
        +              "source"
        +            ],
        +            "type": "object"
        +          }
        +        },
        +        "required": [
        +          "depthVsNormal",
        +          "recentSnow7d",
        +          "forecast7d",
        +          "snowQuality",
        +          "operatingStatus"
        +        ],
        +        "type": "object"
        +      },
        +      "date": {
        +        "description": "YYYY-MM-DD the score is for (Mountain-time day of the scoring run).",
        +        "type": "string"
        +      },
        +      "rating": {
        +        "description": "The score's four-tier label: great ≥ 75, good ≥ 55, fair ≥ 35, else poor.",
        +        "enum": [
        +          "great",
        +          "good",
        +          "fair",
        +          "poor"
        +        ],
        +        "type": "string"
        +      },
        +      "score": {
        +        "maximum": 100,
        +        "minimum": 0,
        +        "type": "integer"
        +      },
        +      "scoredBy": {
        +        "const": "algorithmic",
        +        "description": "Always `algorithmic`: a fixed function of measured and modelled inputs, never an editorial call.",
        +        "type": "string"
        +      },
        +      "tagline": {
        +        "description": "Dated sentence to quote: the score, its rating and the components strongest first.",
        +        "type": "string"
        +      },
        +      "version": {
        +        "description": "Formula version, e.g. `score-v1`; a change re-scores the history.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "date",
        +      "score",
        +      "rating",
        +      "tagline",
        +      "components",
        +      "scoredBy",
        +      "version"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / properties / score / description
        Previous value: -"Today's 0–100 score, once the scorer is live."New value: +"Today's 0–100 Snow Score with components (P7). Null when the scorer has not written a row at most 3 days old; absent only when the score table is not served."
    • Addedget_score
    • Changedsearch_resorts1 field changed
      • addedOutput schema / properties / resorts / items / properties / score
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": false,
        +      "properties": {
        +        "date": {
        +          "description": "YYYY-MM-DD.",
        +          "type": "string"
        +        },
        +        "rating": {
        +          "enum": [
        +            "great",
        +            "good",
        +            "fair",
        +            "poor"
        +          ],
        +          "type": "string"
        +        },
        +        "score": {
        +          "maximum": 100,
        +          "minimum": 0,
        +          "type": "integer"
        +        }
        +      },
        +      "required": [
        +        "date",
        +        "score",
        +        "rating"
        +      ],
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Today's Snow Score (P7); null before the first scoring run, absent when the table is not served. Components at `/resorts/{slug}/score-components`."
        +}
  2. 1 tool update
    • Changedget_resort_conditions6 fields changed
      • addedOutput schema / properties / data
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "baseDepthIn": {
        +      "additionalProperties": false,
        +      "description": "Measured (or model) base depth from the snow report, inches. Prefer this over `operatorBaseDepthIn`.",
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "depthDisagreement": {
        +      "anyOf": [
        +        {
        +          "additionalProperties": false,
        +          "properties": {
        +            "differencePct": {
        +              "description": "|measured − operator| as a percent of the larger value; present only above 30 %.",
        +              "type": "number"
        +            },
        +            "measuredIn": {
        +              "type": "number"
        +            },
        +            "note": {
        +              "type": "string"
        +            },
        +            "operatorIn": {
        +              "type": "number"
        +            },
        +            "preferred": {
        +              "const": "measured",
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "measuredIn",
        +            "operatorIn",
        +            "differencePct",
        +            "preferred",
        +            "note"
        +          ],
        +          "type": "object"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "forecastNext48hCm": {
        +      "additionalProperties": false,
        +      "description": "Blended forecast snowfall over the next 48 h, cm (P4 blend, summit point).",
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "liftsOpen": {
        +      "additionalProperties": false,
        +      "description": "Lifts open per the operator feed.",
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "liftsTotal": {
        +      "additionalProperties": false,
        +      "description": "From the operator feed when it lists lifts, else the profile total.",
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "newSnow24hIn": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "newSnow48hIn": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "operatorBaseDepthIn": {
        +      "additionalProperties": false,
        +      "description": "The operator's own base figure, when a feed carries one.",
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "percentOfNormal": {
        +      "additionalProperties": false,
        +      "description": "SWE against the station's 1991–2020 median, inside the publishable band.",
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "reasons": {
        +      "description": "Why the status and the verdict came out as they did, in order; quote them.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "recommendableToday": {
        +      "description": "True only when the status is OPEN on a usable source, a current base depth is on file and the rating is not poor.",
        +      "type": "boolean"
        +    },
        +    "runsOpen": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "runsTotal": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "seasonClosing": {
        +      "additionalProperties": false,
        +      "description": "YYYY-MM-DD, mainly Southern-hemisphere rows.",
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "seasonOpening": {
        +      "additionalProperties": false,
        +      "description": "YYYY-MM-DD. Source `operator` for a resort-confirmed date, `profile` for a third-party projection.",
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "snowQuality": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "enum": [
        +                "powder",
        +                "packed",
        +                "spring",
        +                "ice"
        +              ],
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "status": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "enum": [
        +                "OPEN",
        +                "CLOSED_TODAY",
        +                "PRE_SEASON",
        +                "OFF_SEASON",
        +                "UNKNOWN"
        +              ],
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "surface": {
        +      "additionalProperties": false,
        +      "description": "Operator-reported surface, when a feed carries one.",
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "sweIn": {
        +      "additionalProperties": false,
        +      "description": "Snow water equivalent, inches.",
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "tempF": {
        +      "additionalProperties": false,
        +      "description": "The highest station with a temperature (summit first).",
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    },
        +    "windMph": {
        +      "additionalProperties": false,
        +      "properties": {
        +        "confidence": {
        +          "description": "0–1: SNOTEL 0.9, other stations 0.8, operator 0.7, profile 0.6, derived 0.6, model 0.5; halved when stale, 0 when unknown.",
        +          "maximum": 1,
        +          "minimum": 0,
        +          "type": "number"
        +        },
        +        "freshness": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "ageHours": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Hours between the observation and `generatedAt`, one decimal; null for static facts and empty fields."
        +            },
        +            "tier": {
        +              "enum": [
        +                "live",
        +                "recent",
        +                "estimated",
        +                "stale",
        +                "unknown"
        +              ],
        +              "type": "string"
        +            }
        +          },
        +          "required": [
        +            "tier",
        +            "ageHours"
        +          ],
        +          "type": "object"
        +        },
        +        "observedAt": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "ISO-8601 instant the value was observed or published; null for static facts and empty fields."
        +        },
        +        "source": {
        +          "enum": [
        +            "snotel",
        +            "station:snotel",
        +            "station:ghcn",
        +            "station:nws",
        +            "station:bc_asws",
        +            "station:eccc",
        +            "operator",
        +            "model",
        +            "profile",
        +            "derived",
        +            "none"
        +          ],
        +          "type": "string"
        +        },
        +        "value": {
        +          "anyOf": [
        +            {
        +              "type": "number"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when PeakCam has nothing for this field."
        +        }
        +      },
        +      "required": [
        +        "value",
        +        "source",
        +        "observedAt",
        +        "confidence",
        +        "freshness"
        +      ],
        +      "type": "object"
        +    }
        +  },
        +  "required": [
        +    "status",
        +    "recommendableToday",
        +    "reasons",
        +    "depthDisagreement",
        +    "seasonOpening",
        +    "seasonClosing",
        +    "baseDepthIn",
        +    "operatorBaseDepthIn",
        +    "newSnow24hIn",
        +    "newSnow48hIn",
        +    "sweIn",
        +    "liftsOpen",
        +    "liftsTotal",
        +    "runsOpen",
        +    "runsTotal",
        +    "surface",
        +    "snowQuality",
        +    "tempF",
        +    "windMph",
        +    "forecastNext48hCm",
        +    "percentOfNormal"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / meta
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "freshness": {
        +      "additionalProperties": {
        +        "enum": [
        +          "live",
        +          "recent",
        +          "estimated",
        +          "stale",
        +          "unknown"
        +        ],
        +        "type": "string"
        +      },
        +      "description": "Freshness tier per field.",
        +      "propertyNames": {
        +        "enum": [
        +          "status",
        +          "seasonOpening",
        +          "seasonClosing",
        +          "baseDepthIn",
        +          "operatorBaseDepthIn",
        +          "newSnow24hIn",
        +          "newSnow48hIn",
        +          "sweIn",
        +          "liftsOpen",
        +          "liftsTotal",
        +          "runsOpen",
        +          "runsTotal",
        +          "surface",
        +          "snowQuality",
        +          "tempF",
        +          "windMph",
        +          "forecastNext48hCm",
        +          "percentOfNormal"
        +        ],
        +        "type": "string"
        +      },
        +      "required": [
        +        "status",
        +        "seasonOpening",
        +        "seasonClosing",
        +        "baseDepthIn",
        +        "operatorBaseDepthIn",
        +        "newSnow24hIn",
        +        "newSnow48hIn",
        +        "sweIn",
        +        "liftsOpen",
        +        "liftsTotal",
        +        "runsOpen",
        +        "runsTotal",
        +        "surface",
        +        "snowQuality",
        +        "tempF",
        +        "windMph",
        +        "forecastNext48hCm",
        +        "percentOfNormal"
        +      ],
        +      "type": "object"
        +    },
        +    "generatedAt": {
        +      "type": "string"
        +    },
        +    "localDate": {
        +      "description": "YYYY-MM-DD at the resort when the status was resolved.",
        +      "type": "string"
        +    },
        +    "newestObservationAt": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "The newest `observedAt` across the populated fields."
        +    },
        +    "resolvedAt": {
        +      "description": "ISO instant the status was evaluated at (ages are measured from it).",
        +      "type": "string"
        +    },
        +    "sources": {
        +      "description": "Distinct sources used, best first.",
        +      "items": {
        +        "enum": [
        +          "snotel",
        +          "station:snotel",
        +          "station:ghcn",
        +          "station:nws",
        +          "station:bc_asws",
        +          "station:eccc",
        +          "operator",
        +          "model",
        +          "profile",
        +          "derived",
        +          "none"
        +        ],
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "timeZone": {
        +      "description": "IANA zone the resort's calendar day runs on.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "generatedAt",
        +    "resolvedAt",
        +    "timeZone",
        +    "localDate",
        +    "newestObservationAt",
        +    "freshness",
        +    "sources"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / schemaUrl
        Added value: +{
        +  "description": "The JSON Schema this document validates against.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / schemaVersion
        Added value: +{
        +  "const": "1.0.0",
        +  "description": "Contract version; the schema file name carries the major.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / sentence
        Added value: +{
        +  "description": "A dated, source-labelled status sentence that can be quoted verbatim.",
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "slug",
        -  "name",
        -  "canonicalUrl",
        -  "apiUrl",
        -  "location",
        -  "profile",
        -  "snow",
        -  "season",
        -  "cams",
        -  "websiteUrl",
        -  "attribution",
        -  "license",
        -  "updatedAt"
        -]New value: +[
        +  "slug",
        +  "name",
        +  "canonicalUrl",
        +  "apiUrl",
        +  "location",
        +  "profile",
        +  "snow",
        +  "season",
        +  "cams",
        +  "websiteUrl",
        +  "attribution",
        +  "license",
        +  "updatedAt",
        +  "schemaVersion",
        +  "schemaUrl",
        +  "sentence",
        +  "meta",
        +  "data"
        +]
  3. 3 tool updates
    • Changedget_resort_cams8 fields changed
      • addedOutput schema / properties / cams / items / properties / timelapses / items / properties / bytes
        Added value: +{
        +  "anyOf": [
        +    {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Size of the MP4."
        +}
      • addedOutput schema / properties / cams / items / properties / timelapses / items / properties / endsAt
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Capture time of the last frame (ISO-8601)."
        +}
      • addedOutput schema / properties / cams / items / properties / timelapses / items / properties / frames / description
        Added value: +"Archived frames in the clip; at 7 fps the duration is frames / 7 seconds."
      • addedOutput schema / properties / cams / items / properties / timelapses / items / properties / posterUrl
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Public JPEG of the clip's last frame, the <video> poster. Null for clips rendered before the poster existed."
        +}
      • addedOutput schema / properties / cams / items / properties / timelapses / items / properties / startsAt
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Capture time of the first frame (ISO-8601)."
        +}
      • changedOutput schema / properties / cams / items / properties / timelapses / items / properties / url / description
        Previous value: -"Public MP4 URL."New value: +"Public MP4 URL (H.264, 7 fps, 720p max, at most 3 MB). Link it; never inline it."
      • changedOutput schema / properties / cams / items / properties / timelapses / items / properties / window / description
        Previous value: -"Which clip: `24h` (rolling day), `storm` (one storm, see `stormDate`), or another label."New value: +"Which clip: `24h` (rolling day, replaced every render), `storm` (one storm, see `stormDate`), or another label."
      • changedOutput schema / properties / cams / items / properties / timelapses / items / required
        Previous value: -[
        -  "id",
        -  "window",
        -  "url",
        -  "frames",
        -  "renderedAt",
        -  "stormDate"
        -]New value: +[
        +  "id",
        +  "window",
        +  "url",
        +  "posterUrl",
        +  "frames",
        +  "startsAt",
        +  "endsAt",
        +  "bytes",
        +  "renderedAt",
        +  "stormDate"
        +]
    • Changedget_resort_conditions8 fields changed
      • addedOutput schema / properties / cams / items / properties / timelapses / items / properties / bytes
        Added value: +{
        +  "anyOf": [
        +    {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Size of the MP4."
        +}
      • addedOutput schema / properties / cams / items / properties / timelapses / items / properties / endsAt
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Capture time of the last frame (ISO-8601)."
        +}
      • addedOutput schema / properties / cams / items / properties / timelapses / items / properties / frames / description
        Added value: +"Archived frames in the clip; at 7 fps the duration is frames / 7 seconds."
      • addedOutput schema / properties / cams / items / properties / timelapses / items / properties / posterUrl
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Public JPEG of the clip's last frame, the <video> poster. Null for clips rendered before the poster existed."
        +}
      • addedOutput schema / properties / cams / items / properties / timelapses / items / properties / startsAt
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Capture time of the first frame (ISO-8601)."
        +}
      • changedOutput schema / properties / cams / items / properties / timelapses / items / properties / url / description
        Previous value: -"Public MP4 URL."New value: +"Public MP4 URL (H.264, 7 fps, 720p max, at most 3 MB). Link it; never inline it."
      • changedOutput schema / properties / cams / items / properties / timelapses / items / properties / window / description
        Previous value: -"Which clip: `24h` (rolling day), `storm` (one storm, see `stormDate`), or another label."New value: +"Which clip: `24h` (rolling day, replaced every render), `storm` (one storm, see `stormDate`), or another label."
      • changedOutput schema / properties / cams / items / properties / timelapses / items / required
        Previous value: -[
        -  "id",
        -  "window",
        -  "url",
        -  "frames",
        -  "renderedAt",
        -  "stormDate"
        -]New value: +[
        +  "id",
        +  "window",
        +  "url",
        +  "posterUrl",
        +  "frames",
        +  "startsAt",
        +  "endsAt",
        +  "bytes",
        +  "renderedAt",
        +  "stormDate"
        +]
    • Addedget_timelapses
  4. 8 tool updates
    • Addedcompare_models
    • Changedcompare_resorts7 fields changed
      • addedOutput schema / properties / resorts / items / properties / forecast / anyOf
        Added value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "issuedAt": {
        +        "description": "Newest model issue instant among the runs blended.",
        +        "type": "string"
        +      },
        +      "modelCount": {
        +        "description": "Models contributing to the first day.",
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "models": {
        +        "description": "Every model id that contributed to any day.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "next48hCm": {
        +        "type": "number"
        +      },
        +      "next48hIn": {
        +        "type": "number"
        +      },
        +      "peak": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "cm": {
        +                "type": "number"
        +              },
        +              "date": {
        +                "description": "The day with the most blended snowfall.",
        +                "type": "string"
        +              },
        +              "in": {
        +                "type": "number"
        +              },
        +              "windowDays": {
        +                "description": "Consecutive days around the peak with at least 1 cm (the storm window).",
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              }
        +            },
        +            "required": [
        +              "date",
        +              "in",
        +              "cm",
        +              "windowDays"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Null when no day has any blended snow."
        +      },
        +      "point": {
        +        "description": "The elevation the summary is for: summit when the resort has a summit point, else base.",
        +        "enum": [
        +          "summit",
        +          "base"
        +        ],
        +        "type": "string"
        +      },
        +      "total14dCm": {
        +        "type": "number"
        +      },
        +      "total14dIn": {
        +        "type": "number"
        +      },
        +      "total7dCm": {
        +        "type": "number"
        +      },
        +      "total7dIn": {
        +        "type": "number"
        +      }
        +    },
        +    "required": [
        +      "point",
        +      "issuedAt",
        +      "modelCount",
        +      "models",
        +      "next48hIn",
        +      "next48hCm",
        +      "total7dIn",
        +      "total7dCm",
        +      "total14dIn",
        +      "total14dCm",
        +      "peak"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / properties / resorts / items / properties / forecast / description
        Previous value: -"Latest run per model and point, once stored forecasts are live."New value: +"Headline numbers from the blended 14-day forecast (summit point when one exists). Null when no run is current; absent on list and compare rows. The full daily blend and every model run are at `/resorts/{slug}/forecast`."
      • removedOutput schema / properties / resorts / items / properties / forecast / items
        Removed value: -{
        -  "additionalProperties": false,
        -  "properties": {
        -    "days": {
        -      "items": {
        -        "additionalProperties": false,
        -        "properties": {
        -          "date": {
        -            "description": "YYYY-MM-DD, local to the resort.",
        -            "type": "string"
        -          },
        -          "precipProb": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "0–100."
        -          },
        -          "snowfallCm": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "snowfallHi": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "snowfallLo": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Low end of the spread across models / members; null for a single model."
        -          },
        -          "tempMax": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "°C as the models report it."
        -          },
        -          "tempMin": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "weatherCode": {
        -            "anyOf": [
        -              {
        -                "maximum": 9007199254740991,
        -                "minimum": -9007199254740991,
        -                "type": "integer"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "WMO weather interpretation code."
        -          },
        -          "windGust": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "km/h."
        -          }
        -        },
        -        "required": [
        -          "date",
        -          "snowfallCm",
        -          "snowfallLo",
        -          "snowfallHi",
        -          "tempMax",
        -          "tempMin",
        -          "precipProb",
        -          "windGust",
        -          "weatherCode"
        -        ],
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "horizonDays": {
        -      "maximum": 9007199254740991,
        -      "minimum": -9007199254740991,
        -      "type": "integer"
        -    },
        -    "id": {
        -      "type": "string"
        -    },
        -    "issuedAt": {
        -      "type": "string"
        -    },
        -    "model": {
        -      "description": "Model id as the provider names it, or `blend` for PeakCam's skill-weighted blend.",
        -      "type": "string"
        -    },
        -    "point": {
        -      "enum": [
        -        "summit",
        -        "base"
        -      ],
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "id",
        -    "point",
        -    "model",
        -    "issuedAt",
        -    "horizonDays",
        -    "days"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / properties / resorts / items / properties / forecast / type
        Removed value: -"array"
      • changedOutput schema / properties / resorts / items / properties / forecastScores / description
        Previous value: -"Per-model verification at this resort, once computed."New value: +"Per-model verification at this resort over 90 days, ranked; empty until the scorer has measured days. Detail at `/resorts/{slug}/forecast-accuracy`."
      • addedOutput schema / properties / resorts / items / properties / forecastScores / items / properties / rank
        Added value: +{
        +  "anyOf": [
        +    {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "1 = lowest day-1 MAE among the models scored at this resort (the blend is ranked too). Null before the first scoring run."
        +}
      • changedOutput schema / properties / resorts / items / properties / forecastScores / items / required
        Previous value: -[
        -  "model",
        -  "periodDays",
        -  "day1Mae",
        -  "day3Mae",
        -  "day7Mae",
        -  "samples",
        -  "biasRatio",
        -  "computedAt"
        -]New value: +[
        +  "model",
        +  "periodDays",
        +  "day1Mae",
        +  "day3Mae",
        +  "day7Mae",
        +  "samples",
        +  "biasRatio",
        +  "computedAt",
        +  "rank"
        +]
    • Changedget_forecast24 fields changed
      • addedInput schema / properties / point
        Added value: +{
        +  "default": "summit",
        +  "description": "Which elevation's blend. Falls back to the other point with a note when the asked one has no runs.",
        +  "enum": [
        +    "summit",
        +    "base"
        +  ],
        +  "type": "string"
        +}
      • addedOutput schema / properties / credits
        Added value: +{
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "license": {
        +        "description": "Licence of the source data, e.g. `CC BY 4.0`.",
        +        "type": "string"
        +      },
        +      "name": {
        +        "type": "string"
        +      },
        +      "text": {
        +        "description": "The attribution line to carry with any reuse, e.g. `Weather data by Open-Meteo.com`.",
        +        "type": "string"
        +      },
        +      "url": {
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "name",
        +      "text",
        +      "license",
        +      "url"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / days
        Added value: +{
        +  "description": "Up to 14 blended days.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "condition": {
        +        "description": "PeakCam icon slug for the weather code (`heavy-snow`, `clear`, ...).",
        +        "type": "string"
        +      },
        +      "date": {
        +        "description": "YYYY-MM-DD, local to the resort.",
        +        "type": "string"
        +      },
        +      "modelCount": {
        +        "description": "Models contributing to this day. Falls with lead time as shorter-range models drop out.",
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "models": {
        +        "description": "Model ids contributing to this day.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "precipProb": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "0–100, median of the models that publish one."
        +      },
        +      "snowfallCm": {
        +        "type": "number"
        +      },
        +      "snowfallHiCm": {
        +        "type": "number"
        +      },
        +      "snowfallHiIn": {
        +        "description": "75th percentile across models, inches.",
        +        "type": "number"
        +      },
        +      "snowfallIn": {
        +        "description": "Median across the models that reach this day, inches.",
        +        "type": "number"
        +      },
        +      "snowfallLoCm": {
        +        "type": "number"
        +      },
        +      "snowfallLoIn": {
        +        "description": "25th percentile across models, inches. Equals the median when one model reaches the day.",
        +        "type": "number"
        +      },
        +      "tempMaxF": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "tempMinF": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "weatherCode": {
        +        "anyOf": [
        +          {
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Modal WMO code across models; ties go to the more severe code."
        +      },
        +      "windGustMph": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "date",
        +      "snowfallIn",
        +      "snowfallLoIn",
        +      "snowfallHiIn",
        +      "snowfallCm",
        +      "snowfallLoCm",
        +      "snowfallHiCm",
        +      "tempMaxF",
        +      "tempMinF",
        +      "precipProb",
        +      "windGustMph",
        +      "weatherCode",
        +      "condition",
        +      "modelCount",
        +      "models"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / forecastUrl
        Added value: +{
        +  "description": "The REST document with every model run.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / issuedAt
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Newest model issue instant among the runs blended."
        +}
      • addedOutput schema / properties / modelCount
        Added value: +{
        +  "description": "Models contributing to the first day.",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / models
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / periods / description
        Added value: +"NWS daily narrative for US resorts (up to 5 days); empty elsewhere or when NWS does not answer."
      • removedOutput schema / properties / periods / items / properties / condition / description
        Removed value: -"PeakCam condition key derived from the text."
      • removedOutput schema / properties / periods / items / properties / date / description
        Removed value: -"YYYY-MM-DD when NWS supplies it."
      • removedOutput schema / properties / periods / items / properties / dow / description
        Removed value: -"`Today`, then three-letter weekday."
      • removedOutput schema / properties / periods / items / properties / feelsLikeF / description
        Removed value: -"Wind-chill adjusted high."
      • removedOutput schema / properties / periods / items / properties / precipProbability / description
        Removed value: -"Percent."
      • removedOutput schema / properties / periods / items / properties / shortForecast / description
        Removed value: -"NWS short forecast text, e.g. `Snow Likely`."
      • addedOutput schema / properties / periods / items / properties / snowInches
        Added value: +{
        +  "description": "From the blend when one is stored for that date, else the keyword estimate (see snowSource).",
        +  "type": "number"
        +}
      • removedOutput schema / properties / periods / items / properties / snowInchesEstimate
        Removed value: -{
        -  "description": "Keyword heuristic from the forecast text (blizzard/heavy snow 8, snow 3, flurries 1, else 0). Not a quantitative forecast; say so when quoting it.",
        -  "type": "number"
        -}
      • addedOutput schema / properties / periods / items / properties / snowSource
        Added value: +{
        +  "enum": [
        +    "blend",
        +    "nws_keyword",
        +    "open_meteo"
        +  ],
        +  "type": "string"
        +}
      • changedOutput schema / properties / periods / items / required
        Previous value: -[
        -  "dow",
        -  "date",
        -  "shortForecast",
        -  "condition",
        -  "highF",
        -  "lowF",
        -  "snowInchesEstimate",
        -  "precipProbability",
        -  "windMph",
        -  "windDirection",
        -  "feelsLikeF"
        -]New value: +[
        +  "dow",
        +  "date",
        +  "shortForecast",
        +  "condition",
        +  "highF",
        +  "lowF",
        +  "snowInches",
        +  "snowSource",
        +  "precipProbability",
        +  "windMph",
        +  "windDirection",
        +  "feelsLikeF"
        +]
      • addedOutput schema / properties / point
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "summit",
        +        "base"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ]
        +}
      • removedOutput schema / properties / provider / const
        Removed value: -"nws"
      • addedOutput schema / properties / provider / description
        Added value: +"`blend`: stored multi-model blend; `nws`: NWS narrative only, snow amounts are keyword estimates; `none`: nothing available."
      • addedOutput schema / properties / provider / enum
        Added value: +[
        +  "blend",
        +  "nws",
        +  "none"
        +]
      • addedOutput schema / properties / summary
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": false,
        +      "properties": {
        +        "issuedAt": {
        +          "description": "Newest model issue instant among the runs blended.",
        +          "type": "string"
        +        },
        +        "modelCount": {
        +          "description": "Models contributing to the first day.",
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        "models": {
        +          "description": "Every model id that contributed to any day.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "next48hCm": {
        +          "type": "number"
        +        },
        +        "next48hIn": {
        +          "type": "number"
        +        },
        +        "peak": {
        +          "anyOf": [
        +            {
        +              "additionalProperties": false,
        +              "properties": {
        +                "cm": {
        +                  "type": "number"
        +                },
        +                "date": {
        +                  "description": "The day with the most blended snowfall.",
        +                  "type": "string"
        +                },
        +                "in": {
        +                  "type": "number"
        +                },
        +                "windowDays": {
        +                  "description": "Consecutive days around the peak with at least 1 cm (the storm window).",
        +                  "maximum": 9007199254740991,
        +                  "minimum": -9007199254740991,
        +                  "type": "integer"
        +                }
        +              },
        +              "required": [
        +                "date",
        +                "in",
        +                "cm",
        +                "windowDays"
        +              ],
        +              "type": "object"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Null when no day has any blended snow."
        +        },
        +        "point": {
        +          "description": "The elevation the summary is for: summit when the resort has a summit point, else base.",
        +          "enum": [
        +            "summit",
        +            "base"
        +          ],
        +          "type": "string"
        +        },
        +        "total14dCm": {
        +          "type": "number"
        +        },
        +        "total14dIn": {
        +          "type": "number"
        +        },
        +        "total7dCm": {
        +          "type": "number"
        +        },
        +        "total7dIn": {
        +          "type": "number"
        +        }
        +      },
        +      "required": [
        +        "point",
        +        "issuedAt",
        +        "modelCount",
        +        "models",
        +        "next48hIn",
        +        "next48hCm",
        +        "total7dIn",
        +        "total7dCm",
        +        "total14dIn",
        +        "total14dCm",
        +        "peak"
        +      ],
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "slug",
        -  "name",
        -  "canonicalUrl",
        -  "provider",
        -  "available",
        -  "note",
        -  "periods",
        -  "generatedAt"
        -]New value: +[
        +  "slug",
        +  "name",
        +  "canonicalUrl",
        +  "forecastUrl",
        +  "provider",
        +  "available",
        +  "note",
        +  "point",
        +  "issuedAt",
        +  "modelCount",
        +  "models",
        +  "summary",
        +  "days",
        +  "periods",
        +  "credits",
        +  "generatedAt"
        +]
    • Addedget_leaderboard
    • Addedget_monthly_climatology
    • Changedget_resort_conditions7 fields changed
      • addedOutput schema / properties / forecast / anyOf
        Added value: +[
        +  {
        +    "additionalProperties": false,
        +    "properties": {
        +      "issuedAt": {
        +        "description": "Newest model issue instant among the runs blended.",
        +        "type": "string"
        +      },
        +      "modelCount": {
        +        "description": "Models contributing to the first day.",
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "models": {
        +        "description": "Every model id that contributed to any day.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "next48hCm": {
        +        "type": "number"
        +      },
        +      "next48hIn": {
        +        "type": "number"
        +      },
        +      "peak": {
        +        "anyOf": [
        +          {
        +            "additionalProperties": false,
        +            "properties": {
        +              "cm": {
        +                "type": "number"
        +              },
        +              "date": {
        +                "description": "The day with the most blended snowfall.",
        +                "type": "string"
        +              },
        +              "in": {
        +                "type": "number"
        +              },
        +              "windowDays": {
        +                "description": "Consecutive days around the peak with at least 1 cm (the storm window).",
        +                "maximum": 9007199254740991,
        +                "minimum": -9007199254740991,
        +                "type": "integer"
        +              }
        +            },
        +            "required": [
        +              "date",
        +              "in",
        +              "cm",
        +              "windowDays"
        +            ],
        +            "type": "object"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Null when no day has any blended snow."
        +      },
        +      "point": {
        +        "description": "The elevation the summary is for: summit when the resort has a summit point, else base.",
        +        "enum": [
        +          "summit",
        +          "base"
        +        ],
        +        "type": "string"
        +      },
        +      "total14dCm": {
        +        "type": "number"
        +      },
        +      "total14dIn": {
        +        "type": "number"
        +      },
        +      "total7dCm": {
        +        "type": "number"
        +      },
        +      "total7dIn": {
        +        "type": "number"
        +      }
        +    },
        +    "required": [
        +      "point",
        +      "issuedAt",
        +      "modelCount",
        +      "models",
        +      "next48hIn",
        +      "next48hCm",
        +      "total7dIn",
        +      "total7dCm",
        +      "total14dIn",
        +      "total14dCm",
        +      "peak"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedOutput schema / properties / forecast / description
        Previous value: -"Latest run per model and point, once stored forecasts are live."New value: +"Headline numbers from the blended 14-day forecast (summit point when one exists). Null when no run is current; absent on list and compare rows. The full daily blend and every model run are at `/resorts/{slug}/forecast`."
      • removedOutput schema / properties / forecast / items
        Removed value: -{
        -  "additionalProperties": false,
        -  "properties": {
        -    "days": {
        -      "items": {
        -        "additionalProperties": false,
        -        "properties": {
        -          "date": {
        -            "description": "YYYY-MM-DD, local to the resort.",
        -            "type": "string"
        -          },
        -          "precipProb": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "0–100."
        -          },
        -          "snowfallCm": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "snowfallHi": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "snowfallLo": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Low end of the spread across models / members; null for a single model."
        -          },
        -          "tempMax": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "°C as the models report it."
        -          },
        -          "tempMin": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "weatherCode": {
        -            "anyOf": [
        -              {
        -                "maximum": 9007199254740991,
        -                "minimum": -9007199254740991,
        -                "type": "integer"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "WMO weather interpretation code."
        -          },
        -          "windGust": {
        -            "anyOf": [
        -              {
        -                "type": "number"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "km/h."
        -          }
        -        },
        -        "required": [
        -          "date",
        -          "snowfallCm",
        -          "snowfallLo",
        -          "snowfallHi",
        -          "tempMax",
        -          "tempMin",
        -          "precipProb",
        -          "windGust",
        -          "weatherCode"
        -        ],
        -        "type": "object"
        -      },
        -      "type": "array"
        -    },
        -    "horizonDays": {
        -      "maximum": 9007199254740991,
        -      "minimum": -9007199254740991,
        -      "type": "integer"
        -    },
        -    "id": {
        -      "type": "string"
        -    },
        -    "issuedAt": {
        -      "type": "string"
        -    },
        -    "model": {
        -      "description": "Model id as the provider names it, or `blend` for PeakCam's skill-weighted blend.",
        -      "type": "string"
        -    },
        -    "point": {
        -      "enum": [
        -        "summit",
        -        "base"
        -      ],
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "id",
        -    "point",
        -    "model",
        -    "issuedAt",
        -    "horizonDays",
        -    "days"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / properties / forecast / type
        Removed value: -"array"
      • changedOutput schema / properties / forecastScores / description
        Previous value: -"Per-model verification at this resort, once computed."New value: +"Per-model verification at this resort over 90 days, ranked; empty until the scorer has measured days. Detail at `/resorts/{slug}/forecast-accuracy`."
      • addedOutput schema / properties / forecastScores / items / properties / rank
        Added value: +{
        +  "anyOf": [
        +    {
        +      "maximum": 9007199254740991,
        +      "minimum": -9007199254740991,
        +      "type": "integer"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "1 = lowest day-1 MAE among the models scored at this resort (the blend is ranked too). Null before the first scoring run."
        +}
      • changedOutput schema / properties / forecastScores / items / required
        Previous value: -[
        -  "model",
        -  "periodDays",
        -  "day1Mae",
        -  "day3Mae",
        -  "day7Mae",
        -  "samples",
        -  "biasRatio",
        -  "computedAt"
        -]New value: +[
        +  "model",
        +  "periodDays",
        +  "day1Mae",
        +  "day3Mae",
        +  "day7Mae",
        +  "samples",
        +  "biasRatio",
        +  "computedAt",
        +  "rank"
        +]
    • Addedget_season_stats
    • Changedget_snow_history5 fields changed
      • changedInput schema / properties / days / description
        Previous value: -"Days back, 1–30."New value: +"Days back, 1–30. Ignored when `season` is set."
      • addedInput schema / properties / season
        Added value: +{
        +  "description": "A season label (`2024-25` for the Northern water year, `2026` for an Andes resort) or `current`: returns every daily row of that season, oldest first, with daily new snow.",
        +  "pattern": "^(current|\\d{4}(-\\d{2})?)$",
        +  "type": "string"
        +}
      • addedOutput schema / properties / rows / items / properties / newSnowIn
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Daily new snow (positive depth change), season reads only."
        +}
      • addedOutput schema / properties / season
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The season label when `season` was asked for; null for a last-N-days read."
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "slug",
        -  "name",
        -  "canonicalUrl",
        -  "source",
        -  "station",
        -  "days",
        -  "count",
        -  "rows",
        -  "generatedAt"
        -]New value: +[
        +  "slug",
        +  "name",
        +  "canonicalUrl",
        +  "source",
        +  "station",
        +  "days",
        +  "season",
        +  "count",
        +  "rows",
        +  "generatedAt"
        +]
  5. 3 tool updates
    • Changedcompare_resorts12 fields changed
      • addedOutput schema / properties / resorts / items / properties / measuredNow / items / properties / ageMinutes
        Added value: +{
        +  "description": "Minutes between `observedAt` and `generatedAt`. Daily sources read 1,440 or more; hourly sources under 120 when live.",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / resorts / items / properties / measuredNow / items / properties / attribution
        Added value: +{
        +  "description": "The credit line the provider's terms ask for.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / resorts / items / properties / measuredNow / items / properties / distanceKm
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Great-circle distance from the resort's coordinates."
        +}
      • addedOutput schema / properties / resorts / items / properties / measuredNow / items / properties / elevationFt
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Station elevation. Every value below describes this elevation."
        +}
      • addedOutput schema / properties / resorts / items / properties / measuredNow / items / properties / name
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ]
        +}
      • changedOutput schema / properties / resorts / items / properties / measuredNow / items / properties / newSnowIn / description
        Previous value: -"New snow since the previous observation, inches."New value: +"New snow over the provider's own period (24 h for daily sources), inches. Null for hourly sources, which do not measure it."
      • changedOutput schema / properties / resorts / items / properties / measuredNow / items / properties / observedAt / description
        Previous value: -"ISO-8601 instant of the observation."New value: +"ISO-8601 instant of the observation; a daily value is stamped at the end of its UTC day."
      • addedOutput schema / properties / resorts / items / properties / measuredNow / items / properties / role
        Added value: +{
        +  "description": "summit / mid / base by the station's elevation against the resort's vertical.",
        +  "enum": [
        +    "summit",
        +    "mid",
        +    "base",
        +    "approach"
        +  ],
        +  "type": "string"
        +}
      • addedOutput schema / properties / resorts / items / properties / measuredNow / items / properties / source
        Added value: +{
        +  "enum": [
        +    "snotel",
        +    "ghcn",
        +    "nws",
        +    "bc_asws",
        +    "eccc"
        +  ],
        +  "type": "string"
        +}
      • addedOutput schema / properties / resorts / items / properties / measuredNow / items / properties / sourceId
        Added value: +{
        +  "description": "The provider's own station id, e.g. `AMB`, `1308:UT:SNTL`, `USC00420072`.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / resorts / items / properties / measuredNow / items / properties / stationId / description
        Added value: +"PeakCam station id; joins `stations[]`."
      • changedOutput schema / properties / resorts / items / properties / measuredNow / items / required
        Previous value: -[
        -  "stationId",
        -  "observedAt",
        -  "snowDepthIn",
        -  "sweIn",
        -  "newSnowIn",
        -  "tempF",
        -  "windMph"
        -]New value: +[
        +  "stationId",
        +  "role",
        +  "source",
        +  "sourceId",
        +  "name",
        +  "elevationFt",
        +  "distanceKm",
        +  "observedAt",
        +  "ageMinutes",
        +  "snowDepthIn",
        +  "sweIn",
        +  "newSnowIn",
        +  "tempF",
        +  "windMph",
        +  "attribution"
        +]
    • Changedget_resort_conditions12 fields changed
      • addedOutput schema / properties / measuredNow / items / properties / ageMinutes
        Added value: +{
        +  "description": "Minutes between `observedAt` and `generatedAt`. Daily sources read 1,440 or more; hourly sources under 120 when live.",
        +  "maximum": 9007199254740991,
        +  "minimum": -9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / measuredNow / items / properties / attribution
        Added value: +{
        +  "description": "The credit line the provider's terms ask for.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / measuredNow / items / properties / distanceKm
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Great-circle distance from the resort's coordinates."
        +}
      • addedOutput schema / properties / measuredNow / items / properties / elevationFt
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Station elevation. Every value below describes this elevation."
        +}
      • addedOutput schema / properties / measuredNow / items / properties / name
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ]
        +}
      • changedOutput schema / properties / measuredNow / items / properties / newSnowIn / description
        Previous value: -"New snow since the previous observation, inches."New value: +"New snow over the provider's own period (24 h for daily sources), inches. Null for hourly sources, which do not measure it."
      • changedOutput schema / properties / measuredNow / items / properties / observedAt / description
        Previous value: -"ISO-8601 instant of the observation."New value: +"ISO-8601 instant of the observation; a daily value is stamped at the end of its UTC day."
      • addedOutput schema / properties / measuredNow / items / properties / role
        Added value: +{
        +  "description": "summit / mid / base by the station's elevation against the resort's vertical.",
        +  "enum": [
        +    "summit",
        +    "mid",
        +    "base",
        +    "approach"
        +  ],
        +  "type": "string"
        +}
      • addedOutput schema / properties / measuredNow / items / properties / source
        Added value: +{
        +  "enum": [
        +    "snotel",
        +    "ghcn",
        +    "nws",
        +    "bc_asws",
        +    "eccc"
        +  ],
        +  "type": "string"
        +}
      • addedOutput schema / properties / measuredNow / items / properties / sourceId
        Added value: +{
        +  "description": "The provider's own station id, e.g. `AMB`, `1308:UT:SNTL`, `USC00420072`.",
        +  "type": "string"
        +}
      • addedOutput schema / properties / measuredNow / items / properties / stationId / description
        Added value: +"PeakCam station id; joins `stations[]`."
      • changedOutput schema / properties / measuredNow / items / required
        Previous value: -[
        -  "stationId",
        -  "observedAt",
        -  "snowDepthIn",
        -  "sweIn",
        -  "newSnowIn",
        -  "tempF",
        -  "windMph"
        -]New value: +[
        +  "stationId",
        +  "role",
        +  "source",
        +  "sourceId",
        +  "name",
        +  "elevationFt",
        +  "distanceKm",
        +  "observedAt",
        +  "ageMinutes",
        +  "snowDepthIn",
        +  "sweIn",
        +  "newSnowIn",
        +  "tempF",
        +  "windMph",
        +  "attribution"
        +]
    • Addedget_stations
  6. 6 tool updates
    • Addedask
    • Addedget_alert_options
    • Addedget_cam_timeline
    • Addedget_percent_of_normal
    • Addedget_resort_profile
    • Addedlist_regions
  7. 3 tool updates
    • Changedcompare_resorts9 fields changed
      • addedOutput schema / properties / resorts / items / properties / forecast
        Added value: +{
        +  "description": "Latest run per model and point, once stored forecasts are live.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "days": {
        +        "items": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "date": {
        +              "description": "YYYY-MM-DD, local to the resort.",
        +              "type": "string"
        +            },
        +            "precipProb": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "0–100."
        +            },
        +            "snowfallCm": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "snowfallHi": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "snowfallLo": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Low end of the spread across models / members; null for a single model."
        +            },
        +            "tempMax": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "°C as the models report it."
        +            },
        +            "tempMin": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "weatherCode": {
        +              "anyOf": [
        +                {
        +                  "maximum": 9007199254740991,
        +                  "minimum": -9007199254740991,
        +                  "type": "integer"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "WMO weather interpretation code."
        +            },
        +            "windGust": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "km/h."
        +            }
        +          },
        +          "required": [
        +            "date",
        +            "snowfallCm",
        +            "snowfallLo",
        +            "snowfallHi",
        +            "tempMax",
        +            "tempMin",
        +            "precipProb",
        +            "windGust",
        +            "weatherCode"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "horizonDays": {
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "id": {
        +        "type": "string"
        +      },
        +      "issuedAt": {
        +        "type": "string"
        +      },
        +      "model": {
        +        "description": "Model id as the provider names it, or `blend` for PeakCam's skill-weighted blend.",
        +        "type": "string"
        +      },
        +      "point": {
        +        "enum": [
        +          "summit",
        +          "base"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "id",
        +      "point",
        +      "model",
        +      "issuedAt",
        +      "horizonDays",
        +      "days"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / resorts / items / properties / forecastScores
        Added value: +{
        +  "description": "Per-model verification at this resort, once computed.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "biasRatio": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Sum(forecast) / sum(observed); above 1 means the model over-forecasts snow."
        +      },
        +      "computedAt": {
        +        "type": "string"
        +      },
        +      "day1Mae": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Mean absolute error of the day-1 snowfall forecast, cm."
        +      },
        +      "day3Mae": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "day7Mae": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "model": {
        +        "type": "string"
        +      },
        +      "periodDays": {
        +        "description": "Trailing verification window, days.",
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "samples": {
        +        "anyOf": [
        +          {
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "model",
        +      "periodDays",
        +      "day1Mae",
        +      "day3Mae",
        +      "day7Mae",
        +      "samples",
        +      "biasRatio",
        +      "computedAt"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / resorts / items / properties / location / properties / summitElevationFt
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ]
        +}
      • changedOutput schema / properties / resorts / items / properties / location / required
        Previous value: -[
        -  "state",
        -  "region",
        -  "country",
        -  "lat",
        -  "lon",
        -  "baseElevationFt"
        -]New value: +[
        +  "state",
        +  "region",
        +  "country",
        +  "lat",
        +  "lon",
        +  "baseElevationFt",
        +  "summitElevationFt"
        +]
      • addedOutput schema / properties / resorts / items / properties / measuredNow
        Added value: +{
        +  "description": "Latest observation per station, once the station layer is live.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "newSnowIn": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "New snow since the previous observation, inches."
        +      },
        +      "observedAt": {
        +        "description": "ISO-8601 instant of the observation.",
        +        "type": "string"
        +      },
        +      "snowDepthIn": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "stationId": {
        +        "type": "string"
        +      },
        +      "sweIn": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "tempF": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "windMph": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "stationId",
        +      "observedAt",
        +      "snowDepthIn",
        +      "sweIn",
        +      "newSnowIn",
        +      "tempF",
        +      "windMph"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / resorts / items / properties / profile
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "aliases": {
        +      "description": "Other names the resort is known by, e.g. `A-Basin`.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "annualSnowfallIn": {
        +      "anyOf": [
        +        {
        +          "type": "number"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Operator-stated average annual snowfall, inches."
        +    },
        +    "description": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "descriptionSource": {
        +      "anyOf": [
        +        {
        +          "enum": [
        +            "operator",
        +            "generated",
        +            "editor"
        +          ],
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "`operator`: the resort's own copy. `generated`: a model-written draft, labelled as such on the page. `editor`: hand-written by PeakCam."
        +    },
        +    "liftsTotal": {
        +      "anyOf": [
        +        {
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "longestRunMi": {
        +      "anyOf": [
        +        {
        +          "type": "number"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "passes": {
        +      "description": "Multi-resort passes the resort is on.",
        +      "items": {
        +        "enum": [
        +          "ikon",
        +          "epic",
        +          "mountain-collective",
        +          "indy",
        +          "power"
        +        ],
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "runsTotal": {
        +      "anyOf": [
        +        {
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "skiableAcres": {
        +      "anyOf": [
        +        {
        +          "type": "number"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "trailMapUrl": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "The operator's trail map (linked, never copied)."
        +    },
        +    "verticalFt": {
        +      "anyOf": [
        +        {
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "wikidataId": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    }
        +  },
        +  "required": [
        +    "runsTotal",
        +    "liftsTotal",
        +    "skiableAcres",
        +    "verticalFt",
        +    "annualSnowfallIn",
        +    "longestRunMi",
        +    "description",
        +    "descriptionSource",
        +    "trailMapUrl",
        +    "wikidataId",
        +    "aliases",
        +    "passes"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / resorts / items / properties / score
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": false,
        +      "properties": {
        +        "components": {
        +          "additionalProperties": {
        +            "anyOf": [
        +              {
        +                "type": "number"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "date": {
        +          "description": "YYYY-MM-DD the score is for.",
        +          "type": "string"
        +        },
        +        "rating": {
        +          "anyOf": [
        +            {
        +              "enum": [
        +                "great",
        +                "good",
        +                "fair",
        +                "poor"
        +              ],
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "score": {
        +          "maximum": 100,
        +          "minimum": 0,
        +          "type": "integer"
        +        },
        +        "scoredBy": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Scorer version, e.g. `score-v1`."
        +        }
        +      },
        +      "required": [
        +        "date",
        +        "score",
        +        "rating",
        +        "components",
        +        "scoredBy"
        +      ],
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Today's 0–100 score, once the scorer is live."
        +}
      • addedOutput schema / properties / resorts / items / properties / stations
        Added value: +{
        +  "description": "Observation stations serving the resort, once the station layer is live.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "distanceKm": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Great-circle distance from the resort's coordinates."
        +      },
        +      "elevationFt": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "id": {
        +        "description": "PeakCam station id (UUID).",
        +        "type": "string"
        +      },
        +      "kind": {
        +        "enum": [
        +          "snotel",
        +          "scan",
        +          "nws_obs",
        +          "metar",
        +          "ghcn",
        +          "bc_asws",
        +          "eccc",
        +          "road_cam"
        +        ],
        +        "type": "string"
        +      },
        +      "lat": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "lon": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "name": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "rank": {
        +        "description": "1 = the preferred station for its role.",
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "role": {
        +        "description": "Where the station sits relative to the resort.",
        +        "enum": [
        +          "summit",
        +          "mid",
        +          "base",
        +          "approach"
        +        ],
        +        "type": "string"
        +      },
        +      "source": {
        +        "description": "Provider, e.g. `nrcs`, `nws`, `eccc`, `udot`.",
        +        "type": "string"
        +      },
        +      "sourceId": {
        +        "description": "The provider's own identifier (SNOTEL triplet, ICAO code, GHCN id).",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "id",
        +      "source",
        +      "sourceId",
        +      "name",
        +      "kind",
        +      "role",
        +      "lat",
        +      "lon",
        +      "elevationFt",
        +      "distanceKm",
        +      "rank"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • changedOutput schema / properties / resorts / items / required
        Previous value: -[
        -  "slug",
        -  "name",
        -  "canonicalUrl",
        -  "apiUrl",
        -  "location",
        -  "snow",
        -  "season",
        -  "websiteUrl",
        -  "attribution",
        -  "license",
        -  "updatedAt",
        -  "camCount",
        -  "liveCamCount"
        -]New value: +[
        +  "slug",
        +  "name",
        +  "canonicalUrl",
        +  "apiUrl",
        +  "location",
        +  "profile",
        +  "snow",
        +  "season",
        +  "websiteUrl",
        +  "attribution",
        +  "license",
        +  "updatedAt",
        +  "camCount",
        +  "liveCamCount"
        +]
    • Changedget_resort_cams5 fields changed
      • addedOutput schema / properties / cams / items / properties / credit
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Attribution line to show with the frame. Null means credit the resort."
        +}
      • addedOutput schema / properties / cams / items / properties / kind
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "summit",
        +        "mid",
        +        "base",
        +        "snow-stake",
        +        "village",
        +        "approach"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "What the cam looks at. Null when not classified."
        +}
      • addedOutput schema / properties / cams / items / properties / sourceTermsUrl
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The operator's terms governing reuse of this feed, when known."
        +}
      • addedOutput schema / properties / cams / items / properties / timelapses
        Added value: +{
        +  "description": "Rendered clips, once PeakCam renders them for this cam.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "frames": {
        +        "anyOf": [
        +          {
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "id": {
        +        "type": "string"
        +      },
        +      "renderedAt": {
        +        "description": "ISO-8601 instant the clip was rendered.",
        +        "type": "string"
        +      },
        +      "stormDate": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "YYYY-MM-DD of the storm a `storm` clip covers."
        +      },
        +      "url": {
        +        "description": "Public MP4 URL.",
        +        "type": "string"
        +      },
        +      "window": {
        +        "description": "Which clip: `24h` (rolling day), `storm` (one storm, see `stormDate`), or another label.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "id",
        +      "window",
        +      "url",
        +      "frames",
        +      "renderedAt",
        +      "stormDate"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • changedOutput schema / properties / cams / items / required
        Previous value: -[
        -  "id",
        -  "name",
        -  "elevation",
        -  "live",
        -  "lastCheckedAt",
        -  "stillUrl",
        -  "capturedAt",
        -  "embedType",
        -  "pageUrl",
        -  "sourceUrl"
        -]New value: +[
        +  "id",
        +  "name",
        +  "elevation",
        +  "live",
        +  "lastCheckedAt",
        +  "stillUrl",
        +  "capturedAt",
        +  "embedType",
        +  "pageUrl",
        +  "sourceUrl",
        +  "kind",
        +  "credit",
        +  "sourceTermsUrl"
        +]
    • Changedget_resort_conditions14 fields changed
      • addedOutput schema / properties / cams / items / properties / credit
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Attribution line to show with the frame. Null means credit the resort."
        +}
      • addedOutput schema / properties / cams / items / properties / kind
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "summit",
        +        "mid",
        +        "base",
        +        "snow-stake",
        +        "village",
        +        "approach"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "What the cam looks at. Null when not classified."
        +}
      • addedOutput schema / properties / cams / items / properties / sourceTermsUrl
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The operator's terms governing reuse of this feed, when known."
        +}
      • addedOutput schema / properties / cams / items / properties / timelapses
        Added value: +{
        +  "description": "Rendered clips, once PeakCam renders them for this cam.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "frames": {
        +        "anyOf": [
        +          {
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "id": {
        +        "type": "string"
        +      },
        +      "renderedAt": {
        +        "description": "ISO-8601 instant the clip was rendered.",
        +        "type": "string"
        +      },
        +      "stormDate": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "YYYY-MM-DD of the storm a `storm` clip covers."
        +      },
        +      "url": {
        +        "description": "Public MP4 URL.",
        +        "type": "string"
        +      },
        +      "window": {
        +        "description": "Which clip: `24h` (rolling day), `storm` (one storm, see `stormDate`), or another label.",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "id",
        +      "window",
        +      "url",
        +      "frames",
        +      "renderedAt",
        +      "stormDate"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • changedOutput schema / properties / cams / items / required
        Previous value: -[
        -  "id",
        -  "name",
        -  "elevation",
        -  "live",
        -  "lastCheckedAt",
        -  "stillUrl",
        -  "capturedAt",
        -  "embedType",
        -  "pageUrl",
        -  "sourceUrl"
        -]New value: +[
        +  "id",
        +  "name",
        +  "elevation",
        +  "live",
        +  "lastCheckedAt",
        +  "stillUrl",
        +  "capturedAt",
        +  "embedType",
        +  "pageUrl",
        +  "sourceUrl",
        +  "kind",
        +  "credit",
        +  "sourceTermsUrl"
        +]
      • addedOutput schema / properties / forecast
        Added value: +{
        +  "description": "Latest run per model and point, once stored forecasts are live.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "days": {
        +        "items": {
        +          "additionalProperties": false,
        +          "properties": {
        +            "date": {
        +              "description": "YYYY-MM-DD, local to the resort.",
        +              "type": "string"
        +            },
        +            "precipProb": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "0–100."
        +            },
        +            "snowfallCm": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "snowfallHi": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "snowfallLo": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "Low end of the spread across models / members; null for a single model."
        +            },
        +            "tempMax": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "°C as the models report it."
        +            },
        +            "tempMin": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ]
        +            },
        +            "weatherCode": {
        +              "anyOf": [
        +                {
        +                  "maximum": 9007199254740991,
        +                  "minimum": -9007199254740991,
        +                  "type": "integer"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "WMO weather interpretation code."
        +            },
        +            "windGust": {
        +              "anyOf": [
        +                {
        +                  "type": "number"
        +                },
        +                {
        +                  "type": "null"
        +                }
        +              ],
        +              "description": "km/h."
        +            }
        +          },
        +          "required": [
        +            "date",
        +            "snowfallCm",
        +            "snowfallLo",
        +            "snowfallHi",
        +            "tempMax",
        +            "tempMin",
        +            "precipProb",
        +            "windGust",
        +            "weatherCode"
        +          ],
        +          "type": "object"
        +        },
        +        "type": "array"
        +      },
        +      "horizonDays": {
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "id": {
        +        "type": "string"
        +      },
        +      "issuedAt": {
        +        "type": "string"
        +      },
        +      "model": {
        +        "description": "Model id as the provider names it, or `blend` for PeakCam's skill-weighted blend.",
        +        "type": "string"
        +      },
        +      "point": {
        +        "enum": [
        +          "summit",
        +          "base"
        +        ],
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "id",
        +      "point",
        +      "model",
        +      "issuedAt",
        +      "horizonDays",
        +      "days"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / forecastScores
        Added value: +{
        +  "description": "Per-model verification at this resort, once computed.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "biasRatio": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Sum(forecast) / sum(observed); above 1 means the model over-forecasts snow."
        +      },
        +      "computedAt": {
        +        "type": "string"
        +      },
        +      "day1Mae": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Mean absolute error of the day-1 snowfall forecast, cm."
        +      },
        +      "day3Mae": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "day7Mae": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "model": {
        +        "type": "string"
        +      },
        +      "periodDays": {
        +        "description": "Trailing verification window, days.",
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "samples": {
        +        "anyOf": [
        +          {
        +            "maximum": 9007199254740991,
        +            "minimum": -9007199254740991,
        +            "type": "integer"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "model",
        +      "periodDays",
        +      "day1Mae",
        +      "day3Mae",
        +      "day7Mae",
        +      "samples",
        +      "biasRatio",
        +      "computedAt"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / location / properties / summitElevationFt
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ]
        +}
      • changedOutput schema / properties / location / required
        Previous value: -[
        -  "state",
        -  "region",
        -  "country",
        -  "lat",
        -  "lon",
        -  "baseElevationFt"
        -]New value: +[
        +  "state",
        +  "region",
        +  "country",
        +  "lat",
        +  "lon",
        +  "baseElevationFt",
        +  "summitElevationFt"
        +]
      • addedOutput schema / properties / measuredNow
        Added value: +{
        +  "description": "Latest observation per station, once the station layer is live.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "newSnowIn": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "New snow since the previous observation, inches."
        +      },
        +      "observedAt": {
        +        "description": "ISO-8601 instant of the observation.",
        +        "type": "string"
        +      },
        +      "snowDepthIn": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "stationId": {
        +        "type": "string"
        +      },
        +      "sweIn": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "tempF": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "windMph": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      }
        +    },
        +    "required": [
        +      "stationId",
        +      "observedAt",
        +      "snowDepthIn",
        +      "sweIn",
        +      "newSnowIn",
        +      "tempF",
        +      "windMph"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / profile
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "aliases": {
        +      "description": "Other names the resort is known by, e.g. `A-Basin`.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "annualSnowfallIn": {
        +      "anyOf": [
        +        {
        +          "type": "number"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Operator-stated average annual snowfall, inches."
        +    },
        +    "description": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "descriptionSource": {
        +      "anyOf": [
        +        {
        +          "enum": [
        +            "operator",
        +            "generated",
        +            "editor"
        +          ],
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "`operator`: the resort's own copy. `generated`: a model-written draft, labelled as such on the page. `editor`: hand-written by PeakCam."
        +    },
        +    "liftsTotal": {
        +      "anyOf": [
        +        {
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "longestRunMi": {
        +      "anyOf": [
        +        {
        +          "type": "number"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "passes": {
        +      "description": "Multi-resort passes the resort is on.",
        +      "items": {
        +        "enum": [
        +          "ikon",
        +          "epic",
        +          "mountain-collective",
        +          "indy",
        +          "power"
        +        ],
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "runsTotal": {
        +      "anyOf": [
        +        {
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "skiableAcres": {
        +      "anyOf": [
        +        {
        +          "type": "number"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "trailMapUrl": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "The operator's trail map (linked, never copied)."
        +    },
        +    "verticalFt": {
        +      "anyOf": [
        +        {
        +          "maximum": 9007199254740991,
        +          "minimum": -9007199254740991,
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    },
        +    "wikidataId": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ]
        +    }
        +  },
        +  "required": [
        +    "runsTotal",
        +    "liftsTotal",
        +    "skiableAcres",
        +    "verticalFt",
        +    "annualSnowfallIn",
        +    "longestRunMi",
        +    "description",
        +    "descriptionSource",
        +    "trailMapUrl",
        +    "wikidataId",
        +    "aliases",
        +    "passes"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / score
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": false,
        +      "properties": {
        +        "components": {
        +          "additionalProperties": {
        +            "anyOf": [
        +              {
        +                "type": "number"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "propertyNames": {
        +            "type": "string"
        +          },
        +          "type": "object"
        +        },
        +        "date": {
        +          "description": "YYYY-MM-DD the score is for.",
        +          "type": "string"
        +        },
        +        "rating": {
        +          "anyOf": [
        +            {
        +              "enum": [
        +                "great",
        +                "good",
        +                "fair",
        +                "poor"
        +              ],
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ]
        +        },
        +        "score": {
        +          "maximum": 100,
        +          "minimum": 0,
        +          "type": "integer"
        +        },
        +        "scoredBy": {
        +          "anyOf": [
        +            {
        +              "type": "string"
        +            },
        +            {
        +              "type": "null"
        +            }
        +          ],
        +          "description": "Scorer version, e.g. `score-v1`."
        +        }
        +      },
        +      "required": [
        +        "date",
        +        "score",
        +        "rating",
        +        "components",
        +        "scoredBy"
        +      ],
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Today's 0–100 score, once the scorer is live."
        +}
      • addedOutput schema / properties / stations
        Added value: +{
        +  "description": "Observation stations serving the resort, once the station layer is live.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "distanceKm": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ],
        +        "description": "Great-circle distance from the resort's coordinates."
        +      },
        +      "elevationFt": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "id": {
        +        "description": "PeakCam station id (UUID).",
        +        "type": "string"
        +      },
        +      "kind": {
        +        "enum": [
        +          "snotel",
        +          "scan",
        +          "nws_obs",
        +          "metar",
        +          "ghcn",
        +          "bc_asws",
        +          "eccc",
        +          "road_cam"
        +        ],
        +        "type": "string"
        +      },
        +      "lat": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "lon": {
        +        "anyOf": [
        +          {
        +            "type": "number"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "name": {
        +        "anyOf": [
        +          {
        +            "type": "string"
        +          },
        +          {
        +            "type": "null"
        +          }
        +        ]
        +      },
        +      "rank": {
        +        "description": "1 = the preferred station for its role.",
        +        "maximum": 9007199254740991,
        +        "minimum": -9007199254740991,
        +        "type": "integer"
        +      },
        +      "role": {
        +        "description": "Where the station sits relative to the resort.",
        +        "enum": [
        +          "summit",
        +          "mid",
        +          "base",
        +          "approach"
        +        ],
        +        "type": "string"
        +      },
        +      "source": {
        +        "description": "Provider, e.g. `nrcs`, `nws`, `eccc`, `udot`.",
        +        "type": "string"
        +      },
        +      "sourceId": {
        +        "description": "The provider's own identifier (SNOTEL triplet, ICAO code, GHCN id).",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "id",
        +      "source",
        +      "sourceId",
        +      "name",
        +      "kind",
        +      "role",
        +      "lat",
        +      "lon",
        +      "elevationFt",
        +      "distanceKm",
        +      "rank"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "slug",
        -  "name",
        -  "canonicalUrl",
        -  "apiUrl",
        -  "location",
        -  "snow",
        -  "season",
        -  "cams",
        -  "websiteUrl",
        -  "attribution",
        -  "license",
        -  "updatedAt"
        -]New value: +[
        +  "slug",
        +  "name",
        +  "canonicalUrl",
        +  "apiUrl",
        +  "location",
        +  "profile",
        +  "snow",
        +  "season",
        +  "cams",
        +  "websiteUrl",
        +  "attribution",
        +  "license",
        +  "updatedAt"
        +]
  8. 8 tool updates
    • First observedcompare_resorts
    • First observedfind_powder
    • First observedget_forecast
    • First observedget_opening_dates
    • First observedget_resort_cams
    • First observedget_resort_conditions
    • First observedget_snow_history
    • First observedsearch_resorts

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables users to search ski resorts, retrieve up to 15-day snow forecasts and current conditions, compare or rank resorts for powder and trip planning, and access opening dates, lift status, resort news, and station-verified forecast accuracy across 667 ski resorts.
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Live ski & snow data for AI agents: 14-day multi-model forecasts, powder rankings, resort guides, webcams, ski-pass intelligence, and avalanche/road safety across 500+ resorts. Hosted streamable-HTTP — no install, no auth.
    40
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides access to real-time and historical snow conditions, weather data, and snowpack analysis from over 800 SNOTEL stations across the western United States through the USDA Air and Water Database API.
    2
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.