fix(mcp): use standard newline-delimited stdio

This commit is contained in:
游雁
2026-07-14 03:52:38 +00:00
parent 25fbe2a3d1
commit 51ef095fc9
2 changed files with 53 additions and 20 deletions
+6 -20
View File
@@ -28,14 +28,14 @@ import base64
def send_response(id, result):
msg = {"jsonrpc": "2.0", "id": id, "result": result}
out = json.dumps(msg)
sys.stdout.write(f"Content-Length: {len(out)}\r\n\r\n{out}")
sys.stdout.write(f"{out}\n")
sys.stdout.flush()
def send_notification(method, params=None):
msg = {"jsonrpc": "2.0", "method": method, "params": params or {}}
out = json.dumps(msg)
sys.stdout.write(f"Content-Length: {len(out)}\r\n\r\n{out}")
sys.stdout.write(f"{out}\n")
sys.stdout.flush()
@@ -154,25 +154,11 @@ def handle_request(request):
def main():
"""Run MCP server over stdio."""
import re
buffer = ""
while True:
line = sys.stdin.readline()
for line in sys.stdin:
line = line.strip()
if not line:
break
buffer += line
if "\r\n\r\n" in buffer:
header, body_start = buffer.split("\r\n\r\n", 1)
match = re.search(r"Content-Length: (\d+)", header)
if match:
length = int(match.group(1))
while len(body_start) < length:
body_start += sys.stdin.read(length - len(body_start))
request = json.loads(body_start[:length])
buffer = body_start[length:]
handle_request(request)
else:
buffer = ""
continue
handle_request(json.loads(line))
if __name__ == "__main__":
+47
View File
@@ -0,0 +1,47 @@
import json
import subprocess
import sys
import unittest
from pathlib import Path
SERVER = Path(__file__).with_name("funasr_mcp.py")
class FunASRMCPTransportTest(unittest.TestCase):
def test_stdio_uses_newline_delimited_json_rpc(self):
requests = [
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {"name": "transport-test", "version": "1.0"},
},
},
{"jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {}},
]
stdin = "".join(f"{json.dumps(request)}\n" for request in requests)
completed = subprocess.run(
[sys.executable, str(SERVER)],
input=stdin,
text=True,
capture_output=True,
check=False,
timeout=5,
)
self.assertEqual(completed.returncode, 0, completed.stderr)
responses = [json.loads(line) for line in completed.stdout.splitlines()]
self.assertEqual([response["id"] for response in responses], [1, 2])
self.assertEqual(responses[0]["result"]["serverInfo"]["name"], "funasr")
self.assertEqual(
responses[1]["result"]["tools"][0]["name"], "transcribe_audio"
)
if __name__ == "__main__":
unittest.main()