uxarray-mcp 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
uxarray_mcp/server.py ADDED
@@ -0,0 +1,230 @@
1
+ """UXarray MCP Server - Provides mesh analysis tools for AI agents.
2
+
3
+ The MCP-registered tool names are kept short and stable. Tools that can run
4
+ on either the local machine or a configured Globus Compute endpoint expose a
5
+ ``use_remote`` flag — there is a single canonical name per tool (no
6
+ ``*_hpc`` suffix). The dispatcher falls back to local execution
7
+ automatically when no endpoint is configured.
8
+ """
9
+
10
+ from fastmcp import FastMCP
11
+
12
+ from uxarray_mcp.tools import (
13
+ analyze_dataset,
14
+ calculate_anomaly,
15
+ calculate_area,
16
+ calculate_azimuthal_mean,
17
+ calculate_bias,
18
+ calculate_curl,
19
+ calculate_divergence,
20
+ calculate_ensemble_mean,
21
+ calculate_ensemble_spread,
22
+ calculate_gradient,
23
+ calculate_pattern_correlation,
24
+ calculate_rmse,
25
+ calculate_temporal_mean,
26
+ calculate_zonal_mean,
27
+ compare_fields,
28
+ create_session,
29
+ endpoint_status,
30
+ export_to_csv,
31
+ export_to_netcdf,
32
+ extract_cross_section,
33
+ get_capabilities,
34
+ get_execution_mode,
35
+ get_operation_status,
36
+ get_result_handle,
37
+ get_session_state,
38
+ get_workflow_status,
39
+ inspect_mesh,
40
+ inspect_variable,
41
+ list_datasets,
42
+ list_operations,
43
+ plot_mesh,
44
+ plot_mesh_geo,
45
+ plot_variable,
46
+ plot_zonal_mean,
47
+ probe_path_access,
48
+ register_dataset,
49
+ regrid_dataset,
50
+ remap_variable,
51
+ reset_session_state,
52
+ resume_workflow,
53
+ run_scientific_agent,
54
+ run_workflow,
55
+ set_execution_mode,
56
+ subset_bbox,
57
+ subset_polygon,
58
+ validate_dataset,
59
+ validate_hpc_setup,
60
+ write_result,
61
+ )
62
+
63
+ # Initialize the MCP server
64
+ mcp = FastMCP("uxarray-mcp-server")
65
+
66
+ # Tool discovery — always call this first with a new dataset
67
+ mcp.tool()(get_capabilities)
68
+
69
+ # Deterministic one-shot analysis — full first-look pipeline in a single call
70
+ mcp.tool()(analyze_dataset)
71
+
72
+ # Autonomous scientific agent — Analyze → Plan → Execute → Verify
73
+ mcp.tool()(run_scientific_agent)
74
+ mcp.tool()(run_workflow)
75
+ mcp.tool()(resume_workflow)
76
+ mcp.tool()(get_workflow_status)
77
+ mcp.tool()(create_session)
78
+ mcp.tool()(register_dataset)
79
+ mcp.tool()(get_session_state)
80
+ mcp.tool()(reset_session_state)
81
+ mcp.tool()(get_result_handle)
82
+ mcp.tool()(get_operation_status)
83
+ mcp.tool()(list_operations)
84
+
85
+ # Core inspection + computation tools. Each accepts ``use_remote`` /
86
+ # ``endpoint`` and falls back to local execution when no endpoint is configured.
87
+ mcp.tool()(inspect_mesh)
88
+ mcp.tool()(inspect_variable)
89
+ mcp.tool()(calculate_area)
90
+ mcp.tool()(calculate_zonal_mean)
91
+ mcp.tool()(validate_dataset)
92
+ mcp.tool()(list_datasets)
93
+
94
+ # Visualization tools — same dispatcher pattern.
95
+ mcp.tool()(plot_mesh)
96
+ mcp.tool()(plot_mesh_geo)
97
+ mcp.tool()(plot_variable)
98
+ mcp.tool()(plot_zonal_mean)
99
+
100
+ # Vector calculus — gradient, curl (vorticity), divergence, azimuthal mean
101
+ mcp.tool()(calculate_gradient)
102
+ mcp.tool()(calculate_curl)
103
+ mcp.tool()(calculate_divergence)
104
+ mcp.tool()(calculate_azimuthal_mean)
105
+
106
+ # Analysis extensions
107
+ mcp.tool()(subset_bbox)
108
+ mcp.tool()(subset_polygon)
109
+ mcp.tool()(extract_cross_section)
110
+ mcp.tool()(compare_fields)
111
+ mcp.tool()(calculate_bias)
112
+ mcp.tool()(calculate_rmse)
113
+ mcp.tool()(calculate_pattern_correlation)
114
+ mcp.tool()(remap_variable)
115
+ mcp.tool()(regrid_dataset)
116
+ mcp.tool()(calculate_temporal_mean)
117
+ mcp.tool()(calculate_anomaly)
118
+ mcp.tool()(calculate_ensemble_mean)
119
+ mcp.tool()(calculate_ensemble_spread)
120
+ mcp.tool()(export_to_netcdf)
121
+ mcp.tool()(export_to_csv)
122
+ mcp.tool()(write_result)
123
+
124
+ # Execution mode + diagnostics
125
+ mcp.tool()(get_execution_mode)
126
+ mcp.tool()(endpoint_status)
127
+ mcp.tool()(probe_path_access)
128
+ mcp.tool()(set_execution_mode)
129
+ mcp.tool()(validate_hpc_setup)
130
+
131
+ # ---------------------------------------------------------------------------
132
+ # MCP Prompts — user-invokable slash commands that guide common workflows.
133
+ # Each prompt returns a structured message the client injects into the
134
+ # conversation; the AI then calls the appropriate tools.
135
+ # ---------------------------------------------------------------------------
136
+
137
+
138
+ @mcp.prompt()
139
+ def first_look(path: str) -> str:
140
+ """Run the full first-look analysis pipeline on a mesh or dataset.
141
+
142
+ Pass a local file path (or HEALPix spec like healpix:4). The assistant
143
+ will call get_capabilities, then analyze_dataset to inspect topology,
144
+ validate data quality, compute area statistics, zonal mean, and produce
145
+ mesh and variable plots — all in one shot.
146
+
147
+ Parameters
148
+ ----------
149
+ path : str
150
+ Path to the mesh or data file, e.g. /data/grid.nc or healpix:4.
151
+ """
152
+ return (
153
+ f"Run a complete first-look analysis on `{path}`.\n\n"
154
+ "Steps:\n"
155
+ '1. Call `get_capabilities` with `grid_path="{path}"` to discover '
156
+ "what tools apply.\n"
157
+ '2. Call `analyze_dataset` with `file_path="{path}"` to run the full '
158
+ "pipeline: inspect_mesh → validate_dataset → inspect_variable → "
159
+ "calculate_area → calculate_zonal_mean → plot_mesh → plot_variable.\n"
160
+ "3. Summarise the mesh topology, any data quality issues, and the "
161
+ "zonal mean profile. Show the plots inline.\n"
162
+ "4. List the recommended next steps from the result."
163
+ ).format(path=path)
164
+
165
+
166
+ @mcp.prompt()
167
+ def vorticity_analysis(grid_path: str, data_path: str, u_var: str, v_var: str) -> str:
168
+ """Compute and interpret relative vorticity and wind divergence.
169
+
170
+ Runs calculate_curl (vorticity ζ = ∂v/∂x − ∂u/∂y) and
171
+ calculate_divergence (∂u/∂x + ∂v/∂y) on the provided wind components,
172
+ then asks the assistant to interpret the atmospheric dynamics.
173
+
174
+ Parameters
175
+ ----------
176
+ grid_path : str
177
+ Path to the mesh grid file.
178
+ data_path : str
179
+ Path to the data file containing wind components.
180
+ u_var : str
181
+ Zonal wind variable name (e.g. uReconstructZonal).
182
+ v_var : str
183
+ Meridional wind variable name (e.g. uReconstructMeridional).
184
+ """
185
+ return (
186
+ f"Analyse the vorticity and divergence of the wind field in `{data_path}`.\n\n"
187
+ f'1. Call `calculate_curl` with grid_path="{grid_path}", '
188
+ f'data_path="{data_path}", u_variable="{u_var}", v_variable="{v_var}".\n'
189
+ f"2. Call `calculate_divergence` with the same arguments.\n"
190
+ "3. Interpret the results:\n"
191
+ " - Where is vorticity largest/smallest? What does that indicate "
192
+ "(cyclonic vs anticyclonic flow)?\n"
193
+ " - Where is divergence strongly negative (convergence)? That "
194
+ "indicates rising motion and potential convection.\n"
195
+ " - Report the global min/max/mean/std for both fields.\n"
196
+ "4. Suggest follow-up analysis (e.g. subset_bbox over regions of "
197
+ "extreme vorticity, plot_variable of a derived field)."
198
+ )
199
+
200
+
201
+ @mcp.prompt()
202
+ def hpc_diagnose(endpoint: str = "") -> str:
203
+ """Diagnose the HPC endpoint connection and configuration.
204
+
205
+ Runs endpoint_status, then validate_hpc_setup, and guides the user
206
+ through fixing any issues found.
207
+
208
+ Parameters
209
+ ----------
210
+ endpoint : str, optional
211
+ Named endpoint to diagnose (e.g. "improv", "ucar"). Leave blank
212
+ to check all configured endpoints.
213
+ """
214
+ ep_arg = f'endpoint="{endpoint}"' if endpoint else ""
215
+ return (
216
+ "Diagnose the HPC Globus Compute configuration.\n\n"
217
+ f"1. Call `endpoint_status`({ep_arg}) to get a fast cached status "
218
+ "summary of all configured endpoints.\n"
219
+ f"2. Call `validate_hpc_setup`({ep_arg}) to run a deeper check: "
220
+ "SDK auth, endpoint manager reachability, and a remote no-op probe.\n"
221
+ "3. If any check fails, explain what the error means and what the "
222
+ "user should do to fix it (re-authenticate, restart the endpoint "
223
+ "manager, check the worker environment, etc.).\n"
224
+ "4. If everything passes, confirm the endpoint is ready for "
225
+ "use_remote=True tool calls."
226
+ )
227
+
228
+
229
+ if __name__ == "__main__":
230
+ mcp.run()