@standby/mcp-server-chart 0.9.10

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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +285 -0
  3. package/build/charts/area.d.ts +41 -0
  4. package/build/charts/area.js +56 -0
  5. package/build/charts/bar.d.ts +41 -0
  6. package/build/charts/bar.js +57 -0
  7. package/build/charts/base.d.ts +30 -0
  8. package/build/charts/base.js +79 -0
  9. package/build/charts/boxplot.d.ts +40 -0
  10. package/build/charts/boxplot.js +50 -0
  11. package/build/charts/column.d.ts +41 -0
  12. package/build/charts/column.js +57 -0
  13. package/build/charts/dual-axes.d.ts +43 -0
  14. package/build/charts/dual-axes.js +59 -0
  15. package/build/charts/fishbone-diagram.d.ts +32 -0
  16. package/build/charts/fishbone-diagram.js +59 -0
  17. package/build/charts/flow-diagram.d.ts +39 -0
  18. package/build/charts/flow-diagram.js +45 -0
  19. package/build/charts/funnel.d.ts +36 -0
  20. package/build/charts/funnel.js +41 -0
  21. package/build/charts/histogram.d.ts +36 -0
  22. package/build/charts/histogram.js +45 -0
  23. package/build/charts/index.d.ts +26 -0
  24. package/build/charts/index.js +52 -0
  25. package/build/charts/line.d.ts +41 -0
  26. package/build/charts/line.js +52 -0
  27. package/build/charts/liquid.d.ts +39 -0
  28. package/build/charts/liquid.js +46 -0
  29. package/build/charts/mind-map.d.ts +30 -0
  30. package/build/charts/mind-map.js +43 -0
  31. package/build/charts/network-graph.d.ts +39 -0
  32. package/build/charts/network-graph.js +45 -0
  33. package/build/charts/organization-chart.d.ts +49 -0
  34. package/build/charts/organization-chart.js +60 -0
  35. package/build/charts/pie.d.ts +37 -0
  36. package/build/charts/pie.js +48 -0
  37. package/build/charts/radar.d.ts +38 -0
  38. package/build/charts/radar.js +49 -0
  39. package/build/charts/sankey.d.ts +43 -0
  40. package/build/charts/sankey.js +47 -0
  41. package/build/charts/scatter.d.ts +39 -0
  42. package/build/charts/scatter.js +47 -0
  43. package/build/charts/treemap.d.ts +44 -0
  44. package/build/charts/treemap.js +59 -0
  45. package/build/charts/venn.d.ts +37 -0
  46. package/build/charts/venn.js +49 -0
  47. package/build/charts/violin.d.ts +40 -0
  48. package/build/charts/violin.js +50 -0
  49. package/build/charts/waterfall.d.ts +44 -0
  50. package/build/charts/waterfall.js +73 -0
  51. package/build/charts/word-cloud.d.ts +36 -0
  52. package/build/charts/word-cloud.js +44 -0
  53. package/build/index.d.ts +2 -0
  54. package/build/index.js +73 -0
  55. package/build/sdk.d.ts +6 -0
  56. package/build/sdk.js +24 -0
  57. package/build/server.d.ts +17 -0
  58. package/build/server.js +151 -0
  59. package/build/services/index.d.ts +3 -0
  60. package/build/services/index.js +9 -0
  61. package/build/services/sse.d.ts +2 -0
  62. package/build/services/sse.js +59 -0
  63. package/build/services/stdio.d.ts +2 -0
  64. package/build/services/stdio.js +21 -0
  65. package/build/services/streamable.d.ts +2 -0
  66. package/build/services/streamable.js +58 -0
  67. package/build/utils/callTool.d.ts +18 -0
  68. package/build/utils/callTool.js +129 -0
  69. package/build/utils/env.d.ts +12 -0
  70. package/build/utils/env.js +38 -0
  71. package/build/utils/generate.d.ts +4 -0
  72. package/build/utils/generate.js +35 -0
  73. package/build/utils/image-server.d.ts +18 -0
  74. package/build/utils/image-server.js +66 -0
  75. package/build/utils/index.d.ts +3 -0
  76. package/build/utils/index.js +9 -0
  77. package/build/utils/local-render.d.ts +17 -0
  78. package/build/utils/local-render.js +121 -0
  79. package/build/utils/logger.d.ts +28 -0
  80. package/build/utils/logger.js +57 -0
  81. package/build/utils/schema.d.ts +4 -0
  82. package/build/utils/schema.js +12 -0
  83. package/build/utils/spec-translator.d.ts +12 -0
  84. package/build/utils/spec-translator.js +515 -0
  85. package/build/utils/validator.d.ts +34 -0
  86. package/build/utils/validator.js +76 -0
  87. package/package.json +66 -0
@@ -0,0 +1,515 @@
1
+ "use strict";
2
+ /**
3
+ * Translates MCP server chart input arguments into @antv/g2 spec format.
4
+ * Each chart type's custom schema is mapped to a G2 declarative spec
5
+ * that can be rendered by @antv/g2-ssr.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.translateToG2Spec = translateToG2Spec;
9
+ /**
10
+ * Translate an MCP chart type + args into a G2 spec.
11
+ * Returns null for unknown chart types.
12
+ */
13
+ function translateToG2Spec(chartType, args) {
14
+ const translator = TRANSLATORS[chartType];
15
+ if (!translator)
16
+ return null;
17
+ return translator(args);
18
+ }
19
+ function applyCommonStyle(spec, args) {
20
+ var _a, _b;
21
+ if (args.title) {
22
+ spec.title = { title: args.title };
23
+ }
24
+ if ((_a = args.style) === null || _a === void 0 ? void 0 : _a.palette) {
25
+ spec.scale = Object.assign(Object.assign({}, spec.scale), { color: { range: args.style.palette } });
26
+ }
27
+ if ((_b = args.style) === null || _b === void 0 ? void 0 : _b.backgroundColor) {
28
+ spec.viewStyle = { viewFill: args.style.backgroundColor };
29
+ }
30
+ }
31
+ function applyAxisTitles(spec, args) {
32
+ if (args.axisXTitle || args.axisYTitle) {
33
+ spec.axis = spec.axis || {};
34
+ if (args.axisXTitle) {
35
+ spec.axis.x = Object.assign(Object.assign({}, (spec.axis.x || {})), { title: args.axisXTitle });
36
+ }
37
+ if (args.axisYTitle) {
38
+ spec.axis.y = Object.assign(Object.assign({}, (spec.axis.y || {})), { title: args.axisYTitle });
39
+ }
40
+ }
41
+ }
42
+ const TRANSLATORS = {
43
+ line: (args) => {
44
+ var _a, _b, _c;
45
+ const hasGroup = (_a = args.data) === null || _a === void 0 ? void 0 : _a.some((d) => d.group);
46
+ const spec = {
47
+ type: "line",
48
+ data: args.data,
49
+ encode: Object.assign({ x: "time", y: "value" }, (hasGroup ? { color: "group" } : {})),
50
+ style: Object.assign({}, (((_b = args.style) === null || _b === void 0 ? void 0 : _b.lineWidth) ? { lineWidth: args.style.lineWidth } : {})),
51
+ };
52
+ if ((_c = args.style) === null || _c === void 0 ? void 0 : _c.startAtZero) {
53
+ spec.scale = { y: { domainMin: 0 } };
54
+ }
55
+ applyCommonStyle(spec, args);
56
+ applyAxisTitles(spec, args);
57
+ return spec;
58
+ },
59
+ area: (args) => {
60
+ var _a, _b;
61
+ const hasGroup = (_a = args.data) === null || _a === void 0 ? void 0 : _a.some((d) => d.group);
62
+ const spec = {
63
+ type: "area",
64
+ data: args.data,
65
+ encode: Object.assign({ x: "time", y: "value" }, (hasGroup ? { color: "group" } : {})),
66
+ style: Object.assign({ fillOpacity: 0.5 }, (((_b = args.style) === null || _b === void 0 ? void 0 : _b.lineWidth) ? { lineWidth: args.style.lineWidth } : {})),
67
+ };
68
+ if (args.stack && hasGroup) {
69
+ spec.transform = [{ type: "stackY" }];
70
+ }
71
+ applyCommonStyle(spec, args);
72
+ applyAxisTitles(spec, args);
73
+ return spec;
74
+ },
75
+ bar: (args) => {
76
+ var _a;
77
+ const hasGroup = (_a = args.data) === null || _a === void 0 ? void 0 : _a.some((d) => d.group);
78
+ const spec = {
79
+ type: "interval",
80
+ data: args.data,
81
+ encode: Object.assign({ x: "category", y: "value" }, (hasGroup ? { color: "group" } : {})),
82
+ coordinate: { transform: [{ type: "transpose" }] },
83
+ };
84
+ if (hasGroup) {
85
+ if (args.group) {
86
+ spec.transform = [{ type: "dodgeX" }];
87
+ }
88
+ else if (args.stack !== false) {
89
+ spec.transform = [{ type: "stackY" }];
90
+ }
91
+ }
92
+ applyCommonStyle(spec, args);
93
+ applyAxisTitles(spec, args);
94
+ return spec;
95
+ },
96
+ column: (args) => {
97
+ var _a;
98
+ const hasGroup = (_a = args.data) === null || _a === void 0 ? void 0 : _a.some((d) => d.group);
99
+ const spec = {
100
+ type: "interval",
101
+ data: args.data,
102
+ encode: Object.assign({ x: "category", y: "value" }, (hasGroup ? { color: "group" } : {})),
103
+ };
104
+ if (hasGroup) {
105
+ if (args.stack) {
106
+ spec.transform = [{ type: "stackY" }];
107
+ }
108
+ else if (args.group !== false) {
109
+ spec.transform = [{ type: "dodgeX" }];
110
+ }
111
+ }
112
+ applyCommonStyle(spec, args);
113
+ applyAxisTitles(spec, args);
114
+ return spec;
115
+ },
116
+ scatter: (args) => {
117
+ var _a;
118
+ const hasGroup = (_a = args.data) === null || _a === void 0 ? void 0 : _a.some((d) => d.group);
119
+ const spec = {
120
+ type: "point",
121
+ data: args.data,
122
+ encode: Object.assign({ x: "x", y: "y" }, (hasGroup ? { color: "group" } : {})),
123
+ };
124
+ applyCommonStyle(spec, args);
125
+ applyAxisTitles(spec, args);
126
+ return spec;
127
+ },
128
+ pie: (args) => {
129
+ const spec = {
130
+ type: "interval",
131
+ data: args.data,
132
+ encode: { y: "value", color: "category" },
133
+ transform: [{ type: "stackY" }],
134
+ coordinate: Object.assign({ type: "theta" }, (args.innerRadius ? { innerRadius: args.innerRadius } : {})),
135
+ legend: { color: { position: "right" } },
136
+ labels: [{ text: "value" }],
137
+ };
138
+ applyCommonStyle(spec, args);
139
+ return spec;
140
+ },
141
+ funnel: (args) => {
142
+ const spec = {
143
+ type: "interval",
144
+ data: args.data,
145
+ encode: { x: "category", y: "value", color: "category", shape: "funnel" },
146
+ transform: [{ type: "symmetryY" }],
147
+ coordinate: { transform: [{ type: "transpose" }] },
148
+ scale: { x: { padding: 0 } },
149
+ axis: false,
150
+ legend: { color: { position: "bottom" } },
151
+ labels: [
152
+ { text: (d) => `${d.category} ${d.value}`, position: "inside" },
153
+ ],
154
+ };
155
+ applyCommonStyle(spec, args);
156
+ return spec;
157
+ },
158
+ radar: (args) => {
159
+ var _a, _b, _c;
160
+ const hasGroup = (_a = args.data) === null || _a === void 0 ? void 0 : _a.some((d) => d.group);
161
+ const children = [];
162
+ if (hasGroup) {
163
+ children.push({
164
+ type: "area",
165
+ encode: { x: "name", y: "value", color: "group" },
166
+ style: { fillOpacity: 0.3 },
167
+ });
168
+ children.push({
169
+ type: "line",
170
+ encode: { x: "name", y: "value", color: "group" },
171
+ style: Object.assign({}, (((_b = args.style) === null || _b === void 0 ? void 0 : _b.lineWidth) ? { lineWidth: args.style.lineWidth } : {})),
172
+ });
173
+ children.push({
174
+ type: "point",
175
+ encode: { x: "name", y: "value", color: "group" },
176
+ });
177
+ }
178
+ else {
179
+ children.push({
180
+ type: "area",
181
+ encode: { x: "name", y: "value" },
182
+ style: Object.assign({ fillOpacity: 0.5 }, (((_c = args.style) === null || _c === void 0 ? void 0 : _c.lineWidth) ? { lineWidth: args.style.lineWidth } : {})),
183
+ });
184
+ children.push({
185
+ type: "line",
186
+ encode: { x: "name", y: "value" },
187
+ });
188
+ }
189
+ const spec = {
190
+ type: "view",
191
+ data: args.data,
192
+ coordinate: { type: "polar" },
193
+ scale: { x: { padding: 0.5, align: 0 } },
194
+ axis: { y: { title: false } },
195
+ children,
196
+ };
197
+ applyCommonStyle(spec, args);
198
+ return spec;
199
+ },
200
+ histogram: (args) => {
201
+ // histogram data is an array of numbers; convert to objects for G2
202
+ const data = args.data.map((v) => ({ value: v }));
203
+ const spec = {
204
+ type: "rect",
205
+ data,
206
+ encode: { x: "value" },
207
+ transform: [
208
+ Object.assign({ type: "binX", y: "count" }, (args.binNumber ? { thresholds: args.binNumber } : {})),
209
+ ],
210
+ };
211
+ applyCommonStyle(spec, args);
212
+ applyAxisTitles(spec, args);
213
+ return spec;
214
+ },
215
+ boxplot: (args) => {
216
+ var _a, _b;
217
+ const hasGroup = (_a = args.data) === null || _a === void 0 ? void 0 : _a.some((d) => d.group);
218
+ const spec = {
219
+ type: "boxplot",
220
+ data: args.data,
221
+ encode: Object.assign({ x: "category", y: "value" }, (hasGroup ? { color: "group" } : { color: "category" })),
222
+ };
223
+ if ((_b = args.style) === null || _b === void 0 ? void 0 : _b.startAtZero) {
224
+ spec.scale = { y: { domainMin: 0 } };
225
+ }
226
+ applyCommonStyle(spec, args);
227
+ applyAxisTitles(spec, args);
228
+ return spec;
229
+ },
230
+ violin: (args) => {
231
+ var _a, _b;
232
+ const hasGroup = (_a = args.data) === null || _a === void 0 ? void 0 : _a.some((d) => d.group);
233
+ const spec = {
234
+ type: "boxplot",
235
+ data: args.data,
236
+ encode: Object.assign({ x: "category", y: "value", shape: "violin" }, (hasGroup ? { color: "group" } : { color: "category" })),
237
+ style: { opacity: 0.5, strokeOpacity: 0.5, point: false },
238
+ };
239
+ if ((_b = args.style) === null || _b === void 0 ? void 0 : _b.startAtZero) {
240
+ spec.scale = { y: { domainMin: 0 } };
241
+ }
242
+ applyCommonStyle(spec, args);
243
+ applyAxisTitles(spec, args);
244
+ return spec;
245
+ },
246
+ waterfall: (args) => {
247
+ var _a;
248
+ // Pre-process waterfall data to compute cumulative start/end
249
+ const waterfallData = [];
250
+ let cumulative = 0;
251
+ for (const item of args.data) {
252
+ if (item.isTotal) {
253
+ waterfallData.push({
254
+ category: item.category,
255
+ start: 0,
256
+ end: cumulative,
257
+ value: cumulative,
258
+ type: "total",
259
+ });
260
+ }
261
+ else if (item.isIntermediateTotal) {
262
+ waterfallData.push({
263
+ category: item.category,
264
+ start: 0,
265
+ end: cumulative,
266
+ value: cumulative,
267
+ type: "total",
268
+ });
269
+ }
270
+ else {
271
+ const start = cumulative;
272
+ cumulative += item.value;
273
+ waterfallData.push({
274
+ category: item.category,
275
+ start,
276
+ end: cumulative,
277
+ value: item.value,
278
+ type: item.value >= 0 ? "positive" : "negative",
279
+ });
280
+ }
281
+ }
282
+ const palette = ((_a = args.style) === null || _a === void 0 ? void 0 : _a.palette) || {};
283
+ const positiveColor = palette.positiveColor || "#FF4D4F";
284
+ const negativeColor = palette.negativeColor || "#2EBB59";
285
+ const totalColor = palette.totalColor || "#1783FF";
286
+ const spec = {
287
+ type: "interval",
288
+ data: waterfallData,
289
+ encode: {
290
+ x: "category",
291
+ y: ["start", "end"],
292
+ color: "type",
293
+ },
294
+ scale: {
295
+ color: {
296
+ domain: ["positive", "negative", "total"],
297
+ range: [positiveColor, negativeColor, totalColor],
298
+ },
299
+ },
300
+ labels: [{ text: "value" }],
301
+ };
302
+ applyCommonStyle(spec, args);
303
+ applyAxisTitles(spec, args);
304
+ return spec;
305
+ },
306
+ liquid: (args) => {
307
+ var _a;
308
+ const spec = {
309
+ type: "liquid",
310
+ data: args.percent,
311
+ style: Object.assign({ shape: args.shape || "circle" }, (((_a = args.style) === null || _a === void 0 ? void 0 : _a.color) ? { fill: args.style.color } : {})),
312
+ };
313
+ applyCommonStyle(spec, args);
314
+ return spec;
315
+ },
316
+ "word-cloud": (args) => {
317
+ const spec = {
318
+ type: "wordCloud",
319
+ data: args.data,
320
+ layout: { spiral: "rectangular" },
321
+ encode: { color: "text" },
322
+ axis: false,
323
+ };
324
+ applyCommonStyle(spec, args);
325
+ return spec;
326
+ },
327
+ venn: (args) => {
328
+ const spec = {
329
+ type: "path",
330
+ data: {
331
+ type: "inline",
332
+ value: args.data,
333
+ transform: [{ type: "venn" }],
334
+ },
335
+ encode: { d: "path", color: "key" },
336
+ style: { fillOpacity: 0.6 },
337
+ labels: [{ text: "label", position: "inside" }],
338
+ };
339
+ applyCommonStyle(spec, args);
340
+ return spec;
341
+ },
342
+ treemap: (args) => {
343
+ // The MCP schema provides an array of tree nodes; G2 expects a single root
344
+ const treeData = args.data.length === 1
345
+ ? args.data[0]
346
+ : { name: "root", children: args.data };
347
+ const spec = {
348
+ type: "treemap",
349
+ data: {
350
+ type: "inline",
351
+ value: treeData,
352
+ },
353
+ layout: { tile: "treemapBinary" },
354
+ encode: { value: "value", color: "name" },
355
+ style: {
356
+ labelText: (d) => { var _a; return ((_a = d.data) === null || _a === void 0 ? void 0 : _a.name) || ""; },
357
+ labelFill: "#000",
358
+ labelFontSize: 12,
359
+ },
360
+ };
361
+ applyCommonStyle(spec, args);
362
+ return spec;
363
+ },
364
+ sankey: (args) => {
365
+ const spec = {
366
+ type: "sankey",
367
+ data: {
368
+ type: "inline",
369
+ value: { links: args.data },
370
+ },
371
+ layout: {
372
+ nodeAlign: args.nodeAlign || "center",
373
+ nodePadding: 0.03,
374
+ },
375
+ style: {
376
+ labelSpacing: 3,
377
+ labelFontWeight: "bold",
378
+ nodeStrokeWidth: 1.2,
379
+ linkFillOpacity: 0.4,
380
+ },
381
+ };
382
+ applyCommonStyle(spec, args);
383
+ return spec;
384
+ },
385
+ "dual-axes": (args) => {
386
+ // Build combined data from categories + series
387
+ const data = [];
388
+ for (let i = 0; i < args.categories.length; i++) {
389
+ const row = { category: args.categories[i] };
390
+ for (let j = 0; j < args.series.length; j++) {
391
+ row[`series_${j}`] = args.series[j].data[i];
392
+ }
393
+ data.push(row);
394
+ }
395
+ const children = args.series.map((s, idx) => {
396
+ const field = `series_${idx}`;
397
+ const child = {
398
+ type: s.type === "column" ? "interval" : "line",
399
+ encode: { x: "category", y: field },
400
+ scale: { y: { independent: true } },
401
+ axis: {
402
+ y: {
403
+ title: s.axisYTitle || "",
404
+ position: idx === 0 ? "left" : "right",
405
+ },
406
+ },
407
+ };
408
+ if (s.type === "line") {
409
+ child.style = { lineWidth: 2 };
410
+ }
411
+ return child;
412
+ });
413
+ const spec = {
414
+ type: "view",
415
+ data,
416
+ children,
417
+ };
418
+ if (args.axisXTitle) {
419
+ spec.axis = { x: { title: args.axisXTitle } };
420
+ }
421
+ applyCommonStyle(spec, args);
422
+ return spec;
423
+ },
424
+ // Graph/diagram types - rendered as force graph in G2 (simplified)
425
+ "network-graph": (args) => {
426
+ const links = args.data.edges.map((e) => ({
427
+ source: e.source,
428
+ target: e.target,
429
+ }));
430
+ const nodes = args.data.nodes.map((n) => ({
431
+ id: n.name,
432
+ }));
433
+ const spec = {
434
+ type: "forceGraph",
435
+ data: {
436
+ type: "inline",
437
+ value: { nodes, links },
438
+ },
439
+ };
440
+ applyCommonStyle(spec, args);
441
+ return spec;
442
+ },
443
+ // Mind map, org chart, flow diagram, fishbone - rendered as tree/force graph
444
+ "mind-map": (args) => {
445
+ // Flatten tree to nodes + links for forceGraph
446
+ const { nodes, links } = flattenTree(args.data);
447
+ const spec = {
448
+ type: "forceGraph",
449
+ data: {
450
+ type: "inline",
451
+ value: { nodes, links },
452
+ },
453
+ };
454
+ applyCommonStyle(spec, args);
455
+ return spec;
456
+ },
457
+ "organization-chart": (args) => {
458
+ const { nodes, links } = flattenTree(args.data);
459
+ const spec = {
460
+ type: "forceGraph",
461
+ data: {
462
+ type: "inline",
463
+ value: { nodes, links },
464
+ },
465
+ };
466
+ applyCommonStyle(spec, args);
467
+ return spec;
468
+ },
469
+ "flow-diagram": (args) => {
470
+ const links = args.data.edges.map((e) => ({
471
+ source: e.source,
472
+ target: e.target,
473
+ }));
474
+ const nodes = args.data.nodes.map((n) => ({
475
+ id: n.name,
476
+ }));
477
+ const spec = {
478
+ type: "forceGraph",
479
+ data: {
480
+ type: "inline",
481
+ value: { nodes, links },
482
+ },
483
+ };
484
+ applyCommonStyle(spec, args);
485
+ return spec;
486
+ },
487
+ "fishbone-diagram": (args) => {
488
+ const { nodes, links } = flattenTree(args.data);
489
+ const spec = {
490
+ type: "forceGraph",
491
+ data: {
492
+ type: "inline",
493
+ value: { nodes, links },
494
+ },
495
+ };
496
+ applyCommonStyle(spec, args);
497
+ return spec;
498
+ },
499
+ };
500
+ /** Flatten a tree structure into nodes and links for forceGraph rendering */
501
+ function flattenTree(root) {
502
+ const nodes = [];
503
+ const links = [];
504
+ function walk(node) {
505
+ nodes.push({ id: node.name });
506
+ if (node.children) {
507
+ for (const child of node.children) {
508
+ links.push({ source: node.name, target: child.name });
509
+ walk(child);
510
+ }
511
+ }
512
+ }
513
+ walk(root);
514
+ return { nodes, links };
515
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The Error class for validation errors in zod.
3
+ */
4
+ export declare class ValidateError extends Error {
5
+ constructor(message: string);
6
+ }
7
+ export type NodeEdgeDataType = {
8
+ nodes: Array<{
9
+ name: string;
10
+ }>;
11
+ edges: Array<{
12
+ name: string;
13
+ source: string;
14
+ target: string;
15
+ }>;
16
+ };
17
+ export type TreeDataType = {
18
+ name: string;
19
+ children?: TreeDataType[];
20
+ };
21
+ /**
22
+ * Valid node name is unique.
23
+ * Valid edge source and target are existing in nodes.
24
+ * Valid edge source edge target pair are unique.
25
+ * @param data
26
+ * @returns boolean
27
+ */
28
+ export declare const validatedNodeEdgeDataSchema: (data: NodeEdgeDataType) => boolean;
29
+ /**
30
+ * Valid TreeData name is unique.
31
+ * @param data
32
+ * @returns boolean
33
+ */
34
+ export declare const validatedTreeDataSchema: (data: TreeDataType) => boolean;
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validatedTreeDataSchema = exports.validatedNodeEdgeDataSchema = exports.ValidateError = void 0;
4
+ /**
5
+ * The Error class for validation errors in zod.
6
+ */
7
+ class ValidateError extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "ValidateError";
11
+ }
12
+ }
13
+ exports.ValidateError = ValidateError;
14
+ /**
15
+ * Valid node name is unique.
16
+ * Valid edge source and target are existing in nodes.
17
+ * Valid edge source edge target pair are unique.
18
+ * @param data
19
+ * @returns boolean
20
+ */
21
+ const validatedNodeEdgeDataSchema = (data) => {
22
+ const nodeNames = new Set(data.nodes.map((node) => node.name));
23
+ const uniqueNodeNames = new Set();
24
+ // 1. valid node name is unique
25
+ for (const node of data.nodes) {
26
+ if (uniqueNodeNames.has(node.name)) {
27
+ throw new ValidateError(`Invalid parameters: node's name '${node.name}' should be unique.`);
28
+ }
29
+ uniqueNodeNames.add(node.name);
30
+ }
31
+ // 2. valid edge source and target are existing in nodes
32
+ for (const edge of data.edges) {
33
+ if (!nodeNames.has(edge.source)) {
34
+ throw new ValidateError(`Invalid parameters: edge's source '${edge.source}' should exist in nodes.`);
35
+ }
36
+ if (!nodeNames.has(edge.target)) {
37
+ throw new ValidateError(`Invalid parameters: edge's target '${edge.target}' should exist in nodes.`);
38
+ }
39
+ }
40
+ // 3. valid edge source edge target pair are unique
41
+ const edgePairs = new Set();
42
+ for (const edge of data.edges) {
43
+ const pair = `${edge.source}-${edge.target}`;
44
+ if (edgePairs.has(pair)) {
45
+ throw new ValidateError(`Invalid parameters: edge pair '${pair}' should be unique.`);
46
+ }
47
+ edgePairs.add(pair);
48
+ }
49
+ return true;
50
+ };
51
+ exports.validatedNodeEdgeDataSchema = validatedNodeEdgeDataSchema;
52
+ /**
53
+ * Valid TreeData name is unique.
54
+ * @param data
55
+ * @returns boolean
56
+ */
57
+ const validatedTreeDataSchema = (data) => {
58
+ const node = data;
59
+ const names = new Set();
60
+ // valid node name is unique
61
+ const checkUniqueness = (currentNode) => {
62
+ if (names.has(currentNode.name)) {
63
+ throw new ValidateError(`Invalid parameters: node's name '${currentNode.name}' should be unique.`);
64
+ }
65
+ names.add(currentNode.name);
66
+ if (currentNode.children) {
67
+ for (let i = 0; i < currentNode.children.length; i++) {
68
+ const child = currentNode.children[i];
69
+ checkUniqueness(child);
70
+ }
71
+ }
72
+ };
73
+ checkUniqueness(node);
74
+ return true;
75
+ };
76
+ exports.validatedTreeDataSchema = validatedTreeDataSchema;
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@standby/mcp-server-chart",
3
+ "description": "A Model Context Protocol server for generating charts using AntV. This is a TypeScript-based MCP server that provides chart generation capabilities. It allows you to create various types of charts through MCP tools.",
4
+ "mcpName": "io.github.standby/mcp-server-chart",
5
+ "version": "0.9.10",
6
+ "main": "build/index.js",
7
+ "types": "build/index.d.ts",
8
+ "exports": {
9
+ "./sdk": "./build/sdk.js"
10
+ },
11
+ "scripts": {
12
+ "prebuild": "rm -rf build/*",
13
+ "build": "tsc && tsc-alias -p tsconfig.json",
14
+ "postbuild": "chmod +x build/index.js",
15
+ "start": "npx @modelcontextprotocol/inspector node build/index.js",
16
+ "prepare": "husky && npm run build",
17
+ "prepublishOnly": "npm run build",
18
+ "test": "vitest"
19
+ },
20
+ "lint-staged": {
21
+ "*.{ts,js,json}": [
22
+ "biome check --write",
23
+ "biome format --write",
24
+ "biome lint"
25
+ ]
26
+ },
27
+ "bin": {
28
+ "mcp-server-chart": "./build/index.js"
29
+ },
30
+ "publishConfig": {
31
+ "registry": "https://registry.npmjs.org/",
32
+ "access": "public"
33
+ },
34
+ "files": ["build"],
35
+ "keywords": ["antv", "mcp", "data-visualization", "chart", "graph", "map"],
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/standby/mcp-server-chart"
39
+ },
40
+ "author": {
41
+ "name": "Stephen",
42
+ "url": "https://github.com/standby/mcp-server-chart"
43
+ },
44
+ "license": "MIT",
45
+ "dependencies": {
46
+ "@antv/g2-ssr": "^0.2.0",
47
+ "@modelcontextprotocol/sdk": "^1.25.2",
48
+ "cors": "^2.8.5",
49
+ "express": "^5.1.0",
50
+ "zod": "^4.3.5"
51
+ },
52
+ "devDependencies": {
53
+ "@biomejs/biome": "1.9.4",
54
+ "@modelcontextprotocol/inspector": "^0.16.6",
55
+ "@types/cors": "^2.8.19",
56
+ "@types/express": "^5.0.3",
57
+ "@types/node": "^22.15.21",
58
+ "@vitest/coverage-v8": "3.2.4",
59
+ "husky": "^9.1.7",
60
+ "lint-staged": "^15.5.2",
61
+ "ts-node": "^10.9.2",
62
+ "tsc-alias": "^1.8.16",
63
+ "typescript": "^5.8.3",
64
+ "vitest": "^3.1.4"
65
+ }
66
+ }