initial mcp server setup
This commit is contained in:
@@ -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']
|
||||
@@ -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,
|
||||
)
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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,
|
||||
)
|
||||
Reference in New Issue
Block a user