Files
superset2/superset/mcp_service/simple_proxy.py
Amin Ghadersohi a9d543b6f4 update: unify FastMCP server, modularize tools, and document new DAO-based architecture
- 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
2025-07-30 14:20:37 -04:00

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()