@bonnard/mcp-charts 0.1.3 → 0.2.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 +133 -17
- package/dist/bigquery.d.ts +1 -1
- package/dist/bigquery.js +1 -1
- package/dist/chunk-7MYIOIDH.js +17 -0
- package/dist/chunk-7MYIOIDH.js.map +1 -0
- package/dist/chunk-EZYN3JQ4.js +706 -0
- package/dist/chunk-EZYN3JQ4.js.map +1 -0
- package/dist/{chunk-I3HINKHN.js → chunk-IXRGLZX2.js} +98 -5
- package/dist/chunk-IXRGLZX2.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +512 -0
- package/dist/cli.js.map +1 -0
- package/dist/databricks.d.ts +1 -1
- package/dist/databricks.js +1 -1
- package/dist/duckdb.d.ts +1 -1
- package/dist/duckdb.js +1 -1
- package/dist/fixtures.d.ts +30 -0
- package/dist/fixtures.js +156 -0
- package/dist/fixtures.js.map +1 -0
- package/dist/index.d.ts +119 -35
- package/dist/index.js +260 -713
- package/dist/index.js.map +1 -1
- package/dist/postgres.d.ts +1 -1
- package/dist/postgres.js +1 -1
- package/dist/snowflake.d.ts +1 -1
- package/dist/snowflake.js +1 -1
- package/dist/sql-BYkJnQOP.d.ts +35 -0
- package/dist/{types-6ALzXWjE.d.ts → types-DUKpye7m.d.ts} +63 -1
- package/package.json +8 -1
- package/dist/chunk-I3HINKHN.js.map +0 -1
package/dist/fixtures.js
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolve
|
|
3
|
+
} from "./chunk-EZYN3JQ4.js";
|
|
4
|
+
import {
|
|
5
|
+
buildChartData
|
|
6
|
+
} from "./chunk-IXRGLZX2.js";
|
|
7
|
+
|
|
8
|
+
// src/fixtures/dashboards.ts
|
|
9
|
+
var KIND_BY_TOKEN = {
|
|
10
|
+
string: "string",
|
|
11
|
+
number: "number",
|
|
12
|
+
time: "time",
|
|
13
|
+
boolean: "boolean"
|
|
14
|
+
};
|
|
15
|
+
var mapKind = (type) => KIND_BY_TOKEN[String(type)] ?? "string";
|
|
16
|
+
function buildCellSpec(input) {
|
|
17
|
+
const data = buildChartData({ rows: input.rows, columns: input.columns, mapKind });
|
|
18
|
+
return resolve(data, input.opts);
|
|
19
|
+
}
|
|
20
|
+
function isChartInput(input) {
|
|
21
|
+
return input.kind === "chart";
|
|
22
|
+
}
|
|
23
|
+
function toItem(input) {
|
|
24
|
+
if (isChartInput(input)) {
|
|
25
|
+
return input.span != null ? { spec: buildCellSpec(input), span: input.span } : { spec: buildCellSpec(input) };
|
|
26
|
+
}
|
|
27
|
+
return input;
|
|
28
|
+
}
|
|
29
|
+
function toSpec(inputs) {
|
|
30
|
+
const spec = { items: inputs.items.map(toItem) };
|
|
31
|
+
if (inputs.title != null) spec.title = inputs.title;
|
|
32
|
+
if (inputs.columns != null) spec.columns = inputs.columns;
|
|
33
|
+
if (inputs.notes != null) spec.notes = inputs.notes;
|
|
34
|
+
return spec;
|
|
35
|
+
}
|
|
36
|
+
var col = (name, type) => ({ name, type });
|
|
37
|
+
var chart = (rows, columns, opts, span) => ({ kind: "chart", rows, columns, opts, ...span != null && { span } });
|
|
38
|
+
var barRevenueByStatus = chart(
|
|
39
|
+
[
|
|
40
|
+
{ status: "shipped", revenue: 43700 },
|
|
41
|
+
{ status: "open", revenue: 8400 },
|
|
42
|
+
{ status: "cancelled", revenue: 1450 }
|
|
43
|
+
],
|
|
44
|
+
[col("status", "string"), col("revenue", "number")],
|
|
45
|
+
{ chartType: "bar", title: "Revenue by Status" }
|
|
46
|
+
);
|
|
47
|
+
var lineMonthly = chart(
|
|
48
|
+
[
|
|
49
|
+
{ month: "2026-04-01", revenue: 18e3 },
|
|
50
|
+
{ month: "2026-05-01", revenue: 15500 },
|
|
51
|
+
{ month: "2026-06-01", revenue: 20300 }
|
|
52
|
+
],
|
|
53
|
+
[col("month", "time"), col("revenue", "number")],
|
|
54
|
+
{ chartType: "line", title: "Monthly Revenue" }
|
|
55
|
+
);
|
|
56
|
+
var pieRegion = chart(
|
|
57
|
+
[
|
|
58
|
+
{ region: "EU", revenue: 29300 },
|
|
59
|
+
{ region: "US", revenue: 23e3 },
|
|
60
|
+
{ region: "APAC", revenue: 850 }
|
|
61
|
+
],
|
|
62
|
+
[col("region", "string"), col("revenue", "number")],
|
|
63
|
+
{ chartType: "pie", title: "Revenue by Region" }
|
|
64
|
+
);
|
|
65
|
+
var tableOrders = chart(
|
|
66
|
+
[
|
|
67
|
+
{ id: "o_1001", amount: 4200, status: "shipped" },
|
|
68
|
+
{ id: "o_1003", amount: 900, status: "open" }
|
|
69
|
+
],
|
|
70
|
+
[col("id", "string"), col("amount", "number"), col("status", "string")],
|
|
71
|
+
{ chartType: "table", title: "Orders Sample" }
|
|
72
|
+
);
|
|
73
|
+
var barRegion = chart(
|
|
74
|
+
[
|
|
75
|
+
{ region: "EU", revenue: 29300 },
|
|
76
|
+
{ region: "US", revenue: 23e3 }
|
|
77
|
+
],
|
|
78
|
+
[col("region", "string"), col("revenue", "number")],
|
|
79
|
+
{ chartType: "bar", title: "Revenue by Region" }
|
|
80
|
+
);
|
|
81
|
+
var emptyTable = chart([], [col("label", "string"), col("value", "number")], { chartType: "table" });
|
|
82
|
+
var kpiCurrency = {
|
|
83
|
+
type: "kpi",
|
|
84
|
+
label: "Revenue",
|
|
85
|
+
value: 128400,
|
|
86
|
+
format: "currency",
|
|
87
|
+
currency: "USD",
|
|
88
|
+
delta: 12400,
|
|
89
|
+
caption: "vs last month"
|
|
90
|
+
};
|
|
91
|
+
var kpiPercent = {
|
|
92
|
+
type: "kpi",
|
|
93
|
+
label: "Conversion",
|
|
94
|
+
value: 0.184,
|
|
95
|
+
format: "percent",
|
|
96
|
+
fraction: true,
|
|
97
|
+
delta: -0.021,
|
|
98
|
+
deltaFraction: true
|
|
99
|
+
};
|
|
100
|
+
var kpiPlain = {
|
|
101
|
+
type: "kpi",
|
|
102
|
+
label: "Orders",
|
|
103
|
+
value: 1042,
|
|
104
|
+
caption: "this month"
|
|
105
|
+
};
|
|
106
|
+
var kpiNull = {
|
|
107
|
+
type: "kpi",
|
|
108
|
+
label: "Refunds",
|
|
109
|
+
value: null
|
|
110
|
+
};
|
|
111
|
+
var textIntro = {
|
|
112
|
+
type: "text",
|
|
113
|
+
heading: "Q2 Overview",
|
|
114
|
+
text: "Revenue is up quarter over quarter, led by the EU region.",
|
|
115
|
+
span: 2
|
|
116
|
+
};
|
|
117
|
+
var dashboardFixtures = [
|
|
118
|
+
{
|
|
119
|
+
name: "single-chart",
|
|
120
|
+
...pack({ columns: 1, items: [barRevenueByStatus] })
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: "grid-2x2",
|
|
124
|
+
...pack({ columns: 2, items: [barRegion, lineMonthly, pieRegion, tableOrders] })
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: "kpi-row",
|
|
128
|
+
...pack({ columns: 3, items: [kpiCurrency, kpiPercent, kpiPlain] })
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: "mixed",
|
|
132
|
+
...pack({
|
|
133
|
+
title: "Sales Dashboard",
|
|
134
|
+
columns: 2,
|
|
135
|
+
items: [textIntro, kpiCurrency, kpiPercent, { ...lineMonthly, span: 2 }]
|
|
136
|
+
})
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: "narrow-stacked",
|
|
140
|
+
...pack({ columns: 1, items: [kpiPlain, barRevenueByStatus, lineMonthly] })
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
// Edge cases in one grid: an empty-result chart cell (renders `.empty`) + a null-value KPI
|
|
144
|
+
// (renders a placeholder, not "null").
|
|
145
|
+
name: "degenerate",
|
|
146
|
+
...pack({ columns: 2, items: [emptyTable, kpiNull] })
|
|
147
|
+
}
|
|
148
|
+
];
|
|
149
|
+
function pack(inputs) {
|
|
150
|
+
return { inputs, spec: toSpec(inputs) };
|
|
151
|
+
}
|
|
152
|
+
export {
|
|
153
|
+
buildCellSpec,
|
|
154
|
+
dashboardFixtures
|
|
155
|
+
};
|
|
156
|
+
//# sourceMappingURL=fixtures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/fixtures/dashboards.ts"],"sourcesContent":["// Shared dashboard fixtures. Each carries both INPUTS and the expected OUTPUT `spec`: the widget\n// consumes `spec`; a platform that composes dashboards from SQL reproduces `spec` from `inputs`.\n//\n// Chart-cell specs are computed at module load through the library's own path (buildChartData +\n// resolve), so a fixture is definitionally what core produces and cannot rot against resolve().\n// Fixture names are load-bearing: both repos' tests iterate them by name.\nimport { buildChartData } from \"../adapters/sql.js\";\nimport type { SourceColumn } from \"../adapters/sql.js\";\nimport { resolve } from \"../resolve/resolve.js\";\nimport type {\n ChartSpec,\n DashboardItem,\n DashboardSpec,\n FieldKind,\n KpiTile,\n ResolveOptions,\n TextBlock,\n} from \"../types.js\";\n\n/** Raw inputs for a chart cell: a SQL-shaped result (rows + typed columns) + resolve options. */\nexport interface ChartCellInput {\n kind: \"chart\";\n rows: Record<string, unknown>[];\n columns: SourceColumn[];\n opts: ResolveOptions;\n span?: number;\n}\n\n/** A dashboard-item input: either a chart to be built, or a final KPI/text item. */\nexport type DashboardItemInput = ChartCellInput | KpiTile | TextBlock;\n\n/** Inputs from which a DashboardSpec is (re)producible without hand-authoring chart specs. */\nexport interface DashboardFixtureInputs {\n title?: string;\n columns?: number;\n items: DashboardItemInput[];\n notes?: string[];\n}\n\nexport interface DashboardFixture {\n name: string;\n inputs: DashboardFixtureInputs;\n spec: DashboardSpec;\n}\n\n// Column-type tokens the test mapKind understands. Chart-cell inputs declare these so the fixture\n// spec is built the same way an adapter would build it (typed columns -> buildChartData).\nconst KIND_BY_TOKEN: Record<string, FieldKind> = {\n string: \"string\",\n number: \"number\",\n time: \"time\",\n boolean: \"boolean\",\n};\n\nconst mapKind = (type: unknown): FieldKind => KIND_BY_TOKEN[String(type)] ?? \"string\";\n\n/** Build a ChartCell's ChartSpec through the library path: buildChartData -> resolve. */\nexport function buildCellSpec(input: ChartCellInput): ChartSpec {\n const data = buildChartData({ rows: input.rows, columns: input.columns, mapKind });\n return resolve(data, input.opts);\n}\n\nfunction isChartInput(input: DashboardItemInput): input is ChartCellInput {\n return (input as ChartCellInput).kind === \"chart\";\n}\n\nfunction toItem(input: DashboardItemInput): DashboardItem {\n if (isChartInput(input)) {\n return input.span != null ? { spec: buildCellSpec(input), span: input.span } : { spec: buildCellSpec(input) };\n }\n return input;\n}\n\nfunction toSpec(inputs: DashboardFixtureInputs): DashboardSpec {\n const spec: DashboardSpec = { items: inputs.items.map(toItem) };\n if (inputs.title != null) spec.title = inputs.title;\n if (inputs.columns != null) spec.columns = inputs.columns;\n if (inputs.notes != null) spec.notes = inputs.notes;\n return spec;\n}\n\nconst col = (name: string, type: string): SourceColumn => ({ name, type });\n\nconst chart = (\n rows: Record<string, unknown>[],\n columns: SourceColumn[],\n opts: ResolveOptions,\n span?: number,\n): ChartCellInput => ({ kind: \"chart\", rows, columns, opts, ...(span != null && { span }) });\n\n// --- Reusable chart-cell inputs ---\n\nconst barRevenueByStatus = chart(\n [\n { status: \"shipped\", revenue: 43700 },\n { status: \"open\", revenue: 8400 },\n { status: \"cancelled\", revenue: 1450 },\n ],\n [col(\"status\", \"string\"), col(\"revenue\", \"number\")],\n { chartType: \"bar\", title: \"Revenue by Status\" },\n);\n\nconst lineMonthly = chart(\n [\n { month: \"2026-04-01\", revenue: 18000 },\n { month: \"2026-05-01\", revenue: 15500 },\n { month: \"2026-06-01\", revenue: 20300 },\n ],\n [col(\"month\", \"time\"), col(\"revenue\", \"number\")],\n { chartType: \"line\", title: \"Monthly Revenue\" },\n);\n\nconst pieRegion = chart(\n [\n { region: \"EU\", revenue: 29300 },\n { region: \"US\", revenue: 23000 },\n { region: \"APAC\", revenue: 850 },\n ],\n [col(\"region\", \"string\"), col(\"revenue\", \"number\")],\n { chartType: \"pie\", title: \"Revenue by Region\" },\n);\n\nconst tableOrders = chart(\n [\n { id: \"o_1001\", amount: 4200, status: \"shipped\" },\n { id: \"o_1003\", amount: 900, status: \"open\" },\n ],\n [col(\"id\", \"string\"), col(\"amount\", \"number\"), col(\"status\", \"string\")],\n { chartType: \"table\", title: \"Orders Sample\" },\n);\n\nconst barRegion = chart(\n [\n { region: \"EU\", revenue: 29300 },\n { region: \"US\", revenue: 23000 },\n ],\n [col(\"region\", \"string\"), col(\"revenue\", \"number\")],\n { chartType: \"bar\", title: \"Revenue by Region\" },\n);\n\n// An empty result: buildChartData over zero rows, then resolve as a table (matches the platform's\n// emptyResult table shape for a cell that returned no rows).\nconst emptyTable = chart([], [col(\"label\", \"string\"), col(\"value\", \"number\")], { chartType: \"table\" });\n\n// --- KPI + text item inputs ---\n\nconst kpiCurrency: KpiTile = {\n type: \"kpi\",\n label: \"Revenue\",\n value: 128400,\n format: \"currency\",\n currency: \"USD\",\n delta: 12400,\n caption: \"vs last month\",\n};\n\nconst kpiPercent: KpiTile = {\n type: \"kpi\",\n label: \"Conversion\",\n value: 0.184,\n format: \"percent\",\n fraction: true,\n delta: -0.021,\n deltaFraction: true,\n};\n\nconst kpiPlain: KpiTile = {\n type: \"kpi\",\n label: \"Orders\",\n value: 1042,\n caption: \"this month\",\n};\n\nconst kpiNull: KpiTile = {\n type: \"kpi\",\n label: \"Refunds\",\n value: null,\n};\n\nconst textIntro: TextBlock = {\n type: \"text\",\n heading: \"Q2 Overview\",\n text: \"Revenue is up quarter over quarter, led by the EU region.\",\n span: 2,\n};\n\n// --- The six fixtures ---\n\nexport const dashboardFixtures: DashboardFixture[] = [\n {\n name: \"single-chart\",\n ...pack({ columns: 1, items: [barRevenueByStatus] }),\n },\n {\n name: \"grid-2x2\",\n ...pack({ columns: 2, items: [barRegion, lineMonthly, pieRegion, tableOrders] }),\n },\n {\n name: \"kpi-row\",\n ...pack({ columns: 3, items: [kpiCurrency, kpiPercent, kpiPlain] }),\n },\n {\n name: \"mixed\",\n ...pack({\n title: \"Sales Dashboard\",\n columns: 2,\n items: [textIntro, kpiCurrency, kpiPercent, { ...lineMonthly, span: 2 }],\n }),\n },\n {\n name: \"narrow-stacked\",\n ...pack({ columns: 1, items: [kpiPlain, barRevenueByStatus, lineMonthly] }),\n },\n {\n // Edge cases in one grid: an empty-result chart cell (renders `.empty`) + a null-value KPI\n // (renders a placeholder, not \"null\").\n name: \"degenerate\",\n ...pack({ columns: 2, items: [emptyTable, kpiNull] }),\n },\n];\n\nfunction pack(inputs: DashboardFixtureInputs): { inputs: DashboardFixtureInputs; spec: DashboardSpec } {\n return { inputs, spec: toSpec(inputs) };\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,124 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { A as AxisSpec,
|
|
1
|
+
import { a as ChartSpec, D as DashboardSpec, R as ResolveOptions, F as FieldMeta, E as Encode, C as ChartData, b as ChartCell, c as ChartExplanation, d as ChartContext, e as ChartType } from './types-DUKpye7m.js';
|
|
2
|
+
export { A as AxisSpec, f as ColumnSpec, g as DashboardItem, h as FieldFormat, i as FieldKind, j as FieldRole, K as KpiTile, k as ReferenceLine, S as SeriesSpec, l as Stacking, T as TextBlock, m as TimeGranularity } from './types-DUKpye7m.js';
|
|
3
3
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
export { B as BuildChartDataOptions, C as CellNormalizer, K as KindMapper, S as SourceColumn, a as assertReadOnlySql, b as buildChartData, d as defaultNormalizeCell } from './sql-BYkJnQOP.js';
|
|
6
|
+
|
|
7
|
+
declare function isDashboardSpec(x: unknown): x is DashboardSpec;
|
|
8
|
+
declare function isChartSpec(x: unknown): x is ChartSpec;
|
|
9
|
+
|
|
10
|
+
/** Extra per-cell options layered on top of resolve()'s options. */
|
|
11
|
+
interface ChartCellOptions extends ResolveOptions {
|
|
12
|
+
/** Stable id for addressing this cell via render_view's item_id (re-render one chart alone). */
|
|
13
|
+
id?: string;
|
|
14
|
+
/** Grid columns this cell spans (renderer clamps to the dashboard's column count). */
|
|
15
|
+
span?: number;
|
|
16
|
+
/** Declare field typing when inference can't nail it (currency, numeric-string dimensions). */
|
|
17
|
+
fields?: FieldMeta[];
|
|
18
|
+
/** Map columns to x / y / series when the names aren't obvious. */
|
|
19
|
+
encode?: Encode;
|
|
20
|
+
}
|
|
21
|
+
/** Options for a standalone chart: resolve()'s options plus the field-typing / encoding escape hatches. */
|
|
22
|
+
type ChartOptions = ResolveOptions & {
|
|
23
|
+
fields?: FieldMeta[];
|
|
24
|
+
encode?: Encode;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Build a standalone ChartSpec, inferring the encoding via resolve(). The first arg is EITHER raw
|
|
28
|
+
* rows (`Record<string, unknown>[]` — inference sniffs types) OR a typed `ChartData` (`{ rows,
|
|
29
|
+
* fields?, encode?, notes? }` from an adapter — driver types are trusted, no sniff). For a
|
|
30
|
+
* DB-connected view, `chart(await runSql("select ..."), { chartType: "line" })` is the same one
|
|
31
|
+
* line but rides declared types. `fields`/`encode` are escape hatches for the raw path. The sibling
|
|
32
|
+
* of chartCell, which wraps this spec in a dashboard cell.
|
|
33
|
+
*/
|
|
34
|
+
declare function chart(source: Record<string, unknown>[] | ChartData, opts?: ChartOptions): ChartSpec;
|
|
35
|
+
/**
|
|
36
|
+
* Build a dashboard chart cell, inferring the encoding via resolve(). Like chart(), the first arg is
|
|
37
|
+
* either raw rows or a typed `ChartData`. `fields`/`encode` are escape hatches; `span` sets the grid
|
|
38
|
+
* width.
|
|
39
|
+
*/
|
|
40
|
+
declare function chartCell(source: Record<string, unknown>[] | ChartData, opts: ChartCellOptions): ChartCell;
|
|
41
|
+
/**
|
|
42
|
+
* Diagnose how rows (or a typed ChartData) would be charted, WITHOUT building the render payload:
|
|
43
|
+
* the inferred field typing, the resolved chartType / x / series, and any notes. For asserting the
|
|
44
|
+
* encoding in a unit test or CI before a host ever renders it, e.g.
|
|
45
|
+
* `expect(explain(sampleRows, { chartType: "bar" }).series.length).toBeGreaterThan(0)`. Pair with
|
|
46
|
+
* `strict: true` to throw on a bad encoding (zero series, ignored encode column) instead of noting.
|
|
47
|
+
*/
|
|
48
|
+
declare function explain(source: Record<string, unknown>[] | ChartData, opts?: ChartOptions): ChartExplanation;
|
|
49
|
+
/** A compact, bounded text summary of a dashboard for the model + a non-widget fallback. One line
|
|
50
|
+
* per item (KPI value/delta, chart title/type/row-count, text heading) — never echoes chart rows. */
|
|
51
|
+
declare function summarizeDashboard(spec: DashboardSpec): string;
|
|
52
|
+
/** The DashboardSpec envelope: structuredContent for the widget + a text fallback + the widget link.
|
|
53
|
+
* Absorbs the structuredContent cast so callers never write it. */
|
|
54
|
+
declare function dashboardResult(spec: DashboardSpec, opts?: {
|
|
55
|
+
summary?: string | ((s: DashboardSpec) => string);
|
|
56
|
+
}): {
|
|
57
|
+
content: {
|
|
58
|
+
type: "text";
|
|
59
|
+
text: string;
|
|
60
|
+
}[];
|
|
61
|
+
structuredContent: Record<string, unknown>;
|
|
62
|
+
_meta: {
|
|
63
|
+
readonly ui: {
|
|
64
|
+
readonly resourceUri: "ui://bonnard/chart";
|
|
65
|
+
};
|
|
66
|
+
readonly "openai/outputTemplate": "ui://bonnard/chart";
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
declare const DASHBOARD_OUTPUT_SCHEMA: {
|
|
70
|
+
title: z.ZodOptional<z.ZodString>;
|
|
71
|
+
columns: z.ZodOptional<z.ZodNumber>;
|
|
72
|
+
items: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
73
|
+
notes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
74
|
+
};
|
|
75
|
+
/** What a view's render returns: a bare spec or one paired with a summary. */
|
|
76
|
+
type ViewResult = ChartSpec | DashboardSpec | {
|
|
77
|
+
spec: ChartSpec | DashboardSpec;
|
|
78
|
+
summary?: string;
|
|
79
|
+
};
|
|
80
|
+
/** One named, renderable view in a views registry. */
|
|
81
|
+
interface ViewDef {
|
|
82
|
+
/** The render_view view_id enum value (snake/kebab, stable). */
|
|
83
|
+
id: string;
|
|
84
|
+
title: string;
|
|
85
|
+
/** One line; shown in explore_views and the render_view catalog. */
|
|
86
|
+
description: string;
|
|
87
|
+
/** Optional author hint for the catalog. */
|
|
88
|
+
kind?: "chart" | "dashboard";
|
|
89
|
+
/** Per-view input params as a zod raw shape. */
|
|
90
|
+
params?: Record<string, z.ZodTypeAny>;
|
|
91
|
+
/**
|
|
92
|
+
* Produce the view's spec(s). For a DB-connected view, return a typed `ChartData` so the encoding
|
|
93
|
+
* rides driver types instead of a value sniff, e.g. `chart(await runSql("select ..."), { chartType:
|
|
94
|
+
* "line" })` — `chart`/`chartCell` accept a `ChartData` anywhere they accept raw rows.
|
|
95
|
+
*/
|
|
96
|
+
render: (args: Record<string, unknown>) => ViewResult | Promise<ViewResult>;
|
|
97
|
+
}
|
|
98
|
+
/** Options for addViews. */
|
|
99
|
+
interface AddViewsOptions {
|
|
100
|
+
views: ViewDef[];
|
|
101
|
+
/** Override the discovery tool name (default: "explore_views"). */
|
|
102
|
+
exploreToolName?: string;
|
|
103
|
+
/** Override the execute tool name (default: "render_view"). */
|
|
104
|
+
renderToolName?: string;
|
|
105
|
+
/** Extra text appended to render_view's description. */
|
|
106
|
+
renderDescription?: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Register a two-tool named-views surface: `explore_views` (list the available views) and
|
|
110
|
+
* `render_view` (render one, bound to the chart widget). Each view returns a ChartSpec or a
|
|
111
|
+
* DashboardSpec. Owns the widget resource, the outputSchema, the _meta link, param validation, the
|
|
112
|
+
* result envelope, and error handling.
|
|
113
|
+
*/
|
|
114
|
+
declare function addViews(server: McpServer, opts: AddViewsOptions): void;
|
|
4
115
|
|
|
5
116
|
declare function resolve(data: ChartData, opts?: ResolveOptions): ChartSpec;
|
|
6
117
|
|
|
7
118
|
/** Complete field metadata for every column, declared values taking precedence. */
|
|
8
119
|
declare function inferFields(data: ChartData): FieldMeta[];
|
|
9
120
|
|
|
121
|
+
declare const CHART_RESOURCE_URI = "ui://bonnard/chart";
|
|
10
122
|
/** Options for addCharts. */
|
|
11
123
|
interface AddChartsOptions {
|
|
12
124
|
/** SQL mode: the agent writes SQL; you execute it read-only and return rows. */
|
|
@@ -20,39 +132,11 @@ interface AddChartsOptions {
|
|
|
20
132
|
/** Override the tool name (default: "visualize"). */
|
|
21
133
|
toolName?: string;
|
|
22
134
|
}
|
|
135
|
+
/** Register the chart/dashboard widget ui:// resource. Idempotent per server. A consumer that
|
|
136
|
+
* returns a ChartSpec/DashboardSpec from its own tool (instead of `visualize`) calls this so the
|
|
137
|
+
* host has the widget to render into. */
|
|
138
|
+
declare function registerChartWidget(server: McpServer): void;
|
|
23
139
|
/** Register the generic `visualize` tool on an MCP server. */
|
|
24
140
|
declare function addCharts(server: McpServer, options: AddChartsOptions): void;
|
|
25
141
|
|
|
26
|
-
|
|
27
|
-
interface SourceColumn {
|
|
28
|
-
name: string;
|
|
29
|
-
/** Engine type, passed verbatim to mapKind (e.g. "INT64", a Postgres OID, "VARCHAR", a field object). */
|
|
30
|
-
type: unknown;
|
|
31
|
-
}
|
|
32
|
-
/** Map an engine's column type to our FieldKind. The one piece of real per-engine work. */
|
|
33
|
-
type KindMapper = (type: unknown, column: SourceColumn) => FieldKind;
|
|
34
|
-
/** Coerce one cell value to a flat scalar, guided by the resolved kind. */
|
|
35
|
-
type CellNormalizer = (value: unknown, kind: FieldKind, column: SourceColumn) => unknown;
|
|
36
|
-
interface BuildChartDataOptions {
|
|
37
|
-
rows: Record<string, unknown>[];
|
|
38
|
-
columns: SourceColumn[];
|
|
39
|
-
mapKind: KindMapper;
|
|
40
|
-
/** Optional; defaults to {@link defaultNormalizeCell}, which suits drivers that return JS-native values. */
|
|
41
|
-
normalizeCell?: CellNormalizer;
|
|
42
|
-
}
|
|
43
|
-
/** Default cell normalizer: pass scalars through, coerce numbers/booleans, stringify non-scalars.
|
|
44
|
-
* Handles `{ value }` wrapper objects (some drivers wrap typed values). Adapters whose driver
|
|
45
|
-
* needs special handling (e.g. BigQuery's typed-string + wrapper mix) supply their own. */
|
|
46
|
-
declare function defaultNormalizeCell(value: unknown, kind: FieldKind): unknown;
|
|
47
|
-
/**
|
|
48
|
-
* Turn a SQL result (rows + column types) into typed ChartData. Builds a complete FieldMeta per
|
|
49
|
-
* column from the engine kind + name-based format/granularity hints, then normalizes every cell.
|
|
50
|
-
*/
|
|
51
|
-
declare function buildChartData({ rows, columns, mapKind, normalizeCell, }: BuildChartDataOptions): ChartData;
|
|
52
|
-
/**
|
|
53
|
-
* Reject anything that isn't a single SELECT/WITH statement. A cheap check on LLM-authored SQL;
|
|
54
|
-
* enforce real read-only access with a database role.
|
|
55
|
-
*/
|
|
56
|
-
declare function assertReadOnlySql(sql: string): void;
|
|
57
|
-
|
|
58
|
-
export { type AddChartsOptions, type BuildChartDataOptions, type CellNormalizer, ChartContext, ChartData, ChartSpec, ChartType, FieldKind, FieldMeta, type KindMapper, ResolveOptions, type SourceColumn, addCharts, assertReadOnlySql, buildChartData, defaultNormalizeCell, inferFields, resolve };
|
|
142
|
+
export { type AddChartsOptions, type AddViewsOptions, CHART_RESOURCE_URI, ChartCell, type ChartCellOptions, ChartContext, ChartData, ChartExplanation, type ChartOptions, ChartSpec, ChartType, DASHBOARD_OUTPUT_SCHEMA, DashboardSpec, Encode, FieldMeta, ResolveOptions, type ViewDef, type ViewResult, addCharts, addViews, chart, chartCell, dashboardResult, explain, inferFields, isChartSpec, isDashboardSpec, registerChartWidget, resolve, summarizeDashboard };
|