Skip to main content
Glama
nellupop

river-watershed-mcp

by nellupop

river-watershed-mcp

An MCP (Model Context Protocol) server that gives AI agents live access to bioregional river and watershed data, pulled directly from public U.S. federal APIs:

  • USGS NWIS (National Water Information System) — real-time stream flow, gage height, water temperature

  • EPA WQP (Water Quality Portal) — water-quality results ranked against EPA-style compliance thresholds

Built for the "Encrypt/access the river data" bioregional sensor bounty (#450).

Tools exposed

Tool

What it does

get_stream_flow

Live discharge (cfs), gage height (ft), and water temp for a USGS site number

get_water_quality

Recent DO, pH, turbidity, temperature, E. coli, nitrate, phosphorus for a WQP site, each ranked good / fair / poor

get_basin_health

Composite 0–100 score across multiple sites in a basin (70% water-quality compliance, 30% live-flow gauge coverage)

All three return a common SensorReading JSON shape (see src/schema.ts):

{
  sensor_id: string;
  sensor_type: "stream_flow" | "water_quality" | "basin_health";
  location: { lat: number; lon: number; name?: string; huc_code?: string };
  parameters: Record<string, { value: number; unit: string; compliance?: "good"|"fair"|"poor"|"unknown" }>;
  observed_at: string; // ISO-8601
  source: "USGS-NWIS" | "EPA-WQP" | "COMPOSITE";
}

On the "bounty #450 sensor schema": I wasn't able to retrieve the exact spec text for that field layout from this build environment's network access. The schema above follows the common convention for bioregional sensor-network payloads (typed location + parameters map + provenance + timestamp). If the bounty spec differs, toSensorReading logic lives entirely in src/usgs.ts, src/epaWqp.ts, and src/basinHealth.ts — remap field names there.

Related MCP server: mcp-usgs-water-data

Setup

npm install
npm run build

Then point any MCP-compatible client (Claude Desktop, Claude Code, etc.) at:

{
  "mcpServers": {
    "river-watershed": {
      "command": "node",
      "args": ["/absolute/path/to/river-watershed-mcp/dist/index.js"]
    }
  }
}

Live demo

npm run build
npm run demo

src/demo.ts acts as an AI agent: it spawns the server over real MCP stdio transport, lists its tools, then calls all three against real Potomac River basin sites (USGS 01646500, 01651800).

Verified vs. not yet verified: the MCP protocol wiring (tool registration, JSON-RPC over stdio, request/response shape) was verified live in this repo's build environment — listTools() and callTool() both work end-to-end against the compiled server. The underlying USGS/EPA HTTP calls were not verified from that same environment, because its network allowlist doesn't include waterservices.usgs.gov or www.waterqualitydata.us (confirmed: a live call returns a clean fetch failed isError: true result — the server handles it correctly, but no real river data crossed the wire). Run npm run demo on a machine with normal internet access to see live values.

Example site numbers to try

  • 01646500 — Potomac River near Washington, DC

  • 01651800 — Northeast Branch Anacostia River at Riverdale, MD

  • 01474500 — Schuylkill River at Philadelphia, PA

Find any USGS site at https://waterdata.usgs.gov/nwis/inventory, and its matching WQP ID is usually USGS-<site number>.

License

MIT

Available Tools

3 tools
get_basin_healthA

Get a composite bioregional basin/watershed health score (0-100) across a set of USGS monitoring sites, combining EPA water-quality compliance with live flow-gauge coverage. Pass every USGS site number in the basin you want scored together.

ParametersJSON Schema
NameRequiredDescriptionDefault
basin_nameYesHuman-readable basin/watershed name, e.g. 'Anacostia River'
wqp_site_idsNoOptional matching EPA WQP site IDs (same order as usgs_site_numbers). Defaults to 'USGS-<site_number>' for each.
usgs_site_numbersYesUSGS site numbers within the basin

TDQS

A3.8/5.0
Behavior3/5

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

With no annotations, the description carries the behavioral burden but only partially meets it: it discloses the score range (0-100), the composite nature, and the contributing data sources. It does not explain how the composite is calculated, what happens for invalid or missing sites, or whether the return is just a score or includes supporting details.

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?

Two sentences with the purpose and data sources in the first sentence and the critical usage instruction in the second. Slight redundancy in 'bioregional basin/watershed' exists, but the description is well front-loaded and every sentence earns its place.

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

Completeness3/5

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

For a tool with 3 parameters, no output schema, and no annotations, the description provides the core inputs and score range but omits the exact return structure, error behavior, and the relationship between wqp_site_ids and usgs_site_numbers. It is adequate for a simple call but not fully self-contained.

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

Parameters3/5

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

Schema description coverage is 100%, so the baseline applies. The description adds meaning only by emphasizing that all USGS site numbers must be passed together, reinforcing the array semantics; it adds no extra meaning for basin_name or the optional wqp_site_ids beyond what the schema already provides.

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 action: 'Get a composite... health score (0-100)' across a set of USGS monitoring sites. It names the data sources (EPA water-quality compliance and live flow-gauge coverage), which clearly differentiates it from siblings get_stream_flow and get_water_quality.

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

Usage Guidelines4/5

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

Explicitly instructs the agent to 'Pass every USGS site number in the basin you want scored together,' which is the key usage requirement. It implies when to use this tool—when a combined basin-level score is needed rather than raw stream flow or water quality—but does not name explicit exclusions or fully contrast with siblings.

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

get_stream_flowA

Get live stream flow (discharge, gage height, water temperature) for a USGS monitoring site from the NWIS Instantaneous Values service. Site numbers are 8-15 digit USGS site codes, e.g. '01646500' (Potomac River near Washington, DC). Find sites at https://waterdata.usgs.gov/nwis/inventory.

ParametersJSON Schema
NameRequiredDescriptionDefault
usgs_site_numberYesUSGS site number, e.g. '01646500'

TDQS

A4.2/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It discloses that the data is live from the NWIS Instantaneous Values service and provides the site number format. It stops short of explicitly stating the operation is read-only or describing error cases, but for a single-param get tool this is adequate context.

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

Conciseness5/5

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

Two concise sentences. The first front-loads the purpose and the data fields; the second covers site number format and how to find sites. No fluff or redundancy.

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

Completeness4/5

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

There is no output schema, so the description should explain what is returned. It lists the three variables but not units or response format. The site-discovery URL and the service name give useful context, making it reasonably complete for a tool with one parameter.

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 description coverage is 100% for the sole parameter, so the baseline is 3. The description adds value by specifying the site number is 8-15 digits, giving a concrete example, and pointing to a site-discovery resource — all beyond the schema's generic description.

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 verb ('Get') and resource ('live stream flow') and explicitly lists the measurements (discharge, gage height, water temperature). This clearly distinguishes it from sibling tools focused on water quality and basin health.

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

Usage Guidelines3/5

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

Usage context is implied by the description — it is for retrieving stream flow data — but there is no explicit guidance on when to use this tool versus the siblings, nor any 'when-not' conditions. The site-inventory URL is operational context, not tool-selection guidance.

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

get_water_qualityA

Get recent water-quality results (dissolved oxygen, pH, turbidity, temperature, E. coli, nitrate, phosphorus) for a monitoring site from the EPA Water Quality Portal, each ranked good/fair/poor against EPA-style compliance thresholds. Site ID format is '-', e.g. 'USGS-01646500'.

ParametersJSON Schema
NameRequiredDescriptionDefault
wqp_site_idYesEPA WQP MonitoringLocationIdentifier, e.g. 'USGS-01646500'

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries full behavioral burden. It discloses the data source, the ranking methodology against EPA-style thresholds, and the required site ID format. It implies a read-only operation via 'Get' and describes the nature of results. While it doesn't cover error handling or pagination, it provides substantive behavioral context beyond a bare name.

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 two sentences, front-loaded with the core purpose, then lists the measured parameters, the ranking system, and the ID format. Every sentence adds value with no redundancy or filler.

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?

Despite having no output schema, the description effectively communicates what the tool returns (a list of recent results for the listed parameters, each ranked). It covers the required argument format, the data source, and the ranking scale. For a single-parameter read-only lookup, this is sufficient for correct invocation.

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

Parameters3/5

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

The schema already documents the single parameter with an example, and the description essentially repeats that format. Since schema coverage is 100%, the baseline is 3. The description adds a small clarification by explaining the ranking context, but it does not add meaning beyond what the schema provides.

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 clearly states the verb 'Get' with a specific resource 'recent water-quality results' and enumerates the exact parameters (dissolved oxygen, pH, turbidity, temperature, E. coli, nitrate, phosphorus). It also specifies the data source (EPA Water Quality Portal) and the ranking scheme, distinguishing it from siblings like get_stream_flow and get_basin_health.

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

Usage Guidelines4/5

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

The description provides clear context that this tool is for water-quality data from a monitoring site, which implicitly differentiates it from the sibling tools for flow and basin health. However, it does not explicitly state when to prefer this over alternatives or provide exclusion conditions, so it slightly misses the top tier.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv1.0.0
    • First observedget_basin_health
    • First observedget_stream_flow
    • First observedget_water_quality

TDQS

A4.2/5.0

Scored across 3 tools

Disambiguation5/5

Each tool targets a distinct data domain: stream flow is live hydrologic measurements, water quality is compliance-ranked sample results, and basin health is a composite score aggregating both. There is no overlap or ambiguity in purpose.

Naming Consistency5/5

All three tools follow the consistent verb_noun pattern: get_stream_flow, get_water_quality, get_basin_health. The naming is predictable and clearly indicates the resource being accessed.

Tool Count5/5

Three tools is well-scoped for a river watershed monitoring server. Each tool covers a major data category without unnecessary bloat or redundancy.

Completeness4/5

The core surface covers live flow, water quality, and an integrated health score, which addresses the primary needs of watershed monitoring. Minor gaps exist, such as no dedicated site metadata or historical data retrieval, but these are workarounds via external links and not critical to the main purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides access to real-time water data from the USGS Water Services API, allowing users to fetch instantaneous measurements like stream flow, gage height, temperature, and water quality parameters from thousands of monitoring stations across the US.
    3
    -
  • A
    license
    A
    quality
    B
    maintenance
    Enables querying USGS water data including real-time and historical streamflow, gage height, and water temperature from USGS gauges across the United States.
    3
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides lake conditions, fish-stocking records, fishing-favorability scoring, and live weather for outdoor recreation AI agents, powering trip-planning and fishing apps with 72,000+ US lakes and 293,000+ stocking events.
    MIT