sg-haze-rain-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@sg-haze-rain-mcp how's the haze right now, and can I run at 6?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
🌫️ sg-haze-rain-mcp
Ask your AI agent "how's the haze?" and get Singapore's live PSI, PM2.5 and rain, straight from NEA, for exactly where you are.
Every haze season, Singaporeans refresh the NEA app, squint at five regional numbers and try to remember what "Unhealthy" means for a 6 pm run. sg-haze-rain-mcp puts that knowledge inside the AI tools you already have open. It is a zero-config Model Context Protocol server for Claude Code, Codex, Claude Desktop, Cursor, VS Code, Windsurf, Zed and any other MCP client.
🧭 Knows where you are. Geolocates your public IP and picks the nearest of NEA's five PSI regions. Or pass a region, coordinates or an IP explicitly.
🏥 Speaks NEA's language. Every reading comes with the official band and the three-tier health advisory (general public · elderly, pregnant women and children · chronic lung or heart conditions).
🌧️ Rain, not just haze. Nearest three rain gauges with 5-minute totals, the 2-hour area nowcast, and how many of ~90 gauges are wet island-wide.
🔑 No API key, no account. Pure public data. One
npxcommand and you are done.🌏 English and Chinese labels and advisories, per call or by default.
🤖 Agent-friendly. Human-readable text plus
structuredContentJSON in every result, so an agent can quote the summary or branch on the numbers.
> how's the haze right now, and can I run at 6?
🌫️ Singapore haze — 28 Sept 2026, 21:46 SGT
Location: Bishan, Singapore → nearest PSI region: central (located via public IP)
24-hr PSI: 108 — Unhealthy (101–200)
1-hr PM2.5: 119 µg/m³ — Elevated (Band II)
24-hr PM2.5: 63 µg/m³ · 24-hr PM10: 72 µg/m³
Health advisory (Unhealthy):
• General public: Reduce prolonged or strenuous outdoor physical exertion.
• Elderly, pregnant women, children: Minimise prolonged or strenuous outdoor physical exertion.
• Chronic lung / heart conditions: Avoid prolonged or strenuous outdoor physical exertion.
All regions (24-hr PSI): north 75 · south 105 · east 90 · west 101 · central 108
☀️ No rain nearby — 21:45 SGT
• Macritchie Reservoir (1.9 km): 0 mm • Lower Peirce Reservoir (2.1 km): 0 mm • Upper Peirce (2.6 km): 0 mm
2-hour forecast Bishan: Cloudy — 9.30 pm to 11.30 pm
Island-wide: 0/89 stations reporting rainQuick start
Requires Node.js 18.17+ (node --version). Nothing else: no sign-up, no key.
claude mcp add --scope user sg-haze-rain -- npx -y github:ericwang915/sg-haze-rain-mcpPrefer Chinese labels by default:
claude mcp add --scope user --env SG_HAZE_LANG=zh sg-haze-rain -- npx -y github:ericwang915/sg-haze-rain-mcpRun /mcp inside Claude Code to confirm the server is connected with five tools. To share with a team, commit a project-level .mcp.json instead.
codex mcp add sg-haze-rain -- npx -y github:ericwang915/sg-haze-rain-mcpor in ~/.codex/config.toml:
[mcp_servers.sg_haze_rain]
command = "npx"
args = ["-y", "github:ericwang915/sg-haze-rain-mcp"]
# env = { SG_HAZE_LANG = "zh" }Add to claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):
{
"mcpServers": {
"sg-haze-rain": {
"command": "npx",
"args": ["-y", "github:ericwang915/sg-haze-rain-mcp"]
}
}
}Use the one-click badges at the top, or paste the same command / args pair into that client's MCP config (.cursor/mcp.json, .vscode/mcp.json, …):
{ "command": "npx", "args": ["-y", "github:ericwang915/sg-haze-rain-mcp"] }# pin to a release tag
npx -y "github:ericwang915/sg-haze-rain-mcp#v0.1.0"
# install once, then reference the binary
npm install -g github:ericwang915/sg-haze-rain-mcp
claude mcp add sg-haze-rain -- sg-haze-rain-mcp
# hack on it
git clone https://github.com/ericwang915/sg-haze-rain-mcp.git && cd sg-haze-rain-mcp
npm install # builds dist/ via prepare
claude mcp add sg-haze-rain -- node "$PWD/dist/index.js"The first npx run downloads and builds (about 20 s); later starts come from the npx cache and are instant.
Things to ask
"How's the haze right now?"
"Is it safe for my kids to play outside this afternoon?"
"Will it rain in the next two hours in Jurong?"
"Compare PSI across all regions."
"What's the 4-day outlook?"
"Should I bring an umbrella to Changi at 5 pm?"
Related MCP server: data-gov-sg
Tools
Tool | Purpose | Key fields in |
| One call: haze + rain + 2-hour forecast for your spot. Start here. |
|
| 24-hr PSI, 1-hr PM2.5, 24-hr PM2.5 / PM10, NEA band, advisory, all five regions, pollutant sub-indices. |
|
| Nearest three gauges (5-minute totals), 2-hour area forecast, island-wide wet-station count. |
|
|
|
|
| Shows the location and PSI region the other tools will use, and how it was decided. |
|
All tools take the same optional inputs: region (north · south · east · west · central), lat + lon, ip, lang (en · zh).
One prompt ships too: haze_check (activity: "run 5 km at 6pm") asks the assistant for a plain-language go / no-go based on the current readings.
How it works
flowchart LR
A[MCP client<br/>Claude Code · Codex · Cursor …] -- stdio --> S[sg-haze-rain-mcp]
S --> L{Where is the caller?}
L -- region given --> R[Region centroid]
L -- lat/lon given --> C[Coordinates]
L -- otherwise --> IP[Public IP → city<br/>ipwho.is ⟶ ipapi.co]
R & C & IP --> N[Nearest PSI region<br/>+ nearest gauges / area]
N --> F[NEA real-time feeds<br/>data.gov.sg v2]
F --> B[NEA bands +<br/>health advisory]
B --> ALocation resolution is strictly ordered: an explicit region wins, then lat/lon, then a given ip, then the machine's own public IP. If the IP lands outside Singapore or the lookup fails, the server falls back to a default region and says so in the reply, so the agent never silently reports the wrong place.
Feeds are cached in-process for 60 s. data.gov.sg rate-limits bursts with HTTP 429; the client retries with backoff, honours Retry-After, and if the feed still refuses it serves the last good copy it holds rather than failing a "how is the haze" question.
Data
Everything comes from the National Environment Agency (NEA), published on Singapore's open-data platform data.gov.sg. No key, same data as the NEA app.
Feed | Endpoint ( | Refresh |
24-hr PSI, 24-hr PM2.5 / PM10, pollutant sub-indices, 5 regions |
| hourly |
1-hr PM2.5, 5 regions |
| hourly |
Rainfall, 5-minute totals, ~90 gauges |
| every 5 min |
2-hour area forecast, 47 areas |
| every 30 min |
24-hour forecast, general + regional periods |
| several times daily |
4-day outlook |
| daily |
NEA bands, as reported
24-hr PSI
PSI | Band | General public |
0–50 | Good | Normal activities |
51–100 | Moderate | Normal activities |
101–200 | Unhealthy | Reduce prolonged or strenuous outdoor exertion |
201–300 | Very Unhealthy | Avoid prolonged or strenuous outdoor exertion |
> 300 | Hazardous | Minimise outdoor activity; N95 for anyone outdoors for hours |
Replies also include the stricter guidance NEA gives for the elderly, pregnant women, children, and people with chronic lung or heart disease.
1-hr PM2.5 (µg/m³), NEA's indicator for the coming hours: 0–55 Normal (I) · 56–150 Elevated (II) · 151–250 High (III) · > 250 Very High (IV).
Privacy
With no location inputs, the server asks a public IP-geolocation service where your public IP is: ipwho.is first, ipapi.co as fallback. Both are free and keyless. Only the returned coordinates and city name are used; nothing is stored. Resolution is city-level, and a VPN or corporate egress will move you.
Do not want that call at all?
SG_HAZE_IP_LOOKUP=off(optionally withSG_HAZE_DEFAULT_REGION=west), oralways pass
regionorlat/lonfrom the client.
Requests to NEA / data.gov.sg carry no information about you; the feeds are identical for everyone.
Configuration
Variable | Default | Effect |
|
|
|
|
| Region used when location is unknown or outside Singapore |
|
|
|
|
| How long a fetched feed is reused |
| data.gov.sg v2 URL | Point at a mirror or a test server |
Pass them with --env KEY=value in claude mcp add, an env table in Codex's config.toml, or an env object in JSON configs.
Development
npm install # installs and builds
npm run build # tsc → dist/
npm test # build + stdio smoke test against the live feeds
node dist/index.js --helptest/smoke.mjs speaks raw JSON-RPC to the built server, lists the tools and calls each one with explicit regions or coordinates. It sets SG_HAZE_IP_LOOKUP=off, so running the tests never geolocates your machine. CI runs it on Node 18, 20 and 22.
src/index.ts stdio entry point, --help / --version
src/server.ts tool + prompt definitions, text formatting (en / zh)
src/nea.ts NEA feed client: camel/snake normalisation, cache, 429 handling
src/geo.ts region / coords / IP resolution, haversine nearest-neighbour
src/bands.ts PSI and PM2.5 bands and NEA health advisoriesRoadmap
UV index, air temperature, humidity and wind from the same NEA feed family
Haze trend: compare the current PSI with 3 and 6 hours ago
Optional HTTP / SSE transport for hosted deployments
More languages for labels and advisories (Malay, Tamil)
Have a use case? Open an issue or see CONTRIBUTING.md.
FAQ
Does it need npm? It needs Node.js 18.17+. npx ships with Node, so if you can run Claude Code or Codex you already have everything.
Why five regions and not my street? NEA publishes PSI for north, south, east, west and central only. Rain, however, is gauge-level, so the nearest three gauges are usually within 2–3 km.
Is this official? No. It relays NEA's published data unchanged. For official advisories see haze.gov.sg and nea.gov.sg.
I am outside Singapore. The server notices, uses the default region, and tells the agent so. Pass region to pick one deliberately.
License
MIT. Data © National Environment Agency, Singapore, under the Singapore Open Data Licence.
If this saves you a trip to the NEA app, a ⭐ helps other Singaporeans find it.
Made by the team behind Audiee.ai — private AI meeting notes for Mac that also hand your meetings to Claude Code and Cursor as MCP tools.
Available Tools
5 toolsget_forecastSingapore weather forecastA
NEA forecast for the caller's area/region. horizon: '2h' (area nowcast), '24h' (default; general + regional periods) or '4d' (island-wide outlook).
Inputs: ip, lat, lon, lang, +2 more.
get_hazeSingapore haze (PSI / PM2.5)A
Current haze for the caller's nearest PSI region: 24-hr PSI, 1-hr PM2.5, 24-hr PM2.5/PM10, the NEA band and health advisory, plus all five regions for comparison. Data: NEA via data.gov.sg, refreshed hourly.
Inputs: ip, lat, lon, lang, +1 more.
get_rainSingapore rain nowA
Is it raining near the caller? Uses NEA's 5-minute rain-gauge network (nearest three stations) plus the 2-hour area forecast; also counts wet stations island-wide.
Inputs: ip, lat, lon, lang, +1 more.
locate_meLocate caller in SingaporeA
Resolve the caller's location (public IP by default) to coordinates and the nearest NEA PSI region. Useful to check what the other tools will use before calling them.
Inputs: ip, lat, lon, lang.
weather_nowSingapore weather now (haze + rain)A
One-call summary for the caller's location in Singapore: 24-hr PSI and 1-hr PM2.5 with NEA's health advisory, whether it is raining nearby, and the 2-hour forecast. Location comes from the caller's public IP unless region / lat+lon / ip is given.
Inputs: ip, lat, lon, lang, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 5 tools
The three get_* tools target distinct data (haze/PSI, rain, forecast), but weather_now is a composite summary that duplicates all of them, creating genuine overlap about when to call the aggregate vs. the specific tools. Descriptions do clarify intent, keeping it from being worse than moderate ambiguity.
Four tools follow a verb_object pattern (get_haze, get_rain, get_forecast, locate_me), but weather_now breaks the convention with a noun_first form. The deviation is minor and all names remain readable.
Five tools is well-scoped for a focused Singapore weather/haze server, with a clear summary tool plus targeted drill-downs. Each tool earns its place.
The surface covers location resolution, haze/PSI, rain, forecast, and an aggregate summary, giving good lifecycle coverage for the domain. Only marginal extras (e.g. historical data or alert subscriptions) are absent, which agents can work around.
Maintenance
Related MCP Connectors
data.gov.sg MCP — Singapore open data + real-time environment/transport feeds
Air Quality MCP — wraps air-quality-api.open-meteo.com (free, no auth)
The official Model Context Protocol server for Ambee. It gives any MCP-compatible AI assistant — Claude, ChatGPT, Cursor, VS Code, Ollama, and more direct access to live air quality, pollen, and weather data. To get started, including information on signing up and obtaining your Ambee key, check out the Ambee documentation on https://docs.ambeedata.com
Singapore property & financial data APIs for AI agents. 27 MCP tools. x402 micropayments.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceReal-time Singapore government data for AI agents. Weather forecasts, air quality (PSI/PM2.5), HDB carpark availability, and taxi supply from data.gov.sg.7 npm2ISC
- AlicenseNot gradedqualityBmaintenanceEnables access to Singapore government open data and real-time environment/transport feeds including weather, air quality, taxi availability, and traffic incidents.97 npmMIT
- FlicenseNot gradedqualityDmaintenanceWraps NEA's 2-hour weather forecast API to provide rain alerts for central Singapore areas, enabling automations for rain detection.1-
- FlicenseNot gradedqualityCmaintenanceProvides current weather conditions and forecasts for Singapore from official NEA APIs, enabling users to query real-time weather data and multi-day forecasts through natural language.-