@barivia/barmesh-mcp 0.8.8 → 0.8.9

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.
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import{McpServer as e}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as s}from"@modelcontextprotocol/sdk/server/stdio.js";import{getUiCapability as r,registerAppResource as t,RESOURCE_MIME_TYPE as o}from"@modelcontextprotocol/ext-apps/server";import{startVizServer as n}from"./viz-server.js";import{API_KEY as a,CLIENT_VERSION as i,apiCall as l,apiRawCall as c,loadViewHtml as m,setVizPort as d,setClientSupportsMcpApps as h}from"./shared.js";import{registerGuideTool as u}from"./tools/guide.js";import{registerDatasetsTool as p}from"./tools/datasets.js";import{registerCfdTools as b}from"./tools/cfd.js";import{registerJobsTool as f}from"./tools/jobs.js";import{registerResultsTool as _}from"./tools/results.js";import{registerResultsExplorerTool as y,RESULTS_EXPLORER_URI as v}from"./tools/barmesh_results_explorer.js";import{registerTrainingMonitorTool as g,TRAINING_MONITOR_URI as w}from"./tools/training_monitor.js";import{registerFeedbackTool as j}from"./tools/feedback.js";a||(console.error("Error: BARIVIA_API_KEY not set. Set it in your MCP client config."),process.exit(1));(async function(){const a=new e({name:"barmesh",version:i},{instructions:"# Barivia barmesh — CFD mesh-convergence analytics\n\nSOM-based mesh-convergence verification: compare CFD meshes of a refinement study by the\nvolume-weighted distribution their cells form on a shared self-organizing map, plus\nclassical Richardson/GCI on scalar quantities.\n\n## Two tracks\n- barmesh_mesh_convergence: high-dimensional field comparison. Symmetric KL and\n Wasserstein-1 (EMD) distances between each mesh's SOM fingerprint and a reference,\n and between consecutive meshes. Decreasing, plateauing distances toward the finest\n mesh indicate sufficiency. Complements (does not replace) numerical uncertainty analysis.\n- barmesh_richardson: classical grid-convergence index on scalar QoIs.\n\n## Workflow (read-only first)\n1. barmesh_guide_workflow — orient and confirm your plan includes CFD tools.\n2. barmesh_prepare_mesh_data — recipe for the combined per-cell CSV (mesh_id + features + cell volume V).\n3. barmesh_datasets(action=upload) then preview (optional description/tags for inventory).\n4. barmesh_mesh_convergence (and/or barmesh_richardson) returns a job id.\n5. barmesh_training_monitor(job_id) visual MCP App with live curves (default); barmesh_jobs(action=monitor) — headless blocking snapshots; or barmesh_jobs(status) for one-shot polls every 10-20s.\n6. barmesh_results(action=get) distances, convergence reading, and figures; then\n barmesh_results_explorer(job_id) to browse every figure interactively.\n\n## Org inventory recipe\n- Prefer `barmesh_jobs(action=inventory)` for a markdown datasets+jobs overview.\n- Or compose `barmesh_datasets(list)` + `barmesh_jobs(action=list, limit=50)` (page with `cursor`; filter with `status`/`job_type`/`has_results=true` for a results catalog).\n- Cleanup: `barmesh_jobs(action=delete, job_id=…)` + `barmesh_datasets(action=delete)` for known IDs — do not deep-page list to find them.\n- Set `description`+`tags` on upload/submit/update so duplicates stay navigable. List is slim by default (no fat params).\n\n## UI delivery (barmesh_training_monitor, barmesh_results_explorer)\n\nHosts vary: some embed MCP Apps; others list ui:// but never mount them (expected on some Cursor builds). Tool results always lead with a standalone localhost URL and a structured ui_delivery block (delivery, urls, hint_for_agent) — follow hint_for_agent without user prompting.\n\n- Surface the standalone URL as a clickable markdown link. Do not bury it after metrics.\n- Env: BARIVIA_UI_DELIVERY=auto|apps|localhost|inline; BARIVIA_VIZ_PORT pins the viz port across restarts.\n- Standalone pages cross-link training monitor ↔ results explorer for the same job_id.\n\nThese tools are gated by the 'cfd' entitlement; analysis calls return 403 if your plan\ndoes not include it.\n\n## API briefly unavailable (demos)\nIf barmesh_jobs / barmesh_results / barmesh_send_feedback (or any tool) reports the mesh analysis\nAPI temporarily unavailable: say so in one calm line, do not paste HTML/502 pages, and pause\nafter the proxy's burst retries (3 tries ~2s apart; then retry_after_sec≈30). Figures already\ndownloaded stay usable. Keep talking about the last good distances, GCI CSV, and figures —\ndegrade to \"review what we have\", not \"everything failed\". Suggest a later retry for new jobs\nor feedback.\n\n## Outages / feedback\n- barmesh_api_health probes GET /health + /ready (no R2). Use when tools fail with api_unreachable.\n- barmesh_send_feedback queues drafts under ~/.barivia/deferred-feedback when the API/gateway\n is down and flushes them on the next successful call (shared directory with barsom send_feedback).\n- API errors are slim structured lines (error_code, cause, request_id, retry_after_sec) — never raw Cloudflare HTML."});t(a,v,v,{mimeType:o},async()=>{const e=await m("barmesh-results-explorer");return{contents:[{uri:v,mimeType:o,text:e??"<html><body>Results Explorer view not built yet. Run: npm run build:views</body></html>"}]}}),t(a,w,w,{mimeType:o},async()=>{const e=await m("barmesh-training-monitor");return{contents:[{uri:w,mimeType:o,text:e??"<html><body>Training Monitor view not built yet. Run: npm run build:views</body></html>"}]}}),u(a),y(a),p(a),b(a),f(a),g(a),_(a),j(a);try{const e=await n(l,c,m);d(e)}catch(e){process.env.BARIVIA_VIZ_PORT&&console.error("barmesh viz server failed to start:",e)}const I=a.server;I.oninitialized=()=>{const e=I.getClientCapabilities(),s=r(e);h(!!s?.mimeTypes?.includes(o))};const k=new s;await a.connect(k),console.error(`barmesh-mcp ${i} ready (API: ${process.env.BARIVIA_API_URL??"https://api.barivia.se"})`)})().catch(e=>{console.error("Fatal error starting barmesh-mcp:",e),process.exit(1)});
2
+ import{McpServer as e}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as r}from"@modelcontextprotocol/sdk/server/stdio.js";import{getUiCapability as o,registerAppResource as s,RESOURCE_MIME_TYPE as t}from"@modelcontextprotocol/ext-apps/server";import{startVizServer as n}from"./viz-server.js";import{API_KEY as i,CLIENT_VERSION as a,apiCall as m,apiRawCall as l,loadViewHtml as c,setVizPort as p,setClientSupportsMcpApps as h}from"./shared.js";import{registerGuideTool as d}from"./tools/guide.js";import{registerDatasetsTool as _}from"./tools/datasets.js";import{registerCfdTools as b}from"./tools/cfd.js";import{registerJobsTool as u}from"./tools/jobs.js";import{registerResultsTool as f}from"./tools/results.js";import{registerResultsExplorerTool as v,RESULTS_EXPLORER_URI as y}from"./tools/barmesh_results_explorer.js";import{registerTrainingMonitorTool as I,TRAINING_MONITOR_URI as w}from"./tools/training_monitor.js";import{registerFeedbackTool as g}from"./tools/feedback.js";i||(console.error("Error: BARIVIA_API_KEY not set. Set it in your MCP client config."),process.exit(1));(async function(){const i=new e({name:"barmesh",version:a},{instructions:"# Barivia barmesh — CFD mesh-convergence analytics\n\n## Bootstrap (do this first)\n\nCall `barmesh_guide_workflow` (plan-scoped) and `barmesh_prepare_mesh_data` before upload/submit. Method details and mesh-prep recipe come from the API when your key has the CFD entitlement.\n\n## Tracks (names only)\n\n- `barmesh_mesh_convergence` field-level mesh comparison (SOM fingerprints)\n- `barmesh_richardson` classical Richardson/GCI on scalar QoIs\n\n## Workflow (short)\n\n1. `barmesh_guide_workflow`\n2. `barmesh_prepare_mesh_data`\n3. `barmesh_datasets(upload)` preview\n4. Submit mesh_convergence and/or richardson job_id\n5. `barmesh_training_monitor` or `barmesh_jobs(monitor/status)`\n6. `barmesh_results(get)` `barmesh_results_explorer`\n\nInventory: `barmesh_jobs(inventory)` or list datasets+jobs. Set description/tags on upload/submit.\n\n## UI / outages\n\nTool results lead with a localhost viz URL and `ui_delivery` — follow `hint_for_agent`. Env: `BARIVIA_UI_DELIVERY`, `BARIVIA_VIZ_PORT`.\nOn `api_unreachable`: one calm line; honor `retry_after_sec`; use `barmesh_api_health`; keep reviewing last good figures. `barmesh_send_feedback` queues deferred drafts when the API is down."});s(i,y,y,{mimeType:t},async()=>{const e=await c("barmesh-results-explorer");return{contents:[{uri:y,mimeType:t,text:e??"<html><body>Results Explorer view not built yet. Run: npm run build:views</body></html>"}]}}),s(i,w,w,{mimeType:t},async()=>{const e=await c("barmesh-training-monitor");return{contents:[{uri:w,mimeType:t,text:e??"<html><body>Training Monitor view not built yet. Run: npm run build:views</body></html>"}]}}),d(i),v(i),_(i),b(i),u(i),I(i),f(i),g(i);try{const e=await n(m,l,c);p(e)}catch(e){process.env.BARIVIA_VIZ_PORT&&console.error("barmesh viz server failed to start:",e)}const j=i.server;j.oninitialized=()=>{const e=j.getClientCapabilities(),r=o(e);h(!!r?.mimeTypes?.includes(t))};const A=new r;await i.connect(A),console.error(`barmesh-mcp ${a} ready (API: ${process.env.BARIVIA_API_URL??"https://api.barivia.se"})`)})().catch(e=>{console.error("Fatal error starting barmesh-mcp:",e),process.exit(1)});
package/dist/shared.js CHANGED
@@ -35,7 +35,7 @@ function newRequestId() {
35
35
  return randomUUID();
36
36
  }
37
37
  /** Single source of truth for the proxy version. Keep in sync with package.json on bump. */
38
- export const CLIENT_VERSION = "0.8.8";
38
+ export const CLIENT_VERSION = "0.8.9";
39
39
  export const PUBLIC_SITE_ORIGIN = "https://barivia.se";
40
40
  /** Large per-cell CSV uploads may exceed the default fetch timeout. */
41
41
  export const UPLOAD_DATASET_TIMEOUT_MS = 180_000;
package/dist/tools/cfd.js CHANGED
@@ -5,34 +5,33 @@ import { pollCfdPrepareIfPresent } from "../cfd_prepare.js";
5
5
  export function registerCfdTools(server) {
6
6
  registerAuditedTool(server, "barmesh_mesh_convergence", `Run SOM-based mesh-convergence analysis on an uploaded combined per-cell CSV.
7
7
 
8
- What it does (one call): joint-normalizes all meshes, trains one SOM on a stratified pooled subsample, projects each mesh to a volume-weighted fingerprint, and computes symmetric KL and Wasserstein-1 (EMD) distances stepwise and against a reference mesh, plus publication figures and an advisory convergence reading.
9
-
10
- BEST FOR: A mesh-refinement study where you want a field-level (not just scalar) view of whether the mesh has converged.
11
- NOT FOR: Single scalar quantities of interest use barmesh_richardson for classical GCI.
12
- ASYNC: This is a queued job. It returns a job id immediately. Then poll barmesh_jobs(action=status) every 10-20s; datacenter-scale grids plus EMD can take a few minutes keep polling. On completion call barmesh_results(action=get).
13
- COMMON MISTAKES: omitting feature_columns (required); choosing a reference_mesh label that is not present; forgetting the cell-volume column at upload time; multi-topology studies (uniform U + graded G meshes) without explicit mesh_order — equal cell counts sort U-then-G and invent bogus stepwise pairs (U160|G20). Pass mesh_order coarse→fine interleaved by refinement (U20,G20,U40,G40,…) or use preset=cavity which defaults interleaved when U/G labels are detected.`, {
8
+ BEST FOR: Field-level mesh-refinement comparison (not a single scalar QoI).
9
+ NOT FOR: Classical GCI on scalars — use barmesh_richardson.
10
+ ASYNC: Returns job_id; poll barmesh_jobs(status) every 10–20s; then barmesh_results(get).
11
+ Call **barmesh_guide_workflow** / **barmesh_prepare_mesh_data** for method details, mesh_order rules, and prep recipe (API, CFD entitlement).
12
+ COMMON MISTAKES: omitting feature_columns; bad reference_mesh label; missing volume columnsee prepare_mesh_data.`, {
14
13
  dataset_id: z.string().describe("Dataset ID from barmesh_datasets(upload)"),
15
- feature_columns: z.array(z.string()).describe("Per-cell numeric feature columns to train the SOM on (e.g. [\"p\",\"U_mag\",\"k\",\"log_epsilon\"])"),
16
- preset: z.enum(["generic", "cavity", "pitz", "datacenter"]).optional().describe("Hyperparameter preset; defaults to generic. cavity/pitz/datacenter reproduce the published settings."),
17
- mesh_column: z.string().optional().describe("Column with the mesh label (default mesh_id)"),
18
- volume_column: z.string().optional().describe("Cell-volume column for fingerprint weights (default V; equal weights if absent)"),
19
- reference_mesh: z.string().optional().describe("Mesh label used as reference (default: the mesh with the most cells = finest)"),
20
- mesh_order: z.array(z.string()).optional().describe("Explicit coarse-to-fine mesh order (default: ascending cell count; cavity preset and tied U/G cell counts auto-interleave U20→G20→U40→G40→…)"),
21
- grid: z.array(z.number().int()).optional().describe("SOM grid [rows, cols] (overrides preset)"),
22
- epochs: z.array(z.number().int()).optional().describe("[ordering, convergence] epochs (overrides preset)"),
23
- batch_size: z.number().int().optional().describe("SOM batch size (overrides preset)"),
24
- sigma_f: z.number().optional().describe("Final ordering neighborhood width (overrides preset)"),
25
- backend: z.enum(["auto", "cpu", "gpu", "gpu_graphs"]).optional().describe("Compute backend (default auto / preset)"),
26
- stratify_scale: z.number().optional().describe("[0,1] per-mesh training-row cap; 1 uses all cells (default 1)"),
27
- emd_method: z.enum(["exact", "sinkhorn"]).optional().describe("EMD solver: exact LP (default) or sinkhorn (fast approximation for large grids)"),
28
- te_panel_size: z.number().int().optional().describe("Fixed evaluation-panel size for live topographic error during training (default clamp(grid_nodes*6, 500, 10000); curve stays on this panel end-to-end)"),
14
+ feature_columns: z.array(z.string()).describe("Per-cell numeric feature columns for the SOM"),
15
+ preset: z.enum(["generic", "cavity", "pitz", "datacenter"]).optional().describe("Hyperparameter preset (default generic) see barmesh_guide_workflow"),
16
+ mesh_column: z.string().optional().describe("Mesh label column (default mesh_id)"),
17
+ volume_column: z.string().optional().describe("Cell-volume column (default V)"),
18
+ reference_mesh: z.string().optional().describe("Reference mesh label (default: finest / most cells)"),
19
+ mesh_order: z.array(z.string()).optional().describe("Explicit coarsefine mesh order see barmesh_prepare_mesh_data"),
20
+ grid: z.array(z.number().int()).optional().describe("SOM grid [rows, cols] override"),
21
+ epochs: z.array(z.number().int()).optional().describe("[ordering, convergence] epochs override"),
22
+ batch_size: z.number().int().optional().describe("SOM batch size override"),
23
+ sigma_f: z.number().optional().describe("Final ordering neighborhood width override"),
24
+ backend: z.enum(["auto", "cpu", "gpu", "gpu_graphs"]).optional().describe("Compute backend"),
25
+ stratify_scale: z.number().optional().describe("[0,1] per-mesh training-row cap"),
26
+ emd_method: z.enum(["exact", "sinkhorn"]).optional().describe("EMD solver see barmesh_guide_workflow"),
27
+ te_panel_size: z.number().int().optional().describe("Live TE evaluation panel size"),
29
28
  te_inner_samples: z.number().int().optional().describe("Deprecated alias for te_panel_size"),
30
- component_planes_physical: z.boolean().optional().describe("Physical-scale component-plane colorbars (default true)"),
29
+ component_planes_physical: z.boolean().optional().describe("Physical-scale component-plane colorbars"),
31
30
  figures: z.boolean().optional().describe("Generate publication figures (default true)"),
32
- transforms: z.record(z.enum(["log", "log1p", "log10", "sqrt", "square", "abs", "invert", "none"])).optional().describe("Per-feature transform applied before normalization (e.g. log1p to compress k/epsilon/omega). Same preprocessing engine as barsom training."),
33
- normalize: z.union([z.enum(["all", "auto", "mad", "sigmoidal", "sepd"]), z.array(z.string())]).optional().describe("Normalization mode for SOM features (default auto = joint z-score of non-cyclic features). Use mad for heavy-tailed channels."),
34
- normalization_methods: z.record(z.enum(["zscore", "mad", "sigmoidal", "sepd", "none"])).optional().describe("Per-feature normalization override; keys must be in feature_columns."),
35
- row_range: z.tuple([z.number().int().min(1), z.number().int().min(1)]).optional().describe("1-based inclusive [start, end] row slice applied during preprocessing (and to mesh labels / cell volumes)."),
31
+ transforms: z.record(z.enum(["log", "log1p", "log10", "sqrt", "square", "abs", "invert", "none"])).optional().describe("Per-feature transform before normalization"),
32
+ normalize: z.union([z.enum(["all", "auto", "mad", "sigmoidal", "sepd"]), z.array(z.string())]).optional().describe("SOM feature normalization mode"),
33
+ normalization_methods: z.record(z.enum(["zscore", "mad", "sigmoidal", "sepd", "none"])).optional().describe("Per-feature normalization override"),
34
+ row_range: z.tuple([z.number().int().min(1), z.number().int().min(1)]).optional().describe("1-based inclusive [start, end] row slice"),
36
35
  label: z.string().optional().describe("Optional job label"),
37
36
  description: z.string().optional().describe("Optional free-text description for inventory"),
38
37
  tags: z.array(z.string()).optional().describe("Optional tags for inventory/navigation"),
@@ -63,21 +62,20 @@ COMMON MISTAKES: omitting feature_columns (required); choosing a reference_mesh
63
62
  }
64
63
  return textResult(data);
65
64
  });
66
- registerAuditedTool(server, "barmesh_richardson", `Run classical Richardson extrapolation / Grid Convergence Index (GCI) on scalar quantities of interest.
67
-
68
- What it does: from a small CSV with one row per mesh (a mesh label, a representative cell size h or a cell count, and one or more QoI columns), slides the three-level Celik (2008) GCI over consecutive mesh triplets (finest first) and reports the observed order p, the extrapolated value, and the fine-grid GCI per triplet per QoI.
65
+ registerAuditedTool(server, "barmesh_richardson", `Run classical Richardson extrapolation / Grid Convergence Index (GCI) on scalar QoIs.
69
66
 
70
- BEST FOR: Scalar benchmarks (reattachment length, centerline values, probe readings) where a classical asymptotic-convergence check is expected.
71
- NOT FOR: High-dimensional field comparison — use barmesh_mesh_convergence (complementary).
72
- ASYNC: queued job; poll barmesh_jobs(action=status), then barmesh_results(action=get).
73
- COMMON MISTAKES: not providing h_column or n_cells_column; mixing QoIs with different mesh sets in one CSV; mixing uniform (U…) and graded (G…) mesh families in one CSV — classical GCI assumes one topology per job; run separate Richardson jobs per family (e.g. G160|G80|G40 graded, U160|U80|U40 uniform).`, {
67
+ BEST FOR: Scalar benchmarks where classical asymptotic-convergence checks are expected.
68
+ NOT FOR: High-dimensional field comparison — use barmesh_mesh_convergence.
69
+ ASYNC: queued job; poll barmesh_jobs(status), then barmesh_results(get).
70
+ Method details (Fs, one-family-per-CSV, triplets): **barmesh_guide_workflow**.
71
+ COMMON MISTAKES: missing h_column or n_cells_column; mixing mesh families — see guide.`, {
74
72
  dataset_id: z.string().describe("Dataset ID (one row per mesh)"),
75
73
  qoi_columns: z.array(z.string()).describe("Scalar QoI column names to extrapolate"),
76
74
  mesh_column: z.string().optional().describe("Mesh label column (default mesh_id)"),
77
- h_column: z.string().optional().describe("Representative cell-size column (provide this or n_cells_column)"),
78
- n_cells_column: z.string().optional().describe("Cell-count column; h is derived as n_cells^(-1/dimension)"),
79
- dimension: z.number().int().optional().describe("Spatial dimension d for deriving h from cell count (default 3)"),
80
- safety_factor: z.number().optional().describe("GCI safety factor Fs (default 1.25, Roache)"),
75
+ h_column: z.string().optional().describe("Representative cell-size column (or use n_cells_column)"),
76
+ n_cells_column: z.string().optional().describe("Cell-count column (alternative to h_column)"),
77
+ dimension: z.number().int().optional().describe("Spatial dimension for h from cell count"),
78
+ safety_factor: z.number().optional().describe("GCI safety factor see barmesh_guide_workflow"),
81
79
  label: z.string().optional().describe("Optional job label"),
82
80
  description: z.string().optional().describe("Optional free-text description for inventory"),
83
81
  tags: z.array(z.string()).optional().describe("Optional tags for inventory/navigation"),
@@ -3,27 +3,12 @@ import { apiCall, probeApiHealth, structuredTextResult, textResult } from "../sh
3
3
  import { listDeferredFeedback } from "../deferred_feedback.js";
4
4
  const OFFLINE_GUIDE = `Mesh analysis API temporarily unavailable — figures already on disk stay available; new jobs/feedback will wait.
5
5
 
6
- barmesh offline summary (demo-safe): keep reviewing the last good distances, GCI CSV, and downloaded figures. Say the API is unavailable plainly; the proxy already burst-retried (~3×2s) — wait ~30s before another round. Do not treat the session as failed.
6
+ Say the API is unavailable plainly; the proxy already burst-retried (~3×2s) — wait ~30s before another round. Keep reviewing the last good distances/figures; do not treat the session as failed.
7
7
 
8
- Two tracks (when API returns):
9
- - barmesh_mesh_convergence SOM volume-fingerprint distances (symmetric KL + Wasserstein-1 vs reference and stepwise)
10
- - barmesh_richardson — classical Richardson / GCI on scalar QoIs (one mesh family per CSV: uniform OR graded, not mixed)
8
+ When reconnecting (BARIVIA_API_KEY / BARIVIA_API_URL), call barmesh_guide_workflow again for the plan-scoped workflow.`;
9
+ const OFFLINE_PREP = `API unreachable cannot load the CFD mesh-prep recipe.
11
10
 
12
- Workflow (when API returns):
13
- 1. barmesh_prepare_mesh_data — recipe for the combined per-cell CSV (mesh_id + features + cell volume V)
14
- 2. barmesh_datasets(upload) → barmesh_datasets(preview)
15
- 3. barmesh_mesh_convergence and/or barmesh_richardson — returns job_id
16
- - Multi-topology cavity studies: pass mesh_order interleaved (U20,G20,U40,G40,…) or preset=cavity
17
- 4. barmesh_training_monitor (visual MCP App) or barmesh_jobs(action=monitor) headless — poll until complete
18
- 5. barmesh_results(action=get) → barmesh_results_explorer for figures (mesh_convergence) or richardson_gci.csv summary (Richardson)
19
-
20
- (Set BARIVIA_API_KEY / BARIVIA_API_URL when reconnecting.)`;
21
- const OFFLINE_PREP = `barmesh mesh-data prep (offline summary; API unreachable):
22
- Build ONE combined per-cell CSV across all meshes of the refinement study:
23
- - one row per cell; a mesh label column (mesh_id); the physical channels you want compared (e.g. p, U_mag, k, log_epsilon — log-compress turbulence quantities); and a cell-volume column (V) for fingerprint weighting.
24
- - keep the SAME feature columns across every mesh; pick the finest mesh as the reference.
25
- - multi-topology (U + G): pass mesh_order coarse→fine interleaved by refinement (U20,G20,U40,G40,U80,G80,U160,G160) or use preset=cavity.
26
- Then: barmesh_datasets(upload) -> barmesh_mesh_convergence. (Set BARIVIA_API_KEY / BARIVIA_API_URL.)`;
11
+ Retry when BARIVIA_API_KEY / BARIVIA_API_URL reconnect, then call barmesh_prepare_mesh_data again (entitlement-scoped).`;
27
12
  export function registerGuideTool(server) {
28
13
  registerAuditedTool(server, "barmesh_guide_workflow", `Get the barmesh CFD mesh-convergence workflow and tool map from the API (tier-scoped).
29
14
 
@@ -49,7 +34,7 @@ UNAVAILABLE: If the API is down, this tool returns a calm offline summary — sa
49
34
 
50
35
  BEST FOR: Before barmesh_datasets(upload) — tells you which physical channels to extract, how to label meshes (mesh_id), the cell-volume column (V), and how to pick the reference mesh.
51
36
  NOT FOR: Submitting jobs — after preparing the CSV, use barmesh_datasets(upload) then barmesh_mesh_convergence.
52
- COMMON MISTAKES: forgetting the per-cell cell-volume column; using different channels across meshes; not log-compressing turbulence quantities (k, epsilon, omega); multi-topology U+G studies without mesh_order (use interleaved U20,G20,U40,G40,… or preset=cavity).`, {}, async () => {
37
+ COMMON MISTAKES: missing volume column; mismatched channels across meshes; multi-topology order issues full recipe is in the API response when entitled.`, {}, async () => {
53
38
  try {
54
39
  const data = (await apiCall("GET", "/v1/cfd/prep"));
55
40
  return textResult({ recipe: data.recipe, entitled: data.entitled });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barivia/barmesh-mcp",
3
- "version": "0.8.8",
3
+ "version": "0.8.9",
4
4
  "description": "barmesh MCP proxy — SOM-based CFD mesh-convergence and Richardson/GCI analysis on the Barivia cloud API",
5
5
  "keywords": [
6
6
  "mcp",