Skip to main content
Glama

usgs-water-mcp-server

Water Get Conditions

water_get_conditions
Read-onlyIdempotent

Get a USGS site's current reading ranked against its full period-of-record daily-mean percentiles for the same calendar day — a "how unusual is this" percentileClass (record-high to record-low), not a flood-stage or drought determination (this tool fetches no authoritative thresholds). The reading is instantaneous but the percentiles are daily-mean, so the ranking is approximate (see historicalContext.comparisonBasis). When the record is too short to rank, returns the reading with historicalContext=null instead of an error. A reading NWIS reports as no data (a seasonal, discontinued, dry, or malfunctioning gage) returns an empty currentValue with the qualifiers naming why, and is not ranked. When the site measures the parameter with several sensors (methods), one reading is used and named by methodId/methodDescription — from the sensor its percentile series is described as when one is, otherwise the most recent across them; water_get_readings lists every method. Use water_find_sites and water_list_parameters to resolve inputs.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
siteYesUSGS site number (8–15 digits, e.g. "01646500" for Potomac River at Little Falls). Use water_find_sites to discover valid site numbers.
parameterCdYes5-digit USGS parameter code (e.g. "00060" for discharge, "00065" for gage height). Use water_list_parameters to discover codes.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
noteNoInformational note explaining why historicalContext is null or incomplete, that NWIS reported no value for the current reading, or which statistics series the percentiles came from when methodMatched is false. Absent when the reading is measured and ranked against a statistics series described exactly as its method.
errorNoPresent when the call failed. Absent on success.
methodIdNoNWIS method ID of the sensor series the current reading comes from. When the site reports the parameter from several, a method with a measured latest reading is preferred, then one whose description a statistics series carries exactly (so reading and percentiles come from one sensor), then the most recent. Null only when NWIS returned the series with no method block.
siteNameNoHuman-readable USGS site name.
unitCodeNoUnit of measure for currentValue and the historical percentiles (e.g. "ft3/s", "ft").
qualifiersNoData qualifier codes for the current reading. When currentValue is empty they name why NWIS has no value (e.g. "Ssn" seasonal, "Dis" discontinued, "Dry", "Eqp" equipment malfunction).
siteNumberNoUSGS site number (8–15 digits, e.g. "01646500").
parameterCdNo5-digit USGS parameter code that was queried (e.g. "00060").
currentValueNoMost recent observed value as a string. Empty string when NWIS reported no value for the reading — qualifiers then give the reason, and historicalContext does not rank it. A method with a measured latest reading is preferred over one whose latest reading has no value.
parameterNameNoHuman-readable parameter name with units (e.g. "Streamflow, ft³/s").
currentDateTimeNoISO 8601 date-time of the most recent observation.
historicalContextNoHistorical percentile context for the observation's calendar day. Non-null only when historicalContextStatus is "available"; see that field for why it is otherwise absent.
methodDescriptionNoNWIS description of that method (e.g. "From multiparameter sonde", "[(2)]"). Null when NWIS leaves it blank, as it does for the default series at most single-sensor sites.
historicalContextStatusNoWhy historicalContext is or is not populated. 'available': percentiles for the observation's calendar day are present. 'no_matching_day': the stat table has rows but none for that calendar day. 'no_matching_method': the stat table covers several sensor series at this site and none is identified by the reported method's description — exactly, or apart from a bracketed label — so no series is picked to rank against (note lists them). 'no_record': the stat table is empty — a new site, or a record too short to compute percentiles. 'unavailable': the statistics service call failed — a transient upstream error, not a statement about the site's record; retry shortly.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed10 schema fields changed
    • changedOutput schema / anyOf
      Previous value: -[
      -  {
      -    "not": {
      -      "required": [
      -        "error"
      -      ]
      -    },
      -    "required": [
      -      "siteNumber",
      -      "siteName",
      -      "parameterCd",
      -      "parameterName",
      -      "unitCode",
      -      "currentValue",
      -      "currentDateTime",
      -      "qualifiers",
      -      "historicalContext",
      -      "historicalContextStatus"
      -    ]
      -  },
      -  {
      -    "required": [
      -      "error"
      -    ]
      -  }
      -]New value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "siteNumber",
      +      "siteName",
      +      "parameterCd",
      +      "parameterName",
      +      "unitCode",
      +      "methodId",
      +      "methodDescription",
      +      "currentValue",
      +      "currentDateTime",
      +      "qualifiers",
      +      "historicalContext",
      +      "historicalContextStatus"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • changedOutput schema / properties / currentValue / description
      Previous value: -"Most recent observed value as a string. Empty string when no data is available for the current period."New value: +"Most recent observed value as a string. Empty string when NWIS reported no value for the reading — qualifiers then give the reason, and historicalContext does not rank it. A method with a measured latest reading is preferred over one whose latest reading has no value."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_data_for_parameter`: NWIS returned no IV data — the site may not exist, or may not measure the requested parameter. NWIS returns the same empty response for both cases. `invalid_request`: NWIS rejected the request. Input formats are validated against NWIS-accepted patterns before the call, so this surfaces a value that is well-formed but unacceptable upstream. `upstream_error`: NWIS IV or stat endpoint returned a 5xx error or timed out. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `no_data_for_parameter`: NWIS returned no IV data — the site may not exist, or may not measure the requested parameter. NWIS returns the same empty response for both cases. `invalid_request`: NWIS rejected the request. Input formats are validated against NWIS-accepted patterns before the call, so this surfaces a value that is well-formed but unacceptable upstream. `upstream_error`: The NWIS IV endpoint returned a 5xx error, timed out, or sent a response body that is not valid WaterML-JSON (cut off mid-document), and retrying did not clear it. A stat-endpoint failure does not raise this — it is reported as historicalContextStatus \"unavailable\". Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / historicalContext / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "comparisonBasis": {
      -        "description": "Fixed disclosure that percentileClass ranks an instantaneous reading against approved daily-mean percentiles — a cross-granularity approximation, not a flood-stage or drought determination. Present whenever historicalContext is non-null.",
      -        "type": "string"
      -      },
      -      "p05": {
      -        "description": "5th percentile value in unitCode for this calendar month+day, based on the period of record. Null if that threshold is unavailable.",
      -        "type": [
      -          "number",
      -          "null"
      -        ]
      -      },
      -      "p10": {
      -        "description": "10th percentile value in unitCode for this calendar month+day. Null if unavailable.",
      -        "type": [
      -          "number",
      -          "null"
      -        ]
      -      },
      -      "p25": {
      -        "description": "25th percentile (lower quartile) in unitCode. Null if unavailable.",
      -        "type": [
      -          "number",
      -          "null"
      -        ]
      -      },
      -      "p50": {
      -        "description": "Median (50th percentile) in unitCode for this calendar month+day. Null if unavailable.",
      -        "type": [
      -          "number",
      -          "null"
      -        ]
      -      },
      -      "p75": {
      -        "description": "75th percentile (upper quartile) in unitCode. Null if unavailable.",
      -        "type": [
      -          "number",
      -          "null"
      -        ]
      -      },
      -      "p95": {
      -        "description": "95th percentile value in unitCode for this calendar month+day. Null if unavailable.",
      -        "type": [
      -          "number",
      -          "null"
      -        ]
      -      },
      -      "percentileClass": {
      -        "description": "Classification relative to the full period-of-record: record-high (≥ p95), above-normal (p75–p95), normal (p25–p75), below-normal (p10–p25), low (p05–p10), record-low (< p05). See percentileLabel for the threshold in plain language.",
      -        "enum": [
      -          "record-high",
      -          "above-normal",
      -          "normal",
      -          "below-normal",
      -          "low",
      -          "record-low",
      -          "unknown"
      -        ],
      -        "type": "string"
      -      },
      -      "percentileLabel": {
      -        "description": "Plain-language threshold for percentileClass (e.g. \"25th–75th percentile\"). The record-high and record-low classes mark percentile-of-record extremes (≥ p95 / < p05), not verified all-time records — this field says so where the class name does not.",
      -        "type": "string"
      -      },
      -      "periodOfRecord": {
      -        "description": "Range of years used to compute the percentile statistics (e.g. \"1930–2025\").",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "percentileClass",
      -      "percentileLabel",
      -      "p05",
      -      "p10",
      -      "p25",
      -      "p50",
      -      "p75",
      -      "p95",
      -      "periodOfRecord",
      -      "comparisonBasis"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "comparisonBasis": {
      +        "description": "Fixed disclosure that percentileClass ranks an instantaneous reading against approved daily-mean percentiles — a cross-granularity approximation, not a flood-stage or drought determination. Present whenever historicalContext is non-null.",
      +        "type": "string"
      +      },
      +      "methodMatched": {
      +        "description": "True when statSeriesDescription equals the reported methodDescription, which is how the percentiles are matched to the sensor that produced the reading. False when the descriptions differ but the series was still used — it is the only statistics series whose description matches once the bracketed label the statistics service appends (e.g. \"[BASE GAGE]\") is set aside, or the only statistics series at the site; note says which. The percentiles may then come from a different sensor or location than the reading.",
      +        "type": "boolean"
      +      },
      +      "p05": {
      +        "description": "5th percentile value in unitCode for this calendar month+day, based on the period of record. Null if that threshold is unavailable.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "p10": {
      +        "description": "10th percentile value in unitCode for this calendar month+day. Null if unavailable.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "p25": {
      +        "description": "25th percentile (lower quartile) in unitCode. Null if unavailable.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "p50": {
      +        "description": "Median (50th percentile) in unitCode for this calendar month+day. Null if unavailable.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "p75": {
      +        "description": "75th percentile (upper quartile) in unitCode. Null if unavailable.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "p95": {
      +        "description": "95th percentile value in unitCode for this calendar month+day. Null if unavailable.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "percentileClass": {
      +        "description": "Classification relative to the full period-of-record: record-high (≥ p95), above-normal (p75–p95), normal (p25–p75), below-normal (p10–p25), low (p05–p10), record-low (< p05). Decided by the thresholds NWIS published: with p95 blank a value ≥ p75 is above-normal, and with p10 or p05 blank a value below p25 or p10 is below-normal or low. normal requires both p25 and p75; a value the published thresholds cannot place is unknown, as is a reading NWIS reported as no data (currentValue empty). See percentileLabel for the threshold in plain language.",
      +        "enum": [
      +          "record-high",
      +          "above-normal",
      +          "normal",
      +          "below-normal",
      +          "low",
      +          "record-low",
      +          "unknown"
      +        ],
      +        "type": "string"
      +      },
      +      "percentileLabel": {
      +        "description": "Plain-language threshold for percentileClass (e.g. \"25th–75th percentile\"). When the class was decided without an unpublished threshold, the label names it (e.g. \"≥ 75th percentile; 95th not published\") — the value may lie past it. An unknown class names the published thresholds either side and the blank ones between (e.g. \"25th–95th percentile; 75th not published\"), or, for a reading with no value, says so and names its qualifiers. The record-high and record-low classes mark percentile-of-record extremes (≥ p95 / < p05), not verified all-time records — this field says so where the class name does not.",
      +        "type": "string"
      +      },
      +      "periodOfRecord": {
      +        "description": "Range of years used to compute the percentile statistics (e.g. \"1930–2025\").",
      +        "type": "string"
      +      },
      +      "statSeriesDescription": {
      +        "description": "Location description NWIS gives that statistics series (e.g. \"From multiparameter sonde\"). Null when blank.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "statSeriesId": {
      +        "description": "NWIS statistics time-series ID (ts_id) the percentiles were computed from. A daily-mean series ID, numbered independently of the IV methodId. Null when NWIS omits it.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      }
      +    },
      +    "required": [
      +      "percentileClass",
      +      "percentileLabel",
      +      "p05",
      +      "p10",
      +      "p25",
      +      "p50",
      +      "p75",
      +      "p95",
      +      "periodOfRecord",
      +      "comparisonBasis",
      +      "statSeriesId",
      +      "statSeriesDescription",
      +      "methodMatched"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedOutput schema / properties / historicalContextStatus / description
      Previous value: -"Why historicalContext is or is not populated. 'available': percentiles for the observation's calendar day are present. 'no_matching_day': the stat table has rows but none for that calendar day. 'no_record': the stat table is empty — a new site, or a record too short to compute percentiles. 'unavailable': the statistics service call failed — a transient upstream error, not a statement about the site's record; retry shortly."New value: +"Why historicalContext is or is not populated. 'available': percentiles for the observation's calendar day are present. 'no_matching_day': the stat table has rows but none for that calendar day. 'no_matching_method': the stat table covers several sensor series at this site and none is identified by the reported method's description — exactly, or apart from a bracketed label — so no series is picked to rank against (note lists them). 'no_record': the stat table is empty — a new site, or a record too short to compute percentiles. 'unavailable': the statistics service call failed — a transient upstream error, not a statement about the site's record; retry shortly."
    • changedOutput schema / properties / historicalContextStatus / enum
      Previous value: -[
      -  "available",
      -  "no_matching_day",
      -  "no_record",
      -  "unavailable"
      -]New value: +[
      +  "available",
      +  "no_matching_day",
      +  "no_matching_method",
      +  "no_record",
      +  "unavailable"
      +]
    • addedOutput schema / properties / methodDescription
      Added value: +{
      +  "description": "NWIS description of that method (e.g. \"From multiparameter sonde\", \"[(2)]\"). Null when NWIS leaves it blank, as it does for the default series at most single-sensor sites.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / methodId
      Added value: +{
      +  "description": "NWIS method ID of the sensor series the current reading comes from. When the site reports the parameter from several, a method with a measured latest reading is preferred, then one whose description a statistics series carries exactly (so reading and percentiles come from one sensor), then the most recent. Null only when NWIS returned the series with no method block.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • changedOutput schema / properties / note / description
      Previous value: -"Informational note explaining why historicalContext is null or incomplete. Absent when full historical context is available."New value: +"Informational note explaining why historicalContext is null or incomplete, that NWIS reported no value for the current reading, or which statistics series the percentiles came from when methodMatched is false. Absent when the reading is measured and ranked against a statistics series described exactly as its method."
    • changedOutput schema / properties / qualifiers / description
      Previous value: -"Data qualifier codes for the current reading."New value: +"Data qualifier codes for the current reading. When currentValue is empty they name why NWIS has no value (e.g. \"Ssn\" seasonal, \"Dis\" discontinued, \"Dry\", \"Eqp\" equipment malfunction)."
  2. Changed1 schema field changed
    • changedOutput schema / properties / historicalContext / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "comparisonBasis": {
      -        "description": "Fixed disclosure that percentileClass ranks an instantaneous reading against approved daily-mean percentiles — a cross-granularity approximation, not a flood-stage or drought determination. Present whenever historicalContext is non-null.",
      -        "type": "string"
      -      },
      -      "p05": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "5th percentile value in unitCode for this calendar month+day, based on the period of record. Null if that threshold is unavailable."
      -      },
      -      "p10": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "10th percentile value in unitCode for this calendar month+day. Null if unavailable."
      -      },
      -      "p25": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "25th percentile (lower quartile) in unitCode. Null if unavailable."
      -      },
      -      "p50": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Median (50th percentile) in unitCode for this calendar month+day. Null if unavailable."
      -      },
      -      "p75": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "75th percentile (upper quartile) in unitCode. Null if unavailable."
      -      },
      -      "p95": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "95th percentile value in unitCode for this calendar month+day. Null if unavailable."
      -      },
      -      "percentileClass": {
      -        "description": "Classification relative to the full period-of-record: record-high (≥ p95), above-normal (p75–p95), normal (p25–p75), below-normal (p10–p25), low (p05–p10), record-low (< p05). See percentileLabel for the threshold in plain language.",
      -        "enum": [
      -          "record-high",
      -          "above-normal",
      -          "normal",
      -          "below-normal",
      -          "low",
      -          "record-low",
      -          "unknown"
      -        ],
      -        "type": "string"
      -      },
      -      "percentileLabel": {
      -        "description": "Plain-language threshold for percentileClass (e.g. \"25th–75th percentile\"). The record-high and record-low classes mark percentile-of-record extremes (≥ p95 / < p05), not verified all-time records — this field says so where the class name does not.",
      -        "type": "string"
      -      },
      -      "periodOfRecord": {
      -        "description": "Range of years used to compute the percentile statistics (e.g. \"1930–2025\").",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "percentileClass",
      -      "percentileLabel",
      -      "p05",
      -      "p10",
      -      "p25",
      -      "p50",
      -      "p75",
      -      "p95",
      -      "periodOfRecord",
      -      "comparisonBasis"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "comparisonBasis": {
      +        "description": "Fixed disclosure that percentileClass ranks an instantaneous reading against approved daily-mean percentiles — a cross-granularity approximation, not a flood-stage or drought determination. Present whenever historicalContext is non-null.",
      +        "type": "string"
      +      },
      +      "p05": {
      +        "description": "5th percentile value in unitCode for this calendar month+day, based on the period of record. Null if that threshold is unavailable.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "p10": {
      +        "description": "10th percentile value in unitCode for this calendar month+day. Null if unavailable.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "p25": {
      +        "description": "25th percentile (lower quartile) in unitCode. Null if unavailable.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "p50": {
      +        "description": "Median (50th percentile) in unitCode for this calendar month+day. Null if unavailable.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "p75": {
      +        "description": "75th percentile (upper quartile) in unitCode. Null if unavailable.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "p95": {
      +        "description": "95th percentile value in unitCode for this calendar month+day. Null if unavailable.",
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "percentileClass": {
      +        "description": "Classification relative to the full period-of-record: record-high (≥ p95), above-normal (p75–p95), normal (p25–p75), below-normal (p10–p25), low (p05–p10), record-low (< p05). See percentileLabel for the threshold in plain language.",
      +        "enum": [
      +          "record-high",
      +          "above-normal",
      +          "normal",
      +          "below-normal",
      +          "low",
      +          "record-low",
      +          "unknown"
      +        ],
      +        "type": "string"
      +      },
      +      "percentileLabel": {
      +        "description": "Plain-language threshold for percentileClass (e.g. \"25th–75th percentile\"). The record-high and record-low classes mark percentile-of-record extremes (≥ p95 / < p05), not verified all-time records — this field says so where the class name does not.",
      +        "type": "string"
      +      },
      +      "periodOfRecord": {
      +        "description": "Range of years used to compute the percentile statistics (e.g. \"1930–2025\").",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "percentileClass",
      +      "percentileLabel",
      +      "p05",
      +      "p10",
      +      "p25",
      +      "p50",
      +      "p75",
      +      "p95",
      +      "periodOfRecord",
      +      "comparisonBasis"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  3. Changed6 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "siteNumber",
      +      "siteName",
      +      "parameterCd",
      +      "parameterName",
      +      "unitCode",
      +      "currentValue",
      +      "currentDateTime",
      +      "qualifiers",
      +      "historicalContext",
      +      "historicalContextStatus"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `no_data_for_parameter`: NWIS returned no IV data — the site may not exist, or may not measure the requested parameter. NWIS returns the same empty response for both cases. `invalid_request`: NWIS rejected the request. Input formats are validated against NWIS-accepted patterns before the call, so this surfaces a value that is well-formed but unacceptable upstream. `upstream_error`: NWIS IV or stat endpoint returned a 5xx error or timed out. Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "no_data_for_parameter",
      +            "invalid_request",
      +            "upstream_error"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "siteNumber",
      -  "siteName",
      -  "parameterCd",
      -  "parameterName",
      -  "unitCode",
      -  "currentValue",
      -  "currentDateTime",
      -  "qualifiers",
      -  "historicalContext",
      -  "historicalContextStatus"
      -]
  4. Changed1 schema field changed
    • changedOutput schema / properties / historicalContext / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "comparisonBasis": {
      -        "description": "Fixed disclosure that percentileClass ranks an instantaneous reading against approved daily-mean percentiles — a cross-granularity approximation, not a flood-stage or drought determination. Present whenever historicalContext is non-null; carried as its own field because schema description text is invisible wherever the raw value is read.",
      -        "type": "string"
      -      },
      -      "p05": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "5th percentile value in unitCode for this calendar month+day, based on the period of record. Null if that threshold is unavailable."
      -      },
      -      "p10": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "10th percentile value in unitCode for this calendar month+day. Null if unavailable."
      -      },
      -      "p25": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "25th percentile (lower quartile) in unitCode. Null if unavailable."
      -      },
      -      "p50": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Median (50th percentile) in unitCode for this calendar month+day. Null if unavailable."
      -      },
      -      "p75": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "75th percentile (upper quartile) in unitCode. Null if unavailable."
      -      },
      -      "p95": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "95th percentile value in unitCode for this calendar month+day. Null if unavailable."
      -      },
      -      "percentileClass": {
      -        "description": "Classification relative to the full period-of-record: record-high (≥ p95), above-normal (p75–p95), normal (p25–p75), below-normal (p10–p25), low (p05–p10), record-low (< p05). See percentileLabel for the threshold in plain language.",
      -        "enum": [
      -          "record-high",
      -          "above-normal",
      -          "normal",
      -          "below-normal",
      -          "low",
      -          "record-low",
      -          "unknown"
      -        ],
      -        "type": "string"
      -      },
      -      "percentileLabel": {
      -        "description": "Plain-language threshold for percentileClass (e.g. \"25th–75th percentile\"). The record-high and record-low classes mark percentile-of-record extremes (≥ p95 / < p05), not verified all-time records — this field says so where the class name does not. Report this alongside percentileClass rather than the class name alone.",
      -        "type": "string"
      -      },
      -      "periodOfRecord": {
      -        "description": "Range of years used to compute the percentile statistics (e.g. \"1930–2025\").",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "percentileClass",
      -      "percentileLabel",
      -      "p05",
      -      "p10",
      -      "p25",
      -      "p50",
      -      "p75",
      -      "p95",
      -      "periodOfRecord",
      -      "comparisonBasis"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "comparisonBasis": {
      +        "description": "Fixed disclosure that percentileClass ranks an instantaneous reading against approved daily-mean percentiles — a cross-granularity approximation, not a flood-stage or drought determination. Present whenever historicalContext is non-null.",
      +        "type": "string"
      +      },
      +      "p05": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "5th percentile value in unitCode for this calendar month+day, based on the period of record. Null if that threshold is unavailable."
      +      },
      +      "p10": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "10th percentile value in unitCode for this calendar month+day. Null if unavailable."
      +      },
      +      "p25": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "25th percentile (lower quartile) in unitCode. Null if unavailable."
      +      },
      +      "p50": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Median (50th percentile) in unitCode for this calendar month+day. Null if unavailable."
      +      },
      +      "p75": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "75th percentile (upper quartile) in unitCode. Null if unavailable."
      +      },
      +      "p95": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "95th percentile value in unitCode for this calendar month+day. Null if unavailable."
      +      },
      +      "percentileClass": {
      +        "description": "Classification relative to the full period-of-record: record-high (≥ p95), above-normal (p75–p95), normal (p25–p75), below-normal (p10–p25), low (p05–p10), record-low (< p05). See percentileLabel for the threshold in plain language.",
      +        "enum": [
      +          "record-high",
      +          "above-normal",
      +          "normal",
      +          "below-normal",
      +          "low",
      +          "record-low",
      +          "unknown"
      +        ],
      +        "type": "string"
      +      },
      +      "percentileLabel": {
      +        "description": "Plain-language threshold for percentileClass (e.g. \"25th–75th percentile\"). The record-high and record-low classes mark percentile-of-record extremes (≥ p95 / < p05), not verified all-time records — this field says so where the class name does not.",
      +        "type": "string"
      +      },
      +      "periodOfRecord": {
      +        "description": "Range of years used to compute the percentile statistics (e.g. \"1930–2025\").",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "percentileClass",
      +      "percentileLabel",
      +      "p05",
      +      "p10",
      +      "p25",
      +      "p50",
      +      "p75",
      +      "p95",
      +      "periodOfRecord",
      +      "comparisonBasis"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  5. Changed6 schema fields changed
    • addedInput schema / properties / parameterCd / pattern
      Added value: +"^\\d{5}$"
    • addedInput schema / properties / site / pattern
      Added value: +"^\\d{8,15}$"
    • changedOutput schema / properties / historicalContext / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "p05": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "5th percentile value in unitCode for this calendar month+day, based on the period of record. Null if that threshold is unavailable."
      -      },
      -      "p10": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "10th percentile value in unitCode for this calendar month+day. Null if unavailable."
      -      },
      -      "p25": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "25th percentile (lower quartile) in unitCode. Null if unavailable."
      -      },
      -      "p50": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Median (50th percentile) in unitCode for this calendar month+day. Null if unavailable."
      -      },
      -      "p75": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "75th percentile (upper quartile) in unitCode. Null if unavailable."
      -      },
      -      "p95": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "95th percentile value in unitCode for this calendar month+day. Null if unavailable."
      -      },
      -      "percentileClass": {
      -        "description": "Classification relative to the full period-of-record: record-high (≥ p95), above-normal (p75–p95), normal (p25–p75), below-normal (p10–p25), low (p05–p10), record-low (< p05). See percentileLabel for the threshold in plain language.",
      -        "enum": [
      -          "record-high",
      -          "above-normal",
      -          "normal",
      -          "below-normal",
      -          "low",
      -          "record-low",
      -          "unknown"
      -        ],
      -        "type": "string"
      -      },
      -      "percentileLabel": {
      -        "description": "Plain-language threshold for percentileClass (e.g. \"25th–75th percentile\"). The record-high and record-low classes mark percentile-of-record extremes (≥ p95 / < p05), not verified all-time records — this field says so where the class name does not. Report this alongside percentileClass rather than the class name alone.",
      -        "type": "string"
      -      },
      -      "periodOfRecord": {
      -        "description": "Range of years used to compute the percentile statistics (e.g. \"1930–2025\").",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "percentileClass",
      -      "percentileLabel",
      -      "p05",
      -      "p10",
      -      "p25",
      -      "p50",
      -      "p75",
      -      "p95",
      -      "periodOfRecord"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "comparisonBasis": {
      +        "description": "Fixed disclosure that percentileClass ranks an instantaneous reading against approved daily-mean percentiles — a cross-granularity approximation, not a flood-stage or drought determination. Present whenever historicalContext is non-null; carried as its own field because schema description text is invisible wherever the raw value is read.",
      +        "type": "string"
      +      },
      +      "p05": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "5th percentile value in unitCode for this calendar month+day, based on the period of record. Null if that threshold is unavailable."
      +      },
      +      "p10": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "10th percentile value in unitCode for this calendar month+day. Null if unavailable."
      +      },
      +      "p25": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "25th percentile (lower quartile) in unitCode. Null if unavailable."
      +      },
      +      "p50": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Median (50th percentile) in unitCode for this calendar month+day. Null if unavailable."
      +      },
      +      "p75": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "75th percentile (upper quartile) in unitCode. Null if unavailable."
      +      },
      +      "p95": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "95th percentile value in unitCode for this calendar month+day. Null if unavailable."
      +      },
      +      "percentileClass": {
      +        "description": "Classification relative to the full period-of-record: record-high (≥ p95), above-normal (p75–p95), normal (p25–p75), below-normal (p10–p25), low (p05–p10), record-low (< p05). See percentileLabel for the threshold in plain language.",
      +        "enum": [
      +          "record-high",
      +          "above-normal",
      +          "normal",
      +          "below-normal",
      +          "low",
      +          "record-low",
      +          "unknown"
      +        ],
      +        "type": "string"
      +      },
      +      "percentileLabel": {
      +        "description": "Plain-language threshold for percentileClass (e.g. \"25th–75th percentile\"). The record-high and record-low classes mark percentile-of-record extremes (≥ p95 / < p05), not verified all-time records — this field says so where the class name does not. Report this alongside percentileClass rather than the class name alone.",
      +        "type": "string"
      +      },
      +      "periodOfRecord": {
      +        "description": "Range of years used to compute the percentile statistics (e.g. \"1930–2025\").",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "percentileClass",
      +      "percentileLabel",
      +      "p05",
      +      "p10",
      +      "p25",
      +      "p50",
      +      "p75",
      +      "p95",
      +      "periodOfRecord",
      +      "comparisonBasis"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedOutput schema / properties / historicalContext / description
      Previous value: -"Historical percentile context. Null when the stat service has no data for this site."New value: +"Historical percentile context for the observation's calendar day. Non-null only when historicalContextStatus is \"available\"; see that field for why it is otherwise absent."
    • addedOutput schema / properties / historicalContextStatus
      Added value: +{
      +  "description": "Why historicalContext is or is not populated. 'available': percentiles for the observation's calendar day are present. 'no_matching_day': the stat table has rows but none for that calendar day. 'no_record': the stat table is empty — a new site, or a record too short to compute percentiles. 'unavailable': the statistics service call failed — a transient upstream error, not a statement about the site's record; retry shortly.",
      +  "enum": [
      +    "available",
      +    "no_matching_day",
      +    "no_record",
      +    "unavailable"
      +  ],
      +  "type": "string"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "siteNumber",
      -  "siteName",
      -  "parameterCd",
      -  "parameterName",
      -  "unitCode",
      -  "currentValue",
      -  "currentDateTime",
      -  "qualifiers",
      -  "historicalContext"
      -]New value: +[
      +  "siteNumber",
      +  "siteName",
      +  "parameterCd",
      +  "parameterName",
      +  "unitCode",
      +  "currentValue",
      +  "currentDateTime",
      +  "qualifiers",
      +  "historicalContext",
      +  "historicalContextStatus"
      +]
  6. Changed1 schema field changed
    • changedOutput schema / properties / historicalContext / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "p05": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "5th percentile value in unitCode for this calendar month+day, based on the period of record. Null if that threshold is unavailable."
      -      },
      -      "p10": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "10th percentile value in unitCode for this calendar month+day. Null if unavailable."
      -      },
      -      "p25": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "25th percentile (lower quartile) in unitCode. Null if unavailable."
      -      },
      -      "p50": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Median (50th percentile) in unitCode for this calendar month+day. Null if unavailable."
      -      },
      -      "p75": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "75th percentile (upper quartile) in unitCode. Null if unavailable."
      -      },
      -      "p95": {
      -        "anyOf": [
      -          {
      -            "type": "number"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "95th percentile value in unitCode for this calendar month+day. Null if unavailable."
      -      },
      -      "percentileClass": {
      -        "description": "Classification relative to the full period-of-record: record-high (≥ p95), above-normal (p75–p95), normal (p25–p75), below-normal (p10–p25), low (p05–p10), record-low (< p05).",
      -        "enum": [
      -          "record-high",
      -          "above-normal",
      -          "normal",
      -          "below-normal",
      -          "low",
      -          "record-low",
      -          "unknown"
      -        ],
      -        "type": "string"
      -      },
      -      "periodOfRecord": {
      -        "description": "Range of years used to compute the percentile statistics (e.g. \"1930–2025\").",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "percentileClass",
      -      "p05",
      -      "p10",
      -      "p25",
      -      "p50",
      -      "p75",
      -      "p95",
      -      "periodOfRecord"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "p05": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "5th percentile value in unitCode for this calendar month+day, based on the period of record. Null if that threshold is unavailable."
      +      },
      +      "p10": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "10th percentile value in unitCode for this calendar month+day. Null if unavailable."
      +      },
      +      "p25": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "25th percentile (lower quartile) in unitCode. Null if unavailable."
      +      },
      +      "p50": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Median (50th percentile) in unitCode for this calendar month+day. Null if unavailable."
      +      },
      +      "p75": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "75th percentile (upper quartile) in unitCode. Null if unavailable."
      +      },
      +      "p95": {
      +        "anyOf": [
      +          {
      +            "type": "number"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "95th percentile value in unitCode for this calendar month+day. Null if unavailable."
      +      },
      +      "percentileClass": {
      +        "description": "Classification relative to the full period-of-record: record-high (≥ p95), above-normal (p75–p95), normal (p25–p75), below-normal (p10–p25), low (p05–p10), record-low (< p05). See percentileLabel for the threshold in plain language.",
      +        "enum": [
      +          "record-high",
      +          "above-normal",
      +          "normal",
      +          "below-normal",
      +          "low",
      +          "record-low",
      +          "unknown"
      +        ],
      +        "type": "string"
      +      },
      +      "percentileLabel": {
      +        "description": "Plain-language threshold for percentileClass (e.g. \"25th–75th percentile\"). The record-high and record-low classes mark percentile-of-record extremes (≥ p95 / < p05), not verified all-time records — this field says so where the class name does not. Report this alongside percentileClass rather than the class name alone.",
      +        "type": "string"
      +      },
      +      "periodOfRecord": {
      +        "description": "Range of years used to compute the percentile statistics (e.g. \"1930–2025\").",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "percentileClass",
      +      "percentileLabel",
      +      "p05",
      +      "p10",
      +      "p25",
      +      "p50",
      +      "p75",
      +      "p95",
      +      "periodOfRecord"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  7. First observed

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the readOnly/openWorld/idempotent annotations, the description discloses many real behaviors: the ranking is approximate because the reading is instantaneous while percentiles are daily-mean, short records yield historicalContext=null rather than an error, no-data readings return an empty currentValue with qualifiers, and multi-sensor method selection is explained. This gives an agent a reliable model of what the tool will do in edge cases.

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?

The description front-loads the core purpose in the first sentence, then adds caveats in a logical order: approximation, short records, no-data behavior, and multi-sensor selection. It is long but every sentence earns its place because the tool has genuinely complex edge cases.

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?

Given the output schema and annotations, the description covers all behavior an agent needs to invoke and interpret the result correctly: it explains null historicalContext, empty currentValue, qualifier naming, method selection, and input resolution. There are no obvious gaps for selecting or calling this 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%, and both site and parameterCd already include formats, patterns, examples, and pointers to discovery tools. The description does not add parameter-level semantics beyond what the schema provides, 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 names a specific verb and resource: getting a USGS site's current reading, ranked against period-of-record daily-mean percentiles for the same calendar day. It sharply distinguishes itself by stating it produces a percentileClass rather than a flood-stage or drought determination, and it names sibling tools like water_get_readings for a different purpose.

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?

The description explicitly states when not to use this tool: it is not a flood-stage or drought determination and fetches no authoritative thresholds. It also gives actionable direction to use water_find_sites and water_list_parameters for resolving inputs, and notes that water_get_readings lists every sensor method when that is what the agent needs.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.