Skip to main content
Glama
whathebronte

sg-weather-mcp

by whathebronte
README.md
# SG Weather MCP (rain alerts for anywhere in Singapore)

A small MCP server that wraps NEA's 2-hour Weather Forecast API and reports
rain conditions for any of the ~47 NEA forecast areas covering the whole of
Singapore. Check the entire island, or pass your own list of areas to filter
to just the places you care about. Built for use with Poke.com automations
over streamable HTTP.

Data source: data.gov.sg dataset `d_3f9e064e25005b0e42969944ccaf2e7a`
(NEA / Meteorological Service Singapore, 2-hour forecast).

## Tools

### `check_rain`
The main tool for a rain-alert automation. Fetches the live 2-hour forecast
for all of Singapore and reports whether any checked area shows rain,
showers, or thundery weather.

Optional inputs:
- `areas` — list of NEA area names to filter to (case-insensitive). Omit to
  check the whole island. Names not in the live feed are ignored and reported
  back under `unmatched_areas`, so the list is safe to tune per user.
- `response_format` — `markdown` (default) or `json`.

Key fields in the response:
- `rain_expected` (bool) — true if ANY checked area is wet
- `wet_areas` — list of `{area, forecast}` currently wet
- `forecasts` — areas grouped by forecast condition (keeps the whole-island
  payload compact instead of repeating the forecast string ~47 times)
- `checked_area_count` — how many areas were checked
- `unmatched_areas` — requested names that don't exist in the feed
- `valid_period` — forecast validity window
- `retrieved_at` — UTC timestamp

The live NEA feed is always the source of truth for area names — if NEA
adds or renames areas, the server keeps working without a code change.

### `list_all_areas`
Lists every NEA area (~47) with its current forecast. Useful for discovering
exact area names to pass to `check_rain`, or for a Singapore-wide view.
Set `names_only: true` for the smallest possible payload (just the names).

## Deploy to Render

1. Push this folder to a GitHub repo.
2. In Render: New > Web Service > connect the repo (or use the included
   `render.yaml` via New > Blueprint).
3. Render auto-detects Python. Build: `pip install -r requirements.txt`.
   Start: `python server.py`. No environment variables needed — Render's
   `PORT` is picked up automatically, and `render.yaml` pins `PYTHON_VERSION`
   so runtime upgrades on Render's side can't silently break the service.
4. After deploy, your MCP endpoint is:
   `https://<your-service>.onrender.com/mcp`

## Uptime

- **Health checks**: `render.yaml` sets `healthCheckPath: /health`, a
  dedicated liveness endpoint that always returns `200 {"status": "ok"}`.
  Render uses it to verify deploys and restart the service if it stops
  responding. It deliberately does not call the NEA API, so an upstream
  outage never gets the service restarted or a deploy marked as failed.
  Don't point the health check at `/mcp` — the MCP endpoint returns non-2xx
  to plain GETs, which fails every deploy (this bit us before).
- **Free-tier spin-down**: Render's free plan spins the instance down after
  ~15 minutes without inbound traffic, so the next request (e.g. your Poke
  automation) waits out a cold start of up to a minute. Poke's scheduled
  calls will still succeed — MCP clients tolerate the delay — but if you
  want instant responses, either upgrade the service to a paid plan (no
  spin-down) or point an external uptime monitor (UptimeRobot, Better
  Stack, etc.) at `https://<your-service>.onrender.com/health` every
  5–10 minutes. `/health` answers HEAD requests too, which is what most
  monitors send.

## Connect in Poke.com

1. In Poke, add a custom MCP connection pointing at the `/mcp` URL above.
2. Create an automation on a schedule (e.g. every 30 minutes) that calls
   `check_rain` — pass the `areas` you care about (e.g. `["City",
   "Bukit Merah"]`), or omit `areas` for island-wide coverage.
3. In the automation logic, message yourself when `rain_expected` is `true`,
   including `wet_areas` so you know which spots.

> **Upgrading from the earlier version?** The tool was previously named
> `check_rain_central` and defaulted to a hardcoded central-area list. It is
> now `check_rain` and defaults to all of Singapore — update your automation
> to call `check_rain` and pass your preferred `areas`.

## Local test

```bash
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
PORT=8123 python server.py
# then POST an MCP initialize to http://localhost:8123/mcp
```

Note: the NEA API is only reachable from an environment with open outbound
internet (like Render), not from restricted sandboxes.