Skip to main content
Glama

MCP Weather & Transit Advisor

Tests

A small Model Context Protocol server that lets Claude check real-time weather and plan real public-transport trips, then recommend a route that suits the weather.

Tools

Tool

What it does

geocode_location

Converts a city name into latitude, longitude and timezone.

get_current_weather

Current conditions: temperature, feels-like, humidity, precipitation, wind.

get_commute_advice

Plans public-transport trips between two places (stations, landmarks, addresses) using real timetables. In rain, heat, wind or snow it recommends the option with the least walking; otherwise the earliest arrival.

get_stop_departures

Upcoming buses/trains at a stop, by name or Singapore 5-digit bus stop code.

Related MCP server: open-meteo

Data sources

Source

Used for

Key needed?

Open-Meteo

Weather, city geocoding

No

Transitous

Trip planning, stop timetables, stop/landmark search. Community-run router over open GTFS feeds; shows live delays where operators publish them

No

LTA DataMall

Live Singapore bus arrivals with crowding levels

Yes (free)

Transit coverage depends on which operators publish open data. Singapore, most of Europe and much of North America are covered; some regions are not. Times marked scheduled are timetabled, live include real-time updates.

Optional: live Singapore bus arrivals

  1. Request a free AccountKey at https://datamall.lta.gov.sg/content/datamall/en/request-for-api.html.

  2. Provide it as the LTA_ACCOUNT_KEY environment variable (see the Claude Desktop config below).

Without a key, get_stop_departures falls back to Transitous timetables for Singapore stop codes.

Caching

API answers are cached in a local SQLite file (~/.mcp-weather-advisor/cache.sqlite3) so repeated questions are answered instantly and the free APIs aren't hammered. Cached answers end with "(Served from cache, fetched N min ago.)".

Data

Kept for

Notes

Weather

15 min

Trip plans and stop timetables

15 min

Trips and departures that have already left are dropped before answering; if none are left, the API is asked again.

Live LTA bus arrivals

1 min

Live ETAs go stale quickly. Minutes-to-arrival are recomputed from the stored arrival time.

Place lookups (geocoding)

7 days

Coordinates don't change.

  • Change the TTLs at the top of mcp_weather_advisor/server.py (WEATHER_TTL, TRANSIT_TTL, ...).

  • WEATHER_ADVISOR_CACHE=/path/to/file.sqlite3 stores the cache elsewhere; WEATHER_ADVISOR_CACHE=off disables it.

  • API keys are never written to the cache. If the cache file can't be opened, the server simply calls the APIs directly.

  • To clear the cache, delete ~/.mcp-weather-advisor/cache.sqlite3.

Installation

1. Install Python 3.10 or newer

  • macOS: download from https://www.python.org/downloads/ (or brew install python).

  • Windows: download from the same page and tick "Add python.exe to PATH" in the installer.

  • Check it worked: python3 --version (on Windows: python --version).

2. Clone the project and create a virtual environment

A virtual environment (.venv) is a private Python install for this project. Create it inside the project folder: the Claude Desktop config below points at it.

macOS / Linux

git clone https://github.com/viaanshetty3-debug/mcp-weather-advisor.git
cd mcp-weather-advisor
python3 -m venv .venv
source .venv/bin/activate
pip install -e .

Windows (PowerShell)

git clone https://github.com/viaanshetty3-debug/mcp-weather-advisor.git
cd mcp-weather-advisor
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -e .

pip install -e . reads pyproject.toml and:

  • installs the dependencies (mcp, httpx);

  • installs the server as an editable package, so edits to the code take effect without reinstalling;

  • adds a mcp-weather-advisor command that starts the server.

Installing without a virtual environment: pip install -e . also works system-wide, but some Pythons (Homebrew's, and many Linux distributions') refuse with an externally-managed-environment error. There, use the virtual environment above, or pipx: pipx install -e ..

Intel Mac note: cryptography (a dependency of mcp) stopped publishing Intel Mac wheels after version 48. pyproject.toml therefore keeps it below 49 on Intel Macs only, so the install doesn't try to compile it from source. Other platforms get the latest version.

3. Check it runs

python server.py

The server starts and waits silently for Claude to talk to it over stdio. That's expected; press Ctrl+C to stop. mcp-weather-advisor and python -m mcp_weather_advisor start the same server.

To try the tools interactively in the MCP Inspector (needs Node.js and pip install -e ".[dev]"):

mcp dev mcp_weather_advisor/server.py

Connect to Claude Desktop

Claude Desktop starts the server itself, using two absolute paths from its config file:

Config key

Points to

Example (macOS)

command

the Python inside your .venv

/Users/alex/mcp-weather-advisor/.venv/bin/python

args

the server.py in the project's top folder

/Users/alex/mcp-weather-advisor/server.py

With the virtual environment activated, run this from the project folder (macOS/Linux). It prints the block with your real paths filled in:

python -c 'import json, os, sys; print(json.dumps({"mcpServers": {"weather-transit-advisor": {"command": sys.executable, "args": [os.path.abspath("server.py")]}}}, indent=2))'

Or write it by hand. Find the project folder's absolute path with pwd (macOS/Linux) or (Get-Location).Path (Windows), then fill in one of the templates below.

Step 2: The configuration block

macOS / Linux (replace /Users/alex/mcp-weather-advisor with your project folder):

{
  "mcpServers": {
    "weather-transit-advisor": {
      "command": "/Users/alex/mcp-weather-advisor/.venv/bin/python",
      "args": [
        "/Users/alex/mcp-weather-advisor/server.py"
      ]
    }
  }
}

Windows (replace C:\\Users\\alex\\mcp-weather-advisor, keeping the double backslashes that JSON requires):

{
  "mcpServers": {
    "weather-transit-advisor": {
      "command": "C:\\Users\\alex\\mcp-weather-advisor\\.venv\\Scripts\\python.exe",
      "args": [
        "C:\\Users\\alex\\mcp-weather-advisor\\server.py"
      ]
    }
  }
}

Optional: live Singapore bus arrivals. If you have an LTA DataMall key, add an env block after args. Remember the comma after the closing ]:

{
  "mcpServers": {
    "weather-transit-advisor": {
      "command": "/Users/alex/mcp-weather-advisor/.venv/bin/python",
      "args": [
        "/Users/alex/mcp-weather-advisor/server.py"
      ],
      "env": {
        "LTA_ACCOUNT_KEY": "paste-your-real-key-here"
      }
    }
  }
}

Leave env out entirely if you don't have a key. A placeholder value causes 401 errors for Singapore stop codes.

Step 3: Paste it into Claude Desktop

  1. In Claude Desktop, open Settings → Developer → Edit Config. This opens claude_desktop_config.json:

    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

    • Windows: %APPDATA%\Claude\claude_desktop_config.json

  2. Paste the block in:

    • If the file is empty or {}: replace its contents with the block.

    • If it already has an "mcpServers" section: don't paste a second one. Copy only the "weather-transit-advisor": { ... } entry into the existing "mcpServers" object, with a comma between it and the server before it:

      {
        "mcpServers": {
          "some-other-server": { "command": "..." },
          "weather-transit-advisor": {
            "command": "/Users/alex/mcp-weather-advisor/.venv/bin/python",
            "args": ["/Users/alex/mcp-weather-advisor/server.py"]
          }
        }
      }
  3. Save, then fully quit Claude Desktop (macOS: ⌘Q; Windows: right-click the tray icon → Quit) and reopen it. Just closing the window isn't enough.

  4. The tools appear under the tools (🔨) menu in a new chat. Try:

    • "What's the weather in Lisbon, and should I cycle to work?"

    • "How do I get from Orchard MRT to Changi Airport right now?"

    • "When's the next bus at stop 83139?"

Common mistakes

Symptom

Cause

Fix

Server fails with No module named 'httpx' (or 'mcp')

command is a Python outside the .venv: the system python3, or the real file the .venv Python links to

Use the path ending in .venv/bin/python (Windows: .venv\Scripts\python.exe) as-is. Don't resolve it with readlink/realpath.

Server fails to start / file not found

Relative paths like .venv/bin/python or server.py. Claude Desktop doesn't start in your project folder.

Use full absolute paths starting with / (or C:\\ on Windows).

Claude Desktop reports invalid JSON

Single backslashes on Windows, a missing comma between servers, or a trailing comma after the last item

Use \\ in Windows paths, and check commas. Paste the file into a JSON validator if unsure.

No tools appear

Claude Desktop wasn't fully restarted

Quit it completely (⌘Q / tray → Quit) and reopen.

You moved or renamed the project folder

The paths in the config are now wrong

Re-run the Step 1 command and update the config.

Claude Desktop's own log for this server is ~/Library/Logs/Claude/mcp-server-weather-transit-advisor.log on macOS (Windows: %APPDATA%\Claude\logs\). It shows startup errors such as the ones above. Problems inside the tools go to this project's own log; see Logging.

Alternative: instead of python + server.py, command can be the installed launcher alone (/Users/alex/mcp-weather-advisor/.venv/bin/mcp-weather-advisor, Windows ...\\.venv\\Scripts\\mcp-weather-advisor.exe) with no args. Both start the same server.

Project layout

mcp-weather-advisor/
├── server.py                 ← the file Claude Desktop runs (a small launcher)
├── mcp_weather_advisor/      ← the server package
│   ├── __init__.py           version number
│   ├── __main__.py           enables `python -m mcp_weather_advisor`
│   └── server.py             the server: settings, logging, cache, helpers, the four tools
├── tests/                    pytest suite (fake APIs; no internet needed)
│   ├── conftest.py           fixtures: starts the server over stdio
│   ├── fake_api.py           local stand-in for Open-Meteo / Transitous / LTA
│   ├── sample_data.py        realistic API responses for the tests
│   └── test_*.py             the tests (see Testing)
├── pyproject.toml            packaging: dependencies, `mcp-weather-advisor` command, pytest settings
├── requirements.txt          shortcut for `pip install -e .`
├── requirements-dev.txt      shortcut for `pip install -e ".[dev]"`
├── README.md
├── LICENSE                   MIT
└── .venv/                    your virtual environment (created by you, not in git)

mcp_weather_advisor/server.py is organised in labelled sections: settings, logging, cache, helpers, the four tools (decorated with @mcp.tool()) and the entry point. Each tool's docstring is what Claude reads to decide when to use it.

Where files are stored

The cache (cache.sqlite3) and log (mcp_server.log) live in ~/.mcp-weather-advisor/, created on first use. They're kept outside the code folder because an installed package's folder may be read-only. Set WEATHER_ADVISOR_HOME to use another folder, or move each file individually with WEATHER_ADVISOR_CACHE and WEATHER_ADVISOR_LOG.

Logging

Problems are written to ~/.mcp-weather-advisor/mcp_server.log as JSON Lines, one JSON object per line:

{"ts": "2026-11-10T03:29:38.790Z", "level": "ERROR", "event": "api_timeout", "tool": "get_current_weather", "call_id": "27efa384", "url": "https://geocoding-api.open-meteo.com/v1/search", "params": {"name": "tokyo", "count": 1, "language": "en"}, "timeout_s": 20.0, "elapsed_ms": 20004, "error": "ReadTimeout"}

Every record has ts (UTC), level and event. Records made during a tool call also carry tool and a call_id, so you can group everything from one call.

Event

Level

When

api_timeout

ERROR

An API didn't answer within the timeout

api_http_error

ERROR

An API returned HTTP 4xx/5xx (includes status and the first 200 characters of the body)

api_unreachable

ERROR

Connection failed (DNS, refused, network down)

api_invalid_json

ERROR

An API answered with something that isn't JSON

api_bad_shape

ERROR

Valid JSON, but missing expected fields (includes a traceback)

bad_coordinates

ERROR

A geocoder returned missing or impossible latitude/longitude

location_not_found

WARNING

No place/stop matched the query

invalid_input

WARNING

Blank or overlong input

cache_unavailable / cache_error

WARNING

The cache file couldn't be opened, read or written

tool_crashed

ERROR

Any other unexpected exception (includes a traceback)

server_start / server_stop

INFO

Server lifecycle

  • Nothing is ever printed to stdout. stdout carries the MCP protocol, and the test suite checks it stays clean while every failure type is logged.

  • No failure crashes a tool. Every one becomes a readable message for Claude, such as "Could not get weather for 'Tokyo': the service did not respond within 20 seconds."

  • The log rotates at about 1 MB, keeping mcp_server.log.1 to .3.

  • API keys are never logged. Request headers are not recorded, and query parameters with names like key, token or secret are redacted.

  • WEATHER_ADVISOR_LOG=/path/to/file.log moves the log; WEATHER_ADVISOR_LOG=off disables it. If the file can't be opened, log lines go to stderr instead, which Claude Desktop saves in its own MCP logs.

  • WEATHER_ADVISOR_TIMEOUT sets the network timeout in seconds (default 20).

Quick look at recent errors (needs jq):

jq -c 'select(.level != "INFO") | {ts, event, tool, error, status}' ~/.mcp-weather-advisor/mcp_server.log

Testing

pip install -e ".[dev]"
python -m pytest

The suite (~255 tests, about 90 seconds) needs no internet and no API keys:

  • Over stdio, like Claude Desktop: almost every test starts the installed server as a subprocess and calls its tools with the official MCP client.

  • Against a local fake API: each test scripts the fake's replies, via the environment variables OPEN_METEO_GEOCODING_URL, OPEN_METEO_FORECAST_URL, TRANSITOUS_URL and LTA_BUS_ARRIVAL_URL.

File

Covers

tests/test_protocol.py

Tool discovery, schemas, unknown tools, missing/wrong-type arguments

tests/test_weather.py

Weather and geocoding output, unknown/blank/overlong/Unicode places, query-string injection

tests/test_commute.py

Trip ranking in good vs bad weather, local times, departed trips, no-route and bad-timezone cases

tests/test_departures.py

Stop codes vs names, limit clamping, LTA live arrivals, LTA auth/rate-limit errors

tests/test_api_failures.py

Every tool × every upstream API returning HTTP 4xx/5xx, HTML, invalid JSON, empty bodies, wrong JSON shapes, timeouts, or being unreachable

tests/test_cache.py

Cache hits, TTLs, expiry, departed-trip refresh, restart persistence, corrupt/unwritable cache files, keys never stored

tests/test_logging.py

Every failure type writes one valid JSON log record with the right fields; raw stdout stays pure JSON-RPC; key redaction, rotation, unwritable/disabled log

tests/test_packaging.py

Package metadata, the mcp-weather-advisor command, python -m and python server.py launch, running from any folder, default file locations

tests/test_helpers.py

Fast in-process unit tests of weather thresholds, time conversion and cache primitives

Continuous integration

.github/workflows/tests.yml runs the whole suite on GitHub Actions for every push and pull request (and on demand from the Actions tab), on Python 3.11 and 3.12 on Ubuntu. Each run:

  1. installs the package with pip install -e ".[dev]", exactly as a developer would;

  2. runs the SQLite cache tests (tests/test_cache.py) as their own step;

  3. runs everything else: the MCP stdio tool tests, API-failure handling, logging, packaging and unit tests. This step runs even if the cache step failed, so all problems show up in one run.

If anything fails, the run keeps a downloadable artifact with JUnit reports plus each test's server stderr and mcp_server.log. No secrets are needed: the tests use a local fake API.

Troubleshooting

  • Server doesn't appear in Claude: see Common mistakes.

  • ModuleNotFoundError: run pip install -e . with the .venv activated, and make sure command is that .venv's Python (see Common mistakes).

  • mcp-weather-advisor: command not found: the environment's bin (or Scripts) folder isn't on your PATH. Activate the virtual environment, or use the full path.

  • "No location found": try a larger nearby city or add the country.

  • "No public-transport route found": the region may not publish open transit data on Transitous.

  • LTA errors (401): the LTA_ACCOUNT_KEY is missing or wrong.

License

MIT. Weather data by Open-Meteo.com (CC BY 4.0). Transit routing by Transitous using open GTFS data from each operator. Singapore bus arrivals from LTA DataMall under the Singapore Open Data Licence.

Available Tools

4 tools
geocode_locationB

Find the coordinates (latitude/longitude) of a city or town by name.

Args: place: A city or town name, e.g. "Singapore" or "Austin".

Inputs: place (required). Returns: result

get_commute_adviceA

Plan a public-transport trip leaving now, using real timetables, and recommend an option based on the current weather.

Uses open GTFS timetable data via Transitous (live delays where the operator publishes them). Coverage depends on the region.

Args: origin: Where you start - a station, landmark or address, e.g. "Orchard MRT, Singapore". destination: Where you are going, e.g. "Changi Airport".

Inputs: origin (required), destination (required). Returns: result

get_current_weatherA

Get real-time weather for a city or town by name.

Args: place: A city or town name, e.g. "Tokyo".

Inputs: place (required). Returns: result

get_stop_departuresA

List upcoming buses/trains at a public-transport stop.

For a Singapore 5-digit bus stop code (e.g. "83139") this returns LIVE arrivals from LTA DataMall when an LTA key is configured; otherwise it returns timetabled departures from Transitous.

Args: stop: A stop name ("Tampines MRT, Singapore") or a Singapore 5-digit bus stop code ("83139"). limit: Maximum number of departures to list (default 8).

Inputs: stop (required), limit. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 4 tools

    Disambiguation5/5

    Each tool targets a distinct resource/action: coordinate lookup, current conditions, end-to-end commute planning, and stop-level departures. The two transit tools are clearly separated by scope (trip planning vs. a single stop's board), and geocode_location is explicitly a coordinate helper rather than a weather query.

    Naming Consistency5/5

    All four names are snake_case verb_noun constructions (geocode_location, get_current_weather, get_commute_advice, get_stop_departures), with a consistent get_ prefix on the retrieval tools. No mixing of camelCase or vague single-word verbs.

    Tool Count4/5

    Four tools is on the thin side but each one earns its place in a small weather+transit surface, with no filler or redundant tools. A forecast tool would round it out, but the count is well-scoped for the stated purpose.

    Completeness3/5

    Core workflows exist, but the weather side stops at 'current' with no forecast/hourly outlook, and commute advice is fixed to 'leaving now' with no departure-time or alternative-route parameter. There is also no reverse geocoding, leaving notable gaps for a server billed as a weather and transit advisor.

    Maintenance

    ActivityMaintained
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      C
      maintenance
      Enables users to geocode city names and retrieve current weather conditions plus a 1–7 day forecast through a public weather API, with no API key required, for MCP clients such as Claude Desktop or Cursor.
      2
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables Claude and other MCP clients to answer live questions about Toronto's transit network, including next arrivals, routes, connections, detours, accessibility and service advisories. It fetches TTC timetables and real-time feeds on demand, reporting data freshness and attaching relevant disruptions to each answer.
      19
      MIT