162 lines
5.3 KiB
Python
162 lines
5.3 KiB
Python
"""
|
|
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,
|
|
)
|