-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathverify_sse.py
More file actions
91 lines (83 loc) · 2.93 KB
/
Copy pathverify_sse.py
File metadata and controls
91 lines (83 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#!/usr/bin/env python3
"""Verify MCP over SSE: GET stream open, POST messages, read responses from the SSE stream."""
import http.client
import json
import threading
import time
HOST = "localhost"
PORT = 8099
# --- Step 1: GET /sse synchronously to grab the endpoint (sessionid) ---
c = http.client.HTTPConnection(HOST, PORT, timeout=10)
c.request("GET", "/sse")
resp = c.getresponse()
endpoint = None
while True:
line = resp.readline()
if not line:
break
text = line.decode().strip()
if text.startswith("data:"):
endpoint = text.split(":", 1)[1].strip()
break
print("SSE endpoint:", endpoint)
assert endpoint, "no endpoint event"
# --- Step 2: reader thread consumes remaining SSE stream for responses ---
sse_responses = {}
sse_lock = threading.Lock()
def sse_reader():
while True:
line = resp.readline()
if not line:
break
text = line.decode().strip()
if text.startswith("data:"):
try:
msg = json.loads(text.split(":", 1)[1].strip())
if "id" in msg:
with sse_lock:
sse_responses[msg["id"]] = msg
except json.JSONDecodeError:
pass
threading.Thread(target=sse_reader, daemon=True).start()
# --- Step 3: POST helper (same endpoint with sessionid) ---
def post(payload):
pc = http.client.HTTPConnection(HOST, PORT, timeout=10)
body = json.dumps(payload).encode()
pc.request("POST", endpoint, body=body,
headers={"Content-Type": "application/json",
"Accept": "application/json, text/event-stream"})
r = pc.getresponse()
status = r.status
r.read()
pc.close()
return status
def wait_response(msg_id, label):
for _ in range(30):
with sse_lock:
if msg_id in sse_responses:
d = sse_responses[msg_id]
if "result" in d:
print(f" ✅ {label} OK")
return d["result"]
print(f" response: {json.dumps(d)[:300]}")
return None
time.sleep(0.2)
print(f" ⏱️ timeout waiting for {label}")
return None
# --- Step 4: initialize ---
status = post({"jsonrpc": "2.0", "id": 1, "method": "initialize",
"params": {"protocolVersion": "2025-06-18", "capabilities": {},
"clientInfo": {"name": "sse-test", "version": "1.0"}}})
print(f"initialize POST → HTTP {status}")
res = wait_response(1, "initialize")
if res:
srv = res.get("serverInfo", {})
print(" server:", srv.get("name"), srv.get("version"))
# --- Step 5: tools/list ---
status = post({"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}})
print(f"tools/list POST → HTTP {status}")
res = wait_response(2, "tools/list")
if res:
tools = [t["name"] for t in res.get("tools", [])]
print(" tools:", tools)
print("\n✅ MCP over SSE verified (initialize + tools/list)")