You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by mi...@apache.org on 2025/11/26 21:48:44 UTC

(superset) branch master updated: docs: Reorganizes the extensions documentation (#36298)

This is an automated email from the ASF dual-hosted git repository.

michaelsmolina pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new fe21485065 docs: Reorganizes the extensions documentation (#36298)
fe21485065 is described below

commit fe214850656eb99d164078838e749e17deeec729
Author: Michael S. Molina <70...@users.noreply.github.com>
AuthorDate: Wed Nov 26 16:48:36 2025 -0500

    docs: Reorganizes the extensions documentation (#36298)
    
    Co-authored-by: Evan Rusackas <ev...@preset.io>
---
 .github/CODEOWNERS                                 |   1 +
 docs/developer_portal/extensions/architecture.md   |   4 +-
 ...contribution-types.md => contribution-types.md} |  46 +++-
 .../{deploying-extension.md => deployment.md}      |  24 ++-
 .../extensions/development-mode.md                 |  48 -----
 docs/developer_portal/extensions/development.md    | 239 +++++++++++++++++++++
 .../extensions/extension-metadata.md               |  55 -----
 .../extensions/extension-points/sqllab.md          | 209 ++++++++++++++++++
 .../extensions/extension-project-structure.md      |  78 -------
 .../extensions/interacting-with-host.md            | 129 -----------
 docs/developer_portal/extensions/mcp.md            |   7 +-
 docs/developer_portal/extensions/overview.md       |  56 ++---
 docs/developer_portal/extensions/quick-start.md    |   9 +-
 .../{security-implications.md => security.md}      |  10 +-
 docs/developer_portal/sidebars.js                  |  20 +-
 docs/sidebarTutorials.js                           |  20 +-
 16 files changed, 559 insertions(+), 396 deletions(-)

diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 237907f74d..357078af86 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -33,6 +33,7 @@
 
 # Notify PMC members of changes to extension-related files
 
+/docs/developer_portal/extensions/ @michael-s-molina @villebro @rusackas
 /superset-core/ @michael-s-molina @villebro @geido @eschutho @rusackas @kgabryje
 /superset-extensions-cli/ @michael-s-molina @villebro @geido @eschutho @rusackas @kgabryje
 /superset/core/ @michael-s-molina @villebro @geido @eschutho @rusackas @kgabryje
diff --git a/docs/developer_portal/extensions/architecture.md b/docs/developer_portal/extensions/architecture.md
index 313596320d..a5a01bdb29 100644
--- a/docs/developer_portal/extensions/architecture.md
+++ b/docs/developer_portal/extensions/architecture.md
@@ -248,6 +248,6 @@ This architecture provides several key benefits:
 
 Now that you understand the architecture, explore:
 
-- **[Extension Project Structure](./extension-project-structure)** - How to organize your extension code
-- **[Frontend Contribution Types](./frontend-contribution-types)** - What kinds of extensions you can build
 - **[Quick Start](./quick-start)** - Build your first extension
+- **[Contribution Types](./contribution-types)** - What kinds of extensions you can build
+- **[Development](./development)** - Project structure, APIs, and development workflow
diff --git a/docs/developer_portal/extensions/frontend-contribution-types.md b/docs/developer_portal/extensions/contribution-types.md
similarity index 66%
rename from docs/developer_portal/extensions/frontend-contribution-types.md
rename to docs/developer_portal/extensions/contribution-types.md
index 51857ad0c9..6ed4d77b95 100644
--- a/docs/developer_portal/extensions/frontend-contribution-types.md
+++ b/docs/developer_portal/extensions/contribution-types.md
@@ -1,6 +1,6 @@
 ---
-title: Frontend Contribution Types
-sidebar_position: 5
+title: Contribution Types
+sidebar_position: 4
 ---
 
 <!--
@@ -22,11 +22,15 @@ specific language governing permissions and limitations
 under the License.
 -->
 
-# Frontend Contribution Types
+# Contribution Types
 
-To facilitate the development of extensions, we will define a set of well-defined contribution types that extensions can implement. These contribution types will serve as the building blocks for extensions, allowing them to interact with the host application and provide new functionality. The initial set of contribution types will include:
+To facilitate the development of extensions, we define a set of well-defined contribution types that extensions can implement. These contribution types serve as the building blocks for extensions, allowing them to interact with the host application and provide new functionality.
 
-## Views
+## Frontend
+
+Frontend contribution types allow extensions to extend Superset's user interface with new views, commands, and menu items.
+
+### Views
 
 Extensions can add new views or panels to the host application, such as custom SQL Lab panels, dashboards, or other UI components. Each view is registered with a unique ID and can be activated or deactivated as needed. Contribution areas are uniquely identified (e.g., `sqllab.panels` for SQL Lab panels), enabling seamless integration into specific parts of the application.
 
@@ -41,7 +45,7 @@ Extensions can add new views or panels to the host application, such as custom S
 },
 ```
 
-## Commands
+### Commands
 
 Extensions can define custom commands that can be executed within the host application, such as context-aware actions or menu options. Each command can specify properties like a unique command identifier, an icon, a title, and a description. These commands can be invoked by users through menus, keyboard shortcuts, or other UI elements, enabling extensions to add rich, interactive functionality to Superset.
 
@@ -56,7 +60,7 @@ Extensions can define custom commands that can be executed within the host appli
 ]
 ```
 
-## Menus
+### Menus
 
 Extensions can contribute new menu items or context menus to the host application, providing users with additional actions and options. Each menu item can specify properties such as the target view, the command to execute, its placement (primary, secondary, or context), and conditions for when it should be displayed. Menu contribution areas are uniquely identified (e.g., `sqllab.editor` for the SQL Lab editor), allowing extensions to seamlessly integrate their functionality into specific [...]
 
@@ -88,3 +92,31 @@ Extensions can contribute new menu items or context menus to the host applicatio
   },
 }
 ```
+
+## Backend
+
+Backend contribution types allow extensions to extend Superset's server-side capabilities with new API endpoints, MCP tools, and MCP prompts.
+
+### REST API Endpoints
+
+Extensions can register custom REST API endpoints under the `/api/v1/extensions/` namespace. This dedicated namespace prevents conflicts with built-in endpoints and provides a clear separation between core and extension functionality.
+
+``` json
+"backend": {
+  "entryPoints": ["my_extension.entrypoint"],
+  "files": ["backend/src/my_extension/**/*.py"]
+}
+```
+
+The entry point module registers the API with Superset:
+
+``` python
+from superset_core.api.rest_api import add_extension_api
+from .api import MyExtensionAPI
+
+add_extension_api(MyExtensionAPI)
+```
+
+### MCP Tools and Prompts
+
+Extensions can contribute Model Context Protocol (MCP) tools and prompts that AI agents can discover and use. See [MCP Integration](./mcp) for detailed documentation.
diff --git a/docs/developer_portal/extensions/deploying-extension.md b/docs/developer_portal/extensions/deployment.md
similarity index 59%
rename from docs/developer_portal/extensions/deploying-extension.md
rename to docs/developer_portal/extensions/deployment.md
index 48582bceae..2817dcfbbd 100644
--- a/docs/developer_portal/extensions/deploying-extension.md
+++ b/docs/developer_portal/extensions/deployment.md
@@ -1,6 +1,6 @@
 ---
-title: Deploying an Extension
-sidebar_position: 8
+title: Deployment
+sidebar_position: 6
 ---
 
 <!--
@@ -22,7 +22,7 @@ specific language governing permissions and limitations
 under the License.
 -->
 
-# Deploying an Extension
+# Deployment
 
 Once an extension has been developed, the deployment process involves packaging and uploading it to the host application.
 
@@ -33,13 +33,17 @@ Packaging is handled by the `superset-extensions bundle` command, which:
 3. Generates a `manifest.json` with build-time metadata, including the contents of `extension.json` and references to built assets.
 4. Packages everything into a `.supx` file (a zip archive with a specific structure required by Superset).
 
-Uploading is accomplished through Superset's REST API at `/api/v1/extensions/import/`. The endpoint accepts the `.supx` file as form data and processes it by:
+To deploy an extension, place the `.supx` file in the extensions directory configured via `EXTENSIONS_PATH` in your `superset_config.py`:
 
-1. Extracting and validating the extension metadata and manifest.
-2. Storing extension assets in the metadata database for dynamic loading.
-3. Registering the extension in the metadata database, including its name, version, author, and capabilities.
-4. Automatically activating the extension, making it immediately available for use and management via the Superset UI or API.
+``` python
+EXTENSIONS_PATH = "/path/to/extensions"
+```
 
-This API-driven approach enables automated deployment workflows and simplifies extension management for administrators. Extensions can be uploaded through the Swagger UI, programmatically via scripts, or through the management interface:
+During application startup, Superset automatically discovers and loads all `.supx` files from this directory:
 
-https://github.com/user-attachments/assets/98b16cdd-8ec5-4812-9d5e-9915badd8f0d
+1. Scans the configured directory for `.supx` files.
+2. Validates each file is a properly formatted zip archive.
+3. Extracts and validates the extension manifest and metadata.
+4. Loads the extension, making it available for use.
+
+This file-based approach simplifies deployment in containerized environments and enables version control of extensions alongside infrastructure configuration.
diff --git a/docs/developer_portal/extensions/development-mode.md b/docs/developer_portal/extensions/development-mode.md
deleted file mode 100644
index d2fdf36e05..0000000000
--- a/docs/developer_portal/extensions/development-mode.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: Development Mode
-sidebar_position: 10
----
-
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-
-# Development Mode
-
-Development mode accelerates extension development by letting developers see changes in Superset quickly, without the need for repeated packaging and uploading. To enable development mode, set the `LOCAL_EXTENSIONS` configuration in your `superset_config.py`:
-
-``` python
-LOCAL_EXTENSIONS = [
-    "/path/to/your/extension1",
-    "/path/to/your/extension2",
-]
-```
-
-This instructs Superset to load and serve extensions directly from disk, so you can iterate quickly. Running `superset-extensions dev` watches for file changes and rebuilds assets automatically, while the Webpack development server (started separately with `npm run dev-server`) serves updated files as soon as they're modified. This enables immediate feedback for React components, styles, and other frontend code. Changes to backend files are also detected automatically and immediately syn [...]
-
-Example output when running in development mode:
-
-```
-superset-extensions dev
-
-⚙️  Building frontend assets…
-✅ Frontend rebuilt
-✅ Backend files synced
-✅ Manifest updated
-👀 Watching for changes in: /dataset_references/frontend, /dataset_references/backend
-```
diff --git a/docs/developer_portal/extensions/development.md b/docs/developer_portal/extensions/development.md
new file mode 100644
index 0000000000..0550a78983
--- /dev/null
+++ b/docs/developer_portal/extensions/development.md
@@ -0,0 +1,239 @@
+---
+title: Development
+sidebar_position: 5
+---
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+# Development
+
+This guide covers everything you need to know about developing extensions for Superset, from project structure to development workflow.
+
+## Project Structure
+
+The [apache-superset-extensions-cli](https://github.com/apache/superset/tree/master/superset-extensions-cli) package provides a command-line interface (CLI) that streamlines the extension development workflow. It offers the following commands:
+
+```
+superset-extensions init: Generates the initial folder structure and scaffolds a new extension project.
+
+superset-extensions build: Builds extension assets.
+
+superset-extensions bundle: Packages the extension into a .supx file.
+
+superset-extensions dev: Automatically rebuilds the extension as files change.
+```
+
+When creating a new extension with `superset-extensions init <extension-name>`, the CLI generates a standardized folder structure:
+
+```
+dataset_references/
+├── extension.json
+├── frontend/
+│   ├── src/
+│   ├── webpack.config.js
+│   ├── tsconfig.json
+│   └── package.json
+├── backend/
+│   ├── src/
+│        └── dataset_references/
+│   ├── tests/
+│   ├── pyproject.toml
+│   └── requirements.txt
+├── dist/
+│   ├── manifest.json
+│   ├── frontend
+│        └── dist/
+│             ├── remoteEntry.d7a9225d042e4ccb6354.js
+│             └── 900.038b20cdff6d49cfa8d9.js
+│   └── backend
+│        └── dataset_references/
+│             ├── __init__.py
+│             ├── api.py
+│             └── entrypoint.py
+├── dataset_references-1.0.0.supx
+└── README.md
+```
+
+The `extension.json` file serves as the declared metadata for the extension, containing the extension's name, version, author, description, and a list of capabilities. This file is essential for the host application to understand how to load and manage the extension.
+
+The `frontend` directory contains the source code for the frontend components of the extension, including React components, styles, and assets. The `webpack.config.js` file is used to configure Webpack for building the frontend code, while the `tsconfig.json` file defines the TypeScript configuration for the project. The `package.json` file specifies the dependencies and scripts for building and testing the frontend code.
+
+The `backend` directory contains the source code for the backend components of the extension, including Python modules, tests, and configuration files. The `pyproject.toml` file is used to define the Python package and its dependencies, while the `requirements.txt` file lists the required Python packages for the extension. The `src` folder contains the functional backend source files, `tests` directory contains unit tests for the backend code, ensuring that the extension behaves as expec [...]
+
+The `dist` directory is built when running the `build` or `dev` command, and contains the files that will be included in the bundle. The `manifest.json` file contains critical metadata about the extension, including the majority of the contents of the `extension.json` file, but also other build-time information, like the name of the built Webpack Module Federation remote entry file. The files in the `dist` directory will be zipped into the final `.supx` file. Although this file is techni [...]
+
+The `README.md` file provides documentation and instructions for using the extension, including how to install, configure, and use its functionality.
+
+## Extension Metadata
+
+The `extension.json` file contains all metadata necessary for the host application to understand and manage the extension:
+
+```json
+{
+  "name": "dataset_references",
+  "version": "1.0.0",
+  "frontend": {
+    "contributions": {
+      "views": {
+        "sqllab.panels": [
+          {
+            "id": "dataset_references.main",
+            "name": "Dataset references"
+          }
+        ]
+      }
+    },
+    "moduleFederation": {
+      "exposes": ["./index"]
+    }
+  },
+  "backend": {
+    "entryPoints": ["dataset_references.entrypoint"],
+    "files": ["backend/src/dataset_references/**/*.py"]
+  }
+}
+```
+
+The `contributions` section declares how the extension extends Superset's functionality through views, commands, menus, and other contribution types. The `backend` section specifies entry points and files to include in the bundle.
+
+## Interacting with the Host
+
+Extensions interact with Superset through well-defined, versioned APIs provided by the `@apache-superset/core` (frontend) and `apache-superset-core` (backend) packages. These APIs are designed to be stable, discoverable, and consistent for both built-in and external extensions.
+
+**Note**: The `superset_core.api` module provides abstract classes that are replaced with concrete implementations via dependency injection when Superset initializes. This allows extensions to use the same interfaces as the host application.
+
+### Frontend APIs
+
+The frontend extension APIs (via `@apache-superset/core`) are organized into logical namespaces such as `authentication`, `commands`, `extensions`, `sqlLab`, and others. Each namespace groups related functionality, making it easy for extension authors to discover and use the APIs relevant to their needs. For example, the `sqlLab` namespace provides events and methods specific to SQL Lab, allowing extensions to react to user actions and interact with the SQL Lab environment:
+
+```typescript
+export const getCurrentTab: () => Tab | undefined;
+
+export const getDatabases: () => Database[];
+
+export const getTabs: () => Tab[];
+
+export const onDidChangeEditorContent: Event<string>;
+
+export const onDidClosePanel: Event<Panel>;
+
+export const onDidChangeActivePanel: Event<Panel>;
+
+export const onDidChangeTabTitle: Event<string>;
+
+export const onDidQueryRun: Event<Editor>;
+
+export const onDidQueryStop: Event<Editor>;
+```
+
+The following code demonstrates more examples of the existing frontend APIs:
+
+```typescript
+import { core, commands, sqlLab, authentication, Button } from '@apache-superset/core';
+import MyPanel from './MyPanel';
+
+export function activate(context) {
+  // Register a new panel (view) in SQL Lab and use shared UI components in your extension's React code
+  const panelDisposable = core.registerView('my_extension.panel', <MyPanel><Button/></MyPanel>);
+
+  // Register a custom command
+  const commandDisposable = commands.registerCommand('my_extension.copy_query', {
+    title: 'Copy Query',
+    execute: () => {
+      // Command logic here
+    },
+  });
+
+  // Listen for query run events in SQL Lab
+  const eventDisposable = sqlLab.onDidQueryRun(editor => {
+    // Handle query execution event
+  });
+
+  // Access a CSRF token for secure API requests
+  authentication.getCSRFToken().then(token => {
+    // Use token as needed
+  });
+
+  // Add all disposables for automatic cleanup on deactivation
+  context.subscriptions.push(panelDisposable, commandDisposable, eventDisposable);
+}
+```
+
+### Backend APIs
+
+Backend APIs (via `apache-superset-core`) follow a similar pattern, providing access to Superset's models, sessions, and query capabilities. Extensions can register REST API endpoints, access the metadata database, and interact with Superset's core functionality.
+
+Extension endpoints are registered under a dedicated `/extensions` namespace to avoid conflicting with built-in endpoints and also because they don't share the same version constraints. By grouping all extension endpoints under `/extensions`, Superset establishes a clear boundary between core and extension functionality, making it easier to manage, document, and secure both types of APIs.
+
+```python
+from superset_core.api.models import Database, get_session
+from superset_core.api.daos import DatabaseDAO
+from superset_core.api.rest_api import add_extension_api
+from .api import DatasetReferencesAPI
+
+# Register a new extension REST API
+add_extension_api(DatasetReferencesAPI)
+
+# Fetch Superset entities via the DAO to apply base filters that filter out entities
+# that the user doesn't have access to
+databases = DatabaseDAO.find_all()
+
+# ..or apply simple filters on top of base filters
+databases = DatabaseDAO.filter_by(uuid=database.uuid)
+if not databases:
+    raise Exception("Database not found")
+
+return databases[0]
+
+# Perform complex queries using SQLAlchemy Query, also filtering out
+# inaccessible entities
+session = get_session()
+databases_query = session.query(Database).filter(
+    Database.database_name.ilike("%abc%")
+)
+return DatabaseDAO.query(databases_query)
+```
+
+In the future, we plan to expand the backend APIs to support configuring security models, database engines, SQL Alchemy dialects, etc.
+
+## Development Mode
+
+Development mode accelerates extension development by letting developers see changes in Superset quickly, without the need for repeated packaging and uploading. To enable development mode, set the `LOCAL_EXTENSIONS` configuration in your `superset_config.py`:
+
+```python
+LOCAL_EXTENSIONS = [
+    "/path/to/your/extension1",
+    "/path/to/your/extension2",
+]
+```
+
+This instructs Superset to load and serve extensions directly from disk, so you can iterate quickly. Running `superset-extensions dev` watches for file changes and rebuilds assets automatically, while the Webpack development server (started separately with `npm run dev-server`) serves updated files as soon as they're modified. This enables immediate feedback for React components, styles, and other frontend code. Changes to backend files are also detected automatically and immediately syn [...]
+
+Example output when running in development mode:
+
+```
+superset-extensions dev
+
+⚙️  Building frontend assets…
+✅ Frontend rebuilt
+✅ Backend files synced
+✅ Manifest updated
+👀 Watching for changes in: /dataset_references/frontend, /dataset_references/backend
+```
diff --git a/docs/developer_portal/extensions/extension-metadata.md b/docs/developer_portal/extensions/extension-metadata.md
deleted file mode 100644
index 97afb19025..0000000000
--- a/docs/developer_portal/extensions/extension-metadata.md
+++ /dev/null
@@ -1,55 +0,0 @@
----
-title: Extension Metadata
-sidebar_position: 4
----
-
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-
-# Extension Metadata
-
-The `extension.json` file contains all metadata necessary for the host application to understand and manage the extension:
-
-``` json
-{
-  "name": "dataset_references",
-  "version": "1.0.0",
-  "frontend": {
-    "contributions": {
-      "views": {
-        "sqllab.panels": [
-          {
-            "id": "dataset_references.main",
-            "name": "Dataset references"
-          }
-        ]
-      }
-    },
-    "moduleFederation": {
-      "exposes": ["./index"]
-    }
-  },
-  "backend": {
-    "entryPoints": ["dataset_references.entrypoint"],
-    "files": ["backend/src/dataset_references/**/*.py"]
-  },
-}
-```
-
-The `contributions` section declares how the extension extends Superset's functionality through views, commands, menus, and other contribution types. The `backend` section specifies entry points and files to include in the bundle.
diff --git a/docs/developer_portal/extensions/extension-points/sqllab.md b/docs/developer_portal/extensions/extension-points/sqllab.md
new file mode 100644
index 0000000000..95108bbc02
--- /dev/null
+++ b/docs/developer_portal/extensions/extension-points/sqllab.md
@@ -0,0 +1,209 @@
+---
+title: SQL Lab
+sidebar_position: 1
+---
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+# SQL Lab Extension Points
+
+SQL Lab provides 5 extension points where extensions can contribute custom UI components. Each area serves a specific purpose and can be customized to add new functionality.
+
+## Layout Overview
+
+```
+┌──────────┬─────────────────────────────────────────┬─────────────┐
+│          │                                         │             │
+│          │                                         │             │
+│          │                Editor                   │             │
+│          │                                         │             │
+│   Left   │                                         │    Right    │
+│  Sidebar ├─────────────────────────────────────────┤   Sidebar   │
+│          │                                         │             │
+│          │                Panels                   │             │
+│          │                                         │             │
+│          │                                         │             │
+│          │                                         │             │
+├──────────┴─────────────────────────────────────────┴─────────────┤
+│                          Status Bar                              │
+└──────────────────────────────────────────────────────────────────┘
+```
+
+| Extension Point   | ID                    | Description                                                |
+| ----------------- | --------------------- | ---------------------------------------------------------- |
+| **Left Sidebar**  | `sqllab.leftSidebar`  | Navigation and browsing (database explorer, saved queries) |
+| **Editor**        | `sqllab.editor`       | SQL query editor workspace                                 |
+| **Right Sidebar** | `sqllab.rightSidebar` | Contextual tools (AI assistants, query analysis)           |
+| **Panels**        | `sqllab.panels`       | Results and related views (visualizations, data profiling) |
+| **Status Bar**    | `sqllab.statusBar`    | Connection status and query metrics                        |
+
+## Area Customizations
+
+Each extension point area supports three types of action customizations:
+
+```
+┌───────────────────────────────────────────────────────────────┐
+│  Area Title                         [Button] [Button]   [•••] │
+├───────────────────────────────────────────────────────────────┤
+│                                                               │
+│                                                               │
+│                          Area Content                         │
+│                                                               │
+│                  (right-click for context menu)               │
+│                                                               │
+│                                                               │
+└───────────────────────────────────────────────────────────────┘
+```
+
+| Action Type           | Location          | Use Case                                              |
+| --------------------- | ----------------- | ----------------------------------------------------- |
+| **Primary Actions**   | Top-right buttons | Frequently used actions (e.g., run, refresh, add new) |
+| **Secondary Actions** | 3-dot menu (•••)  | Less common actions (e.g., export, settings)          |
+| **Context Actions**   | Right-click menu  | Context-sensitive actions on content                  |
+
+## Examples
+
+### Adding a Panel
+
+This example adds a "Data Profiler" panel to SQL Lab:
+
+```json
+{
+  "name": "data_profiler",
+  "version": "1.0.0",
+  "frontend": {
+    "contributions": {
+      "views": {
+        "sqllab.panels": [
+          {
+            "id": "data_profiler.main",
+            "name": "Data Profiler"
+          }
+        ]
+      }
+    }
+  }
+}
+```
+
+```typescript
+import { core } from '@apache-superset/core';
+import DataProfilerPanel from './DataProfilerPanel';
+
+export function activate(context) {
+  // Register the panel view with the ID declared in extension.json
+  const disposable = core.registerView('data_profiler.main', <DataProfilerPanel />);
+  context.subscriptions.push(disposable);
+}
+```
+
+### Adding Actions to the Editor
+
+This example adds primary, secondary, and context actions to the editor:
+
+```json
+{
+  "name": "query_tools",
+  "version": "1.0.0",
+  "frontend": {
+    "contributions": {
+      "commands": [
+        {
+          "command": "query_tools.format",
+          "title": "Format Query",
+          "icon": "FormatPainterOutlined"
+        },
+        {
+          "command": "query_tools.explain",
+          "title": "Explain Query"
+        },
+        {
+          "command": "query_tools.copy_as_cte",
+          "title": "Copy as CTE"
+        }
+      ],
+      "menus": {
+        "sqllab.editor": {
+          "primary": [
+            {
+              "view": "builtin.editor",
+              "command": "query_tools.format"
+            }
+          ],
+          "secondary": [
+            {
+              "view": "builtin.editor",
+              "command": "query_tools.explain"
+            }
+          ],
+          "context": [
+            {
+              "view": "builtin.editor",
+              "command": "query_tools.copy_as_cte"
+            }
+          ]
+        }
+      }
+    }
+  }
+}
+```
+
+```typescript
+import { commands, sqlLab } from '@apache-superset/core';
+
+export function activate(context) {
+  // Register the commands declared in extension.json
+  const formatCommand = commands.registerCommand('query_tools.format', {
+    execute: () => {
+      const tab = sqlLab.getCurrentTab();
+      if (tab?.editor) {
+        // Format the SQL query
+      }
+    },
+  });
+
+  const explainCommand = commands.registerCommand('query_tools.explain', {
+    execute: () => {
+      const tab = sqlLab.getCurrentTab();
+      if (tab?.editor) {
+        // Show query explanation
+      }
+    },
+  });
+
+  const copyAsCteCommand = commands.registerCommand('query_tools.copy_as_cte', {
+    execute: () => {
+      const tab = sqlLab.getCurrentTab();
+      if (tab?.editor) {
+        // Copy selected text as CTE
+      }
+    },
+  });
+
+  context.subscriptions.push(formatCommand, explainCommand, copyAsCteCommand);
+}
+```
+
+## Next Steps
+
+- **[Contribution Types](../contribution-types)** - Learn about other contribution types (commands, menus)
+- **[Development](../development)** - Set up your development environment
+- **[Quick Start](../quick-start)** - Build a complete extension
diff --git a/docs/developer_portal/extensions/extension-project-structure.md b/docs/developer_portal/extensions/extension-project-structure.md
deleted file mode 100644
index 95165ce22d..0000000000
--- a/docs/developer_portal/extensions/extension-project-structure.md
+++ /dev/null
@@ -1,78 +0,0 @@
----
-title: Extension Project Structure
-sidebar_position: 3
----
-
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-
-# Extension Project Structure
-
-The `apache-superset-extensions-cli` package provides a command-line interface (CLI) that streamlines the extension development workflow. It offers the following commands:
-
-```
-superset-extensions init: Generates the initial folder structure and scaffolds a new extension project.
-
-superset-extensions build: Builds extension assets.
-
-superset-extensions bundle: Packages the extension into a .supx file.
-
-superset-extensions dev: Automatically rebuilds the extension as files change.
-```
-
-When creating a new extension with `superset-extensions init <extension-name>`, the CLI generates a standardized folder structure:
-
-```
-dataset_references/
-├── extension.json
-├── frontend/
-│   ├── src/
-│   ├── webpack.config.js
-│   ├── tsconfig.json
-│   └── package.json
-├── backend/
-│   ├── src/
-│        └── dataset_references/
-│   ├── tests/
-│   ├── pyproject.toml
-│   └── requirements.txt
-├── dist/
-│   ├── manifest.json
-│   ├── frontend
-│        └── dist/
-│             ├── remoteEntry.d7a9225d042e4ccb6354.js
-│             └── 900.038b20cdff6d49cfa8d9.js
-│   └── backend
-│        └── dataset_references/
-│             ├── __init__.py
-│             ├── api.py
-│             └── entrypoint.py
-├── dataset_references-1.0.0.supx
-└── README.md
-```
-
-The `extension.json` file serves as the declared metadata for the extension, containing the extension's name, version, author, description, and a list of capabilities. This file is essential for the host application to understand how to load and manage the extension.
-
-The `frontend` directory contains the source code for the frontend components of the extension, including React components, styles, and assets. The `webpack.config.js` file is used to configure Webpack for building the frontend code, while the `tsconfig.json` file defines the TypeScript configuration for the project. The `package.json` file specifies the dependencies and scripts for building and testing the frontend code.
-
-The `backend` directory contains the source code for the backend components of the extension, including Python modules, tests, and configuration files. The `pyproject.toml` file is used to define the Python package and its dependencies, while the r`equirements.txt` file lists the required Python packages for the extension. The `src` folder contains the functional backend source files, `tests` directory contains unit tests for the backend code, ensuring that the extension behaves as expec [...]
-
-The `dist` directory is built when running the `build` or `dev` command, and contains the files that will be included in the bundle. The `manifest.json` file contains critical metadata about the extension, including the majority of the contents of the `extension.json` file, but also other build-time information, like the name of the built Webpack Module Federation remote entry file. The files in the `dist` directory will be zipped into the final `.supx` file. Although this file is techni [...]
-
-The `README.md` file provides documentation and instructions for using the extension, including how to install, configure, and use its functionality.
diff --git a/docs/developer_portal/extensions/interacting-with-host.md b/docs/developer_portal/extensions/interacting-with-host.md
deleted file mode 100644
index c277af5432..0000000000
--- a/docs/developer_portal/extensions/interacting-with-host.md
+++ /dev/null
@@ -1,129 +0,0 @@
----
-title: Interacting with the Host
-sidebar_position: 6
----
-
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-
-# Interacting with the Host
-
-Extensions interact with Superset through well-defined, versioned APIs provided by the `@apache-superset/core` (frontend) and `apache-superset-core` (backend) packages. These APIs are designed to be stable, discoverable, and consistent for both built-in and external extensions.
-
-**Note**: The `superset_core.api` module provides abstract classes that are replaced with concrete implementations via dependency injection when Superset initializes. This allows extensions to use the same interfaces as the host application.
-
-**Frontend APIs** (via `@apache-superset/core)`:
-
-The frontend extension APIs in Superset are organized into logical namespaces such as `authentication`, `commands`, `extensions`, `sqlLab`, and others. Each namespace groups related functionality, making it easy for extension authors to discover and use the APIs relevant to their needs. For example, the `sqlLab` namespace provides events and methods specific to SQL Lab, allowing extensions to react to user actions and interact with the SQL Lab environment:
-
-``` typescript
-export const getCurrentTab: () => Tab | undefined;
-
-export const getDatabases: () => Database[];
-
-export const getTabs: () => Tab[];
-
-export const onDidChangeEditorContent: Event<string>;
-
-export const onDidClosePanel: Event<Panel>;
-
-export const onDidChangeActivePanel: Event<Panel>;
-
-export const onDidChangeTabTitle: Event<string>;
-
-export const onDidQueryRun: Event<Editor>;
-
-export const onDidQueryStop: Event<Editor>;
-```
-
-The following code demonstrates more examples of the existing frontend APIs:
-
-``` typescript
-import { core, commands, sqlLab, authentication, Button } from '@apache-superset/core';
-import MyPanel from './MyPanel';
-
-export function activate(context) {
-  // Register a new panel (view) in SQL Lab and use shared UI components in your extension's React code
-  const panelDisposable = core.registerView('my_extension.panel', <MyPanel><Button/></MyPanel>);
-
-  // Register a custom command
-  const commandDisposable = commands.registerCommand('my_extension.copy_query', {
-    title: 'Copy Query',
-    execute: () => {
-      // Command logic here
-    },
-  });
-
-  // Listen for query run events in SQL Lab
-  const eventDisposable = sqlLab.onDidQueryRun(editor => {
-    // Handle query execution event
-  });
-
-  // Access a CSRF token for secure API requests
-  authentication.getCSRFToken().then(token => {
-    // Use token as needed
-  });
-
-  // Add all disposables for automatic cleanup on deactivation
-  context.subscriptions.push(panelDisposable, commandDisposable, eventDisposable);
-}
-```
-
-**Backend APIs** (via `apache-superset-core`):
-
-Backend APIs follow a similar pattern, providing access to Superset's models, sessions, and query capabilities. Extensions can register REST API endpoints, access the metadata database, and interact with Superset's core functionality.
-
-Extension endpoints are registered under a dedicated `/extensions` namespace to avoid conflicting with built-in endpoints and also because they don't share the same version constraints. By grouping all extension endpoints under `/extensions`, Superset establishes a clear boundary between core and extension functionality, making it easier to manage, document, and secure both types of APIs.
-
-``` python
-from superset_core.api.models import Database, get_session
-from superset_core.api.daos import DatabaseDAO
-from superset_core.api.rest_api import add_extension_api
-from .api import DatasetReferencesAPI
-
-# Register a new extension REST API
-add_extension_api(DatasetReferencesAPI)
-
-# Fetch Superset entities via the DAO to apply base filters that filter out entities
-# that the user doesn't have access to
-databases = DatabaseDAO.find_all()
-
-# ..or apply simple filters on top of base filters
-databases = DatabaseDAO.filter_by(uuid=database.uuid)
-if not databases:
-    raise Exception("Database not found")
-
-return databases[0]
-
-# Perform complex queries using SQLAlchemy Query, also filtering out
-# inaccessible entities
-session = get_session()
-databases_query = session.query(Database).filter(
-    Database.database_name.ilike("%abc%")
-)
-return DatabaseDAO.query(databases_query)
-
-# Bypass security model for highly custom use cases
-session = get_session()
-all_databases_containing_abc = session.query(Database).filter(
-    Database.database_name.ilike("%abc%")
-).all()
-```
-
-In the future, we plan to expand the backend APIs to support configuring security models, database engines, SQL Alchemy dialects, etc.
diff --git a/docs/developer_portal/extensions/mcp.md b/docs/developer_portal/extensions/mcp.md
index c3184ace46..79c7ea9cf7 100644
--- a/docs/developer_portal/extensions/mcp.md
+++ b/docs/developer_portal/extensions/mcp.md
@@ -1,7 +1,7 @@
 ---
 title: MCP Integration
 hide_title: true
-sidebar_position: 8
+sidebar_position: 7
 version: 1
 ---
 
@@ -455,6 +455,5 @@ async def metrics_guide(ctx: Context) -> str:
 
 ## Next Steps
 
-- **[Extension Project Structure](./extension-project-structure)** - Organize larger extensions
-- **[Development Mode](./development-mode)** - Faster iteration during development
-- **[Security Implications](./security-implications)** - Security best practices for extensions
+- **[Development](./development)** - Project structure, APIs, and dev workflow
+- **[Security](./security)** - Security best practices for extensions
diff --git a/docs/developer_portal/extensions/overview.md b/docs/developer_portal/extensions/overview.md
index f902c3b1c1..0ba62a615c 100644
--- a/docs/developer_portal/extensions/overview.md
+++ b/docs/developer_portal/extensions/overview.md
@@ -24,53 +24,29 @@ under the License.
 
 # Overview
 
-Apache Superset's extension system allows developers to enhance and customize Superset's functionality through a modular, plugin-based architecture. Extensions can add new visualization types, custom UI components, data processing capabilities, and integration points.
+Apache Superset's extension system enables organizations to build custom features without modifying the core codebase. Inspired by the [VS Code extension model](https://code.visualstudio.com/api), this architecture addresses a long-standing challenge: teams previously had to fork Superset or make invasive modifications to add capabilities like query optimizers, custom panels, or specialized integrations—resulting in maintenance overhead and codebase fragmentation.
 
-## What are Superset Extensions?
-
-Superset extensions are self-contained packages that extend the core platform's capabilities. They follow a standardized architecture that ensures compatibility, security, and maintainability while providing powerful customization options.
-
-## Extension Architecture
-
-- **[Architecture](./architecture)** - Architectural principles and high-level system overview
-- **[Extension Project Structure](./extension-project-structure)** - Standard project layout and organization
-- **[Extension Metadata](./extension-metadata)** - Configuration and manifest structure
-
-## Development Guide
-
-- **[Frontend Contribution Types](./frontend-contribution-types)** - Types of UI contributions available
-- **[Interacting with Host](./interacting-with-host)** - Communication patterns with Superset core
-- **[Development Mode](./development-mode)** - Tools and workflows for extension development
+The extension system introduces a modular, plugin-based architecture where both built-in features and external extensions use the same well-defined APIs. This "lean core" approach ensures that any capability available to Superset's internal features is equally accessible to community-developed extensions, fostering a vibrant ecosystem while reducing the maintenance burden on core contributors.
 
-For information about runtime loading and dependency management, see the [Dynamic Module Loading](./architecture#dynamic-module-loading) section in the Architecture page.
-
-## Deployment & Management
-
-- **[Deploying Extension](./deploying-extension)** - Packaging and distribution strategies
-- **[Security Implications](./security-implications)** - Security considerations and best practices
-
-## Hands-on Examples
+## What are Superset Extensions?
 
-- **[Quick Start](./quick-start)** - Complete Hello World extension walkthrough
+Superset extensions are self-contained `.supx` packages that extend the platform's capabilities through standardized contribution points. Each extension can include both frontend (React/TypeScript) and backend (Python) components, bundled together and loaded dynamically at runtime using Webpack Module Federation.
 
 ## Extension Capabilities
 
 Extensions can provide:
 
-- **Custom Visualizations**: New chart types and data visualization components
-- **UI Enhancements**: Custom dashboards, panels, and interactive elements  
-- **Data Connectors**: Integration with external data sources and APIs
-- **Workflow Automation**: Custom actions and batch processing capabilities
-- **Authentication Providers**: SSO and custom authentication mechanisms
-- **Theme Customization**: Custom styling and branding options
-
-## Getting Started
-
-1. **Learn the Architecture**: Start with [Architecture](./architecture) to understand the design philosophy
-2. **Set up Development**: Follow the [Development Mode](./development-mode) guide to configure your environment
-3. **Build Your First Extension**: Complete the [Quick Start](./quick-start) tutorial
-4. **Deploy and Share**: Use the [Deploying Extension](./deploying-extension) guide to package your extension
+- **Custom UI Components**: New panels, views, and interactive elements
+- **Commands and Menus**: Custom actions accessible via menus and keyboard shortcuts
+- **REST API Endpoints**: Backend services under the `/api/v1/extensions/` namespace
+- **MCP Tools and Prompts**: AI agent capabilities for enhanced user assistance
 
-## Extension Ecosystem
+## Next Steps
 
-The extension system is designed to foster a vibrant ecosystem of community-contributed functionality. By following the established patterns and guidelines, developers can create extensions that seamlessly integrate with Superset while maintaining the platform's reliability and performance standards.
+- **[Quick Start](./quick-start)** - Build your first extension with a complete walkthrough
+- **[Architecture](./architecture)** - Design principles and system overview
+- **[Contribution Types](./contribution-types)** - Available extension points
+- **[Development](./development)** - Project structure, APIs, and development workflow
+- **[Deployment](./deployment)** - Packaging and deploying extensions
+- **[MCP Integration](./mcp)** - Adding AI agent capabilities using extensions
+- **[Security](./security)** - Security considerations and best practices
diff --git a/docs/developer_portal/extensions/quick-start.md b/docs/developer_portal/extensions/quick-start.md
index f12dd20a16..66549d8af8 100644
--- a/docs/developer_portal/extensions/quick-start.md
+++ b/docs/developer_portal/extensions/quick-start.md
@@ -388,10 +388,9 @@ Here's what happens when your extension loads:
 
 Now that you have a working extension, explore:
 
-- **[Development Mode](./development-mode)** - Faster iteration with local development and watch mode
-- **[Extension Project Structure](./extension-project-structure)** - Best practices for organizing larger extensions
-- **[Frontend Contribution Types](./frontend-contribution-types)** - Other UI contribution points beyond panels
-- **[Interacting with Host](./interacting-with-host)** - Advanced APIs for interacting with Superset
-- **[Security Implications](./security-implications)** - Security best practices for extensions
+- **[Development](./development)** - Project structure, APIs, and development workflow
+- **[Contribution Types](./contribution-types)** - Other contribution points beyond panels
+- **[Deployment](./deployment)** - Packaging and deploying your extension
+- **[Security](./security)** - Security best practices for extensions
 
 For a complete real-world example, examine the query insights extension in the Superset codebase.
diff --git a/docs/developer_portal/extensions/security-implications.md b/docs/developer_portal/extensions/security.md
similarity index 82%
rename from docs/developer_portal/extensions/security-implications.md
rename to docs/developer_portal/extensions/security.md
index 448904b3c2..d197b86cc0 100644
--- a/docs/developer_portal/extensions/security-implications.md
+++ b/docs/developer_portal/extensions/security.md
@@ -1,6 +1,6 @@
 ---
-title: Security Implications and Responsibilities
-sidebar_position: 12
+title: Security
+sidebar_position: 8
 ---
 
 <!--
@@ -22,7 +22,7 @@ specific language governing permissions and limitations
 under the License.
 -->
 
-# Security Implications and Responsibilities
+# Security
 
 By default, extensions are disabled and must be explicitly enabled by setting the `ENABLE_EXTENSIONS` feature flag. Built-in extensions are included as part of the Superset codebase and are held to the same security standards and review processes as the rest of the application.
 
@@ -30,4 +30,6 @@ For external extensions, administrators are responsible for evaluating and verif
 
 We plan to introduce an optional sandboxed execution model for extensions in the future (as part of an additional SIP). Until then, administrators should exercise caution and follow best practices when selecting and deploying third-party extensions. A directory of known Superset extensions may be maintained in a means similar to [this page](https://github.com/apache/superset/wiki/Superset-Third%E2%80%90Party-Plugins-Directory) on the wiki. We also discussed the possibility of introducing [...]
 
-Any performance or security vulnerabilities introduced by external extensions should be reported directly to the extension author, not as Superset vulnerabilities. Any security concerns regarding built-in extensions (included in Superset's monorepo) should be reported to the Superset Security mailing list for triage and resolution by maintainers.
+**Any performance or security vulnerabilities introduced by external extensions should be reported directly to the extension author, not as Superset vulnerabilities.**
+
+Any security concerns regarding built-in extensions (included in Superset's monorepo) should be reported to the Superset Security mailing list for triage and resolution by maintainers.
diff --git a/docs/developer_portal/sidebars.js b/docs/developer_portal/sidebars.js
index 9ea1db552f..d361865d63 100644
--- a/docs/developer_portal/sidebars.js
+++ b/docs/developer_portal/sidebars.js
@@ -36,13 +36,19 @@ module.exports = {
         'extensions/overview',
         'extensions/quick-start',
         'extensions/architecture',
-        'extensions/extension-project-structure',
-        'extensions/extension-metadata',
-        'extensions/frontend-contribution-types',
-        'extensions/interacting-with-host',
-        'extensions/deploying-extension',
-        'extensions/development-mode',
-        'extensions/security-implications',
+        'extensions/contribution-types',
+        {
+          type: 'category',
+          label: 'Extension Points',
+          collapsed: true,
+          items: [
+            'extensions/extension-points/sqllab',
+          ],
+        },
+        'extensions/development',
+        'extensions/deployment',
+        'extensions/mcp',
+        'extensions/security',
       ],
     },
     {
diff --git a/docs/sidebarTutorials.js b/docs/sidebarTutorials.js
index 8d9d9f72fc..7abc29f51a 100644
--- a/docs/sidebarTutorials.js
+++ b/docs/sidebarTutorials.js
@@ -80,13 +80,19 @@ const sidebars = {
         'extensions/overview',
         'extensions/quick-start',
         'extensions/architecture',
-        'extensions/extension-project-structure',
-        'extensions/extension-metadata',
-        'extensions/frontend-contribution-types',
-        'extensions/interacting-with-host',
-        'extensions/deploying-extension',
-        'extensions/development-mode',
-        'extensions/security-implications',
+        'extensions/contribution-types',
+        {
+          type: 'category',
+          label: 'Extension Points',
+          collapsed: true,
+          items: [
+            'extensions/extension-points/sqllab',
+          ],
+        },
+        'extensions/development',
+        'extensions/deployment',
+        'extensions/mcp',
+        'extensions/security',
       ],
     },
     {