Skip to content

Commit 0945abc

Browse files
committed
feat(keycardai-mcp): session lifecycle management
1 parent c29a710 commit 0945abc

File tree

6 files changed

+1568
-57
lines changed

6 files changed

+1568
-57
lines changed

packages/mcp/src/keycardai/mcp/client/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from .exceptions import ClientConfigurationError, MCPClientError
1616
from .logging_config import configure_logging, get_logger
1717
from .manager import ClientManager
18-
from .session import Session
18+
from .session import Session, SessionStatus, SessionStatusCategory
1919
from .storage import InMemoryBackend, NamespacedStorage, SQLiteBackend, StorageBackend
2020
from .types import AuthChallenge, ToolInfo
2121

@@ -50,4 +50,6 @@
5050
"get_logger",
5151
# Lower-level primitives (advanced usage)
5252
"Session",
53+
"SessionStatus",
54+
"SessionStatusCategory",
5355
]

packages/mcp/src/keycardai/mcp/client/client.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,24 @@ async def connect(self, server: str | None = None, force_reconnect: bool = False
108108
"""
109109
Connect to servers.
110110
111+
This method attempts to connect to the specified server(s). Connection failures
112+
are communicated via session status, not exceptions. Check session.status or
113+
session.is_operational after calling to determine outcome.
114+
111115
Args:
112116
server: Optional server name. If None, connects to all servers.
113117
force_reconnect: If True, disconnect and reconnect even if already connected.
114118
"""
115119
sessions = [server] if server is not None else list(self.sessions.keys())
116120
for session_name in sessions:
117-
if force_reconnect:
118-
await self.sessions[session_name].disconnect()
119-
await self.sessions[session_name].connect()
121+
try:
122+
if force_reconnect:
123+
await self.sessions[session_name].disconnect()
124+
await self.sessions[session_name].connect()
125+
except Exception:
126+
# Session.connect() should not raise for normal failures - this catches
127+
# only truly unexpected programmer errors
128+
logger.error(f"Unexpected error connecting to server {session_name}", exc_info=True)
120129

121130
async def requires_auth(self, server_name: str | None = None) -> bool:
122131
sessions = [server_name] if server_name is not None else list(self.sessions.keys())

0 commit comments

Comments
 (0)