Datavision / backend /mcp /__init__.py
DataVision CI/CD Bot
release: clean production build for HuggingFace Space
09801ca
Raw
History Blame Contribute Delete
13.3 kB
# MCP Integration Layer
"""
Model Context Protocol (MCP) Integration for AI Business Analyst.
This module provides MCP-compatible tools for:
- Data cleaning and preprocessing
- Embedding generation
- Graph construction
- SQL execution
- Vision/OCR processing
- Forecasting engine (time-series prediction)
- Simulation engine (what-if scenarios)
- Insight engine (automated analysis)
Architecture:
- Internal Python modules (not external servers)
- Unified tool interface
- Async-ready design
"""
from dataclasses import dataclass
from typing import Any, Dict, List, Optional, Callable
from enum import Enum
import json
class MCPToolType(Enum):
"""Types of MCP tools available"""
DATA_CLEANER = "data_cleaner"
VECTORIZER = "vectorizer"
GRAPH_BUILDER = "graph_builder"
SQL_EXECUTOR = "sql_executor"
VISION_OCR = "vision_ocr"
FORECAST_ENGINE = "forecast_engine"
SIMULATION_ENGINE = "simulation_engine"
INSIGHT_ENGINE = "insight_engine"
PREDICTION_ENGINE = "prediction_engine"
CHART_GENERATOR = "chart_generator"
@dataclass
class MCPToolResult:
"""Result from an MCP tool execution"""
success: bool
data: Any
error: Optional[str] = None
metadata: Optional[Dict] = None
@dataclass
class MCPTool:
"""Definition of an MCP tool"""
name: str
description: str
tool_type: MCPToolType
parameters: Dict[str, Any]
handler: Callable
class MCPRegistry:
"""
Registry for MCP tools.
Provides a unified interface for all MCP capabilities.
"""
def __init__(self):
self._tools: Dict[str, MCPTool] = {}
self._initialize_tools()
def _initialize_tools(self):
"""Initialize all MCP tools"""
# Import tool handlers
from mcp.data_cleaner import (
clean_table,
format_numbers,
normalize_dates,
deduplicate_rows
)
from mcp.vectorizer import (
generate_embeddings,
batch_embed,
compute_similarity
)
from mcp.graph_builder import (
extract_entities,
build_graph_json,
merge_graphs
)
from mcp.sql_executor import (
execute_sql,
create_table_from_df,
query_to_dataframe
)
from mcp.vision_ocr import (
extract_text_from_image,
extract_tables_from_image,
analyze_chart
)
from mcp.forecast_engine import (
ForecastEngine,
forecast_from_dataframe
)
from mcp.simulation_engine import (
SimulationEngine,
simulate_scenarios
)
from mcp.insight_engine import (
InsightEngine,
generate_insights
)
from mcp.prediction_engine import (
PredictionEngine,
predict_revenue,
predict_sales,
predict_churn,
predict_demand
)
from mcp.chart_generator import (
ChartGenerator,
generate_forecast_chart,
generate_scenario_chart
)
# Register Data Cleaner tools
self._register_tool(MCPTool(
name="clean_table",
description="Clean and normalize tabular data",
tool_type=MCPToolType.DATA_CLEANER,
parameters={"data": "DataFrame or dict", "options": "CleaningOptions"},
handler=clean_table
))
self._register_tool(MCPTool(
name="format_numbers",
description="Format and standardize numeric columns",
tool_type=MCPToolType.DATA_CLEANER,
parameters={"data": "DataFrame", "columns": "List[str]", "format": "str"},
handler=format_numbers
))
self._register_tool(MCPTool(
name="normalize_dates",
description="Normalize date formats across data",
tool_type=MCPToolType.DATA_CLEANER,
parameters={"data": "DataFrame", "date_columns": "List[str]"},
handler=normalize_dates
))
self._register_tool(MCPTool(
name="deduplicate_rows",
description="Remove duplicate rows from data",
tool_type=MCPToolType.DATA_CLEANER,
parameters={"data": "DataFrame", "subset": "Optional[List[str]]"},
handler=deduplicate_rows
))
# Register Vectorizer tools
self._register_tool(MCPTool(
name="generate_embeddings",
description="Generate embeddings for text",
tool_type=MCPToolType.VECTORIZER,
parameters={"text": "str"},
handler=generate_embeddings
))
self._register_tool(MCPTool(
name="batch_embed",
description="Generate embeddings for multiple texts",
tool_type=MCPToolType.VECTORIZER,
parameters={"texts": "List[str]", "batch_size": "int"},
handler=batch_embed
))
self._register_tool(MCPTool(
name="compute_similarity",
description="Compute similarity between embeddings",
tool_type=MCPToolType.VECTORIZER,
parameters={"embedding1": "List[float]", "embedding2": "List[float]"},
handler=compute_similarity
))
# Register Graph Builder tools
self._register_tool(MCPTool(
name="extract_entities",
description="Extract entities from text or data",
tool_type=MCPToolType.GRAPH_BUILDER,
parameters={"data": "Any", "entity_types": "List[str]"},
handler=extract_entities
))
self._register_tool(MCPTool(
name="build_graph_json",
description="Build graph structure from entities",
tool_type=MCPToolType.GRAPH_BUILDER,
parameters={"entities": "List[Dict]", "relations": "List[Dict]"},
handler=build_graph_json
))
self._register_tool(MCPTool(
name="merge_graphs",
description="Merge multiple graphs into one",
tool_type=MCPToolType.GRAPH_BUILDER,
parameters={"graphs": "List[Dict]"},
handler=merge_graphs
))
# Register SQL Executor tools
self._register_tool(MCPTool(
name="execute_sql",
description="Execute SQL query on data",
tool_type=MCPToolType.SQL_EXECUTOR,
parameters={"query": "str", "data": "Dict[str, DataFrame]"},
handler=execute_sql
))
self._register_tool(MCPTool(
name="create_table_from_df",
description="Create virtual table from DataFrame",
tool_type=MCPToolType.SQL_EXECUTOR,
parameters={"name": "str", "df": "DataFrame"},
handler=create_table_from_df
))
self._register_tool(MCPTool(
name="query_to_dataframe",
description="Execute query and return DataFrame",
tool_type=MCPToolType.SQL_EXECUTOR,
parameters={"query": "str"},
handler=query_to_dataframe
))
# Register Vision/OCR tools
self._register_tool(MCPTool(
name="extract_text_from_image",
description="Extract text from image using OCR",
tool_type=MCPToolType.VISION_OCR,
parameters={"image_path": "str"},
handler=extract_text_from_image
))
self._register_tool(MCPTool(
name="extract_tables_from_image",
description="Extract tables from image",
tool_type=MCPToolType.VISION_OCR,
parameters={"image_path": "str"},
handler=extract_tables_from_image
))
self._register_tool(MCPTool(
name="analyze_chart",
description="Analyze chart image and extract data",
tool_type=MCPToolType.VISION_OCR,
parameters={"image_path": "str", "chart_type": "Optional[str]"},
handler=analyze_chart
))
# Register Forecast Engine tools
forecast_engine = ForecastEngine()
self._register_tool(MCPTool(
name="forecast_timeseries",
description="Generate time-series forecast with confidence intervals",
tool_type=MCPToolType.FORECAST_ENGINE,
parameters={"data": "List[Dict]", "periods": "int", "confidence": "float"},
handler=forecast_engine.forecast
))
self._register_tool(MCPTool(
name="forecast_from_dataframe",
description="Generate forecast from pandas DataFrame",
tool_type=MCPToolType.FORECAST_ENGINE,
parameters={"df": "DataFrame", "date_col": "str", "value_col": "str", "periods": "int"},
handler=forecast_from_dataframe
))
# Register Simulation Engine tools
simulation_engine = SimulationEngine()
self._register_tool(MCPTool(
name="simulate_scenarios",
description="Run what-if business scenarios (price, marketing, churn)",
tool_type=MCPToolType.SIMULATION_ENGINE,
parameters={"base_revenue": "float", "base_customers": "int", "modifiers": "Dict"},
handler=simulate_scenarios
))
self._register_tool(MCPTool(
name="simulate_pricing",
description="Simulate price change impact on revenue",
tool_type=MCPToolType.SIMULATION_ENGINE,
parameters={"base_revenue": "float", "price_change_pct": "List[float]"},
handler=simulation_engine.simulate
))
self._register_tool(MCPTool(
name="monte_carlo",
description="Run Monte Carlo simulation for revenue prediction",
tool_type=MCPToolType.SIMULATION_ENGINE,
parameters={"base_revenue": "float", "uncertainty": "float", "simulations": "int"},
handler=simulation_engine.run_monte_carlo
))
# Register Insight Engine tools
insight_engine = InsightEngine()
self._register_tool(MCPTool(
name="generate_insights",
description="Generate automated business insights from metrics",
tool_type=MCPToolType.INSIGHT_ENGINE,
parameters={"revenue": "float", "customers": "int", "churn_rate": "float"},
handler=generate_insights
))
self._register_tool(MCPTool(
name="analyze_business",
description="Full business analysis with trends, risks, and opportunities",
tool_type=MCPToolType.INSIGHT_ENGINE,
parameters={"revenue": "float", "revenue_previous": "float", "customers": "int", "orders": "int"},
handler=insight_engine.analyze
))
def _register_tool(self, tool: MCPTool):
"""Register a tool in the registry"""
self._tools[tool.name] = tool
def get_tool(self, name: str) -> Optional[MCPTool]:
"""Get a tool by name"""
return self._tools.get(name)
def list_tools(self, tool_type: Optional[MCPToolType] = None) -> List[MCPTool]:
"""List all tools, optionally filtered by type"""
if tool_type:
return [t for t in self._tools.values() if t.tool_type == tool_type]
return list(self._tools.values())
def execute(self, tool_name: str, **kwargs) -> MCPToolResult:
"""Execute a tool by name with given parameters"""
tool = self.get_tool(tool_name)
if not tool:
return MCPToolResult(
success=False,
data=None,
error=f"Tool '{tool_name}' not found"
)
try:
result = tool.handler(**kwargs)
return MCPToolResult(
success=True,
data=result,
metadata={"tool": tool_name}
)
except Exception as e:
return MCPToolResult(
success=False,
data=None,
error=str(e),
metadata={"tool": tool_name}
)
def get_schema(self) -> Dict:
"""Get MCP-compatible schema for all tools"""
schema = {
"tools": []
}
for tool in self._tools.values():
tool_schema = {
"name": tool.name,
"description": tool.description,
"type": tool.tool_type.value,
"parameters": tool.parameters
}
schema["tools"].append(tool_schema)
return schema
# Lazy singleton
_registry = None
def get_mcp_registry() -> MCPRegistry:
"""Get or create the MCP registry singleton"""
global _registry
if _registry is None:
_registry = MCPRegistry()
return _registry
def execute_mcp_tool(tool_name: str, **kwargs) -> MCPToolResult:
"""Convenience function to execute an MCP tool"""
registry = get_mcp_registry()
return registry.execute(tool_name, **kwargs)