io.github.cyanheads/noaa-marine-mcp-server

السجل الرسمي أخرى

Find NOAA tide stations and NDBC buoys, fetch tide predictions, currents, and live conditions.

ماذا يمكنك أن تفعل مع io.github.cyanheads/noaa-marine-mcp-server؟

  • CO-OPS data and metadata APIs plus the NDBC active-stations catalog and realtime2 feeds (.txt, .adcp, .ocean), with station catalogs cached in memory for 6 hours; CO-OPS requests carry application= from NOAA_APPLICATION_ID
  • Station IDs never cross sources: CO-OPS tide and water-level IDs are numeric (9447130), CO-OPS current IDs alphanumeric (ACT4176), NDBC IDs 5-character codes (46041)
  • CO-OPS tools take begin_date / end_date as YYYYMMDD or YYYY-MM-DD and check the calendar and each tool's range ceiling before calling (invalid_date_range, date_range_exceeded); heights default to MLLW, and a datum the station lacks is `datum_una...
  • CO-OPS verifies hourly, high_low, daily_mean, and monthly means once a month, for the prior month: an empty window ending on or after the first of the prior month is verified_data_lag, an earlier one no_data
  • CO-OPS answers a burst of requests with HTTP 403 for about two minutes; the CO-OPS data tools report it as a retryable upstream_throttled whose recovery names the wait
  • Byte-bounded paging on the four CO-OPS series tools: a range that fits returns whole, and a longer one returns a leading page with rows_matched, rows_returned, page_offset, and next_offset, walked with offset (limit shrinks a page)
  • Missing means null or omitted, never fabricated: NDBC MM markers become null, blank CO-OPS values are dropped, and quality is left out rather than defaulted
  • Discriminated fields: station source (coops | ndbc), capability type, NDBC platform, and prediction_class, with datum and units echoed on every CO-OPS height response, so callers branch on data, not string parsing

التثبيت

أضف هذا إلى إعدادات MCP في عميلك (Claude Desktop: claude_desktop_config.json، وCursor: ‏.cursor/mcp.json، ويستخدم VS Code وغيره الصيغة نفسها «mcpServers»).

Remote (streamable-http)
Claude Code
claude mcp add --transport http noaa-marine-mcp-server 'https://noaa-marine.caseyjhand.com/mcp'
إعداد JSON (Claude Desktop وCursor وVS Code)
{
    "mcpServers": {
        "noaa-marine-mcp-server": {
            "type": "http",
            "url": "https://noaa-marine.caseyjhand.com/mcp"
        }
    }
}
NPM package @cyanheads/noaa-marine-mcp-server
Claude Code
claude mcp add noaa-marine-mcp-server -e 'NOAA_APPLICATION_ID=noaa-marine-mcp-server' -e 'NOAA_CLAMP_LIMITS=true' -e 'MCP_LOG_LEVEL=info' -- npx -y @cyanheads/noaa-marine-mcp-server@0.7.1
إعداد JSON (Claude Desktop وCursor وVS Code)
{
    "mcpServers": {
        "noaa-marine-mcp-server": {
            "command": "npx",
            "args": [
                "-y",
                "@cyanheads/noaa-marine-mcp-server@0.7.1"
            ],
            "env": {
                "NOAA_APPLICATION_ID": "noaa-marine-mcp-server",
                "NOAA_CLAMP_LIMITS": "true",
                "MCP_LOG_LEVEL": "info"
            }
        }
    }
}

متغيرات البيئة

  • NOAA_APPLICATION_ID Courtesy identifier sent as application= on CO-OPS requests. Defaults to noaa-marine-mcp-server.
  • NOAA_CLAMP_LIMITS Clamp a limit above its cap (1000 rows on the series tools, 200 stations on noaa_marine_find_stations) to the cap with a notice. Set false to advertise and enforce each cap as a schema maximum instead.
  • MCP_LOG_LEVEL Sets the minimum log level for output (e.g., 'debug', 'info', 'warn').
NPM package @cyanheads/noaa-marine-mcp-server
Claude Code
claude mcp add noaa-marine-mcp-server -e 'MCP_TRANSPORT_TYPE=<MCP_TRANSPORT_TYPE>' -e 'NOAA_APPLICATION_ID=noaa-marine-mcp-server' -e 'NOAA_CLAMP_LIMITS=true' -e 'MCP_HTTP_HOST=127.0.0.1' -e 'MCP_HTTP_PORT=3010' -e 'MCP_HTTP_ENDPOINT_PATH=/mcp' -e 'MCP_AUTH_MODE=none' -e 'MCP_LOG_LEVEL=info' -- npx -y @cyanheads/noaa-marine-mcp-server@0.7.1
إعداد JSON (Claude Desktop وCursor وVS Code)
{
    "mcpServers": {
        "noaa-marine-mcp-server": {
            "command": "npx",
            "args": [
                "-y",
                "@cyanheads/noaa-marine-mcp-server@0.7.1"
            ],
            "env": {
                "MCP_TRANSPORT_TYPE": "<MCP_TRANSPORT_TYPE>",
                "NOAA_APPLICATION_ID": "noaa-marine-mcp-server",
                "NOAA_CLAMP_LIMITS": "true",
                "MCP_HTTP_HOST": "127.0.0.1",
                "MCP_HTTP_PORT": "3010",
                "MCP_HTTP_ENDPOINT_PATH": "/mcp",
                "MCP_AUTH_MODE": "none",
                "MCP_LOG_LEVEL": "info"
            }
        }
    }
}

متغيرات البيئة

  • MCP_TRANSPORT_TYPE Selects the HTTP transport.
  • NOAA_APPLICATION_ID Courtesy identifier sent as application= on CO-OPS requests. Defaults to noaa-marine-mcp-server.
  • NOAA_CLAMP_LIMITS Clamp a limit above its cap (1000 rows on the series tools, 200 stations on noaa_marine_find_stations) to the cap with a notice. Set false to advertise and enforce each cap as a schema maximum instead.
  • MCP_HTTP_HOST The hostname for the HTTP server.
  • MCP_HTTP_PORT The port to run the HTTP server on.
  • MCP_HTTP_ENDPOINT_PATH The endpoint path for the MCP server.
  • MCP_AUTH_MODE Authentication mode to use: 'none', 'jwt', or 'oauth'.
  • MCP_LOG_LEVEL Sets the minimum log level for output (e.g., 'debug', 'info', 'warn').

التوثيق

مأخوذ من ملف README للمشروع على GitHub ويُحدَّث أسبوعيًا. تفتح الروابط على GitHub.

المحتويات
  1. @cyanheads/noaa-marine-mcp-server
  2. Overview
  3. Capability reference
  4. Features
  5. Getting started
  6. Configuration
  7. Running the server
  8. Project structure
  9. Development guide
  10. Contributing
  11. License

@cyanheads/noaa-marine-mcp-server

Find NOAA tide stations and NDBC buoys, fetch tide predictions, water levels, tidal currents, and live buoy conditions via MCP. STDIO or Streamable HTTP.

8 Tools • 1 Resource

Public Hosted Server: https://noaa-marine.caseyjhand.com/mcp


Overview

US tides, currents, water levels, and buoy observations from NOAA CO-OPS and NDBC. Find coastal stations and buoys, then fetch tide and tidal-current predictions, observed and monthly-mean water levels, and live buoy conditions, current profiles, and water-column readings. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.

Tools
ToolDescription
noaa_marine_find_stationsFind CO-OPS tide, water-level, and current stations and NDBC buoys by location, name, ID, state, or capability
noaa_marine_get_tide_predictionsHigh/low tide predictions or a 6-minute curve for a CO-OPS tide station
noaa_marine_get_water_levelObserved water level at four cadences, paired with predictions and a storm-surge residual
noaa_marine_get_monthly_meansVerified monthly tidal datums and extremes for a CO-OPS water-level station
noaa_marine_get_currentsCO-OPS tidal-current predictions: max flood, max ebb, and slack events, or a 6-minute curve
noaa_marine_get_conditionsLive NDBC buoy conditions: waves, wind, sea-surface and air temperature, pressure
noaa_marine_get_current_profileObserved ocean-current depth profile from an NDBC ADCP buoy
noaa_marine_get_ocean_observationsSub-surface water-column readings (temperature, salinity, oxygen, and more) from an NDBC station
Resources
ResourceDescription
noaa-marine://station/{station_id}Metadata for a CO-OPS or NDBC station: name, coordinates, source, capabilities, prediction class, platform

Everything in the resource except NDBC owner is also on noaa_marine_find_stations rows, for clients that only call tools.

Capability reference

noaa_marine_find_stations tool
  • Filters combine: latitude + longitude with radius_km (default 100, max 1000), query (name or ID substring on both sources; an exact ID leads unless sorting by distance), state (CO-OPS only), source (coops / ndbc / all), and types (tide, current, water_level, met, current_profile, water_quality, or the platform class buoy); limit defaults to 20, max 200
  • Each station carries source, capabilities, type, and for NDBC a platform; CO-OPS rows add state (state_derived: true when borrowed from the nearest state-bearing station within 25 km), a tide prediction_class (reference, or subordinate with reference_id), and current bins[] giving each bin's number, depth in feet, and class
  • total_found and truncated report the count before limit; zero matches is a success with applied_search, a partial catalog read is flagged in sources, and total catalog failure is sources_unavailable; only one of latitude/longitude is incomplete_coordinates

noaa_marine_get_tide_predictions tool
  • interval hilo (default) or 6min, up to 365 days; ten datums (MLLW, MHHW, MHW, MTL, MSL, MLW, DTL, NAVD, STND, CRD), time_zone (lst_ldt, gmt, lst), and units (english feet, metric meters)
  • 6min works at reference stations only: a subordinate station fails as subordinate_no_6min naming its reference station, and a Great Lakes station is no_predictions, pointing to noaa_marine_get_water_level
  • Other failures: invalid_date_range, date_range_exceeded, station_not_found, datum_unavailable (naming the planes the station carries), and upstream_throttled, a retryable CO-OPS HTTP 403 that clears in a couple of minutes

noaa_marine_get_water_level tool
  • interval 6min (default, 31 days), hourly or high_low (365 days), or daily_mean (3,655 days, Great Lakes only, always in LST; a coastal station is great_lakes_only); thirteen datums (MLLW, MHHW, MHW, MTL, MSL, MLW, NAVD, STND, IGLD, LWD, CRD, LWI, HWI)
  • Observations carry quality (p / v, 6min only), sigma (6min and hourly), and type (H / HH / L / LL, high_low only); slots with no reading are dropped and counted in gaps_dropped
  • Paired predictions at the matching cadence (none on daily_mean), with predictions_status (empty / unavailable) explaining an empty series; residual_summary (max_surge, max_drawdown) covers the whole matched range, on 6min and hourly only. Failures: invalid_date_range, date_range_exceeded, station_not_found, datum_unavailable, no_data, verified_data_lag (a coarser-cadence window ending on or after the first day of the prior month, which CO-OPS may not have verified yet), and upstream_throttled

noaa_marine_get_monthly_means tool
  • Up to 73,000 days per request; eleven datums (MLLW, MHHW, MHW, MTL, MSL, MLW, NAVD, STND, IGLD, LWD, CRD) in english feet or metric meters; the first and last months returned are those begin_date and end_date fall in
  • One row per month: highest, lowest, the tidal datums (mhhw, mhw, msl, mtl, mlw, mllw, dtl), ranges (gt, mn, dhq, dlq), lunitidal intervals in hours (hwi, lwi), and the inferred code verbatim; values CO-OPS leaves blank are omitted, so a Great Lakes station carries only highest, msl, and lowest
  • Failures: invalid_date_range, date_range_exceeded, station_not_found, datum_unavailable, upstream_throttled, and for an empty window verified_data_lag when it ends on or after the first day of the prior month, no_data otherwise

noaa_marine_get_currents tool
  • interval MAX_SLACK (default: max flood, max ebb, and slack events) or 6min, up to 365 days; bin picks a depth bin from bins[] (default the shallowest); units english (knots, feet) or metric (cm/s, meters)
  • Every response echoes bin and depth; rows carry a flood / ebb / slack type, a non-negative speed, and as direction the station's mean bearing for that flow
  • A bin the station lacks is bin_unavailable listing the ones it has; a station CO-OPS won't predict as events returns an empty list with its statement in notice, and one with no published predictions is predictions_unavailable; also invalid_date_range, date_range_exceeded, station_not_found, no_predictions, and upstream_throttled

noaa_marine_get_conditions tool
  • One NDBC station_id; returns wind, waves, sea-surface and air temperature, dew point, and pressure in SI units, except tide_ft and visibility_nmi
  • Every sensor field is nullable; each column block comes from the newest row within 90 minutes that carried it, waves reporting their own waves_observed_at and any other older block named in notice. Failures: buoy_not_found, no_sensor_data

noaa_marine_get_current_profile tool
  • One NDBC station_id, found with types: ["current_profile"]; bins[] runs shallowest first with depth_m, direction_deg (true, flow-toward), and speed_cm_s, the last two null when unreported
  • Observed ADCP measurements, not the CO-OPS predictions noaa_marine_get_currents returns; failures are profile_not_found (no ADCP file) and no_current_data

noaa_marine_get_ocean_observations tool
  • One NDBC station_id, found with types: ["water_quality"], a catalog flag rather than a guarantee; readings[] holds one row per depth with temperature, conductivity, salinity, dissolved oxygen (% and ppm), chlorophyll, turbidity, pH, and redox potential
  • Most stations report only temperature and salinity, and unreported values are null; failures are observations_not_found (no .ocean file) and no_ocean_data

noaa-marine://station/{station_id} resource
  • station_id from noaa_marine_find_stations; returns that tool's station record as application/json, plus owner for NDBC stations, with a 6-hour cacheHint
  • station_not_found only when both catalogs were read; source_unavailable when one could not be

Features

Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.

CO-OPS / NDBC-specific:

  • CO-OPS data and metadata APIs plus the NDBC active-stations catalog and realtime2 feeds (.txt, .adcp, .ocean), with station catalogs cached in memory for 6 hours; CO-OPS requests carry application= from NOAA_APPLICATION_ID
  • Station IDs never cross sources: CO-OPS tide and water-level IDs are numeric (9447130), CO-OPS current IDs alphanumeric (ACT4176), NDBC IDs 5-character codes (46041)
  • CO-OPS tools take begin_date / end_date as YYYYMMDD or YYYY-MM-DD and check the calendar and each tool's range ceiling before calling (invalid_date_range, date_range_exceeded); heights default to MLLW, and a datum the station lacks is datum_unavailable naming ones it carries
  • CO-OPS verifies hourly, high_low, daily_mean, and monthly means once a month, for the prior month: an empty window ending on or after the first of the prior month is verified_data_lag, an earlier one no_data
  • CO-OPS answers a burst of requests with HTTP 403 for about two minutes; the CO-OPS data tools report it as a retryable upstream_throttled whose recovery names the wait

Agent-friendly output:

  • Byte-bounded paging on the four CO-OPS series tools: a range that fits returns whole, and a longer one returns a leading page with rows_matched, rows_returned, page_offset, and next_offset, walked with offset (limit shrinks a page)
  • Missing means null or omitted, never fabricated: NDBC MM markers become null, blank CO-OPS values are dropped, and quality is left out rather than defaulted
  • Discriminated fields: station source (coops | ndbc), capability type, NDBC platform, and prediction_class, with datum and units echoed on every CO-OPS height response, so callers branch on data, not string parsing

Getting started

Public Hosted Instance

A public instance is available at https://noaa-marine.caseyjhand.com/mcp, with no installation or API key. Point any MCP client at it via Streamable HTTP:

{
  "mcpServers": {
    "noaa-marine-mcp-server": {
      "type": "streamable-http",
      "url": "https://noaa-marine.caseyjhand.com/mcp"
    }
  }
}
Self-Hosted / Local

Add the following to your MCP client configuration file:

{
  "mcpServers": {
    "noaa-marine-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/noaa-marine-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Or with npx (no Bun required):

{
  "mcpServers": {
    "noaa-marine-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/noaa-marine-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info"
      }
    }
  }
}

Or with Docker:

{
  "mcpServers": {
    "noaa-marine-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "MCP_TRANSPORT_TYPE=stdio",
        "ghcr.io/cyanheads/noaa-marine-mcp-server:latest"
      ]
    }
  }
}

For Streamable HTTP, set the transport and start the server:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
Prerequisites
  • Bun v1.4.0 or higher (or Node.js v24+).
  • No API key: NOAA CO-OPS and NDBC are open data sources.
Installation
  1. Clone the repository:
git clone https://github.com/cyanheads/noaa-marine-mcp-server.git
  1. Navigate into the directory:
cd noaa-marine-mcp-server
  1. Install dependencies:
bun install
  1. Configure environment:
cp .env.example .env
# edit .env if needed (all vars optional)

Configuration

VariableDescriptionDefault
NOAA_APPLICATION_IDCourtesy identifier sent as application= on CO-OPS requests.noaa-marine-mcp-server
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTHTTP server port.3010
MCP_HTTP_HOSTHTTP bind address.127.0.0.1
MCP_SESSION_MODEHTTP session mode: stateless, stateful, or auto.stateless
MCP_AUTH_MODEAuthentication: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (debug, info, warning, error, etc.).info
LOGS_DIRDirectory for log files (Node.js only).<project-root>/logs
LOG_TOOL_FAILURE_PAYLOADSLog each failed tool call's arguments and result (redacted by key name only), capped by LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES.false
OTEL_ENABLEDEnable OpenTelemetry.false
OTEL_EXPORTER_OTLP_ENDPOINTOTLP base URL; traces and metrics export to /v1/traces and /v1/metrics under it.—
OTEL_EXPORTER_OTLP_LOGS_ENDPOINTOpt-in OTLP log export endpoint; the base URL never enables it.—

See .env.example for the full list of optional overrides.

Running the server

Local development
  • Build and run:
    bun run rebuild
    
    bun run start:stdio
    # or
    bun run start:http
  • Run checks and tests:
    bun run devcheck   # Lint, format, typecheck, security
    bun run test       # Vitest test suite
    bun run lint:mcp   # Validate MCP definitions against spec
Docker
docker build -t noaa-marine-mcp-server .
docker run --rm -p 3010:3010 noaa-marine-mcp-server

The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/noaa-marine-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.

Project structure

PathPurpose
src/index.tscreateApp() entry point: registers the tools and resource, initializes services.
src/config/NOAA_APPLICATION_ID env var parsing with Zod.
src/services/coops/CO-OPS client: station catalog cache, data fetch, error classification, date-range validation, row paging, state resolution.
src/services/ndbc/NDBC service: active-stations XML and realtime2 feed parsers.
src/services/geo.tsHaversine distance for proximity search and state resolution.
src/mcp-server/tools/definitions/Eight tool definitions (*.tool.ts).
src/mcp-server/resources/definitions/Station metadata resource (noaa-marine-station.resource.ts).
tests/Vitest tests mirroring src/.
docs/Design doc and directory tree.

Development guide

See CLAUDE.md/AGENTS.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for request-scoped logging
  • Register tools and resources in src/index.ts directly (no barrels for this server)
  • Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
  • NDBC MM values must normalize to null, not be passed through as strings

Contributing

Issues are welcome. Run checks and tests before submitting:

bun run devcheck
bun run test

License

Apache-2.0 — see LICENSE for details.

الأسئلة الشائعة

ما هو io.github.cyanheads/noaa-marine-mcp-server؟

Find NOAA tide stations and NDBC buoys, fetch tide predictions, currents, and live conditions.

كيف أثبّت io.github.cyanheads/noaa-marine-mcp-server؟

يعمل كخادم بعيد. في Claude Code: claude mcp add --transport http noaa-marine-mcp-server 'https://noaa-marine.caseyjhand.com/mcp'. وفي العملاء الآخرين، الصق إعداد JSON من هذه الصفحة في إعدادات MCP الخاصة بهم.

هل يحتاج io.github.cyanheads/noaa-marine-mcp-server إلى مفتاح API؟

لا يذكر إدراجه في السجل أي مفتاح أو سر إلزامي. قد تتطلب بعض الميزات حسابًا لدى الخدمة التي يتصل بها.

هل io.github.cyanheads/noaa-marine-mcp-server مفتوح المصدر؟

نعم. شيفرته متاحة على GitHub بترخيص Apache-2.0.

من يصون io.github.cyanheads/noaa-marine-mcp-server؟

ينشره cyanheads. يدرجه AI.tn لكنه لا يصونه ولا يوصي به.

من سجل MCP الرسمي. الإدراج ليس توصية: راجع شيفرة الخادم وصلاحياته قبل منحه الوصول إلى بياناتك.