Major changes: - Migrate from low-level MCP to FastMCP framework for better compatibility - Add custom exception hierarchy (VultrAPIError, VultrAuthError, etc.) - Replace basic IPv6 validation with Python's ipaddress module - Add HTTP request timeouts (30s total, 10s connect) - Modernize development workflow with uv package manager - Create FastMCP server with proper async/await patterns New features: - FastMCP server implementation with 12 DNS management tools - Comprehensive Claude Desktop integration guide - Enhanced error handling with specific exception types - Professional README with badges and examples - Complete testing suite with improvement validation Documentation: - CLAUDE.md: Consolidated project documentation - CLAUDE_DESKTOP_SETUP.md: Step-by-step Claude Desktop setup guide - Updated README.md with modern structure and uv-first approach - Enhanced TESTING.md with FastMCP testing patterns Development improvements: - Updated all scripts to use uv run commands - Smart development setup with uv/pip fallback - Added comprehensive test coverage for new features - PyPI-ready package configuration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
53 lines
1.5 KiB
Python
53 lines
1.5 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import asyncio
|
|
import sys
|
|
import os
|
|
from mcp.server import Server
|
|
from mcp.server.stdio import stdio_server
|
|
from mcp.types import Resource, Tool, TextContent
|
|
|
|
async def main():
|
|
# Set up API key
|
|
api_key = os.getenv("VULTR_API_KEY")
|
|
if not api_key:
|
|
print("VULTR_API_KEY not set", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
print(f"Starting server with API key: {api_key[:8]}...", file=sys.stderr)
|
|
|
|
# Create minimal server
|
|
server = Server("vultr-dns-debug")
|
|
|
|
@server.list_tools()
|
|
async def list_tools() -> list[Tool]:
|
|
return [
|
|
Tool(
|
|
name="test_tool",
|
|
description="A simple test tool",
|
|
inputSchema={
|
|
"type": "object",
|
|
"properties": {},
|
|
"required": []
|
|
}
|
|
)
|
|
]
|
|
|
|
@server.call_tool()
|
|
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
|
|
if name == "test_tool":
|
|
return [TextContent(type="text", text="Test tool working!")]
|
|
return [TextContent(type="text", text=f"Unknown tool: {name}")]
|
|
|
|
print("Server configured, starting stdio...", file=sys.stderr)
|
|
|
|
try:
|
|
async with stdio_server() as (read_stream, write_stream):
|
|
print("Running server...", file=sys.stderr)
|
|
await server.run(read_stream, write_stream, None)
|
|
except Exception as e:
|
|
print(f"Server error: {e}", file=sys.stderr)
|
|
raise
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main()) |