National Weather Service
The io.b3os/nws pack: 5 actions with call snippets, fixture outputs, connection setup and error codes, generated from version 1.0.0.
io.b3os/nws 1.0.0 · weather, government-data · MIT
Official US weather from the National Weather Service API (api.weather.gov): look up the forecast grid for a coordinate, then read the 7-day or hourly forecast, active watches, warnings and advisories, and the latest observation from a station. Keyless, read-only, public-domain data; covers the US and its territories only (use io.b3os/open-meteo elsewhere).
Every call's result carries upstream_status and timing: validate_ms, inject_ms, render_ms, upstream_ms, map_ms and total_ms. upstream is the service's time; the others are B3OS's own (call actions). The snippets below show no timing values, because a fixture records none.
Connection
No credential: a keyless public API. Calls name no connection.
Hosts it reaches: api.weather.gov.
Actions
| Action | Effect | MCP tool | Title |
|---|---|---|---|
get-point | read | nws__get-point | Get forecast point |
get-forecast | read | nws__get-forecast | Get 7-day forecast |
get-hourly-forecast | read | nws__get-hourly-forecast | Get hourly forecast |
get-active-alerts | read | nws__get-active-alerts | Get active alerts |
get-latest-observation | read | nws__get-latest-observation | Get latest observation |
get-point
Get forecast point. Resolve a US coordinate to its forecast office and grid cell (office, grid_x, grid_y), which get-forecast and get-hourly-forecast need, plus the nearest city, time zone, forecast zone, county and radar station. Call this first.
Ref io.b3os/nws/get-point@1.0.0 · effect read · no connection · MCP tool nws__get-point
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/nws/get-point@1", "input": {"latitude": 44.05, "longitude": -123.09} }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/nws/get-point@1", input: { latitude: 44.05, longitude: -123.09 },});console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/nws/get-point@1", "input": {"latitude": 44.05, "longitude": -123.09},})print(result["output"])
json{ "method": "tools/call", "params": { "name": "nws__get-point", "arguments": {"latitude": 44.05, "longitude": -123.09} }}
Expose the pack as tools with --packs nws on the local server or ?packs=nws on the remote URL, and the agent calls nws__get-point with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Get forecast point (response recorded 2026-10-26). From the bundle's fixtures/get-point.json, not a live call.
json{ "office": "PQR", "grid_x": 85, "grid_y": 39, "city": "Eugene", "state": "OR", "timezone": "America/Los_Angeles", "forecast_zone_url": "https://api.weather.gov/zones/forecast/ORZ118", "county_url": "https://api.weather.gov/zones/county/ORC039", "observation_stations_url": "https://api.weather.gov/gridpoints/PQR/85,39/stations", "radar_station": "KRTX"}
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
upstream_error | matched on the response body | yes | built from the service's response |
not_found | 404 | no | built from the service's response |
rate_limited | 429 | yes | api.weather.gov rate limit reached; retry in a few seconds. |
invalid_request | 400, 422 | no | built from the service's response |
get-forecast
Get 7-day forecast. The 7-day forecast for a grid cell in 12-hour periods (Today, Tonight, Monday, ...): temperature, chance of precipitation, wind and a detailed text forecast written by the NWS office. Get office, grid_x and grid_y from get-point.
Ref io.b3os/nws/get-forecast@1.0.0 · effect read · no connection · MCP tool nws__get-forecast
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/nws/get-forecast@1", "input": {"office": "PQR", "grid_x": 85, "grid_y": 39} }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/nws/get-forecast@1", input: { office: "PQR", grid_x: 85, grid_y: 39 },});console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/nws/get-forecast@1", "input": {"office": "PQR", "grid_x": 85, "grid_y": 39},})print(result["output"])
json{ "method": "tools/call", "params": { "name": "nws__get-forecast", "arguments": {"office": "PQR", "grid_x": 85, "grid_y": 39} }}
Expose the pack as tools with --packs nws on the local server or ?packs=nws on the remote URL, and the agent calls nws__get-forecast with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Get 7-day forecast (response recorded 2026-10-26). From the bundle's fixtures/get-forecast.json, not a live call.
json{ "updated": "2026-10-26T06:41:25+00:00", "units": "us", "periods": [ { "number": 1, "name": "Overnight", "start_time": "2026-10-26T00:00:00-07:00", "end_time": "2026-10-26T06:00:00-07:00", "is_daytime": false, "temperature": 44, "temperature_unit": "F", "precipitation_probability_percent": 96, "wind_speed": "7 to 10 mph", "wind_direction": "S", "short_forecast": "Rain Showers", "detailed_forecast": "Rain showers. Mostly cloudy. Low around 44, with temperatures rising to around 47 overnight. South wind 7 to 10 mph, with gusts as high as 20 mph. Chance of precipitation is 100%. New rainfall amounts between a tenth and quarter of an inch possible." }, { "number": 2, "name": "Monday", "start_time": "2026-10-26T06:00:00-07:00", "end_time": "2026-10-26T18:00:00-07:00", "is_daytime": true, "temperature": 55, "temperature_unit": "F", "precipitation_probability_percent": 94, "wind_speed": "9 mph", "wind_direction": "SSW", "short_forecast": "Rain Showers", "detailed_forecast": "Rain showers. Cloudy, with a high near 55. South southwest wind around 9 mph, with gusts as high as 23 mph. Chance of precipitation is 90%. New rainfall amounts between a tenth and quarter of an inch possible." } ]}
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
upstream_error | matched on the response body | yes | built from the service's response |
not_found | 404 | no | built from the service's response |
rate_limited | 429 | yes | api.weather.gov rate limit reached; retry in a few seconds. |
invalid_request | 400, 422 | no | built from the service's response |
get-hourly-forecast
Get hourly forecast. Hour-by-hour forecast for a grid cell for about the next 6 days (156 periods): temperature, chance of precipitation, wind and a short forecast per hour. Large; prefer get-forecast unless you need hours. Get office, grid_x and grid_y from get-point.
Ref io.b3os/nws/get-hourly-forecast@1.0.0 · effect read · no connection · MCP tool nws__get-hourly-forecast
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/nws/get-hourly-forecast@1", "input": {"office": "PQR", "grid_x": 85, "grid_y": 39} }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/nws/get-hourly-forecast@1", input: { office: "PQR", grid_x: 85, grid_y: 39 },});console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/nws/get-hourly-forecast@1", "input": {"office": "PQR", "grid_x": 85, "grid_y": 39},})print(result["output"])
json{ "method": "tools/call", "params": { "name": "nws__get-hourly-forecast", "arguments": {"office": "PQR", "grid_x": 85, "grid_y": 39} }}
Expose the pack as tools with --packs nws on the local server or ?packs=nws on the remote URL, and the agent calls nws__get-hourly-forecast with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Get hourly forecast (response recorded 2026-10-26). From the bundle's fixtures/get-hourly-forecast.json, not a live call.
json{ "updated": "2026-10-26T06:41:25+00:00", "units": "us", "periods": [ { "number": 1, "name": "", "start_time": "2026-10-26T00:00:00-07:00", "end_time": "2026-10-26T01:00:00-07:00", "is_daytime": false, "temperature": 51, "temperature_unit": "F", "precipitation_probability_percent": 96, "wind_speed": "9 mph", "wind_direction": "S", "short_forecast": "Rain Showers", "detailed_forecast": "" }, { "number": 2, "name": "", "start_time": "2026-10-26T01:00:00-07:00", "end_time": "2026-10-26T02:00:00-07:00", "is_daytime": false, "temperature": 50, "temperature_unit": "F", "precipitation_probability_percent": 80, "wind_speed": "10 mph", "wind_direction": "S", "short_forecast": "Rain Showers", "detailed_forecast": "" }, { "number": 3, "name": "", "start_time": "2026-10-26T02:00:00-07:00", "end_time": "2026-10-26T03:00:00-07:00", "is_daytime": false, "temperature": 50, "temperature_unit": "F",
The first 40 of 48 lines; the fixture file has the rest.
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
upstream_error | matched on the response body | yes | built from the service's response |
not_found | 404 | no | built from the service's response |
rate_limited | 429 | yes | api.weather.gov rate limit reached; retry in a few seconds. |
invalid_request | 400, 422 | no | built from the service's response |
get-active-alerts
Get active alerts. Active watches, warnings and advisories (tornado, flood, winter storm, heat, red flag, ...) for a US state or marine area code, or for the point at a coordinate. Give either area or latitude and longitude. Each alert has the event, severity, urgency, certainty, affected areas, effective and expiry times, the headline, description and safety instructions.
Ref io.b3os/nws/get-active-alerts@1.0.0 · effect read · no connection · MCP tool nws__get-active-alerts
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"ref": "io.b3os/nws/get-active-alerts@1", "input": {"area": "AK"}}'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/nws/get-active-alerts@1", input: { area: "AK" } });console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({"ref": "io.b3os/nws/get-active-alerts@1", "input": {"area": "AK"}})print(result["output"])
json{ "method": "tools/call", "params": {"name": "nws__get-active-alerts", "arguments": {"area": "AK"}}}
Expose the pack as tools with --packs nws on the local server or ?packs=nws on the remote URL, and the agent calls nws__get-active-alerts with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Get active alerts (response recorded 2026-10-26). From the bundle's fixtures/get-active-alerts.json, not a live call.
json{ "title": "Current watches, warnings, and advisories for Alaska", "updated": "2026-10-26T07:08:28+00:00", "alerts": [ { "id": "urn:oid:2.49.0.1.840.0.b14f258e31fc617bba388a2117559854244a7d3a.001.1", "event": "Coastal Flood Advisory", "severity": "Minor", "urgency": "Expected", "certainty": "Likely", "area": "Kuskokwim Delta Coast and Nunivak Island", "headline": "Coastal Flood Advisory issued October 25 at 8:19PM AKDT until October 28 at 10:00AM AKDT by NWS Anchorage AK", "description": "* WHAT...Coastal flooding, with water levels of 1 to 2.5 feet\nabove the normal highest tide line, and 30 to 40 mph southwest\nwinds with gusts up to 40 to 55 mph.\n\n* WHERE...Kuskokwim Delta Coast, including Kipnuk, Kwigillingok\nand Kongiganak.\n\n* WHEN...Until 10 AM AKDT Wednesday, highest water levels expected\nduring each upcoming high tide through Wednesday morning.\n\n* IMPACTS...Coastal flooding of low lying areas and erosion are\npossible.\n\n* ADDITIONAL DETAILS...Steady south to southwesterly flow is\nexpected to continue for the Kuskokwim Delta coastline through\nWednesday morning as a series of low pressure systems track\nacross the Bering Sea. Coastal erosion and minor coastal\nflooding will be possible with each upcoming high tide due to\nthe persistent onshore winds, during which maximum water levels\nwill reach between 1 and 2.5 ft above the normal highest tide\nline, including in and around Kipnuk and Kwigillingok. The\nstrong winds may reduce the ability for flood waters to recede\nduring and close to low tide, possibly leading to prolonged\nhigher than normal water levels along the coast and near the\nmouth of the Kuskokwim River. There will be a break in strong\nwinds between Wednesday afternoon and Thursday morning,\nhowever, we are monitoring the potential for another strong\nstorm system that could cause additional coastal impacts towards\nthe end of this week.", "instruction": "A coastal flood advisory indicates that onshore winds and tides\nwill combine to generate flooding of low areas along the shore.", "effective": "2026-10-25T20:19:00-08:00", "expires": "2026-10-26T17:00:00-08:00", "sender": "NWS Anchorage AK", "status": "Actual", "message_type": "Update" } ]}
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
upstream_error | matched on the response body | yes | built from the service's response |
not_found | 404 | no | built from the service's response |
rate_limited | 429 | yes | api.weather.gov rate limit reached; retry in a few seconds. |
invalid_request | 400, 422 | no | built from the service's response |
get-latest-observation
Get latest observation. The most recent observation from a weather station (ICAO id such as KEUG for Eugene airport): temperature, dew point, humidity, wind, gusts, pressure, visibility and a short description, in SI units (degrees C, km/h, Pa, m). Values can be null when the station did not report them.
Ref io.b3os/nws/get-latest-observation@1.0.0 · effect read · no connection · MCP tool nws__get-latest-observation
bashcurl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/nws/get-latest-observation@1", "input": {"station": "KEUG"} }'
tsimport { B3OS } from "@b3os/sdk";const b3os = new B3OS();const result = await b3os.actions.call({ ref: "io.b3os/nws/get-latest-observation@1", input: { station: "KEUG" },});console.log(result.output);
pythonfrom b3os import B3OSb3os = B3OS()result = b3os.actions.call({ "ref": "io.b3os/nws/get-latest-observation@1", "input": {"station": "KEUG"},})print(result["output"])
json{ "method": "tools/call", "params": { "name": "nws__get-latest-observation", "arguments": {"station": "KEUG"} }}
Expose the pack as tools with --packs nws on the local server or ?packs=nws on the remote URL, and the agent calls nws__get-latest-observation with the action's input. The tool needs no connection. Without exposing the pack, actions_call takes the same input with ref.
Output, labeled fixture: Get latest observation (response recorded 2026-10-26). From the bundle's fixtures/get-latest-observation.json, not a live call.
json{ "station": "KEUG", "timestamp": "2026-10-26T06:50:00+00:00", "description": "Light Rain", "temperature_c": 11, "dewpoint_c": 10, "relative_humidity_percent": 93.553471551667, "wind_direction_degrees": 120, "wind_speed_kmh": 18.504, "wind_gust_kmh": null, "pressure_pa": 101591.66, "visibility_m": 11265.41}
When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:
pack_error.code | Service status | Retryable | Message |
|---|---|---|---|
upstream_error | matched on the response body | yes | built from the service's response |
not_found | 404 | no | built from the service's response |
rate_limited | 429 | yes | api.weather.gov rate limit reached; retry in a few seconds. |
invalid_request | 400, 422 | no | built from the service's response |