> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beta.b3os.org/llms.txt
> Use this file to discover all available pages before exploring further.

# 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](/actions/call)). 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`](/actions/catalog/nws#nws-get-point) | read | `nws__get-point` | Get forecast point |
| [`get-forecast`](/actions/catalog/nws#nws-get-forecast) | read | `nws__get-forecast` | Get 7-day forecast |
| [`get-hourly-forecast`](/actions/catalog/nws#nws-get-hourly-forecast) | read | `nws__get-hourly-forecast` | Get hourly forecast |
| [`get-active-alerts`](/actions/catalog/nws#nws-get-active-alerts) | read | `nws__get-active-alerts` | Get active alerts |
| [`get-latest-observation`](/actions/catalog/nws#nws-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`

**curl**

```bash
    curl -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}
        }'
    ```
  **TypeScript**

```ts
    import { 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);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/nws/get-point@1",
        "input": {"latitude": 44.05, "longitude": -123.09},
    })
    print(result["output"])
    ```
  **MCP**

```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`](/errors#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`

**curl**

```bash
    curl -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}
        }'
    ```
  **TypeScript**

```ts
    import { 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);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/nws/get-forecast@1",
        "input": {"office": "PQR", "grid_x": 85, "grid_y": 39},
    })
    print(result["output"])
    ```
  **MCP**

```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`](/errors#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`

**curl**

```bash
    curl -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}
        }'
    ```
  **TypeScript**

```ts
    import { 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);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = 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"])
    ```
  **MCP**

```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`](/errors#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`

**curl**

```bash
    curl -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"}}'
    ```
  **TypeScript**

```ts
    import { 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);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({"ref": "io.b3os/nws/get-active-alerts@1", "input": {"area": "AK"}})
    print(result["output"])
    ```
  **MCP**

```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`](/errors#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`

**curl**

```bash
    curl -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"}
        }'
    ```
  **TypeScript**

```ts
    import { 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);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/nws/get-latest-observation@1",
        "input": {"station": "KEUG"},
    })
    print(result["output"])
    ```
  **MCP**

```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`](/errors#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 |