@barivia/barsom-mcp 0.18.0 → 0.19.0

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/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @barivia/barsom-mcp
2
2
 
3
- MCP proxy for the Barivia Analytics Engine — connects any stdio MCP client (Cursor, Claude Desktop, etc.) to the barSOM cloud API. The npm package is **`@barivia/barsom-mcp`**; many configs label the server **`analytics-engine`** (the MCP server name in the client JSON). **`guide_barsom_workflow`** is the canonical bootstrap: it loads plan-scoped workflow text from the Barivia API when online (tool map, async rules, training modes, SOP). If the API is unreachable, it returns a short offline stub. Core tools are `datasets`, `train` (`map`, `siom_map`, `impute`, `floop_siom` where entitled), `jobs` (status/list/compare/cancel/delete — lifecycle only), `results` (get/export/download/recolor), and `inference` (predict/batch_predict/impute_column/compare/project_columns/transition_flow/report). **Optional MCP App tools** (`training_prep`, `training_monitor`, `results_explorer`) add embedded or localhost viz; they are **not required** to complete upload → train → poll → results, though `results_explorer` is the preferred way to browse figures.
3
+ MCP proxy for the Barivia Analytics Engine — connects any stdio MCP client (Cursor, Claude Desktop, etc.) to the barSOM cloud API. The npm package is **`@barivia/barsom-mcp`**; many configs label the server **`analytics-engine`** (the MCP server name in the client JSON). **`guide_barsom_workflow`** is the canonical bootstrap: it loads plan-scoped workflow text from the Barivia API when online (tool map, async rules, training modes, SOP). If the API is unreachable, it returns a short offline stub. Core tools are `datasets`, `train` (`map`, `siom_map`, `impute`, `floop_siom` where entitled), `jobs` (status/list/compare/cancel/delete — lifecycle only), `results` (get/export/download/recolor), and `inference` (predict/batch_predict/impute_column/compare/project_columns/transition_flow/report). **Optional MCP App tools** (`training_monitor`, `results_explorer`) add embedded or localhost viz; they are **not required** to complete upload → train → poll → results, though `results_explorer` is the preferred way to browse figures.
4
4
 
5
- **Pre-training help (pick one):** **`prepare_training`** prompt = narrative checklist (tier-scoped from the API when online); **`training_guidance`** tool = structured presets and parameter hints; **`training_prep`** tool = interactive UI plus **`submit_prepared_training`**.
5
+ **Pre-training help (pick one):** **`prepare_training`** prompt = narrative checklist (tier-scoped from the API when online); **`training_guidance`** tool = structured presets and parameter hints (including the resolved per-column normalization). Review either, then submit with **`train`**.
6
6
 
7
7
  ## Installation
8
8
 
@@ -70,11 +70,11 @@ All multi-action tools follow the `datasets` / `jobs` / `results` / `inference`
70
70
  |--------|--------|
71
71
  | Bootstrap | `guide_barsom_workflow`, prompts `info`, `prepare_training` |
72
72
  | Data | `datasets` |
73
- | Train & poll | `jobs`, `submit_prepared_training` (after `training_prep`), `training_monitor` (optional) |
73
+ | Train & poll | `train`, `jobs`, `training_monitor` (optional) |
74
74
  | Results | `results`, `results_explorer` (optional) |
75
75
  | Inference | `inference` |
76
76
  | Account | `account` |
77
- | Optional UI | `training_prep`, `training_monitor`, `results_explorer` |
77
+ | Optional UI | `training_monitor`, `results_explorer` |
78
78
  | Advanced | `training_guidance` |
79
79
 
80
80
  Agents should not call **`_fetch_figure`** from chat; it exists for the Results Explorer MCP App host. Use `results(action=get)` or `results_explorer` instead.
@@ -162,8 +162,6 @@ All actions use a frozen trained map — no retraining. Derived columns use **`d
162
162
 
163
163
  | Tool | Role |
164
164
  |------|------|
165
- | `training_prep` | Review variables, transforms, hyperparameters before submit |
166
- | `submit_prepared_training` | Submit the reviewed prep (`review_token` + `explicit_confirm=true`) |
167
165
  | `training_monitor` | Live QE + topographic-error curves (ordering/convergence, dual y-axis), FLooP step progress when applicable; optional — `jobs(action=status)` is enough |
168
166
  | `results_explorer` | Browse metrics and figures after training completes |
169
167
  | `_fetch_figure` | **Host / App only** — Results Explorer invokes this for one raster figure; not for agent chat |
@@ -182,6 +180,9 @@ The right viewer depends on **(MCP App support)** **and** **(can the human reach
182
180
 
183
181
  ### Migration notes
184
182
 
183
+ - **Surface cleanup (0.19.0, breaking):**
184
+ - `training_prep` and `submit_prepared_training` **removed**. The interactive prep UI is retired; for pre-train help use the `prepare_training` prompt (narrative checklist) or `training_guidance` (presets + resolved per-column normalization), then submit directly with `train(action=map | siom_map | impute | floop_siom)`.
185
+ - The unused `data-preview` and `map-explorer` view scaffolds were deleted (they were never wired to a tool). The two shipped MCP App UIs are now `training_monitor` and `results_explorer`, both enhanced (auto-resize, earlier render, and silent model-context sync of what the user is viewing).
185
186
  - **Fixes (0.17.1, non-breaking):**
186
187
  - `datasets(action=list/get)` no longer prints `ingest_error=missing` for healthy datasets (a SQL `NULL` was serialized as the literal `"missing"`; fixed server-side, and the proxy now also ignores the `missing`/`null` sentinels).
187
188
  - `file_path` upload help now states that **relative** paths resolve against the MCP **workspace root** — in Cursor/IDE clients that root is often the MCP install dir, so set `BARIVIA_WORKSPACE_ROOT` (or pass an absolute path) if a relative path is "not accessible".
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 t}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as o}from"zod";import{getUiCapability as r,registerAppResource as n,RESOURCE_MIME_TYPE as s}from"@modelcontextprotocol/ext-apps/server";import{startVizServer as i}from"./viz-server.js";import{API_KEY as a,apiCall as l,apiRawCall as p,loadViewHtml as c,setVizPort as m,setClientSupportsMcpApps as d,CLIENT_VERSION as u}from"./shared.js";import{registerDatasetsTool as f}from"./tools/datasets.js";import{registerTrainTool as g}from"./tools/train.js";import{registerJobsTool as _,JOBS_DESCRIPTION_BASE as h}from"./tools/jobs.js";import{registerResultsTool as b}from"./tools/results.js";import{registerExploreMapTool as y,RESULTS_EXPLORER_URI as w}from"./tools/explore_map.js";import{registerAccountTool as j}from"./tools/account.js";import{registerInferenceTool as v}from"./tools/inference.js";import{registerGuideBarsomTool as x}from"./tools/guide_barsom.js";import{registerTrainingGuidanceTool as P}from"./tools/training_guidance.js";import{registerFeedbackTool as k}from"./tools/feedback.js";import{registerTrainingPrepTools as I,TRAINING_PREP_URI as T}from"./tools/training_prep.js";import{registerTrainingMonitorTool as A,TRAINING_MONITOR_URI as M}from"./tools/training_monitor.js";import{resolvePrepareTrainingPromptText as S}from"./prepare_training_prompt.js";a||(console.error("Error: BARIVIA_API_KEY not set. Set it in your MCP client config."),process.exit(1));const O=new e({name:"analytics-engine",version:u,instructions:'# Barivia Mapping Analytics Engine\n\nSelf-organizing map (SOM) analytics: project high-dimensional data to a 2D grid for clusters, gradients, and anomalies.\n\n## Workflow (short)\n\nUpload (`datasets(upload)`) → `datasets(preview)` and `datasets(analyze)` before train → submit one of `train(action=map)`, `train(action=siom_map)`, or `train(action=floop_siom)` (only if plan allows FLooP) → poll `jobs(status)` every 10–15s until `completed` → `results(get)` for metrics and figures (there is no separate analyze tool), then `results_explorer(job_id)` to browse the figures interactively. Then `jobs(compare)`, `results(download/recolor)`, or `inference` (predict / compare / project_columns / impute_column / transition_flow) as needed.\n\n**Full detail:** Call `guide_barsom_workflow` for plan-scoped tool map, training modes, async rules, optional MCP App UIs, and step-by-step SOP (from the Barivia API when online).\n\n## Tool taxonomy (one tool per stage — do not mix)\n\n| Stage | Tool(s) | Contract |\n|-------|---------|----------|\n| Data | `datasets` | upload, preview, analyze, list, **get** (status/staging), subset, add_expression, reduce_spectral, delete — ingest + feature engineering, no map |\n| Train submit | `train` **or** `training_prep` → `submit_prepared_training` | map, siom_map, impute (sparse → map + dense imputed.csv), floop_siom (entitled). Async, returns job_id. Submit only |\n| Lifecycle | `jobs` | status, list, compare (**training runs**), cancel, delete. No training/scoring here |\n| Artifacts | `results` | get (figures="none" for metrics-only), export, download, recolor (async). Read/render completed jobs |\n| Frozen-map ops | `inference` | predict (regime-aware; "compact"|"annotated"), batch_predict, impute_column (neighbor-pool fill for a non-training column), compare (cohort density-diff), project_columns, transition_flow (time-ordered rows only), report. No weight updates |\n| Account | `account` | status, burst/compute actions, history, add_funds |\n| Bootstrap | `guide_barsom_workflow`, `training_guidance`, `prepare_training` prompt | orientation, parameter hints, narrative checklist (API/tier-scoped) |\n| Explore (UI) | `results_explorer`, `training_prep`, `training_monitor` | richer UX over the same API; `jobs(status)`+`results(get)` still suffice headless |\n| Other | `send_feedback` | only after user agrees |\n\n### Avoid these mis-routes\n- `jobs(compare)` = metrics table across **training runs** (pick best in a sweep). `inference(compare)` = density-diff of one map vs a **second dataset** (drift/cohort). Different tools.\n- Post-training map analysis (predict, compare, project_columns, impute_column, **transition_flow**) is all **inference** — not `results`. `results` is presentation/artifacts only (`recolor` stays here: it re-renders, it doesn\'t touch data).\n- Project a quantity onto the map: existing columns → `inference(project_columns)`; a formula → `datasets(add_expression, project_onto_job=<job>)`.\n\n## Async pattern\n\n- **Manual poll:** Training submits return `job_id` immediately — poll `jobs(status)` every 10–15s. **Running is not failed**; large grids or FLooP-SIOM can take many minutes. `max_nodes` (FLooP) is a total node budget, not grid side length.\n- **Often auto-polled:** `inference` actions (incl. `transition_flow`) and `results(recolor)` may wait in-proxy; if you get a `job_id`, poll `jobs(status)` the same way.\n\nCredits: jobs consume compute credits; check `account(status)` before big runs. Per-request HTTP timeout defaults to 60s (`datasets(analyze)` is async + auto-polled, so it is not bound by it); on slow networks raise `BARIVIA_FETCH_TIMEOUT_MS`. Timeouts are NOT auto-retried (avoids duplicating slow/expensive work).\n\n## Constraints\n\n- Prep ladder: `prepare_training` prompt = narrative checklist; `training_guidance` = structured hints; `training_prep` = interactive UI that shows the **resolved per-column normalization / transforms / grid / epochs** and lets the user tweak before a guarded `submit_prepared_training`. Prefer `training_prep` when the user wants to review or fine-tune preprocessing before committing a job; use `train` directly when parameters are already confirmed. Do not guess tiers or FLooP entitlement.\n- `inference(predict)`: prefer `dataset_id` for batch and for SIOM/irregular maps; single-row `rows` uses a fast path that can fail on some topologies — retry with `dataset_id`. FLooP-SIOM: if predict jobs fail while grid SIOM works, capture errors + `job_id`.\n- Column names are case-sensitive — match `datasets(preview)`.\n- Default training path is numeric/cyclic/temporal; use explicit `categorical_features` for baseline categoricals. `predict` must match the model contract.\n- After `results(recolor)`, `inference(transition_flow)`, or `inference(project_columns)`, use the **new** `job_id` returned for follow-up `results` if applicable.'});n(O,w,w,{mimeType:s},async()=>{const e=await c("results-explorer");return{contents:[{uri:w,mimeType:s,text:e??"<html><body>Results Explorer view not built yet. Run: npm run build:views</body></html>"}]}}),n(O,T,T,{mimeType:s},async()=>{const e=await c("training-prep");return{contents:[{uri:T,mimeType:s,text:e??"<html><body>Training Preparation view not built yet.</body></html>"}]}}),n(O,M,M,{mimeType:s},async()=>{const e=await c("training-monitor");return{contents:[{uri:M,mimeType:s,text:e??"<html><body>Training Monitor view not built yet.</body></html>"}]}}),x(O),y(O),I(O),A(O),f(O),g(O),_(O,h),b(O),j(O),v(O),P(O),k(O),O.prompt("info","Short orientation for the Barivia Mapping MCP. For full plan-scoped workflow, tool map, and SOP, the model should call guide_barsom_workflow. Use when the user asks what this MCP can do or how to get started.",{},()=>({messages:[{role:"user",content:{type:"text",text:["Give a concise, scannable answer (headers + bullets):","","**What it is:** MCP client to the Barivia mapping engine (2D SOM / SIOM / FLooP-SIOM when entitled) over HTTPS.","","**First step:** Call `guide_barsom_workflow` for plan-scoped bootstrap (full tool list, async rules, training modes, optional MCP Apps, SOP).","","**Core path:** `datasets(upload)` → `datasets(preview)` + `datasets(analyze)` → choose training action → poll `jobs(status)` every 10–15s until completed → `results(get)` (all main figures/metrics; no separate analyze tool) → `results_explorer(job_id)` to browse figures.","",'**Key tools:** `datasets` (data; reduce_spectral for spectra/long blocks), `train` (map/siom_map/impute/floop_siom; pass `label` for readable compare rows; preset=quick for a fast first map), `jobs` (status/list/compare/cancel/delete — lifecycle only), `results` (get/download/export/recolor; figures="none" for metrics-only), `inference` (predict; batch_predict; impute_column for topology-neighbor pool fill; compare; project_columns; transition_flow; report), `account` (status/credits/queue).',"","**Prep help:** `prepare_training` prompt (checklist) · `training_guidance` (presets/JSON hints) · `training_prep` + `submit_prepared_training` (interactive UI showing resolved normalization/params to review before submit).","","**Browse results:** `results_explorer(job_id)` is the preferred way to explore figures after a first `results(get)` glance; `training_monitor` shows live progress. Both optional — `results` + `jobs(status)` suffice headless.","","**After training:** `jobs(compare)` across runs, `results(recolor)`, `inference(project_columns)` for variables not in training, `inference(transition_flow)` only if rows are time-ordered.","","**Rules:** Running ≠ failed. Column names must match `datasets(preview)` exactly. Do not call `_fetch_figure` from chat (host/UI only); use `results(get)` or `results_explorer`.","","Offer `send_feedback` only after asking the user."].join("\n")}}]})),O.prompt("prepare_training","Narrative pre-training checklist (prompt). Use after upload and before train. Content is tier-scoped from the API when online. Prep ladder: this prompt = story checklist; training_guidance tool = JSON presets/parameter hints; training_prep tool = interactive UI + submit_prepared_training.",{dataset_id:o.string().describe("Dataset ID to prepare for training")},async({dataset_id:e})=>({messages:[{role:"user",content:{type:"text",text:await S(e)}}]}));const C=new t;(async function(){try{const e=await i(l,p,c);m(e)}catch(e){process.env.BARIVIA_VIZ_PORT&&console.error("Barivia viz server failed to start:",e)}const e=O.server;e.oninitialized=()=>{const t=e.getClientCapabilities(),o=r(t);d(!!o?.mimeTypes?.includes(s))},await O.connect(C)})().catch(console.error);
2
+ import{McpServer as e}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as t}from"@modelcontextprotocol/sdk/server/stdio.js";import{z as o}from"zod";import{getUiCapability as r,registerAppResource as s,RESOURCE_MIME_TYPE as n}from"@modelcontextprotocol/ext-apps/server";import{startVizServer as i}from"./viz-server.js";import{API_KEY as a,apiCall as l,apiRawCall as c,loadViewHtml as p,setVizPort as m,setClientSupportsMcpApps as d,CLIENT_VERSION as u}from"./shared.js";import{registerDatasetsTool as f}from"./tools/datasets.js";import{registerTrainTool as g}from"./tools/train.js";import{registerJobsTool as h,JOBS_DESCRIPTION_BASE as _}from"./tools/jobs.js";import{registerResultsTool as b}from"./tools/results.js";import{registerExploreMapTool as w,RESULTS_EXPLORER_URI as y}from"./tools/explore_map.js";import{registerAccountTool as j}from"./tools/account.js";import{registerInferenceTool as v}from"./tools/inference.js";import{registerGuideBarsomTool as x}from"./tools/guide_barsom.js";import{registerTrainingGuidanceTool as P}from"./tools/training_guidance.js";import{registerFeedbackTool as k}from"./tools/feedback.js";import{registerTrainingMonitorTool as I,TRAINING_MONITOR_URI as A}from"./tools/training_monitor.js";import{resolvePrepareTrainingPromptText as T}from"./prepare_training_prompt.js";a||(console.error("Error: BARIVIA_API_KEY not set. Set it in your MCP client config."),process.exit(1));const M=new e({name:"analytics-engine",version:u,instructions:'# Barivia Mapping Analytics Engine\n\nSelf-organizing map (SOM) analytics: project high-dimensional data to a 2D grid for clusters, gradients, and anomalies.\n\n## Workflow (short)\n\nUpload (`datasets(upload)`) → `datasets(preview)` and `datasets(analyze)` before train → submit one of `train(action=map)`, `train(action=siom_map)`, or `train(action=floop_siom)` (only if plan allows FLooP) → poll `jobs(status)` every 10–15s until `completed` → `results(get)` for metrics and figures (there is no separate analyze tool), then `results_explorer(job_id)` to browse the figures interactively. Then `jobs(compare)`, `results(download/recolor)`, or `inference` (predict / compare / project_columns / impute_column / transition_flow) as needed.\n\n**Full detail:** Call `guide_barsom_workflow` for plan-scoped tool map, training modes, async rules, optional MCP App UIs, and step-by-step SOP (from the Barivia API when online).\n\n## Tool taxonomy (one tool per stage — do not mix)\n\n| Stage | Tool(s) | Contract |\n|-------|---------|----------|\n| Data | `datasets` | upload, preview, analyze, list, **get** (status/staging), subset, add_expression, reduce_spectral, delete — ingest + feature engineering, no map |\n| Train submit | `train` | map, siom_map, impute (sparse → map + dense imputed.csv), floop_siom (entitled). Async, returns job_id. Submit only |\n| Lifecycle | `jobs` | status, list, compare (**training runs**), cancel, delete. No training/scoring here |\n| Artifacts | `results` | get (figures="none" for metrics-only), export, download, recolor (async). Read/render completed jobs |\n| Frozen-map ops | `inference` | predict (regime-aware; "compact"|"annotated"), batch_predict, impute_column (neighbor-pool fill for a non-training column), compare (cohort density-diff), project_columns, transition_flow (time-ordered rows only), report. No weight updates |\n| Account | `account` | status, burst/compute actions, history, add_funds |\n| Bootstrap | `guide_barsom_workflow`, `training_guidance`, `prepare_training` prompt | orientation, parameter hints, narrative checklist (API/tier-scoped) |\n| Explore (UI) | `results_explorer`, `training_monitor` | richer UX over the same API; `jobs(status)`+`results(get)` still suffice headless |\n| Other | `send_feedback` | only after user agrees |\n\n### Avoid these mis-routes\n- `jobs(compare)` = metrics table across **training runs** (pick best in a sweep). `inference(compare)` = density-diff of one map vs a **second dataset** (drift/cohort). Different tools.\n- Post-training map analysis (predict, compare, project_columns, impute_column, **transition_flow**) is all **inference** — not `results`. `results` is presentation/artifacts only (`recolor` stays here: it re-renders, it doesn\'t touch data).\n- Project a quantity onto the map: existing columns → `inference(project_columns)`; a formula → `datasets(add_expression, project_onto_job=<job>)`.\n\n## Async pattern\n\n- **Manual poll:** Training submits return `job_id` immediately — poll `jobs(status)` every 10–15s. **Running is not failed**; large grids or FLooP-SIOM can take many minutes. `max_nodes` (FLooP) is a total node budget, not grid side length.\n- **Often auto-polled:** `inference` actions (incl. `transition_flow`) and `results(recolor)` may wait in-proxy; if you get a `job_id`, poll `jobs(status)` the same way.\n\nCredits: jobs consume compute credits; check `account(status)` before big runs. Per-request HTTP timeout defaults to 60s (`datasets(analyze)` is async + auto-polled, so it is not bound by it); on slow networks raise `BARIVIA_FETCH_TIMEOUT_MS`. Timeouts are NOT auto-retried (avoids duplicating slow/expensive work).\n\n## Constraints\n\n- Prep ladder: `prepare_training` prompt = narrative checklist; `training_guidance` = structured hints (presets, resolved normalization/transforms, grid/epochs). Review these, then submit with `train`. Do not guess tiers or FLooP entitlement.\n- `inference(predict)`: prefer `dataset_id` for batch and for SIOM/irregular maps; single-row `rows` uses a fast path that can fail on some topologies — retry with `dataset_id`. FLooP-SIOM: if predict jobs fail while grid SIOM works, capture errors + `job_id`.\n- Column names are case-sensitive — match `datasets(preview)`.\n- Default training path is numeric/cyclic/temporal; use explicit `categorical_features` for baseline categoricals. `predict` must match the model contract.\n- After `results(recolor)`, `inference(transition_flow)`, or `inference(project_columns)`, use the **new** `job_id` returned for follow-up `results` if applicable.'});s(M,y,y,{mimeType:n},async()=>{const e=await p("results-explorer");return{contents:[{uri:y,mimeType:n,text:e??"<html><body>Results Explorer view not built yet. Run: npm run build:views</body></html>"}]}}),s(M,A,A,{mimeType:n},async()=>{const e=await p("training-monitor");return{contents:[{uri:A,mimeType:n,text:e??"<html><body>Training Monitor view not built yet.</body></html>"}]}}),x(M),w(M),I(M),f(M),g(M),h(M,_),b(M),j(M),v(M),P(M),k(M),M.prompt("info","Short orientation for the Barivia Mapping MCP. For full plan-scoped workflow, tool map, and SOP, the model should call guide_barsom_workflow. Use when the user asks what this MCP can do or how to get started.",{},()=>({messages:[{role:"user",content:{type:"text",text:["Give a concise, scannable answer (headers + bullets):","","**What it is:** MCP client to the Barivia mapping engine (2D SOM / SIOM / FLooP-SIOM when entitled) over HTTPS.","","**First step:** Call `guide_barsom_workflow` for plan-scoped bootstrap (full tool list, async rules, training modes, optional MCP Apps, SOP).","","**Core path:** `datasets(upload)` → `datasets(preview)` + `datasets(analyze)` → choose training action → poll `jobs(status)` every 10–15s until completed → `results(get)` (all main figures/metrics; no separate analyze tool) → `results_explorer(job_id)` to browse figures.","",'**Key tools:** `datasets` (data; reduce_spectral for spectra/long blocks), `train` (map/siom_map/impute/floop_siom; pass `label` for readable compare rows; preset=quick for a fast first map), `jobs` (status/list/compare/cancel/delete — lifecycle only), `results` (get/download/export/recolor; figures="none" for metrics-only), `inference` (predict; batch_predict; impute_column for topology-neighbor pool fill; compare; project_columns; transition_flow; report), `account` (status/credits/queue).',"","**Prep help:** `prepare_training` prompt (checklist) · `training_guidance` (presets/JSON hints + resolved normalization/params) — review, then submit with `train`.","","**Browse results:** `results_explorer(job_id)` is the preferred way to explore figures after a first `results(get)` glance; `training_monitor` shows live progress. Both optional — `results` + `jobs(status)` suffice headless.","","**After training:** `jobs(compare)` across runs, `results(recolor)`, `inference(project_columns)` for variables not in training, `inference(transition_flow)` only if rows are time-ordered.","","**Rules:** Running ≠ failed. Column names must match `datasets(preview)` exactly. Do not call `_fetch_figure` from chat (host/UI only); use `results(get)` or `results_explorer`.","","Offer `send_feedback` only after asking the user."].join("\n")}}]})),M.prompt("prepare_training","Narrative pre-training checklist (prompt). Use after upload and before train. Content is tier-scoped from the API when online. Prep ladder: this prompt = story checklist; training_guidance tool = JSON presets/parameter hints. Review, then submit with train.",{dataset_id:o.string().describe("Dataset ID to prepare for training")},async({dataset_id:e})=>({messages:[{role:"user",content:{type:"text",text:await T(e)}}]}));const S=new t;(async function(){try{const e=await i(l,c,p);m(e)}catch(e){process.env.BARIVIA_VIZ_PORT&&console.error("Barivia viz server failed to start:",e)}const e=M.server;e.oninitialized=()=>{const t=e.getClientCapabilities(),o=r(t);d(!!o?.mimeTypes?.includes(n))},await M.connect(S)})().catch(console.error);
package/dist/shared.js CHANGED
@@ -26,7 +26,7 @@ export const RETRYABLE_STATUS = new Set([502, 503, 504]);
26
26
  * X-Barsom-Client-Version so the server can annotate tool guidance with the
27
27
  * wrapper version each action requires. Keep in sync with package.json on bump.
28
28
  */
29
- export const CLIENT_VERSION = "0.18.0";
29
+ export const CLIENT_VERSION = "0.19.0";
30
30
  /** User-facing links; keep aligned with barivia.se / api.barivia.se. */
31
31
  export const PUBLIC_SITE_ORIGIN = "https://barivia.se";
32
32
  /** Self-serve account dashboard (manage plan, billing, and API keys). */
@@ -289,7 +289,8 @@ export async function resolveFilePathForUpload(filePath, mcpServer) {
289
289
  if (err instanceof Error && (err.message.includes("escapes") || err.message.includes("regular file"))) {
290
290
  throw err;
291
291
  }
292
- throw new Error(`File not accessible. For relative paths, set BARIVIA_WORKSPACE_ROOT in your MCP config. Or use an absolute path or file:// URI.`);
292
+ throw new Error(`File not accessible. Easiest fix: pass an ABSOLUTE path (e.g. "/home/you/project/data.csv" or ` +
293
+ `"C:\\\\Users\\\\you\\\\data.csv") or a file:// URI. For relative paths, set BARIVIA_WORKSPACE_ROOT in your MCP config.`);
293
294
  }
294
295
  }
295
296
  /** User-visible API error line (includes request id for support). Exported for tests. */
@@ -278,8 +278,10 @@ ESCALATION: If upload fails with column errors, open the file locally and verify
278
278
  stat = await fs.stat(resolved);
279
279
  }
280
280
  catch {
281
- throw new Error(`File not accessible at resolved path. file_path is relative to workspace root. ` +
282
- `Set BARIVIA_WORKSPACE_ROOT in your MCP config env if needed (current: ${await getWorkspaceRootAsync(server)}).`);
281
+ throw new Error(`File not accessible at resolved path. Easiest fix: pass an ABSOLUTE path ` +
282
+ `(e.g. "/home/you/project/data.csv" or "C:\\\\Users\\\\you\\\\data.csv") or a file:// URI. ` +
283
+ `Relative paths resolve against the MCP workspace root (current: ${await getWorkspaceRootAsync(server)}); ` +
284
+ `set BARIVIA_WORKSPACE_ROOT in your MCP config env to your project directory to use them.`);
283
285
  }
284
286
  if (stat.size > HARD_MAX_BYTES) {
285
287
  const gzipHint = isGzipInput ? "" : ` ${GZIP_UPLOAD_HINT}`;
@@ -152,8 +152,8 @@ async function handleResultsExplorer(job_id) {
152
152
  if (!getClientSupportsMcpApps() && payload.standaloneUrl) {
153
153
  content.push({
154
154
  type: "text",
155
- text: `Interactive visualization: ${payload.standaloneUrl}\n` +
156
- `Open this URL in your browser for a richer results exploration experience. ` +
155
+ text: `Interactive results explorer: [Open results explorer](${payload.standaloneUrl})\n` +
156
+ `AGENT: surface this to the user as a clickable markdown link (e.g. "[Open results explorer](${payload.standaloneUrl})") in your reply do not leave it buried in tool output. ` +
157
157
  `This localhost port is assigned per MCP session and changes if the proxy restarts — if the page won't load, re-run results_explorer for a fresh URL, or set BARIVIA_VIZ_PORT in your MCP env for a persistent port.`,
158
158
  });
159
159
  }
@@ -9,7 +9,7 @@ Configure \`BARIVIA_API_KEY\` and optional \`BARIVIA_API_URL\`, then call **guid
9
9
 
10
10
  **Parameter hints:** call \`training_guidance\` (also API-scoped). **Async:** poll \`jobs(action=status)\` every 10–15s after submit.`;
11
11
  export function registerGuideBarsomTool(server) {
12
- registerAuditedTool(server, "guide_barsom_workflow", "Plan-scoped orientation: proxy model, tool categories, async rules, training modes, and step-by-step SOP — loaded from the Barivia API when online. Call at the start of mapping work. Offline: short stub. For field-level parameters, use training_guidance; for a narrative pre-train checklist, use the prepare_training prompt or training_prep.", {}, async () => {
12
+ registerAuditedTool(server, "guide_barsom_workflow", "Plan-scoped orientation: proxy model, tool categories, async rules, training modes, and step-by-step SOP — loaded from the Barivia API when online. Call at the start of mapping work. Offline: short stub. For field-level parameters, use training_guidance; for a narrative pre-train checklist, use the prepare_training prompt.", {}, async () => {
13
13
  const md = await fetchWorkflowGuideFromApi();
14
14
  if (md) {
15
15
  const text = "Plan-scoped workflow (from Barivia API). Text below reflects your API key / plan.\n\n" + md;
@@ -1,8 +1,7 @@
1
1
  /**
2
2
  * Shared training surface for the barsom proxy: the Zod input schema for training
3
3
  * parameters, the param-building helper, and preset fetch. Declared once here so
4
- * the `train` tool, the deprecated `jobs(train_*)` wrappers, and `training_prep`
5
- * all reuse the same definitions (no drift).
4
+ * the `train` tool reuses a single set of definitions (no drift).
6
5
  */
7
6
  import { z } from "zod";
8
7
  import { apiCall } from "../shared.js";
@@ -12,7 +11,7 @@ export async function fetchTrainingPresets() {
12
11
  }
13
12
  /**
14
13
  * Fetch presets + the plan-scoped allowed_job_types in one /v1/training/config call.
15
- * Used by training_prep to filter the train-action selector to entitled modes.
14
+ * Used to scope train-action selection to entitled modes.
16
15
  */
17
16
  export async function fetchTrainingConfig() {
18
17
  const configData = (await apiCall("GET", "/v1/training/config"));
@@ -129,8 +128,8 @@ export const TRAINING_INPUT_SCHEMA = {
129
128
  anchor_percentile: z.preprocess((v) => (v !== undefined && v !== null && typeof v === "string") ? parseFloat(v) : v, z.number().optional()),
130
129
  };
131
130
  /**
132
- * Build the FLooP-SIOM job params + summary from raw args. Shared single source for
133
- * the `train` tool and `training_prep` so the growing-manifold knobs never drift.
131
+ * Build the FLooP-SIOM job params + summary from raw args. Single source used by
132
+ * the `train` tool so the growing-manifold knobs never drift.
134
133
  * (FLooP has no fixed grid/epochs; it uses topology/max_nodes/effort + growth knobs.)
135
134
  */
136
135
  export function buildFloopParams(args) {
@@ -1,7 +1,7 @@
1
1
  import { registerAuditedTool } from "../audit.js";
2
2
  import { fetchTrainingGuidanceFromApi } from "../shared.js";
3
3
  export function registerTrainingGuidanceTool(server) {
4
- registerAuditedTool(server, "training_guidance", "Structured parameter guidance for training (presets, grid/epochs/batch, model, periodic, SIOM/FLooP fields where your plan allows, categorical baselines, normalization MAD vs SEPD guide). Served from the API and filtered to allowed_job_types. Prep ladder: prepare_training prompt = narrative checklist; this tool = JSON/hints + normalization decision ladder; training_prep = interactive UI + submit_prepared_training. For full orientation and SOP, call guide_barsom_workflow first. Optional UIs: training_prep, results_explorer—not required; jobs + results suffice.", {}, async () => {
4
+ registerAuditedTool(server, "training_guidance", "Structured parameter guidance for training (presets, grid/epochs/batch, model, periodic, SIOM/FLooP fields where your plan allows, categorical baselines, normalization MAD vs SEPD guide). Served from the API and filtered to allowed_job_types. Prep ladder: prepare_training prompt = narrative checklist; this tool = JSON/hints + normalization decision ladder review, then submit with train. For full orientation and SOP, call guide_barsom_workflow first. Optional UI: results_explorer—not required; jobs + results suffice.", {}, async () => {
5
5
  const text = await fetchTrainingGuidanceFromApi();
6
6
  return { content: [{ type: "text", text }] };
7
7
  });
@@ -96,7 +96,8 @@ export function registerTrainingMonitorTool(server) {
96
96
  if (!getClientSupportsMcpApps() && standaloneUrl) {
97
97
  content.push({
98
98
  type: "text",
99
- text: `Open in browser (best kept open during training): ${standaloneUrl}\n` +
99
+ text: `Live training monitor: [Open training monitor](${standaloneUrl})\n` +
100
+ `AGENT: surface this to the user as a clickable markdown link (e.g. "[Open training monitor](${standaloneUrl})") in your reply — do not leave it buried in tool output. Re-post the link after the job completes so the user can return to the curves.\n` +
100
101
  `This localhost port is assigned per MCP session and changes if the proxy restarts — if the page stays at "running 0%" or stops updating, the link is stale: re-run training_monitor for a fresh URL, or set BARIVIA_VIZ_PORT in your MCP env for a persistent port. Health check: http://localhost:${port}/api/health?job_id=${encodeURIComponent(job_id)}`,
101
102
  });
102
103
  }