构建初始UI界面

This commit is contained in:
2026-08-30 13:30:59 +08:00
parent e2f199c6bf
commit 67370888a1
11 changed files with 1634 additions and 171 deletions
+125
View File
@@ -0,0 +1,125 @@
"""opencode <-> Serial Studio MCP bridge.
Serial Studio exposes a native MCP server on TCP port 7777 speaking
JSON-RPC 2.0 (newline-delimited over a raw TCP socket), NOT over HTTP.
opencode's "remote" MCP type expects HTTP (streamableHttp / SSE), so it
cannot talk to Serial Studio directly. This script is a thin stdio
bridge: opencode launches it as a "local" MCP server, reads newline-
delimited JSON-RPC from stdin, forwards each request over TCP to Serial
Studio on port 7777, and writes the response back to stdout.
Usage:
python serial_studio_bridge.py [host] [port]
Defaults: host=127.0.0.1, port=7777
"""
import json
import socket
import sys
DEFAULT_HOST = "127.0.0.1"
DEFAULT_PORT = 7777
def main() -> int:
if len(sys.argv) > 1:
host = sys.argv[1]
else:
host = DEFAULT_HOST
if len(sys.argv) > 2:
port = int(sys.argv[2])
else:
port = DEFAULT_PORT
sock = socket.create_connection((host, port), timeout=10)
sock.settimeout(30)
buf = b""
def send_json(obj) -> None:
line = (json.dumps(obj, separators=(",", ":")) + "\n").encode("utf-8")
sock.sendall(line)
def read_response(target_id) -> dict:
nonlocal buf
while True:
while b"\n" in buf:
line, buf = buf.split(b"\n", 1)
line = line.strip()
if not line:
continue
try:
resp = json.loads(line.decode("utf-8"))
except Exception:
continue
if resp.get("id") == target_id or target_id is None:
return resp
sock.settimeout(30)
data = sock.recv(65536)
if not data:
raise ConnectionError("Serial Studio closed connection")
buf += data
try:
for raw in sys.stdin:
raw = raw.strip()
if not raw:
continue
try:
req = json.loads(raw)
except Exception as e:
err = {
"jsonrpc": "2.0",
"id": None,
"error": {"code": -32700, "message": f"Parse error: {e}"},
}
sys.stdout.write(json.dumps(err) + "\n")
sys.stdout.flush()
continue
if isinstance(req, list):
results = []
for sub in req:
try:
send_json(sub)
results.append(read_response(sub.get("id")))
except Exception as e:
results.append(
{
"jsonrpc": "2.0",
"id": sub.get("id"),
"error": {"code": -32000, "message": str(e)},
}
)
sys.stdout.write(json.dumps(results) + "\n")
sys.stdout.flush()
continue
if req.get("jsonrpc") == "2.0" and not req.get("id"):
send_json(req)
continue
try:
send_json(req)
resp = read_response(req.get("id"))
sys.stdout.write(json.dumps(resp) + "\n")
sys.stdout.flush()
except Exception as e:
err = {
"jsonrpc": "2.0",
"id": req.get("id"),
"error": {"code": -32000, "message": str(e)},
}
sys.stdout.write(json.dumps(err) + "\n")
sys.stdout.flush()
finally:
try:
sock.close()
except Exception:
pass
return 0
if __name__ == "__main__":
sys.exit(main())