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:
kaffa
2026-02-01 13:21:03 +00:00
parent d51e982f7c
commit 85b4e9b4ed

View File

@@ -601,8 +601,15 @@ def restore_servers_from_config() -> int:
def haproxy_list_domains() -> str: def haproxy_list_domains() -> str:
"""List all configured domains with their backend servers. """List all configured domains with their backend servers.
Shows all domains mapped in HAProxy with their pool backend and configured servers.
Returns: 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: try:
domains = [] domains = []
@@ -641,6 +648,9 @@ def haproxy_list_domains() -> str:
def haproxy_add_domain(domain: str, ip: str = "", http_port: int = 80) -> 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). """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: Args:
domain: The domain name to add (e.g., api.example.com) domain: The domain name to add (e.g., api.example.com)
ip: Optional IP address for initial server; if provided, adds to slot 1 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: Returns:
Success message or error description 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 # Validate inputs
if not validate_domain(domain): if not validate_domain(domain):
@@ -754,11 +771,19 @@ def haproxy_remove_domain(domain: str) -> str:
def haproxy_list_servers(domain: str) -> str: def haproxy_list_servers(domain: str) -> str:
"""List all servers for a specific domain. """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: Args:
domain: The domain name to list servers for domain: The domain name to list servers for
Returns: 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): if not validate_domain(domain):
return "Error: Invalid domain format" 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: 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. """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: Args:
domain: The domain name to add the server to 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) ip: IP address of the server (required)
http_port: HTTP port (default: 80) http_port: HTTP port (default: 80)
Returns: Returns:
Success message or error description 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): if not validate_domain(domain):
return "Error: Invalid domain format" 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: def haproxy_remove_server(domain: str, slot: int) -> str:
"""Remove a server from a domain's backend at specified slot. """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: Args:
domain: The domain name to remove the server from 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: Returns:
Success message or error description Success message or error description
Example:
# Remove server at slot 2
haproxy_remove_server("api.example.com", slot=2)
""" """
if not validate_domain(domain): if not validate_domain(domain):
return "Error: Invalid domain format" return "Error: Invalid domain format"
@@ -887,10 +931,19 @@ def haproxy_stats() -> str:
@mcp.tool() @mcp.tool()
def haproxy_health() -> str: 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: 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] = { result: Dict[str, Any] = {
"status": "healthy", "status": "healthy",
@@ -938,11 +991,20 @@ def haproxy_health() -> str:
def haproxy_domain_health(domain: str) -> str: def haproxy_domain_health(domain: str) -> str:
"""Check health status of backend servers for a specific domain. """Check health status of backend servers for a specific domain.
Returns detailed health information for all servers in the domain's backend.
Args: Args:
domain: The domain name to check health for domain: The domain name to check health for
Returns: 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): if not validate_domain(domain):
return json.dumps({"error": "Invalid domain format"}) return json.dumps({"error": "Invalid domain format"})
@@ -1061,15 +1123,27 @@ def haproxy_list_frontends() -> str:
@mcp.tool() @mcp.tool()
def haproxy_set_server_state(backend: str, server: str, state: str) -> str: 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: Args:
backend: Backend name (alphanumeric, underscore, hyphen only) backend: Backend name (e.g., "pool_1" from haproxy_list_servers)
server: Server name within the backend server: Server name (e.g., "pool_1_1" from haproxy_list_servers)
state: Target state - ready, drain, or maint state: Target state:
- ready: Enable server for traffic
- drain: Stop new connections, finish existing (graceful shutdown)
- maint: Disable completely (maintenance mode)
Returns: Returns:
Success message or error description 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): if not validate_backend_name(backend):
return "Error: Invalid backend name (use alphanumeric, underscore, hyphen only)" 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() @mcp.tool()
def haproxy_get_server_health(backend: str = "") -> str: 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: Args:
backend: Optional backend name to filter results backend: Optional backend name to filter (e.g., "pool_1"). If empty, shows all.
Returns: 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): if backend and not validate_backend_name(backend):
return "Error: Invalid backend name (use alphanumeric, underscore, hyphen only)" return "Error: Invalid backend name (use alphanumeric, underscore, hyphen only)"
@@ -1114,15 +1194,25 @@ def haproxy_get_server_health(backend: str = "") -> str:
@mcp.tool() @mcp.tool()
def haproxy_set_server_weight(backend: str, server: str, weight: int) -> str: 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: Args:
backend: Backend name (alphanumeric, underscore, hyphen only) backend: Backend name (e.g., "pool_1")
server: Server name within the backend server: Server name (e.g., "pool_1_1")
weight: Server weight from 0 to 256 weight: Weight 0-256 (0 disables, higher = more traffic)
Returns: Returns:
Success message or error description 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): if not validate_backend_name(backend):
return "Error: Invalid backend name (use alphanumeric, underscore, hyphen only)" 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() @mcp.tool()
def haproxy_get_connections(backend: str = "") -> str: 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: Args:
backend: Optional backend name to filter results backend: Optional backend name to filter (e.g., "pool_1"). If empty, shows all.
Returns: 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): if backend and not validate_backend_name(backend):
return "Error: Invalid backend name (use alphanumeric, underscore, hyphen only)" return "Error: Invalid backend name (use alphanumeric, underscore, hyphen only)"