Skip to main content

EpiDash

CI Python 3.12+ License: MIT Managed with uv

A light, MCP-controlled dashboard service. EpidBot (and any MCP client holding a control key) builds, updates, publishes and unpublishes dashboards through an MCP tool surface; anyone with a dashboard link views it in a minimal web UI. Viewers can ask EpidBot to tweak a dashboard from the browser.

EpidBot agent ──(MCP client, dk_ key)──▶ EpiDash /mcp (FastMCP tools)
                                            │
                       SQLite ◀─────────────┤ (dashboards, charts, keys, audit)
                                            │
Viewer browser ──(public link)──▶ EpiDash / (vanilla JS + Plotly)
      │                                 │
      └── tweak request ──▶ POST /api/dashboards/{slug}/tweak
                                 │  (X-Internal-Request: shared secret)
                                 ▼
                           EpidBot /api/v1/chat ──agent──▶ EpiDash MCP tools

Quick start

uv sync
uv run uvicorn epidash.main:app --port 8000

Then issue a control key and talk to the MCP endpoint:

uv run python -m epidash.cli add-key "local"
# → dk_...  (shown once)
# The MCP endpoint is stateless: one POST per call, no handshake needed.
curl -s -X POST http://localhost:8000/mcp \
  -H "X-API-Key: dk_..." -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

In an MCP client (e.g. Claude Desktop, Cursor, EpidBot):

{
  "mcpServers": {
    "epidash": {
      "url": "http://localhost:8000/mcp",
      "headers": { "X-API-Key": "dk_..." }
    }
  }
}

Configuration (environment variables)

Variable Default Purpose
EPIDASH_DB_PATH data/epidash.db SQLite file (WAL)
EPIDASH_BASE_URL http://localhost:8000 Public base URL for share links
EPIDASH_MCP_PATH /mcp Mount path of the MCP endpoint
EPIDASH_ALLOWED_HOSTS localhost,127.0.0.1 Host header allowlist (DNS-rebinding protection)
EPIDASH_BOOTSTRAP_KEY — Pre-shared dk_ key seeded at startup (infra automation)
EPIDBOT_BASE_URL — EpidBot base URL; enables the tweak flow
EPIDBOT_INTERNAL_SECRET — Shared secret (EpidBot INTERNAL_API_SECRET) or ek_ API key
EPIDASH_TWEAK_RATE_LIMIT_PER_HOUR 20 Per-dashboard viewer tweak budget
EPIDASH_ASK_RATE_LIMIT_PER_HOUR 30 Per-dashboard viewer question budget
EPIDASH_TWEAK_TIMEOUT_S 300 Max wait for an EpidBot tweak turn

MCP tools

Read-only: list_dashboards, get_dashboard, get_view_stats, get_audit_log.

Mutations (audited): create_dashboard, update_dashboard, publish_dashboard (confirm), unpublish_dashboard (confirm), add_chart, update_chart, remove_chart (confirm).

Chart data envelopes

kind data
line, bar, pie, table {"columns": ["month", "cases"], "rows": [["Jan", 120], ...]}
kpi {"value": 1234, "label": "Cases", "unit": "", "delta": "+12%"}
choropleth {"values": {"SP": 120, "RJ": 90}, "region_level": "uf", "label": "cases"}

spec accepts style overrides ({"color": "#4ade80"}, {"y_label": "cases"}) and position controls ordering/width ({"order": 1, "width": "half"}).

Viewer tweak flow

A viewer types a request ("show only the Southeast after 2020") into the dashboard's chat box. EpiDash forwards it as an EpidBot chat turn with the dashboard context; the EpidBot agent uses its EpiDash MCP tools to update the charts; the viewer's browser picks up the change on its next poll.

Viewers can also ask questions ("why did cases spike in March?") via the Ask button — the same chat pipeline, but the prompt instructs EpidBot to answer from the dashboard data without modifying it. No authentication is required for either; questions are recorded in the tweaks table with kind='question' and rate-limited separately from tweaks.

Requires EPIDBOT_BASE_URL + EPIDBOT_INTERNAL_SECRET (EpidBot must accept X-Internal-Request on its chat endpoint — see the EpidBot-side integration docs) or an ek_ API key.

Deployment

Single container, single volume:

docker compose up -d --build

Production (KwarAI) deploys this via the Ansible epidash role behind nginx at dash.kwar-ai.com.br — see the infrastructure repo.

Development

uv sync                  # deps
uv run pytest -v         # tests
uv run ty check epidash/ # type check

License

MIT

Metadata

Release files for epidash 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for epidash 0.2.0
File Size Uploaded Provenance
epidash-0.2.0.tar.gz 1.8 MB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for epidash 0.2.0
File Interpreter ABI Platform
epidash-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 3.5 MB

Release files / epidash-0.2.0.tar.gz

Download URL epidash-0.2.0.tar.gz
Size 1.8 MB
Tags Source
SHA-256 checksum
How to use checksums
b3517d3207818b99dfb60de04e49170adce4eb6d8f9c8b12fb62f154d56c6781
BLAKE2b-256 checksum
How to use checksums
9746d2e8b288016443e5508121a0f60c554a5f1bd3fd6c25556735455d0d4a5e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / epidash-0.2.0-py3-none-any.whl

Download URL epidash-0.2.0-py3-none-any.whl
Size 1.7 MB
Tags Python 3
SHA-256 checksum
How to use checksums
52009a2c635196e3a563a892d79e193025a036883c38bbc96dad360d6170c549
BLAKE2b-256 checksum
How to use checksums
d62410efee90d4ceeb307e49e318365d4b84281873341b39204cc57b2c01d524
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Security for epidash 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for epidash-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page