You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2026/04/17 02:36:36 UTC
(superset) branch docs/mcp-server-6.1 created (now 555324be541)
This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a change to branch docs/mcp-server-6.1
in repository https://gitbox.apache.org/repos/asf/superset.git
at 555324be541 docs(mcp): update MCP server docs for 6.1
This branch includes the following new commits:
new 555324be541 docs(mcp): update MCP server docs for 6.1
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(superset) 01/01: docs(mcp): update MCP server docs for 6.1
Posted by ru...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch docs/mcp-server-6.1
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 555324be541253e9d54725ebff3d7869792f43da
Author: Superset Dev <de...@superset.apache.org>
AuthorDate: Thu Apr 16 19:36:15 2026 -0700
docs(mcp): update MCP server docs for 6.1
- Add new tools to user guide: list_databases, get_database_info,
create_virtual_dataset, save_sql_query, get_chart_type_schema
- Add preview-first workflow tip with 3-step iterative pattern
- Add Browse Databases and Create Virtual Datasets capability sections
- Add RBAC enforcement table mapping tools to FAB permissions
- Add Audit Log section (Settings → Action Log)
- Add Middleware Pipeline table (7 layers with purpose/default)
- Add Error Sanitization section (what gets redacted and why)
- Add Performance section: connection pooling math, response caching guide
- Add Tool Search config section with 85% token savings context
- Add MCP_RBAC_ENABLED, MCP_PARSE_REQUEST_ENABLED, MCP_USER_RESOLVER
to config reference
- Add MCP_TOOL_SEARCH_CONFIG to config reference
Co-Authored-By: Claude Sonnet 4.6 <no...@anthropic.com>
---
docs/admin_docs/configuration/mcp-server.mdx | 133 +++++++++++++++++++++
.../docs/using-superset/using-ai-with-superset.mdx | 43 ++++++-
2 files changed, 174 insertions(+), 2 deletions(-)
diff --git a/docs/admin_docs/configuration/mcp-server.mdx b/docs/admin_docs/configuration/mcp-server.mdx
index 22a80d645b3..05125f3243d 100644
--- a/docs/admin_docs/configuration/mcp-server.mdx
+++ b/docs/admin_docs/configuration/mcp-server.mdx
@@ -501,6 +501,8 @@ All MCP settings go in `superset_config.py`. Defaults are defined in `superset/m
| `MCP_SERVICE_URL` | `None` | Public base URL for MCP-generated links (set this when behind a reverse proxy) |
| `MCP_DEBUG` | `False` | Enable debug logging |
| `MCP_DEV_USERNAME` | -- | Superset username for development mode (no auth) |
+| `MCP_RBAC_ENABLED` | `True` | Enforce Superset's role-based access control on MCP tool calls. When `True`, each tool checks that the authenticated user has the required FAB permission before executing. Disable only for testing or trusted-network deployments. |
+| `MCP_PARSE_REQUEST_ENABLED` | `True` | Accept tool inputs pre-serialized as JSON strings. Enabled by default to work around a double-serialization quirk in some MCP clients (including older versions of Claude Code). Set to `False` when using clients that pass native objects and you want cleaner tool schemas. |
### Authentication
@@ -516,6 +518,7 @@ All MCP settings go in `superset_config.py`. Defaults are defined in `superset/m
| `MCP_REQUIRED_SCOPES` | `[]` | Required JWT scopes |
| `MCP_JWT_DEBUG_ERRORS` | `False` | Log detailed JWT errors server-side (never exposed in HTTP responses per RFC 6750) |
| `MCP_AUTH_FACTORY` | `None` | Custom auth provider factory `(flask_app) -> auth_provider`. Takes precedence over built-in JWT |
+| `MCP_USER_RESOLVER` | `None` | Custom function `(app, access_token) -> username` to extract a Superset username from a validated JWT token. When `None`, the default resolver checks `preferred_username`, `username`, `email`, and `sub` claims in that order. |
### Response Size Guard
@@ -599,6 +602,41 @@ MCP_STORE_CONFIG = {
| `event_store_max_events` | `100` | Maximum events retained per session |
| `event_store_ttl` | `3600` | Event TTL in seconds |
+### Tool Search
+
+By default the MCP server exposes a lightweight tool-search interface instead of advertising every tool at once. This reduces the initial context sent to the LLM by ~70%, which lowers cost and latency. The AI client discovers tools on demand by calling `search_tools` and then invokes them via `call_tool`.
+
+```python
+MCP_TOOL_SEARCH_CONFIG = {
+ "enabled": True,
+ "strategy": "bm25", # "bm25" (natural language) or "regex"
+ "max_results": 5,
+ "always_visible": [ # Tools always listed (pinned)
+ "health_check",
+ "get_instance_info",
+ ],
+ "search_tool_name": "search_tools",
+ "call_tool_name": "call_tool",
+ "compact_schemas": True, # Strip $defs in search results to save tokens
+ "max_description_length": 300,
+}
+```
+
+| Key | Default | Description |
+|-----|---------|-------------|
+| `enabled` | `True` | Enable tool search. When `False`, all tools are listed upfront |
+| `strategy` | `"bm25"` | Search ranking algorithm. `"bm25"` supports natural language; `"regex"` supports pattern matching |
+| `max_results` | `5` | Maximum tools returned per search query |
+| `always_visible` | See above | Tools that always appear in `list_tools`, regardless of search |
+| `compact_schemas` | `True` | Strip `$defs` from search results to reduce token cost. Full schemas are used when the tool is actually called |
+| `max_description_length` | `300` | Truncate tool descriptions in search results (0 = no truncation) |
+
+:::tip
+Set `enabled: False` to revert to the traditional "show all tools at once" behavior, which some clients or workflows may prefer.
+:::
+
+Tool search reduces the initial token cost from ~15–20K tokens (full catalog) down to ~4–5K tokens (pinned tools + search interface) — roughly 85% savings at the start of each conversation.
+
### Session & CSRF
These values are flat-merged into the Flask app config used by the MCP server process:
@@ -620,6 +658,101 @@ MCP_CSRF_CONFIG = {
---
+## Access Control
+
+### RBAC Enforcement
+
+The MCP server respects Superset's full role-based access control (RBAC). Every authenticated user can only access the data and operations their Superset roles permit — the same rules that apply in the Superset UI apply through MCP.
+
+Each tool declares one or more required FAB permissions. The table below maps tool groups to their permission requirements:
+
+| Tool group | Required FAB permission |
+|------------|------------------------|
+| `list_charts`, `get_chart_info`, `get_chart_data`, `get_chart_preview`, `generate_chart`, `update_chart` | `can_read` on `Chart` (read), `can_write` on `Chart` (mutate) |
+| `list_dashboards`, `get_dashboard_info`, `generate_dashboard`, `add_chart_to_existing_dashboard` | `can_read` on `Dashboard` (read), `can_write` on `Dashboard` (mutate) |
+| `list_datasets`, `get_dataset_info`, `create_virtual_dataset` | `can_read` on `Dataset` (read), `can_write` on `Dataset` (mutate) |
+| `list_databases`, `get_database_info` | `can_read` on `Database` |
+| `execute_sql` | `can_execute_sql_query` on `SQLLab` |
+| `open_sql_lab_with_context`, `save_sql_query` | `can_read` on `SQLLab` |
+| `health_check` | None (public) |
+
+To disable RBAC checking globally (for trusted-network deployments or testing), set:
+
+```python
+# superset_config.py
+MCP_RBAC_ENABLED = False
+```
+
+:::warning
+Disabling RBAC removes all permission checks from MCP tool calls. Only do this on isolated, internal deployments where all MCP users are trusted admins.
+:::
+
+### Audit Log
+
+All MCP tool calls are recorded in Superset's action log. You can view them at **Settings → Action Log** (admin only). Each log entry records:
+
+- The tool name (e.g., `mcp.generate_chart.db_write`)
+- The authenticated user
+- A timestamp
+
+This makes MCP activity fully auditable alongside regular Superset activity. The action log uses the same event logger as the rest of Superset, so existing log ingestion pipelines (e.g., sending logs to Elasticsearch or a SIEM) capture MCP events automatically.
+
+### Middleware Pipeline
+
+Every MCP request passes through a fixed middleware stack before reaching the tool function. The layers run in this order:
+
+| Middleware | Purpose | Default |
+|------------|---------|---------|
+| `RateLimitMiddleware` | Sliding-window rate limiting (Redis or in-memory) | Disabled |
+| `ResponseSizeGuardMiddleware` | Estimates token count, warns at 80% of limit, blocks at limit | Enabled |
+| `FieldPermissionsMiddleware` | Strips response fields the authenticated user lacks access to | Enabled |
+| `LoggingMiddleware` | Logs each tool call with user, parameters, and duration | Enabled |
+| `GlobalErrorHandlerMiddleware` | Catches unhandled exceptions and sanitizes sensitive data before it reaches the client | Enabled |
+| `PrivateToolMiddleware` | Blocks invocation of tools tagged as private | Enabled |
+| `StructuredContentStripperMiddleware` | Strips `structuredContent` from responses for Claude.ai bridge compatibility | Enabled |
+
+### Error Sanitization
+
+The `GlobalErrorHandlerMiddleware` automatically redacts sensitive information from all error messages before they reach the LLM client. The following are replaced with generic messages:
+
+- **Database connection strings** — replaced with a generic connection error message
+- **API keys and tokens** — redacted from error traces
+- **File system paths** — stripped to prevent information disclosure
+- **IP addresses** — removed from error context
+
+This ensures that a misconfigured database connection or an unexpected exception never leaks credentials or internal topology to the LLM or its users. All regex patterns used for redaction are bounded to prevent ReDoS attacks.
+
+---
+
+## Performance
+
+### Connection Pooling
+
+Each MCP server process maintains its own SQLAlchemy connection pool to the database. For multi-worker deployments, total open connections = **workers × pool size**.
+
+```python
+# superset_config.py
+SQLALCHEMY_POOL_SIZE = 5
+SQLALCHEMY_MAX_OVERFLOW = 10
+SQLALCHEMY_POOL_TIMEOUT = 30
+SQLALCHEMY_POOL_RECYCLE = 3600 # Recycle connections after 1 hour
+```
+
+For a 3-pod Kubernetes deployment with the defaults above, expect up to 3 × (5 + 10) = 45 connections. Size your database's `max_connections` accordingly.
+
+### Response Caching
+
+Enable response caching for read-heavy workloads (dashboards/datasets that don't change frequently). With the in-memory backend (default when `MCP_STORE_CONFIG` is disabled), caching is per-process. Use Redis-backed caching for consistent cache hits across multiple pods:
+
+```python
+MCP_CACHE_CONFIG = {"enabled": True, "call_tool_ttl": 3600}
+MCP_STORE_CONFIG = {"enabled": True, "CACHE_REDIS_URL": "redis://redis:6379/0"}
+```
+
+Mutating tools (`generate_chart`, `update_chart`, `execute_sql`, `generate_dashboard`) are always excluded from caching regardless of this setting.
+
+---
+
## Troubleshooting
### Server won't start
diff --git a/docs/docs/using-superset/using-ai-with-superset.mdx b/docs/docs/using-superset/using-ai-with-superset.mdx
index 3969042bcd2..80956dd9880 100644
--- a/docs/docs/using-superset/using-ai-with-superset.mdx
+++ b/docs/docs/using-superset/using-ai-with-superset.mdx
@@ -55,8 +55,8 @@ Ask your AI assistant to browse what's available in your Superset instance:
Describe the visualization you want and AI creates it for you:
+- **Preview-first workflow** -- by default AI generates an Explore link so you can review the chart before it is saved. Say "save it" to commit permanently
- **Create charts from natural language** -- describe what you want to see and AI picks the right chart type, metrics, and dimensions
-- **Preview before saving** -- AI generates a preview so you can review before committing
- **Modify existing charts** -- update filters, change chart types, add metrics
- **Get Explore links** -- open any chart in Superset's Explore view for further refinement
@@ -65,6 +65,16 @@ Describe the visualization you want and AI creates it for you:
> "Update chart 42 to use a line chart instead"
> "Give me a link to explore this chart further"
+:::tip Preview-first workflow
+Charts are **not saved by default**. The workflow is intentionally iterative:
+
+1. **Explore** — AI generates an Explore link so you can see the chart before it exists in Superset
+2. **Iterate** — ask the AI to adjust the chart; changes are previewed without touching the database
+3. **Save** — when you're happy, say "save it" and the chart is permanently stored
+
+To skip the preview and save immediately, include "and save it" in your prompt.
+:::
+
### Create Dashboards
Build dashboards from a collection of charts:
@@ -76,16 +86,40 @@ Build dashboards from a collection of charts:
> "Create a dashboard called 'Q4 Sales Overview' with charts 10, 15, and 22"
> "Add the revenue trend chart to the executive dashboard"
+### Browse Databases
+
+Discover what database connections are configured in your Superset instance:
+
+- **List databases** -- see all database connections you have access to
+- **Get database details** -- name, backend type (PostgreSQL, Snowflake, etc.), and connection status
+
+**Example prompts:**
+> "What databases are connected to Superset?"
+> "Show me details about the data warehouse connection"
+
+### Create Virtual Datasets
+
+Build ad-hoc SQL datasets that can be used as the basis for charts:
+
+- **Create virtual datasets** -- write a SQL query and save it as a reusable dataset
+- **Use immediately in charts** -- the returned dataset ID can be passed directly to chart creation
+
+**Example prompts:**
+> "Create a dataset from: SELECT region, SUM(revenue) as total_revenue FROM orders GROUP BY region"
+> "Make a virtual dataset called 'monthly_signups' from the users table filtered to last 12 months"
+
### Run SQL Queries
Execute SQL directly through your AI assistant:
- **Run queries** -- execute SQL with full Superset RBAC enforcement (you can only query data your roles allow)
- **Open SQL Lab** -- get a link to SQL Lab pre-populated with a query, ready to run and explore
+- **Save queries** -- save a SQL query to SQL Lab's Saved Queries for later reuse
**Example prompts:**
> "Run this query: SELECT region, SUM(revenue) FROM sales GROUP BY region"
> "Open SQL Lab with a query to show the top 10 customers by order count"
+> "Save this query as 'Weekly Revenue Report'"
### Analyze Chart Data
@@ -200,13 +234,17 @@ Ask your admin for the MCP server URL and any authentication tokens you need.
| `health_check` | Verify the MCP server is running and connected |
| `get_instance_info` | Get instance statistics (dataset, chart, dashboard counts) |
| `get_schema` | Discover available charts, datasets, and dashboards with schema info |
+| `list_databases` | List database connections with filtering and search |
+| `get_database_info` | Get database metadata (name, backend type, permissions) |
| `list_datasets` | List datasets with filtering and search |
| `get_dataset_info` | Get dataset metadata (columns, metrics, filters) |
+| `create_virtual_dataset` | Create a virtual (SQL-based) dataset |
| `list_charts` | List charts with filtering and search |
| `get_chart_info` | Get chart metadata and configuration |
| `get_chart_data` | Retrieve chart data (JSON, CSV, or Excel) |
| `get_chart_preview` | Generate a chart preview (URL, ASCII, table, or Vega-Lite) |
-| `generate_chart` | Create a new chart from a specification |
+| `get_chart_type_schema` | Get the configuration schema for a specific chart type |
+| `generate_chart` | Create a new chart (preview mode by default; pass `save_chart=true` to persist) |
| `update_chart` | Modify an existing chart's configuration |
| `update_chart_preview` | Update a cached chart preview without saving |
| `list_dashboards` | List dashboards with filtering and search |
@@ -215,6 +253,7 @@ Ask your admin for the MCP server URL and any authentication tokens you need.
| `add_chart_to_existing_dashboard` | Add a chart to an existing dashboard |
| `execute_sql` | Run a SQL query with RBAC enforcement |
| `open_sql_lab_with_context` | Open SQL Lab with a pre-populated query |
+| `save_sql_query` | Save a SQL query to SQL Lab's Saved Queries list |
| `generate_explore_link` | Generate an Explore URL for interactive visualization |
---