# jarvis_mcp/client.py import asyncio import os from contextlib import AsyncExitStack from mcp import ClientSession from mcp.client.streamable_http import streamablehttp_client from util.logger import get_logger logger = get_logger("MCP") class MCPClient: def __init__(self, url: str = "http://localhost:8081"): self.base_url = url.rstrip('/') self.session = None self._exit_stack = AsyncExitStack() async def connect(self): if self.session is not None: return mcp_url = f"{self.base_url}/mcp/" logger.info(f"Verbinde mit OpenHAB MCP: {mcp_url}") try: # Context Manager wie im offiziellen Beispiel self._client_cm = streamablehttp_client(mcp_url) read, write, _ = await self._exit_stack.enter_async_context(self._client_cm) self.session = await self._exit_stack.enter_async_context( ClientSession(read, write) ) await self.session.initialize() logger.info("✅ OpenHAB MCP Verbindung erfolgreich hergestellt") except Exception as e: logger.error(f"❌ MCP Connect Fehler: {e}") raise async def list_tools(self): await self.connect() return await self.session.list_tools() async def call_tool(self, name: str, arguments: dict): await self.connect() return await self.session.call_tool(name, arguments) async def close(self): try: await self._exit_stack.aclose() except Exception as e: logger.warning(f"Close Warning: {e}") self.session = None logger.info("MCP Verbindung geschlossen")