jackkuo's picture
update
2de095a
raw
history blame
5.37 kB
from mcp.server.fastmcp import FastMCP
from typing import Dict, Any, List, Optional
import json
from datetime import datetime
import statistics
# Initialize FastMCP server
mcp = FastMCP(
"DataAnalyzer", # Name of the MCP server
instructions="You are a data analysis assistant that can perform various types of data analysis, statistics, and data processing tasks.",
host="0.0.0.0",
port=8002,
)
@mcp.tool()
async def analyze_data(input_data: Dict[str, Any], operation: str = "default") -> str:
"""
Perform data analysis on the provided input data.
Args:
input_data (Dict[str, Any]): Data to analyze
operation (str): Type of analysis to perform
Returns:
str: Analysis results
"""
try:
analysis_result = {
"input_size": len(str(input_data)),
"operation_type": operation,
"analysis_timestamp": datetime.now().isoformat(),
"data_summary": f"Processed {len(input_data)} items",
"analysis_results": {}
}
# Perform different types of analysis based on operation
if operation == "statistics":
if isinstance(input_data, dict):
values = [v for v in input_data.values() if isinstance(v, (int, float))]
if values:
analysis_result["analysis_results"] = {
"count": len(values),
"mean": statistics.mean(values),
"median": statistics.median(values),
"min": min(values),
"max": max(values),
"std_dev": statistics.stdev(values) if len(values) > 1 else 0
}
elif operation == "text_analysis":
text_content = str(input_data)
analysis_result["analysis_results"] = {
"character_count": len(text_content),
"word_count": len(text_content.split()),
"line_count": len(text_content.splitlines()),
"unique_words": len(set(text_content.lower().split()))
}
elif operation == "structure_analysis":
analysis_result["analysis_results"] = {
"data_type": type(input_data).__name__,
"is_nested": any(isinstance(v, (dict, list)) for v in input_data.values()) if isinstance(input_data, dict) else False,
"key_types": {k: type(v).__name__ for k, v in input_data.items()} if isinstance(input_data, dict) else {},
"depth": _get_nesting_depth(input_data)
}
return json.dumps(analysis_result, indent=2, ensure_ascii=False)
except Exception as e:
return f"Error analyzing data: {str(e)}"
@mcp.tool()
async def get_data_statistics(data: List[float]) -> str:
"""
Calculate comprehensive statistics for a list of numerical data.
Args:
data (List[float]): List of numerical values
Returns:
str: Statistical analysis results
"""
try:
if not data:
return "Error: No data provided"
if not all(isinstance(x, (int, float)) for x in data):
return "Error: All values must be numerical"
stats = {
"count": len(data),
"sum": sum(data),
"mean": statistics.mean(data),
"median": statistics.median(data),
"min": min(data),
"max": max(data),
"range": max(data) - min(data),
"variance": statistics.variance(data) if len(data) > 1 else 0,
"std_dev": statistics.stdev(data) if len(data) > 1 else 0,
"quartiles": statistics.quantiles(data, n=4) if len(data) > 1 else []
}
return json.dumps(stats, indent=2, ensure_ascii=False)
except Exception as e:
return f"Error calculating statistics: {str(e)}"
@mcp.tool()
async def get_service_statistics() -> str:
"""
Get statistics and information about the data analysis service.
Returns:
str: Service statistics and information
"""
stats = {
"service_name": "DataAnalyzer",
"version": "1.0.0",
"status": "running",
"port": 8002,
"endpoints": ["analyze_data", "get_data_statistics", "get_service_statistics"],
"capabilities": [
"statistical_analysis",
"text_analysis",
"structure_analysis",
"data_processing"
],
"description": "A comprehensive data analysis service providing statistical calculations and data insights"
}
return json.dumps(stats, indent=2, ensure_ascii=False)
def _get_nesting_depth(obj, current_depth=0):
"""Helper function to calculate nesting depth of data structures."""
if isinstance(obj, dict):
if not obj:
return current_depth
return max(_get_nesting_depth(v, current_depth + 1) for v in obj.values())
elif isinstance(obj, list):
if not obj:
return current_depth
return max(_get_nesting_depth(item, current_depth + 1) for item in obj)
else:
return current_depth
if __name__ == "__main__":
# Start the MCP server with stdio transport
mcp.run(transport="stdio")