> ## Documentation Index
> Fetch the complete documentation index at: https://schemabrain.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Local dashboard

> A read-only Next.js dashboard, served by a FastAPI sidecar bound to 127.0.0.1, that visualises PII coverage, refused tool calls, and the tamper-evident audit chain over the same SQLite store the MCP server uses.

# Local dashboard

<Note>
  **One-line claim:** `schemabrain dashboard` boots a FastAPI sidecar on `127.0.0.1:7878` that serves a pre-built Next.js static export. The UI reads from the same SQLite store + `mcp_audit` table the MCP server writes to. No Node runtime, no network exposure, no write paths.
</Note>

The dashboard answers three operator questions that the MCP envelope alone does not surface visually:

1. **Which entities carry catastrophic-leak PII categories?** — see [PII matrix](/dashboard/pii-matrix).
2. **What did SchemaBrain refuse, and what envelope did the agent receive?** — see [Refusals](/dashboard/refusals).
3. **Is the hash-chained audit log still intact?** — see [Audit Viewer](/dashboard/audit-viewer).

SchemaBrain renders **nine read-only surfaces** over that same store. The signature surface is the **Knowledge Graph** — your schema as the entity-relationship projection the semantic layer compiles joins against.

<Frame caption="Knowledge Graph — entities as nodes, canonical joins as edges, catastrophic-PII entities flagged, and the compiled join path traced.">
  <img src="https://mintcdn.com/schemabrain/vxsNBZD3F847_0vI/assets/dashboard-graph.png?fit=max&auto=format&n=vxsNBZD3F847_0vI&q=85&s=f5d920945f80824acc0d87824230e2a9" alt="Knowledge Graph dashboard surface" width="1920" height="1333" data-path="assets/dashboard-graph.png" />
</Frame>

<Frame caption="Overview — the whole boundary on one screen: bound entities, catastrophic-PII floors, refusals, and audit-chain health, each panel opening its detail view.">
  <img src="https://mintcdn.com/schemabrain/vxsNBZD3F847_0vI/assets/dashboard-overview.png?fit=max&auto=format&n=vxsNBZD3F847_0vI&q=85&s=fb01f81503b9f6fd69fdad0ab5cb10e9" alt="Overview dashboard surface" width="1920" height="1333" data-path="assets/dashboard-overview.png" />
</Frame>

<Frame caption="Entities — every business entity bound out of the raw schema, with PII exposure, binding confidence, metrics, and join counts.">
  <img src="https://mintcdn.com/schemabrain/vxsNBZD3F847_0vI/assets/dashboard-entities.png?fit=max&auto=format&n=vxsNBZD3F847_0vI&q=85&s=d7661dc39bd3e4b72df963b889a47e3f" alt="Entities dashboard surface" width="1920" height="1333" data-path="assets/dashboard-entities.png" />
</Frame>

<Frame caption="Data Dictionary — every table, column, type, PII class, and join, exportable to Markdown for your repo or wiki.">
  <img src="https://mintcdn.com/schemabrain/vxsNBZD3F847_0vI/assets/dashboard-dict.png?fit=max&auto=format&n=vxsNBZD3F847_0vI&q=85&s=794d91b6b7a9c1dccbd3d0c51ed9ada0" alt="Data Dictionary dashboard surface" width="1920" height="1333" data-path="assets/dashboard-dict.png" />
</Frame>

<Frame caption="PII matrix — one row per classified column across the 12 PII categories, each tagged block / redact / allow; catastrophic columns are hard-blocked regardless of policy.">
  <img src="https://mintcdn.com/schemabrain/vxsNBZD3F847_0vI/assets/dashboard-pii-ledger.png?fit=max&auto=format&n=vxsNBZD3F847_0vI&q=85&s=206ddaf51842f0a5ee49a30d25cbbc38" alt="PII matrix dashboard surface" width="1920" height="1333" data-path="assets/dashboard-pii-ledger.png" />
</Frame>

<Frame caption="Refusals — every held call; expand a row to reveal the reason that fired, the blocked category set, the recovery hint, and the reconstructed envelope.">
  <img src="https://mintcdn.com/schemabrain/vxsNBZD3F847_0vI/assets/dashboard-refusals.png?fit=max&auto=format&n=vxsNBZD3F847_0vI&q=85&s=2ad395e225e27bb40787bbe7974c42f5" alt="Refusals dashboard surface" width="1920" height="1333" data-path="assets/dashboard-refusals.png" />
</Frame>

<Frame caption="Audit Viewer — the tamper-evident chain spined by a derived Merkle root, re-walked and verified intact down to each row's inclusion proof.">
  <img src="https://mintcdn.com/schemabrain/vxsNBZD3F847_0vI/assets/dashboard-audit-viewer.png?fit=max&auto=format&n=vxsNBZD3F847_0vI&q=85&s=e41dea9e60514300a652b065667300d5" alt="Audit Viewer dashboard surface" width="1920" height="1333" data-path="assets/dashboard-audit-viewer.png" />
</Frame>

<Frame caption="Policy — the block / redact / allow grid the firewall enforces, with the always-on catastrophic-leak floor disclosed and the schemabrain.yaml it compiles.">
  <img src="https://mintcdn.com/schemabrain/vxsNBZD3F847_0vI/assets/dashboard-policy.png?fit=max&auto=format&n=vxsNBZD3F847_0vI&q=85&s=23deaad6ce635e6ec6b48bf0a5f5dc51" alt="Policy dashboard surface" width="1920" height="1333" data-path="assets/dashboard-policy.png" />
</Frame>

<Frame caption="Drift — config and enrichment drift the store can detect, each with a copy-the-CLI fix; here, a fresh and in-sync context.">
  <img src="https://mintcdn.com/schemabrain/vxsNBZD3F847_0vI/assets/dashboard-drift.png?fit=max&auto=format&n=vxsNBZD3F847_0vI&q=85&s=732ebb05ab4357690fe5338b75e121f4" alt="Drift dashboard surface" width="1920" height="1333" data-path="assets/dashboard-drift.png" />
</Frame>

It is intentionally a viewer, not a console. No settings, no entity editor, no SQL pad. Configuration still lives in the CLI; YAML still lives on disk.

***

## Install

The dashboard ships as an opt-in extra so the base install stays slim and free of web-server dependencies (`fastapi`, `uvicorn`, `sse-starlette`).

<CodeGroup>
  ```bash pip theme={null}
  pip install 'schemabrain[ui]'
  ```

  ```bash uv theme={null}
  uv pip install 'schemabrain[ui]'
  ```
</CodeGroup>

The pre-built Next.js static export is bundled inside the wheel at `schemabrain/dashboard/static/`. **End users never need Node, npm, or pnpm.** Contributor-dev runs are different — see the repo's `web/README.md`.

<Warning>
  A base `pip install schemabrain` will not boot the dashboard. Running `schemabrain dashboard` without the `[ui]` extra exits with `schemabrain dashboard requires the [ui] extra. Install with 'pip install schemabrain[ui]'.` and a non-zero exit code.
</Warning>

***

## Launch

Index your database first (or run `schemabrain init`), then point the dashboard at the same store:

```bash theme={null}
schemabrain dashboard --store-path ./schemabrain.db
```

You should see:

```
schemabrain dashboard: serving at http://127.0.0.1:7878/
  press Ctrl+C to stop
```

The default browser opens automatically. Pass `--no-open` in CI or on headless machines to skip the auto-open.

### Flags

| Flag                | Default            | Purpose                                                                                                           |
| ------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------- |
| `--store-path PATH` | `./schemabrain.db` | SQLite store written by `schemabrain index`. The sidecar auto-resolves the canonical `source_id` from this store. |
| `--port N`          | `7878`             | TCP port to bind on `127.0.0.1`. Must be in the user-port range (1024-65535).                                     |
| `--no-open`         | (off — auto-opens) | Skip launching the default browser. Use in CI / headless environments.                                            |

<Note>
  **There is no `--host` flag — by design.** The bind host is a constant in `schemabrain/dashboard/sidecar.py` (`BIND_HOST = "127.0.0.1"`). The dashboard is local-only, full stop. Use SSH port-forwarding if you need to view a remote instance.
</Note>

***

## What the sidecar exposes

The FastAPI app declares **only `GET` routes**. There is no `POST`, `PUT`, `PATCH`, or `DELETE` handler anywhere in the surface — a CI invariant test asserts this against the live route table.

| Route                              | Purpose                                                                                                                                                       |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /`                            | Serves the bundled Next.js static export (the UI itself).                                                                                                     |
| `GET /api/health`                  | Liveness + a `SELECT 1` probe against the SQLite store.                                                                                                       |
| `GET /api/meta`                    | Charter version, dashboard schema version, list of indexed sources. Credential-safe — connection URLs are hashed to a canonical short ID before being echoed. |
| `GET /api/entities/pii-matrix`     | Per-entity PII category counts + totals for the PII matrix surface.                                                                                           |
| `GET /api/entities`                | Flat entity list.                                                                                                                                             |
| `GET /api/entities/{name}/columns` | Per-entity column drill-down (physical schema + metrics + canonical joins).                                                                                   |
| `GET /api/audit/rows`              | Paginated rows from `mcp_audit`.                                                                                                                              |
| `GET /api/audit/rows/{id}`         | One audit row with full body.                                                                                                                                 |
| `GET /api/audit/verify`            | Re-walks the chain hash; returns `intact` or `broken`.                                                                                                        |
| `GET /api/audit/merkle/root`       | Derived RFC-6962 Merkle root over every row (`tree_size`, `root_hex`).                                                                                        |
| `GET /api/audit/rows/{id}/proof`   | O(log n) inclusion proof so the browser can reconcile a row to the root.                                                                                      |
| `GET /api/audit/refusals`          | Filtered list of `status='refused'` rows.                                                                                                                     |
| `GET /api/audit/refusals/{id}`     | One refusal row with envelope detail.                                                                                                                         |
| `GET /api/audit/stream`            | Server-Sent Events stream for live row push (2s tick).                                                                                                        |

Every JSON response carries two headers:

* `X-Schemabrain-Charter-Version: 1.2` — the MCP envelope contract.
* `X-Schemabrain-Dashboard-Schema: 1.5` — the dashboard JSON contract.

Consumers can detect protocol drift without parsing the body.

***

## How source resolution works

The `useSourceId()` hook on the client and the `_resolve_source()` helper on the server share one rule: **the dashboard never hardcodes a source ID**. Resolution order:

1. If the request includes `?source_connection_id=...`, use it.
2. Else, if `SidecarConfig.source_connection_id` was set at boot, use it.
3. Else, ask the store for `list_distinct_source_connection_ids()` and pick the first.
4. If the store knows about zero sources, return `null` and let the UI render an empty state.

This means a freshly-installed `schemabrain[ui]` against a previously-indexed store "just works" — no flag plumbing required.

***

## What the dashboard is *not*

* **It is not a write surface.** The sidecar declares no mutating verbs. The UI has no inputs that POST.
* **It is not a SQL console.** SchemaBrain does not execute arbitrary SQL anywhere — see [`/mechanism/read-only`](/mechanism/read-only). The dashboard inherits that posture.
* **It is not network-reachable.** The bind host is hardcoded to `127.0.0.1`. There is no flag, env var, or config file that changes this.
* **It is not authenticated.** Because it binds to localhost, the dashboard relies on OS-level user isolation. Don't run it on a shared multi-user machine without thinking through who owns `127.0.0.1`.
* **It is not a settings editor.** Curate entities, metrics, and joins via the [CLI](/reference/cli/overview). The dashboard reflects state; it does not edit it.
* **It does not include an entity browser.** Editable entity workflows are post-v0.4.

***

## Related

<CardGroup cols={2}>
  <Card title="PII matrix" icon="shield" href="/dashboard/pii-matrix">
    Which entities and columns carry catastrophic-leak categories.
  </Card>

  <Card title="Refusals" icon="ban" href="/dashboard/refusals">
    Live feed of refused tool calls + the envelopes the agent received.
  </Card>

  <Card title="Audit Viewer" icon="signature" href="/dashboard/audit-viewer">
    Tamper-evident audit chain, with one-click verify.
  </Card>

  <Card title="schemabrain dashboard CLI" icon="terminal" href="/reference/cli/dashboard">
    Flags and defaults for the launch command.
  </Card>
</CardGroup>
