MCP server for Preset (managed Apache Superset). Manage dashboards, charts, and datasets from Claude Code and other LLM agents.
Claude Code ──STDIO──> preset-mcp ──> Preset API
- Log in to app.preset.io
- Go to Settings > API Keys
- Create a new token/secret pair
- Copy both the token and secret
uv tool install preset-mcp --with preset-cli --with fastmcp --with sqlglot --with pydanticclaude mcp add --scope user -e PRESET_API_TOKEN=<your-token> \
-e PRESET_API_SECRET=<your-secret> \
preset-mcp -- preset-mcpTo auto-connect to a specific workspace on startup:
claude mcp add --scope user -e PRESET_API_TOKEN=<your-token> \
-e PRESET_API_SECRET=<your-secret> \
-e PRESET_WORKSPACE="Your Workspace Title" \
preset-mcp -- preset-mcpclaude mcp list
# Should show: preset-mcp ... 63 toolsThen in a Claude Code session, try:
> list my preset workspaces
git clone https://github.com/Evan-Kim2028/preset-mcp.git
cd preset-mcp
uv sync
claude mcp add --scope user -e PRESET_API_TOKEN=<your-token> \
-e PRESET_API_SECRET=<your-secret> \
preset-mcp -- uv run --directory /path/to/preset-mcp preset-mcp| Tool | Purpose |
|---|---|
list_workspaces |
List all workspaces you have access to |
use_workspace |
Switch to a workspace by title |
| Tool | Purpose |
|---|---|
list_dashboards |
List dashboards (with progressive disclosure) |
get_dashboard |
Get detail for a single dashboard (supports response_mode) |
list_charts |
List charts |
get_chart |
Get detail for a single chart (supports response_mode) |
list_datasets |
List datasets |
get_dataset |
Get detail for a single dataset (columns, metrics, SQL) |
list_databases |
List database connections |
get_database |
Get detail for a single database connection |
workspace_catalog |
Relationship-aware topology map |
| Tool | Purpose |
|---|---|
create_dashboard |
Create a new empty dashboard |
create_dataset |
Register a SQL query as a virtual dataset |
create_chart |
Build a chart from a dataset |
| Tool | Purpose |
|---|---|
update_dataset |
Change a dataset's SQL, name, or description |
update_chart |
Change a chart's title, viz type, or parameters |
update_dashboard |
Rename or publish/unpublish a dashboard |
| Tool | Purpose |
|---|---|
export_dashboard |
Export a dashboard ZIP bundle for backup or migration |
import_dashboard |
Import a dashboard ZIP bundle and report affected dashboard IDs |
delete_dashboard |
Delete a dashboard after exporting a backup ZIP |
| Tool | Purpose |
|---|---|
run_sql |
Execute a read-only SQL query through Preset's connection |
query_dataset |
Query a dataset using Superset's metric/dimension abstraction |
| Tool | Purpose |
|---|---|
validate_chart |
Validate a single chart via chart-data execution |
validate_dashboard |
Validate all charts on a dashboard |
validate_chart_render |
Validate chart rendering via headless browser probe |
validate_dashboard_render |
Validate render status across dashboard charts |
verify_chart_workflow |
One-shot chart→dashboard query/render verification |
verify_dashboard_structure |
Validate dashboard layout graph and chart references |
verify_dashboard_workflow |
One-shot dashboard structure/query/render verification |
repair_dashboard_chart_refs |
Repair stale dashboard chart ID references |
list_mutations |
Inspect local mutation audit journal entries |
list_dashboard_snapshots |
List local pre-mutation dashboard snapshots |
restore_dashboard_snapshot |
Restore dashboard layout/settings from local snapshot |
capture_dashboard_template |
Capture reusable dashboard+chart template JSON |
capture_golden_templates |
Batch-export templates from dashboard IDs |
snapshot_workspace |
Full inventory dump for auditing |
The intended workflow pairs preset-mcp with a data warehouse MCP (like igloo-mcp for Snowflake):
1. Explore data in Snowflake (igloo-mcp)
2. Write and validate your SQL (igloo-mcp)
3. workspace_catalog (preset-mcp) — understand what exists
4. list_databases (preset-mcp) — find the database_id
5. create_dataset (preset-mcp) — register the SQL
6. create_chart + create_dashboard (preset-mcp) — build the viz
7. update_dataset / update_chart (preset-mcp) — iterate
All list and detail tools accept a response_mode parameter to control token usage:
compact— IDs and names only (~80% fewer tokens)standard— Key metadata fields (default for list tools)full— Raw API response (default for detail tools)
list_dashboards(response_mode="compact")
→ {"count": 42, "data": [{"id": 1, "dashboard_title": "Revenue"}, ...]}
get_dashboard(dashboard_id=80, response_mode="standard")
→ key fields only, no position_json or json_metadata blobs
Detail tools (get_dashboard, get_chart, get_dataset, get_database) default to full for backward compatibility. Use standard or compact to avoid large payloads — dashboards with 20+ charts can return 50-100K chars in full mode.
run_sql uses sqlglot for AST-based validation:
- Blocks write operations (INSERT, UPDATE, DELETE, DROP, ALTER, MERGE, TRUNCATE, GRANT, REVOKE)
- Detects multi-statement injection (
SELECT 1; DROP TABLE x) - Handles comment-wrapped bypasses (
-- comment\nDELETE FROM x) - Catches CTE-wrapped writes (
WITH x AS (...) DELETE FROM y)
Errors include error_type and hints[] so the LLM can self-recover:
{
"error": "No workspace selected.",
"error_type": "no_workspace",
"hints": [
"Call list_workspaces to see available workspaces.",
"Then call use_workspace('Title') to select one."
]
}JSON logs on stderr (stdout is reserved for the STDIO transport):
{"ts":"2025-02-11 12:00:00","level":"INFO","msg":"tool=list_dashboards status=ok duration_ms=234"}All settings are overridable via environment variables:
| Variable | Default | Purpose |
|---|---|---|
PRESET_API_TOKEN |
(required) | Preset API token |
PRESET_API_SECRET |
(required) | Preset API secret |
PRESET_WORKSPACE |
(optional) | Auto-connect to this workspace |
PRESET_MCP_SQL_ROW_LIMIT |
1000 |
Max rows from SQL queries |
PRESET_MCP_SQL_SAMPLE_ROWS |
5 |
Rows shown in standard mode |
PRESET_MCP_TRUNCATION_THRESHOLD |
50 |
Full-mode truncation cutoff |
PRESET_MCP_TRUNCATION_TAIL |
5 |
Tail rows kept when truncating |
PRESET_MCP_LOG_LEVEL |
INFO |
Logging verbosity |
preset-mcp also works as a standalone Python library (no MCP required):
from preset_py import connect
ws = connect("My Workspace")
dashboards = ws.dashboards()
df = ws.run_sql("SELECT * FROM revenue LIMIT 10", database_id=1)
ws.create_dataset("daily_revenue", "SELECT ...", database_id=1)
ws.create_chart(dataset_id=5, title="Revenue", viz_type="echarts_timeseries_bar")Use params_json for advanced chart params such as ad-hoc filters.
{
"dataset_id": 868,
"title": "USDSUI Distribution",
"viz_type": "pie",
"metrics": "[{\"expressionType\":\"SQL\",\"sqlExpression\":\"AVG(AMOUNT_USD)\",\"label\":\"AVG(AMOUNT_USD)\"}]",
"groupby": "[\"CATEGORY\",\"SOURCE_NAME\"]",
"params_json": "{\"adhoc_filters\":[{\"col\":\"TOKEN_SYMBOL\",\"op\":\"==\",\"val\":\"USDSUI\"}]}"
}Notes:
create_chart.metricsaccepts saved metric names or ad-hoc metric objects.create_chart.template="auto"applies viz-specific defaults for missing fields.params_jsonis validated preflight against dataset columns/metrics.params_jsoncannot include datasource-rebinding keys likeviz_typeordatasource_id.create_chart.repair_dashboard_refsdefaults tofalseso chart creation does not mutate dashboard layouts unless explicitly requested.
update_chart(params_json=...)uses strict validation semantics and treatsparams_jsonas a full viz-compatible params payload.- For viz types with required fields (for example
pieand timeseries charts), partial payloads like only{"color_scheme":"..."}are rejected. - Use
get_chart(chart_id=<id>, response_mode="full")to copy/edit the existing params JSON when you need precise updates.
Use proven dashboards (for example BTC Fight, Walrus, DeepBook) as template sources:
- Find dashboard IDs:
list_dashboards(response_mode="compact")
- Verify layout/query/render health before templating:
verify_dashboard_workflow(dashboard_id=<id>, include_render=true, response_mode="standard")
- Export a single reusable template:
capture_dashboard_template(
dashboard_id=<id>,
portable=true,
include_query_context=false,
include_dataset_schema=true,
output_path="~/.preset-mcp/golden-templates/<name>.json"
)
- Export multiple dashboards in one run:
capture_golden_templates(
dashboard_ids="[80,97,162]",
output_dir="~/.preset-mcp/golden-templates",
portable=true,
include_dataset_schema=true
)
CLI alternative:
uv run scripts/export_golden_templates.py \
--workspace "Mysten Labs--General" \
--dashboard-ids 80,103,102 \
--output-dir ~/.preset-mcp/golden-templates \
--overwriteOptional live smoke test (skipped by default):
PRESET_MCP_ENABLE_LIVE_TESTS=1 \
PRESET_MCP_LIVE_DASHBOARD_IDS=80,103,102 \
uv run --with pytest pytest -q tests/test_live_dashboard_smoke.pyMIT