AI agent for weather forecast

Ever since I started going to work by bike I haven’t looked back: I arrive more awake, I get some morning exercise, I save money on fuel, no traffic stress, and my mind is way sharper than when I used to drive.

This is a bit of a luxury for me, not everyone has the option (or the motivation 😅) to bike to work, but I do have one problem: the weather.

Weather affects what I wear a lot, and I always need to dress according to the expected temperature and whether it’s going to rain. Every evening and every morning I open my favourite website (the one I find most reliable), 3bmeteo.com and check the next day’s forecast. If it rained overnight I also check the data from my Shelly weather station: if it rained a lot I’ll take a longer but cleaner route, otherwise I’ll take the path that cuts through a small wood.

This recurring routine pushed me to automate and improve how I consume weather data, so as an experiment I decided to let an AI agent handle it.

Step 1: automating the forecast scraping

We’re in the AI era, so I could have just handed the forecast reading off to any model capable of doing it, but:

  1. I would have created a dependency on the model.
  2. I don’t run a local AI model, so every call, however small, would have had a cost.

For these two reasons I decided to build a tool that automates fetching forecasts from 3bmeteo, complete with cache management and auto data refresh. The same service would expose some API endpoints, consumable by the model, to get a JSON with the forecast data.
The project isn’t tied to my favourite provider and was designed to be flexible.

The project is available on my Github and also on Docker Hub. In the Docker directory of the repository you’ll find the Docker Compose file and the .env template to get it running.

If you want to replicate what I did, just clone the git repo, go into the docker directory, copy .env.template to .env and run docker compose up -d.

The service also supports writing forecast JSONs to the filesystem, in case you don’t want to or can’t expose the APIs to the model. With the JSONs on the filesystem your model can read them as context files.

Step 2: getting data from the weather station

In 2025 I placed first and third in a Shelly competition, and with the voucher I received as a prize I bought a weather station from their website.

From an integration standpoint it’s not the most convenient choice, since I have to pull the data from the cloud and can’t access the station directly. To solve this I extended an app I had already built (the one that got me first place), a project that exposed Shelly data as a REST API and as an MCP server.
This tool simplified access to the weather station data (and the whole Shelly ecosystem), making it easy to plug into my personal projects.

🔗Github project link
🔗 Rest API DockerHub link
🔗 MCP server DockerHub link

In the GitHub repository you’ll find the instructions and the Docker Compose to run the project.

Step 3: n8n as orchestrator

I already had n8n installed on my homelab and had used it for other automations, but I had never tried it to orchestrate an AI flow.
If you need to spin up a local n8n instance you can do it via Docker Compose (which you can find here), the instance I used is started from the Docker Compose provided in the documentation.

Step 4: OpenRouter for the AI model

For those who don’t know it, OpenRouter is a web service that lets you buy credits to spend across AI models from multiple providers, from the most talked-about ones (like Anthropic’s models) all the way to open models.
For this experiment I tried different versions of Qwen3.5, Gemma 3, Gemma 4 and GPT-4o-mini and they all gave me very similar results. OpenRouter is a must for anyone who doesn’t have the hardware at home to run local models, and I prefer it over proprietary APIs because it keeps me flexible and vendor-agnostic.
As for costs, they’re pretty negligible, but we’ll get to that later.

Step 5: Telegram for notifications

Where to receive notifications? Telegram, of course! It’s not an obvious answer, but I’ve worked with Telegram several times and already have other bots running to manage different projects.
For this purpose I chose to receive forecast notifications through a bot I had already set up, where I was already getting other kinds of updates.

Step 6: putting it all together

Time to wire up everything we’ve prepared.

AI Agent node

First I created a new scenario in n8n and dropped the AI Agent tool in the middle of the canvas, which will orchestrate the entire flow.

Next we connect the Chat model node (as mentioned, I use OpenRouter) and in the tools we connect the Shelly APIs and WeatherAgents APIs (Links above). In this specific scenario there’s no need to keep agent memory, since forecasts change every hour and caching responses would lead to wrong results.

Opening the “Weather agent” node we need to configure the prompt and the system message.
For the prompt we’ll use a variable, since it will be passed in from another node (more on that in a moment).

Markdown
{{ $json.chatInput }}

For the system message, we set it up like this:

Markdown
You are a weather forecast presenter and your only job is to answer questions about weather forecasts.

# Rules
* Always reason about dates in dd/MM/yyyy format
* Only provide forecasts between today and the next 7 days
* Reply in the user's language
* The current date and time is: {{ $now }}

# Tool
These are the tools available to you:

## Shelly Weather Station (current + historical)
* If the user asks about the weather RIGHT NOW use the "Shelly Weather Station" tool filtering by the current date and time
* If the user asks for HISTORICAL weather data use the "Shelly Weather Station" tool filtering by the date and time requested by the user

## Weather forecast (future)
* Use this tool when you need to know the weather forecast for a specific day
* The tool is called "Weather forecast"
* Pass dates in yyyy-MM-dd format

The system message has everything it needs to be a solid prompt:

  • Role assignment (presenter)
  • Rules on how to work and respond
  • List of tools and instructions on how to use them

Prompt e scheduling

As I mentioned at the start of the article, my goal was to receive forecasts automatically in the evening and in the morning.

  • In the evening I want to know the forecast and expected temperatures.
  • In the morning I want to know (from the weather station) the temperature, whether it rained and how much, plus the day’s forecast.
    So we need two different prompts, and to set them up I used an “Edit fields (set)” node to define the chatInput variable we referenced in the agent node earlier.

We add two nodes to the workflow and set the prompts like this:

Evening prompt

Markdown
# Task
Write a short message telling me:
* How much it rained between 7pm and 9pm today (skip this if it didn't rain)
* Whether it will rain between 9pm tonight and 7am tomorrow morning (forecast tool, today and tomorrow)
* Whether it will rain between 7am and 7pm tomorrow and what the weather will be like (forecast tool, tomorrow)

# Rules
* If rain is expected, also mention what time it will rain and how much
* Add an icon based on the expected weather
* Be very careful to call the tools with the correct dates
* Include the expected minimum and maximum temperatures
* Include the temperature at 7am

# Examples
* "It rained 18mm between 7pm and 8pm, it's not raining now. No rain expected tonight and tomorrow will be sunny. Temperatures will range between 10 and 28 degrees. At 7am it will be 11 degrees."
* "5mm of rain is expected tonight. Tomorrow it will rain from 9am to 10am and then from 12pm to 7pm. Temperatures will range between 10 and 28 degrees. At 7am it will be 11 degrees."

# Context
The current date and time is: {{ $now }}

Morning prompt

Markdown
# Task
Write a short and concise message telling me:
* Whether it rained between 11pm yesterday and 7am today
* What the weather is like today (if it will rain, also say how much)

# Rules
* If rain is expected, also mention what time it will rain and how much
* Add an icon showing the expected weather
* Be very careful to call the tools with the correct dates
* Include the current temperature (fetch it from the weather station)

# Context
* The current date and time is: {{ $now }}

# Examples
* "It rained 7mm last night between 3am and 5am. Today is expected to be sunny and it's currently 11 degrees."
* "It rained 2mm last night at 11pm, then stopped. Today will be cloudy and it's currently 14 degrees."
* "No rain last night, thunderstorms are expected today between 3pm and 6pm. It's currently 18 degrees."

At this point we’re missing two pieces to complete the flow: a trigger and the Telegram output.

For the trigger we can use a “Schedule trigger” node, setting the date and time we want the workflow to run, connected to the prompt node we just created.

For Telegram, we pick the “Telegram -> Send a chat message” node and configure our account.
The message text will be:

JSON
Weather forecast:<br>{{ $json.output}}

We’re now ready to run the workflow! To cover all my bases, I set the two prompts above to run Monday through Friday and added a third, more generic one for weekends.

I also added a chat node to test the agent directly without going through the preset prompts. This is especially handy during development.

Costs

The cost per execution depends heavily on the model used, though we shouldn’t expect anything significant since the prompt is very small and the API call already returns a structured JSON.

  • 1 single execution with GPT-4o-mini costs $0.0003335.
  • 1 month of executions (morning + evening) costs around $0.30.

    Conclusions

    AI is really changing the way we approach all kinds of problems, and this small experiment is a practical example of that.

    What I showed you in this article is something I would have solved in the past with a “simple” tool that handled all the logic: I would have written code to fetch the weather data, more code to query the station, more code to format the message and finally to send it on Telegram.

    That said, AI has its downsides too: the decision to write a REST service to pull data from the weather website was intentional, since AI doesn’t execute in a predictable way. I also wanted a tool that could be reused in different contexts and by other agents.

    If you want to replicate the project or have any questions, all the repositories are public and I’m happy to help in the comments!

    Until next time!

    Share this article
    Shareable URL
    Prev Post

    Minimal api VS controller

    Next Post

    What’s new in Angular 22

    Read next

    Ocelot API Gateway

    In modern architectures, especially those based on microservices, the API Gateway represents a fundamental…
    Api gateway header

    ChatGPT-5 is coming!

    Back in February, Sam Altman hinted that the new model might drop this summer… and here we are!…

    LINQ Extension Method

    At the 2024 edition of Overnet’s WPC conference, I attended an insightful talk about LINQ extension…