@unovis/mcp 1.7.0-mcp.1 → 1.7.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.
Files changed (130) hide show
  1. package/README.md +3 -2
  2. package/dist/cli.js +7 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/codegen/index.js +23 -8
  5. package/dist/codegen/index.js.map +1 -1
  6. package/dist/html/document.d.ts +16 -3
  7. package/dist/html/document.js +50 -20
  8. package/dist/html/document.js.map +1 -1
  9. package/dist/index.d.ts +7 -6
  10. package/dist/index.js +6 -3
  11. package/dist/index.js.map +1 -1
  12. package/dist/recipes/area.d.ts +3 -2
  13. package/dist/recipes/bar.d.ts +4 -3
  14. package/dist/recipes/bar.js +4 -1
  15. package/dist/recipes/bar.js.map +1 -1
  16. package/dist/recipes/boxplot.d.ts +3 -2
  17. package/dist/recipes/chord.d.ts +1 -0
  18. package/dist/recipes/choropleth.d.ts +1 -0
  19. package/dist/recipes/donut.d.ts +1 -0
  20. package/dist/recipes/graph.d.ts +1 -0
  21. package/dist/recipes/heatmap.d.ts +1 -0
  22. package/dist/recipes/index.d.ts +2 -0
  23. package/dist/recipes/index.js +3 -0
  24. package/dist/recipes/index.js.map +1 -1
  25. package/dist/recipes/line.d.ts +3 -2
  26. package/dist/recipes/nested-donut.d.ts +1 -0
  27. package/dist/recipes/radial-bar.d.ts +1 -0
  28. package/dist/recipes/sankey.d.ts +1 -0
  29. package/dist/recipes/scatter.d.ts +3 -2
  30. package/dist/recipes/shared.d.ts +6 -10
  31. package/dist/recipes/shared.js +7 -53
  32. package/dist/recipes/shared.js.map +1 -1
  33. package/dist/recipes/timeline.d.ts +1 -0
  34. package/dist/recipes/treemap.d.ts +1 -0
  35. package/dist/render/materialize.d.ts +9 -3
  36. package/dist/render/materialize.js +66 -27
  37. package/dist/render/materialize.js.map +1 -1
  38. package/dist/render/renderer.d.ts +2 -7
  39. package/dist/render/renderer.js +1 -1
  40. package/dist/render/renderer.js.map +1 -1
  41. package/dist/render/spec-schema.d.ts +1180 -0
  42. package/dist/render/spec-schema.js +71 -0
  43. package/dist/render/spec-schema.js.map +1 -0
  44. package/dist/render/spec.d.ts +15 -7
  45. package/dist/render/spec.js +9 -8
  46. package/dist/render/spec.js.map +1 -1
  47. package/dist/render/time-ticks.d.ts +10 -0
  48. package/dist/render/time-ticks.js +56 -0
  49. package/dist/render/time-ticks.js.map +1 -0
  50. package/dist/server.js +12 -3
  51. package/dist/server.js.map +1 -1
  52. package/dist/tools/register.d.ts +20 -1
  53. package/dist/tools/register.js +98 -15
  54. package/dist/tools/register.js.map +1 -1
  55. package/dist/widget/bundle.js +470 -465
  56. package/dist/widget/bundle.meta.json +2 -1
  57. package/dist/widget/bundle.standard.js +799 -0
  58. package/dist/widget/entry.d.ts +4 -0
  59. package/dist/widget/entry.js +149 -13
  60. package/dist/widget/entry.js.map +1 -1
  61. package/dist/widget/events.d.ts +25 -0
  62. package/dist/widget/events.js +97 -0
  63. package/dist/widget/events.js.map +1 -0
  64. package/dist/widget/interactions.js +22 -12
  65. package/dist/widget/interactions.js.map +1 -1
  66. package/dist/widget/unpack.d.ts +1 -0
  67. package/dist/widget/unpack.js +1 -0
  68. package/dist/widget/unpack.js.map +1 -0
  69. package/dist/widget/variants.d.ts +14 -0
  70. package/dist/widget/variants.js +22 -0
  71. package/dist/widget/variants.js.map +1 -0
  72. package/docs/README.md +2 -1
  73. package/docs/architecture.md +29 -76
  74. package/docs/chart-spec.md +41 -0
  75. package/docs/getting-started.md +5 -0
  76. package/docs/interactive.md +72 -14
  77. package/docs/output-types.md +9 -9
  78. package/docs/programmatic.md +24 -0
  79. package/docs/tools.md +7 -7
  80. package/docs/troubleshooting.md +14 -44
  81. package/docs/webview.md +83 -0
  82. package/package.json +35 -13
  83. package/schema/chart-spec.v0.1.baseline.json +309 -0
  84. package/schema/chart-spec.v0.1.json +309 -0
  85. package/dist/env/bbox.d.ts +0 -13
  86. package/dist/env/bbox.js +0 -335
  87. package/dist/env/bbox.js.map +0 -1
  88. package/dist/env/canvas.d.ts +0 -9
  89. package/dist/env/canvas.js +0 -55
  90. package/dist/env/canvas.js.map +0 -1
  91. package/dist/env/computed-style.d.ts +0 -38
  92. package/dist/env/computed-style.js +0 -186
  93. package/dist/env/computed-style.js.map +0 -1
  94. package/dist/env/fonts.d.ts +0 -3
  95. package/dist/env/fonts.js +0 -103
  96. package/dist/env/fonts.js.map +0 -1
  97. package/dist/env/index.d.ts +0 -13
  98. package/dist/env/index.js +0 -121
  99. package/dist/env/index.js.map +0 -1
  100. package/dist/env/raf-queue.d.ts +0 -23
  101. package/dist/env/raf-queue.js +0 -51
  102. package/dist/env/raf-queue.js.map +0 -1
  103. package/dist/env/size.d.ts +0 -9
  104. package/dist/env/size.js +0 -30
  105. package/dist/env/size.js.map +0 -1
  106. package/dist/render/headless.d.ts +0 -62
  107. package/dist/render/headless.js +0 -158
  108. package/dist/render/headless.js.map +0 -1
  109. package/dist/render/mutex.d.ts +0 -9
  110. package/dist/render/mutex.js +0 -14
  111. package/dist/render/mutex.js.map +0 -1
  112. package/dist/render/rasterize.d.ts +0 -10
  113. package/dist/render/rasterize.js +0 -29
  114. package/dist/render/rasterize.js.map +0 -1
  115. package/dist/svg/collect-css.d.ts +0 -14
  116. package/dist/svg/collect-css.js +0 -53
  117. package/dist/svg/collect-css.js.map +0 -1
  118. package/dist/svg/css-vars.d.ts +0 -17
  119. package/dist/svg/css-vars.js +0 -64
  120. package/dist/svg/css-vars.js.map +0 -1
  121. package/dist/svg/header.d.ts +0 -8
  122. package/dist/svg/header.js +0 -81
  123. package/dist/svg/header.js.map +0 -1
  124. package/dist/svg/ids.d.ts +0 -12
  125. package/dist/svg/ids.js +0 -94
  126. package/dist/svg/ids.js.map +0 -1
  127. package/dist/svg/postprocess.d.ts +0 -41
  128. package/dist/svg/postprocess.js +0 -135
  129. package/dist/svg/postprocess.js.map +0 -1
  130. package/fonts/README.md +0 -19
@@ -0,0 +1,71 @@
1
+ /** The ChartSpec contract as a zod schema.
2
+ *
3
+ * The TypeScript interface types the IR for this codebase; this schema is the
4
+ * same contract for everyone else — hosts that persist specs, build them by
5
+ * hand, or validate before rendering. `scripts/generate-spec-schema.mjs`
6
+ * emits it as JSON Schema (shipped as `@unovis/mcp/chart-spec.schema.json`),
7
+ * and test/spec-schema.test.ts holds three lines of defense: the emitted file
8
+ * matches this source, every recipe-produced spec validates, and the frozen
9
+ * v1 baseline stays additively compatible.
10
+ */
11
+ import { z } from 'zod';
12
+ import { XY_COMPONENTS, SINGLE_COMPONENTS } from './materialize.js';
13
+ const fieldType = z.enum(['number', 'string', 'date']);
14
+ /** One schema per accessor form so validation errors name the exact shape */
15
+ export const accessorRefSchema = z.union([
16
+ z.object({ $field: z.string(), as: fieldType.optional() }).strict()
17
+ .describe('d => coerce(d[field])'),
18
+ z.object({ $index: z.literal(true) }).strict().describe('(d, i) => i'),
19
+ z.object({ $const: z.unknown() }).strict().describe('() => value'),
20
+ z.object({ $dateTickFormat: z.literal(true) }).strict()
21
+ .describe('Locale-aware date tick formatter'),
22
+ z.object({ $numTickFormat: z.literal(true) }).strict()
23
+ .describe('Locale-aware number tick formatter'),
24
+ z.object({ $lookup: z.array(z.union([z.string(), z.number()])) }).strict()
25
+ .describe('(d, i) => values[i % values.length]'),
26
+ z.object({
27
+ $format: z.object({ field: z.string(), prefix: z.string().optional(), suffix: z.string().optional() }).strict(),
28
+ }).strict().describe('d => prefix + formatNumber(d[field]) + suffix'),
29
+ z.object({
30
+ $mapField: z.object({ field: z.string(), mapping: z.record(z.string(), z.string()), fallback: z.string().optional() }).strict(),
31
+ }).strict().describe('d => mapping[String(d[field])] ?? fallback'),
32
+ ]);
33
+ const axisSchema = z.object({
34
+ label: z.string().optional(),
35
+ gridLine: z.boolean().optional(),
36
+ numTicks: z.number().optional(),
37
+ tickFormat: accessorRefSchema.optional(),
38
+ domainLine: z.boolean().optional(),
39
+ tickTextAngle: z.number().optional(),
40
+ tickValues: z.array(z.number()).optional(),
41
+ }).catchall(z.unknown());
42
+ export const chartSpecSchema = z.object({
43
+ specVersion: z.string().regex(/^\d+\.\d+$/).optional()
44
+ .describe('ChartSpec contract version as major.minor (see SPEC_VERSION). While the major is 0, breaking changes bump the minor; from 1.0 on, minors are additive and only the major breaks'),
45
+ container: z.enum(['xy', 'single']),
46
+ width: z.number().positive(),
47
+ height: z.number().positive(),
48
+ theme: z.enum(['light', 'dark']),
49
+ title: z.string().optional(),
50
+ /** Extra container options — deliberately open: the escape hatch to Unovis
51
+ * config the tool schemas don't expose */
52
+ containerConfig: z.record(z.string(), z.unknown()).optional(),
53
+ components: z.array(z.object({
54
+ type: z.enum([...XY_COMPONENTS, ...SINGLE_COMPONENTS]),
55
+ /** Component config is open for the same reason as containerConfig;
56
+ * accessor descriptors are validated where they appear in typed slots */
57
+ config: z.record(z.string(), z.unknown()),
58
+ }).strict()).min(1),
59
+ xAxis: axisSchema.optional(),
60
+ yAxis: axisSchema.optional(),
61
+ colors: z.array(z.string()).optional(),
62
+ locale: z.string().optional()
63
+ .describe('BCP-47 locale for date/number formatting (default en-US)'),
64
+ legend: z.array(z.object({
65
+ name: z.string(),
66
+ color: z.string().optional(),
67
+ paletteIndex: z.number().int().optional(),
68
+ }).strict()).optional(),
69
+ data: z.unknown(),
70
+ }).strict();
71
+ //# sourceMappingURL=spec-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-schema.js","sourceRoot":"","sources":["../../src/render/spec-schema.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@
6
6
  * generation. Accessors are descriptors referencing data fields by name —
7
7
  * user input is never evaluated as code.
8
8
  */
9
+ import type { LegendItemSpec } from '@unovis/ssr';
9
10
  export type FieldType = 'number' | 'string' | 'date';
10
11
  /** Accessor descriptors (JSON-safe stand-ins for Unovis accessor functions) */
11
12
  export type AccessorRef =
@@ -67,14 +68,19 @@ export interface AxisSpec {
67
68
  tickTextAngle?: number;
68
69
  [key: string]: SpecConfigValue;
69
70
  }
70
- export interface LegendItemSpec {
71
- name: string;
72
- /** Resolved during post-processing when omitted (default palette) */
73
- color?: string;
74
- /** Palette index used when color is not set */
75
- paletteIndex?: number;
76
- }
71
+ export type { LegendItemSpec } from '@unovis/ssr';
72
+ /** Version of the ChartSpec contract, as `major.minor`.
73
+ *
74
+ * While the major is 0 the contract is explicitly unstable: breaking changes
75
+ * are allowed and bump the minor (0.1 → 0.2), each with a freshly frozen
76
+ * schema baseline. Additions never require a bump. Declaring 1.0 is the
77
+ * deliberate act of adopting the additive-only promise — from then on the
78
+ * major moves only on breaking changes. Consumers that persist specs or
79
+ * embed documents compare it via the `unovis:ready` handshake. */
80
+ export declare const SPEC_VERSION = "0.1";
77
81
  export interface ChartSpec {
82
+ /** ChartSpec contract version this spec was written against (see SPEC_VERSION) */
83
+ specVersion?: string;
78
84
  container: 'xy' | 'single';
79
85
  width: number;
80
86
  height: number;
@@ -87,6 +93,8 @@ export interface ChartSpec {
87
93
  yAxis?: AxisSpec;
88
94
  /** Custom palette — overrides --vis-colorN for the whole chart */
89
95
  colors?: string[];
96
+ /** BCP-47 locale for date/number tick and tooltip formatting (default en-US) */
97
+ locale?: string;
90
98
  legend?: LegendItemSpec[];
91
99
  data: unknown;
92
100
  }
@@ -1,15 +1,16 @@
1
- /** ChartSpec — a JSON-serializable intermediate representation of a chart.
2
- *
3
- * Tool inputs are converted to a ChartSpec (recipes), which the renderer
4
- * materializes into live Unovis containers/components. Keeping the IR
5
- * serializable enables the `config` output mode and, later, framework code
6
- * generation. Accessors are descriptors referencing data fields by name —
7
- * user input is never evaluated as code.
8
- */
9
1
  export const isAccessorRef = (value) => {
10
2
  if (typeof value !== 'object' || value === null || Array.isArray(value))
11
3
  return false;
12
4
  const keys = Object.keys(value);
13
5
  return keys.some(k => ['$field', '$index', '$const', '$dateTickFormat', '$numTickFormat', '$lookup', '$format', '$mapField'].includes(k));
14
6
  };
7
+ /** Version of the ChartSpec contract, as `major.minor`.
8
+ *
9
+ * While the major is 0 the contract is explicitly unstable: breaking changes
10
+ * are allowed and bump the minor (0.1 → 0.2), each with a freshly frozen
11
+ * schema baseline. Additions never require a bump. Declaring 1.0 is the
12
+ * deliberate act of adopting the additive-only promise — from then on the
13
+ * major moves only on breaking changes. Consumers that persist specs or
14
+ * embed documents compare it via the `unovis:ready` handshake. */
15
+ export const SPEC_VERSION = '0.1';
15
16
  //# sourceMappingURL=spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/render/spec.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAuBH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAc,EAAwB,EAAE;IACpE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACrF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;AAC3I,CAAC,CAAA"}
1
+ {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/render/spec.ts"],"names":[],"mappings":"AA+BA,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAc,EAAwB,EAAE;IACpE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACrF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;AAC3I,CAAC,CAAA;AAyBD;;;;;;;kEAOkE;AAClE,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAA"}
@@ -0,0 +1,10 @@
1
+ /** Calendar-aligned tick values for time axes — env-free, shared by the
2
+ * recipes (which bake ticks into specs) and the materializer (which derives
3
+ * them when a hand-written spec omits them). */
4
+ /** Calendar-aligned tick values for date axes. Linear-scale ticks land at
5
+ * arbitrary times of day, which the date formatter would render as
6
+ * time-of-day labels ("08:53 AM" on a 3-month chart) — align ticks to
7
+ * month/day/hour/minute boundaries instead. */
8
+ export declare function dateTickValues(min: number, max: number, target?: number): number[] | undefined;
9
+ /** Tick values for a time axis derived from the data extent of a date field */
10
+ export declare function timeTickValuesFromData(data: Record<string, unknown>[], fieldName: string): number[] | undefined;
@@ -0,0 +1,56 @@
1
+ /** Calendar-aligned tick values for time axes — env-free, shared by the
2
+ * recipes (which bake ticks into specs) and the materializer (which derives
3
+ * them when a hand-written spec omits them). */
4
+ const MINUTE = 60_000;
5
+ const HOUR = 60 * MINUTE;
6
+ const DAY = 24 * HOUR;
7
+ /** Calendar-aligned tick values for date axes. Linear-scale ticks land at
8
+ * arbitrary times of day, which the date formatter would render as
9
+ * time-of-day labels ("08:53 AM" on a 3-month chart) — align ticks to
10
+ * month/day/hour/minute boundaries instead. */
11
+ export function dateTickValues(min, max, target = 7) {
12
+ const span = max - min;
13
+ if (!Number.isFinite(span) || span <= 0)
14
+ return undefined;
15
+ const ticks = [];
16
+ if (span >= 60 * DAY) { // month starts
17
+ const stepMonths = Math.max(1, Math.ceil(span / (30 * DAY) / target));
18
+ const start = new Date(min);
19
+ let date = new Date(Date.UTC(start.getUTCFullYear(), start.getUTCMonth(), 1));
20
+ if (date.getTime() < min)
21
+ date = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1, 1));
22
+ while (date.getTime() <= max && ticks.length < 24) {
23
+ ticks.push(date.getTime());
24
+ date = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + stepMonths, 1));
25
+ }
26
+ }
27
+ else {
28
+ // day / hour / minute boundaries (uniform in UTC epoch time)
29
+ const unit = span >= 2 * DAY ? DAY : span >= 2 * HOUR ? HOUR : MINUTE;
30
+ const niceSteps = unit === DAY ? [1, 2, 7, 14] : unit === HOUR ? [1, 2, 3, 6, 12] : [1, 2, 5, 10, 15, 30];
31
+ const rawStep = span / unit / target;
32
+ const step = (niceSteps.find(s => s >= rawStep) ?? Math.ceil(rawStep)) * unit;
33
+ for (let t = Math.ceil(min / step) * step; t <= max && ticks.length < 24; t += step)
34
+ ticks.push(t);
35
+ }
36
+ return ticks.length >= 2 ? ticks : undefined;
37
+ }
38
+ /** Tick values for a time axis derived from the data extent of a date field */
39
+ export function timeTickValuesFromData(data, fieldName) {
40
+ let min = Infinity;
41
+ let max = -Infinity;
42
+ for (const record of data) {
43
+ const raw = record[fieldName];
44
+ if (raw === null || raw === undefined || raw === '')
45
+ continue;
46
+ const time = typeof raw === 'number' ? raw : new Date(String(raw)).getTime();
47
+ if (Number.isNaN(time))
48
+ continue;
49
+ if (time < min)
50
+ min = time;
51
+ if (time > max)
52
+ max = time;
53
+ }
54
+ return dateTickValues(min, max);
55
+ }
56
+ //# sourceMappingURL=time-ticks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time-ticks.js","sourceRoot":"","sources":["../../src/render/time-ticks.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -2,7 +2,7 @@ import { readFileSync } from 'node:fs';
2
2
  import { join, dirname } from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
- import { registerTools, WIDGET_URI } from './tools/register.js';
5
+ import { registerTools, sniffAppsCapability, WIDGET_URI, APPS_MIME_TYPE } from './tools/register.js';
6
6
  import { buildEmbedDocument } from './html/document.js';
7
7
  export function getPackageVersion() {
8
8
  try {
@@ -18,6 +18,12 @@ export function buildServer(options = {}) {
18
18
  name: 'unovis',
19
19
  version: getPackageVersion(),
20
20
  });
21
+ // Sniff the MCP Apps capability from the raw initialize (see register.ts)
22
+ const connect = server.connect.bind(server);
23
+ server.connect = async (transport) => {
24
+ sniffAppsCapability(server, transport);
25
+ await connect(transport);
26
+ };
21
27
  // eslint-disable-next-line @typescript-eslint/no-use-before-define
22
28
  registerWidgetResource(server);
23
29
  registerTools(server, options);
@@ -32,11 +38,14 @@ function registerWidgetResource(server) {
32
38
  server.registerResource('chart-widget', WIDGET_URI, {
33
39
  title: 'Unovis chart widget',
34
40
  description: 'Interactive chart renderer. Send it a chart spec to render.',
35
- mimeType: 'text/html+skybridge',
41
+ mimeType: APPS_MIME_TYPE,
42
+ // Empty CSP allowlists are the point: the widget is fully self-contained
43
+ // (a tested no-network guarantee), so hosts can sandbox it completely
44
+ _meta: { ui: { csp: { connectDomains: [], resourceDomains: [] }, prefersBorder: true } },
36
45
  }, async () => ({
37
46
  contents: [{
38
47
  uri: WIDGET_URI,
39
- mimeType: 'text/html+skybridge',
48
+ mimeType: APPS_MIME_TYPE,
40
49
  text: buildEmbedDocument(),
41
50
  }],
42
51
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAEnE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAE/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAEvD,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAA;QACnF,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,OAAO,CAAA;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAA;IAChB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAE,UAA6B,EAAE;IAC1D,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,iBAAiB,EAAE;KAC7B,CAAC,CAAA;IACF,mEAAmE;IACnE,sBAAsB,CAAC,MAAM,CAAC,CAAA;IAC9B,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;mEAImE;AACnE,SAAS,sBAAsB,CAAE,MAAiB;IAChD,MAAM,CAAC,gBAAgB,CACrB,cAAc,EACd,UAAU,EACV;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,6DAA6D;QAC1E,QAAQ,EAAE,qBAAqB;KAChC,EACD,KAAK,IAAI,EAAE,CAAC,CAAC;QACX,QAAQ,EAAE,CAAC;gBACT,GAAG,EAAE,UAAU;gBACf,QAAQ,EAAE,qBAAqB;gBAC/B,IAAI,EAAE,kBAAkB,EAAE;aAC3B,CAAC;KACH,CAAC,CACH,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAEnE,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpG,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAEvD,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAA;QACnF,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,OAAO,CAAA;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAA;IAChB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAE,UAA6B,EAAE;IAC1D,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,iBAAiB,EAAE;KAC7B,CAAC,CAAA;IACF,0EAA0E;IAC1E,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC3C,MAAM,CAAC,OAAO,GAAG,KAAK,EAAE,SAAS,EAAE,EAAE;QACnC,mBAAmB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;QACtC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAA;IAC1B,CAAC,CAAA;IACD,mEAAmE;IACnE,sBAAsB,CAAC,MAAM,CAAC,CAAA;IAC9B,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;mEAImE;AACnE,SAAS,sBAAsB,CAAE,MAAiB;IAChD,MAAM,CAAC,gBAAgB,CACrB,cAAc,EACd,UAAU,EACV;QACE,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,6DAA6D;QAC1E,QAAQ,EAAE,cAAc;QACxB,yEAAyE;QACzE,sEAAsE;QACtE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE;KACzF,EACD,KAAK,IAAI,EAAE,CAAC,CAAC;QACX,QAAQ,EAAE,CAAC;gBACT,GAAG,EAAE,UAAU;gBACf,QAAQ,EAAE,cAAc;gBACxB,IAAI,EAAE,kBAAkB,EAAE;aAC3B,CAAC;KACH,CAAC,CACH,CAAA;AACH,CAAC"}
@@ -5,8 +5,27 @@ export interface ToolFilterOptions {
5
5
  disabledTools?: string[];
6
6
  /** When set, only these tools are exposed (--tools) */
7
7
  enabledTools?: string[];
8
+ /** Where `outputPath` may write. `undefined` = anywhere (a local stdio
9
+ * server acts with its user's own authority); a directory = only inside
10
+ * it; `false` = file writes disabled. The HTTP transport defaults to
11
+ * `false` — an unauthenticated network endpoint must not double as a
12
+ * remote file-write primitive. */
13
+ writeDir?: string | false;
8
14
  }
9
- /** MCP UI resource the interactive output binds to (registered in server.ts) */
15
+ /** MCP Apps resource the interactive output binds to (registered in server.ts) */
10
16
  export declare const WIDGET_URI = "ui://unovis/chart";
17
+ /** MCP Apps extension (SEP-1865, io.modelcontextprotocol/ui) wire constants.
18
+ * Pinned by tests; keep in sync with the extension spec rather than importing
19
+ * @modelcontextprotocol/ext-apps, whose react peer deps we don't need. */
20
+ export declare const APPS_MIME_TYPE = "text/html;profile=mcp-app";
21
+ export declare const APPS_EXTENSION_ID = "io.modelcontextprotocol/ui";
22
+ /** Enforce the write policy on a requested outputPath. Returns an error
23
+ * message, or undefined when the write is allowed. */
24
+ export declare function refuseWrite(outputPath: string, writeDir: ToolFilterOptions['writeDir']): string | undefined;
11
25
  export declare function activeRecipes(filter?: ToolFilterOptions): AnyRecipe[];
26
+ /** Intercept a transport's onmessage assignment to sniff
27
+ * `capabilities.extensions` from the raw initialize request. Must run BEFORE
28
+ * connect — with an in-memory transport the initialize can arrive in the same
29
+ * microtask the connection is established in. */
30
+ export declare function sniffAppsCapability(server: McpServer, transport: object): void;
12
31
  export declare function registerTools(server: McpServer, filter?: ToolFilterOptions): void;
@@ -1,14 +1,19 @@
1
1
  /** Bind chart recipes to MCP tools. */
2
2
  import { mkdirSync, mkdtempSync, writeFileSync } from 'node:fs';
3
3
  import { tmpdir } from 'node:os';
4
- import { dirname, isAbsolute, join } from 'node:path';
4
+ import { dirname, isAbsolute, join, resolve, sep } from 'node:path';
5
+ import { svgToPng, themeBackground } from '@unovis/ssr';
5
6
  import { recipes } from '../recipes/index.js';
6
7
  import { renderChart, resolveMapMarkers, ChartInputError } from '../render/renderer.js';
7
- import { svgToPng, themeBackground } from '../render/rasterize.js';
8
8
  import { buildChartDocument } from '../html/document.js';
9
9
  import { generateCode, formatGeneratedFiles } from '../codegen/index.js';
10
- /** MCP UI resource the interactive output binds to (registered in server.ts) */
10
+ /** MCP Apps resource the interactive output binds to (registered in server.ts) */
11
11
  export const WIDGET_URI = 'ui://unovis/chart';
12
+ /** MCP Apps extension (SEP-1865, io.modelcontextprotocol/ui) wire constants.
13
+ * Pinned by tests; keep in sync with the extension spec rather than importing
14
+ * @modelcontextprotocol/ext-apps, whose react peer deps we don't need. */
15
+ export const APPS_MIME_TYPE = 'text/html;profile=mcp-app';
16
+ export const APPS_EXTENSION_ID = 'io.modelcontextprotocol/ui';
12
17
  const textResult = (text, isError = false) => ({ content: [{ type: 'text', text }], ...(isError ? { isError: true } : {}) });
13
18
  /** Map data lives behind a `{ $unovisMap }` marker that only the Node renderer
14
19
  * resolves — the browser widget has no map bundles, so bake it into the spec */
@@ -16,17 +21,44 @@ async function specForBrowser(spec) {
16
21
  return { ...spec, components: await resolveMapMarkers(spec.components) };
17
22
  }
18
23
  const chartSummary = (spec) => `${spec.title ?? spec.components.map(c => c.type).join(' + ')} (${spec.width}×${spec.height}, ${spec.theme} theme)`;
19
- async function runRecipe(recipe, input) {
24
+ /** Enforce the write policy on a requested outputPath. Returns an error
25
+ * message, or undefined when the write is allowed. */
26
+ export function refuseWrite(outputPath, writeDir) {
27
+ if (writeDir === undefined)
28
+ return undefined;
29
+ if (writeDir === false) {
30
+ return 'outputPath is disabled on this server — request inline output, or start the server with --allow-write-dir <dir>';
31
+ }
32
+ const dir = resolve(writeDir);
33
+ const target = resolve(outputPath);
34
+ if (target !== dir && !target.startsWith(dir + sep)) {
35
+ return `outputPath must be inside ${dir} on this server, got: ${outputPath}`;
36
+ }
37
+ return undefined;
38
+ }
39
+ /** In an MCP Apps host, every declared tool call renders the widget iframe —
40
+ * so every result must carry the spec, or the frame sits empty next to the
41
+ * answer. Gated on the client capability to keep non-Apps responses lean
42
+ * (the spec embeds the full dataset). */
43
+ async function appsResult(result, spec, appsHost) {
44
+ if (!appsHost)
45
+ return result;
46
+ return {
47
+ ...result,
48
+ structuredContent: { spec: (await specForBrowser(spec)) },
49
+ };
50
+ }
51
+ async function runRecipe(recipe, input, writeDir, appsHost = false) {
20
52
  try {
21
53
  const spec = recipe.toSpec(input);
22
54
  if (input.outputType === 'config') {
23
- return textResult(JSON.stringify(spec, null, 2));
55
+ return appsResult(textResult(JSON.stringify(spec, null, 2)), spec, appsHost);
24
56
  }
25
57
  // Code: emit source for the chosen wrapper. Uses the unresolved spec so
26
58
  // map data stays an import rather than an inlined payload.
27
59
  if (input.outputType === 'code') {
28
60
  const files = generateCode(spec, input.framework ?? 'ts');
29
- return textResult(formatGeneratedFiles(files));
61
+ return appsResult(textResult(formatGeneratedFiles(files)), spec, appsHost);
30
62
  }
31
63
  // Interactive: hand the spec to a UI-capable client, which renders it with
32
64
  // the widget resource. Static content stays in the transcript as a summary.
@@ -35,6 +67,8 @@ async function runRecipe(recipe, input) {
35
67
  return {
36
68
  content: [{ type: 'text', text: `Interactive chart: ${chartSummary(spec)}` }],
37
69
  structuredContent: { spec: browserSpec },
70
+ // Result-level template link kept for pre-MCP-Apps hosts; official
71
+ // hosts key off the tool-level _meta.ui declaration instead
38
72
  _meta: { 'openai/outputTemplate': WIDGET_URI },
39
73
  };
40
74
  }
@@ -45,15 +79,25 @@ async function runRecipe(recipe, input) {
45
79
  if (outputPath && (!isAbsolute(outputPath) || !outputPath.endsWith(extension))) {
46
80
  return textResult(`outputPath must be an absolute path ending in ${extension} (matching outputType), got: ${outputPath}`, true);
47
81
  }
82
+ if (outputPath) {
83
+ const refused = refuseWrite(outputPath, writeDir);
84
+ if (refused)
85
+ return textResult(refused, true);
86
+ }
48
87
  // Self-contained interactive document. Always written to disk: the inlined
49
88
  // widget bundle is far too large to put in a tool result.
50
89
  if (isHtml) {
90
+ // html output IS a file — with writes disabled there is nothing to return
91
+ if (writeDir === false) {
92
+ return textResult('outputType "html" writes a file, which is disabled on this server — use "svg", "png" or "interactive", or start the server with --allow-write-dir <dir>', true);
93
+ }
51
94
  const html = buildChartDocument(await specForBrowser(spec));
52
- const target = outputPath ?? join(mkdtempSync(join(tmpdir(), 'unovis-chart-')), 'chart.html');
95
+ const fallbackDir = typeof writeDir === 'string' ? resolve(writeDir) : tmpdir();
96
+ const target = outputPath ?? join(mkdtempSync(join(fallbackDir, 'unovis-chart-')), 'chart.html');
53
97
  mkdirSync(dirname(target), { recursive: true });
54
98
  writeFileSync(target, html);
55
- return textResult(`Interactive chart saved to ${target} — open it in a browser for tooltips, ` +
56
- `crosshair and hover highlighting. ${chartSummary(spec)}`);
99
+ return appsResult(textResult(`Interactive chart saved to ${target} — open it in a browser for tooltips, ` +
100
+ `crosshair and hover highlighting. ${chartSummary(spec)}`), spec, appsHost);
57
101
  }
58
102
  const result = await renderChart(spec);
59
103
  const warningsNote = result.warnings.length ? ` (warnings: ${result.warnings.join('; ')})` : '';
@@ -66,21 +110,21 @@ async function runRecipe(recipe, input) {
66
110
  if (outputPath) {
67
111
  mkdirSync(dirname(outputPath), { recursive: true });
68
112
  writeFileSync(outputPath, png);
69
- return textResult(`Chart saved to ${outputPath} (${result.width}×${result.height} at ${input.scale ?? 2}x)${warningsNote}`);
113
+ return appsResult(textResult(`Chart saved to ${outputPath} (${result.width}×${result.height} at ${input.scale ?? 2}x)${warningsNote}`), spec, appsHost);
70
114
  }
71
- return {
115
+ return appsResult({
72
116
  content: [
73
117
  { type: 'image', data: png.toString('base64'), mimeType: 'image/png' },
74
118
  ...(warningsNote ? [{ type: 'text', text: warningsNote.trim() }] : []),
75
119
  ],
76
- };
120
+ }, spec, appsHost);
77
121
  }
78
122
  if (outputPath) {
79
123
  mkdirSync(dirname(outputPath), { recursive: true });
80
124
  writeFileSync(outputPath, `<?xml version="1.0" encoding="UTF-8"?>\n${result.svg}`);
81
- return textResult(`Chart saved to ${outputPath} (${result.width}×${result.height})${warningsNote}`);
125
+ return appsResult(textResult(`Chart saved to ${outputPath} (${result.width}×${result.height})${warningsNote}`), spec, appsHost);
82
126
  }
83
- return textResult(result.svg + (result.warnings.length ? `\n<!-- warnings: ${result.warnings.join('; ')} -->` : ''));
127
+ return appsResult(textResult(result.svg + (result.warnings.length ? `\n<!-- warnings: ${result.warnings.join('; ')} -->` : '')), spec, appsHost);
84
128
  }
85
129
  catch (e) {
86
130
  if (e instanceof ChartInputError) {
@@ -94,6 +138,42 @@ export function activeRecipes(filter = {}) {
94
138
  const enabled = filter.enabledTools?.length ? new Set(filter.enabledTools) : undefined;
95
139
  return recipes.filter(r => !disabled.has(r.name) && (!enabled || enabled.has(r.name)));
96
140
  }
141
+ /** Connections whose client advertised the MCP Apps extension.
142
+ *
143
+ * The SDK's ClientCapabilities schema predates SEP-1724, so it strips the
144
+ * `extensions` key during initialize — getClientCapabilities() can never see
145
+ * it (verified end-to-end). Until the SDK learns the field, the raw
146
+ * initialize message is sniffed at the transport seam; the schema path below
147
+ * takes over automatically once it stops returning undefined. */
148
+ const appsClients = new WeakSet();
149
+ /** Intercept a transport's onmessage assignment to sniff
150
+ * `capabilities.extensions` from the raw initialize request. Must run BEFORE
151
+ * connect — with an in-memory transport the initialize can arrive in the same
152
+ * microtask the connection is established in. */
153
+ export function sniffAppsCapability(server, transport) {
154
+ let assigned;
155
+ Object.defineProperty(transport, 'onmessage', {
156
+ configurable: true,
157
+ enumerable: true,
158
+ get: () => assigned,
159
+ set: (handler) => {
160
+ assigned = handler && ((...args) => {
161
+ const message = args[0];
162
+ if (message?.method === 'initialize' && message.params?.capabilities?.extensions?.[APPS_EXTENSION_ID]) {
163
+ appsClients.add(server);
164
+ }
165
+ handler.apply(transport, args);
166
+ });
167
+ },
168
+ });
169
+ }
170
+ /** Did the connected client advertise the MCP Apps extension capability? */
171
+ function appsCapableClient(server) {
172
+ if (appsClients.has(server))
173
+ return true;
174
+ const capabilities = server.server.getClientCapabilities();
175
+ return Boolean(capabilities?.extensions?.[APPS_EXTENSION_ID]);
176
+ }
97
177
  export function registerTools(server, filter = {}) {
98
178
  for (const recipe of activeRecipes(filter)) {
99
179
  server.registerTool(recipe.name, {
@@ -104,9 +184,12 @@ export function registerTools(server, filter = {}) {
104
184
  readOnlyHint: false, // outputPath can write a file
105
185
  openWorldHint: false, // fully local, no network
106
186
  },
187
+ // MCP Apps: the template is declared on the tool, ahead of time, so
188
+ // hosts can prefetch, cache and security-review it before any call
189
+ _meta: { ui: { resourceUri: WIDGET_URI } },
107
190
  },
108
191
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
109
- async (args) => runRecipe(recipe, args));
192
+ async (args) => runRecipe(recipe, args, filter.writeDir, appsCapableClient(server)));
110
193
  }
111
194
  server.registerTool('get_unovis_info', {
112
195
  title: 'Unovis info',
@@ -1 +1 @@
1
- {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/tools/register.ts"],"names":[],"mappings":"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"}