Skip to main content
Glama
narendrareddi

MCP Weather Agent

MCP Weather Agent

An MCP (Model Context Protocol) server that turns a public REST API into tools an AI agent can call directly — geocode a place name, then pull current conditions or a multi-day forecast, with typed inputs and typed, structured outputs instead of free text.

This is a small, self-contained example of the same pattern used to build production agent-tool servers for enterprise systems: typed tool schemas, input validation, retry/timeout handling on outbound calls, and structured logging, so an agent's tool calls are predictable and debuggable.

Why this exists

Most "AI agent" demos either hardcode a single API call or let the model free-form parse HTML. Neither scales past a toy example. This project shows the pattern that does: each capability is a small, independently testable tool with a strict input/output contract, and the server itself knows nothing about how an agent decides to call it — that separation is what lets the same server work behind Claude Desktop, Claude Code, or a custom LangGraph agent without changes.

Related MCP server: mcp-poc

Architecture

Agent (Claude Desktop / Claude Code / LangGraph, etc.)
        │  MCP protocol (stdio transport)
        ▼
FastMCP server (server.py)
   ├─ geocode_location(location_name)      → GeocodeResponse
   ├─ get_current_weather(lat, lon)        → CurrentWeather
   └─ get_forecast(lat, lon, days)         → ForecastResponse
        │  validated params → httpx call w/ retry+timeout
        ▼
Open-Meteo REST API (geocoding + forecast, no API key required)

Each tool's return value is a Pydantic model, not a string — so a calling agent (or a downstream function in a larger pipeline) can read result.temperature_c directly instead of re-parsing prose.

Design decisions & trade-offs

  • Open-Meteo over a keyed provider: no API key means anyone cloning this repo can run it in under a minute. A production system would swap in whatever provider the business already pays for.

  • Structured Pydantic outputs over raw JSON passthrough: costs a bit of mapping code per tool, but means malformed upstream responses fail loudly at the boundary instead of silently confusing the agent three steps later.

  • Bounded retries in _get_json, not a retry library: for a 3-tool demo a dependency like tenacity is unnecessary weight; the same slot is where you'd add exponential backoff or circuit-breaking for a heavier-traffic service.

  • stdio transport by default: simplest to run locally via Claude Desktop/Claude Code. Swapping to Streamable HTTP (see mcp.server.fastmcp docs) is a one-line change to mcp.run(transport=...) when you need a server other machines can call.

Running it

python -m venv .venv
source .venv/bin/activate          # .venv\Scripts\activate on Windows
pip install -e ".[dev]"

pytest                              # run the offline unit test suite
python -m mcp_weather_agent.server  # run the server over stdio

Connecting it to Claude Desktop or Claude Code

Add to your MCP config (see examples/claude_desktop_config.json):

{
  "mcpServers": {
    "weather-agent": {
      "command": "python",
      "args": ["-m", "mcp_weather_agent.server"],
      "cwd": "/absolute/path/to/mcp-weather-agent"
    }
  }
}

Restart the client, and the three tools (geocode_location, get_current_weather, get_forecast) become available for the agent to call.

Tools

Tool

Input

Output

geocode_location

location_name: str, max_results: int

Ranked list of name/country/lat/lon candidates

get_current_weather

latitude: float, longitude: float

Current temperature, apparent temp, wind, precipitation

get_forecast

latitude: float, longitude: float, days: int

Daily high/low/precipitation for up to 16 days

Testing

tests/test_server.py monkeypatches the HTTP layer so the suite runs fully offline and fast — useful for CI, and for making sure tool-shape regressions (a renamed field, a missing key) get caught before an agent ever sees them.

Possible extensions

  • Swap stdio for Streamable HTTP transport and deploy behind auth for multi-client access.

  • Add a severe_weather_alerts tool against a provider that supports it.

  • Add response caching (short TTL) to cut duplicate calls when an agent re-checks the same location across a multi-step plan.

License

MIT — see LICENSE.

Available Tools

3 tools
geocode_locationA

Resolve a place name (city, landmark, region) into candidate coordinates.

Args: location_name: Free-text place name, e.g. "Charlotte, NC" or "Kyoto". max_results: Maximum number of candidate matches to return (1-10).

ParametersJSON Schema
NameRequiredDescriptionDefault
max_resultsNo
location_nameYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
queryYes
resultsYes
match_countYes

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It discloses that the tool returns candidate coordinates rather than a single definitive result, which is a meaningful trait. However, it does not mention potential failure modes, ambiguity resolution, or service-side behavior such as rate limits or geographic coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and well structured: a one-sentence purpose statement followed by a minimal Args section. Every sentence adds value, and there is no redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter geocoding lookup with an output schema present, the description is nearly complete: it defines the purpose and all parameters. The only notable omissions are explicit usage guidance and edge-case behavior, but these are minor given the tool's simplicity and the existing output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides no per-parameter descriptions (0% coverage), so the description is the only source of parameter meaning. It fully compensates by defining location_name as a free-text place name with concrete examples ('Charlotte, NC' or 'Kyoto') and max_results with a clear 1-10 range and its role in limiting candidate matches.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Resolve a place name ... into candidate coordinates.' This clearly identifies the tool as a geocoder and distinguishes it from the weather-focused sibling tools, get_current_weather and get_forecast.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is implied rather than stated: an agent can infer this tool is for turning free-text place names into coordinate candidates. However, the description gives no explicit when-to-use instructions, exclusions, or alternatives, even though the sibling tools make the distinction fairly obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_current_weatherA

Get current weather conditions for a coordinate pair.

Args: latitude: Latitude in decimal degrees (-90 to 90). longitude: Longitude in decimal degrees (-180 to 180).

ParametersJSON Schema
NameRequiredDescriptionDefault
latitudeYes
longitudeYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
latitudeYes
timezoneYes
longitudeYes
observed_atYes
weather_codeYes
temperature_cYes
wind_speed_kmhYes
precipitation_mmYes
apparent_temperature_cYes

TDQS

A3.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure, but it only restates the basic operation and input ranges. It does not mention data sources, freshness, units, errors, or any side effects, so an agent gets little behavioral context beyond the tool name.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very compact and front-loaded with the tool's purpose, followed by concise parameter details that add genuine value. There is no filler or redundant explanation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter tool with an output schema, the parameter details are sufficient for correct invocation. The main gap is the absence of explicit guidance on when to choose this over sibling tools, though 'current' makes the intended context reasonably clear.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides only bare type and title information, but the description adds meaningful semantics: latitude and longitude in decimal degrees with valid ranges. This fully compensates for the 0% schema description coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves current weather conditions for a coordinate pair, using a specific verb and resource. 'Current' differentiates it from the get_forecast sibling and 'coordinate pair' differentiates it from geocoding.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use it: when current weather conditions at a latitude/longitude coordinate pair are needed. However, it does not explicitly mention alternatives like get_forecast for future conditions or geocode_location for converting addresses to coordinates.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_forecastA

Get a daily forecast for a coordinate pair.

Args: latitude: Latitude in decimal degrees (-90 to 90). longitude: Longitude in decimal degrees (-180 to 180). days: Number of forecast days to return (1-16). unit_system: Reserved for future unit support; only "metric" today.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNo
latitudeYes
longitudeYes
unit_systemNometric

Output Schema

ParametersJSON Schema
NameRequiredDescription
daysYes
latitudeYes
timezoneYes
longitudeYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the behavioral disclosure burden. It does convey the read-only nature through the verb 'Get' and notes that unit_system is reserved with only 'metric' available, but it does not disclose error behavior, data source, or output semantics beyond what the output schema already supplies.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short, front-loaded with the purpose, and uses a clean Args list. Every sentence adds value; the parameter details are directly relevant and not redundant with the schema's type/const metadata.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core operation and all parameter semantics, and the output schema handles return-value details. The main gap is the absence of explicit guidance on when to choose this tool over get_current_weather, though 'daily forecast' strongly implies the distinction.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description fully compensates by explaining every parameter: latitude/longitude in decimal degrees with ranges, days with a 1-16 bound, and unit_system's reserved status. This adds meaningful information not available from the schema's titles and defaults.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description is specific: 'Get a daily forecast for a coordinate pair' names a clear verb, resource, and target. It distinguishes from geocode_location and get_current_weather implicitly through 'daily forecast', but does not explicitly call out the sibling relationship.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the phrase 'daily forecast' rather than explicitly stated. The description does not name alternatives or provide when-to-use vs. when-not-to-use guidance relative to get_current_weather or geocode_location.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 3 tool updatesv0.1.0
    • First observedgeocode_location
    • First observedget_current_weather
    • First observedget_forecast

TDQS

A4.2/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: geocoding a place name, retrieving current conditions, and retrieving a forecast. There is no meaningful overlap between geocode_location and the weather retrieval tools, and current vs. forecast are well differentiated by their descriptions.

Naming Consistency5/5

All tool names use lowercase snake_case with a verb_noun style: geocode_location, get_current_weather, get_forecast. The two retrieval tools follow a uniform get_* pattern, and geocode_location fits the same verb-first convention.

Tool Count5/5

Three tools is an appropriate, well-scoped size for a weather agent. Each tool covers a necessary step in the core workflow: resolve location, get current conditions, get forecast, with no redundancy.

Completeness4/5

The core weather lookup workflow is complete: geocode a place, then retrieve current or forecast weather. Minor gaps such as lack of alerts, historical data, or reverse geocoding are not essential for the stated purpose.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers