| 853 | } |
| 854 | |
| 855 | fn write_jsonrpc_script() -> PathBuf { |
| 856 | let root = temp_dir(); |
| 857 | fs::create_dir_all(&root).expect("temp dir"); |
| 858 | let script_path = root.join("jsonrpc-mcp.py"); |
| 859 | let script = [ |
| 860 | "#!/usr/bin/env python3", |
| 861 | "import json, sys", |
| 862 | "header = b''", |
| 863 | r"while not header.endswith(b'\r\n\r\n'):", |
| 864 | " chunk = sys.stdin.buffer.read(1)", |
| 865 | " if not chunk:", |
| 866 | " raise SystemExit(1)", |
| 867 | " header += chunk", |
| 868 | "length = 0", |
| 869 | r"for line in header.decode().split('\r\n'):", |
| 870 | r" if line.lower().startswith('content-length:'):", |
| 871 | r" length = int(line.split(':', 1)[1].strip())", |
| 872 | "payload = sys.stdin.buffer.read(length)", |
| 873 | "request = json.loads(payload.decode())", |
| 874 | r"assert request['jsonrpc'] == '2.0'", |
| 875 | r"assert request['method'] == 'initialize'", |
| 876 | r"response = json.dumps({", |
| 877 | r" 'jsonrpc': '2.0',", |
| 878 | r" 'id': request['id'],", |
| 879 | r" 'result': {", |
| 880 | r" 'protocolVersion': request['params']['protocolVersion'],", |
| 881 | r" 'capabilities': {'tools': {}},", |
| 882 | r" 'serverInfo': {'name': 'fake-mcp', 'version': '0.1.0'}", |
| 883 | r" }", |
| 884 | r"}).encode()", |
| 885 | r"sys.stdout.buffer.write(f'Content-Length: {len(response)}\r\n\r\n'.encode() + response)", |
| 886 | "sys.stdout.buffer.flush()", |
| 887 | "", |
| 888 | ] |
| 889 | .join("\n"); |
| 890 | fs::write(&script_path, script).expect("write script"); |
| 891 | let mut permissions = fs::metadata(&script_path).expect("metadata").permissions(); |
| 892 | permissions.set_mode(0o755); |
| 893 | fs::set_permissions(&script_path, permissions).expect("chmod"); |
| 894 | script_path |
| 895 | } |
| 896 | |
| 897 | #[allow(clippy::too_many_lines)] |
| 898 | fn write_mcp_server_script() -> PathBuf { |