Refactor to use MCP resources for read operations (v1.0.2)
- Convert all read/list operations from tools to resources following MCP best practices - Add @mcp.resource decorators for domains, records, and analysis endpoints - Update version to 1.0.2 - Add uvx support documentation for Claude Desktop integration - Fix CLI asyncio usage for FastMCP synchronous run() method - Add vultr-mcp-server console script entry point This improves alignment with MCP patterns where resources represent readable data and tools perform actions that modify state. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
66c4c3cb18
commit
691963a43b
14
CHANGELOG.md
14
CHANGELOG.md
@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
|
|||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [1.0.2] - 2025-01-16
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Refactored read operations to use MCP resources instead of tools
|
||||||
|
- List domains endpoint: `@mcp.resource("dns://domains")`
|
||||||
|
- Get domain endpoint: `@mcp.resource("dns://domains/{domain}")`
|
||||||
|
- List records endpoint: `@mcp.resource("dns://domains/{domain}/records")`
|
||||||
|
- Get record endpoint: `@mcp.resource("dns://domains/{domain}/records/{record_id}")`
|
||||||
|
- Analyze domain endpoint: `@mcp.resource("dns://domains/{domain}/analysis")`
|
||||||
|
|
||||||
|
### Improved
|
||||||
|
- Better alignment with MCP best practices (resources for read, tools for write)
|
||||||
|
- Enhanced Claude Desktop integration documentation with uvx support
|
||||||
|
|
||||||
## [1.0.1] - 2024-12-20
|
## [1.0.1] - 2024-12-20
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
14
CLAUDE.md
14
CLAUDE.md
@ -24,7 +24,9 @@ vultr-dns-mcp domains list
|
|||||||
vultr-dns-mcp records list example.com
|
vultr-dns-mcp records list example.com
|
||||||
|
|
||||||
# As MCP server
|
# As MCP server
|
||||||
uv run python -m vultr_dns_mcp
|
vultr-mcp-server
|
||||||
|
# or using Python module
|
||||||
|
python -m vultr_dns_mcp
|
||||||
```
|
```
|
||||||
|
|
||||||
## Development Setup
|
## Development Setup
|
||||||
@ -135,6 +137,7 @@ vultr-dns-mcp/
|
|||||||
- Built on FastMCP 2.0 framework for better Claude Desktop compatibility
|
- Built on FastMCP 2.0 framework for better Claude Desktop compatibility
|
||||||
- All tools use proper async/await patterns
|
- All tools use proper async/await patterns
|
||||||
- 12 comprehensive DNS management tools
|
- 12 comprehensive DNS management tools
|
||||||
|
- **Important**: FastMCP's `run()` method is synchronous, not async. Do not wrap with `asyncio.run()`
|
||||||
|
|
||||||
### MCP Tools (12 total)
|
### MCP Tools (12 total)
|
||||||
- Domain management: list, create, delete, get details
|
- Domain management: list, create, delete, get details
|
||||||
@ -167,7 +170,8 @@ vultr-dns-mcp/
|
|||||||
- **FEATURE**: Added HTTP request timeouts (30s total, 10s connect)
|
- **FEATURE**: Added HTTP request timeouts (30s total, 10s connect)
|
||||||
- **FEATURE**: Full uv package manager integration throughout project
|
- **FEATURE**: Full uv package manager integration throughout project
|
||||||
- **FEATURE**: Created comprehensive Claude Desktop setup documentation
|
- **FEATURE**: Created comprehensive Claude Desktop setup documentation
|
||||||
- **FIX**: Resolved event loop issues with proper async/await patterns
|
- **FIX**: Resolved event loop issues - FastMCP 2.0 uses synchronous `run()` method
|
||||||
|
- **FEATURE**: Added `vultr-mcp-server` console script entry point for easier Claude Desktop integration
|
||||||
- **IMPROVEMENT**: Enhanced README with professional structure and badges
|
- **IMPROVEMENT**: Enhanced README with professional structure and badges
|
||||||
- **IMPROVEMENT**: Added test suite for validating all improvements
|
- **IMPROVEMENT**: Added test suite for validating all improvements
|
||||||
|
|
||||||
@ -233,7 +237,7 @@ Use the GitHub Actions "Publish to PyPI" workflow with manual trigger.
|
|||||||
### Common Issues
|
### Common Issues
|
||||||
- **ImportError**: Run `uv sync` or `pip install -e .` from repository root
|
- **ImportError**: Run `uv sync` or `pip install -e .` from repository root
|
||||||
- **AsyncioError**: FastMCP handles async properly, ensure tools use `async def`
|
- **AsyncioError**: FastMCP handles async properly, ensure tools use `async def`
|
||||||
- **Event Loop Error**: Use `await` instead of `asyncio.run()` in FastMCP tools
|
- **Event Loop Error**: FastMCP 2.0's `run()` method is synchronous - do NOT use `asyncio.run()`
|
||||||
- **MCP Connection**: Ensure Claude Desktop config uses absolute Python path
|
- **MCP Connection**: Ensure Claude Desktop config uses absolute Python path
|
||||||
- **API Errors**: Verify VULTR_API_KEY environment variable is set
|
- **API Errors**: Verify VULTR_API_KEY environment variable is set
|
||||||
|
|
||||||
@ -263,8 +267,8 @@ python -c "from vultr_dns_mcp.server import create_mcp_server"
|
|||||||
{
|
{
|
||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"vultr-dns": {
|
"vultr-dns": {
|
||||||
"command": "/path/to/python",
|
"command": "vultr-mcp-server",
|
||||||
"args": ["-m", "vultr_dns_mcp"],
|
"args": [],
|
||||||
"env": {
|
"env": {
|
||||||
"VULTR_API_KEY": "your-api-key"
|
"VULTR_API_KEY": "your-api-key"
|
||||||
}
|
}
|
||||||
|
@ -40,12 +40,28 @@ The configuration file location depends on your OS:
|
|||||||
|
|
||||||
Add this to your `claude_desktop_config.json`:
|
Add this to your `claude_desktop_config.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"vultr-dns": {
|
||||||
|
"command": "vultr-mcp-server",
|
||||||
|
"args": [],
|
||||||
|
"env": {
|
||||||
|
"VULTR_API_KEY": "YOUR_VULTR_API_KEY_HERE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note**: If `vultr-mcp-server` is not in your PATH, use the full Python module approach:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"vultr-dns": {
|
"vultr-dns": {
|
||||||
"command": "python",
|
"command": "python",
|
||||||
"args": ["-m", "vultr_dns_mcp.server"],
|
"args": ["-m", "vultr_dns_mcp"],
|
||||||
"env": {
|
"env": {
|
||||||
"VULTR_API_KEY": "YOUR_VULTR_API_KEY_HERE"
|
"VULTR_API_KEY": "YOUR_VULTR_API_KEY_HERE"
|
||||||
}
|
}
|
||||||
@ -61,7 +77,49 @@ Add this to your `claude_desktop_config.json`:
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"vultr-dns": {
|
"vultr-dns": {
|
||||||
"command": "uv",
|
"command": "uv",
|
||||||
"args": ["run", "python", "-m", "vultr_dns_mcp.server"],
|
"args": ["run", "vultr-mcp-server"],
|
||||||
|
"env": {
|
||||||
|
"VULTR_API_KEY": "YOUR_VULTR_API_KEY_HERE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3a. Using uvx (Recommended for Easy Installation)
|
||||||
|
|
||||||
|
This approach uses `uvx` to automatically install and run the package without needing to manage Python environments:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"vultr-dns": {
|
||||||
|
"command": "uvx",
|
||||||
|
"args": [
|
||||||
|
"--from", "vultr-dns-mcp",
|
||||||
|
"vultr-mcp-server"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"VULTR_API_KEY": "YOUR_VULTR_API_KEY_HERE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For TestPyPI version:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"vultr-dns": {
|
||||||
|
"command": "uvx",
|
||||||
|
"args": [
|
||||||
|
"--index-url", "https://test.pypi.org/simple/",
|
||||||
|
"--extra-index-url", "https://pypi.org/simple/",
|
||||||
|
"--index-strategy", "unsafe-best-match",
|
||||||
|
"--from", "vultr-dns-mcp==1.0.1",
|
||||||
|
"vultr-mcp-server"
|
||||||
|
],
|
||||||
"env": {
|
"env": {
|
||||||
"VULTR_API_KEY": "YOUR_VULTR_API_KEY_HERE"
|
"VULTR_API_KEY": "YOUR_VULTR_API_KEY_HERE"
|
||||||
}
|
}
|
||||||
@ -79,7 +137,7 @@ If you have issues, use the absolute path to your Python installation:
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"vultr-dns": {
|
"vultr-dns": {
|
||||||
"command": "/usr/bin/python3",
|
"command": "/usr/bin/python3",
|
||||||
"args": ["-m", "vultr_dns_mcp.server"],
|
"args": ["-m", "vultr_dns_mcp"],
|
||||||
"env": {
|
"env": {
|
||||||
"VULTR_API_KEY": "YOUR_VULTR_API_KEY_HERE"
|
"VULTR_API_KEY": "YOUR_VULTR_API_KEY_HERE"
|
||||||
}
|
}
|
||||||
@ -151,7 +209,9 @@ The server provides these tools that Claude Desktop can use:
|
|||||||
2. **Test server manually**:
|
2. **Test server manually**:
|
||||||
```bash
|
```bash
|
||||||
export VULTR_API_KEY="your-key"
|
export VULTR_API_KEY="your-key"
|
||||||
python -m vultr_dns_mcp.server
|
vultr-mcp-server
|
||||||
|
# or
|
||||||
|
python -m vultr_dns_mcp
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Check API key**:
|
3. **Check API key**:
|
||||||
@ -185,7 +245,7 @@ If Claude Desktop can't find Python:
|
|||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"vultr-dns": {
|
"vultr-dns": {
|
||||||
"command": "/full/path/to/python3",
|
"command": "/full/path/to/python3",
|
||||||
"args": ["-m", "vultr_dns_mcp.server"],
|
"args": ["-m", "vultr_dns_mcp"],
|
||||||
"env": {
|
"env": {
|
||||||
"VULTR_API_KEY": "YOUR_KEY"
|
"VULTR_API_KEY": "YOUR_KEY"
|
||||||
}
|
}
|
||||||
@ -209,8 +269,8 @@ If using a virtual environment:
|
|||||||
{
|
{
|
||||||
"mcpServers": {
|
"mcpServers": {
|
||||||
"vultr-dns": {
|
"vultr-dns": {
|
||||||
"command": "/path/to/your-venv/bin/python",
|
"command": "/path/to/your-venv/bin/vultr-mcp-server",
|
||||||
"args": ["-m", "vultr_dns_mcp.server"],
|
"args": [],
|
||||||
"env": {
|
"env": {
|
||||||
"VULTR_API_KEY": "YOUR_KEY"
|
"VULTR_API_KEY": "YOUR_KEY"
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "vultr-dns-mcp"
|
name = "vultr-dns-mcp"
|
||||||
version = "1.0.1"
|
version = "1.0.2"
|
||||||
description = "A comprehensive Model Context Protocol (MCP) server for managing Vultr DNS records"
|
description = "A comprehensive Model Context Protocol (MCP) server for managing Vultr DNS records"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = {text = "MIT"}
|
license = {text = "MIT"}
|
||||||
@ -82,6 +82,7 @@ Changelog = "https://github.com/rsp2k/vultr-dns-mcp/blob/main/CHANGELOG.md"
|
|||||||
[project.scripts]
|
[project.scripts]
|
||||||
vultr-dns-mcp = "vultr_dns_mcp.cli:main"
|
vultr-dns-mcp = "vultr_dns_mcp.cli:main"
|
||||||
vultr-dns-server = "vultr_dns_mcp.cli:server_command"
|
vultr-dns-server = "vultr_dns_mcp.cli:server_command"
|
||||||
|
vultr-mcp-server = "vultr_dns_mcp.fastmcp_server:run_server"
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
where = ["src"]
|
where = ["src"]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
"""Version information for vultr-dns-mcp package."""
|
"""Version information for vultr-dns-mcp package."""
|
||||||
|
|
||||||
__version__ = "1.0.1"
|
__version__ = "1.0.2"
|
||||||
__version_info__ = tuple(int(i) for i in __version__.split(".") if i.isdigit())
|
__version_info__ = tuple(int(i) for i in __version__.split(".") if i.isdigit())
|
||||||
|
@ -47,7 +47,7 @@ def server(ctx: click.Context):
|
|||||||
click.echo(f"🔄 Press Ctrl+C to stop")
|
click.echo(f"🔄 Press Ctrl+C to stop")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
asyncio.run(run_server(api_key))
|
run_server(api_key)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
click.echo("\n👋 Server stopped")
|
click.echo("\n👋 Server stopped")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -35,12 +35,12 @@ def create_vultr_mcp_server(api_key: Optional[str] = None) -> FastMCP:
|
|||||||
# Initialize Vultr client
|
# Initialize Vultr client
|
||||||
vultr_client = VultrDNSServer(api_key)
|
vultr_client = VultrDNSServer(api_key)
|
||||||
|
|
||||||
@mcp.tool
|
@mcp.resource("dns://domains")
|
||||||
async def list_dns_domains() -> List[Dict[str, Any]]:
|
async def list_dns_domains() -> List[Dict[str, Any]]:
|
||||||
"""List all DNS domains in your Vultr account."""
|
"""List all DNS domains in your Vultr account."""
|
||||||
return await vultr_client.list_domains()
|
return await vultr_client.list_domains()
|
||||||
|
|
||||||
@mcp.tool
|
@mcp.resource("dns://domains/{domain}")
|
||||||
async def get_dns_domain(domain: str) -> Dict[str, Any]:
|
async def get_dns_domain(domain: str) -> Dict[str, Any]:
|
||||||
"""Get details for a specific DNS domain.
|
"""Get details for a specific DNS domain.
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ def create_vultr_mcp_server(api_key: Optional[str] = None) -> FastMCP:
|
|||||||
await vultr_client.delete_domain(domain)
|
await vultr_client.delete_domain(domain)
|
||||||
return {"status": "success", "message": f"Domain {domain} deleted successfully"}
|
return {"status": "success", "message": f"Domain {domain} deleted successfully"}
|
||||||
|
|
||||||
@mcp.tool
|
@mcp.resource("dns://domains/{domain}/records")
|
||||||
async def list_dns_records(domain: str) -> List[Dict[str, Any]]:
|
async def list_dns_records(domain: str) -> List[Dict[str, Any]]:
|
||||||
"""List all DNS records for a domain.
|
"""List all DNS records for a domain.
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ def create_vultr_mcp_server(api_key: Optional[str] = None) -> FastMCP:
|
|||||||
"""
|
"""
|
||||||
return await vultr_client.list_records(domain)
|
return await vultr_client.list_records(domain)
|
||||||
|
|
||||||
@mcp.tool
|
@mcp.resource("dns://domains/{domain}/records/{record_id}")
|
||||||
async def get_dns_record(domain: str, record_id: str) -> Dict[str, Any]:
|
async def get_dns_record(domain: str, record_id: str) -> Dict[str, Any]:
|
||||||
"""Get details for a specific DNS record.
|
"""Get details for a specific DNS record.
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ def create_vultr_mcp_server(api_key: Optional[str] = None) -> FastMCP:
|
|||||||
"""
|
"""
|
||||||
return await vultr_client.validate_record(record_type, name, data, ttl, priority)
|
return await vultr_client.validate_record(record_type, name, data, ttl, priority)
|
||||||
|
|
||||||
@mcp.tool
|
@mcp.resource("dns://domains/{domain}/analysis")
|
||||||
async def analyze_dns_records(domain: str) -> Dict[str, Any]:
|
async def analyze_dns_records(domain: str) -> Dict[str, Any]:
|
||||||
"""Analyze DNS records for a domain and provide recommendations.
|
"""Analyze DNS records for a domain and provide recommendations.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user