jarvis_mcp/client.py aktualisiert
This commit is contained in:
+57
-21
@@ -1,31 +1,54 @@
|
||||
# jarvis_mcp/client.py (oder wo du sie hast)
|
||||
|
||||
# jarvis_mcp/client.py
|
||||
import asyncio
|
||||
from mcp import ClientSession
|
||||
from mcp.client.streamable_http import streamablehttp_client # wichtig: streamablehttp_client (ohne _)
|
||||
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):
|
||||
self.url = url
|
||||
self.url = url.rstrip('/') + "/mcp/" # WICHTIG: /mcp Endpunkt
|
||||
self.session = None
|
||||
self._client_context = None # Context Manager
|
||||
self._client_context = None
|
||||
|
||||
async def connect(self):
|
||||
if self.session:
|
||||
if self.session is not None:
|
||||
return
|
||||
|
||||
# Neuer Streamable HTTP Client (gibt 3 Werte zurück)
|
||||
self._client_context = streamablehttp_client(
|
||||
self.url,
|
||||
terminate_on_close=False # wichtig für langlebige Verbindungen
|
||||
)
|
||||
logger.info(f"Verbinde mit OpenHAB MCP: {self.url}")
|
||||
|
||||
read, write, _ = await self._client_context.__aenter__()
|
||||
try:
|
||||
self._client_context = streamablehttp_client(
|
||||
self.url,
|
||||
terminate_on_close=True
|
||||
)
|
||||
|
||||
self.session = ClientSession(read, write)
|
||||
await self.session.initialize()
|
||||
streams = await self._client_context.__aenter__()
|
||||
|
||||
print("✅ MCP Verbindung hergestellt")
|
||||
# Manche Versionen geben 2, manche 3 Werte zurück
|
||||
if isinstance(streams, tuple):
|
||||
if len(streams) == 3:
|
||||
read, write, _ = streams
|
||||
else:
|
||||
read, write = streams
|
||||
else:
|
||||
raise ValueError("Unerwartetes Format von streamablehttp_client")
|
||||
|
||||
self.session = ClientSession(read, write)
|
||||
|
||||
# Mit Timeout
|
||||
await asyncio.wait_for(self.session.initialize(), timeout=8.0)
|
||||
|
||||
logger.info("✅ OpenHAB MCP Verbindung erfolgreich")
|
||||
|
||||
except asyncio.TimeoutError:
|
||||
logger.error("❌ Timeout beim MCP Connect")
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"❌ MCP Connect Fehler: {e}")
|
||||
raise
|
||||
|
||||
async def list_tools(self):
|
||||
await self.connect()
|
||||
@@ -36,10 +59,23 @@ class MCPClient:
|
||||
return await self.session.call_tool(name, arguments)
|
||||
|
||||
async def close(self):
|
||||
if self._client_context:
|
||||
await self._client_context.__aexit__(None, None, None)
|
||||
self._client_context = None
|
||||
"""Sauberes Aufräumen"""
|
||||
closed = False
|
||||
if self.session:
|
||||
# Session schließen falls nötig
|
||||
await self.session.close()
|
||||
self.session = None
|
||||
try:
|
||||
if hasattr(self.session, "close"):
|
||||
await self.session.close()
|
||||
closed = True
|
||||
except Exception as e:
|
||||
logger.warning(f"Session close Warning: {e}")
|
||||
|
||||
if self._client_context:
|
||||
try:
|
||||
await self._client_context.__aexit__(None, None, None)
|
||||
except Exception as e:
|
||||
logger.warning(f"Context close Warning: {e}")
|
||||
|
||||
self.session = None
|
||||
self._client_context = None
|
||||
if closed:
|
||||
logger.info("MCP Verbindung geschlossen")
|
||||
Reference in New Issue
Block a user