@barivia/barsom-mcp 0.17.1 → 0.18.1
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 +3 -1
- package/dist/shared.js +3 -2
- package/dist/tools/datasets.js +4 -2
- package/dist/tools/explore_map.js +11 -7
- package/dist/tools/training_monitor.js +4 -2
- package/dist/tools/training_prep.js +2 -1
- package/dist/views/src/views/results-explorer/index.html +12 -12
- package/dist/views/src/views/training-monitor/index.html +12 -12
- package/dist/viz-server.js +36 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ MCP clients typically run it with **`npx`** (downloads on first use):
|
|
|
43
43
|
| `BARIVIA_API_URL` | No | `https://api.barivia.se` | API base URL |
|
|
44
44
|
| `BARIVIA_WORKSPACE_ROOT` | No | `process.cwd()` or `PWD` | Directory for relative `file_path` and `save_to_disk`. In Cursor MCP, `process.cwd()` is often the MCP install dir — add `BARIVIA_WORKSPACE_ROOT` to your MCP config `env` with your project path (e.g. `/home/user/myproject`). Absolute paths and `file://` URIs work without it. |
|
|
45
45
|
| `BARIVIA_FETCH_TIMEOUT_MS` | No | `60000` | Per-request HTTP timeout (ms) to the API. Increase (e.g. `120000`) on slow networks or when the API does long-running work. Large dataset uploads use a separate longer timeout internally, and `datasets(analyze)` runs asynchronously (auto-polled) so it is not bound by this. A timeout is not auto-retried (re-firing slow work would only multiply load / risk duplicates). |
|
|
46
|
-
| `BARIVIA_VIZ_PORT` | No | OS-assigned | When the client has no MCP Apps support, the proxy may start a local viz server on `127.0.0.1
|
|
46
|
+
| `BARIVIA_VIZ_PORT` | No | OS-assigned | When the client has no MCP Apps support, the proxy may start a local viz server on `127.0.0.1`. The port is **assigned per MCP session and changes when the proxy restarts**, so standalone `…/viz/…` URLs from a previous session go stale (the page then can't reach `/api/*` and shows a "stale session — re-run the tool" message). Set a fixed port for stable bookmark URLs. Diagnostic: `GET http://127.0.0.1:<port>/api/health?job_id=<id>` reports the port, API reachability, and the job's status. |
|
|
47
47
|
| `BARIVIA_ENFORCE_WORKSPACE_SANDBOX` | No | `1` (enabled) | File uploads are constrained to the MCP workspace root by default. Set to `0` or `false` to allow absolute paths anywhere on the machine (high trust). **Changed in v0.x:** previously defaulted to off; now on for security. If uploads fail with "paths outside the workspace are disabled", either set `BARIVIA_WORKSPACE_ROOT` to cover your data directory, or opt out with `BARIVIA_ENFORCE_WORKSPACE_SANDBOX=0`. |
|
|
48
48
|
|
|
49
49
|
Legacy `BARSOM_API_KEY` / `BARSOM_API_URL` / `BARSOM_WORKSPACE_ROOT` are also accepted as fallbacks.
|
|
@@ -228,6 +228,8 @@ MCP Client (Cursor/Claude) ←stdio→ @barivia/barsom-mcp ←HTTPS→ api.bariv
|
|
|
228
228
|
| `Path must be within the workspace` / upload can’t find file | Set `BARIVIA_WORKSPACE_ROOT` to your project directory, or use an absolute path / `file:///...` URI. |
|
|
229
229
|
| Job stuck “running” | Poll `jobs(action=status)` every 10–15s; large grids or FLooP-SIOM can take several minutes—not an MCP error. Staged datasets enqueue **`prepare_training_matrix`** (or impute prepare) first — train submit returns `prepare_job_id`; MCP auto-polls prepare when present. CFD mesh submit may return `prepare_job_id` for **`cfd_prepare`** (barmesh auto-polls). |
|
|
230
230
|
| `429` | Rate limit—wait and retry. |
|
|
231
|
+
| Standalone `…/viz/…` page stuck at "running 0%" or "Loading…" | The link is stale: the viz port is assigned per MCP session and changes when the proxy restarts. Re-run `training_monitor` / `results_explorer` for a fresh URL, or set `BARIVIA_VIZ_PORT` for a persistent port. Confirm with `GET /api/health?job_id=<id>`. |
|
|
232
|
+
| Embedded results explorer: switching figures shows nothing | Fixed in `0.18.0` — earlier versions pointed embedded figures at a localhost URL the webview can't load. Update the package; the embedded view now lazy-loads figures over the MCP App bridge. |
|
|
231
233
|
| Malformed MCP / client errors | Ensure nothing writes to **stdout** except MCP JSON-RPC (the proxy logs API traffic to **stderr** only). |
|
|
232
234
|
|
|
233
235
|
## Development
|
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.
|
|
29
|
+
export const CLIENT_VERSION = "0.18.1";
|
|
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.
|
|
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. */
|
package/dist/tools/datasets.js
CHANGED
|
@@ -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.
|
|
282
|
-
`
|
|
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}`;
|
|
@@ -26,7 +26,12 @@ function buildAvailableFigures(jobId, summary) {
|
|
|
26
26
|
const files = (summary.files ?? []).filter((file) => /\.(png|pdf|svg)$/i.test(file));
|
|
27
27
|
const fallback = getResultsImagesToFetch(jobType, summary, "default", false);
|
|
28
28
|
const figureFiles = files.length > 0 ? files : fallback;
|
|
29
|
-
|
|
29
|
+
// NOTE: this payload feeds the *embedded* MCP App view, which runs in a
|
|
30
|
+
// sandboxed webview that cannot load a localhost http asset. So we never set
|
|
31
|
+
// a `url` here — the App lazy-loads each raster as base64 through the
|
|
32
|
+
// `_fetch_figure` server-tool bridge (the default figure also arrives as a
|
|
33
|
+
// base64 image via the tool result). The standalone browser page builds its
|
|
34
|
+
// own relative-URL payload separately (see views/results-explorer/app.ts).
|
|
30
35
|
return figureFiles.map((filename) => {
|
|
31
36
|
const base = filename.replace(/\.(png|pdf|svg)$/i, "");
|
|
32
37
|
const featureName = base.startsWith("component_")
|
|
@@ -40,7 +45,6 @@ function buildAvailableFigures(jobId, summary) {
|
|
|
40
45
|
kind: base.startsWith("component_") ? "component" : base === "combined" ? "summary" : "diagnostic",
|
|
41
46
|
featureName,
|
|
42
47
|
caption: getCaptionForImage(filename) || (!isRaster ? "This figure is available for download, but it is not inline-displayable in this first iteration." : undefined),
|
|
43
|
-
url: port && isRaster ? `http://localhost:${port}/api/results/${jobId}/image/${filename}` : undefined,
|
|
44
48
|
};
|
|
45
49
|
});
|
|
46
50
|
}
|
|
@@ -96,7 +100,7 @@ function buildMetrics(summary) {
|
|
|
96
100
|
{ label: "Features", value: features },
|
|
97
101
|
];
|
|
98
102
|
}
|
|
99
|
-
function buildPayload(jobId, data) {
|
|
103
|
+
export function buildPayload(jobId, data) {
|
|
100
104
|
const summary = (data.summary ?? {});
|
|
101
105
|
const figures = buildAvailableFigures(jobId, summary);
|
|
102
106
|
const grid = summary.grid ?? [];
|
|
@@ -117,9 +121,7 @@ function buildPayload(jobId, data) {
|
|
|
117
121
|
metrics,
|
|
118
122
|
highlights,
|
|
119
123
|
availableFigures: figures,
|
|
120
|
-
defaultFigureKey: figures.find((figure) => figure.key === "combined"
|
|
121
|
-
?? figures.find((figure) => Boolean(figure.url))?.key
|
|
122
|
-
?? figures.find((figure) => figure.key === "combined")?.key
|
|
124
|
+
defaultFigureKey: figures.find((figure) => figure.key === "combined")?.key
|
|
123
125
|
?? figures[0]?.key,
|
|
124
126
|
standaloneUrl: port ? `http://localhost:${port}/viz/results-explorer?mode=standalone&job_id=${jobId}` : undefined,
|
|
125
127
|
};
|
|
@@ -150,7 +152,9 @@ async function handleResultsExplorer(job_id) {
|
|
|
150
152
|
if (!getClientSupportsMcpApps() && payload.standaloneUrl) {
|
|
151
153
|
content.push({
|
|
152
154
|
type: "text",
|
|
153
|
-
text: `Interactive
|
|
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
|
+
`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.`,
|
|
154
158
|
});
|
|
155
159
|
}
|
|
156
160
|
return structuredTextResult(payload, undefined, content);
|
|
@@ -54,7 +54,7 @@ async function enrichWithTrainingLog(job_id, data) {
|
|
|
54
54
|
export function registerTrainingMonitorTool(server) {
|
|
55
55
|
registerAppTool(server, "training_monitor", {
|
|
56
56
|
title: "Training Monitor",
|
|
57
|
-
description: "Optional embedded or standalone view of training progress for a job_id. When embedded in a client that supports MCP Apps, the panel auto-refreshes every 5s until the job completes: live QE/TE learning curves plus a per-epoch hit-distribution heatmap (sampled BMU counts across the map, showing where observations are landing as training proceeds). A standalone browser URL is also available. The same scalar fields are available via jobs(action=status)—not required to complete training or read results.",
|
|
57
|
+
description: "Optional embedded or standalone view of training progress for a job_id. When embedded in a client that supports MCP Apps, the panel auto-refreshes every 5s until the job completes: live QE/TE learning curves plus a per-epoch hit-distribution heatmap (sampled BMU counts across the map, showing where observations are landing as training proceeds). A standalone browser URL is also available — its localhost port is per MCP session and goes stale if the proxy restarts (set BARIVIA_VIZ_PORT for a persistent port; re-run this tool for a fresh link). The same scalar fields are available via jobs(action=status)—not required to complete training or read results.",
|
|
58
58
|
inputSchema: {
|
|
59
59
|
job_id: z.string().describe("Training job ID to monitor"),
|
|
60
60
|
fetch_training_log: z
|
|
@@ -96,7 +96,9 @@ export function registerTrainingMonitorTool(server) {
|
|
|
96
96
|
if (!getClientSupportsMcpApps() && standaloneUrl) {
|
|
97
97
|
content.push({
|
|
98
98
|
type: "text",
|
|
99
|
-
text: `
|
|
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` +
|
|
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)}`,
|
|
100
102
|
});
|
|
101
103
|
}
|
|
102
104
|
return structuredTextResult(structuredContent, text, content);
|
|
@@ -481,7 +481,8 @@ function buildTrainingPrepContent(payload) {
|
|
|
481
481
|
if (!getClientSupportsMcpApps() && payload.standaloneUrl) {
|
|
482
482
|
content.push({
|
|
483
483
|
type: "text",
|
|
484
|
-
text: `Interactive review: ${payload.standaloneUrl}\
|
|
484
|
+
text: `Interactive training prep review: [Open training prep](${payload.standaloneUrl})\n` +
|
|
485
|
+
`AGENT: surface this to the user as a clickable markdown link (e.g. "[Open training prep](${payload.standaloneUrl})") in your reply — do not leave it buried in tool output. The user opens it to review and submit the prepared job.`,
|
|
485
486
|
});
|
|
486
487
|
}
|
|
487
488
|
return content;
|