Skip to content
Node.js

Building a Node.js Chatbot that Uses Real-Time Weather Data

Create a Node.js chatbot using OpenRouter to fetch real-time weather data, showcasing an Agentic Tool-Use architecture.

Topic
Node.js
Reading time
5 min
Length
1,059 words
Published
Sep 8, 2026
04:16 pm IST
In this article
  1. Understanding Agentic Tool-Use
  2. Implementing the Agentic Workflow
  3. Executing the Loop Safely
  4. Fetching Weather Data
  5. Resilient API Calls
  6. Integrating an Express Backend
  7. Actions for Implementing Chatbots with Real-Time Data
  8. Limitations and Considerations

The recent article on DEV highlights an interesting project: a Node.js chatbot named Mausam AI, which fetches real-time weather data. This project acts as a Minimum Viable Product (MVP) and showcases an Agentic Tool-Use architecture. It's a great example of how a chatbot can use external APIs to pull in live data.

Understanding Agentic Tool-Use

Large Language Models (LLMs) have a big limitation: they can't access real-time data. Their knowledge is static, stuck at the time they were trained. Ask about the current weather in Mumbai, and a standard LLM might just make something up or admit it doesn't know, since it can't browse the internet. This is where Agentic workflows become useful.

A tool-use framework equips an LLM to grab real-time data. In our case, the bot uses a tool named get_mausam to fetch weather info from an external API, wttr.in. This data is then woven back into the chat, so the LLM can answer with the most current information.

Implementing the Agentic Workflow

The main logic for Mausam AI is found in helper.js, where the prompts and agent logic are set up. The workflow loops through these steps: START ➡️ PLAN ➡️ TOOL ➡️ OUTPUT. Here's how it plays out:

const MAIN_SYSTEM_PROMPT = `
You are an AI agent that reply only to queries related to weather, temperate and humidity.
STRICT RULES:
- output must a single valid json without any extra space, text. NO markdown , No Text, No output tags.
- MUST run one step at a time. Do not run multiple steps in parallel. Stop after each step
- Strictly follow the Sequence of steps must be START then PLAN then TOOL then OUTPUT
- don't run a step more than once for a single query.
OUTPUT FORMAT:
{
    "step": START|PLAN|TOOL|OUTPUT,
    "context": "string",
    "input": "string",
    "usefull": "boolean",
    "toolname": "string"
}
AVAILABLE TOOL:
- get_mausam -> return temperate, weather and humidity for a given location
`;

This structure allows the backend to handle JSON output step by step. When the AI needs to use a tool, it produces a JSON object indicating the necessary action.

Executing the Loop Safely

To ensure the execution loop runs safely, Mausam AI uses a getConversation function with a max iteration limit. This helps avoid infinite loops or hallucinations. The function processes the AI's output and decides what to do next:

const getConversation = async function (messages, context = []) { 
    let iterations = 0;
    const MAX_ITERATIONS = 5;
    while (iterations < MAX_ITERATIONS) {
        iterations++;
        try {
            const completion = await callOpenRouterModel(messages);
            let outputContent = completion?.choices[0]?.message?.content;
            if (output.step === "OUTPUT") {
                context.push({ sender: "SYSTEM", message: output.context });
                return;
            } else if (output.step === "TOOL" && output.toolname === "get_mausam") {
                 let tool_resp = await getWeather(output.input);
                 messages.push({ role: "system", content: `RESPONSE FROM get_mausam: ${tool_resp}` });
            } else {
                 context.push({ sender: "BOT", message: (output.context || 'Thinking') + '...' });
                 messages.push({ role: "system", content: outputContent });
            }
            await sleep(1000);
        } catch (error) {
            console.error("Agent loop error:", error.message);
            context.push({ sender: "SYSTEM", message: "An error occurred while processing your request." });
            return;
        }
    }
}

This ensures the tool is called safely and the AI's responses are handled effectively.

Fetching Weather Data

When the AI uses get_mausam, a JavaScript fetch request to the wttr.in API is triggered, fetching the weather data. Here’s the function that does the fetching:

async function getWeather(city) {
    const url = `https://wttr.in/${encodeURIComponent(city)}?format=%c+%C+%t+%h+%T`;
    const response = await fetch(url);
    if (!response.ok) throw new Error(`Request failed`);
    const data = await response.text(); 
    return data.trim();
}

This function processes and formats the weather data, feeding it back into the chatbot's context for a coherent response.

Resilient API Calls

To keep the chatbot running even during API key failures, Mausam AI uses a try/catch block for the primary API key and switches to a backup if needed:

const client1 = new OpenAI({ baseURL: "https://openrouter.ai/api/v1", apiKey: process.env.API_KEY });
const client2 = new OpenAI({ baseURL: "https://openrouter.ai/api/v1", apiKey: process.env.OPEN_ROUTER_KEY_2 });
const callOpenRouterModel = async function (messages) {
    const requestPayload = {
        model: "liquid/lfm-2.5-2.6b:free",
        messages: messages,
        response_format: { type: "json_object" }
    };
    try {
        return await client1.chat.completions.create(requestPayload);
    } catch (error) {
        console.error("Primary key failed, trying fallback...", error.message);
        return await client2.chat.completions.create(requestPayload);
    }
}

This setup ensures the chatbot can handle failures without breaking the user experience.

Integrating an Express Backend

Everything is wrapped up in a straightforward Express.js server, which supports numerous concurrent users without race conditions. The server uses a session map indexed by a unique sessionId, generated on the frontend, to maintain chat states:

On the frontend, a user-friendly dark-mode UI is set up, generating sessionIds via sessionStorage and checking the backend API for messages. Intermediate "thinking" steps are styled differently, making it clear to users how the AI is reasoning through its processes.

Actions for Implementing Chatbots with Real-Time Data

Looking to build a similar chatbot for your projects? Here are a few things to keep in mind:

  • Understand your LLM's limitations: Remember that your model's knowledge is static and doesn't include real-time data.
  • Add an Agentic Tool-Use Architecture: Equip your model with tools to pull in real-time data via external APIs.
  • Create a Structured Workflow: Use a looped workflow with well-defined stages (e.g., START, PLAN, TOOL, OUTPUT) for effective tool use.
  • Ensure Safe Execution: Set iteration limits and error boundaries to avoid infinite loops and secure tool calls.
  • Prepare for API Key Exhaustions: Have fallback mechanisms for dealing with API failures smoothly.
  • Build a Reliable Backend: Choose frameworks like Express.js to manage chat states and support multiple users simultaneously.
  • Prioritize User Experience: Design an intuitive interface that shows users how the AI thinks without overwhelming them.

Limitations and Considerations

The Agentic Tool-Use architecture is quite powerful, but here are some caveats:

  • MVP Status: Mausam AI is only a proof-of-concept and not ready for production. More testing and optimization are necessary for live deployments.
  • Dependency on External APIs: The chatbot relies on external APIs, which can cause delays or be unavailable at times.
  • Complex Tool Integration: Managing multiple tools and their interactions can add complexity to the system architecture.
  • Security Concerns: Handling API keys and user data requires strict security to avoid unauthorized access or data breaches.

Creating a Node.js chatbot with real-time data capabilities calls for a careful approach to architecture, tool integration, and user experience. Follow these guidelines and be mindful of potential limitations to build innovative solutions that combine the strengths of LLMs with real-time data access.

Sources

Building an MVP Agentic Tool-Use Bot with Node.js and OpenRouter 🌤️🤖

Every claim above was checked against this source before publishing. The analysis, the code and the opinions are mine.

Frequently asked

What is the purpose of Agentic Tool-Use?

Agentic Tool-Use allows LLMs to access real-time data by using external tools, overcoming the static nature of their trained knowledge.

How does Mausam AI fetch weather data?

Mausam AI uses a tool called get_mausam that fetches weather data from the wttr.in API, providing real-time updates.

What are the limitations of Mausam AI?

Mausam AI is an MVP, not production-ready, and relies on external APIs, which may introduce latency or availability issues.

How does Mausam AI handle API key failures?

Mausam AI implements a fallback mechanism, switching to a backup API key if the primary key fails, ensuring resilience.

Deepak Kumar

Written by

Deepak Kumar

Sr Software Engineer at India Today Group | Aaj Tak · MERN Stack · Generative AI

Most of my backend work is Node — APIs, queues and ingestion pipelines behind editorial products at India Today Group, plus the services running my own marketplaces. I write here about what those systems actually do once real traffic hits them.

Message me