Skip to main content
Glama

Get Ocean Observations

noaa_marine_get_ocean_observations
Read-only

Live sub-surface oceanographic observations from an NDBC station's water-quality sensors: at each reported depth, water temperature, conductivity, salinity, dissolved oxygen as both saturation percent and concentration in ppm, chlorophyll, turbidity, pH, and redox potential. This is the water-column counterpart to noaa_marine_get_conditions, which returns surface meteorological and wave data — use this tool for what the water is doing below the surface, that one for weather and sea state at the buoy. It returns the most recent observation as one reading per reported depth, and most stations report a single depth while some report several at the same time; sensor coverage is sparse, most stations populating only water temperature and salinity, and any value the station did not report comes back null rather than a fabricated zero, as do latitude and longitude for a station absent from the NDBC active-stations list. Sub-surface sensors are on only a subset of NDBC stations, so find one with noaa_marine_find_stations using source="ndbc" and types=["water_quality"], which filters on NDBC's own water-quality catalog flag — the flag and actual .ocean availability drift, so this tool reads any station that serves the file and returns observations_not_found for one that does not.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
station_idYesNDBC station ID (5-character alphanumeric, e.g. "44033" or "TIBC1"). Obtain from noaa_marine_find_stations with source="ndbc" and types=["water_quality"].

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
errorNoPresent when the call failed. Absent on success.
sourceNoData source — always "ndbc" for this tool.
latitudeNoStation latitude in decimal degrees. Null when the station is absent from the NDBC active-stations list — the .ocean feed carries observations but no coordinates.
readingsNoPer-depth readings sharing the most recent observation timestamp, in NDBC source order.
longitudeNoStation longitude in decimal degrees. Null when the station is absent from the NDBC active-stations list.
station_idNoStation ID echoed from the request — for chaining.
observed_atNoISO 8601 UTC timestamp of the observation. Always a valid instant — a row whose upstream time columns are malformed is rejected rather than timestamped with the current time.
station_nameNoStation name from the NDBC active stations list.
reading_countNoNumber of per-depth readings in the latest observation (usually 1).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / station_id / description
      Previous value: -"NDBC station ID (5-character alphanumeric, e.g. \"44033\" or \"TIBC1\"). Obtain candidate IDs from noaa_marine_find_stations with source=\"ndbc\" — ocean-sensor coverage is not flagged in the catalog, so this is a best-effort call on any NDBC station."New value: +"NDBC station ID (5-character alphanumeric, e.g. \"44033\" or \"TIBC1\"). Obtain from noaa_marine_find_stations with source=\"ndbc\" and types=[\"water_quality\"]."
    • changedOutput schema / properties / observed_at / description
      Previous value: -"ISO 8601 UTC timestamp of the observation."New value: +"ISO 8601 UTC timestamp of the observation. Always a valid instant — a row whose upstream time columns are malformed is rejected rather than timestamped with the current time."
  2. Changed22 schema fields changed
    • removedOutput schema / properties / latitude / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / latitude / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / longitude / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / longitude / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / readings / items / properties / chlorophyll_ug_l / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / readings / items / properties / chlorophyll_ug_l / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / readings / items / properties / conductivity_ms_cm / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / readings / items / properties / conductivity_ms_cm / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / readings / items / properties / oxygen_percent / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / readings / items / properties / oxygen_percent / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / readings / items / properties / oxygen_ppm / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / readings / items / properties / oxygen_ppm / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / readings / items / properties / ph / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / readings / items / properties / ph / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / readings / items / properties / redox_mv / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / readings / items / properties / redox_mv / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / readings / items / properties / salinity_psu / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / readings / items / properties / salinity_psu / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / readings / items / properties / turbidity_ftu / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / readings / items / properties / turbidity_ftu / type
      Added value: +[
      +  "number",
      +  "null"
      +]
    • removedOutput schema / properties / readings / items / properties / water_temp_c / anyOf
      Removed value: -[
      -  {
      -    "type": "number"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedOutput schema / properties / readings / items / properties / water_temp_c / type
      Added value: +[
      +  "number",
      +  "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": [
      +      "station_id",
      +      "station_name",
      +      "latitude",
      +      "longitude",
      +      "observed_at",
      +      "source",
      +      "reading_count",
      +      "readings"
      +    ]
      +  },
      +  {
      +    "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: `observations_not_found`: NDBC returned 404 for the station — no .ocean oceanographic file exists for it. `no_ocean_data`: The .ocean file exists but has no usable data rows — station offline or every depth row missing. Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "observations_not_found",
      +            "no_ocean_data"
      +          ],
      +          "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: -[
      -  "station_id",
      -  "station_name",
      -  "latitude",
      -  "longitude",
      -  "observed_at",
      -  "source",
      -  "reading_count",
      -  "readings"
      -]
  4. Added

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the readOnlyHint and openWorldHint annotations, the description discloses important behavioral traits: it returns one reading per reported depth, most stations report a single depth, sensor coverage is sparse, missing values come back as null rather than fabricated zeros, and latitude/longitude may be null for stations absent from the active-stations list. It also states that the tool reads any station serving the file and returns observations_not_found otherwise, which is valuable operational context.

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?

The description is dense and front-loaded with the core purpose, then the sibling distinction, then behavioral details and station-selection guidance. It is long but every sentence carries meaningful information; the main weakness is that it is one sprawling paragraph rather than broken into scannable sections, but for a complex domain this is acceptable.

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 single-parameter read-only tool with an output schema, the description is remarkably complete. It covers the data variables, depth behavior, sparse coverage, null handling, station discovery, catalog drift, and the observations_not_found failure mode. Nothing an agent needs to select and call this tool correctly is missing.

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% for the single station_id parameter, so the baseline is 3. The description adds practical value by explaining how to discover suitable station IDs, clarifying that station IDs are 5-character alphanumeric strings from NDBC, and warning that the water-quality catalog flag can drift from actual data availability. This goes beyond the schema's basic parameter 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 names a specific resource (NDBC station water-quality sensors), a specific action (get live sub-surface oceanographic observations), and enumerates the returned variables. It also explicitly distinguishes itself from noaa_marine_get_conditions, so an agent can immediately tell which tool applies to water-column data versus surface weather and waves.

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 to use this tool versus noaa_marine_get_conditions: use this for what the water is doing below the surface, that one for weather and sea state at the buoy. It also instructs the agent to find stations with noaa_marine_find_stations using source='ndbc' and types=['water_quality'], and warns about the drift between the catalog flag and actual .ocean availability.

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.