Skip to main content
Glama
README.md
# mcp-weather-ts

TypeScript [MCP](https://modelcontextprotocol.io/docs/2026-07-28/learn/) server that exposes US weather from the [National Weather Service API](https://www.weather.gov/documentation/services-web-api) to hosts such as Cursor.

The host starts `node build/index.js` and talks JSON-RPC over **stdio**. The model never calls NWS itself; it calls this server’s tools (and can read a resource or use a prompt).

How MCP works (tools, resources, prompts, transport): [docs/create-mcp.readme.md](docs/create-mcp.readme.md).

---

## Requirements

- Node.js 22+ (this repo uses ESM and `fetch`)
- npm
- Network access to `https://api.weather.gov` (US locations only)

---

## Setup

```bash
npm install
npm run build
```

`tsc` writes JavaScript to `build/`. Cursor must run the **built** file, not `src/index.ts`.

### Scripts

| Command | What it does |
| --- | --- |
| `npm run build` | Compile `src/` → `build/` |
| `npm test` | Smoke-test NWS: `/points` then forecast + hourly URLs |

---

## Mount in Cursor

1. Build (`npm run build`).
2. Add `.cursor/mcp.json` in this project:

```json
{
  "mcpServers": {
    "weather": {
      "type": "stdio",
      "command": "node",
      "args": ["${workspaceFolder}/build/index.js"]
    }
  }
}
```

For all Cursor projects, use `%USERPROFILE%\.cursor\mcp.json` and a full path to `build\index.js` instead of `${workspaceFolder}`.

3. Open **Customize → MCP** (or Cursor Settings → MCP) and enable **weather**.
4. After you change `src/`, run `npm run build` again and toggle the server off/on so Cursor restarts the process.

Do not `console.log` after the server connects: stdout is the MCP wire. Use `console.error` for logs.

---

## What you can call

### Tools

The model (or you, by asking in Agent chat) invokes these with `tools/call`.

| Name | Inputs | What it does |
| --- | --- | --- |
| `get_alerts` | `state` — 2-letter US code (`CA`, `NY`) | Active alerts for that state |
| `get_forecast` | `latitude`, `longitude` | 12-hour forecast (NWS `/points` then `properties.forecast`) |
| `test_tool` | `name` | Practice: `Hello, {name}!` |

Example chat:

- “Any weather alerts for CA?”
- “Forecast for 39.7456, -97.0892”

Example arguments:

```json
{ "state": "CA" }
```

```json
{ "latitude": 39.7456, "longitude": -97.0892 }
```

### Resource

| Name | URI | What it does |
| --- | --- | --- |
| `nws_guide` | `weather://nws-guide` | Short static note on tools and the NWS lookup flow |

Ask the agent to read `weather://nws-guide`, or use `resources/read` in a client.

### Prompt

| Name | Args | What it does |
| --- | --- | --- |
| `check_weather` | `place` — e.g. `Boston MA` or `CA` | User-message template that tells the model to use `get_forecast` / `get_alerts` |

In Cursor, pick the **Check weather** prompt and fill `place`.

---

## Project layout

```
src/index.ts              Create McpServer, register, connect stdio
src/tools.ts              get_alerts, get_forecast, test_tool
src/resources.ts          weather://nws-guide
src/prompts.ts            check_weather
src/weather-api-call.ts   NWS fetch + types + alert formatting
src/createTransport.ts    StdioServerTransport + connect
tests/weather-api-call.test.ts
docs/create-mcp.readme.md How to design MCP servers
```

Startup order in `src/index.ts`:

1. `new McpServer({ name: "weather", version: "1.0.0" })`
2. `registerWeatherTools` / `registerWeatherResources` / `registerWeatherPrompts`
3. `connectStdioTransport(server)`

---

## NWS notes

- Forecasts are **not** at `/points/{lat},{lon}/forecast`. Load `/points/{lat},{lon}` (four decimal places), then follow `properties.forecast` or `properties.forecastHourly`.
- NWS requires a `User-Agent` header (set in `weather-api-call.ts`).
- Coverage is US (and some territories). Other coordinates often fail.

---

## Troubleshooting

| Symptom | What to try |
| --- | --- |
| Server red / no tools | Rebuild, confirm `build/index.js` exists, toggle MCP |
| Handshake fails | Make sure you `connect` stdio and do not log to stdout |
| Empty or failed forecast | US lat/lon only; check MCP Logs |
| `npm test` fails | Network / NWS outage |

Cursor: **Output → MCP Logs**.

---

## License

ISC

TDQS

C2.4/5.0

Scored across 3 tools

Disambiguation4/5

get_alerts and get_forecast are clearly distinct in purpose, but test_tool is ambiguous and could be mistaken for a generic utility, though it doesn't overlap with the weather tools. An agent can easily differentiate the two weather tools, and test_tool is separate enough to avoid confusion.

Naming Consistency3/5

Two tools follow a consistent 'get_<noun>' pattern (get_alerts, get_forecast), but test_tool breaks this convention with a different verb and structure. The naming is still readable, but the inconsistency is noticeable given only three tools.

Tool Count3/5

Three tools is borderline for a weather server, which typically needs more operations like current conditions or location search. The presence of test_tool, which does not serve a core weather purpose, makes the count feel less purposeful and slightly thin.

Completeness2/5

The server covers alerts and forecasts but lacks fundamental weather operations like current conditions or historical data. The test_tool is irrelevant to the domain, leaving notable gaps that would require agents to work around missing functionality.

Maintenance

ActivityMaintained
ResponsivenessNo issues