From 9f1589d3303ec03ce97d2cc19f3569fcc2e07677 Mon Sep 17 00:00:00 2001 From: Till Immer Date: Sun, 5 Jul 2026 12:53:56 +0000 Subject: [PATCH] jarvis_mcp/client.py aktualisiert --- jarvis_mcp/client.py | 58 ++++++++++++++++---------------------------- 1 file changed, 21 insertions(+), 37 deletions(-) diff --git a/jarvis_mcp/client.py b/jarvis_mcp/client.py index 2957984..1053014 100644 --- a/jarvis_mcp/client.py +++ b/jarvis_mcp/client.py @@ -1,5 +1,7 @@ # 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 @@ -8,44 +10,32 @@ logger = get_logger("MCP") class MCPClient: - def __init__(self, url: str): - # Entferne alles nach /mcp und füge exakt /mcp/ hinzu - base = url.rstrip('/').split('/mcp')[0] - self.url = base + "/mcp/" # ← WICHTIG: Slash am Ende - + def __init__(self, url: str = "http://localhost:8081"): + self.base_url = url.rstrip('/') self.session = None - self._client_context = None + self._exit_stack = AsyncExitStack() async def connect(self): if self.session is not None: return - logger.info(f"Verbinde mit OpenHAB MCP Server: {self.url}") + mcp_url = f"{self.base_url}/mcp/" + logger.info(f"Verbinde mit OpenHAB MCP: {mcp_url}") try: - self._client_context = streamablehttp_client( - self.url, - terminate_on_close=True + # 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) ) - streams = await self._client_context.__aenter__() + await self.session.initialize() + logger.info("✅ OpenHAB MCP Verbindung erfolgreich hergestellt") - # Flexibles Unpacking - if isinstance(streams, tuple): - read, write = streams[:2] # nimm nur die ersten zwei - else: - raise ValueError("Unerwartetes Response-Format vom Client") - - self.session = ClientSession(read, write) - await asyncio.wait_for(self.session.initialize(), timeout=12.0) - - logger.info("✅ OpenHAB MCP Verbindung erfolgreich hergestellt!") - - except asyncio.TimeoutError: - logger.error("❌ Timeout - MCP Server antwortet nicht rechtzeitig") - raise except Exception as e: - logger.error(f"❌ MCP Verbindungsfehler: {e}") + logger.error(f"❌ MCP Connect Fehler: {e}") raise async def list_tools(self): @@ -57,15 +47,9 @@ class MCPClient: return await self.session.call_tool(name, arguments) async def close(self): - for obj in [self.session, self._client_context]: - if obj: - try: - if hasattr(obj, "close"): - await obj.close() - elif hasattr(obj, "__aexit__"): - await obj.__aexit__(None, None, None) - except Exception as e: - logger.warning(f"Close Warning: {e}") - + try: + await self._exit_stack.aclose() + except Exception as e: + logger.warning(f"Close Warning: {e}") self.session = None - self._client_context = None \ No newline at end of file + logger.info("MCP Verbindung geschlossen") \ No newline at end of file