initial mcp server setup

This commit is contained in:
OwusuBlessing
2025-09-11 23:13:58 +01:00
commit 20f96c0f30
141 changed files with 14444 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
# MCP Tools Collection
from .math_tools import MathTools
from .text_tools import TextTools
from .system_tools import SystemTools
from .web_tools import WebTools
from .tool_registry import ToolRegistry
__all__ = ['MathTools', 'TextTools', 'SystemTools', 'WebTools', 'ToolRegistry']
+186
View File
@@ -0,0 +1,186 @@
"""
Mathematical Tools for MCP
"""
from typing import List
from ..core.types import MCPTool
class MathTools:
"""Collection of mathematical tools"""
@staticmethod
def get_tools() -> List[MCPTool]:
"""Get all math tools"""
return [
MathTools._create_add_tool(),
MathTools._create_subtract_tool(),
MathTools._create_multiply_tool(),
MathTools._create_divide_tool(),
MathTools._create_power_tool(),
MathTools._create_square_root_tool(),
MathTools._create_calculate_bmi_tool(),
]
@staticmethod
def _create_add_tool() -> MCPTool:
"""Create addition tool"""
async def add(a: float, b: float) -> float:
"""Add two numbers together"""
return a + b
return MCPTool(
name="add",
description="Add two numbers together",
input_schema={
"type": "object",
"properties": {
"a": {"type": "number", "description": "First number"},
"b": {"type": "number", "description": "Second number"},
},
"required": ["a", "b"],
},
handler=add,
)
@staticmethod
def _create_subtract_tool() -> MCPTool:
"""Create subtraction tool"""
async def subtract(a: float, b: float) -> float:
"""Subtract second number from first"""
return a - b
return MCPTool(
name="subtract",
description="Subtract second number from first",
input_schema={
"type": "object",
"properties": {
"a": {"type": "number", "description": "First number"},
"b": {"type": "number", "description": "Number to subtract"},
},
"required": ["a", "b"],
},
handler=subtract,
)
@staticmethod
def _create_multiply_tool() -> MCPTool:
"""Create multiplication tool"""
async def multiply(a: float, b: float) -> float:
"""Multiply two numbers"""
return a * b
return MCPTool(
name="multiply",
description="Multiply two numbers",
input_schema={
"type": "object",
"properties": {
"a": {"type": "number", "description": "First number"},
"b": {"type": "number", "description": "Second number"},
},
"required": ["a", "b"],
},
handler=multiply,
)
@staticmethod
def _create_divide_tool() -> MCPTool:
"""Create division tool"""
async def divide(a: float, b: float) -> float:
"""Divide first number by second"""
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b
return MCPTool(
name="divide",
description="Divide first number by second",
input_schema={
"type": "object",
"properties": {
"a": {"type": "number", "description": "Dividend"},
"b": {"type": "number", "description": "Divisor (cannot be zero)"},
},
"required": ["a", "b"],
},
handler=divide,
)
@staticmethod
def _create_power_tool() -> MCPTool:
"""Create power tool"""
async def power(base: float, exponent: float) -> float:
"""Calculate base raised to the power of exponent"""
return base ** exponent
return MCPTool(
name="power",
description="Calculate base raised to the power of exponent",
input_schema={
"type": "object",
"properties": {
"base": {"type": "number", "description": "Base number"},
"exponent": {"type": "number", "description": "Exponent"},
},
"required": ["base", "exponent"],
},
handler=power,
)
@staticmethod
def _create_square_root_tool() -> MCPTool:
"""Create square root tool"""
async def square_root(number: float) -> float:
"""Calculate square root of a number"""
if number < 0:
raise ValueError("Cannot calculate square root of negative number")
return number ** 0.5
return MCPTool(
name="square_root",
description="Calculate square root of a number",
input_schema={
"type": "object",
"properties": {
"number": {"type": "number", "description": "Number to find square root of (must be non-negative)"},
},
"required": ["number"],
},
handler=square_root,
)
@staticmethod
def _create_calculate_bmi_tool() -> MCPTool:
"""Create BMI calculation tool"""
async def calculate_bmi(weight_kg: float, height_m: float) -> str:
"""Calculate BMI and provide health category"""
if weight_kg <= 0 or height_m <= 0:
raise ValueError("Weight and height must be positive numbers")
bmi = weight_kg / (height_m ** 2)
if bmi < 18.5:
category = "Underweight"
elif bmi < 25:
category = "Normal weight"
elif bmi < 30:
category = "Overweight"
else:
category = "Obese"
return ".1f"
return MCPTool(
name="calculate_bmi",
description="Calculate BMI and provide health assessment",
input_schema={
"type": "object",
"properties": {
"weight_kg": {"type": "number", "description": "Weight in kilograms"},
"height_m": {"type": "number", "description": "Height in meters"},
},
"required": ["weight_kg", "height_m"],
},
handler=calculate_bmi,
)
@@ -0,0 +1,157 @@
"""
System Tools for MCP
"""
import os
import platform
import psutil
from datetime import datetime
from typing import Dict, Any, List
from ..core.types import MCPTool
class SystemTools:
"""Collection of system-related tools"""
@staticmethod
def get_tools() -> List[MCPTool]:
"""Get all system tools"""
return [
SystemTools._create_get_system_info_tool(),
SystemTools._create_get_current_time_tool(),
SystemTools._create_list_directory_tool(),
SystemTools._create_get_file_info_tool(),
SystemTools._create_get_environment_variable_tool(),
]
@staticmethod
def _create_get_system_info_tool() -> MCPTool:
"""Create system info tool"""
async def get_system_info() -> Dict[str, Any]:
"""Get basic system information"""
try:
return {
"platform": platform.system(),
"platform_version": platform.version(),
"architecture": platform.machine(),
"processor": platform.processor(),
"python_version": platform.python_version(),
"cpu_count": os.cpu_count(),
"memory_total": psutil.virtual_memory().total if psutil else "psutil not available",
"memory_available": psutil.virtual_memory().available if psutil else "psutil not available",
}
except Exception as e:
return {"error": f"Could not retrieve system info: {str(e)}"}
return MCPTool(
name="get_system_info",
description="Get basic system information including OS, CPU, and memory details",
input_schema={"type": "object", "properties": {}},
handler=get_system_info,
)
@staticmethod
def _create_get_current_time_tool() -> MCPTool:
"""Create current time tool"""
async def get_current_time() -> str:
"""Get the current date and time"""
now = datetime.now()
return now.strftime("%Y-%m-%d %H:%M:%S")
return MCPTool(
name="get_current_time",
description="Get the current date and time in YYYY-MM-DD HH:MM:SS format",
input_schema={"type": "object", "properties": {}},
handler=get_current_time,
)
@staticmethod
def _create_list_directory_tool() -> MCPTool:
"""Create directory listing tool"""
async def list_directory(path: str = ".") -> List[str]:
"""List contents of a directory"""
try:
if not os.path.exists(path):
raise ValueError(f"Path does not exist: {path}")
if not os.path.isdir(path):
raise ValueError(f"Path is not a directory: {path}")
return os.listdir(path)
except Exception as e:
raise ValueError(f"Could not list directory: {str(e)}")
return MCPTool(
name="list_directory",
description="List the contents of a directory",
input_schema={
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "Directory path to list",
"default": "."
},
},
},
handler=list_directory,
)
@staticmethod
def _create_get_file_info_tool() -> MCPTool:
"""Create file info tool"""
async def get_file_info(file_path: str) -> Dict[str, Any]:
"""Get information about a file"""
try:
if not os.path.exists(file_path):
raise ValueError(f"File does not exist: {file_path}")
stat = os.stat(file_path)
return {
"name": os.path.basename(file_path),
"path": os.path.abspath(file_path),
"size": stat.st_size,
"is_file": os.path.isfile(file_path),
"is_directory": os.path.isdir(file_path),
"modified_time": datetime.fromtimestamp(stat.st_mtime).isoformat(),
"created_time": datetime.fromtimestamp(stat.st_ctime).isoformat(),
}
except Exception as e:
raise ValueError(f"Could not get file info: {str(e)}")
return MCPTool(
name="get_file_info",
description="Get detailed information about a file or directory",
input_schema={
"type": "object",
"properties": {
"file_path": {"type": "string", "description": "Path to the file or directory"},
},
"required": ["file_path"],
},
handler=get_file_info,
)
@staticmethod
def _create_get_environment_variable_tool() -> MCPTool:
"""Create environment variable tool"""
async def get_environment_variable(name: str, default_value: str = "") -> str:
"""Get the value of an environment variable"""
return os.getenv(name, default_value)
return MCPTool(
name="get_environment_variable",
description="Get the value of an environment variable",
input_schema={
"type": "object",
"properties": {
"name": {"type": "string", "description": "Name of the environment variable"},
"default_value": {
"type": "string",
"description": "Default value if variable is not set",
"default": ""
},
},
"required": ["name"],
},
handler=get_environment_variable,
)
+187
View File
@@ -0,0 +1,187 @@
"""
Text Processing Tools for MCP
"""
import re
from typing import List
from ..core.types import MCPTool
class TextTools:
"""Collection of text processing tools"""
@staticmethod
def get_tools() -> List[MCPTool]:
"""Get all text tools"""
return [
TextTools._create_word_count_tool(),
TextTools._create_text_search_tool(),
TextTools._create_text_replace_tool(),
TextTools._create_text_uppercase_tool(),
TextTools._create_text_lowercase_tool(),
TextTools._create_text_length_tool(),
TextTools._create_generate_greeting_tool(),
]
@staticmethod
def _create_word_count_tool() -> MCPTool:
"""Create word count tool"""
async def count_words(text: str) -> int:
"""Count the number of words in a text"""
words = text.strip().split()
return len(words)
return MCPTool(
name="count_words",
description="Count the number of words in a text",
input_schema={
"type": "object",
"properties": {
"text": {"type": "string", "description": "Text to count words in"},
},
"required": ["text"],
},
handler=count_words,
)
@staticmethod
def _create_text_search_tool() -> MCPTool:
"""Create text search tool"""
async def search_text(text: str, pattern: str, case_sensitive: bool = False) -> List[str]:
"""Search for a pattern in text and return all matches"""
flags = 0 if case_sensitive else re.IGNORECASE
matches = re.findall(pattern, text, flags)
return matches
return MCPTool(
name="search_text",
description="Search for a pattern in text and return all matches",
input_schema={
"type": "object",
"properties": {
"text": {"type": "string", "description": "Text to search in"},
"pattern": {"type": "string", "description": "Regular expression pattern to search for"},
"case_sensitive": {"type": "boolean", "description": "Whether search should be case sensitive", "default": False},
},
"required": ["text", "pattern"],
},
handler=search_text,
)
@staticmethod
def _create_text_replace_tool() -> MCPTool:
"""Create text replace tool"""
async def replace_text(text: str, old_pattern: str, new_text: str) -> str:
"""Replace all occurrences of a pattern in text"""
return text.replace(old_pattern, new_text)
return MCPTool(
name="replace_text",
description="Replace all occurrences of a pattern in text",
input_schema={
"type": "object",
"properties": {
"text": {"type": "string", "description": "Original text"},
"old_pattern": {"type": "string", "description": "Text to replace"},
"new_text": {"type": "string", "description": "Replacement text"},
},
"required": ["text", "old_pattern", "new_text"],
},
handler=replace_text,
)
@staticmethod
def _create_text_uppercase_tool() -> MCPTool:
"""Create uppercase tool"""
async def to_uppercase(text: str) -> str:
"""Convert text to uppercase"""
return text.upper()
return MCPTool(
name="to_uppercase",
description="Convert text to uppercase",
input_schema={
"type": "object",
"properties": {
"text": {"type": "string", "description": "Text to convert to uppercase"},
},
"required": ["text"],
},
handler=to_uppercase,
)
@staticmethod
def _create_text_lowercase_tool() -> MCPTool:
"""Create lowercase tool"""
async def to_lowercase(text: str) -> str:
"""Convert text to lowercase"""
return text.lower()
return MCPTool(
name="to_lowercase",
description="Convert text to lowercase",
input_schema={
"type": "object",
"properties": {
"text": {"type": "string", "description": "Text to convert to lowercase"},
},
"required": ["text"],
},
handler=to_lowercase,
)
@staticmethod
def _create_text_length_tool() -> MCPTool:
"""Create text length tool"""
async def text_length(text: str) -> int:
"""Get the length of text"""
return len(text)
return MCPTool(
name="text_length",
description="Get the length of text (number of characters)",
input_schema={
"type": "object",
"properties": {
"text": {"type": "string", "description": "Text to measure length of"},
},
"required": ["text"],
},
handler=text_length,
)
@staticmethod
def _create_generate_greeting_tool() -> MCPTool:
"""Create greeting generation tool"""
async def generate_greeting(name: str, style: str = "casual") -> str:
"""Generate a personalized greeting"""
name = name.strip()
if not name:
raise ValueError("Name cannot be empty")
if style == "casual":
return f"Hey {name}! Welcome! 👋"
elif style == "formal":
return f"Good day, {name}. Welcome to our platform."
elif style == "professional":
return f"Hello, {name}. Thank you for joining us."
else:
return f"Hi {name}! Welcome!"
return MCPTool(
name="generate_greeting",
description="Generate a personalized greeting with different styles",
input_schema={
"type": "object",
"properties": {
"name": {"type": "string", "description": "Person's name"},
"style": {
"type": "string",
"enum": ["casual", "formal", "professional"],
"description": "Greeting style",
"default": "casual"
},
},
"required": ["name"],
},
handler=generate_greeting,
)
@@ -0,0 +1,80 @@
"""
Tool Registry for easy tool management and combination
"""
from typing import List, Dict, Any, Optional
from ..core.types import MCPTool
from .math_tools import MathTools
from .text_tools import TextTools
from .system_tools import SystemTools
from .web_tools import WebTools
class ToolRegistry:
"""Registry for managing and combining MCP tools from different categories"""
def __init__(self):
self._tool_categories = {
'math': MathTools,
'text': TextTools,
'system': SystemTools,
'web': WebTools,
}
self._custom_tools: List[MCPTool] = []
def get_tools_by_category(self, category: str) -> List[MCPTool]:
"""Get all tools from a specific category"""
if category not in self._tool_categories:
raise ValueError(f"Unknown tool category: {category}")
return self._tool_categories[category].get_tools()
def get_tools_by_categories(self, categories: List[str]) -> List[MCPTool]:
"""Get tools from multiple categories"""
tools = []
for category in categories:
tools.extend(self.get_tools_by_category(category))
return tools
def get_all_tools(self) -> List[MCPTool]:
"""Get all tools from all categories"""
tools = []
for category in self._tool_categories.values():
tools.extend(category.get_tools())
tools.extend(self._custom_tools)
return tools
def add_custom_tool(self, tool: MCPTool) -> None:
"""Add a custom tool to the registry"""
self._custom_tools.append(tool)
def add_custom_tools(self, tools: List[MCPTool]) -> None:
"""Add multiple custom tools to the registry"""
self._custom_tools.extend(tools)
def get_available_categories(self) -> List[str]:
"""Get list of available tool categories"""
return list(self._tool_categories.keys())
def get_category_info(self) -> Dict[str, Dict[str, Any]]:
"""Get information about each category"""
info = {}
for category_name, category_class in self._tool_categories.items():
tools = category_class.get_tools()
info[category_name] = {
'tool_count': len(tools),
'tool_names': [tool.name for tool in tools]
}
return info
def create_server_config(self, categories: Optional[List[str]] = None) -> Dict[str, Any]:
"""Create a server configuration with tools from specified categories"""
if categories is None:
tools = self.get_all_tools()
else:
tools = self.get_tools_by_categories(categories)
return {
'tools': tools,
'tool_count': len(tools),
'categories': categories or self.get_available_categories()
}
+161
View File
@@ -0,0 +1,161 @@
"""
Web Tools for MCP
"""
import urllib.parse
from typing import Dict, Any, List, Optional
from ..core.types import MCPTool
class WebTools:
"""Collection of web-related tools"""
@staticmethod
def get_tools() -> List[MCPTool]:
"""Get all web tools"""
return [
WebTools._create_url_encode_tool(),
WebTools._create_url_decode_tool(),
WebTools._create_parse_url_tool(),
WebTools._create_validate_email_tool(),
WebTools._create_extract_domain_tool(),
]
@staticmethod
def _create_url_encode_tool() -> MCPTool:
"""Create URL encode tool"""
async def url_encode(text: str) -> str:
"""URL encode a string"""
return urllib.parse.quote(text)
return MCPTool(
name="url_encode",
description="URL encode a string for safe transmission",
input_schema={
"type": "object",
"properties": {
"text": {"type": "string", "description": "Text to URL encode"},
},
"required": ["text"],
},
handler=url_encode,
)
@staticmethod
def _create_url_decode_tool() -> MCPTool:
"""Create URL decode tool"""
async def url_decode(encoded_text: str) -> str:
"""URL decode a string"""
try:
return urllib.parse.unquote(encoded_text)
except Exception:
raise ValueError("Invalid URL encoded string")
return MCPTool(
name="url_decode",
description="URL decode a previously encoded string",
input_schema={
"type": "object",
"properties": {
"encoded_text": {"type": "string", "description": "URL encoded text to decode"},
},
"required": ["encoded_text"],
},
handler=url_decode,
)
@staticmethod
def _create_parse_url_tool() -> MCPTool:
"""Create URL parsing tool"""
async def parse_url(url: str) -> Dict[str, str]:
"""Parse a URL and return its components"""
try:
parsed = urllib.parse.urlparse(url)
return {
"scheme": parsed.scheme,
"netloc": parsed.netloc,
"hostname": parsed.hostname,
"port": str(parsed.port) if parsed.port else "",
"path": parsed.path,
"query": parsed.query,
"fragment": parsed.fragment,
}
except Exception:
raise ValueError("Invalid URL format")
return MCPTool(
name="parse_url",
description="Parse a URL and return its components (scheme, host, path, etc.)",
input_schema={
"type": "object",
"properties": {
"url": {"type": "string", "description": "URL to parse"},
},
"required": ["url"],
},
handler=parse_url,
)
@staticmethod
def _create_validate_email_tool() -> MCPTool:
"""Create email validation tool"""
async def validate_email(email: str) -> Dict[str, Any]:
"""Validate an email address format"""
import re
email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
is_valid = bool(re.match(email_pattern, email))
# Extract domain
if is_valid and '@' in email:
domain = email.split('@')[1]
else:
domain = ""
return {
"email": email,
"is_valid": is_valid,
"domain": domain,
}
return MCPTool(
name="validate_email",
description="Validate an email address format and extract domain",
input_schema={
"type": "object",
"properties": {
"email": {"type": "string", "description": "Email address to validate"},
},
"required": ["email"],
},
handler=validate_email,
)
@staticmethod
def _create_extract_domain_tool() -> MCPTool:
"""Create domain extraction tool"""
async def extract_domain(url: str) -> str:
"""Extract the domain from a URL"""
try:
parsed = urllib.parse.urlparse(url)
if parsed.hostname:
return parsed.hostname
else:
# Fallback for URLs without scheme
url_with_scheme = "http://" + url if "://" not in url else url
parsed = urllib.parse.urlparse(url_with_scheme)
return parsed.hostname or ""
except Exception:
return ""
return MCPTool(
name="extract_domain",
description="Extract the domain name from a URL",
input_schema={
"type": "object",
"properties": {
"url": {"type": "string", "description": "URL to extract domain from"},
},
"required": ["url"],
},
handler=extract_domain,
)