55from contextlib import AsyncExitStack
66from types import TracebackType
77from typing import Any , Generic , Protocol , TypeVar
8+ from abc import ABC , abstractmethod
89
910import anyio
1011from anyio .streams .memory import MemoryObjectReceiveStream , MemoryObjectSendStream
@@ -154,9 +155,23 @@ def cancelled(self) -> bool: # pragma: no cover
154155 return self ._cancel_scope .cancel_called
155156
156157
157- class Session :
158- """Base class for a session that can send progress notifications."""
158+ class Session (ABC ,
159+ Generic [
160+ SendRequestT ,
161+ SendNotificationT ,
162+ SendResultT ,
163+ ReceiveRequestT ,
164+ ReceiveNotificationT ,
165+ ]):
166+ """
167+ Base class for a session that could be inherited by
168+ BaseSessions for JSON-RPC (read-write stream dependent)
169+ and other non JSON-RPC transports.
170+ """
171+
172+ _progress_callbacks : dict [RequestId , ProgressFnT ]
159173
174+ @abstractmethod
160175 async def send_progress_notification (
161176 self ,
162177 progress_token : ProgressToken ,
@@ -165,18 +180,29 @@ async def send_progress_notification(
165180 message : str | None = None ,
166181 ) -> None :
167182 """Sends a progress notification for a request that is currently being processed."""
183+ raise NotImplementedError
168184
185+ @abstractmethod
186+ async def send_request (
187+ self ,
188+ request : SendRequestT ,
189+ result_type : type [ReceiveResultT ],
190+ request_read_timeout_seconds : float | None = None ,
191+ metadata : MessageMetadata = None ,
192+ progress_callback : ProgressFnT | None = None ,
193+ ) -> ReceiveResultT :
194+ """Send a request"""
195+ raise NotImplementedError
169196
170- class BaseSession (
171- Session ,
172- Generic [
173- SendRequestT ,
174- SendNotificationT ,
175- SendResultT ,
176- ReceiveRequestT ,
177- ReceiveNotificationT ,
178- ],
179- ):
197+ async def send_notification (
198+ self ,
199+ notification : SendNotificationT ,
200+ related_request_id : RequestId | None = None ,
201+ ) -> None :
202+ """Emits a notification, which is a one-way message that does not expect a response."""
203+
204+
205+ class BaseSession (Session ):
180206 """Implements an MCP "session" on top of read/write streams, including features
181207 like request/response linking, notifications, and progress.
182208
@@ -187,7 +213,6 @@ class BaseSession(
187213 _response_streams : dict [RequestId , MemoryObjectSendStream [JSONRPCResponse | JSONRPCError ]]
188214 _request_id : int
189215 _in_flight : dict [RequestId , RequestResponder [ReceiveRequestT , SendResultT ]]
190- _progress_callbacks : dict [RequestId , ProgressFnT ]
191216 _response_routers : list [ResponseRouter ]
192217
193218 def __init__ (
0 commit comments