Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
@@ -121,7 +121,7 @@ transport = SseServerTransport("/airtable/mcp")
|
|
121 |
@app.get("/airtable/mcp")
|
122 |
async def handle_sse(request: Request):
|
123 |
logger.debug("Handling SSE connection request")
|
124 |
-
session_id = None # We'll extract this from
|
125 |
async def sse_writer():
|
126 |
nonlocal session_id
|
127 |
logger.debug("Starting SSE writer")
|
@@ -131,35 +131,24 @@ async def handle_sse(request: Request):
|
|
131 |
{"event": "endpoint", "data": endpoint_data}
|
132 |
)
|
133 |
logger.debug(f"Sent endpoint event: {endpoint_data}")
|
134 |
-
async for
|
135 |
-
|
136 |
-
|
137 |
-
message = json.loads(message_data)
|
138 |
# Extract session_id from the endpoint event
|
139 |
-
if
|
140 |
-
endpoint_url =
|
141 |
if "session_id=" in endpoint_url:
|
142 |
session_id = endpoint_url.split("session_id=")[1]
|
143 |
write_streams[session_id] = write_stream
|
144 |
logger.debug(f"Extracted session_id: {session_id}")
|
145 |
-
|
146 |
-
|
147 |
-
"event": "message",
|
148 |
-
"data": message_data
|
149 |
-
}
|
150 |
-
)
|
151 |
|
152 |
sse_stream_writer, sse_stream_reader = anyio.create_memory_object_stream(0)
|
153 |
try:
|
154 |
async with transport.connect_sse(request.scope, request.receive, request._send) as streams:
|
155 |
read_stream, write_stream = streams
|
156 |
write_stream_reader = write_stream # Since streams are MemoryObject streams
|
157 |
-
# Directly extract session_id from transport
|
158 |
-
session_id = None
|
159 |
-
# Access transport's internal session_id (this is a simplification; we need to match the session_id)
|
160 |
-
# SseServerTransport sets the session_id during connect_sse
|
161 |
-
# We can get it from the endpoint event or transport's internal state
|
162 |
-
# For now, we'll rely on the sse_writer to extract it
|
163 |
logger.debug("Running MCP server with streams")
|
164 |
await mcp_server.run(read_stream, write_stream, mcp_server.create_initialization_options())
|
165 |
except Exception as e:
|
@@ -206,20 +195,18 @@ async def handle_post_message(request: Request):
|
|
206 |
}
|
207 |
}
|
208 |
logger.debug(f"Manual initialize response: {response}")
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
|
|
214 |
return Response(status_code=202)
|
215 |
if message.get("method") == "tools/list":
|
216 |
logger.debug("Handling tools/list request manually")
|
217 |
# If write_stream is not found, try to find it by iterating over write_streams
|
218 |
if not write_stream and session_id:
|
219 |
-
# Since we're not extracting session_id correctly, we'll bypass for now
|
220 |
-
# In a real scenario, we'd need to ensure session_id is set
|
221 |
logger.warning(f"Session ID {session_id} not found in write_streams, attempting to proceed")
|
222 |
-
# Send the response to all active write_streams (temporary workaround)
|
223 |
response = {
|
224 |
"jsonrpc": "2.0",
|
225 |
"id": message.get("id"),
|
@@ -229,14 +216,14 @@ async def handle_post_message(request: Request):
|
|
229 |
}
|
230 |
}
|
231 |
logger.debug(f"Manual tools/list response: {response}")
|
232 |
-
|
233 |
-
message=mcp_types.JSONRPCResponse(**response),
|
234 |
-
metadata=mcp_types.ServerMessageMetadata(request_context=request)
|
235 |
-
)
|
236 |
# Send to all active write_streams (temporary workaround)
|
237 |
for sid, ws in list(write_streams.items()):
|
238 |
try:
|
239 |
-
await ws.send(
|
|
|
|
|
|
|
240 |
logger.debug(f"Sent tools/list response to session {sid}")
|
241 |
except Exception as e:
|
242 |
logger.error(f"Error sending to session {sid}: {str(e)}")
|
|
|
121 |
@app.get("/airtable/mcp")
|
122 |
async def handle_sse(request: Request):
|
123 |
logger.debug("Handling SSE connection request")
|
124 |
+
session_id = None # We'll extract this from the endpoint event
|
125 |
async def sse_writer():
|
126 |
nonlocal session_id
|
127 |
logger.debug("Starting SSE writer")
|
|
|
131 |
{"event": "endpoint", "data": endpoint_data}
|
132 |
)
|
133 |
logger.debug(f"Sent endpoint event: {endpoint_data}")
|
134 |
+
async for event in sse_stream_writer.stream:
|
135 |
+
# Log the raw SSE event to understand its format
|
136 |
+
logger.debug(f"Raw SSE event: {event}")
|
|
|
137 |
# Extract session_id from the endpoint event
|
138 |
+
if event.get("event") == "endpoint":
|
139 |
+
endpoint_url = event.get("data", "")
|
140 |
if "session_id=" in endpoint_url:
|
141 |
session_id = endpoint_url.split("session_id=")[1]
|
142 |
write_streams[session_id] = write_stream
|
143 |
logger.debug(f"Extracted session_id: {session_id}")
|
144 |
+
# Forward the event to the client
|
145 |
+
await sse_stream_writer.send(event)
|
|
|
|
|
|
|
|
|
146 |
|
147 |
sse_stream_writer, sse_stream_reader = anyio.create_memory_object_stream(0)
|
148 |
try:
|
149 |
async with transport.connect_sse(request.scope, request.receive, request._send) as streams:
|
150 |
read_stream, write_stream = streams
|
151 |
write_stream_reader = write_stream # Since streams are MemoryObject streams
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
logger.debug("Running MCP server with streams")
|
153 |
await mcp_server.run(read_stream, write_stream, mcp_server.create_initialization_options())
|
154 |
except Exception as e:
|
|
|
195 |
}
|
196 |
}
|
197 |
logger.debug(f"Manual initialize response: {response}")
|
198 |
+
# Send the response directly as an SSE event
|
199 |
+
response_data = json.dumps(response)
|
200 |
+
await write_stream.send({
|
201 |
+
"event": "message",
|
202 |
+
"data": response_data
|
203 |
+
})
|
204 |
return Response(status_code=202)
|
205 |
if message.get("method") == "tools/list":
|
206 |
logger.debug("Handling tools/list request manually")
|
207 |
# If write_stream is not found, try to find it by iterating over write_streams
|
208 |
if not write_stream and session_id:
|
|
|
|
|
209 |
logger.warning(f"Session ID {session_id} not found in write_streams, attempting to proceed")
|
|
|
210 |
response = {
|
211 |
"jsonrpc": "2.0",
|
212 |
"id": message.get("id"),
|
|
|
216 |
}
|
217 |
}
|
218 |
logger.debug(f"Manual tools/list response: {response}")
|
219 |
+
response_data = json.dumps(response)
|
|
|
|
|
|
|
220 |
# Send to all active write_streams (temporary workaround)
|
221 |
for sid, ws in list(write_streams.items()):
|
222 |
try:
|
223 |
+
await ws.send({
|
224 |
+
"event": "message",
|
225 |
+
"data": response_data
|
226 |
+
})
|
227 |
logger.debug(f"Sent tools/list response to session {sid}")
|
228 |
except Exception as e:
|
229 |
logger.error(f"Error sending to session {sid}: {str(e)}")
|