Skip to content

Commit 7619049

Browse files
committed
feat: add analysis guide to MCP server + early .env loading
- MCP: expose get_analysis_guide tool (33 topics: data ops, statistics, climate indices, visualization, maritime) with enum validation - web/app.py: load_dotenv() at startup so /api/keys-status sees .env keys immediately (fixes API key panel appearing unnecessarily)
1 parent 232258c commit 7619049

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

src/eurus/server.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
)
5959
from eurus.memory import get_memory
6060
from eurus.tools.era5 import retrieve_era5_data, ERA5RetrievalArgs
61+
from eurus.tools.analysis_guide import get_analysis_guide, ANALYSIS_GUIDES
6162

6263
# Import Maritime Routing tool
6364
from eurus.tools.routing import (
@@ -120,6 +121,39 @@ async def list_tools() -> list[Tool]:
120121
"additionalProperties": False
121122
}
122123
),
124+
Tool(
125+
name="get_analysis_guide",
126+
description=(
127+
"Get methodological guidance for climate data analysis and visualization.\n\n"
128+
"Returns workflow steps, quality checklists, common pitfalls, and best practices.\n\n"
129+
"TOPICS:\n"
130+
"- Data: load_data, spatial_subset, temporal_subset\n"
131+
"- Statistics: anomalies, zscore, trend_analysis, eof_analysis\n"
132+
"- Advanced: correlation_analysis, composite_analysis, diurnal_cycle, "
133+
"seasonal_decomposition, spectral_analysis, spatial_statistics, "
134+
"multi_variable, climatology_normals\n"
135+
"- Climate: climate_indices, extremes, drought_analysis, heatwave_detection, "
136+
"atmospheric_rivers, blocking_events\n"
137+
"- Domain: energy_budget, wind_energy, moisture_budget, convective_potential, snow_cover\n"
138+
"- Visualization: visualization_spatial, visualization_timeseries, "
139+
"visualization_anomaly_map, visualization_wind, visualization_comparison, "
140+
"visualization_profile, visualization_distribution, visualization_animation, "
141+
"visualization_dashboard, visualization_contour, visualization_correlation_map\n"
142+
"- Maritime: maritime_route, maritime_visualization\n\n"
143+
"CALL THIS BEFORE writing analysis/plotting code!"
144+
),
145+
inputSchema={
146+
"type": "object",
147+
"properties": {
148+
"topic": {
149+
"type": "string",
150+
"description": "Analysis topic to get guidance for",
151+
"enum": sorted(ANALYSIS_GUIDES.keys())
152+
}
153+
},
154+
"required": ["topic"]
155+
}
156+
),
123157
]
124158

125159
# ========== MARITIME ROUTING TOOL (if dependencies available) ==========
@@ -137,7 +171,7 @@ async def list_tools() -> list[Tool]:
137171
"WORKFLOW:\n"
138172
"1. Call this tool → get waypoints + instructions\n"
139173
"2. Download ERA5 wind data (u10, v10) for the region\n"
140-
"3. Call get_visualization_guide(viz_type='maritime_risk_assessment')\n"
174+
"3. Call get_analysis_guide(topic='maritime_visualization')\n"
141175
"4. Execute analysis in python_repl"
142176
),
143177
inputSchema=RouteArgs.model_json_schema()
@@ -181,6 +215,10 @@ async def call_tool(name: str, arguments: dict[str, Any]) -> CallToolResult:
181215
result = memory.list_datasets()
182216
return CallToolResult(content=[TextContent(type="text", text=result)])
183217

218+
elif name == "get_analysis_guide":
219+
result = get_analysis_guide(arguments["topic"])
220+
return CallToolResult(content=[TextContent(type="text", text=result)])
221+
184222
# ========== MARITIME ROUTING HANDLER ==========
185223
elif name == "calculate_maritime_route":
186224
if not HAS_ROUTING_DEPS:

web/app.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
from pathlib import Path
1111
from contextlib import asynccontextmanager
1212

13+
from dotenv import load_dotenv
14+
load_dotenv() # Load .env EARLY so /api/keys-status sees the keys
15+
1316
from fastapi import FastAPI
1417
from fastapi.staticfiles import StaticFiles
1518
from fastapi.templating import Jinja2Templates

0 commit comments

Comments
 (0)