Skip to content

lukaisailovic/openislands

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

115 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OpenIslands

OpenIslands

Dashboards your AI agent builds and keeps maintaining, over data that never leaves your machine.

Point a coding agent at a folder of files. It builds a typed, durable dashboard and keeps it healthy for months as the data changes. No cloud, no account, no rendering code to rot.

License: MIT Node >= 20 ESM only Status: alpha PRs welcome

Quickstart  ·  Why  ·  How it works  ·  Islands  ·  Docs  ·  Contributing


AI agents are great at building a dashboard once. Then a column gets renamed, a new export lands, you ask a different question, and the generated app quietly breaks or, worse, keeps rendering the wrong number. OpenIslands fixes the part agents are bad at: keeping it alive.

It's a local-first compiler and runtime. An app is a typed manifest of reusable visual islands (KPI cards, charts, tables, gauges, timelines) bound to typed data contracts built from your files. Your agent edits the manifest, never the rendering code, through a pipeline that validates, diffs, and can roll back every change. When the data and an island disagree, the build fails loudly and names the island instead of drawing something wrong.

Quickstart

Scaffold a project, then serve it over your files:

npx openislands init my-dashboard            # blank starter (the empty template)
cd my-dashboard
npx openislands serve                        # http://127.0.0.1:4321

With no flag, init scaffolds the empty template: a blank starter you build up from your own files. Want a populated example? Pass --template finance (the flagship: net worth, allocation, holdings, and transactions over CSVs you own). health and operations ship too.

Now hand it to an agent. Add the MCP server to your tool of choice (Claude Code, Cursor, and friends), pointed at the project directory:

// .mcp.json
{
  "mcpServers": {
    "openislands": {
      "command": "npx",
      "args": ["-y", "@openislands/mcp", "."]
    }
  }
}

Then just ask:

Drop data/spending.csv into the project and add a page charting monthly spend by category.

The agent reads your data, proposes the change so you see a diff before anything is written, applies it with a snapshot of the prior version, and rolls back if the result is wrong. Leave serve running and the page live-updates over SSE as each edit lands.

Agents and skills

init sets this up for you. Every scaffolded project ships a local .mcp.json, an AGENTS.md, and the OpenIslands skill under .agents/skills/openislands/, so an agent that opens the folder picks up the MCP tools and the conventions with no extra wiring.

Want the skill in another project or in your own agent setup? Install it anywhere:

npx skills add lukaisailovic/openislands --skill openislands

Or skip the scaffold entirely and let an agent drive from a single paste:

Read https://openislands.sh/start.md then help me build my first agent-maintained dashboard.

Why OpenIslands

Your data, your disk Plain files you own. No account, no cloud, nothing to sign into.
Built to last Typed islands from a closed registry. There's no 300-line React component to rot.
Agent-maintained A CLI and an MCP server, so Claude Code or Cursor build the dashboard and keep it healthy.
Fails loudly Bind an island to a field that doesn't exist and validation stops with a named error. You never get a silently wrong chart.
Always live Edit the manifest or drop a new export and the dashboard updates over your live files. No rebuild, no snapshot to drift.

It isn't a hosted app builder or a BI platform. It's the typed, file-based layer your agent edits safely.

How it works

 files (CSV / JSON / Parquet / md)
        │
        ▼
 DuckDB query core  ──  runs transforms + queries live  ──┐
        │                                                 │
 manifest (typed islands)  ──►  serve runtime  ──►  your dashboard
                                (TanStack Start SSR)      ▲
                                       │ SSE on file change → islands refetch
        AI agent  ──(Code Mode: execute → validate → apply → rollback)──┘

The pieces, smallest contract first:

Package Role
@openislands/schema The keystone. Zod schemas for the manifest and islands, emitted as TypeScript types and JSON Schema for editor autocomplete and agent grounding. Everything else depends on it.
@openislands/compiler The DuckDB query core. Turns files into typed data contracts, runs transforms and queries live, and checks every island binding against the data.
@openislands/runtime The island registry and renderers behind serve (TanStack Start SSR + React islands + live updates).
openislands The CLI: init, validate, serve, add, infer.
@openislands/mcp The MCP server, in Code Mode: one execute tool the agent drives with JavaScript against the oi API. Read many, write one, so it edits the manifest without breaking it.

Islands

An island is a reusable, typed visual block. You declare it in the manifest, bind it to fields that exist in your data, and the runtime renders it. The built-ins cover most of a dashboard:

  • Metrics & gauges: KPI cards, scorecards, goal rings, meters, status grids.
  • Charts: line, bar, combo, and pie, over time or category.
  • Tables & feeds: sortable grids and activity feeds.
  • Content & layout: Markdown notes, a rich content editor, and rows that group islands.

Need something the registry doesn't have? Drop a renderer under components/custom/ and bind to it like any other island. The full catalog, with required fields and live previews, lives in the docs.

Templates

Three templates ship with the repo, and the same engine renders all of them with no domain-specific hacks:

  • finance: net worth, portfolio allocation, holdings, transactions.
  • health: macros, biomarkers, and wearables (pairs with health-mcp).
  • operations: a non-personal template that proves the breadth of the island set.

Self-host with Docker

Want it always-on — on a home server or NAS, reachable by a remote agent? Run the published image. One process serves the dashboard and the MCP server (over Streamable HTTP) on a single port. Mount a single app or a workspace dir at /project:

# MCP is a write surface, so off-loopback it needs a token:
docker run -d -p 127.0.0.1:4321:4321 \
  -e OPENISLANDS_MCP_TOKEN="$(openssl rand -hex 32)" \
  -v "$PWD/my-dashboard:/project" \
  ghcr.io/lukaisailovic/openislands:latest

Then open 127.0.0.1:4321. To reach it across your LAN, bind 0.0.0.0 and keep the token set; for a dashboard-only container with no agent write path, set OPENISLANDS_MCP=0 to boot token-free. See Self-hosting for the full guide.

Status

Alpha, and live-first. The schema, compiler, runtime, CLI, MCP server, and all three templates work today, and pnpm test is green. There's no static export in v1: serve boots the production runtime and queries your files on every request. A hosted publish/sync tier may come later.

Documentation

  • Data app model: the manifest, the island catalog, data contracts, and workspaces.
  • Agent edit loop: the read-many/write-one MCP loop in Code Mode (execute + oi), actions, queries, and connectors.
  • Contributing: adding an island, the PR gate, releases.

The full docs site lives in apps/docs (built with Fumadocs on TanStack Start, deployed static to Cloudflare Workers).

Develop

pnpm install
pnpm build                 # tsdown (rolldown / Oxc) across packages
pnpm test                  # vitest
pnpm typecheck             # tsc --noEmit per package
pnpm lint                  # oxlint
pnpm validate:templates    # every template's manifest + bindings
pnpm demo                  # serve the finance template locally

Toolchain: pnpm + Turborepo + Changesets, tsdown for builds, oxlint and oxfmt for lint/format, Vitest, Node ≥ 20, ESM only. See CONTRIBUTING.md before opening a PR.

License

MIT © Luka Isailovic