Releases: cyanheads/usgs-water-mcp-server
Release list
v0.2.2: Error contract delivery
Error contract delivery
Wires declared error recovery hints through to callers, and closes two water_dataframe_query gaps: silent truncation and canvas-internal error wording.
- Every ctx.fail call site across all seven tools and the site resource now delivers its errors[] recovery hint via ctx.recoveryFor() (#24)
- water_dataframe_query returns a new truncated output field — true when the 10,000-row cap capped the result (#23)
- water_dataframe_query's non-SELECT/multi-statement rejections state its own read-only SELECT contract instead of the canvas engine's registerTable/drop/clear wording; missing-table and system-catalog reads get their own table_not_found / system_catalog_access reasons (#25)
- water_get_series drops its unreachable site_not_found errors[] entry (#26)
v0.2.1: Definition language accuracy across the MCP surface
Definition language accuracy across the MCP surface
Fixed:
water_dataframe_describe/water_dataframe_querynamed onlywater_get_seriesas a canvas producer — both now namewater_find_sites, whose full match set has staged to a canvas since 0.1.12.row_countonwater_dataframe_querycounts rows returned, not rows matched; the description now says so and discloses that a match over 10,000 rows truncates silently. Thesqlinput drops its series-only column list for a pointer towater_dataframe_describe.water_get_conditionsno longer blames the gage for an empty stat table — NWIS publishes no daily-statistics percentile product at all for some parameters (commonly gage height, 00065). Its no-current-reading error now names the two-hour lookback and points atwater_get_series.- Server instructions: parameter 00065 is "Gage height".
Changed:
- Tool, resource, and server-instruction descriptions are single strings rather than concatenated fragments; the
water_find_sites,water_get_readings,water_get_series, andwater_get_conditionsdescriptions were also shortened.
Dependency bumps:
@biomejs/biome^2.5.0 → 2.5.4 (exact pin)
123 tests pass; bun run devcheck clean.
v0.2.0: hucCd optional on water_find_sites
hucCd optional on water_find_sites
water_find_sites and the usgs-water://site/{siteId} resource now omit hucCd for sites USGS NWIS assigns no Hydrologic Unit Code, instead of backfilling an empty string.
Breaking Changes:
- hucCd is now optional on water_find_sites sites[].hucCd and the usgs-water://site/{siteId} resource. It is omitted when NWIS assigns the site no HUC (previously an empty string). Migration: treat hucCd as possibly-absent, guarding for undefined and reading absence as "no HUC assigned" rather than the former "" placeholder. (#22)
Fixed:
- Bare
**HUC:**label /hucCd: ""for sites with no HUC. hucCd is now omitted like every sparse sibling field (stateCd, countyCd, drainageArea, altitude, contributingArea); the HUC/State/County line renders only the parts present, and canvas staging carrieshuc_cd: null. (#22)
123 tests pass; bun run devcheck clean.
v0.1.13: content[] rendering parity and accurate spillover notice
content[] rendering parity and accurate spillover notice
Rendering-correctness fixes — content[] now carries the same data structuredContent already returned.
Fixed:
water_get_seriesrenders every returned value in content[], not just the last 20 (#16)water_find_sitesrenders altitude independent of drainageArea, so basic-mode sites no longer drop it (#16)water_find_sitesno longer emits a literalnotice: undefinedon the non-truncated path (#16)water_get_seriesspillover notice reports the real preview count instead of a fixed 500 (#19)
120 tests pass; bun run devcheck clean.
v0.1.12: water_find_sites DataCanvas spillover
water_find_sites DataCanvas spillover
Large match sets past the 500-site inline cap now stage the full result to a DuckDB canvas for gap-free retrieval.
Added:
water_find_sitesstages the full match set to a DataCanvas when a query exceeds the 500-site inline cap and a canvas provider is enabled; the response carriescanvas_idandtable_nameto retrieve every match past the cap viawater_dataframe_query(#6)- Optional
canvas_idinput onwater_find_sitesto stage into an existing canvas (#6)
Changed:
water_find_sitestruncation notice andformat()surface the stagedcanvas_id/table_namewhen DataCanvas is enabled; the inline cap +truncated/upstreamTotalfallback is unchanged when it is off (#6)
117 tests pass; bun run devcheck clean.
v0.1.11: countyCd query echo, site-resource validation, and site-metadata doc corrections
countyCd query echo, site-resource validation, and site-metadata doc corrections
Added:
water_find_sitesechoes thecountyCdfilter in enrichment + trailer (#4)usgs-water://site/{siteId}declares typednot_found/invalid_request/upstream_errorreasons (#21)
Changed:
usgs-water://site/{siteId}validatessiteIdvia the sharedSiteNumberSchemaat the resource edge (#21)
Fixed:
- Dropped the stale "available data types / parameters" claim from the site resource, README, and design doc (#7)
- Corrected
altitude: present in both basic and expanded site-output modes, not expanded-only (#7)
113 tests pass; bun run devcheck clean.
v0.1.10: water_get_conditions edge validation and honest historical context
water_get_conditions edge validation and honest historical context
Added:
historicalContextStatusenum (available/no_matching_day/no_record/unavailable) reporting why historical context is present or absent (#20)historicalContext.comparisonBasisdisclosing the instantaneous-vs-daily-mean approximation (#17)invalid_requesterror reason for well-formed inputs NWIS still rejects (#18)
Changed:
site/parameterCdvalidated via the shared SiteNumberSchema/ParameterCdSchema; patterns now advertise in the JSON Schema (#18)- Dropped the flood/drought framing for a "how unusual is this reading" ranking (#17)
Fixed:
- Failed getStats no longer masquerades as an empty stat table — now a captured tagged outcome (#20)
- Upstream-error classification uses classifyNwisFailure() (err.code) instead of the substring match that missed real 5xx messages (#18)
Dependency bumps:
tsc-alias^1.8.17 (1.9.0 → 1.9.1)
108 tests pass; bun run devcheck clean.
v0.1.9: Conditions timezone fix, percentileLabel, and hucCd doc correction
Conditions timezone fix, percentileLabel, and hucCd doc correction
Fixes a midnight timezone bug in water_get_conditions' stat-row matching, adds a percentileLabel field, and corrects the hucCd width claim.
Added:
water_get_conditionsgainshistoricalContext.percentileLabel— a plain-language threshold string alongsidepercentileClass(#14)
Fixed:
water_get_conditionsstat-row selection now matches the observation's own calendar date instead of the runtime's local timezone, which could pick the neighboring day's percentiles near midnight (#9)hucCd.describe()text no longer claims a fixed 8-digit width — NWIS returns 8- and 12-digit codes depending on the level assigned (#13)
101 tests pass; bun run devcheck clean.
v0.1.8: validated NWIS inputs and bounded readings output
validated NWIS inputs and bounded readings output
Closes three tracked issues in NWIS input handling and the water_get_readings batch output; adopts the mcp-ts-core 0.10.14 supply-chain baseline.
Added
water_get_readingstotalValues/truncated— each series capped at its 10 most recent records, with the true upstream count and cap flag reachingstructuredContent(#10)water_get_readingsmissingSites— requested sites NWIS returned no series for, named instead of dropped (#11)bunfig.tomlsupply-chain guards —minimumReleaseAge(3-day hold,@cyanheads/mcp-ts-coreexcluded) and a Socket install scanner
Changed
- Dockerfile drops the
apt-get python3 make g++toolchain stage — the DuckDB binding now installs as a prebuilt platform package; base image pinned tooven/bun:1.3.14
Fixed
water_find_sites,water_get_readings,water_get_series—invalid_filter/invalid_site_formatcollapse intoinvalid_request, which carries the NWIS rejection message verbatim instead of guessing the field from wrapper text; newsrc/services/nwis/input-schemas.tsrejects malformed values before the call (#10, #11, #12)huc/countyCd.describe()text corrected — NWIS accepts only 2- or 8-digit HUCs and bare 5-digit FIPS codes (#12)
Dependencies
@cyanheads/mcp-ts-core^0.10.9 → ^0.10.14@types/node^26.0.0 → ^26.1.1ignore^7.0.5 → ^7.0.6vitest^4.1.9 → ^4.1.10- New:
@socketsecurity/bun-security-scanner^1.1.2 bun auditclears all 7 previously-flagged advisories (0 remaining)
98 tests pass; bun run devcheck clean.
v0.1.7: Sanitize CANVAS_PROVIDER_TYPE from agent-facing canvas-disabled surfaces
Sanitize CANVAS_PROVIDER_TYPE from agent-facing canvas-disabled surfaces
Follow-up to #2 (which sanitized the tool descriptions). The operator-set env var no longer leaks to agents through the dataframe-tool error contract or the server instructions.
Changed:
water_dataframe_describe/water_dataframe_querycanvas_disabledpath: error message anderrors[]when/recoveryno longer nameCANVAS_PROVIDER_TYPE; agent-facing error now points towater_get_series, and the env-var hint moves toctx.logfor self-hosters (#8)- Server-level
instructions: thewater_get_seriesspillover note dropsset CANVAS_PROVIDER_TYPE=duckdbfor behavior-level phrasing (#8)
73 tests pass; bun run devcheck clean.