Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ under their entry.
## Unreleased

### Added
- `analyze_dataset`: deterministic one-shot orchestrator that runs the
full first-look pipeline (inspect_mesh → validate_dataset →
inspect_variable → calculate_area → calculate_zonal_mean → plot_mesh →
plot_variable) and returns a single structured result with
`recommended_next_steps`. Accepts direct paths or
`session_id` + `dataset_handle`. Forwards `use_remote`/`endpoint` to
every underlying stage. (#32)
- `recommended_next_steps` field on result-bearing tools to guide
agent chaining: `calculate_zonal_mean`, `validate_dataset` (branched
on pass/fail), `subset_bbox`, `subset_polygon`,
`extract_cross_section`. (#30)
- `uxarray-mcp` CLI entry point with subcommands: `serve`, `setup`,
`endpoints add/list/remove`, `doctor`, `install-claude`.
- Multi-endpoint config schema (`hpc.endpoints.<name>` with
Expand Down
4 changes: 4 additions & 0 deletions src/uxarray_mcp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from fastmcp import FastMCP

from uxarray_mcp.tools import (
analyze_dataset,
calculate_anomaly,
calculate_area_hpc,
calculate_bias,
Expand Down Expand Up @@ -58,6 +59,9 @@
# Tool discovery — always call this first with a new dataset
mcp.tool()(get_capabilities)

# Deterministic one-shot analysis — full first-look pipeline in a single call
mcp.tool()(analyze_dataset)

# Autonomous scientific agent — Analyze → Plan → Execute → Verify
mcp.tool()(run_scientific_agent)
mcp.tool()(run_workflow)
Expand Down
2 changes: 2 additions & 0 deletions src/uxarray_mcp/tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
inspect_variable,
validate_dataset,
)
from .orchestration import analyze_dataset
from .plotting import plot_mesh, plot_variable, plot_zonal_mean
from .remote_tools import (
calculate_area_hpc,
Expand Down Expand Up @@ -62,6 +63,7 @@
__all__ = [
"get_capabilities",
"list_datasets",
"analyze_dataset",
"run_scientific_agent",
"run_workflow",
"resume_workflow",
Expand Down
30 changes: 30 additions & 0 deletions src/uxarray_mcp/tools/advanced.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,16 @@ def subset_bbox(
"variable_summary": variable_summary,
"result_handle": result_handle,
}
next_steps = [
f'plot_mesh(grid_path="{resolved_grid}")',
f'export_to_netcdf("<output.nc>", result_handle="{result_handle}")',
]
if resolved_data is not None:
next_steps.insert(
0,
f'plot_variable("{resolved_grid}", "{resolved_data}", "<variable_name>")',
)
result["recommended_next_steps"] = next_steps
tracker.succeed("Bounding-box subset complete.")
result = attach_provenance(
result,
Expand Down Expand Up @@ -293,6 +303,16 @@ def subset_polygon(
"variable_summary": variable_summary,
"result_handle": result_handle,
}
next_steps = [
f'plot_mesh(grid_path="{resolved_grid}")',
f'export_to_netcdf("<output.nc>", result_handle="{result_handle}")',
]
if resolved_data is not None:
next_steps.insert(
0,
f'plot_variable("{resolved_grid}", "{resolved_data}", "<variable_name>")',
)
result["recommended_next_steps"] = next_steps
result = attach_provenance(
result,
tool="subset_polygon",
Expand Down Expand Up @@ -379,6 +399,16 @@ def extract_cross_section(
"variable_summary": variable_summary,
"result_handle": result_handle,
}
next_steps = [
f'plot_mesh(grid_path="{resolved_grid}")',
f'export_to_netcdf("<output.nc>", result_handle="{result_handle}")',
]
if resolved_data is not None:
next_steps.insert(
0,
f'calculate_zonal_mean("{resolved_grid}", "{resolved_data}", "<variable_name>")',
)
result["recommended_next_steps"] = next_steps
result = attach_provenance(
result,
tool="extract_cross_section",
Expand Down
19 changes: 19 additions & 0 deletions src/uxarray_mcp/tools/inspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,12 @@ def calculate_zonal_mean(
except Exception as e:
raise RuntimeError(f"Failed to compute zonal mean: {str(e)}")

result["recommended_next_steps"] = [
f'plot_zonal_mean("{grid_path}", "{data_path}", "{variable_name}")',
f'plot_variable("{grid_path}", "{data_path}", "{variable_name}")',
f'extract_cross_section(latitude=0.0, grid_path="{grid_path}", '
f'data_path="{data_path}", variable_name="{variable_name}")',
]
return attach_provenance(
result,
tool="calculate_zonal_mean",
Expand Down Expand Up @@ -530,6 +536,19 @@ def validate_dataset(grid_path: str, data_path: str) -> Dict[str, Any]:
"issues": issues,
}

if overall_passed:
result["recommended_next_steps"] = [
f'inspect_variable("{grid_path}", "{data_path}")',
f'calculate_zonal_mean("{grid_path}", "{data_path}", "<variable_name>")',
f'plot_variable("{grid_path}", "{data_path}", "<variable_name>")',
]
else:
result["recommended_next_steps"] = [
"Validation failed; review the per-variable warnings above before "
"running analysis.",
"Drop or repair affected variables, or rerun with a corrected data file.",
]

return attach_provenance(
result,
tool="validate_dataset",
Expand Down
Loading
Loading