| import httpx |
| from typing import List, Dict, Any |
|
|
| class MCPClient: |
| """ |
| A client for interacting with a Model Context Protocol (MCP) server. |
| Handles listing and executing tools via HTTP requests. |
| """ |
| def __init__(self, server_url: str): |
| self.server_url = server_url.rstrip('/') |
| self.http_client = httpx.AsyncClient(timeout=30.0) |
|
|
| async def list_tools(self) -> List[Dict[str, Any]]: |
| """Fetches the list of available tools from the MCP server.""" |
| try: |
| response = await self.http_client.get(f"{self.server_url}/mcp/tools") |
| response.raise_for_status() |
| tools_response = response.json() |
| |
| if "tools" in tools_response and isinstance(tools_response["tools"], list): |
| return tools_response["tools"] |
| return [] |
| except (httpx.RequestError, httpx.HTTPStatusError) as e: |
| print(f"Error fetching tools from {self.server_url}: {e}") |
| return [] |
|
|
| async def execute_tool(self, tool_name: str, params: Dict[str, Any]) -> Dict[str, Any]: |
| """Executes a specific tool on the MCP server with the given parameters.""" |
| try: |
| response = await self.http_client.post( |
| f"{self.server_url}/mcp/tools/{tool_name}", |
| json={"params": params} |
| ) |
| response.raise_for_status() |
| return response.json() |
| except (httpx.RequestError, httpx.HTTPStatusError) as e: |
| print(f"Error executing tool '{tool_name}' on {self.server_url}: {e}") |
| return { |
| "status": "error", |
| "result": f"Failed to connect or execute tool on {self.server_url}. Error: {e}" |
| } |
|
|
| async def close(self): |
| """Closes the underlying HTTP client.""" |
| await self.http_client.aclose() |