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 409cdad264 fix(mcp): prevent MCP service from corrupting shared 
appbuilder singleton (#37252)
409cdad264 is described below

commit 409cdad2648c7476cf1769196e970149cbecf800
Author: Michael S. Molina <[email protected]>
AuthorDate: Mon Jan 19 13:03:37 2026 -0300

    fix(mcp): prevent MCP service from corrupting shared appbuilder singleton 
(#37252)
---
 superset/mcp_service/flask_singleton.py | 82 ++++++++++++++++++++++-----------
 1 file changed, 54 insertions(+), 28 deletions(-)

diff --git a/superset/mcp_service/flask_singleton.py 
b/superset/mcp_service/flask_singleton.py
index 055883cd5b..d508943e86 100644
--- a/superset/mcp_service/flask_singleton.py
+++ b/superset/mcp_service/flask_singleton.py
@@ -25,6 +25,7 @@ Following the Stack Overflow recommendation:
 """
 
 import logging
+import os
 
 from flask import Flask
 
@@ -33,34 +34,59 @@ logger = logging.getLogger(__name__)
 logger.info("Creating Flask app instance for MCP service")
 
 try:
-    from superset.app import create_app
-    from superset.mcp_service.mcp_config import get_mcp_config
-
-    # Create a temporary context to avoid
-    # "Working outside of application context" errors.
-    _temp_app = create_app()
-
-    # Push an application context and initialize core dependencies and 
extensions
-    with _temp_app.app_context():
-        # Apply MCP configuration - reads from app.config first, falls back to 
defaults
-        mcp_config = get_mcp_config(_temp_app.config)
-        _temp_app.config.update(mcp_config)
-        try:
-            from superset.initialization import SupersetAppInitializer
-
-            # Create initializer and run only dependency injection
-            # NOT the full init_app_in_ctx which includes web views
-            initializer = SupersetAppInitializer(_temp_app)
-            initializer.init_all_dependencies_and_extensions()
-
-            logger.info("Core dependencies and extensions initialized for MCP 
service")
-        except Exception as e:
-            logger.warning("Failed to initialize dependencies for MCP service: 
%s", e)
-
-    # Store the app instance for later use
-    app = _temp_app
-
-    logger.info("Minimal Flask app instance created successfully for MCP 
service")
+    from superset.extensions import appbuilder
+
+    # Check if appbuilder is already initialized (main Superset app is 
running).
+    # If so, reuse that app to avoid corrupting the shared appbuilder 
singleton.
+    # Calling create_app() again would re-initialize appbuilder and break 
views.
+    if appbuilder.app is not None:
+        logger.info("Reusing existing Flask app from appbuilder for MCP 
service")
+        app = appbuilder.app
+    else:
+        # Create a minimal Flask app for standalone MCP server.
+        # We avoid calling create_app() which would run full FAB initialization
+        # and could corrupt the shared appbuilder singleton if main app starts.
+        from superset.app import SupersetApp
+        from superset.mcp_service.mcp_config import get_mcp_config
+
+        # Disable debug mode to avoid side-effects like file watchers
+        _mcp_app = SupersetApp(__name__)
+        _mcp_app.debug = False
+
+        # Load configuration
+        config_module = os.environ.get("SUPERSET_CONFIG", "superset.config")
+        _mcp_app.config.from_object(config_module)
+
+        # Apply MCP-specific configuration
+        mcp_config = get_mcp_config(_mcp_app.config)
+        _mcp_app.config.update(mcp_config)
+
+        # Initialize only the minimal dependencies needed for MCP service
+        with _mcp_app.app_context():
+            try:
+                from superset.extensions import db
+
+                db.init_app(_mcp_app)
+
+                # Initialize only MCP-specific dependencies
+                # MCP tools import directly from superset.daos/models, so we 
only need
+                # the MCP decorator injection, not the full superset_core 
abstraction
+                from superset.core.mcp.core_mcp_injection import (
+                    initialize_core_mcp_dependencies,
+                )
+
+                initialize_core_mcp_dependencies()
+
+                logger.info(
+                    "Minimal MCP dependencies initialized for standalone MCP 
service"
+                )
+            except Exception as e:
+                logger.warning(
+                    "Failed to initialize dependencies for MCP service: %s", e
+                )
+
+        app = _mcp_app
+        logger.info("Minimal Flask app instance created successfully for MCP 
service")
 
 except Exception as e:
     logger.error("Failed to create Flask app: %s", e)

Reply via email to