diff --git a/examples/mcp_server/funasr_mcp.py b/examples/mcp_server/funasr_mcp.py index 48c9bba59..6dabeca1f 100644 --- a/examples/mcp_server/funasr_mcp.py +++ b/examples/mcp_server/funasr_mcp.py @@ -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__": diff --git a/examples/mcp_server/test_funasr_mcp.py b/examples/mcp_server/test_funasr_mcp.py new file mode 100644 index 000000000..95c3ce791 --- /dev/null +++ b/examples/mcp_server/test_funasr_mcp.py @@ -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()