Skip to main content
Glama
README.md
[![M8ven Live Monitored](https://m8ven.ai/badge/mcp/rashjredmund-weather-mcp-fg5e2v)](https://m8ven.ai/mcp/rashjredmund-weather-mcp-fg5e2v)
<!-- [![M8ven Score](https://m8ven.ai/badge/mcp/rashjredmund-weather-mcp-fg5e2v)](https://m8ven.ai/mcp/rashjredmund-weather-mcp-fg5e2v) -->
<!-- [![Glama](https://glama.ai/mcp/servers/RashJrEdmund/Weather-MCP/badge)](https://glama.ai/mcp/servers/RashJrEdmund/Weather-MCP) -->

**Verified on** [M8ven](https://m8ven.ai/mcp/rashjredmund-weather-mcp-fg5e2v) and [Glama](https://glama.ai/mcp/servers/RashJrEdmund/Weather-MCP).

___

![preview image](./preview.png)

# weather-mcp

TypeScript [MCP](https://modelcontextprotocol.io/docs/) server that exposes weather tools backed by [OpenWeatherMap](https://openweathermap.org/).

**Tools**

| Tool | Description |
| --- | --- |
| `get_current_weather` | Current conditions by city name or lat/lon, plus umbrella advice and outdoor checks |
| `get_forecast` | 5-day / 3-hour forecast by lat/lon, plus umbrella advice and outdoor checks per period |

Each successful tool response appends:

- **Umbrella** - whether to take one, based on rain/storm/snow and precipitation chance
- **Outdoor** - whether it is a good time to be outside, including heat, cold, wind, and humidity checks

**Transports**

| Mode | Env | Use when |
| --- | --- | --- |
| `stdio` (default) | `TRANSPORT=stdio` | Local Cursor / Claude Desktop |
| Streamable HTTP | `TRANSPORT=http` | Deploy (Render, etc.) / remote URL |

Official MCP docs: <https://modelcontextprotocol.io/docs/>

## Live remote (Render)

Deployed on Render’s free tier:

| | |
| --- | --- |
| Landing page | <https://weather-mcp-ts.onrender.com/> |
| **MCP endpoint** | <https://weather-mcp-ts.onrender.com/mcp> |
| Health check | <https://weather-mcp-ts.onrender.com/health> |

### Cursor config (remote)

Add this to **Settings → MCP** or `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "weather": {
      "url": "https://weather-mcp-ts.onrender.com/mcp"
    }
  }
}
```

No local build or API key in Cursor - the key lives in Render’s env vars.

> **Render free tier:** the service shuts down after ~**15 minutes** of inactivity. The next request is a **cold start** and can take up to ~**50 seconds** before MCP responds. Hit `/health` once if Cursor tools look stuck waking up.

## Prerequisites (local only)

- Node.js 20+
- pnpm (or npm/yarn)
- An OpenWeatherMap API key ([get one here](https://home.openweathermap.org/api_keys))

## Setup (local)

```bash
pnpm install
cp .env.example .env
```

Edit `.env` and set your key:

```bash
OPEN_WEATHER_MAP_API_KEY=your_key_here
TRANSPORT=stdio
```

Build the server:

```bash
pnpm run build
```

This writes the runnable entrypoint to `dist/index.js`.

## Add to Cursor (local stdio)

Cursor does not start this process from the project root by default for env loading, so pass the env file with an **absolute** path via Node’s `--env-file` flag.

1. Open **Cursor Settings → MCP**, or edit `~/.cursor/mcp.json`.
2. Add a `weather` entry under `mcpServers`:

```json
{
  "mcpServers": {
    "weather": {
      "command": "node",
      "args": [
        "--env-file",
        "/ABSOLUTE/PATH/TO/weather-mcp/.env",
        "/ABSOLUTE/PATH/TO/weather-mcp/dist/index.js"
      ]
    }
  }
}
```

Replace `/ABSOLUTE/PATH/TO/weather-mcp` with your real project path (e.g. run `pwd` from the repo root). Keep `TRANSPORT=stdio` (or unset) in `.env`.

### Alternative: env inline

```json
{
  "mcpServers": {
    "weather": {
      "command": "node",
      "args": [
        "/ABSOLUTE/PATH/TO/weather-mcp/dist/index.js"
      ],
      "env": {
        "OPEN_WEATHER_MAP_API_KEY": "your_key_here",
        "TRANSPORT": "stdio"
      }
    }
  }
}
```

Prefer `.env` + `--env-file` so the key stays out of `mcp.json`.

1. Save, then toggle the server off/on in **Settings → MCP** (or restart Cursor).
2. Confirm the server shows as connected and lists `get_current_weather` and `get_forecast`.

### After code changes

```bash
pnpm run build
```

Then reload the MCP server in Cursor.

## Streamable HTTP (local)

HTTP mode serves a landing page at `GET /`, MCP at `POST/GET /mcp` (configurable), plus `GET /health`. Streamable HTTP is configured via the official SDK’s `createMcpHandler` + `toNodeHandler`. The build copies `src/index.html` into `dist/`.

```bash
pnpm run build
TRANSPORT=http PORT=3000 pnpm run start
# or
pnpm run start:http
```

You should see something like:

```text
Weather MCP Server running on http://0.0.0.0:3000/mcp (Streamable HTTP)
```

## Deploy on Render

1. Create a **Web Service** from this repo (root of the project).
2. Build: `pnpm install && pnpm run build` (or `npm` equivalent).
3. Start: `node dist/index.js` (or `pnpm run start`).
4. Env vars:
   - `TRANSPORT=http`
   - `OPEN_WEATHER_MAP_API_KEY=...`
   - `PORT` is set by Render automatically
5. MCP URL: `https://<your-service>.onrender.com/mcp`  
   This deployment: `https://weather-mcp-ts.onrender.com/mcp`

> The HTTP endpoint is **unauthenticated**. Anyone with the URL can call the tools. Add auth before sharing widely.

## Manual smoke check (OpenWeatherMap)

With `.env` set:

```bash
node --env-file=.env -e "
import { getApiKey, buildCurrentWeatherUrl, makeOWMRequest, formatCurrentWeather } from './dist/utils.js';
const apiKey = getApiKey();
const data = await makeOWMRequest(buildCurrentWeatherUrl({ apiKey, city: 'Yaounde,CM', units: 'metric' }));
console.log(data ? formatCurrentWeather(data, 'metric') : 'failed');
"
```

Remote health:

```bash
curl -s https://weather-mcp-ts.onrender.com/health
```

## Repo layout

```text
weather-mcp/
├── README.md
├── LICENSE
├── package.json
├── tsconfig.json
├── .env.example
└── src/
    ├── index.html    # landing page (copied to dist on build)
    ├── index.ts      # stdio + Streamable HTTP entry
    ├── server.ts     # tool registration
    ├── types.ts
    └── utils.ts
```

## Notes

- Never commit `.env` (it is gitignored).
- Stdio servers must not write to stdout except MCP JSON-RPC; logs go to stderr (`console.error`).
- Free OpenWeatherMap plans cover current weather and the 5-day / 3-hour forecast used here.

## License

[ISC](./LICENSE) © 2026 RashJrEdmund

Maintenance

ActivityMaintained
ResponsivenessNo issues