SkillAgentSearch skills...

boardstate

Your dashboard is data. Any AI can build it; any human can edit it. A protocol + runtime for agent-composable dashboards — layout-as-data, one guarded control plane, sandboxed agent-authored widgets, MCP server included.

Install / Use

claude mcp add 100yenadmin -- npx -y github:100yenadmin/boardstate

If the server publishes to npm under a different name, use that package instead — check the repo README.

About this skill
🔌

MCP Server

Model Context Protocol server

Quality Score

84/100

Supported Platforms

Claude Code
Claude Desktop

Boardstate

CI npm version License: MIT PRs Welcome

Your dashboard is data. Any AI can build it; any human can edit it.

▶ Live app — plug in your key — bring your own provider (GLM, Anthropic, OpenAI, Ollama, or any OpenAI-compatible endpoint) and watch the AI build your dashboard live, in your browser. Prefer no key? The component demo presses “Simulate agent” and composes the board with a scripted agent — then drag things around yourself.

Plug in your AI: pick a provider (or go keyless), ask for a live ticker, and the agent builds a stream-bound board that ticks on its own

<details> <summary>More demos: a real Claude over MCP, and the component demo's scripted agent</summary>

A real Claude connected over MCP composes the board: tab, chart, sandboxed widget, approval

An agent builds a dashboard: creates a tab, adds a chart, scaffolds a sandboxed widget, and it renders live the moment you approve it

</details>

Boardstate is a protocol and runtime for agent-composable dashboards. The entire dashboard — tabs, widgets, layout, data bindings, even the registry of agent-authored custom widgets — is one validated JSON document: the board state. An AI agent composes it through tools, a human rearranges it with drag & drop, a script edits it over RPC — all through the same guarded control plane, with no privileged path. Agent-authored widgets render live inside a sandbox strict enough that foreign code is safe by construction, behind an explicit operator approval gate.

  • 📄 The document is the API — diffable, undoable, exportable, importable, templatable, time-travelable.
  • 🤖 Any AI, zero integration@boardstate/mcp exposes the full tool set to any MCP client (Claude, or anything else that speaks MCP).
  • 🧑‍🎨 Human parity is a protocol requirement — drag/drop, collapse, approve, undo: the same methods the agent uses.
  • 🔒 A security ladder, not a warning label — trusted builtins vs. sandboxed customs (opaque origin, CSP connect-src 'none', capability manifest, approval-gated mount, server-side 404 for anything unapproved).
  • 🔌 Your dashboard can DO things — Boardstate is also an MCP client: point it at OfficeCLI, Pipedream, Composio, or any MCP server and the board reads their tools as live data and runs their tools as operator-confirmed actions (see below).

Your dashboard can DO things

Boardstate is an MCP client, not just an MCP server. Give it an operator-authored connector config (@boardstate/broker) and it connects outward to an external tool server — importing that server's read-ish tools as board data (source:"mcp" bindings) and its side-effecting tools as operator-confirmed actions (action buttons). The whole thing runs behind the same capability gate as everything else:

  1. The agent discovers tools it needs (boardstate_tool_search) and requests them — it can never grant them.
  2. A card appears in the approvals widget; a human operator grants a subset.
  3. Read tools flow onto the board live; anything consequential parks as a pending action that a networked client physically cannot confirm — only the local operator can.
  4. Grants are revocable, and re-pend the instant a tool's surface changes under them.
pnpm build
node examples/operational-demo/demo.mjs   # keyless — a fake OfficeCLI double; no binary, no keys

Open the board and the loopback operator console it prints: approve the grant, watch a table fill from a live workbook, click "Generate .docx", and confirm the action. OfficeCLI, Pipedream, and Composio ship as first-party connector presets (docs/connectors/). The broker, its network, and every secret stay node-side — @boardstate/core never learns an external tool exists.

How it fits together

flowchart TB
  subgraph Authors["Who composes a dashboard — one validated control plane"]
    A1["🤖 AI agent · tools<br/>(dashboard_tab_create, _widget_scaffold, …)"]
    A2["👤 Human · UI<br/>(drag / drop / approve)"]
    A3["⌨️ Scripts · CLI / RPC"]
  end
  A1 --> CP
  A2 --> CP
  A3 --> CP
  CP["Control plane · dashboard.* methods<br/>(allowed-keys whitelists, full validation)"]
  CP --> STORE["🔒 Store<br/>serialized writes · atomic persistence<br/>undo ring · size caps"]
  STORE --> DOC[["workspace document<br/>the board state"]]
  STORE -- "boardstate.changed" --> UI["Host UI · <boardstate-view>"]
  UI --> B["✅ Builtin widgets — trusted tier"]
  UI --> C["🧩 Custom widgets — sandboxed tier<br/>opaque origin · no network · approval-gated"]
  C -. "postMessage bridge — parent resolves all data" .-> UI

Why agent-authored code is safe to run:

sequenceDiagram
  participant Agent as 🤖 Agent
  participant Store as Store
  participant Op as 👤 Operator
  participant Frame as Sandboxed iframe
  Agent->>Store: widget_scaffold (manifest + index.html)
  Store-->>Op: status "pending" — a card, NOT an iframe
  Op->>Store: Approve
  Store-->>Frame: assets served (unapproved → 404) + CSP connect-src 'none'
  Frame->>Store: only the bindings its manifest declared — via the parent
  Note over Frame: no origin · no network · no credentials

Where Boardstate runs

The same library, in production agent products:

  • OpenClaw adopted the stack in-tree as "Workspaces" — our upstream contribution merged directly (openclaw#101792), follow-on work landed maintainer-wrapped (openclaw#104139); tracker openclaw#101136.

  • Hermes — the boardstate-hermes-plugin puts the board inside Hermes: a Board tab in the web dashboard and a page in the desktop app, with Hermes-native design skins, live Hermes data widgets, sandboxed custom widgets, and an operator-governed connector layer. Bundling PRs are open upstream — tracker hermes-agent#66413 · web #66381 · desktop #66425. Prefer zero install? The no-plugin recipe points Hermes' MCP client straight at @boardstate/mcp:

    A Hermes agent building a live sales board through @boardstate/mcp

  • Anywhere npm or MCP reaches — embed <boardstate-view>, run a Node host, or point any MCP-speaking AI at a board (see Installation).

Features

The document is the whole product

Everything below operates on one validated JSON document (≤ 256 KB, schema v1). Because the board is data, you get for free: undo (a 20-entry ring), export/import (a board is a file you can email), templates (templates/ — Agent HQ, Showcase, small-business, OSS-maintainer), provenance (every tab and widget records its createdBy actor — human, system, or which agent), and diffability (review an agent's board the way you review a PR). Mutations go through dashboard.* methods with per-method allowed-keys whitelists — unknown keys are rejected at the wire, which catches contract drift before it ships.

Widgets: a trusted tier and a sandboxed tier

17 builtin widgets cover the common jobs: stat-card, chart, table, markdown, notes, iframe-embed, preview, activity, sessions, usage, cron, instances, agent-status, chat (talk to the agent inside the board), approvals (the operator's grant + pending-action console), action-form, and action-button (governed actions — see below). Every builtin has a schema-valid example in the widget catalog (boardstate_widget_catalog), honesty-gated in CI so the examples can never rot.

Custom widgets are agent- or user-authored HTML that renders live — safely, by construction: opaque-origin iframe, connect-src 'none' (no network), a capability manifest that declares exactly which bindings it may read, an operator approval gate before first mount, and server-side 404s for unapproved assets. A scaffolded widget lands as a pending card, not running code.

Data bindings: six sources, one model

Any widget can bind live data. A binding declares a source; the host resolves and refreshes it:

| Source | What it does | | ---------- | ---------------------------------------------------------------------------------------------------- | | static | Inline JSON (≤ 8 KB) — fixtures, thresholds, copy | | file | Reads from the host's state dir — reports, scratch data | | rpc | Calls a whitelisted host method — anything your host exposes | | stream | Subscribes to a host event stream — tickers, logs, agent output; updates push live | | computed | Derives from other bindings with a pure expression — totals, deltas, ratios | | mcp | Reads a granted external MCP tool through the connector broker (readOnly-only, side-effect-free) |

The agent layer

  • @boardstate/mcp — the full tool set for any MCP client; --serve gives you a live page of the board being built, and boardstate_board_view renders it inside MCP-Apps clients like Claude Desktop.
  • @boardstate/agent — the embeddable chat agent: streaming tool loop, provider adapters (Anthropic, or any OpenAI-compatible endpoint — GLM, OpenAI, Ollama, vLLM), the composition system prompt, and a definition-token budget so big tool catalogs can't blow the context.
  • builtin:chat — the conversation lives on the board, next to what it's building.
  • The self-building loopboardstate_design_review + selfReview:"once": the agent screenshots the board it just built, critiques it, and fixes what it finds.
  • The conventionsliving answers (answer visual questions with widgets, not prose) and composition patterns (which widget for which job). See AGENTS.md for the full agent guide.

Actions & the operate loop (the trust spine)

Side effects are first-class and governed. The capability broker tracks per-connector, per-tool grants (requested → granted / denied / revoked): an agent can discover and request tools (boardstate_tool_search) but never grant them; the operator approves a subset in the approvals widget. Granted readOnly tools execute directly; mutations park as pending actions that only the local operator can confirm — a networked client is refused at the transport (OPERATOR_ONLY). Grants re-pend automatically if the external server changes a tool's surface underneath them (anti-rug-pull, both directions), and every invoke is rate-limited and audit-logged. Reads and actions are different verbs: a source:"mcp" binding resolves through a pure-read verb that structurally cannot trigger a side effect.

Beyond one agent

Grants can carry **per-tool aut

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars9
CategoryDevelopment
Updated2mo ago
Forks0

Languages

TypeScript

Security Score

92/100

Audited on Jul 18, 2026

1 low