Developing in Lightdash
For in-process agents and MCP clients working with JSON content tools; Autopilot reuses the chart references with its own workflow.
Use this skill when working with Lightdash dashboards and charts.
MCP tool names
This skill is shared with Lightdash's native agent, so its workflows use camelCase tool names. When reading it through MCP:
- Use
read_content, edit_content, and create_content for readContent, editContent, and createContent.
- Use
grep_fields and get_metadata for native grepFields and getMetadata.
- Use
generate_hashes for native generateHashes.
- Replace
runContentQuery with run_metric_query to validate a chart's governed semantic-layer metricQuery. Do not use run_sql for this validation.
What You Can Do
| Task |
Tools/Action |
References |
| Read dashboards and charts |
readContent |
dashboard-reference, chart refs |
| Read data apps (read-only) |
readContent with type: data_app |
manifest-shaped JSON, no source code |
| Edit dashboards |
editContent with RFC6902 JSON Patch |
dashboard-reference |
| Edit charts and tiles |
editContent, then update referencing dashboards if needed |
Chart refs, dashboard-reference |
| Create charts |
grepFields, getMetadata, runContentQuery, createContent |
Chart refs |
| Create dashboards |
grepFields, getMetadata, createContent |
dashboard-reference, best practices |
| Add period comparisons |
Edit chart metricQuery and config |
period-over-period-reference |
| Verify changed metric queries |
runContentQuery with source.type: "metricQuery" |
Chart refs |
Rules:
- Always read content before editing if you have not read it since the last user message.
- Preserve unrelated fields.
- Prefer minimal patches.
- Follow the dashboard or chart shape from the resource instead of inventing structure.
- When you create or edit content, please provide links for them in the final response
Common Mistakes
| Mistake |
Consequence |
Prevention |
| Guessing filter values |
Case mismatches like "Payment" vs "payment" can make a chart silently return no data |
Verify exact values before editing filters. Do not guess string filter values |
| Not updating dashboard tiles after renaming a chart |
Dashboard tile still shows the old title because tile title and chartName do not auto-update |
If you change a chart's name or purpose, also update dashboard tiles that reference its chartSlug |
Including unused dimensions in metricQuery |
Extra dimensions change grouping and can produce wrong numbers |
Every dimension in metricQuery.dimensions must be used by the chart configuration |
| Leaving invalid touched tile positions |
Edited tiles overlap, sit outside the 36-column grid, or leave unintended gaps |
Validate touched tiles against dashboard-reference grid layout rules after tile actions |
Missing contentType |
Content type becomes ambiguous |
Always keep contentType: "chart" or contentType: "dashboard" |
Core Workflows
Edit Dashboards
- Call
readContent and inspect the current JSON shape.
- Always read the
dashboard-reference resource.
- Build the smallest possible JSON Patch.
- Call
editContent with that patch.
- Re-read if needed to verify the final state.
Edit Charts and Dashboard Tiles
- Call
readContent for the chart slug.
- Always read the chart reference for chart type (see
Choosing the Right Chart Type below).
- If you add or change filters, verify exact filter values before patching.
- If you change the chart's name or purpose, also update dashboards that reference that chart.
- Build the smallest possible JSON Patch.
- If you changed the chart's
metricQuery, call runContentQuery with source.type: "metricQuery" and the edited chart's tableName/metricQuery.
- Call
editContent with that patch.
- Re-read if needed to verify the final state.
Create Charts
- Use
grepFields, then getMetadata, to explore available fields and plan your chart.
- Always read the chart reference for chart type (see
Choosing the Right Chart Type below) to understand required fields and configuration.
- Build the full chart JSON with that metric query and other required fields.
- Call
runContentQuery with source.type: "metricQuery" and the chart's tableName/metricQuery.
- Call
createContent with the verified chart JSON.
Create Dashboards
- Always read the
dashboard-reference and dashboard-best-practices resources.
- Explore existing dashboards and charts to find reusable content and inspiration for layout and design.
- Use
grepFields, then getMetadata, to explore available fields and plan which charts to include.
- Create an empty dashboard shell first.
- Start building charts and adding them to the dashboard one by one, using the workflow above for creating charts.
Editing Charts
Dashboard tiles have their own titles. A saved_chart tile's title and chartName are independent overrides and do not automatically change when a chart is renamed. If you change a chart from "Total Revenue" to "Gross Profit", update the dashboard tile too.
{
"tiles": [
{
"properties": {
"chartName": "Gross Profit",
"chartSlug": "total-revenue-kpi",
"title": "Gross Profit"
},
"type": "saved_chart"
}
]
}
Slug Fields
slug is a read-only stable identifier.
Dashboards
spaceSlug is the dashboard's space path. Changing it moves the dashboard to another space.
- Dashboard tile
properties.chartSlug references an existing reusable or dashboard-owned chart.
Charts
Charts are either reusable space charts or dashboard-owned charts.
- Reusable chart: no
dashboardSlug; spaceSlug is its space path and changing it moves the chart.
- Dashboard-owned chart: has
dashboardSlug; both dashboardSlug and spaceSlug are read-only, and spaceSlug is the owning dashboard's space.
Chart Types
All charts share a common base structure:
{
"chartConfig": {
"config": {},
"type": "<type>"
},
"contentType": "chart",
"dashboardSlug": "my-dashboard",
"metricQuery": {
"dimensions": ["my_explore_category"],
"exploreName": "my_explore",
"filters": {},
"limit": 500,
"metrics": ["my_explore_total_sales"],
"sorts": []
},
"name": "Chart Name",
"slug": "unique-chart-slug",
"spaceSlug": "target-space",
"tableConfig": {
"columnOrder": []
},
"tableName": "my_explore",
"version": 1
}
Spaces can be nested. Use parent/child syntax in spaceSlug for sub-spaces, for example "sales/forecasts". A bare slug like "sales-forecasts" is a flat top-level space; the slash defines the hierarchy.
Choosing the Right Chart Type
| Data Pattern |
Recommended Chart |
Why |
| Trends over time |
Line or area (cartesian) |
Shows continuous change with time on the X-axis |
| Category comparisons |
Bar (cartesian) |
Easy visual comparison between discrete categories |
| Part-of-whole relationships |
pie or treemap |
Shows proportions or composition |
| Single KPI metric |
big_number |
Focuses attention on one important value |
| Conversion stages |
funnel |
Shows drop-off between sequential stages |
| Progress toward target |
gauge |
Shows current value relative to a goal |
| Geographic data |
map |
Places values on points or regions |
| Flow between categories |
sankey |
Shows how values move from source to target |
| Detailed records |
table |
Shows row-level or pivoted data clearly |
| Advanced custom needs |
custom |
Full Vega-Lite control |
| Type |
Use Case |
Resource |
cartesian |
Bar, line, area, scatter |
cartesian-chart-reference |
pie |
Parts of whole |
pie-chart-reference |
table |
Data tables |
table-chart-reference |
big_number |
KPIs |
big-number-chart-reference |
funnel |
Conversion funnels |
funnel-chart-reference |
gauge |
Progress indicators |
gauge-chart-reference |
treemap |
Hierarchical composition |
treemap-chart-reference |
map |
Geographic data |
map-chart-reference |
sankey |
Flow diagrams |
sankey-chart-reference |
custom |
Vega-Lite |
custom-viz-reference |
For period comparisons, read period-over-period-reference in addition to the chart type reference.
Resources
Charts
cartesian-chart-reference - Bar, line, area, scatter
pie-chart-reference - Parts of whole
table-chart-reference - Data tables
big-number-chart-reference - KPIs
funnel-chart-reference - Conversion funnels
gauge-chart-reference - Progress indicators
treemap-chart-reference - Hierarchical composition
map-chart-reference - Geographic data
sankey-chart-reference - Flow diagrams
custom-viz-reference - Vega-Lite
period-over-period-reference - PoP comparisons
field-formatting-reference - Chart-level field formatting overrides for metrics and dimensions
Dashboards
dashboard-reference - Dashboard structure, layout, tabs, tiles, and filters
dashboard-best-practices - Dashboard design guidance
1---2name: developing-in-lightdash-33description: Use when reading, creating, and editing Lightdash dashboards and charts as JSON, including dashboard layout and chart-type-specific configuration.4---56# Developing in Lightdash78For in-process agents and MCP clients working with JSON content tools; Autopilot reuses the chart references with its own workflow.910Use this skill when working with Lightdash dashboards and charts.1112## MCP tool names1314This skill is shared with Lightdash's native agent, so its workflows use camelCase tool names. When reading it through MCP:1516- Use `read_content`, `edit_content`, and `create_content` for `readContent`, `editContent`, and `createContent`.17- Use `grep_fields` and `get_metadata` for native `grepFields` and `getMetadata`.18- Use `generate_hashes` for native `generateHashes`.19- Replace `runContentQuery` with `run_metric_query` to validate a chart's governed semantic-layer `metricQuery`. Do not use `run_sql` for this validation.2021## What You Can Do2223| Task | Tools/Action | References |24| ----------------------------- | --------------------------------------------------------------- | ------------------------------------- |25| Read dashboards and charts | `readContent` | `dashboard-reference`, chart refs |26| Read data apps (read-only) | `readContent` with `type: data_app` | manifest-shaped JSON, no source code |27| Edit dashboards | `editContent` with RFC6902 JSON Patch | `dashboard-reference` |28| Edit charts and tiles | `editContent`, then update referencing dashboards if needed | Chart refs, `dashboard-reference` |29| Create charts | `grepFields`, `getMetadata`, `runContentQuery`, `createContent` | Chart refs |30| Create dashboards | `grepFields`, `getMetadata`, `createContent` | `dashboard-reference`, best practices |31| Add period comparisons | Edit chart `metricQuery` and config | `period-over-period-reference` |32| Verify changed metric queries | `runContentQuery` with `source.type: "metricQuery"` | Chart refs |3334Rules:3536- Always read content before editing if you have not read it since the last user message.37- Preserve unrelated fields.38- Prefer minimal patches.39- Follow the dashboard or chart shape from the resource instead of inventing structure.40- When you create or edit content, please provide links for them in the final response4142## Common Mistakes4344| Mistake | Consequence | Prevention |45| ------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- |46| **Guessing filter values** | Case mismatches like `"Payment"` vs `"payment"` can make a chart silently return no data | Verify exact values before editing filters. Do not guess string filter values |47| **Not updating dashboard tiles after renaming a chart** | Dashboard tile still shows the old title because tile `title` and `chartName` do not auto-update | If you change a chart's name or purpose, also update dashboard tiles that reference its `chartSlug` |48| **Including unused dimensions in `metricQuery`** | Extra dimensions change grouping and can produce wrong numbers | Every dimension in `metricQuery.dimensions` must be used by the chart configuration |49| **Leaving invalid touched tile positions** | Edited tiles overlap, sit outside the 36-column grid, or leave unintended gaps | Validate touched tiles against `dashboard-reference` grid layout rules after tile actions |50| **Missing `contentType`** | Content type becomes ambiguous | Always keep `contentType: "chart"` or `contentType: "dashboard"` |5152## Core Workflows5354### Edit Dashboards55561. Call `readContent` and inspect the current JSON shape.572. Always read the `dashboard-reference` resource.583. Build the smallest possible JSON Patch.594. Call `editContent` with that patch.605. Re-read if needed to verify the final state.6162### Edit Charts and Dashboard Tiles63641. Call `readContent` for the chart slug.652. Always read the chart reference for chart type (see `Choosing the Right Chart Type` below).663. If you add or change filters, verify exact filter values before patching.674. If you change the chart's name or purpose, also update dashboards that reference that chart.685. Build the smallest possible JSON Patch.696. If you changed the chart's `metricQuery`, call `runContentQuery` with `source.type: "metricQuery"` and the edited chart's `tableName`/`metricQuery`.707. Call `editContent` with that patch.718. Re-read if needed to verify the final state.7273### Create Charts74751. Use `grepFields`, then `getMetadata`, to explore available fields and plan your chart.762. Always read the chart reference for chart type (see `Choosing the Right Chart Type` below) to understand required fields and configuration.773. Build the full chart JSON with that metric query and other required fields.784. Call `runContentQuery` with `source.type: "metricQuery"` and the chart's `tableName`/`metricQuery`.795. Call `createContent` with the verified chart JSON.8081### Create Dashboards82831. Always read the `dashboard-reference` and `dashboard-best-practices` resources.842. Explore existing dashboards and charts to find reusable content and inspiration for layout and design.853. Use `grepFields`, then `getMetadata`, to explore available fields and plan which charts to include.864. Create an empty dashboard shell first.875. Start building charts and adding them to the dashboard one by one, using the workflow above for creating charts.8889## Editing Charts9091Dashboard tiles have their own titles. A `saved_chart` tile's `title` and `chartName` are independent overrides and do not automatically change when a chart is renamed. If you change a chart from `"Total Revenue"` to `"Gross Profit"`, update the dashboard tile too.9293```json94{95 "tiles": [96 {97 "properties": {98 "chartName": "Gross Profit",99 "chartSlug": "total-revenue-kpi",100 "title": "Gross Profit"101 },102 "type": "saved_chart"103 }104 ]105}106```107108## Slug Fields109110`slug` is a read-only stable identifier.111112### Dashboards113114- `spaceSlug` is the dashboard's space path. Changing it moves the dashboard to another space.115- Dashboard tile `properties.chartSlug` references an existing reusable or dashboard-owned chart.116117### Charts118119Charts are either reusable space charts or dashboard-owned charts.120121- Reusable chart: no `dashboardSlug`; `spaceSlug` is its space path and changing it moves the chart.122- Dashboard-owned chart: has `dashboardSlug`; both `dashboardSlug` and `spaceSlug` are read-only, and `spaceSlug` is the owning dashboard's space.123124## Chart Types125126All charts share a common base structure:127128```json129{130 "chartConfig": {131 "config": {},132 "type": "<type>"133 },134 "contentType": "chart",135 "dashboardSlug": "my-dashboard",136 "metricQuery": {137 "dimensions": ["my_explore_category"],138 "exploreName": "my_explore",139 "filters": {},140 "limit": 500,141 "metrics": ["my_explore_total_sales"],142 "sorts": []143 },144 "name": "Chart Name",145 "slug": "unique-chart-slug",146 "spaceSlug": "target-space",147 "tableConfig": {148 "columnOrder": []149 },150 "tableName": "my_explore",151 "version": 1152}153```154155Spaces can be nested. Use `parent/child` syntax in `spaceSlug` for sub-spaces, for example `"sales/forecasts"`. A bare slug like `"sales-forecasts"` is a flat top-level space; the slash defines the hierarchy.156157## Choosing the Right Chart Type158159| Data Pattern | Recommended Chart | Why |160| --------------------------- | -------------------------- | -------------------------------------------------- |161| Trends over time | Line or area (`cartesian`) | Shows continuous change with time on the X-axis |162| Category comparisons | Bar (`cartesian`) | Easy visual comparison between discrete categories |163| Part-of-whole relationships | `pie` or `treemap` | Shows proportions or composition |164| Single KPI metric | `big_number` | Focuses attention on one important value |165| Conversion stages | `funnel` | Shows drop-off between sequential stages |166| Progress toward target | `gauge` | Shows current value relative to a goal |167| Geographic data | `map` | Places values on points or regions |168| Flow between categories | `sankey` | Shows how values move from source to target |169| Detailed records | `table` | Shows row-level or pivoted data clearly |170| Advanced custom needs | `custom` | Full Vega-Lite control |171172| Type | Use Case | Resource |173| ------------ | ------------------------ | ---------------------------- |174| `cartesian` | Bar, line, area, scatter | `cartesian-chart-reference` |175| `pie` | Parts of whole | `pie-chart-reference` |176| `table` | Data tables | `table-chart-reference` |177| `big_number` | KPIs | `big-number-chart-reference` |178| `funnel` | Conversion funnels | `funnel-chart-reference` |179| `gauge` | Progress indicators | `gauge-chart-reference` |180| `treemap` | Hierarchical composition | `treemap-chart-reference` |181| `map` | Geographic data | `map-chart-reference` |182| `sankey` | Flow diagrams | `sankey-chart-reference` |183| `custom` | Vega-Lite | `custom-viz-reference` |184185For period comparisons, read `period-over-period-reference` in addition to the chart type reference.186187## Resources188189### Charts190191- `cartesian-chart-reference` - Bar, line, area, scatter192- `pie-chart-reference` - Parts of whole193- `table-chart-reference` - Data tables194- `big-number-chart-reference` - KPIs195- `funnel-chart-reference` - Conversion funnels196- `gauge-chart-reference` - Progress indicators197- `treemap-chart-reference` - Hierarchical composition198- `map-chart-reference` - Geographic data199- `sankey-chart-reference` - Flow diagrams200- `custom-viz-reference` - Vega-Lite201- `period-over-period-reference` - PoP comparisons202- `field-formatting-reference` - Chart-level field formatting overrides for metrics and dimensions203204### Dashboards205206- `dashboard-reference` - Dashboard structure, layout, tabs, tiles, and filters207- `dashboard-best-practices` - Dashboard design guidance