servers / lightdash-mcp
lightdash_mcp MCP server
communitystdiolocaldestructive capablehealthy
mcp server for lightdash
01Tools · 28
How to read this: tool names here are observed from a live tools/list handshake. The Risk label is a heuristic inferred from the tool name (write/destructive verbs), not from executing the tool — a conservative guess, not a verified capability. We never escalate risk from a description. Found one that's wrong? Tell us — we fix on report.
| Tool | Risk | Side effects | Approval |
|---|---|---|---|
| delete-space Delete a space (folder).
**Important constraints:**
- Cannot delete spaces that contain charts or dashboards
- Must move or delete all content from the space first
- This is a permanent operation
**When to use:**
- To remove empty, unused spaces
- To clean up organizational structure
- After moving all content to other spaces
**Steps to delete a space with content:**
1. List charts and dashboards in the space
2. Move them to other spaces or delete them
3. Delete the now-empty space
**Accepts:** Either space UUID or space name (will search for exact match) | destructive | true | true |
| delete-chart Delete a saved chart from the project.
**Warning:** This is a destructive operation and cannot be undone.
**When to use:**
- To remove outdated or incorrect charts
- To clean up test/development charts
- Before recreating a chart with the same name (delete old, create new)
**Important notes:**
- Charts still referenced on dashboards will show as broken/missing after deletion
- Consider checking which dashboards use this chart before deleting (use get-dashboard-tiles)
- For modifying existing charts, use update-chart instead of delete + recreate
**Accepts:** Either chart UUID or chart name (will search for exact match) | destructive | true | true |
| get-dashboard-tiles Get all tiles from a specific dashboard.
Returns a list of all tiles on the dashboard with their:
- UUID (unique identifier)
- Type (saved_chart, markdown, loom, etc.)
- Title or chart name
- savedChartUuid (for chart tiles)
- Position and size (x, y, h, w)
- OPTIONAL: Full chart configuration if include_full_config=true
**When to use:**
- To see what content is on a dashboard before modifying it
- To find a tile's UUID for update or delete operations
- To understand the layout of a dashboard
- To find which charts are used on a dashboard
- To get full configuration of dashboard-only charts
**Search behavior:** Matches dashboard names case-insensitively with partial matching. | read | false | unknown |
| duplicate-dashboard Create a complete copy of an existing dashboard with a new name.
This copies everything from the source dashboard:
- All tiles with their positions and configurations
- All tabs (if the dashboard has tabs)
- Dashboard-level filters
- Layout and styling
**What gets regenerated:**
- Dashboard UUID (new unique ID)
- Tile UUIDs (new IDs for each tile)
- Tab UUIDs (new IDs for each tab)
**What stays the same:**
- Chart references (tiles still point to the same charts)
- Content and configuration
- Layout and positioning
**When to use:**
- To create dashboard variants for different teams/regions
- To create a test version before modifying production dashboards
- To use an existing dashboard as a template
- To create regional/customer-specific versions
**Best practice:** Use descriptive names to distinguish the copy from the original. | unknown | unknown | unknown |
| get-explore-schema Get the complete schema for an explore/table including all available dimensions, metrics, and joins.
This is **essential before creating charts** to understand what fields exist and their types.
**Returns:**
- **Base table information:** Name, label, description
- **All dimensions by table:** Field IDs, types, labels, descriptions
- **All metrics by table:** Field IDs, types, SQL, labels, descriptions
- **Joins:** How tables are connected, join types, join conditions
- **Summary statistics:** Counts of tables, dimensions, metrics
**Field information includes:**
- `fieldId`: Use this exact value in chart queries (format: `table_fieldname`)
- `type`: Field data type (string, number, date, timestamp, etc.)
- `label`: Human-readable name
- `description`: What the field represents
- `hidden`: Whether field is hidden by default
- `sql`: For metrics, the SQL expression used
**When to use:**
- **Before creating any chart** - to find correct field IDs
- To understand available data and metrics
- To discover join relationships between tables
- To find field types for proper formatting
- To explore what analysis is possible with a data model
**Best practices:**
1. Start with get-catalog or get-metrics-catalog to find relevant explores
2. Use get-explore-schema on specific explores to get detailed field information
3. Copy exact fieldId values when building chart queries
4. Check field descriptions to ensure you're using the right data
**Hidden fields:** By default, hidden fields are excluded. Set include_hidden=true to see all fields including internal/technical ones. | read | false | unknown |
| run-raw-query Execute a raw metric query against a Lightdash explore.
This tool allows you to run arbitrary queries by specifying dimensions, metrics, filters, and sorts directly.
It is useful for:
- Running ad-hoc analysis without creating a saved chart
- Executing queries for dashboard-only charts (which don't have a saved chart UUID)
- Debugging data issues by running simplified queries
**Input:**
- `explore_name`: The name of the explore (table) to query.
- `metric_query`: The query definition (dimensions, metrics, filters, etc.).
- `limit`: Optional row limit.
═══════════════════════════════════════════════════════════════════
COMPLETE WORKING EXAMPLE:
═══════════════════════════════════════════════════════════════════
metric_query:
{
"dimensions": ["my_table_date_day"],
"metrics": [],
"filters": {
"dimensions": {
"id": "root",
"and": [
{
"id": "filter_1",
"target": {"fieldId": "my_table_country"},
"operator": "equals",
"values": ["US"]
},
{
"id": "filter_2",
"target": {"fieldId": "my_table_date_day"},
"values": [30],
"operator": "inThePast",
"required": false,
"settings": {
"completed": false,
"unitOfTime": "days"
}
}
]
}
},
"sorts": [{"fieldId": "my_table_date_day", "descending": true}],
"limit": 500,
"tableCalculations": [],
"additionalMetrics": [
{
"name": "dau",
"label": "Daily Active Users",
"description": "Count of unique users",
"type": "count_distinct",
"sql": "${TABLE}.user_id",
"table": "my_table",
"baseDimensionName": "user_id",
"formatOptions": {"type": "default", "separator": "default"}
}
]
}
**Key Rules:**
1. **Field IDs**: Use `table_field` format (e.g., `orders_amount`). Use `get-explore-schema` to find correct IDs.
2. **Filters**:
- Simple: `{"operator": "equals", "values": ["value"]}`
- Time: `{"operator": "inThePast", "values": [7], "settings": {"unitOfTime": "days", "completed": false}}`
3. **Additional Metrics**: Use this to create ad-hoc metrics (like count distinct) that aren't in the dbt model.
| write | true | unknown |
| list-projects List all projects in your Lightdash organization.
Returns project information including:
- Project UUID (required for other API calls)
- Project name and type
- Database connection details (warehouse type)
- Creation and update timestamps
**When to use:** Start here to discover available projects or to find the UUID of a project you want to work with. If LIGHTDASH_PROJECT_UUID environment variable is set, most other tools will use that project automatically. | read | false | unknown |
| list-explores List all available explores/tables in the project catalog.
Returns a catalog of all tables/explores organized by project and dataset:
- Explore/table names
- Table descriptions
- SQL table references
**When to use:**
- To discover what tables/explores are available in the project
- To browse the data catalog and find relevant tables by description
- Before using get-explore-schema to get detailed field information
**Best practice:** Use this for initial discovery to find table names, then use get-explore-schema for detailed dimensions, metrics, and joins.
**Note:** This can return large amounts of data for projects with many explores. | read | false | unknown |
| get-dashboard-tile-chart-config Get the complete chart configuration for a dashboard tile, including dashboard-only charts.
Dashboard-only charts store their full configuration (metric query, chart config, visualization settings)
directly in the dashboard tile structure. This tool extracts that complete configuration.
**Returns:**
- Complete chart configuration including:
- metricQuery: The query configuration (dimensions, metrics, filters, sorts)
- chartConfig: Visualization configuration (chart type, axes, series)
- tableConfig: Table column configuration
- pivotConfig: Pivot configuration if applicable
- For saved charts: retrieves the chart via the savedChartUuid reference
- For dashboard-only charts: extracts from tile's belongsToChart property
**When to use:**
- To get full details of a a chart visible on a dashboard
- To understand the configuration of dashboard-only charts
- To export or duplicate dashboard-only chart configurations
- Before modifying a dashboard tile's chart
**Parameters:**
- dashboard_name: Name of the dashboard (supports partial matching)
- tile_identifier: Title of the tile or partial match | read | false | unknown |
| get-project Get detailed information about a specific project.
Returns comprehensive project details including:
- Project configuration and settings
- Warehouse connection information
- dbt integration details
- Project metadata
**When to use:** When you need detailed configuration information about a specific project, such as its warehouse connection, dbt settings, or other metadata.
**Parameters:**
- project_uuid: Optional. If not provided, uses the current/default project. | read | false | unknown |
| update-dashboard-tile Update any properties of a tile on a dashboard.
You can modify multiple tile properties in a single operation:
**Position properties** (at tile level):
- `x`, `y`: Change tile position
- `h`, `w`: Resize tile
**Display properties** (in properties object):
- `title`: Change display name
- `content`: Update markdown content
- `savedChartUuid`: Change which chart is displayed (for saved_chart tiles)
- Any other tile-specific properties
**CRITICAL - Grid System:**
Lightdash uses a **36-column grid** horizontally:
- For 2 tiles per row: `w: 18` each (x: 0 and x: 18)
- For 3 tiles per row: `w: 12` each (x: 0, x: 12, x: 24)
- For full-width tile: `w: 36`
**When to use:**
- To reposition or resize tiles on a dashboard
- To update multiple tile properties at once
- To change content of markdown tiles
- To swap which chart is displayed in a chart tile
**Example properties_update values:**
- Two tiles per row: `{"x": 0, "y": 0, "h": 6, "w": 18}` and `{"x": 18, "y": 0, "h": 6, "w": 18}`
- Full width: `{"x": 0, "w": 36, "h": 6}`
- Reposition: `{"x": 0, "y": 10}` | write | true | unknown |
| list-spaces List all spaces (folders) in the Lightdash project.
Spaces are organizational folders that contain charts and dashboards.
**Returns for each space:**
- UUID and name
- Whether it's private (restricted access)
- Count of charts in the space
- Count of dashboards in the space
**When to use:**
- To discover organizational structure of content
- To find space UUIDs for creating charts
- To get an overview of content organization
- Before creating new spaces to avoid duplicates
**Space types:**
- Public spaces: Visible to all project users
- Private spaces: Restricted to specific users/groups | read | false | unknown |
| create-chart Create a new saved chart in a space. Requires table name, metric query, and chart configuration.
⚠️ CRITICAL: Chart configuration structure must be precise or the chart will break!
═══════════════════════════════════════════════════════════════════
COMPLETE WORKING EXAMPLE - Line Chart with Count Distinct Metric:
═══════════════════════════════════════════════════════════════════
metricQuery:
{
"exploreName": "my_table",
"dimensions": ["my_table_date_day"],
"metrics": [],
"filters": {
"dimensions": {
"id": "root",
"and": [
{
"id": "filter_1",
"target": {"fieldId": "my_table_country"},
"operator": "equals",
"values": ["US"]
},
{
"id": "filter_2",
"target": {"fieldId": "my_table_date_day"},
"values": [30],
"operator": "inThePast",
"required": false,
"settings": {
"completed": false,
"unitOfTime": "days"
}
}
]
}
},
"sorts": [{"fieldId": "my_table_date_day", "descending": true}],
"limit": 500,
"tableCalculations": [],
"additionalMetrics": [
{
"name": "dau",
"label": "Daily Active Users",
"description": "Count of unique users",
"type": "count_distinct",
"sql": "${TABLE}.user_id",
"table": "my_table",
"baseDimensionName": "user_id",
"formatOptions": {"type": "default", "separator": "default"}
}
]
}
chartConfig:
{
"type": "cartesian",
"config": {
"layout": {
"xField": "my_table_date_day",
"yField": ["my_table_dau"],
"flipAxes": false
},
"eChartsConfig": {
"xAxis": [{"name": "Date"}],
"yAxis": [{"name": "DAU"}],
"series": [
{
"type": "line",
"encode": {
"xRef": {"field": "my_table_date_day"},
"yRef": {"field": "my_table_dau"}
},
"yAxisIndex": 0
}
]
}
}
}
pivotConfig (optional):
{
"columns": ["my_table_country"]
}
═══════════════════════════════════════════════════════════════════
EXAMPLE WITH CUSTOM DIMENSIONS - Stacked/Segmented Charts:
═══════════════════════════════════════════════════════════════════
Use Case: Create grouped/segmented visualizations by categorizing data into
meaningful buckets (e.g., Top N + "Other" pattern, status groupings, etc.)
metricQuery:
{
"exploreName": "your_table",
"dimensions": ["your_table_date_day", "category_dimension"],
"metrics": [],
"filters": {
"dimensions": {
"id": "root",
"and": [
{
"id": "filter_1",
"target": {"fieldId": "your_table_date_day"},
"values": [30],
"operator": "inThePast",
"required": false,
"settings": {"completed": false, "unitOfTime": "days"}
}
]
}
},
"sorts": [{"fieldId": "your_table_date_day", "descending": true}],
"limit": 500,
"additionalMetrics": [
{
"name": "unique_count",
"label": "Unique Count",
"type": "count_distinct",
"sql": "${TABLE}.identifier_column",
"table": "your_table",
"baseDimensionName": "identifier_column"
}
],
"customDimensions": [
{
"id": "category_dimension",
"name": "Category Dimension",
"type": "sql",
"table": "your_table",
"sql": "CASE\n WHEN raw_field = 'value1' THEN 'Category A'\n WHEN raw_field = 'value2' THEN 'Category B'\n WHEN raw_field IN ('value3', 'value4') THEN 'Category C'\n ELSE 'Other'\n END",
"dimensionType": "string"
}
]
}
chartConfig:
{
"type": "cartesian",
"config": {
"layout": {
"xField": "your_table_date_day",
"yField": ["your_table_unique_count"],
"flipAxes": false
},
"eChartsConfig": {
"xAxis": [{"name": "Date"}],
"yAxis": [{"name": "Count"}],
"series": [
{
"type": "bar",
"stack": "your_table_unique_count",
"encode": {
"xRef": {"field": "your_table_date_day"},
"yRef": {"field": "your_table_unique_count"}
},
"yAxisIndex": 0
}
]
}
}
}
pivotConfig:
{
"columns": ["category_dimension"]
}
Key Pattern: The custom dimension "category_dimension" is:
1. Defined in customDimensions with SQL CASE logic
2. Added to dimensions array for grouping
3. Used in pivotConfig.columns to create separate stacks/segments per category
Result: One stacked segment per CASE branch, visualizing data by category over time
═══════════════════════════════════════════════════════════════════
KEY RULES (MUST FOLLOW):
═══════════════════════════════════════════════════════════════════
1. additionalMetrics naming:
- Metrics are referenced as: "{table}_{metricName}"
- Example: table="my_table", name="dau" → "my_table_dau"
2. series.encode MUST use objects (NOT strings):
✅ CORRECT: "xRef": {"field": "my_table_date_day"}
❌ WRONG: "xRef": "my_table_date_day"
3. eChartsConfig.series is required:
- Must have at least one series object
- Each series MUST have: type, encode.xRef, encode.yRef
4. Metric types for additionalMetrics:
- "count_distinct": COUNT(DISTINCT field)
- "count": COUNT(*)
- "sum": SUM(field)
- "avg": AVG(field)
- "min": MIN(field)
- "max": MAX(field)
5. Filter operators and structures:
**Simple filters:**
- "equals": {"operator": "equals", "values": ["US"]}
- "notEquals": {"operator": "notEquals", "values": ["US"]}
- "contains": {"operator": "contains", "values": ["search_term"]}
- "notNull": {"operator": "notNull"}
- "isNull": {"operator": "isNull"}
**Time-based filters (CRITICAL - note the structure):**
The "inThePast" operator requires specific structure:
{
"id": "filter_1",
"target": {"fieldId": "table_date_field"},
"values": [30], # ← Number goes HERE in values array
"operator": "inThePast",
"required": false,
"settings": {
"completed": false, # ← Must be FALSE (not true)
"unitOfTime": "days" # Options: "days", "weeks", "months", "years"
}
}
⚠️ Common mistakes to AVOID:
❌ WRONG: "settings": {"number": 30} → Number does NOT go in settings
❌ WRONG: "completed": true → Must be false
✅ CORRECT: "values": [30] + "completed": false
6. Pivot configuration:
- Use pivotConfig to split series by dimension values
- Example: {"columns": ["my_table_country"]} creates one line per country
- This enables grouping/segmentation in charts
7. Custom Dimensions (customDimensions):
- Create calculated dimensions using SQL expressions (CASE, CONCAT, etc.)
- Custom dimensions can be used in dimensions array, pivots, and filters
- Each custom dimension requires: id, name, type, table, sql, dimensionType
**Structure:**
{
"id": "custom_dim_id", # Unique identifier to reference in dimensions/pivots
"name": "Custom Dimension Name", # Display name shown in UI
"type": "sql", # Always "sql" for custom dimensions
"table": "base_table", # Base table name (matches exploreName)
"sql": "CASE WHEN ... THEN ... ELSE ... END", # SQL expression
"dimensionType": "string" # Data type: "string", "number", "date", etc.
}
**Common Patterns:**
a) Top N + "Other" grouping (reduce cardinality):
{
"id": "top_items_group",
"sql": "CASE
WHEN item_name = 'TopItem1' THEN 'TopItem1'
WHEN item_name = 'TopItem2' THEN 'TopItem2'
WHEN item_name IN ('TopItem3', 'TopItem4') THEN 'TopItem3/4'
ELSE 'Other'
END",
"dimensionType": "string"
}
b) Status/Category mapping:
{
"id": "status_group",
"sql": "CASE
WHEN status IN ('active', 'pending') THEN 'Active'
WHEN status IN ('completed', 'archived') THEN 'Completed'
ELSE 'Other'
END",
"dimensionType": "string"
}
c) Numeric bucketing:
{
"id": "value_bucket",
"sql": "CASE
WHEN amount < 10 THEN 'Small'
WHEN amount < 100 THEN 'Medium'
ELSE 'Large'
END",
"dimensionType": "string"
}
**Usage in metricQuery:**
- Add to customDimensions array: "customDimensions": [...]
- Reference by id in dimensions: "dimensions": ["table_date", "custom_dim_id"]
- Use in pivots: "pivotConfig": {"columns": ["custom_dim_id"]}
- Filter on custom dimensions just like regular dimensions
**Benefits:**
- Reduce high-cardinality dimensions to manageable segments
- Apply business logic without modifying base tables
- Create "Top N + Other" patterns for cleaner visualizations
- Categorize raw values into meaningful groups
**With Pivots - Creating Segmented Charts:**
When a custom dimension is used in BOTH dimensions array AND pivotConfig.columns,
Lightdash creates one separate series/segment per unique value from the CASE statement.
Example: 5 CASE branches = 5 stacked segments in the chart.
═══════════════════════════════════════════════════════════════════
CHART TYPES:
═══════════════════════════════════════════════════════════════════
Line Chart: series[].type = "line"
Bar Chart: series[].type = "bar"
Area Chart: series[].type = "line" + series[].areaStyle = {}
Stacked Area: series[].type = "line" + series[].areaStyle = {} + series[].stack = "stack_name"
═══════════════════════════════════════════════════════════════════
VALIDATION:
═══════════════════════════════════════════════════════════════════
The server will automatically:
- Validate chart config structure (xRef/yRef objects)
- Validate field references match metricQuery
- Auto-generate tableConfig.columnOrder
- Add additionalMetrics to metrics array for proper display
If validation fails, you'll get a detailed error message.
| write | true | unknown |
| list-dashboards List all dashboards in the Lightdash project.
Returns dashboard metadata including:
- Dashboard UUID and name
- Description
- Space (folder) the dashboard belongs to
- View and update timestamps
**When to use:**
- To discover available dashboards
- To find a dashboard UUID for other operations
- To get an overview of dashboard organization
**Next steps:** Use get-dashboard-tiles to see what's on a dashboard, or get-dashboard-code to get the complete configuration. | read | false | unknown |
| update-dashboard-filters Update dashboard-level filters that apply to all tiles.
Dashboard filters allow users to:
- Filter all charts on a dashboard at once
- Create interactive dashboards where users can change filters
- Implement global date ranges or category filters
**Filter configuration structure:**
Filters use the same structure as chart filters with:
- Field references (fieldId)
- Operators (equals, notEquals, contains, greaterThan, etc.)
- Values or value ranges
- Time-based filters (inThePast, inTheNext, etc.)
**When to use:**
- To add global date range selectors
- To create region/category filters that apply to all charts
- To update filter options or defaults
- To remove filters that are no longer needed
**Important:** Changes apply immediately to all dashboard viewers.
**Testing:** Use run-dashboard-chart after updating to verify filters work as expected. | write | true | unknown |
| list-charts List all saved charts in the Lightdash project.
Returns chart information including:
- Chart UUID and name
- Space (folder) the chart belongs to
- Description
- Last updated timestamp
**When to use:**
- To discover available charts in the project
- To find a chart UUID for adding to dashboards or querying
- To get an overview of what visualizations exist
- To filter charts by name before getting details
**Optional search_term:** Filters the list to only charts matching the search term in their name. | read | false | unknown |
| rename-dashboard-tile Rename a tile on a dashboard by updating its title property.
This is a convenience tool for the common operation of changing a tile's display name.
**When to use:**
- To change the title of a markdown tile
- To override the display name of a chart tile
- Quick title updates without modifying other properties
**For more complex updates:** Use update-dashboard-tile to change multiple properties at once. | write | true | unknown |
| search-charts Search for charts by name or description.
Performs case-insensitive partial matching against:
- Chart names
- Chart descriptions
Returns matching charts with their UUID, name, space, and description.
**When to use:**
- To find charts related to a topic or metric
- When you know part of a chart's name but not the exact name
- To discover charts by business term (if described well)
**Difference from list-charts:** This searches both name AND description, while list-charts only filters by name. | read | false | unknown |
| create-dashboard Create a new dashboard in the Lightdash project.
You can create an empty dashboard (just name and description) or a fully configured dashboard with tiles and tabs.
**Tile Types:**
- `saved_chart`: Display a saved chart (requires savedChartUuid in properties)
- `markdown`: Text/markdown content (requires title and content in properties)
- `loom`: Embedded Loom video (requires url in properties)
**Tile Position Properties (required for each tile):**
- `x`: Column position (0-indexed, grid is 12 columns wide)
- `y`: Row position (0-indexed)
- `h`: Height in grid units
- `w`: Width in grid units (max 12)
**When to use:**
- To create a new empty dashboard that you'll populate later
- To create a fully configured dashboard from a template or copy
- Use duplicate-dashboard if you want to copy an existing dashboard
**Best practice:** Start with an empty dashboard, then use create-dashboard-tile to add content. | write | true | unknown |
| delete-dashboard-tile Delete a tile from a dashboard.
This permanently removes a tile from the dashboard. The operation cannot be undone.
**When to use:**
- To remove outdated or unwanted tiles from a dashboard
- To clean up dashboards during reorganization
- To remove tiles before replacing them with updated versions
**Important notes:**
- This is a destructive operation - the tile cannot be recovered after deletion
- If the tile displays a saved chart, the chart itself is NOT deleted (only the tile reference)
- Dashboard-only charts (charts that exist only in the tile) will be permanently lost
- You should save the dashboard after deletion (this is done automatically)
**Search behavior:** Matches tile titles case-insensitively with partial matching. | destructive | true | true |
| create-dashboard-tile Create a new tile and add it to an existing dashboard.
**Required for all tiles:**
- Position and size: `x`, `y`, `h`, `w` (in the properties JSON)
- Tile type: One of 'saved_chart', 'markdown', 'loom'
**Tile-specific requirements:**
*saved_chart tiles:*
- `savedChartUuid`: UUID of the chart to display (use list-charts to find)
- Optional: `title` to override the chart's name
*markdown tiles:*
- `title`: Display title
- `content`: Markdown content to display
*loom tiles:*
- `url`: Loom video URL
- Optional: `title`
**CRITICAL - Grid system:**
- Dashboard is **36 columns wide** (not 12!)
- `x` ranges from 0-35 (column position)
- `y` is row position (grows downward)
- `w` is width in columns (1-36)
- `h` is height in grid units
- For 2 tiles per row: use `w: 18` each
- For 3 tiles per row: use `w: 12` each
- For full width: use `w: 36`
**When to use:**
- To add charts to a dashboard
- To add markdown documentation/headers
- To embed Loom videos for context
**Best practice:** Use get-dashboard-tiles first to see existing layout and find an empty position. | write | true | unknown |
| create-space Create a new space (folder) to organize charts and dashboards.
Spaces help organize content by:
- Team (e.g., "Marketing Analytics", "Finance")
- Product area (e.g., "User Growth", "Revenue")
- Development stage (e.g., "Production Dashboards", "Development")
**When to use:**
- Before creating charts that belong to a new category
- To organize existing content into logical groups
- To set up restricted areas for sensitive data (use is_private=true)
**Best practices:**
- Use descriptive names that indicate content purpose
- Create private spaces for sensitive or work-in-progress content
- Get the space UUID from the response to use when creating charts | write | true | unknown |
| get-custom-metrics Get custom metrics defined in the project.
Custom metrics are user-defined metrics created in the Lightdash UI that aren't part of the dbt model definitions. These are stored separately and can be used in charts and dashboards.
Returns:
- Custom metric definitions
- SQL expressions used to calculate them
- Associated tables/explores
- Labels and descriptions
**When to use:**
- To discover custom business metrics created by analysts
- To understand what custom calculations are available
- Before using a custom metric in a chart or query
**Note:** These are different from metrics defined in your dbt models. | read | false | unknown |
| update-chart Update an existing saved chart's configuration.
This tool allows partial updates - you only need to provide the fields you want to change.
**Updatable fields:**
- `name`: Chart name
- `description`: Chart description
- `metric_query`: JSON string with metricQuery updates (dimensions, metrics, filters, sorts, etc.)
- `chart_config`: JSON string with chartConfig updates (visualization settings)
- `pivot_config`: JSON string with pivotConfig updates
**Common use cases:**
1. **Change sorting:**
metric_query: {"sorts": [{"fieldId": "table_field_name", "descending": false}]}
2. **Update filters:**
metric_query: {"filters": {"dimensions": {"id": "root", "and": [...]}}}
3. **Change chart type:**
chart_config: {"type": "cartesian", "config": {...}}
4. **Add/remove dimensions or metrics:**
metric_query: {"dimensions": ["dim1", "dim2"], "metrics": ["metric1"]}
**Important notes:**
- Uses PATCH endpoint - only provided fields are updated
- For metric_query updates, provide only the keys you want to change
- The tool merges your updates with the existing configuration
- Use get-chart-details first to see current configuration
**Example - Change sort to ascending by name:**
```
chart_identifier: "My Chart Name"
metric_query: {"sorts": [{"fieldId": "table_column_name", "descending": false}]}
``` | write | true | unknown |
| get-chart-details Get detailed information about a specific saved chart.
Returns complete chart configuration including:
- Chart type and visualization settings (eChartsConfig)
- Metric query configuration (dimensions, metrics, filters, sorts)
- Table configuration (column order, conditional formatting)
- Metadata (name, description, space, timestamps)
**When to use:**
- Before modifying or duplicating a chart
- To understand how a chart is configured
- To extract query logic for reuse
- To debug chart issues
**Accepts:** Either chart UUID or chart name (will search for exact match) | read | false | unknown |
| get-dashboard-code Get the complete dashboard configuration including full tile definitions.
Returns the raw dashboard configuration as code, including:
- All tile definitions with complete properties
- Tab configuration
- Filter configuration
- Layout information
- Chart references
**When to use:**
- To export a dashboard for version control
- To understand the complete structure of a complex dashboard
- Before programmatically duplicating a dashboard
- To backup dashboard configurations
- To debug dashboard issues
**Use cases:**
- **Backup:** Save dashboard configs before making changes
- **Version control:** Track dashboard changes over time
- **Migration:** Move dashboards between projects/environments
- **Templates:** Create reusable dashboard templates
**Alternative:** Use duplicate-dashboard for a simpler way to copy dashboards. | read | false | unknown |
| run-chart-query Execute a chart query and return the data results in CSV format.
Runs the chart's configured query against the data warehouse and returns the results as CSV.
**Returns:**
- CSV-formatted string with headers and data rows
- Metadata comment line with row count (format: `# Metadata: {"row_count":N}`)
**When to use:**
- To get actual data from a chart for analysis
- To verify a chart is returning expected results
- To export chart data programmatically
- To preview data before creating a dashboard tile
**Performance notes:**
- Large result sets may take time to execute
- Use the `limit` parameter to restrict rows returned
- Query execution happens in real-time against your warehouse
**Optional limit parameter:** Restricts the number of rows returned (useful for large datasets) | write | true | unknown |
| run-dashboard-tiles Run one or multiple dashboard tiles (or all tiles) concurrently.
This tool fetches the dashboard configuration once and then executes the selected tiles in parallel.
**When to use:**
- To download the entire dashboard data.
- To get data from multiple specific tiles at once (or from single tile).
**Returns:**
- A dictionary where keys are tile UUIDs and values contain:
- `title`: Tile title
- `status`: "success" or "error"
- `csv_data`: CSV-formatted string with headers, data rows, and metadata (for successful tiles)
- `error`: Error message (for failed tiles)
- Each CSV data includes a metadata comment line with row count and field information
- If a tile fails to execute, the value will contain an error message.
| write | true | unknown |
02Install & source
uvx lightdash-mcp
uvx- repohttps://github.com/poddubnyoleg/lightdash_mcp
- homepagehttps://pypi.org/project/lightdash-mcp/
- licenseMIT
- adoption23 stars · 6 forks
03Access granted
Query a database · write
The access this server can exercise, inferred from its verified tools — not a declared OAuth scope.
05Provenance & freshness
sourcesGitHub repo search [p4]
last_checked2026-08-16 18:50Z
next_check2026-08-16 21:50Z
cadenceevery 3h
verifiedhandshake:failed metadata:passed handshake:failed metadata:passed handshake:failed metadata:passed handshake:failed metadata:passed handshake:failed metadata:passed
index_statusindex — 9 unique facts >= 5
06Badge
Add the “as seen on MCPExplorer” badge to your README.
[](https://mcpexplorer.com/servers/lightdash-mcp)
Next step
This is one server. A loadout combines the right servers, governance, and proven plays for a whole job — assembled deliberately, not tool-dumped.
Explore loadouts →