Skip to main content
Glama

usgs-water-mcp-server

Water Get Readings

water_get_readings
Read-onlyIdempotent

Get the latest instantaneous (~15-min, real-time) values for up to 100 USGS sites in one call — per-site, per-parameter records with timestamp, value, unit, and provisional/approved qualifiers. Omitting parameterCd returns every parameter each site publishes. A site measuring one parameter with several sensors returns one series per method, each named by methodId and methodDescription. At most 100 series return per call — every site that returned data keeps at least one, and totalSeries reports how many NWIS returned; pass parameterCd or split the sites across calls to reach the rest. Each series returns only its 10 most recent records (totalValues reports the true count); truncated=true when either cap applied. Use water_get_series for a full date-range series. Sites NWIS returns nothing for are listed in missingSites, not dropped silently. Use water_find_sites first to discover site numbers and available parameters.

Input Schema

NameRequiredDescriptionDefault
sitesYesOne or more USGS site numbers to query. Maximum 100 per call.
periodNoISO 8601 duration for the lookback period (e.g. "PT2H" = last 2 hours, "P1D" = last 1 day, "P7D" = last 7 days). Default: "PT2H" (last 2 hours of readings). Widening it raises totalValues, but each series still returns only its 10 most recent records — use water_get_series to retrieve a full series.PT2H
parameterCdNoParameter codes to return. Omit to get every parameter each site publishes — one series per site, parameter, and method, so a large batch can exceed the 100-series cap. Use water_list_parameters to discover codes.

Output Schema

NameRequiredDescriptionDefault
errorNoPresent when the call failed. Absent on success.
queryNoQuery parameters used for this request.
totalNoNumber of site + parameter + method time series returned in readings (at most 100).
readingsNoTime series per site + parameter + method combination, in NWIS order (site, then parameter code, then method). A method block NWIS returned empty is omitted when another method of the same site and parameter carries values. At most 100: past that, series are kept round-robin across sites — every site's first series, then every site's second — with a site's series carrying values ahead of its empty ones, a series whose every record is no data counting as empty.
truncatedNoTrue when either cap applied. The series cap: totalSeries > total — pass parameterCd or split the sites across calls. The 10-record cap: some readings[].totalValues > values.length — use water_get_series for the full series.
totalSeriesNoNumber of site + parameter + method time series before the 100-series cap — an empty method block omitted as described under readings is not counted. Greater than total exactly when the cap dropped series; narrow with parameterCd or split the sites across calls to get the rest.
missingSitesNoRequested site numbers NWIS returned no series for — the site may not exist, or may not measure the requested parameter(s) in the requested period. Empty when every requested site returned data. Verify these with water_find_sites.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • 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 time series — the site(s) may not exist, or may not have data for the requested parameter(s) in the requested period. 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 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. 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 time series — the site(s) may not exist, or may not have data for the requested parameter(s) in the requested period. 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 returned a 5xx error or sent a response body that is not valid WaterML-JSON (cut off mid-document), and retrying did not clear it. `upstream_timeout`: The NWIS request exceeded its deadline. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "no_data_for_parameter",
      -  "invalid_request",
      -  "upstream_error"
      -]New value: +[
      +  "no_data_for_parameter",
      +  "invalid_request",
      +  "upstream_error",
      +  "upstream_timeout"
      +]
  2. Changed12 schema fields changed
    • changedInput schema / properties / parameterCd / description
      Previous value: -"Parameter codes to return. Omit to get all parameters available at each site. Use water_list_parameters to discover codes."New value: +"Parameter codes to return. Omit to get every parameter each site publishes — one series per site, parameter, and method, so a large batch can exceed the 100-series cap. Use water_list_parameters to discover codes."
    • changedOutput schema / anyOf
      Previous value: -[
      -  {
      -    "not": {
      -      "required": [
      -        "error"
      -      ]
      -    },
      -    "required": [
      -      "readings",
      -      "total",
      -      "truncated",
      -      "missingSites",
      -      "query"
      -    ]
      -  },
      -  {
      -    "required": [
      -      "error"
      -    ]
      -  }
      -]New value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "readings",
      +      "total",
      +      "totalSeries",
      +      "truncated",
      +      "missingSites",
      +      "query"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • 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 time series — the site(s) may not exist, or may not have data for the requested parameter(s) in the requested period. 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 returned a 5xx error or the request 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 time series — the site(s) may not exist, or may not have data for the requested parameter(s) in the requested period. 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 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. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / readings / description
      Previous value: -"Time series per site+parameter combination."New value: +"Time series per site + parameter + method combination, in NWIS order (site, then parameter code, then method). A method block NWIS returned empty is omitted when another method of the same site and parameter carries values. At most 100: past that, series are kept round-robin across sites — every site's first series, then every site's second — with a site's series carrying values ahead of its empty ones, a series whose every record is no data counting as empty."
    • changedOutput schema / properties / readings / items / description
      Previous value: -"Time series result for one site+parameter combination."New value: +"Time series result for one site + parameter + method combination."
    • addedOutput schema / properties / readings / items / properties / methodDescription
      Added value: +{
      +  "description": "NWIS description of the method, e.g. \"From multiparameter sonde\", \"[(2)]\", or \"7.1 ft from riverbed (top), [Discontinued]\". Null when NWIS leaves it blank, as it does for the default series at most single-sensor sites.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / readings / items / properties / methodId
      Added value: +{
      +  "description": "NWIS method ID of this series. A site can measure one parameter with several sensors or at several locations — each is its own method and its own entry in readings. Null only when NWIS returned the series with no method block.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • changedOutput schema / properties / readings / items / properties / values / items / properties / value / description
      Previous value: -"Measured value as a string (empty string means no data for that interval)."New value: +"Measured value as a string. Empty string when NWIS reported no value for that interval — qualifiers then give the reason (e.g. \"Ssn\" seasonal, \"Dis\" discontinued, \"Dry\", \"Eqp\" equipment malfunction)."
    • changedOutput schema / properties / readings / items / required
      Previous value: -[
      -  "siteNumber",
      -  "siteName",
      -  "parameterCd",
      -  "parameterName",
      -  "unitCode",
      -  "values",
      -  "totalValues"
      -]New value: +[
      +  "siteNumber",
      +  "siteName",
      +  "parameterCd",
      +  "parameterName",
      +  "unitCode",
      +  "methodId",
      +  "methodDescription",
      +  "values",
      +  "totalValues"
      +]
    • changedOutput schema / properties / total / description
      Previous value: -"Total number of site+parameter time series returned."New value: +"Number of site + parameter + method time series returned in readings (at most 100)."
    • addedOutput schema / properties / totalSeries
      Added value: +{
      +  "description": "Number of site + parameter + method time series before the 100-series cap — an empty method block omitted as described under readings is not counted. Greater than total exactly when the cap dropped series; narrow with parameterCd or split the sites across calls to get the rest.",
      +  "maximum": 9007199254740991,
      +  "minimum": -9007199254740991,
      +  "type": "integer"
      +}
    • changedOutput schema / properties / truncated / description
      Previous value: -"True when at least one series held more than 10 records and was capped. Per-series counts are in readings[].totalValues; use water_get_series for the full series."New value: +"True when either cap applied. The series cap: totalSeries > total — pass parameterCd or split the sites across calls. The 10-record cap: some readings[].totalValues > values.length — use water_get_series for the full series."
  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": [
      +      "readings",
      +      "total",
      +      "truncated",
      +      "missingSites",
      +      "query"
      +    ]
      +  },
      +  {
      +    "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 time series — the site(s) may not exist, or may not have data for the requested parameter(s) in the requested period. 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 returned a 5xx error or the request 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: -[
      -  "readings",
      -  "total",
      -  "truncated",
      -  "missingSites",
      -  "query"
      -]
  4. Changed10 schema fields changed
    • addedInput schema / properties / parameterCd / items / pattern
      Added value: +"^\\d{5}$"
    • changedInput schema / properties / period / description
      Previous value: -"ISO 8601 duration for the lookback period (e.g. \"PT2H\" = last 2 hours, \"P1D\" = last 1 day, \"P7D\" = last 7 days). Default: \"PT2H\" (last 2 hours of readings)."New value: +"ISO 8601 duration for the lookback period (e.g. \"PT2H\" = last 2 hours, \"P1D\" = last 1 day, \"P7D\" = last 7 days). Default: \"PT2H\" (last 2 hours of readings). Widening it raises totalValues, but each series still returns only its 10 most recent records — use water_get_series to retrieve a full series."
    • addedInput schema / properties / period / pattern
      Added value: +"^P(?!$)(\\d+Y)?(\\d+M)?(\\d+W)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+(\\.\\d+)?S)?)?$"
    • addedInput schema / properties / sites / items / pattern
      Added value: +"^\\d{8,15}$"
    • addedOutput schema / properties / missingSites
      Added value: +{
      +  "description": "Requested site numbers NWIS returned no series for — the site may not exist, or may not measure the requested parameter(s) in the requested period. Empty when every requested site returned data. Verify these with water_find_sites.",
      +  "items": {
      +    "description": "A requested USGS site number that returned no time series.",
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / readings / items / properties / totalValues
      Added value: +{
      +  "description": "Number of value records NWIS returned for this site and parameter over the requested period, before the 10-record cap. Equals values.length when nothing was capped.",
      +  "maximum": 9007199254740991,
      +  "minimum": -9007199254740991,
      +  "type": "integer"
      +}
    • changedOutput schema / properties / readings / items / properties / values / description
      Previous value: -"Time-ordered value records for this site and parameter."New value: +"Time-ordered value records for this site and parameter, capped at the most recent 10. Compare with totalValues to see whether the period held more; use water_get_series for the full series."
    • changedOutput schema / properties / readings / items / required
      Previous value: -[
      -  "siteNumber",
      -  "siteName",
      -  "parameterCd",
      -  "parameterName",
      -  "unitCode",
      -  "values"
      -]New value: +[
      +  "siteNumber",
      +  "siteName",
      +  "parameterCd",
      +  "parameterName",
      +  "unitCode",
      +  "values",
      +  "totalValues"
      +]
    • addedOutput schema / properties / truncated
      Added value: +{
      +  "description": "True when at least one series held more than 10 records and was capped. Per-series counts are in readings[].totalValues; use water_get_series for the full series.",
      +  "type": "boolean"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "readings",
      -  "total",
      -  "query"
      -]New value: +[
      +  "readings",
      +  "total",
      +  "truncated",
      +  "missingSites",
      +  "query"
      +]
  5. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Goes well beyond the readOnly/idempotent/openWorld annotations by disclosing the operational caps: max 100 series per call, at least one series per returned site, only the 10 most recent records per series, truncated=true when a cap applied, and missingSites for sites with no data. This is exactly the behavioral context an agent needs to interpret partial 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?

Dense but front-loaded, opening with the core purpose before moving to cap/truncation semantics. Most sentences carry distinct information, though the cap/truncation behavior is restated across several clauses and could be tightened.

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 capped, multi-site read tool with an output schema, the description covers everything an agent needs: discovery prerequisite, cap behavior, truncation signaling, missing-site reporting, and where to go for full series. Return-shape explanation is complementary rather than redundant.

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; the description adds meaning by describing the interaction between omitting parameterCd and hitting the 100-series cap, and by explaining that one parameter with several sensors yields one series per method named by methodId/methodDescription — return-structure detail the schema does not carry.

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 precise scope: latest instantaneous (~15-min) values for up to 100 USGS sites, returning per-site/per-parameter records. It explicitly distinguishes itself from sibling water_get_series, so an agent can route 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?

Explicit alternatives and sequencing: 'Use water_get_series for a full date-range series' and 'Use water_find_sites first to discover site numbers and available parameters.' It also states when to omit or pass parameterCd to avoid the 100-series cap.

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.