# Nordic Weather Forecast API: SMHI, Yr (MET Norway), FMI, DMI (`nightwave-owner/nordic-weather`) Actor

Returns hourly weather forecasts or station observations for Sweden, Norway, Finland, Denmark and Iceland from SMHI, MET Norway (Yr), FMI and DMI in one schema: temperature, wind, gusts, precipitation, humidity, pressure, cloud cover and weather symbol.

- **URL**: https://apify.com/nightwave-owner/nordic-weather.md
- **Developed by:** [Viktor Wiberg](https://apify.com/nightwave-owner) (community)
- **Categories:** Developer tools, AI, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 weather rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Nordic Weather Forecast API: SMHI, Yr (MET Norway), FMI, DMI

A weather forecast API for the Nordics: hourly weather forecasts and station observations for Sweden, Norway, Finland, Denmark and Iceland, straight from the four national weather institutes: SMHI, MET Norway (the data behind Yr), FMI and DMI. Every source is converted to the same row format, so the weather data for Stockholm, Oslo, Helsinki and Copenhagen comes back with the same fields, the same units and the same weather symbols.

Ask for a city by name or any point by coordinates. In `auto` mode each place gets the forecast from its own country's institute, which is usually the best local model. You can also pick one source for every place, for example to compare SMHI and MET Norway for the same city.

### What you get

One row per place and hour:

- temperature (°C), wind speed, gusts (m/s) and wind direction (degrees)
- precipitation (mm) and the length of the period it covers
- relative humidity (%), sea level pressure (hPa) and cloud cover (%)
- a weather symbol in one shared vocabulary, plus the source's own code
- the source, license and attribution text for each row

Forecasts run from the current hour up to 10 days ahead. Observations are measured values from the nearest weather station for up to the last 7 days (Sweden, Finland and Denmark).

### Typical uses

- Weather columns for logistics, field service, construction or event planning in the Nordics
- Inputs for energy and demand models (temperature, wind and cloud cover by hour)
- Comparing forecasts from two institutes for the same place
- A daily feed of forecasts or observations into a spreadsheet, database or AI agent

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `cities` | array | `["Stockholm"]` if no locations | Built-in Nordic places by name. Swedish, English and local spellings work. See the list below. |
| `locations` | array | none | Any point as `{"name": "Cabin", "lat": 61.1, "lon": 12.9}`. Add `"country": "NO"` to set the country yourself, otherwise it is taken from the nearest built-in place. |
| `mode` | string | `forecast` | `forecast` or `observations`. |
| `source` | string | `auto` | `auto`, `smhi`, `met`, `fmi` or `dmi`. See below. |
| `hoursAhead` | integer | `48` | Forecast length from the current hour, 1 to 240. |
| `hoursBack` | integer | `24` | Observation period up to now, 1 to 168. |
| `maxResults` | integer | `50` | Maximum rows in total, shared evenly between the places. 1 to 10 000. |
| `onlyNew` | boolean | `false` | Only rows later than the last row delivered by an earlier run with the same input. |

A run with empty input returns the next 48 hours for Stockholm.

#### Source per country in auto mode

| Country | Forecast | Observations |
|---|---|---|
| Sweden | SMHI | SMHI |
| Norway | MET Norway | not available |
| Finland | FMI | FMI |
| Denmark | DMI | DMI |
| Iceland and elsewhere | MET Norway | not available |

MET Norway publishes observations through the Frost API, which requires each user to register a client ID. This actor does not use it, so observations for Norway and Iceland are skipped with a message in the log.

#### Built-in places

| Country | Places |
|---|---|
| Sweden | Stockholm, Göteborg (Gothenburg), Malmö, Uppsala, Västerås, Örebro, Linköping, Helsingborg, Jönköping, Norrköping, Lund, Umeå, Gävle, Borås, Sundsvall, Karlstad, Växjö, Halmstad, Luleå, Östersund, Kalmar, Visby, Kiruna, Falun, Åre |
| Norway | Oslo, Bergen, Trondheim, Stavanger, Drammen, Fredrikstad, Kristiansand, Tromsø, Ålesund, Bodø, Lillehammer, Hammerfest, Longyearbyen |
| Finland | Helsinki (Helsingfors), Espoo (Esbo), Tampere (Tammerfors), Vantaa (Vanda), Turku (Åbo), Oulu (Uleåborg), Jyväskylä, Kuopio, Lahti, Vaasa (Vasa), Rovaniemi, Joensuu, Mariehamn |
| Denmark | København (Copenhagen, Köpenhamn), Aarhus (Århus), Odense, Aalborg, Esbjerg, Randers, Kolding, Roskilde, Helsingør (Elsinore), Rønne |
| Iceland | Reykjavík, Akureyri |

Names are matched without regard to case or accents, so `goteborg` and `Tromso` also work. For any other place, use `locations`.

#### Example input

The input used for the sample output below: the next 24 hours for the four capitals.

```json
{
  "cities": ["Stockholm", "Oslo", "Helsinki", "Copenhagen"],
  "mode": "forecast",
  "hoursAhead": 24,
  "maxResults": 100
}
```

Observations for the last 6 hours at a construction site and in Aarhus:

```json
{
  "locations": [{ "name": "Site 14", "lat": 59.62, "lon": 16.55 }],
  "cities": ["Aarhus"],
  "mode": "observations",
  "hoursBack": 6
}
```

### Output

| Field | Description |
|---|---|
| `location` | Name of the place as given, or the built-in name |
| `lat`, `lon` | Coordinates used for the request |
| `country` | `SE`, `NO`, `FI`, `DK`, `IS`, or `null` for points far from the Nordics |
| `source` | `smhi`, `met`, `fmi` or `dmi` |
| `mode` | `forecast` or `observations` |
| `time` | Hour in UTC, ISO 8601 |
| `temperatureC` | Air temperature at 2 m, °C |
| `windSpeedMs` | Mean wind speed at 10 m, m/s |
| `windGustMs` | Wind gust, m/s |
| `windDirectionDeg` | Direction the wind comes from, degrees (0 north, 90 east) |
| `precipitationMm` | Precipitation in the period that ends at `time`, mm |
| `precipitationPeriodHours` | Length of that period: 1 for hourly steps, longer for later forecast steps (SMHI uses 3, 6 and 12 hours after a few days, MET Norway 6 hours) |
| `humidityPct` | Relative humidity, % |
| `pressureHpa` | Air pressure at sea level, hPa |
| `cloudCoverPct` | Total cloud cover, % |
| `weatherSymbol` | Shared symbol, see below |
| `weatherSymbolOriginal` | The source's own code, for example `smhi:2`, `met:lightrain`, `fmi:3`, `fmi-wawa:61`. `null` when the source has none |
| `station` | Observation station and its distance from the place. `null` for forecasts |
| `license`, `attribution` | License and credit line for the source of the row |

A value the source does not provide for that hour is `null`.

Sample rows from a cloud run on 3 October 2026 with the example input above:

```json
[
  {
    "location": "Stockholm", "lat": 59.3293, "lon": 18.0686, "country": "SE",
    "source": "smhi", "mode": "forecast", "time": "2026-10-03T15:00:00Z",
    "temperatureC": 17.4, "windSpeedMs": 4.2, "windGustMs": 8.3, "windDirectionDeg": 241,
    "precipitationMm": 0, "precipitationPeriodHours": 1, "humidityPct": 55, "pressureHpa": 1024.8,
    "cloudCoverPct": 75, "weatherSymbol": "clear", "weatherSymbolOriginal": "smhi:2", "station": null,
    "license": "CC BY 4.0", "attribution": "Swedish Meteorological and Hydrological Institute (SMHI)"
  },
  {
    "location": "Oslo", "lat": 59.9139, "lon": 10.7522, "country": "NO",
    "source": "met", "mode": "forecast", "time": "2026-10-03T15:00:00Z",
    "temperatureC": 15.1, "windSpeedMs": 3.8, "windGustMs": 10.2, "windDirectionDeg": 187,
    "precipitationMm": 0.2, "precipitationPeriodHours": 1, "humidityPct": 90, "pressureHpa": 1021.4,
    "cloudCoverPct": 100, "weatherSymbol": "light_rain", "weatherSymbolOriginal": "met:lightrain", "station": null,
    "license": "CC BY 4.0 / NLOD 2.0", "attribution": "Data from MET Norway (Norwegian Meteorological Institute)"
  },
  {
    "location": "Helsinki", "lat": 60.1699, "lon": 24.9384, "country": "FI",
    "source": "fmi", "mode": "forecast", "time": "2026-10-03T15:00:00Z",
    "temperatureC": 14.4, "windSpeedMs": 3.4, "windGustMs": 6, "windDirectionDeg": 221,
    "precipitationMm": 0, "precipitationPeriodHours": 1, "humidityPct": 95, "pressureHpa": 1023.9,
    "cloudCoverPct": 100, "weatherSymbol": "cloudy", "weatherSymbolOriginal": "fmi:3", "station": null,
    "license": "CC BY 4.0", "attribution": "Finnish Meteorological Institute (FMI) open data"
  },
  {
    "location": "København", "lat": 55.6761, "lon": 12.5683, "country": "DK",
    "source": "dmi", "mode": "observations", "time": "2026-10-03T12:00:00Z",
    "temperatureC": 17.8, "windSpeedMs": 4.1, "windGustMs": 6.7, "windDirectionDeg": 170,
    "precipitationMm": 0, "precipitationPeriodHours": 1, "humidityPct": 73, "pressureHpa": 1030.8,
    "cloudCoverPct": 0, "weatherSymbol": "clear", "weatherSymbolOriginal": null, "station": "DMI 06186 (2 km)",
    "license": "CC BY 4.0", "attribution": "Danish Meteorological Institute (DMI) open data"
  }
]
```

The last row is from an observations run on the same day.

#### Weather symbols

`clear`, `partly_cloudy`, `cloudy`, `fog`, `light_rain`, `rain`, `heavy_rain`, `rain_showers`, `thunder`, `sleet`, `sleet_showers`, `light_snow`, `snow`, `heavy_snow`, `snow_showers`.

SMHI, MET Norway and FMI forecasts come with their own symbol, which is mapped to this list (SMHI's "nearly clear" and MET Norway's "fair" both become `clear`). The symbol always comes from the source, so it can differ slightly from the cloud cover value in the same row. DMI forecasts and SMHI and DMI observations have no symbol; there it is derived from precipitation per hour (rain or snow depending on the temperature) and otherwise from cloud cover (`clear` under 25 %, `partly_cloudy` under 75 %, `cloudy` above). FMI observations use the station's present weather code when it reports one.

### Example from a real run

Input:

```json
{
  "cities": [
    "Stockholm"
  ],
  "hoursAhead": 6,
  "maxResults": 5
}
```

Output (first 3 of 5 rows, values unchanged):

```json
[
  {
    "location": "Stockholm",
    "lat": 59.3293,
    "lon": 18.0686,
    "country": "SE",
    "source": "smhi",
    "mode": "forecast",
    "time": "2026-10-04T08:00:00Z",
    "temperatureC": 13.2,
    "windSpeedMs": 4.4,
    "windGustMs": 8.8,
    "windDirectionDeg": 267,
    "precipitationMm": 0,
    "precipitationPeriodHours": 1,
    "humidityPct": 76,
    "pressureHpa": 1019.4,
    "cloudCoverPct": 100,
    "weatherSymbol": "cloudy",
    "weatherSymbolOriginal": "smhi:6",
    "station": null,
    "license": "CC BY 4.0",
    "attribution": "Swedish Meteorological and Hydrological Institute (SMHI)"
  },
  {
    "location": "Stockholm",
    "lat": 59.3293,
    "lon": 18.0686,
    "country": "SE",
    "source": "smhi",
    "mode": "forecast",
    "time": "2026-10-04T09:00:00Z",
    "temperatureC": 13.6,
    "windSpeedMs": 4,
    "windGustMs": 8.7,
    "windDirectionDeg": 282,
    "precipitationMm": 0,
    "precipitationPeriodHours": 1,
    "humidityPct": 76,
    "pressureHpa": 1019.6,
    "cloudCoverPct": 100,
    "weatherSymbol": "cloudy",
    "weatherSymbolOriginal": "smhi:6",
    "station": null,
    "license": "CC BY 4.0",
    "attribution": "Swedish Meteorological and Hydrological Institute (SMHI)"
  },
  {
    "location": "Stockholm",
    "lat": 59.3293,
    "lon": 18.0686,
    "country": "SE",
    "source": "smhi",
    "mode": "forecast",
    "time": "2026-10-04T10:00:00Z",
    "temperatureC": 14,
    "windSpeedMs": 3.5,
    "windGustMs": 7.9,
    "windDirectionDeg": 286,
    "precipitationMm": 0,
    "precipitationPeriodHours": 1,
    "humidityPct": 76,
    "pressureHpa": 1019.7,
    "cloudCoverPct": 100,
    "weatherSymbol": "cloudy",
    "weatherSymbolOriginal": "smhi:6",
    "station": null,
    "license": "CC BY 4.0",
    "attribution": "Swedish Meteorological and Hydrological Institute (SMHI)"
  }
]
```

Run ZYBMjgHKgdLQWjm5h on 2026-10-04, 5 rows, 4 seconds.

### Monitoring and scheduling

To keep a table up to date, schedule the actor in Apify (Schedules, Create new) and turn on `onlyNew`:

```json
{
  "cities": ["Stockholm", "Göteborg", "Malmö"],
  "mode": "observations",
  "hoursBack": 24,
  "maxResults": 300,
  "onlyNew": true
}
```

With the cron expression `0 6 * * *` this runs every morning at 06:00 UTC and returns only the hours measured since the previous run. The first run returns everything in the window. The last delivered hour is stored per place, source and mode in the key-value store `nightwave-state-nordic-weather`, under a record named after a hash of the input, so different inputs do not affect each other.

For forecasts, `onlyNew` returns only hours later than those already delivered. Updated forecasts for hours you already have are not sent again, so turn it off if you want each run to replace the whole forecast.

### Good to know

- Forecast models differ in length: SMHI and FMI reach about 10 days, MET Norway about 9 to 10 days and DMI about 60 hours. A longer `hoursAhead` simply returns what the source has.
- SMHI, FMI and DMI forecasts cover a limited area around their own country and the Nordic region. A place outside the area of a chosen source is skipped with a message in the log; `auto` and `met` work everywhere.
- Observations use the nearest station that measures each value, within about 40 to 50 km. For SMHI and DMI the station named in `station` is the temperature station, and wind or cloud values can come from another station nearby. The latest hour is left out until a station has reported it.
- Times are in UTC. Swedish, Norwegian, Danish and Finnish local time is UTC+1 in winter and UTC+2 in summer (Finland UTC+2 and UTC+3).
- Every request is retried three times on network errors, rate limits (HTTP 429) and server errors. A response in an unexpected format stops the run with a clear message instead of storing broken rows.

### Data sources, licenses and limits

| Source | API | License | Credit | Limits |
|---|---|---|---|---|
| SMHI | [Meteorological Forecasts](https://opendata.smhi.se/metfcst/snow1gv1/) (`snow1g`, which replaced `pmp3g`) and [Meteorological Observations](https://opendata.smhi.se/metobs/introduction) | [CC BY 4.0](https://www.smhi.se/data/om-smhis-data/villkor-for-anvandning) | Swedish Meteorological and Hydrological Institute (SMHI) | No key. No published request limit; SMHI asks users not to overload the service. |
| MET Norway | [Locationforecast 2.0](https://api.met.no/weatherapi/locationforecast/2.0/documentation) (`complete`) | [CC BY 4.0 and NLOD 2.0](https://api.met.no/doc/License) | Data from MET Norway | No key. [Terms of service](https://developer.yr.no/doc/TermsOfService/): requests must carry an identifying User-Agent with contact details, at most 20 requests per second per application, coordinates with at most 4 decimals, and clients should respect the `Expires` header. The actor sends `NightwaveNordicWeather/0.1 (Apify actor; kontakt@nightwave.se)`, rounds coordinates to 4 decimals and makes one request per place per run. For forecasts, one scheduled run per hour is plenty. |
| FMI | [FMI open data WFS](https://en.ilmatieteenlaitos.fi/open-data-manual) | [CC BY 4.0](https://en.ilmatieteenlaitos.fi/open-data-licence) | Finnish Meteorological Institute | No key. The open data manual sets a daily request limit per user (20 000 requests per day when this was written). |
| DMI | Forecast Data EDR API (`opendataapi.dmi.dk/v1/forecastedr`, HARMONIE DINI) and Meteorological Observation API (`opendataapi.dmi.dk/v2/metObs`) | [CC BY 4.0](https://www.dmi.dk/friedata/dokumentation/terms-of-use) | Danish Meteorological Institute (DMI) | No key (checked October 2026). DMI applies rate limits and answers HTTP 429 when they are reached; the actor waits and retries. |

When you publish or share the data, credit the source given in `attribution` on each row and link to the license. The actor converts units and names but does not change the values.

This actor is not affiliated with SMHI, MET Norway, FMI or DMI.

### Pricing

Pay per event: USD 0.001 per weather row (event `weather-row`), which is USD 1 per 1 000 rows. Platform usage is included, so you pay only per row. A run with 4 cities and 24 hours (100 rows) costs USD 0.10 and takes about 10 seconds. `maxResults` caps how many rows, and so how much, a run can cost.

Rows are delivered only after they have been charged. If you set a maximum cost per run (maxTotalChargeUsd), the run stops there and its status message says how many rows were delivered.

### Contact

Built and maintained by Nightwave AB. Questions, bugs and feature requests: kontakt@nightwave.se

### På svenska

Actorn hämtar väderprognoser och observationer för Sverige, Norge, Finland, Danmark och Island direkt från SMHI, MET Norway (som står bakom Yr), FMI och DMI. Alla källor får samma radformat: temperatur, vind, byvind, vindriktning, nederbörd, luftfuktighet, lufttryck, molnighet och en gemensam vädersymbol, timme för timme i UTC.

Exempel från en verklig körning: input och de första raderna i outputen finns i avsnittet Example from a real run ovan (körning ZYBMjgHKgdLQWjm5h, 2026-10-04, 5 rader, 4 sekunder).

- Ange orter med namn (till exempel Stockholm, Göteborg, Oslo, Helsingfors eller Köpenhamn) eller valfria koordinater.
- `auto` väljer det egna landets institut: SMHI för Sverige, MET Norway för Norge och Island, FMI för Finland och DMI för Danmark. Du kan också välja en källa för alla orter.
- Prognoser upp till 10 dygn framåt. Observationer från närmaste station upp till 7 dygn bakåt för Sverige, Finland och Danmark. Norska observationer kräver registrering hos MET Norway och ingår inte.
- `onlyNew` ger bara nya timmar vid schemalagda körningar.
- Källor: SMHI, MET Norway, FMI och DMI. Alla under CC BY 4.0 (MET Norway även NLOD 2.0). Ange källan enligt fältet `attribution` när du publicerar datan.
- Pris: 0,001 USD per rad (1 USD per 1 000 rader). Plattformsanvändningen ingår.
- Kontakt: kontakt@nightwave.se

# Actor input Schema

## `cities` (type: `array`):

Nordic places by name, for example Stockholm, Oslo, Helsinki, Copenhagen, Reykjavik. Swedish, English and local spellings work (Göteborg or Gothenburg, Köpenhamn or København). About 60 places are built in, see the README. Use locations for anything else. If both cities and locations are empty, Stockholm is used.

## `locations` (type: `array`):

Any point as {"name": "Cabin", "lat": 61.1, "lon": 12.9}. The country is guessed from the nearest built-in place; add "country": "NO" to set it yourself. Used together with cities.

## `mode` (type: `string`):

"forecast" gives hourly forecasts from now. "observations" gives measured values from the nearest weather station for the last hours (Sweden, Finland and Denmark only).

## `source` (type: `string`):

"auto" uses the national institute of each place's country: SMHI for Sweden, MET Norway for Norway and Iceland, FMI for Finland, DMI for Denmark. Choose one source to use it for every place, for example to compare SMHI and MET Norway for the same city.

## `hoursAhead` (type: `integer`):

How far ahead to forecast, from the current hour. Example: 24. At most 240 (10 days). DMI forecasts reach about 60 hours ahead.

## `hoursBack` (type: `integer`):

How many hours of observations to return, up to now. Example: 24. At most 168 (7 days).

## `maxResults` (type: `integer`):

Maximum number of rows in total, shared evenly between the places. Example: 100 for four cities and 24 hours.

## `onlyNew` (type: `boolean`):

For scheduled runs: return only hours later than the last row delivered by an earlier run with the same input. The first run returns everything.

## Actor input object example

```json
{
  "cities": [
    "Stockholm",
    "Oslo",
    "Helsinki",
    "Copenhagen"
  ],
  "locations": [
    {
      "name": "Åre ski area",
      "lat": 63.4,
      "lon": 13.08
    }
  ],
  "mode": "forecast",
  "source": "auto",
  "hoursAhead": 24,
  "hoursBack": 24,
  "maxResults": 100,
  "onlyNew": false
}
```

# Actor output Schema

## `results` (type: `string`):

All weather rows produced by the run, as JSON. Open in Apify Console or download via the dataset API.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "cities": [
        "Stockholm",
        "Oslo"
    ],
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("nightwave-owner/nordic-weather").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "cities": [
        "Stockholm",
        "Oslo",
    ],
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("nightwave-owner/nordic-weather").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "cities": [
    "Stockholm",
    "Oslo"
  ],
  "maxResults": 50
}' |
apify call nightwave-owner/nordic-weather --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nightwave-owner/nordic-weather"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/tmHPap46m6am9S96G/builds/YVfcMjeZS4vvFXj2f/openapi.json
