mirror of
https://github.com/apache/superset.git
synced 2026-05-10 18:35:40 +00:00
- Replace dual Flask/FastAPI setup with a single, unified FastMCP server (`server.py`) - Introduce `MCPDAOWrapper` for secure, context-aware DAO access (`dao_wrapper.py`) - Refactor all MCP tools to be modular and domain-organized (`tools/dashboard/`, `tools/chart/`, `tools/dataset/`, `tools/system/`) - Strongly type all tool contracts with Pydantic v2 models, including full field documentation for LLM/OpenAPI compatibility - Refactor and extend `BaseDAO` for robust, generic CRUD/list operations - Add and update documentation: - Architecture and flow diagrams (`README_ARCHITECTURE.md`) - Tool schema reference and usage instructions (`README.md`, `README_SCHEMAS.md`) - Phase 1 status and roadmap (`README_PHASE1_STATUS.md`) - Implement and test all core list/info tools for dashboards, datasets, and charts, with full search and filter support - Add chart creation tool (`create_chart_simple`) - Provide extension points for Preset-specific auth, RBAC, and logging (stubbed in Phase 1) - Prepare for LLM/agent workflows and future command-based mutations (create/update/delete) - Expand and update unit/integration test coverage for all tools
72 lines
1.9 KiB
Python
72 lines
1.9 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Simple MCP proxy server that connects to FastMCP server on localhost:5009
|
|
"""
|
|
|
|
import signal
|
|
import sys
|
|
import time
|
|
import logging
|
|
from typing import Optional
|
|
|
|
# Configure logging
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Global proxy instance for cleanup
|
|
proxy: Optional['FastMCP'] = None
|
|
|
|
def signal_handler(signum, frame):
|
|
"""Handle shutdown signals gracefully"""
|
|
logger.info(f"Received signal {signum}, shutting down gracefully...")
|
|
if proxy:
|
|
try:
|
|
# Give the proxy a moment to clean up
|
|
time.sleep(0.1)
|
|
except Exception as e:
|
|
logger.warning(f"Error during proxy cleanup: {e}")
|
|
sys.exit(0)
|
|
|
|
def main():
|
|
"""Main function to run the proxy"""
|
|
global proxy
|
|
|
|
try:
|
|
from fastmcp import FastMCP
|
|
|
|
# Set up signal handlers for graceful shutdown
|
|
signal.signal(signal.SIGINT, signal_handler)
|
|
signal.signal(signal.SIGTERM, signal_handler)
|
|
|
|
logger.info("Starting MCP proxy server...")
|
|
|
|
# Create a proxy to the remote FastMCP server
|
|
proxy = FastMCP.as_proxy(
|
|
"http://localhost:5008/mcp/",
|
|
name="Superset MCP Proxy"
|
|
)
|
|
|
|
logger.info("Proxy created successfully, starting...")
|
|
|
|
# Run the proxy (this will block until interrupted)
|
|
proxy.run()
|
|
|
|
except KeyboardInterrupt:
|
|
logger.info("Received keyboard interrupt, shutting down...")
|
|
sys.exit(0)
|
|
except ImportError as e:
|
|
logger.error(f"Failed to import FastMCP: {e}")
|
|
logger.error("Please install fastmcp: pip install fastmcp")
|
|
sys.exit(1)
|
|
except Exception as e:
|
|
logger.error(f"Unexpected error: {e}")
|
|
sys.exit(1)
|
|
finally:
|
|
logger.info("Proxy server stopped")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|