@barivia/barsom-mcp 0.5.9 → 0.6.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 +15 -4
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/views/src/views/data-preview/index.html +24 -13
- package/dist/views/src/views/map-explorer/index.html +11 -11
- package/dist/views/src/views/training-monitor/index.html +11 -11
- package/dist/viz-server.d.ts +16 -0
- package/dist/viz-server.d.ts.map +1 -0
- package/dist/viz-server.js +161 -0
- package/dist/viz-server.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local HTTP server for MCP App views when the client does not support MCP Apps.
|
|
3
|
+
* Serves built HTML at /viz/:viewName and proxies API data at /api/results/:jobId and
|
|
4
|
+
* /api/results/:jobId/image/:filename. Bind to 127.0.0.1 only; port from BARIVIA_VIZ_PORT or 0.
|
|
5
|
+
*/
|
|
6
|
+
export type ApiCallFn = (method: "GET" | "POST" | "DELETE", path: string, body?: unknown, extraHeaders?: Record<string, string>) => Promise<unknown>;
|
|
7
|
+
export type ApiRawCallFn = (path: string) => Promise<{
|
|
8
|
+
data: Buffer;
|
|
9
|
+
contentType: string;
|
|
10
|
+
}>;
|
|
11
|
+
export type LoadViewHtmlFn = (viewName: string) => Promise<string | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Start the local viz HTTP server. Returns the port (from BARIVIA_VIZ_PORT or OS-assigned).
|
|
14
|
+
*/
|
|
15
|
+
export declare function startVizServer(apiCall: ApiCallFn, apiRawCall: ApiRawCallFn, loadViewHtml: LoadViewHtmlFn): Promise<number>;
|
|
16
|
+
//# sourceMappingURL=viz-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viz-server.d.ts","sourceRoot":"","sources":["../src/viz-server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH,MAAM,MAAM,SAAS,GAAG,CACtB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,EACjC,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,OAAO,EACd,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAClC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE5F,MAAM,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAE1E;;GAEG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,SAAS,EAClB,UAAU,EAAE,YAAY,EACxB,YAAY,EAAE,cAAc,GAC3B,OAAO,CAAC,MAAM,CAAC,CAqJjB"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local HTTP server for MCP App views when the client does not support MCP Apps.
|
|
3
|
+
* Serves built HTML at /viz/:viewName and proxies API data at /api/results/:jobId and
|
|
4
|
+
* /api/results/:jobId/image/:filename. Bind to 127.0.0.1 only; port from BARIVIA_VIZ_PORT or 0.
|
|
5
|
+
*/
|
|
6
|
+
import http from "node:http";
|
|
7
|
+
const ID_REGEX = /^[a-zA-Z0-9_-]+$/;
|
|
8
|
+
const FILENAME_REGEX = /^[a-zA-Z0-9_.-]+$/;
|
|
9
|
+
const ALLOWED_VIEWS = new Set(["map-explorer", "data-preview", "training-monitor"]);
|
|
10
|
+
const CORS_HEADERS = {
|
|
11
|
+
"Access-Control-Allow-Origin": "*",
|
|
12
|
+
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
|
|
13
|
+
"Access-Control-Allow-Headers": "Content-Type",
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Start the local viz HTTP server. Returns the port (from BARIVIA_VIZ_PORT or OS-assigned).
|
|
17
|
+
*/
|
|
18
|
+
export function startVizServer(apiCall, apiRawCall, loadViewHtml) {
|
|
19
|
+
const portOverride = process.env.BARIVIA_VIZ_PORT;
|
|
20
|
+
const port = portOverride ? parseInt(portOverride, 10) : 0;
|
|
21
|
+
if (portOverride && (Number.isNaN(port) || port < 0 || port > 65535)) {
|
|
22
|
+
return Promise.reject(new Error(`Invalid BARIVIA_VIZ_PORT: ${portOverride}`));
|
|
23
|
+
}
|
|
24
|
+
const server = http.createServer(async (req, res) => {
|
|
25
|
+
const url = new URL(req.url ?? "/", `http://127.0.0.1`);
|
|
26
|
+
const pathname = url.pathname;
|
|
27
|
+
const send = (status, body, contentType) => {
|
|
28
|
+
res.writeHead(status, { "Content-Type": contentType, ...CORS_HEADERS });
|
|
29
|
+
res.end(body);
|
|
30
|
+
};
|
|
31
|
+
const sendJson = (status, data) => {
|
|
32
|
+
res.writeHead(status, { "Content-Type": "application/json", ...CORS_HEADERS });
|
|
33
|
+
res.end(JSON.stringify(data));
|
|
34
|
+
};
|
|
35
|
+
if (req.method === "OPTIONS") {
|
|
36
|
+
res.writeHead(204, CORS_HEADERS);
|
|
37
|
+
res.end();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// GET /viz/:viewName
|
|
41
|
+
const vizMatch = pathname.match(/^\/viz\/([^/]+)$/);
|
|
42
|
+
if (req.method === "GET" && vizMatch) {
|
|
43
|
+
const viewName = vizMatch[1];
|
|
44
|
+
if (!ALLOWED_VIEWS.has(viewName)) {
|
|
45
|
+
send(404, "Not found", "text/plain");
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const html = await loadViewHtml(viewName);
|
|
49
|
+
if (!html) {
|
|
50
|
+
send(404, "View not built. Run: npm run build:views", "text/plain");
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
send(200, html, "text/html; charset=utf-8");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
// GET /api/results/:jobId
|
|
57
|
+
const resultsMatch = pathname.match(/^\/api\/results\/([^/]+)$/);
|
|
58
|
+
if (req.method === "GET" && resultsMatch) {
|
|
59
|
+
const jobId = resultsMatch[1];
|
|
60
|
+
if (!ID_REGEX.test(jobId)) {
|
|
61
|
+
sendJson(400, { error: "Invalid job_id" });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const data = await apiCall("GET", `/v1/results/${jobId}`);
|
|
66
|
+
sendJson(200, data);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
const status = err?.httpStatus ?? 500;
|
|
70
|
+
const message = err instanceof Error ? err.message : "Request failed";
|
|
71
|
+
sendJson(status, { error: message });
|
|
72
|
+
}
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// GET /api/results/:jobId/image/:filename
|
|
76
|
+
const imageMatch = pathname.match(/^\/api\/results\/([^/]+)\/image\/([^/]+)$/);
|
|
77
|
+
if (req.method === "GET" && imageMatch) {
|
|
78
|
+
const [, jobId, filename] = imageMatch;
|
|
79
|
+
if (!ID_REGEX.test(jobId) || !FILENAME_REGEX.test(filename)) {
|
|
80
|
+
sendJson(400, { error: "Invalid job_id or filename" });
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const { data, contentType } = await apiRawCall(`/v1/results/${jobId}/image/${filename}`);
|
|
85
|
+
res.writeHead(200, { "Content-Type": contentType, ...CORS_HEADERS });
|
|
86
|
+
res.end(data);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
sendJson(404, { error: "Image not found" });
|
|
90
|
+
}
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// GET /api/jobs/:jobId (for training-monitor polling)
|
|
94
|
+
const jobMatch = pathname.match(/^\/api\/jobs\/([^/]+)$/);
|
|
95
|
+
if (req.method === "GET" && jobMatch) {
|
|
96
|
+
const jobId = jobMatch[1];
|
|
97
|
+
if (!ID_REGEX.test(jobId)) {
|
|
98
|
+
sendJson(400, { error: "Invalid job_id" });
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
try {
|
|
102
|
+
const data = await apiCall("GET", `/v1/jobs/${jobId}`);
|
|
103
|
+
sendJson(200, data);
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
const status = err?.httpStatus ?? 500;
|
|
107
|
+
const message = err instanceof Error ? err.message : "Request failed";
|
|
108
|
+
sendJson(status, { error: message });
|
|
109
|
+
}
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
// POST /api/jobs/:jobId/cancel (for training-monitor cancel)
|
|
113
|
+
const cancelMatch = pathname.match(/^\/api\/jobs\/([^/]+)\/cancel$/);
|
|
114
|
+
if (req.method === "POST" && cancelMatch) {
|
|
115
|
+
const jobId = cancelMatch[1];
|
|
116
|
+
if (!ID_REGEX.test(jobId)) {
|
|
117
|
+
sendJson(400, { error: "Invalid job_id" });
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
const data = await apiCall("POST", `/v1/jobs/${jobId}/cancel`, {});
|
|
122
|
+
sendJson(200, data);
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
const status = err?.httpStatus ?? 500;
|
|
126
|
+
const message = err instanceof Error ? err.message : "Request failed";
|
|
127
|
+
sendJson(status, { error: message });
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// GET /api/datasets/:datasetId/preview (for data-preview standalone; query e.g. n_rows=10)
|
|
132
|
+
const previewMatch = pathname.match(/^\/api\/datasets\/([^/]+)\/preview$/);
|
|
133
|
+
if (req.method === "GET" && previewMatch) {
|
|
134
|
+
const datasetId = previewMatch[1];
|
|
135
|
+
if (!ID_REGEX.test(datasetId)) {
|
|
136
|
+
sendJson(400, { error: "Invalid dataset_id" });
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
const qs = url.search || "?n_rows=10";
|
|
141
|
+
const data = await apiCall("GET", `/v1/datasets/${datasetId}/preview${qs}`);
|
|
142
|
+
sendJson(200, data);
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
const status = err?.httpStatus ?? 500;
|
|
146
|
+
const message = err instanceof Error ? err.message : "Request failed";
|
|
147
|
+
sendJson(status, { error: message });
|
|
148
|
+
}
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
send(404, "Not found", "text/plain");
|
|
152
|
+
});
|
|
153
|
+
return new Promise((resolve, reject) => {
|
|
154
|
+
server.listen(port, "127.0.0.1", () => {
|
|
155
|
+
const assigned = server.address()?.port;
|
|
156
|
+
resolve(assigned ?? port);
|
|
157
|
+
});
|
|
158
|
+
server.on("error", reject);
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=viz-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viz-server.js","sourceRoot":"","sources":["../src/viz-server.ts"],"names":[],"mappings":"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"}
|