Skip to main content
Glama

usgs-water-mcp-server

Water Find Sites

water_find_sites
Read-onlyIdempotent

Find USGS water monitoring sites by bounding box, state, county, or HUC watershed code, filtered by site type and parameter availability. Returns site numbers, names, coordinates, types, altitude, and (in expanded mode) drainage area. Call this first — water_get_readings, water_get_series, and water_get_conditions all require a site number. Supply exactly one major filter — bbox, stateCd, countyCd, or huc; siteType, parameterCd, and hasDataTypeCd only narrow within it and cannot stand alone. Page through matches with limit/offset (500 per page); truncated=true means matches remain after the returned window and upstreamTotal holds the full count. When the match set exceeds 500 and DataCanvas is enabled, the complete set also stages to a canvas (canvas_id/table_name) — inspect it with water_dataframe_describe, then retrieve it with water_dataframe_query.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
hucNoHydrologic Unit Code (HUC) scoping results to a watershed. Either a 2-digit major HUC (e.g. "02" for the Mid-Atlantic region) or an 8-digit minor HUC (e.g. "02070008" for the Middle Potomac). NWIS accepts no other lengths. Major filter — supply exactly one of bbox, stateCd, countyCd, huc.
bboxNoBounding box as "west,south,east,north" in decimal degrees (e.g. "-77.5,38.5,-76.5,39.5" for the DC metro area). One of the four major filters — bbox, stateCd, countyCd, and huc are mutually exclusive with each other, and exactly one must be supplied.
limitNoMaximum sites to return inline, 1–500. Default 500 (the inline cap).
offsetNoNumber of matching sites to skip before returning results. Page through matches beyond the inline cap by advancing offset by limit. Default 0.
stateCdNo2-character US state abbreviation (e.g. "VA", "WA"). Returns all sites in the state for the given filters. Major filter — supply exactly one of bbox, stateCd, countyCd, huc.
countyCdNoFIPS county code(s) as bare 5-digit numbers — state and county digits concatenated, no separator (e.g. "51013" for Arlington, VA). Comma-separate up to 20 (e.g. "51059,51061"). The 5 digits already encode the state, so the code stands alone. Major filter — supply exactly one of bbox, stateCd, countyCd, huc.
siteTypeNoSite type filter. Common codes: "ST" (stream), "GW" (groundwater well), "LK" (lake/reservoir), "SP" (spring), "AT" (atmosphere), "OC" (ocean), "ES" (estuary). Comma-separate multiple types (e.g. "ST,GW").
canvas_idNoCanvas ID from a prior call to add this match set as a table on an existing canvas rather than creating a new one. Each distinct filter set gets its own table name, so re-running the identical query replaces its own table while a different query adds another alongside it. Applies only when the match set exceeds the inline cap and DataCanvas is enabled. Omit to start a fresh canvas.
siteOutputNo"basic" returns core identification fields. "expanded" adds drainage area, altitude, contributing area, and other metadata.basic
parameterCdNo5-digit parameter code to require at each returned site (e.g. "00060" for discharge). Use water_list_parameters to discover codes. Comma-separate multiple codes with no spaces (e.g. "00060,00065").
hasDataTypeCdNoRequire sites with data of this type. Common values: "iv" (real-time/instantaneous), "dv" (daily values), "gw" (groundwater). Comma-separate multiple types.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
errorNoPresent when the call failed. Absent on success.
sitesNoThe requested window of matching USGS monitoring sites — the slice starting at offset, at most limit long (500 max). upstreamTotal holds the full match count; canvas_id/table_name point to the staged full set when it exceeded the cap and DataCanvas is enabled.
totalNoNumber of sites returned inline in this response — at most limit, and 0 when offset is at or past upstreamTotal.
noticeNoAdvisory about the returned window: the staged canvas and how to read it, the filters to narrow by, the window actually returned, the valid offset range when the request landed past the end of the match set, or the fact that a supplied canvas_id went unused because nothing was staged.
filtersNoFilters applied to this query.
canvas_idNoCanvas ID for the DataCanvas holding the full, uncapped match set. Present only when the match set exceeded the 500-site cap and DataCanvas is enabled. Pass to water_dataframe_describe then water_dataframe_query to retrieve sites beyond the inline cap.
truncatedNoTrue when matches remain after the returned window (offset + total < upstreamTotal) — false on the last page, and false for a window starting past the end of the match set, where the notice names the valid offset range instead. Advance offset by limit for the next page, narrow filters (add bbox, countyCd, huc, siteType, parameterCd, or hasDataTypeCd), or when canvas_id is present read the staged set with water_dataframe_describe then water_dataframe_query.
table_nameNoDuckDB table name in the canvas holding all matching sites. Present when canvas_id is present. Use as the FROM target in water_dataframe_query SQL.
upstreamTotalNoTotal number of sites matching the query upstream, before limit/offset windowing. Equals total when the whole match set fits in one window.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed15 schema fields changed
    • changedInput schema / properties / bbox / description
      Previous value: -"Bounding box as \"west,south,east,north\" in decimal degrees (e.g. \"-77.5,38.5,-76.5,39.5\" for the DC metro area). Mutually exclusive with stateCd/countyCd/huc."New value: +"Bounding box as \"west,south,east,north\" in decimal degrees (e.g. \"-77.5,38.5,-76.5,39.5\" for the DC metro area). One of the four major filters — bbox, stateCd, countyCd, and huc are mutually exclusive with each other, and exactly one must be supplied."
    • changedInput schema / properties / canvas_id / description
      Previous value: -"Canvas ID from a prior call to stage the full match set into an existing canvas rather than creating a new one. Applies only when the result is truncated and DataCanvas is enabled. Omit to start a fresh canvas."New value: +"Canvas ID from a prior call to add this match set as a table on an existing canvas rather than creating a new one. Each distinct filter set gets its own table name, so re-running the identical query replaces its own table while a different query adds another alongside it. Applies only when the match set exceeds the inline cap and DataCanvas is enabled. Omit to start a fresh canvas."
    • changedInput schema / properties / countyCd / description
      Previous value: -"FIPS county code(s) as bare 5-digit numbers — state and county digits concatenated, no separator (e.g. \"51013\" for Arlington, VA). Comma-separate up to 20 (e.g. \"51059,51061\"). Use with stateCd for clarity."New value: +"FIPS county code(s) as bare 5-digit numbers — state and county digits concatenated, no separator (e.g. \"51013\" for Arlington, VA). Comma-separate up to 20 (e.g. \"51059,51061\"). The 5 digits already encode the state, so the code stands alone. Major filter — supply exactly one of bbox, stateCd, countyCd, huc."
    • changedInput schema / properties / huc / description
      Previous value: -"Hydrologic Unit Code (HUC) scoping results to a watershed. Either a 2-digit major HUC (e.g. \"02\" for the Mid-Atlantic region) or an 8-digit minor HUC (e.g. \"02070008\" for the Middle Potomac). NWIS accepts no other lengths."New value: +"Hydrologic Unit Code (HUC) scoping results to a watershed. Either a 2-digit major HUC (e.g. \"02\" for the Mid-Atlantic region) or an 8-digit minor HUC (e.g. \"02070008\" for the Middle Potomac). NWIS accepts no other lengths. Major filter — supply exactly one of bbox, stateCd, countyCd, huc."
    • addedInput schema / properties / limit
      Added value: +{
      +  "default": 500,
      +  "description": "Maximum sites to return inline, 1–500. Default 500 (the inline cap).",
      +  "maximum": 500,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / offset
      Added value: +{
      +  "default": 0,
      +  "description": "Number of matching sites to skip before returning results. Page through matches beyond the inline cap by advancing offset by limit. Default 0.",
      +  "maximum": 9007199254740991,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • changedInput schema / properties / stateCd / description
      Previous value: -"2-character US state abbreviation (e.g. \"VA\", \"WA\"). Returns all sites in the state for the given filters."New value: +"2-character US state abbreviation (e.g. \"VA\", \"WA\"). Returns all sites in the state for the given filters. Major filter — supply exactly one of bbox, stateCd, countyCd, huc."
    • changedOutput schema / properties / canvas_id / description
      Previous value: -"Canvas ID for the DataCanvas holding the full, uncapped match set. Present only when truncated=true and DataCanvas is enabled. Pass to water_dataframe_describe then water_dataframe_query to retrieve sites beyond the inline cap."New value: +"Canvas ID for the DataCanvas holding the full, uncapped match set. Present only when the match set exceeded the 500-site cap and DataCanvas is enabled. Pass to water_dataframe_describe then water_dataframe_query to retrieve sites beyond the inline cap."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_sites_found`: No sites match the given geographic and filter criteria. `invalid_request`: NWIS rejected the request. Filter formats are validated against NWIS-accepted patterns before the call, so this surfaces a well-formed value NWIS still refused (an unknown code, or an unsupported filter combination). `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_sites_found`: No sites match the given geographic and filter criteria. `missing_major_filter`: None of bbox, stateCd, countyCd, or huc was supplied. NWIS scopes every site query by exactly one of them; siteType, parameterCd, and hasDataTypeCd only narrow within that scope. `conflicting_major_filters`: More than one of bbox, stateCd, countyCd, and huc was supplied. NWIS accepts exactly one per request. `invalid_request`: NWIS rejected the request. Filter formats are pattern-validated and the major-filter rule is enforced before the call, so this surfaces a well-formed value NWIS still refused — an unknown state, county, HUC, parameter, or site-type code. `upstream_error`: NWIS returned a 5xx error or the request timed out. `canvas_not_found`: The supplied canvas_id names a canvas that never existed or has expired. Raised before the NWIS request, so no upstream call is spent on it. `canvas_capacity_exhausted`: canvas_id was omitted and a fresh canvas was needed to stage the match set, but this tenant already holds the maximum number of active canvases. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "no_sites_found",
      -  "invalid_request",
      -  "upstream_error"
      -]New value: +[
      +  "no_sites_found",
      +  "missing_major_filter",
      +  "conflicting_major_filters",
      +  "invalid_request",
      +  "upstream_error",
      +  "canvas_not_found",
      +  "canvas_capacity_exhausted"
      +]
    • changedOutput schema / properties / notice / description
      Previous value: -"Advisory when results were capped — points to the staged canvas when DataCanvas is enabled, otherwise to narrowing filters, for retrieving all matches."New value: +"Advisory about the returned window: the staged canvas and how to read it, the filters to narrow by, the window actually returned, the valid offset range when the request landed past the end of the match set, or the fact that a supplied canvas_id went unused because nothing was staged."
    • changedOutput schema / properties / sites / description
      Previous value: -"Matching USGS monitoring sites (capped at 500 inline; when truncated, upstreamTotal holds the full count and canvas_id/table_name point to the staged full set when DataCanvas is enabled)."New value: +"The requested window of matching USGS monitoring sites — the slice starting at offset, at most limit long (500 max). upstreamTotal holds the full match count; canvas_id/table_name point to the staged full set when it exceeded the cap and DataCanvas is enabled."
    • changedOutput schema / properties / total / description
      Previous value: -"Number of sites returned inline in this response (at most 500)."New value: +"Number of sites returned inline in this response — at most limit, and 0 when offset is at or past upstreamTotal."
    • changedOutput schema / properties / truncated / description
      Previous value: -"True when the upstream result set exceeded the 500-site cap. Query the full match set via water_dataframe_query when canvas_id is present, or narrow filters (add bbox, countyCd, huc, siteType, parameterCd, or hasDataTypeCd) to retrieve all matches."New value: +"True when matches remain after the returned window (offset + total < upstreamTotal) — false on the last page, and false for a window starting past the end of the match set, where the notice names the valid offset range instead. Advance offset by limit for the next page, narrow filters (add bbox, countyCd, huc, siteType, parameterCd, or hasDataTypeCd), or when canvas_id is present read the staged set with water_dataframe_describe then water_dataframe_query."
    • changedOutput schema / properties / upstreamTotal / description
      Previous value: -"Total number of sites matching the query upstream, before the 500-site cap was applied. Equals total when truncated=false."New value: +"Total number of sites matching the query upstream, before limit/offset windowing. Equals total when the whole match set fits in one window."
  2. Changed1 schema field changed
    • addedInput schema / properties / canvas_id / pattern
      Added value: +"^[A-Za-z0-9_-]{10}$"
  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": [
      +      "sites",
      +      "total",
      +      "truncated",
      +      "upstreamTotal",
      +      "filters"
      +    ]
      +  },
      +  {
      +    "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_sites_found`: No sites match the given geographic and filter criteria. `invalid_request`: NWIS rejected the request. Filter formats are validated against NWIS-accepted patterns before the call, so this surfaces a well-formed value NWIS still refused (an unknown code, or an unsupported filter combination). `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_sites_found",
      +            "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: -[
      -  "sites",
      -  "total",
      -  "truncated",
      -  "upstreamTotal",
      -  "filters"
      -]
  4. Changed1 schema field changed
    • changedOutput schema / properties / sites / items / properties / hucCd / description
      Previous value: -"Hydrologic Unit Code (HUC) of the watershed containing this site. Length varies by the level NWIS assigned the site — 8-digit (HUC8) and 12-digit (HUC12, e.g. \"020700081005\") values are both common, so do not assume a fixed width. Absent when NWIS assigns the site no HUC. Do not pass this value straight back as the huc input filter, which takes 2 or 8 digits only; HUC codes nest, so the first 8 digits are the containing HUC8 subbasin and are what that filter accepts."New value: +"Hydrologic Unit Code of the watershed containing this site; width varies (8-digit HUC8 and 12-digit HUC12, e.g. \"020700081005\", are both common — do not assume a fixed width), and absent when NWIS assigns none. Do not pass it straight back to the huc filter (which takes 2 or 8 digits); HUCs nest, so its first 8 digits are the containing HUC8 that filter accepts."
  5. Changed2 schema fields changed
    • changedOutput schema / properties / sites / items / properties / hucCd / description
      Previous value: -"Hydrologic Unit Code (HUC) of the watershed containing this site. Length varies by the level NWIS assigned the site — 8-digit (HUC8) and 12-digit (HUC12, e.g. \"020700081005\") values are both common, so do not assume a fixed width. Do not pass this value straight back as the huc input filter, which takes 2 or 8 digits only; HUC codes nest, so the first 8 digits are the containing HUC8 subbasin and are what that filter accepts."New value: +"Hydrologic Unit Code (HUC) of the watershed containing this site. Length varies by the level NWIS assigned the site — 8-digit (HUC8) and 12-digit (HUC12, e.g. \"020700081005\") values are both common, so do not assume a fixed width. Absent when NWIS assigns the site no HUC. Do not pass this value straight back as the huc input filter, which takes 2 or 8 digits only; HUC codes nest, so the first 8 digits are the containing HUC8 subbasin and are what that filter accepts."
    • changedOutput schema / properties / sites / items / required
      Previous value: -[
      -  "siteNumber",
      -  "siteName",
      -  "siteType",
      -  "latitude",
      -  "longitude",
      -  "hucCd"
      -]New value: +[
      +  "siteNumber",
      +  "siteName",
      +  "siteType",
      +  "latitude",
      +  "longitude"
      +]
  6. Changed7 schema fields changed
    • addedInput schema / properties / canvas_id
      Added value: +{
      +  "description": "Canvas ID from a prior call to stage the full match set into an existing canvas rather than creating a new one. Applies only when the result is truncated and DataCanvas is enabled. Omit to start a fresh canvas.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / canvas_id
      Added value: +{
      +  "description": "Canvas ID for the DataCanvas holding the full, uncapped match set. Present only when truncated=true and DataCanvas is enabled. Pass to water_dataframe_describe then water_dataframe_query to retrieve sites beyond the inline cap.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / notice / description
      Previous value: -"Advisory when results were capped — add narrowing filters to retrieve all matches."New value: +"Advisory when results were capped — points to the staged canvas when DataCanvas is enabled, otherwise to narrowing filters, for retrieving all matches."
    • changedOutput schema / properties / sites / description
      Previous value: -"Matching USGS monitoring sites (capped at 500; see truncated/upstreamTotal for overflow)."New value: +"Matching USGS monitoring sites (capped at 500 inline; when truncated, upstreamTotal holds the full count and canvas_id/table_name point to the staged full set when DataCanvas is enabled)."
    • addedOutput schema / properties / table_name
      Added value: +{
      +  "description": "DuckDB table name in the canvas holding all matching sites. Present when canvas_id is present. Use as the FROM target in water_dataframe_query SQL.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / total / description
      Previous value: -"Number of sites returned in this response (at most 500)."New value: +"Number of sites returned inline in this response (at most 500)."
    • changedOutput schema / properties / truncated / description
      Previous value: -"True when the upstream result set exceeded the 500-site cap. Narrow filters (add bbox, countyCd, huc, siteType, parameterCd, or hasDataTypeCd) to retrieve all matches."New value: +"True when the upstream result set exceeded the 500-site cap. Query the full match set via water_dataframe_query when canvas_id is present, or narrow filters (add bbox, countyCd, huc, siteType, parameterCd, or hasDataTypeCd) to retrieve all matches."
  7. Changed2 schema fields changed
    • addedOutput schema / properties / filters / properties / countyCd
      Added value: +{
      +  "description": "County FIPS filter applied, if any.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / sites / items / properties / altitude / description
      Previous value: -"Altitude of the gage datum in feet above sea level (NAVD 88 or NGVD 29). Populated only when siteOutput=\"expanded\"; absent in basic mode."New value: +"Altitude of the gage datum in feet above sea level (NAVD 88 or NGVD 29). Present in both basic and expanded modes when USGS records an altitude for the site."
  8. Changed9 schema fields changed
    • addedInput schema / properties / bbox / pattern
      Added value: +"^-?\\d+(\\.\\d+)?(,-?\\d+(\\.\\d+)?){3}$"
    • changedInput schema / properties / countyCd / description
      Previous value: -"FIPS county code(s) as \"SS:CCC\" or comma-separated list (e.g. \"51:013\" for Arlington, VA). Use with stateCd for clarity."New value: +"FIPS county code(s) as bare 5-digit numbers — state and county digits concatenated, no separator (e.g. \"51013\" for Arlington, VA). Comma-separate up to 20 (e.g. \"51059,51061\"). Use with stateCd for clarity."
    • addedInput schema / properties / countyCd / pattern
      Added value: +"^\\d{5}(,\\d{5}){0,19}$"
    • changedInput schema / properties / huc / description
      Previous value: -"Hydrologic Unit Code (HUC) — 2, 4, 6, or 8 digits (e.g. \"02070010\" for Potomac/Shenandoah). Scopes results to a watershed."New value: +"Hydrologic Unit Code (HUC) scoping results to a watershed. Either a 2-digit major HUC (e.g. \"02\" for the Mid-Atlantic region) or an 8-digit minor HUC (e.g. \"02070008\" for the Middle Potomac). NWIS accepts no other lengths."
    • addedInput schema / properties / huc / pattern
      Added value: +"^(\\d{2}|\\d{8})$"
    • changedInput schema / properties / parameterCd / description
      Previous value: -"5-digit parameter code to require at each returned site (e.g. \"00060\" for discharge). Use water_list_parameters to discover codes. Comma-separate multiple codes."New value: +"5-digit parameter code to require at each returned site (e.g. \"00060\" for discharge). Use water_list_parameters to discover codes. Comma-separate multiple codes with no spaces (e.g. \"00060,00065\")."
    • addedInput schema / properties / parameterCd / pattern
      Added value: +"^\\d{5}(,\\d{5})*$"
    • addedInput schema / properties / stateCd / pattern
      Added value: +"^[A-Za-z]{2}$"
    • changedOutput schema / properties / sites / items / properties / hucCd / description
      Previous value: -"8-digit Hydrologic Unit Code (HUC8) for the watershed containing this site."New value: +"Hydrologic Unit Code (HUC) of the watershed containing this site. Length varies by the level NWIS assigned the site — 8-digit (HUC8) and 12-digit (HUC12, e.g. \"020700081005\") values are both common, so do not assume a fixed width. Do not pass this value straight back as the huc input filter, which takes 2 or 8 digits only; HUC codes nest, so the first 8 digits are the containing HUC8 subbasin and are what that filter accepts."
  9. Changed12 schema fields changed
    • addedOutput schema / properties / notice
      Added value: +{
      +  "description": "Advisory when results were capped — add narrowing filters to retrieve all matches.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / sites / description
      Previous value: -"Matching USGS monitoring sites."New value: +"Matching USGS monitoring sites (capped at 500; see truncated/upstreamTotal for overflow)."
    • addedOutput schema / properties / sites / items / properties / altitude
      Added value: +{
      +  "description": "Altitude of the gage datum in feet above sea level (NAVD 88 or NGVD 29). Populated only when siteOutput=\"expanded\"; absent in basic mode.",
      +  "type": "number"
      +}
    • addedOutput schema / properties / sites / items / properties / contributingArea
      Added value: +{
      +  "description": "Contributing drainage area in square miles (may differ from drainageArea for regulated basins). Populated only when siteOutput=\"expanded\"; absent in basic mode.",
      +  "type": "number"
      +}
    • removedOutput schema / properties / sites / items / properties / dataTypes
      Removed value: -{
      -  "description": "Available data type codes at this site.",
      -  "items": {
      -    "description": "A data type code available at this site (e.g. \"iv\", \"dv\").",
      -    "type": "string"
      -  },
      -  "type": "array"
      -}
    • addedOutput schema / properties / sites / items / properties / drainageArea
      Added value: +{
      +  "description": "Total drainage area in square miles. Populated only when siteOutput=\"expanded\"; absent in basic mode.",
      +  "type": "number"
      +}
    • removedOutput schema / properties / sites / items / properties / parameterCds
      Removed value: -{
      -  "description": "Parameter codes available at this site. Present when siteOutput=\"expanded\" or when a parameterCd filter was applied; may be empty for basic output.",
      -  "items": {
      -    "description": "A parameter code available at this site (e.g. \"00060\").",
      -    "type": "string"
      -  },
      -  "type": "array"
      -}
    • changedOutput schema / properties / sites / items / required
      Previous value: -[
      -  "siteNumber",
      -  "siteName",
      -  "siteType",
      -  "latitude",
      -  "longitude",
      -  "hucCd",
      -  "dataTypes",
      -  "parameterCds"
      -]New value: +[
      +  "siteNumber",
      +  "siteName",
      +  "siteType",
      +  "latitude",
      +  "longitude",
      +  "hucCd"
      +]
    • changedOutput schema / properties / total / description
      Previous value: -"Total number of sites returned in this response."New value: +"Number of sites returned in this response (at most 500)."
    • addedOutput schema / properties / truncated
      Added value: +{
      +  "description": "True when the upstream result set exceeded the 500-site cap. Narrow filters (add bbox, countyCd, huc, siteType, parameterCd, or hasDataTypeCd) to retrieve all matches.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / upstreamTotal
      Added value: +{
      +  "description": "Total number of sites matching the query upstream, before the 500-site cap was applied. Equals total when truncated=false.",
      +  "maximum": 9007199254740991,
      +  "minimum": -9007199254740991,
      +  "type": "integer"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "sites",
      -  "total",
      -  "filters"
      -]New value: +[
      +  "sites",
      +  "total",
      +  "truncated",
      +  "upstreamTotal",
      +  "filters"
      +]
  10. First observed

TDQS

A5/5.0
Behavior5/5

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

Annotations already declare readOnlyHint, openWorldHint, and idempotentHint, but the description adds valuable behavior: paging with truncated/upstreamTotal semantics, canvas staging when matches exceed 500, and the rule that re-running identical queries replaces its own table. No contradictions with annotations.

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

Conciseness5/5

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

The description is information-dense but every sentence adds value, front-loading the core purpose and then layering constraints and edge-case behavior. The structure flows logically from purpose to usage to pagination to canvas handling, with no fluff.

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 exists, the description covers all necessary operational aspects: what filters are allowed, how pagination works, what the truncated/upstreamTotal fields mean, and the canvas workflow. An agent has everything needed to invoke this tool correctly.

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

Parameters5/5

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

Schema coverage is 100%, but the description goes beyond the schema by explaining the exclusivity of major filters, the dependency of minor filters, and the canvas_id behavior. It also clarifies that 'supply exactly one major filter' is a hard rule, which is not obvious from the schema alone.

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 states a specific action (find USGS water monitoring sites) with clear filtering dimensions (bounding box, state, county, HUC) and distinguishes itself from siblings by noting that water_get_readings, water_get_series, and water_get_conditions require a site number from this tool. This makes its purpose unambiguous and distinct.

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?

Explicitly instructs to 'Call this first' and explains the dependency of sibling tools on site numbers. It also enforces the 'exactly one major filter' rule and clarifies that minor filters (siteType, parameterCd, hasDataTypeCd) cannot stand alone, providing clear when-to-use and when-not-to-use guidance.

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.