SSE Client Execution Flow

Visualizing the asynchronous Server-Sent Events client workflow
1
Connect to SSE Endpoint
async with aiohttp.ClientSession() as session: async with session.get(sse_url) as sse_response:
DEBUG: Connecting to SSE endpoint: http://sse-server-py:3001/sse
GET http://sse-server-py:3001/sse 200 OK
DEBUG: Connected to SSE endpoint: http://sse-server-py:3001/sse
2
Extract Session ID from SSE Stream
async for line in sse_response.content: if line: decoded_line = line.decode().strip() if decoded_line.startswith('event:'): event_type = decoded_line[6:].strip() elif decoded_line.startswith('data:'): data = decoded_line[5:].strip() if event_type == 'endpoint': session_id = data.split('session_id=')[1]
event: endpoint
data: {"url":"http://sse-server-py:3001/messages/?session_id=abc123"}
DEBUG: Received line: event: endpoint
DEBUG: Event type: endpoint
DEBUG: Received line: data: {"url":"http://sse-server-py:3001/messages/?session_id=abc123"}
DEBUG: Data: {"url":"http://sse-server-py:3001/messages/?session_id=abc123"}
INFO: Obtained session_id: abc123
3
Send Initialize Request
initialize_payload = { "jsonrpc": "2.0", "id": 0, "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": { "sampling": {}, "roots": {"listChanged": True} }, "clientInfo": { "name": "mcp", "version": "0.1.0" } } } async with session.post(url, json=initialize_payload)
POST http://sse-server-py:3001/messages/?session_id=abc123 202 Accepted
{ "jsonrpc": "2.0", "id": 0, "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": { "sampling": {}, "roots": {"listChanged": true} }, "clientInfo": { "name": "mcp", "version": "0.1.0" } } }
DEBUG: Sending initialize request with payload: {...}
INFO: Initialize request accepted.
4
Send Initialized Notification
initialized_notification = { "jsonrpc": "2.0", "method": "notifications/initialized" } async with session.post(url, json=initialized_notification)
POST http://sse-server-py:3001/messages/?session_id=abc123 202 Accepted
{ "jsonrpc": "2.0", "method": "notifications/initialized" }
DEBUG: Sending notifications/initialized notification: {...}
INFO: notifications/initialized notification accepted.
5
Send Fetch Tool Call Request
fetch_payload = { "method": "tools/call", "params": { "name": "fetch", "arguments": {"url": "https://httpstat.us/200"} }, "jsonrpc": "2.0", "id": 1 } async with session.post(url, json=fetch_payload)
POST http://sse-server-py:3001/messages/?session_id=abc123 202 Accepted
{ "method": "tools/call", "params": { "name": "fetch", "arguments": {"url": "https://httpstat.us/200"} }, "jsonrpc": "2.0", "id": 1 }
DEBUG: Sending fetch tool call request with payload: {...}
INFO: fetch tool call request accepted.
6
Listen for SSE Responses
async for line in sse_response.content: if line: decoded_line = line.decode().strip() if decoded_line.startswith('data:'): data = decoded_line[5:].strip() message = json.loads(data) if message.get('id') == 1: logger.info(f"Received response: {message}")
event: message
data: { "jsonrpc": "2.0", "id": 1, "result": { "status": 200, "body": "200 OK", "headers": {...} } }
DEBUG: Received line: data: {...}
INFO: Received fetch tool call sse_response: {...}
SSE Client Workflow Diagram
1
Establish SSE Connection
Client connects to the SSE endpoint and waits for initial messages
2
Receive Session ID
Client extracts session_id from the SSE stream's endpoint event
3
Initialize Session
Client sends initialize request with capabilities and client info
4
Send Initialized Notification
Client notifies server that initialization is complete
5
Make API Call
Client sends a fetch tool call request with target URL
SSE
Receive Response via SSE
Client listens for SSE messages containing the API response