get_area_average
Retrieve daily tree, grass, and weed pollen aggregates over a radius to compare pollen levels and trends over the forecast period.
Instructions
Get tree, grass, and weed pollen aggregates over a radius around a point.
Use this for higher-level questions like "is tree or grass pollen worse this week?" or "is pollen rising over the next few days in Stockholm?". Returns one entry per day with overall_risk and per-category aggregates (tree_tot, grass_tot, weed_tot).
radius_km (default 25) controls the area. forecast_days (default 7) sets the horizon.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | ||
| lon | Yes | ||
| radius_km | No | ||
| forecast_days | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- atmospore_mcp/server.py:190-221 (handler)The handler function for the get_area_average tool. Calls client.pollen_area with lat, lon, radius_km, forecast_days, and species filters (tree_tot, grass_tot, weed_tot). Returns per-day data with overall_risk and per-category aggregates.
@mcp.tool(description=GET_AREA_AVERAGE_DESCRIPTION) async def get_area_average( lat: float, lon: float, radius_km: float = 25, forecast_days: int = 7, ) -> dict[str, Any]: async def call() -> Any: days = await client.pollen_area( lat=lat, lon=lon, radius_km=radius_km, forecast_days=forecast_days, species=["tree_tot", "grass_tot", "weed_tot"], ) return [ { "date": d.date, "overall_risk": d.overall_risk, "categories": { cat: { "value": lvl.value, "units": lvl.units, "risk_level": lvl.risk_level, } for cat, lvl in d.pollen_levels.items() }, } for d in days ] return await _safe_call(call()) - atmospore_mcp/server.py:49-55 (schema)Description/schema for the get_area_average tool, documenting its purpose, return shape, and default parameter values.
GET_AREA_AVERAGE_DESCRIPTION = """Get tree, grass, and weed pollen aggregates over a radius around a point. Use this for higher-level questions like "is tree or grass pollen worse this week?" or "is pollen rising over the next few days in Stockholm?". Returns one entry per day with overall_risk and per-category aggregates (tree_tot, grass_tot, weed_tot). `radius_km` (default 25) controls the area. `forecast_days` (default 7) sets the horizon.""" - atmospore_mcp/server.py:190-191 (registration)Registration of get_area_average as an MCP tool via the @mcp.tool decorator, with the description from GET_AREA_AVERAGE_DESCRIPTION.
@mcp.tool(description=GET_AREA_AVERAGE_DESCRIPTION) async def get_area_average( - atmospore_mcp/server.py:117-147 (helper)The _safe_call helper used by get_area_average (and all tools) to wrap client calls and normalize errors (authentication, quota, API, unexpected) into a structured dict for the LLM.
async def _safe_call(coro) -> dict[str, Any]: """Wrap a client call so structured errors reach the LLM cleanly.""" try: return {"ok": True, "data": await coro} except AuthenticationError as e: return { "ok": False, "error": "authentication_failed", "message": str(e), "hint": "Check ATMOSPORE_API_KEY. Get a free key at https://atmospore.com/account.", } except RateLimitError as e: return { "ok": False, "error": "quota_exceeded", "message": str(e), "limit": e.limit, "used": e.used, "resets_at": e.resets_at, "hint": "Daily quota hit. Upgrade at https://atmospore.com/plans for higher limits.", } except APIError as e: return { "ok": False, "error": "api_error", "status": e.status, "message": str(e), } except Exception as e: # noqa: BLE001 — surface unknown errors to LLM logger.exception("Unexpected error in MCP tool") return {"ok": False, "error": "unexpected_error", "message": str(e)}