Repository navigation
Releases: simonliu-ai-product/open-dashboard
Release list
open-dashboard v0.8.0
Highlights
Put it online: open-dashboard serve
When the data has to stay live, serve gives readers the dashboards with results queried as they look — on the same cache and collector schedule as dev — and none of the authoring: no edit mode, notes, inspector or data sources page, no SQL or file path in any reply, nothing that writes. The viewer is built once (again only when a dashboard, a chart or core changes), so there is no Vite at runtime and no cold-start blank page.
serve: { allowedHosts: ['.run.app'], assistant: false },FROM node:24-slim
WORKDIR /app
RUN corepack enable
COPY . .
RUN pnpm install --frozen-lockfile && pnpm exec open-dashboard serve --build-only
CMD ["pnpm", "exec", "open-dashboard", "serve", "--host", "0.0.0.0"]It listens on PORT, answers only localhost and serve.allowedHosts, refuses cross-origin API calls, and ignores fresh so a reader cannot make every panel skip the cache. It has no sign-in: put it behind IAP, Cloudflare Access or an authenticating proxy unless the dashboards are meant to be public. The assistant is off unless serve.assistant: true.
The assistant looks beyond this page
It is shown the workspace's other dashboards — titles, descriptions, panels — and when this page cannot answer, it reads the panels of the one that can, under that dashboard's default filters. The reply names them as Dashboard › Panel and links to the dashboard.
Compare without switching the page
read_panels takes filter values: asked "which of the four games had the best umpire?", the assistant reads each game in one turn and answers, while the page stays where you left it.
Fixes
- A prop that names a constant —
options={GAMES}, withGAMESexported by another dashboard — is read as that literal list. Before, its options were invisible:checkcould not verify them,buildsnapshotted only the default, and the assistant could not switch to any other. - Gemini's parallel tool calls, all sent as
index: 0, are kept apart; they were merged into one call and refused with a 400. - A CSV with a header and no rows keeps its columns, so a
LEFT JOINover it still returns rows. devprints config reloads and collector runs (a failure with its last line of output); Vite's quiet log level had been hiding them.
Upgrade
pnpm add @open-dashboard/core@^0.8.0
pnpm add -D @open-dashboard/mcp@^0.8.0 # for the MCP server
pnpm exec open-dashboard sync-skillspnpm audit --prod: no known vulnerabilities.
open-dashboard v0.7.1
Highlights
Fixes for what came up building ten dashboards on 0.7.0.
Whole numbers stay whole
JSON, CSV, http and mcp tables store a column of whole numbers as INTEGER, the way a database would type it: home || ':' || away reads 2:6, not 2.0:6.0. Integer division follows: write wins * 1.0 / games for a rate. -- uses: queries across databases are unchanged.
An empty table is not an error
An empty file, [], or an empty API response is a table with no rows: its panels say they have no data instead of the whole dashboard failing with "returned no columns to combine". A table that had columns keeps them, so a LEFT JOIN over it still returns rows.
Collectors cannot break a working page
With a json or csv source, a run that leaves a file unreadable, or empties one that had rows, gets the previous file put back and is reported as failed with the reason. Tables that may turn empty for real go in allowEmpty:
collectors: { live: { run: 'uv run collector/collect.py --live', every: '1m', source: 'cpbl', allowEmpty: ['live_now'] } }New
httpandmcpsources keep at most 4 requests in flight across all panels (concurrencychanges it); a429or503is retried after itsRetry-After.open-dashboard checkreuses API responses up to 10 minutes old, the dev server's included, so rerunning it does not spend an hourly quota.--freshfetches again.
Fixes
- The assistant joins the names of panels and filters it read or switched with a middle dot instead of a localized list, which ran "和" into English titles.
Upgrade
pnpm add @open-dashboard/core@^0.7.1
pnpm add -D @open-dashboard/mcp@^0.7.1 # for the MCP server
pnpm exec open-dashboard sync-skillspnpm audit --prod: no known vulnerabilities.
open-dashboard v0.7.0
Highlights
Share a snapshot: open-dashboard build
Writes the dashboards and their results, taken now, as a static site — GitHub Pages, S3, any web server, under any path. The filters still work: every combination of the filter values a query reads is run ahead (--max-runs, default 100). No SQL, no connection string, no file path in the site, and nothing on it reaches your database.
pnpm exec open-dashboard build # → site/The assistant reads panels and switches filters
The chat answers by native tool calling with exactly two tools: read_panels reads only the panels a question needs (86% less sent on the demo's 29-panel gallery), and set_filters changes what the page shows — "switch to the North, last 90 days" — only to values the filters offer. The page follows, and the reply says what it switched, with Undo.
Agents can look at what they drew
open-dashboard render <id> --panel "Title" (MCP: render_panel) draws a panel exactly as the page does and writes a PNG — for what check cannot see: labels cut off, a chart that hides the point. Needs Playwright in the workspace; no dev server.
Collectors keep the data fresh
collectors: { stocks: { run: 'uv run collector/collect.py', every: '1h', source: 'stocks' } }dev runs them on schedule, open-dashboard collect now, and the data source page has an Update now button. The page names a collector; it never sends a command.
Gantt panel
<Gantt> draws a project plan: phases, progress, milestones, finish-to-start arrows (flagged when a task starts before its predecessor ends) and days off from an optional holidays query.
New
- Download a panel or the dashboard as PDF, and the whole dashboard as one HTML file that opens from disk with its filters working.
- The inspector's History tab, and MCP
query_history: who changed a query's SQL, when and how, from git. open-dashboard mcp [--allow-sql]: the MCP tools over stdio, for clients that start their server;list_collectorsandrun_collectortools.- A failed download says why, under the button.
Fixes
- The Gantt axis's last date stays inside the panel.
- Writing a
.sqlfile through MCP drops that dashboard's cached results.
Upgrade
pnpm add @open-dashboard/core@^0.7.0
pnpm add -D @open-dashboard/mcp@^0.7.0 # for the MCP server
pnpm add -D playwright && pnpm exec playwright install chromium # for render
pnpm exec open-dashboard sync-skillspnpm audit --prod: no known vulnerabilities.
open-dashboard v0.6.0
Highlights
An MCP server for any agent
Skills teach a coding agent that edits files. Any agent framework that speaks the Model Context Protocol now gets the same workspace as tools, through the new package @open-dashboard/mcp:
pnpm add -D @open-dashboard/mcp
pnpm exec open-dashboard dev --mcp # http://localhost:5473/mcp- 16 tools over the same code the viewer and the CLI use:
list_dashboards,read_dashboard,write_dashboard_file,check_dashboard,run_query,list_sources,read_schema,read_database_doc,write_database_doc,list_charts,list_themes,read_theme,write_theme,list_comments,add_comment,current_view. - It runs on the dev server, so the page in the browser reloads as the agent writes.
- Streamable HTTP, stateless: no session handshake, any client connects.
--allow-sqladdsrun_sqlfor exploring data — one read-only statement through the same drivers as every query. Off unless asked for.
Safe by the same rules
- Host and Origin must be loopback: a page on another origin cannot drive the tools, also under
--host. - Writes reach only
dashboards/<id>/index.tsx,dashboards/<id>/*.sql,databases/<source>/database.mdandthemes/<id>.json. Each carries the hash it read; a file changed meanwhile — by the person in Edit mode, or another agent — is refused with409, not overwritten. - Tool errors are masked like every other message.
New
open-dashboard dev --mcp [--allow-sql].- Core ops
readDashboardFiles,writeDashboardFileandwriteDatabaseDoc(with the same hash check as layout saves);readDatabaseDocreturns ahash.
Upgrade
pnpm add @open-dashboard/core@^0.6.0
pnpm add -D @open-dashboard/mcp@^0.6.0 # for the MCP server
pnpm exec open-dashboard sync-skillspnpm audit --prod: no known vulnerabilities.
v0.5.0
Highlights
JSON and CSV files as datasources
Exported results, spreadsheets saved as CSV, a folder of logs: a json or csv source reads files in the workspace as tables, with the same SQL, filters, check and -- uses: joins as any database.
evals: {
type: 'json',
tables: {
results: { file: 'data/results/**/results_*.json' }, // one row per file, _file = its path
models: { file: 'data/models.json', rows: 'official' }, // the array at a dot path
},
},
sheets: { type: 'csv', tables: { budget: { file: 'data/budget.csv' } } },- A glob stacks every matching file into one table with its path in
_file— drop a new file in the folder and its rows appear. - JSON Lines (
.jsonl,.ndjson) is read one record per line;.tsvis tab-separated. - A CSV column becomes numbers only when every value is one, so a code like
0050stays text. - Files are read only from inside the workspace, never written, and never served to the page as files. Edit one and the panels reading it refresh.
- The Data sources page shows each table's file or glob and how many files it matched.
Download the whole dashboard
The download button beside Preview / Edit saves the dashboard — title, the filters as set, every panel — as one PNG (2×) or SVG, on the page's background.
Fixes
- API tables and the result cache. A parameter used only in an
httptable's URL or anmcptable's arguments (a<Select>choosing the stock to fetch, say) was left out of the cache key, so switching it returned the previous result. It is now part of the key, andcheckreports such a parameter when no filter provides it. - JSON keys that differ only in case (
rtMessagein one record,rtmessagein the next) no longer fail the query: SQLite treats them as one column, and so does the reader. - Custom charts resize in Edit mode. A chart made with
defineChartsnapped back after a drag until Save; it now shows the staged size, like the built-ins. - Gauge. Above 50 % the arc was drawn the long way round, off the panel; it now stays on the half circle, sits centred, and a plain rate no longer repeats itself as "88 % of 100 %".
Upgrade
pnpm add @open-dashboard/core@^0.5.0
pnpm exec open-dashboard sync-skillspnpm audit --prod: no known vulnerabilities.
v0.4.1
New
- The assistant shows its thinking. While the model thinks, the chat shows its current step; once it answers, "Thought for N s" opens the full thinking. Gemini's thought summaries and the
reasoning_contentfield of OpenAI-compatible servers (DeepSeek, vLLM, Ollama) are both read. reasoningEffort—low,mediumorhigh, usually fromASSISTANT_REASONING_EFFORTin.env. Gemini defaults tomedium;lowanswers in a few seconds but sends no thinking to show. Foropenaiproviders it is sent only when set.
Fixes
- The reply language follows
assistant.mdwhen it names one. The built-in rule and an instruction in another language used to conflict, and Gemini could spend up to a minute deliberating over it.
Upgrade
pnpm add @open-dashboard/core@^0.4.1
pnpm exec open-dashboard sync-skillspnpm audit --prod: no known vulnerabilities.
v0.4.0
Includes everything in v0.3.0 — custom charts, the Charts page, themes and panel download — which was not published to npm on its own.
Highlights
An optional chat assistant
Configure assistant and a chat button appears at the bottom right of every dashboard; leave it out and there is no button at all. It answers from the page: each panel's results under the reader's filters, the queries' -- description: lines and database.md. No tools, no SQL — it never runs a query.
assistant: {
provider: 'gemini', // or 'openai': any OpenAI-compatible API (Ollama, vLLM…)
model: process.env.ASSISTANT_MODEL ?? '',
apiKey: process.env.GEMINI_API_KEY, // from .env — never sent to the page
},- The key stays in
.envand on the server: the page has no field for it, the API only says whether the assistant is on, and errors mask it. assistant.md(workspace) anddashboards/<id>/assistant.mdadd your own instructions — reader, tone, terms, format — after the built-in rules, read on every question.- Replies stream; stop, new conversation, suggestions, IME-safe Enter.
Skills
/create-theme and /set-up-assistant, alongside /create-chart.
Upgrade
pnpm add @open-dashboard/core@^0.4.0
pnpm exec open-dashboard sync-skillspnpm audit --prod: no known vulnerabilities.
v0.3.0
Not published to npm — its changes shipped in v0.4.0.
Highlights
Custom charts
When none of the 40 built-in panels draws what you need, write one in charts/<id>/index.tsx with defineChart({ name, columns, sample, render }). render only draws the data; the panel frame comes with it — loading and error states, the inspector, notes for the agent, download, edit chrome and the dashboard's theme. check verifies the columns a chart declares, and an optional sample.sql previews it. New skill: /create-chart.
Charts page and open-dashboard charts
Every chart you can use — the 40 built-ins and your charts/ — in one searchable list, each with the dashboards using it and a preview drawn from a real use.
Themes
themes/<id>.json sets the series palette, accent, up/down colours, backgrounds, fonts and corner radius, light and dark apart. The Themes page edits them with a live preview; a dashboard picks one with meta.theme (also from Edit mode), the workspace default goes in the config.
Download any panel
PNG (2×) or SVG, title and legend included, buttons left out. The SVG is plain vectors, so it opens outside the browser too.
Fixes
- A custom panel in a row no longer turns off moving panels in Edit mode.
- A chart whose
renderthrows fails alone, inside its panel. - Unsaved theme or layout changes block leaving the page.
- Font names in CJK scripts are accepted in themes.
v0.2.1
Fixes
- Maps colour by the data's range. Choropleth and tile maps started their scale at zero, so values in a narrow band — county temperatures of 28–32 °C — came out as one colour. The scale now spans the data's own minimum and maximum, and the lowest value stays visibly tinted apart from "no data".
- Queries that open with a scalar subquery are accepted.
SELECT (SELECT max(x) FROM t) AS top, …was refused as not-a-SELECT by the read-only check, on every source.
New
open-dashboard sync-skills—initcopies the agent skills into the workspace once, and upgrading@open-dashboard/coredid not update them. This refreshes the framework's skills in.claude/skillsand.agents/skills(skills you wrote are left alone), andopen-dashboard devnow says when they are out of date.
Upgrade
pnpm add @open-dashboard/core@^0.2.1
pnpm exec open-dashboard sync-skillsv0.2.0
Highlights
API and MCP as data sources
Alongside the nine databases, a datasource can now be a JSON HTTP API (type: 'http') or an MCP server (type: 'mcp', remote or local). Each endpoint or tool becomes a table; queries are ordinary SQL (SQLite) over them, so filters, check, the cache and -- uses: joins all work — including joining an API to a database.
twse: { type: 'http', baseUrl: 'https://openapi.twse.com.tw/v1',
tables: { stock_day: { url: '/exchangeReport/STOCK_DAY_ALL' } } },
hub: { type: 'mcp', url: 'https://example.com/mcp/',
headers: { Authorization: process.env.HUB_AUTHORIZATION ?? '' },
tables: { reservoir: { tool: 'tw_rt_reservoir_live', args: { name: ':reservoir' }, rows: 'data' } } },http: GET only, to URLs in the config.mcp: only tools annotatedreadOnlyHint, neverdestructiveHint. MCP's read-only guarantee is the tool's own word — weaker than a database's; connect servers you trust.- The data sources page shows each source's endpoints or tools, their safety, and the parameters a table needs.
Security
- Fixed: the dev server served raw database files (
/data/shop.db), bypassing read-only queries and row caps;.sql, the config and key files too. Now refused by type and by any path a datasource names. Upgrade if you run 0.1.0, especially with--host. - Secrets are masked in every error, log line and CLI message.
--hostwarns that the API has no login; request bodies are capped at 1 MB.SECURITY.mdmaps assets, threats and controls to ISO/IEC 27001:2022 Annex A (a self-assessment, not a certification).
Fixes
- SQL Server ADO.NET connection strings (
Server=…;Password=…) always failed; they work now.
Upgrade
pnpm add @open-dashboard/core@^0.2.0