Files
archon/python/src/mcp_server/utils/http_client.py
Rasmus Widing cf3d7b17fe feat(mcp): Add robust error handling and timeout configuration
Critical improvements to MCP server reliability and client experience:

Error Handling:
- Created MCPErrorFormatter for consistent error responses across all tools
- Provides structured errors with type, message, details, and actionable suggestions
- Helps clients (like Claude Code) understand and handle failures gracefully
- Categorizes errors (connection_timeout, validation_error, etc.) for better debugging

Timeout Configuration:
- Centralized timeout config with environment variable support
- Different timeouts for regular operations vs polling operations
- Configurable via MCP_REQUEST_TIMEOUT, MCP_CONNECT_TIMEOUT, etc.
- Prevents indefinite hangs when services are unavailable

Module Registration:
- Distinguishes between ImportError (acceptable) and code errors (must fix)
- SyntaxError/NameError/AttributeError now halt execution immediately
- Prevents broken code from silently failing in production

Polling Safety:
- Fixed project creation polling with exponential backoff
- Handles API unavailability with proper error messages
- Maximum attempts configurable via MCP_MAX_POLLING_ATTEMPTS

Response Normalization:
- Fixed inconsistent response handling in list_tasks
- Validates and normalizes different API response formats
- Clear error messages when response format is unexpected

These changes address critical issues from PR review while maintaining
backward compatibility. All 20 existing tests pass.
2025-08-19 15:38:13 +03:00

38 lines
1.0 KiB
Python

"""
HTTP client utilities for MCP Server.
Provides consistent HTTP client configuration.
"""
from contextlib import asynccontextmanager
from typing import AsyncIterator, Optional
import httpx
from .timeout_config import get_default_timeout, get_polling_timeout
@asynccontextmanager
async def get_http_client(
timeout: Optional[httpx.Timeout] = None, for_polling: bool = False
) -> AsyncIterator[httpx.AsyncClient]:
"""
Create an HTTP client with consistent configuration.
Args:
timeout: Optional custom timeout. If not provided, uses defaults.
for_polling: If True, uses polling-specific timeout configuration.
Yields:
Configured httpx.AsyncClient
Example:
async with get_http_client() as client:
response = await client.get(url)
"""
if timeout is None:
timeout = get_polling_timeout() if for_polling else get_default_timeout()
# Future: Could add retry logic, custom headers, etc. here
async with httpx.AsyncClient(timeout=timeout) as client:
yield client