docs: Improve MCP tool docstrings with examples and usage guidance
- haproxy_add_domain: Explain pool backend, link to haproxy_add_server - haproxy_add_server: Clarify slots 1-10 for load balancing, add examples - haproxy_remove_server: Add usage example - haproxy_list_servers: Explain output format with example - haproxy_list_domains: Add output format example - haproxy_health: Describe JSON structure and monitoring use case - haproxy_domain_health: Explain status values (healthy/degraded/down) - haproxy_set_server_state: Document ready/drain/maint with examples - haproxy_set_server_weight: Explain weight ratio and soft disable - haproxy_get_server_health: Clarify vs haproxy_domain_health - haproxy_get_connections: Add usage examples Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
139
mcp/server.py
139
mcp/server.py
@@ -601,8 +601,15 @@ def restore_servers_from_config() -> int:
|
||||
def haproxy_list_domains() -> str:
|
||||
"""List all configured domains with their backend servers.
|
||||
|
||||
Shows all domains mapped in HAProxy with their pool backend and configured servers.
|
||||
|
||||
Returns:
|
||||
List of domains with their associated backend servers
|
||||
List of domains in format: domain -> pool_N (pool): server=ip:port
|
||||
|
||||
Example:
|
||||
# Output:
|
||||
# • api.example.com -> pool_1 (pool): pool_1_1=10.0.0.1:8080, pool_1_2=10.0.0.2:8080
|
||||
# • web.example.com -> pool_2 (pool): pool_2_1=10.0.0.3:80
|
||||
"""
|
||||
try:
|
||||
domains = []
|
||||
@@ -641,6 +648,9 @@ def haproxy_list_domains() -> str:
|
||||
def haproxy_add_domain(domain: str, ip: str = "", http_port: int = 80) -> str:
|
||||
"""Add a new domain to HAProxy using map-based routing (no reload required).
|
||||
|
||||
Creates a domain mapping to a pool backend. Each domain can have up to 10
|
||||
backend servers for load balancing. Use haproxy_add_server to add more servers.
|
||||
|
||||
Args:
|
||||
domain: The domain name to add (e.g., api.example.com)
|
||||
ip: Optional IP address for initial server; if provided, adds to slot 1
|
||||
@@ -648,6 +658,13 @@ def haproxy_add_domain(domain: str, ip: str = "", http_port: int = 80) -> str:
|
||||
|
||||
Returns:
|
||||
Success message or error description
|
||||
|
||||
Example:
|
||||
# Add domain without server (add servers later)
|
||||
haproxy_add_domain("api.example.com")
|
||||
|
||||
# Add domain with initial server
|
||||
haproxy_add_domain("api.example.com", ip="10.0.0.1", http_port=8080)
|
||||
"""
|
||||
# Validate inputs
|
||||
if not validate_domain(domain):
|
||||
@@ -754,11 +771,19 @@ def haproxy_remove_domain(domain: str) -> str:
|
||||
def haproxy_list_servers(domain: str) -> str:
|
||||
"""List all servers for a specific domain.
|
||||
|
||||
Shows all configured servers with their slot numbers, addresses, and status.
|
||||
Use this to see which slots are in use before adding or removing servers.
|
||||
|
||||
Args:
|
||||
domain: The domain name to list servers for
|
||||
|
||||
Returns:
|
||||
List of servers with their addresses and status
|
||||
List of servers with slot number, address (ip:port), and status (UP/DOWN/MAINT)
|
||||
|
||||
Example:
|
||||
haproxy_list_servers("api.example.com")
|
||||
# Output: pool_1_1: 10.0.0.1:8080 (UP)
|
||||
# pool_1_2: 10.0.0.2:8080 (UP)
|
||||
"""
|
||||
if not validate_domain(domain):
|
||||
return "Error: Invalid domain format"
|
||||
@@ -789,14 +814,26 @@ def haproxy_list_servers(domain: str) -> str:
|
||||
def haproxy_add_server(domain: str, slot: int, ip: str, http_port: int = 80) -> str:
|
||||
"""Add a server to a domain's backend at specified slot.
|
||||
|
||||
Each domain can have up to 10 servers (slots 1-10) for load balancing.
|
||||
To add multiple servers, call this with different slot numbers.
|
||||
HAProxy distributes traffic across all configured servers using round-robin.
|
||||
|
||||
Args:
|
||||
domain: The domain name to add the server to
|
||||
slot: Server slot number (1 to MAX_SLOTS)
|
||||
slot: Server slot number (1-10). Use different slots for multiple servers
|
||||
ip: IP address of the server (required)
|
||||
http_port: HTTP port (default: 80)
|
||||
|
||||
Returns:
|
||||
Success message or error description
|
||||
|
||||
Example:
|
||||
# Add two servers for load balancing
|
||||
haproxy_add_server("api.example.com", slot=1, ip="10.0.0.1", http_port=8080)
|
||||
haproxy_add_server("api.example.com", slot=2, ip="10.0.0.2", http_port=8080)
|
||||
|
||||
# Add a third server
|
||||
haproxy_add_server("api.example.com", slot=3, ip="10.0.0.3", http_port=8080)
|
||||
"""
|
||||
if not validate_domain(domain):
|
||||
return "Error: Invalid domain format"
|
||||
@@ -831,12 +868,19 @@ def haproxy_add_server(domain: str, slot: int, ip: str, http_port: int = 80) ->
|
||||
def haproxy_remove_server(domain: str, slot: int) -> str:
|
||||
"""Remove a server from a domain's backend at specified slot.
|
||||
|
||||
Removes the server from load balancing rotation. Use haproxy_list_servers
|
||||
to see which slots are in use before removing.
|
||||
|
||||
Args:
|
||||
domain: The domain name to remove the server from
|
||||
slot: Server slot number (1 to MAX_SLOTS) to remove
|
||||
slot: Server slot number (1-10) to remove
|
||||
|
||||
Returns:
|
||||
Success message or error description
|
||||
|
||||
Example:
|
||||
# Remove server at slot 2
|
||||
haproxy_remove_server("api.example.com", slot=2)
|
||||
"""
|
||||
if not validate_domain(domain):
|
||||
return "Error: Invalid domain format"
|
||||
@@ -887,10 +931,19 @@ def haproxy_stats() -> str:
|
||||
|
||||
@mcp.tool()
|
||||
def haproxy_health() -> str:
|
||||
"""Check health of MCP server and HAProxy connectivity.
|
||||
"""Check overall system health (MCP server, HAProxy, config files).
|
||||
|
||||
Use this for monitoring integration. Returns "healthy" if all components are OK.
|
||||
|
||||
Returns:
|
||||
JSON with health status of MCP server, HAProxy, and configuration files
|
||||
JSON with:
|
||||
- status: "healthy" or "unhealthy"
|
||||
- components.mcp: MCP server status
|
||||
- components.haproxy: HAProxy connectivity, version, uptime
|
||||
- components.config_files: map_file and servers_file accessibility
|
||||
|
||||
Example:
|
||||
# Returns: {"status": "healthy", "components": {"mcp": {"status": "ok"}, ...}}
|
||||
"""
|
||||
result: Dict[str, Any] = {
|
||||
"status": "healthy",
|
||||
@@ -938,11 +991,20 @@ def haproxy_health() -> str:
|
||||
def haproxy_domain_health(domain: str) -> str:
|
||||
"""Check health status of backend servers for a specific domain.
|
||||
|
||||
Returns detailed health information for all servers in the domain's backend.
|
||||
|
||||
Args:
|
||||
domain: The domain name to check health for
|
||||
|
||||
Returns:
|
||||
JSON with domain health status including each server's state
|
||||
JSON with:
|
||||
- status: "healthy" (all UP), "degraded" (partial UP), "down" (all DOWN), "no_servers"
|
||||
- servers: list with name, addr, status (UP/DOWN), check_status (L4OK/L4TOUT/L4CON)
|
||||
- healthy_count/total_count: server counts
|
||||
|
||||
Example:
|
||||
haproxy_domain_health("api.example.com")
|
||||
# Returns: {"status": "healthy", "servers": [...], "healthy_count": 2, "total_count": 2}
|
||||
"""
|
||||
if not validate_domain(domain):
|
||||
return json.dumps({"error": "Invalid domain format"})
|
||||
@@ -1061,15 +1123,27 @@ def haproxy_list_frontends() -> str:
|
||||
|
||||
@mcp.tool()
|
||||
def haproxy_set_server_state(backend: str, server: str, state: str) -> str:
|
||||
"""Set server state. States: ready (enable), drain (graceful shutdown), maint (maintenance/disable)
|
||||
"""Set server state for maintenance or traffic control.
|
||||
|
||||
Use haproxy_list_servers to get the backend and server names.
|
||||
|
||||
Args:
|
||||
backend: Backend name (alphanumeric, underscore, hyphen only)
|
||||
server: Server name within the backend
|
||||
state: Target state - ready, drain, or maint
|
||||
backend: Backend name (e.g., "pool_1" from haproxy_list_servers)
|
||||
server: Server name (e.g., "pool_1_1" from haproxy_list_servers)
|
||||
state: Target state:
|
||||
- ready: Enable server for traffic
|
||||
- drain: Stop new connections, finish existing (graceful shutdown)
|
||||
- maint: Disable completely (maintenance mode)
|
||||
|
||||
Returns:
|
||||
Success message or error description
|
||||
|
||||
Example:
|
||||
# Put server in maintenance
|
||||
haproxy_set_server_state("pool_1", "pool_1_2", "maint")
|
||||
|
||||
# Re-enable server
|
||||
haproxy_set_server_state("pool_1", "pool_1_2", "ready")
|
||||
"""
|
||||
if not validate_backend_name(backend):
|
||||
return "Error: Invalid backend name (use alphanumeric, underscore, hyphen only)"
|
||||
@@ -1086,13 +1160,19 @@ def haproxy_set_server_state(backend: str, server: str, state: str) -> str:
|
||||
|
||||
@mcp.tool()
|
||||
def haproxy_get_server_health(backend: str = "") -> str:
|
||||
"""Get health status of all servers or servers in a specific backend.
|
||||
"""Get health status of all servers (low-level view across all backends).
|
||||
|
||||
For domain-specific health, use haproxy_domain_health instead.
|
||||
|
||||
Args:
|
||||
backend: Optional backend name to filter results
|
||||
backend: Optional backend name to filter (e.g., "pool_1"). If empty, shows all.
|
||||
|
||||
Returns:
|
||||
Server health status or error description
|
||||
List of servers with status: UP (healthy), DOWN (failed), MAINT (maintenance)
|
||||
|
||||
Example:
|
||||
haproxy_get_server_health() # All servers
|
||||
haproxy_get_server_health("pool_1") # Only pool_1 backend
|
||||
"""
|
||||
if backend and not validate_backend_name(backend):
|
||||
return "Error: Invalid backend name (use alphanumeric, underscore, hyphen only)"
|
||||
@@ -1114,15 +1194,25 @@ def haproxy_get_server_health(backend: str = "") -> str:
|
||||
|
||||
@mcp.tool()
|
||||
def haproxy_set_server_weight(backend: str, server: str, weight: int) -> str:
|
||||
"""Set server weight (0-256). Weight 0 disables the server for new connections.
|
||||
"""Set server weight for load balancing ratio control.
|
||||
|
||||
Higher weight = more traffic. Default is 1. Use 0 to disable without maintenance mode.
|
||||
|
||||
Args:
|
||||
backend: Backend name (alphanumeric, underscore, hyphen only)
|
||||
server: Server name within the backend
|
||||
weight: Server weight from 0 to 256
|
||||
backend: Backend name (e.g., "pool_1")
|
||||
server: Server name (e.g., "pool_1_1")
|
||||
weight: Weight 0-256 (0 disables, higher = more traffic)
|
||||
|
||||
Returns:
|
||||
Success message or error description
|
||||
|
||||
Example:
|
||||
# Send 2x traffic to server 1 vs server 2
|
||||
haproxy_set_server_weight("pool_1", "pool_1_1", 2)
|
||||
haproxy_set_server_weight("pool_1", "pool_1_2", 1)
|
||||
|
||||
# Temporarily disable server (soft disable, not maintenance)
|
||||
haproxy_set_server_weight("pool_1", "pool_1_3", 0)
|
||||
"""
|
||||
if not validate_backend_name(backend):
|
||||
return "Error: Invalid backend name (use alphanumeric, underscore, hyphen only)"
|
||||
@@ -1139,13 +1229,20 @@ def haproxy_set_server_weight(backend: str, server: str, weight: int) -> str:
|
||||
|
||||
@mcp.tool()
|
||||
def haproxy_get_connections(backend: str = "") -> str:
|
||||
"""Get active connections per server.
|
||||
"""Get active connection counts per server.
|
||||
|
||||
Useful for monitoring traffic distribution and identifying hot spots.
|
||||
|
||||
Args:
|
||||
backend: Optional backend name to filter results
|
||||
backend: Optional backend name to filter (e.g., "pool_1"). If empty, shows all.
|
||||
|
||||
Returns:
|
||||
Connection statistics or error description
|
||||
List of servers with current active connections
|
||||
|
||||
Example:
|
||||
haproxy_get_connections() # All backends
|
||||
haproxy_get_connections("pool_1") # Only pool_1
|
||||
# Output: pool_1/pool_1_1: 5 active connections
|
||||
"""
|
||||
if backend and not validate_backend_name(backend):
|
||||
return "Error: Invalid backend name (use alphanumeric, underscore, hyphen only)"
|
||||
|
||||
Reference in New Issue
Block a user