iflow-mcp_czh2774-cocosmcp 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Python/__init__.py ADDED
@@ -0,0 +1 @@
1
+ # Cocos MCP Server Package
@@ -0,0 +1,154 @@
1
+ import socket
2
+ import json
3
+ import logging
4
+ from dataclasses import dataclass
5
+ from typing import Dict, Any, Optional
6
+ from config import config
7
+
8
+ # Configure logging
9
+ logging.basicConfig(
10
+ level=getattr(logging, config.log_level),
11
+ format=config.log_format,
12
+ filename=config.log_file,
13
+ filemode='a'
14
+ )
15
+ logger = logging.getLogger("CocosMCP")
16
+
17
+ @dataclass
18
+ class CocosConnection:
19
+ """Manages the socket connection to the Cocos Creator Editor."""
20
+ host: str = config.cocos_host
21
+ port: int = config.cocos_port
22
+ sock: Optional[socket.socket] = None
23
+
24
+ def connect(self) -> bool:
25
+ """Establish a connection to the Cocos Creator Editor."""
26
+ if self.sock:
27
+ return True
28
+ try:
29
+ self.sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
30
+ self.sock.connect((self.host, self.port))
31
+ logger.info(f"Connected to Cocos Creator at {self.host}:{self.port}")
32
+ return True
33
+ except Exception as e:
34
+ logger.error(f"Failed to connect to Cocos Creator: {str(e)}")
35
+ self.sock = None
36
+ return False
37
+
38
+ def disconnect(self):
39
+ """Close the connection to the Cocos Creator Editor."""
40
+ if self.sock:
41
+ try:
42
+ self.sock.close()
43
+ except Exception as e:
44
+ logger.error(f"Error disconnecting from Cocos Creator: {str(e)}")
45
+ finally:
46
+ self.sock = None
47
+
48
+ def receive_full_response(self, sock, buffer_size=config.buffer_size) -> bytes:
49
+ """Receive a complete response from Cocos Creator, handling chunked data."""
50
+ chunks = []
51
+ sock.settimeout(config.connection_timeout) # Use timeout from config
52
+ try:
53
+ while True:
54
+ chunk = sock.recv(buffer_size)
55
+ if not chunk:
56
+ if not chunks:
57
+ raise Exception("Connection closed before receiving data")
58
+ break
59
+ chunks.append(chunk)
60
+
61
+ # Process the data received so far
62
+ data = b''.join(chunks)
63
+ decoded_data = data.decode('utf-8')
64
+
65
+ # Check if we've received a complete response
66
+ try:
67
+ # Special case for ping-pong
68
+ if decoded_data.strip().startswith('{"status":"success","result":{"message":"pong"'):
69
+ logger.debug("Received ping response")
70
+ return data
71
+
72
+ # Validate JSON format
73
+ json.loads(decoded_data)
74
+
75
+ # If we get here, we have valid JSON
76
+ logger.info(f"Received complete response ({len(data)} bytes)")
77
+ return data
78
+ except json.JSONDecodeError:
79
+ # We haven't received a complete valid JSON response yet
80
+ continue
81
+ except Exception as e:
82
+ logger.warning(f"Error processing response chunk: {str(e)}")
83
+ # Continue reading more chunks as this might not be the complete response
84
+ continue
85
+ except socket.timeout:
86
+ logger.warning("Socket timeout during receive")
87
+ raise Exception("Timeout receiving Cocos Creator response")
88
+ except Exception as e:
89
+ logger.error(f"Error during receive: {str(e)}")
90
+ raise
91
+
92
+ def send_command(self, command_type: str, params: Dict[str, Any] = None) -> Dict[str, Any]:
93
+ """发送命令到 Cocos Creator 并返回响应(同步版本)."""
94
+ if not self.sock and not self.connect():
95
+ raise ConnectionError("Not connected to Cocos Creator")
96
+
97
+ # Special handling for ping command
98
+ if command_type == "ping":
99
+ try:
100
+ logger.debug("Sending ping to verify connection")
101
+ self.sock.sendall(b"ping")
102
+ response_data = self.receive_full_response(self.sock)
103
+ response = json.loads(response_data.decode('utf-8'))
104
+
105
+ if response.get("status") != "success":
106
+ logger.warning("Ping response was not successful")
107
+ self.sock = None
108
+ raise ConnectionError("Connection verification failed")
109
+
110
+ return {"message": "pong"}
111
+ except Exception as e:
112
+ logger.error(f"Ping error: {str(e)}")
113
+ self.sock = None
114
+ raise ConnectionError(f"Connection verification failed: {str(e)}")
115
+
116
+ # Normal command handling
117
+ command = {"type": command_type, "params": params or {}}
118
+ try:
119
+ logger.info(f"Sending command: {command_type} with params: {params}")
120
+ self.sock.sendall(json.dumps(command).encode('utf-8'))
121
+ response_data = self.receive_full_response(self.sock)
122
+ response = json.loads(response_data.decode('utf-8'))
123
+
124
+ if response.get("status") == "error":
125
+ error_message = response.get("error") or response.get("message", "Unknown Cocos Creator error")
126
+ logger.error(f"Cocos Creator error: {error_message}")
127
+ raise Exception(error_message)
128
+
129
+ result = response.get("result", {})
130
+ logger.debug(f"Command result: {result}")
131
+ return result
132
+ except Exception as e:
133
+ logger.error(f"Communication error with Cocos Creator: {str(e)}")
134
+ self.sock = None
135
+ raise Exception(f"Failed to communicate with Cocos Creator: {str(e)}")
136
+
137
+ async def send_command_async(self, command_type: str, params: Dict[str, Any] = None) -> Dict[str, Any]:
138
+ """发送命令到 Cocos Creator 并返回响应(异步版本)."""
139
+ # 这里我们直接调用同步版本,因为异步处理的问题较多
140
+ # 在实际应用中,如果需要真正的异步,应该使用异步IO库
141
+ return self.send_command(command_type, params)
142
+
143
+ # Global connection instance
144
+ _connection: Optional[CocosConnection] = None
145
+
146
+ def get_cocos_connection() -> CocosConnection:
147
+ """Get the global Cocos Creator connection instance."""
148
+ global _connection
149
+ if _connection is None:
150
+ _connection = CocosConnection()
151
+ if not _connection.connect():
152
+ logger.error("Failed to establish initial connection to Cocos Creator")
153
+
154
+ return _connection
Python/config.py ADDED
@@ -0,0 +1,30 @@
1
+ """
2
+ Configuration settings for the Cocos MCP Server.
3
+ This file contains all configurable parameters for the server.
4
+ """
5
+
6
+ from dataclasses import dataclass
7
+
8
+ @dataclass
9
+ class ServerConfig:
10
+ """Main configuration class for the MCP server."""
11
+
12
+ # Cocos Creator connection settings
13
+ cocos_host: str = "::1" # 使用IPv6地址
14
+ cocos_port: int = 6400
15
+
16
+ # Connection settings
17
+ connection_timeout: float = 5.0 # 5 seconds timeout
18
+ buffer_size: int = 8192 # 8KB buffer size
19
+
20
+ # Logging settings
21
+ log_level: str = "INFO"
22
+ log_format: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
23
+ log_file: str = "cocos_mcp.log"
24
+
25
+ # Server settings
26
+ max_retries: int = 3
27
+ retry_delay: float = 1.0
28
+
29
+ # Create a global config instance
30
+ config = ServerConfig()
Python/log_client.py ADDED
@@ -0,0 +1,127 @@
1
+ import asyncio
2
+ import websockets
3
+ import json
4
+ from typing import Dict, Any, Optional, List, Callable
5
+
6
+ class LogClient:
7
+ def __init__(self, uri=None, host='127.0.0.1', port=8765):
8
+ if uri:
9
+ self.uri = uri
10
+ else:
11
+ self.uri = f'ws://{host}:{port}/logs'
12
+ self.ws = None
13
+ self.log_callback = None
14
+ self.connected = False
15
+
16
+ async def connect(self):
17
+ """连接到日志服务器"""
18
+ try:
19
+ self.ws = await websockets.connect(self.uri)
20
+ self.connected = True
21
+ print(f"Successfully connected to {self.uri}")
22
+ # 启动日志监听
23
+ asyncio.create_task(self._listen_logs())
24
+ return True
25
+ except Exception as e:
26
+ print(f"Failed to connect to log server: {e}")
27
+ self.connected = False
28
+ return False
29
+
30
+ async def _listen_logs(self):
31
+ """监听日志消息"""
32
+ if not self.ws:
33
+ return
34
+
35
+ while True:
36
+ try:
37
+ message = await self.ws.recv()
38
+ data = json.loads(message)
39
+ if data.get('type') == 'log' and self.log_callback:
40
+ await self.log_callback(data['data'])
41
+ except websockets.exceptions.ConnectionClosed:
42
+ print("WebSocket connection closed")
43
+ self.connected = False
44
+ break
45
+ except Exception as e:
46
+ print(f"Error listening to logs: {e}")
47
+ break
48
+
49
+ async def query_logs(self, show_logs: bool = True, show_warnings: bool = True,
50
+ show_errors: bool = True, search_term: Optional[str] = None) -> Dict[str, Any]:
51
+ """查询日志"""
52
+ if not self.ws or not self.connected:
53
+ return {"error": "Not connected to log server"}
54
+
55
+ try:
56
+ message = {
57
+ 'type': 'query-logs',
58
+ 'params': {
59
+ 'showLogs': show_logs,
60
+ 'showWarnings': show_warnings,
61
+ 'showErrors': show_errors,
62
+ 'searchTerm': search_term
63
+ }
64
+ }
65
+ await self.ws.send(json.dumps(message))
66
+ response = await self.ws.recv()
67
+ return json.loads(response)
68
+ except Exception as e:
69
+ print(f"Error querying logs: {e}")
70
+ return {"error": str(e)}
71
+
72
+ async def clear_logs(self) -> Dict[str, Any]:
73
+ """清除日志"""
74
+ if not self.ws or not self.connected:
75
+ return {"error": "Not connected to log server"}
76
+
77
+ try:
78
+ message = {
79
+ 'type': 'clear-logs'
80
+ }
81
+ await self.ws.send(json.dumps(message))
82
+ response = await self.ws.recv()
83
+ return json.loads(response)
84
+ except Exception as e:
85
+ print(f"Error clearing logs: {e}")
86
+ return {"error": str(e)}
87
+
88
+ def on_log(self, callback: Callable[[Dict[str, Any]], None]):
89
+ """设置日志回调函数"""
90
+ self.log_callback = callback
91
+
92
+ async def close(self):
93
+ """关闭连接"""
94
+ if self.ws:
95
+ try:
96
+ await self.ws.close()
97
+ self.connected = False
98
+ print("Connection to log server closed")
99
+ except Exception as e:
100
+ print(f"Error closing connection: {e}")
101
+
102
+ async def main():
103
+ # 示例用法
104
+ client = LogClient()
105
+ if await client.connect():
106
+ # 设置日志回调
107
+ async def log_callback(log_data):
108
+ print(f"Received log: {log_data}")
109
+
110
+ client.on_log(log_callback)
111
+
112
+ # 查询日志示例
113
+ logs = await client.query_logs(search_term="error")
114
+ print(f"Query result: {logs}")
115
+
116
+ # 清除日志示例
117
+ result = await client.clear_logs()
118
+ print(f"Clear result: {result}")
119
+
120
+ # 保持连接一段时间以接收实时日志
121
+ await asyncio.sleep(60)
122
+ await client.close()
123
+ else:
124
+ print("Failed to connect to log server")
125
+
126
+ if __name__ == "__main__":
127
+ asyncio.run(main())
@@ -0,0 +1,6 @@
1
+ # MCP协议依赖
2
+ mcp>=0.1.0
3
+
4
+ # 类型提示支持
5
+ typing-extensions>=4.0.0
6
+ dataclasses>=0.6
Python/server.py ADDED
@@ -0,0 +1,84 @@
1
+ from mcp.server.fastmcp import FastMCP, Context, Image
2
+ import logging
3
+ from dataclasses import dataclass
4
+ from contextlib import asynccontextmanager
5
+ from typing import AsyncIterator, Dict, Any, List
6
+ from config import config
7
+ from tools import register_all_tools
8
+ from cocos_connection import get_cocos_connection
9
+
10
+ # Configure logging using settings from config
11
+ logging.basicConfig(
12
+ level=getattr(logging, config.log_level),
13
+ format=config.log_format,
14
+ filename=config.log_file,
15
+ filemode='a'
16
+ )
17
+ logger = logging.getLogger("CocosMCP")
18
+
19
+ @asynccontextmanager
20
+ async def server_lifespan(server: FastMCP) -> AsyncIterator[Dict[str, Any]]:
21
+ """Handle server startup and shutdown."""
22
+ logger.info("CocosMCP server starting up")
23
+ try:
24
+ # 尝试连接到Cocos Creator
25
+ cocos_connection = get_cocos_connection()
26
+ try:
27
+ # 验证连接是否有效 - 使用同步方式
28
+ # 我们直接使用socket发送ping而不是调用异步方法
29
+ cocos_connection.sock.sendall(b"ping")
30
+ response_data = cocos_connection.receive_full_response(cocos_connection.sock)
31
+ logger.info("Connected to Cocos Creator on startup")
32
+ except Exception as e:
33
+ logger.warning(f"Could not verify Cocos Creator connection: {str(e)}")
34
+ except Exception as e:
35
+ logger.warning(f"Could not connect to Cocos Creator on startup: {str(e)}")
36
+
37
+ try:
38
+ yield {}
39
+ finally:
40
+ # 获取连接并断开
41
+ try:
42
+ cocos_connection = get_cocos_connection()
43
+ cocos_connection.disconnect()
44
+ except:
45
+ pass
46
+ logger.info("CocosMCP server shut down")
47
+
48
+ # Initialize MCP server
49
+ mcp = FastMCP(
50
+ "CocosMCP",
51
+ lifespan=server_lifespan
52
+ )
53
+
54
+ # Add prompt to explain tool usage
55
+ @mcp.prompt()
56
+ def log_management_guide() -> str:
57
+ """Guide for managing Cocos Creator logs."""
58
+ return (
59
+ "Cocos Creator MCP Tools Guide:\n\n"
60
+ "1. **Querying Logs**\n"
61
+ " - `query_logs(show_logs=True, show_warnings=True, show_errors=True, search_term=None)` - Read and filter Cocos Creator Console logs\n"
62
+ "2. **Clearing Logs**\n"
63
+ " - `clear_logs()` - Clear all console logs\n"
64
+ "3. **Checking Connection**\n"
65
+ " - `connection_status()` - Check if connected to Cocos Creator\n\n"
66
+ "4. **Best Practices**\n"
67
+ " - Always check connection status before performing operations\n"
68
+ " - Use search terms to filter console output when debugging\n"
69
+ " - Clear logs before major operations to make debugging easier\n"
70
+ " - Filter by log types when looking for specific issues\n"
71
+ )
72
+
73
+ # Register all tools
74
+ register_all_tools(mcp)
75
+
76
+ def main():
77
+ """Main entry point for the MCP server."""
78
+ logger.info("Starting CocosMCP server")
79
+ # Use stdio transport for Cursor integration
80
+ mcp.run(transport='stdio')
81
+
82
+ # Run the server
83
+ if __name__ == "__main__":
84
+ main()
Python/start_server.sh ADDED
@@ -0,0 +1,19 @@
1
+ #!/bin/bash
2
+
3
+ # 确保我们使用正确的 Python
4
+ PYTHON_PATH="/opt/homebrew/bin/python3"
5
+
6
+ # 检查 mcp 模块是否可用,如果不可用则安装
7
+ $PYTHON_PATH -c "import mcp" 2>/dev/null || $PYTHON_PATH -m pip install mcp --break-system-packages
8
+
9
+ # 设置 PYTHONPATH 以确保可以找到所有模块
10
+ cd "$(dirname "$0")"
11
+ export PYTHONPATH=$PYTHONPATH:$(pwd)
12
+
13
+ # 打印一些有用的信息
14
+ echo "Starting Cocos MCP server with Python: $PYTHON_PATH"
15
+ echo "PYTHONPATH: $PYTHONPATH"
16
+ echo "Current directory: $(pwd)"
17
+
18
+ # 启动服务器
19
+ $PYTHON_PATH server.py
@@ -0,0 +1,98 @@
1
+ from .log_tools import register_log_tools
2
+ import sys
3
+ import os
4
+ # 添加父目录到路径以便导入
5
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
6
+ from cocos_connection import get_cocos_connection
7
+ from mcp.server.fastmcp import Context
8
+ from typing import Dict, Any, Optional
9
+ import logging
10
+
11
+ # 尝试导入 scene_tools,如果不存在则跳过
12
+ try:
13
+ from .scene_tools import SceneTools
14
+ HAS_SCENE_TOOLS = True
15
+ except ImportError:
16
+ HAS_SCENE_TOOLS = False
17
+
18
+ def register_all_tools(mcp):
19
+ """Register all tools with the MCP server."""
20
+ register_log_tools(mcp)
21
+
22
+ # 如果场景工具可用则注册
23
+ if HAS_SCENE_TOOLS:
24
+ register_scene_tools(mcp)
25
+
26
+ def register_scene_tools(mcp):
27
+ """Register scene tools with the MCP server."""
28
+ if not HAS_SCENE_TOOLS:
29
+ return
30
+
31
+ # 创建一个SceneTools实例
32
+ cocos_client = get_cocos_connection()
33
+ scene_tools = SceneTools(cocos_client)
34
+
35
+ # 1. 打开场景工具
36
+ def open_scene(ctx: Context, scene_uuid: str) -> Dict[str, Any]:
37
+ """
38
+ 打开指定UUID的场景
39
+
40
+ Args:
41
+ scene_uuid: 场景资源的UUID
42
+
43
+ Returns:
44
+ 操作结果
45
+ """
46
+ logging.info(f"MCP处理open_scene请求: {scene_uuid}")
47
+
48
+ if not scene_uuid:
49
+ return {"success": False, "error": "Missing scene_uuid parameter"}
50
+
51
+ try:
52
+ # 直接调用SceneTools的方法并返回结果
53
+ result = scene_tools.open_scene(scene_uuid)
54
+ return result
55
+ except Exception as e:
56
+ logging.error(f"open_scene错误: {e}", exc_info=True)
57
+ return {"success": False, "error": str(e)}
58
+
59
+ # 2. 获取场景信息工具
60
+ def get_scene_info(ctx: Context) -> Dict[str, Any]:
61
+ """
62
+ 获取当前场景信息
63
+
64
+ Returns:
65
+ 场景信息
66
+ """
67
+ logging.info("MCP处理get_scene_info请求")
68
+
69
+ try:
70
+ # 调用SceneTools的方法
71
+ result = scene_tools.get_scene_info()
72
+ return result
73
+ except Exception as e:
74
+ logging.error(f"get_scene_info错误: {e}", exc_info=True)
75
+ return {"success": False, "error": str(e)}
76
+
77
+ # 4. 列出场景节点工具
78
+ def list_scene_nodes(ctx: Context) -> Dict[str, Any]:
79
+ """
80
+ 列出场景中的所有节点
81
+
82
+ Returns:
83
+ 节点列表
84
+ """
85
+ logging.info("MCP处理list_scene_nodes请求")
86
+
87
+ try:
88
+ # 调用SceneTools的方法
89
+ result = scene_tools.list_scene_nodes()
90
+ return result
91
+ except Exception as e:
92
+ logging.error(f"list_scene_nodes错误: {e}", exc_info=True)
93
+ return {"success": False, "error": str(e)}
94
+
95
+ # 注册工具
96
+ mcp.tool(name="open_scene")(open_scene)
97
+ mcp.tool(name="get_scene_info")(get_scene_info)
98
+ mcp.tool(name="list_scene_nodes")(list_scene_nodes)
@@ -0,0 +1,117 @@
1
+ import logging
2
+ from typing import Dict, Any, Optional, List
3
+ from mcp.server.fastmcp import Context
4
+ from cocos_connection import get_cocos_connection
5
+
6
+ # Get the logger
7
+ logger = logging.getLogger("CocosMCP")
8
+
9
+ async def query_logs(
10
+ ctx: Context,
11
+ show_logs: bool = True,
12
+ show_warnings: bool = True,
13
+ show_errors: bool = True,
14
+ search_term: Optional[str] = None,
15
+ module_filter: Optional[str] = None
16
+ ) -> Dict[str, Any]:
17
+ """
18
+ Query Cocos Creator editor logs with optional filtering.
19
+
20
+ Args:
21
+ show_logs: Include regular logs in results
22
+ show_warnings: Include warning logs in results
23
+ show_errors: Include error logs in results
24
+ search_term: Optional search term to filter logs
25
+ module_filter: Optional module name to filter logs (e.g. "Scene", "Assets")
26
+
27
+ Returns:
28
+ Dictionary containing filtered logs
29
+ """
30
+ try:
31
+ cocos = get_cocos_connection()
32
+ # 保存日志请求的副本,因为我们要修改它
33
+ params = {
34
+ "show_logs": show_logs,
35
+ "show_warnings": show_warnings,
36
+ "show_errors": show_errors
37
+ }
38
+
39
+ # 只有在提供了 search_term 且非空且是字符串类型时才添加
40
+ if search_term and isinstance(search_term, str) and search_term.strip():
41
+ logger.info(f"Adding search term to log query: {search_term}")
42
+ params["search_term"] = search_term.strip()
43
+
44
+ # 添加模块过滤
45
+ if module_filter and isinstance(module_filter, str) and module_filter.strip():
46
+ logger.info(f"Adding module filter to log query: {module_filter}")
47
+ params["module_filter"] = module_filter.strip()
48
+
49
+ result = cocos.send_command("QUERY_LOGS", params)
50
+ return result
51
+ except Exception as e:
52
+ logger.error(f"Error querying logs: {e}")
53
+ return {"error": str(e), "logs": []}
54
+
55
+ async def clear_logs(ctx: Context) -> Dict[str, Any]:
56
+ """
57
+ Clear all Cocos Creator editor logs.
58
+
59
+ Returns:
60
+ Success status and message
61
+ """
62
+ try:
63
+ cocos = get_cocos_connection()
64
+ result = cocos.send_command("CLEAR_LOGS", {})
65
+ return result
66
+ except Exception as e:
67
+ logger.error(f"Error clearing logs: {e}")
68
+ return {"error": str(e)}
69
+
70
+ async def connection_status(ctx: Context) -> Dict[str, Any]:
71
+ """
72
+ Check the connection status to Cocos Creator.
73
+
74
+ Returns:
75
+ Dictionary with connection status information
76
+ """
77
+ try:
78
+ cocos = get_cocos_connection()
79
+ # Try a ping command to verify connection
80
+ cocos.send_command("ping")
81
+ return {
82
+ "connected": True,
83
+ "host": cocos.host,
84
+ "port": cocos.port
85
+ }
86
+ except Exception as e:
87
+ logger.error(f"Connection check failed: {e}")
88
+ return {
89
+ "connected": False,
90
+ "error": str(e)
91
+ }
92
+
93
+ def log_management_guide() -> str:
94
+ """Guide for managing Cocos Creator logs."""
95
+ return (
96
+ "Cocos Creator MCP Log Tools Guide:\n\n"
97
+ "1. **Querying Logs**\n"
98
+ " - `query_logs(show_logs=True, show_warnings=True, show_errors=True, search_term=None, module_filter=None)` - Read and filter Cocos Creator Console logs\n"
99
+ " - Use `module_filter` to filter logs by specific modules (e.g. 'Scene', 'Assets')\n"
100
+ "2. **Clearing Logs**\n"
101
+ " - `clear_logs()` - Clear all console logs\n"
102
+ "3. **Checking Connection**\n"
103
+ " - `connection_status()` - Check if connected to Cocos Creator\n\n"
104
+ "4. **Best Practices**\n"
105
+ " - Always check connection status before performing operations\n"
106
+ " - Use module filters to focus on specific components (e.g. 'Scene', 'Assets')\n"
107
+ " - Use search terms to filter console output when debugging\n"
108
+ " - Clear logs before major operations to make debugging easier\n"
109
+ " - Filter by log types when looking for specific issues\n"
110
+ )
111
+
112
+ def register_log_tools(mcp):
113
+ """Register all log tools with the MCP server."""
114
+ mcp.tool()(query_logs)
115
+ mcp.tool()(clear_logs)
116
+ mcp.tool()(connection_status)
117
+ mcp.prompt()(log_management_guide)
@@ -0,0 +1,85 @@
1
+ import logging
2
+ from typing import Dict, Any, Optional, List
3
+
4
+ class SceneTools:
5
+ """场景操作工具类"""
6
+
7
+ def __init__(self, cocos_client) -> None:
8
+ """
9
+ 初始化场景工具
10
+
11
+ Args:
12
+ cocos_client: Cocos TCP 客户端实例
13
+ """
14
+ self.cocos_client = cocos_client
15
+ logging.info("SceneTools initialized")
16
+
17
+ def open_scene(self, scene_uuid: str) -> Dict[str, Any]:
18
+ """
19
+ 打开指定UUID的场景
20
+
21
+ Args:
22
+ scene_uuid: 场景资源的UUID
23
+
24
+ Returns:
25
+ 操作结果
26
+ """
27
+ try:
28
+ logging.info(f"向Cocos Creator发送打开场景命令: {scene_uuid}")
29
+
30
+ # 发送命令并获取响应 - 使用同步方式
31
+ response = self.cocos_client.send_command("OPEN_SCENE", {"sceneUuid": scene_uuid})
32
+
33
+ # 记录响应
34
+ logging.info(f"Cocos Creator响应: {response}")
35
+
36
+ # 返回结果
37
+ return {"success": True, "message": "Scene opened successfully"}
38
+
39
+ except Exception as e:
40
+ logging.error(f"打开场景错误: {e}", exc_info=True)
41
+ return {"success": False, "error": str(e)}
42
+
43
+ def get_scene_info(self) -> Dict[str, Any]:
44
+ """
45
+ 获取当前场景信息
46
+
47
+ Returns:
48
+ 场景信息
49
+ """
50
+ try:
51
+ logging.info("向Cocos Creator发送获取场景信息命令")
52
+
53
+ # 发送命令并获取响应
54
+ response = self.cocos_client.send_command("GET_SCENE_INFO", {})
55
+
56
+ # 记录响应
57
+ logging.info(f"Cocos Creator响应: {response}")
58
+
59
+ return response
60
+
61
+ except Exception as e:
62
+ logging.error(f"获取场景信息错误: {e}", exc_info=True)
63
+ return {"success": False, "error": str(e)}
64
+
65
+ def list_scene_nodes(self) -> Dict[str, Any]:
66
+ """
67
+ 列出场景中的所有节点
68
+
69
+ Returns:
70
+ 节点列表
71
+ """
72
+ try:
73
+ logging.info("向Cocos Creator发送列出场景节点命令")
74
+
75
+ # 发送命令并获取响应
76
+ response = self.cocos_client.send_command("LIST_SCENE_NODES", {})
77
+
78
+ # 记录响应
79
+ logging.info(f"Cocos Creator响应: {response}")
80
+
81
+ return response
82
+
83
+ except Exception as e:
84
+ logging.error(f"列出场景节点错误: {e}", exc_info=True)
85
+ return {"success": False, "error": str(e)}
@@ -0,0 +1,126 @@
1
+ Metadata-Version: 2.4
2
+ Name: iflow-mcp_czh2774-cocosmcp
3
+ Version: 1.0.0
4
+ Summary: Cocos Creator MCP Log Bridge
5
+ License-File: LICENSE
6
+ Requires-Python: >=3.7
7
+ Requires-Dist: dataclasses>=0.6
8
+ Requires-Dist: mcp>=0.1.0
9
+ Requires-Dist: typing-extensions>=4.0.0
10
+ Description-Content-Type: text/markdown
11
+
12
+ # Cocos MCP Log Bridge
13
+
14
+ 一个强大的日志桥接工具,用于在 Cocos Creator 编辑器和 Cursor AI 之间同步日志信息,帮助开发者更有效地分析和解决问题。
15
+
16
+ [![GitHub stars](https://img.shields.io/github/stars/czh2774/cocosMCP.svg)](https://github.com/czh2774/cocosMCP/stargazers)
17
+ [![License](https://img.shields.io/github/license/czh2774/cocosMCP.svg)](https://github.com/czh2774/cocosMCP/blob/main/LICENSE)
18
+
19
+ ![Cocos Creator](https://img.shields.io/badge/Cocos%20Creator-3.8.0%2B-blue)
20
+ ![Cursor AI](https://img.shields.io/badge/Cursor%20AI-Compatible-green)
21
+
22
+ ## 🌟 功能特点
23
+
24
+ - **实时日志同步**: 直接从 Cocos Creator 编辑器获取最新日志
25
+ - **智能过滤**: 支持按类型过滤(普通日志、警告、错误)
26
+ - **关键词搜索**: 精确定位特定问题
27
+ - **一键清除**: 随时清空日志以减少干扰
28
+ - **场景信息**: 获取当前场景的基本信息和节点列表
29
+ - **场景操作**: 支持打开场景等基础操作
30
+ - **TCP 通信桥接**: 稳定可靠的通信机制
31
+ - **Cursor AI 集成**: 完全兼容 Cursor MCP 协议
32
+
33
+ ## 🚀 快速入门
34
+
35
+ ### 前置条件
36
+
37
+ - Cocos Creator 3.8.0 或更高版本
38
+ - Python 3.7 或更高版本
39
+ - uv 包管理器 (推荐) 或 pip
40
+
41
+ ### 安装步骤
42
+
43
+ 1. **克隆仓库**
44
+ ```bash
45
+ git clone https://github.com/czh2774/cocosMCP.git
46
+ ```
47
+
48
+ 2. **复制到 Cocos Creator 项目**
49
+
50
+ 将克隆的 `cocosMCP` 目录复制到你的 Cocos Creator 项目的 `extensions` 目录下。
51
+
52
+ 3. **安装 Python 依赖**
53
+ ```bash
54
+ cd your-project/extensions/cocosMCP/Python
55
+ uv pip install -r requirements.txt
56
+ ```
57
+
58
+ 4. **在 Cocos Creator 中启用扩展**
59
+
60
+ 启动 Cocos Creator,进入 `扩展 -> 扩展管理器`,确保 `cocosMCP` 扩展已启用。
61
+
62
+ 5. **配置 Cursor AI**
63
+
64
+ 在 Cursor AI 设置中配置 MCP 服务器,指向 Python 服务器脚本。
65
+
66
+ ### 基本用法
67
+
68
+ ```python
69
+ # 查询日志
70
+ logs = await mcp.query_logs({
71
+ "show_logs": True,
72
+ "show_warnings": True,
73
+ "show_errors": True
74
+ })
75
+
76
+ # 清除日志
77
+ await mcp.clear_logs()
78
+
79
+ # 检查连接状态
80
+ status = await mcp.connection_status()
81
+
82
+ # 获取场景信息
83
+ scene_info = await mcp.get_scene_info()
84
+
85
+ # 列出场景中的所有节点
86
+ nodes = await mcp.list_scene_nodes()
87
+
88
+ # 打开指定UUID的场景
89
+ await mcp.open_scene("scene-uuid-here")
90
+ ```
91
+
92
+ ## 📚 详细文档
93
+
94
+ 本项目包含三个详细的文档:
95
+
96
+ - [用户使用指南](USAGE.md): 安装、配置和使用方法
97
+ - [开发者指南](DEVELOPMENT.md): 代码结构、扩展功能和维护说明
98
+ - [问题排查](TROUBLESHOOTING.md): 常见问题和解决方案
99
+
100
+ ## 🔧 技术架构
101
+
102
+ Cocos MCP 由三个主要部分组成:
103
+
104
+ 1. **Cocos Creator 扩展**: TypeScript 编写的编辑器扩展
105
+ 2. **TCP 通信桥**: 连接编辑器和 Python 服务器
106
+ 3. **Python MCP 服务器**: 处理 Cursor AI 的请求
107
+
108
+ ![架构图](https://via.placeholder.com/800x400?text=Cocos+MCP+Architecture)
109
+
110
+ ## 🤝 贡献指南
111
+
112
+ 欢迎贡献代码、报告问题或提出新功能建议!请查看 [开发者指南](DEVELOPMENT.md) 了解详情。
113
+
114
+ ## 📄 许可证
115
+
116
+ 本项目采用 MIT 许可证 - 详情请参阅 [LICENSE](LICENSE) 文件。
117
+
118
+ ## 🙏 致谢
119
+
120
+ - Cocos Creator 团队提供的优秀游戏引擎
121
+ - Cursor AI 团队开发的智能编程助手
122
+ - 所有贡献者和用户的支持和反馈
123
+
124
+ ---
125
+
126
+ 如有问题或建议,请提交 [Issues](https://github.com/czh2774/cocosMCP/issues)。
@@ -0,0 +1,15 @@
1
+ Python/__init__.py,sha256=nTveuBUrE7ts1FtWIBCzO-sNE-3RYCv2k2PiNSFlijk,26
2
+ Python/cocos_connection.py,sha256=isUrv2E29YxOqL00PoPmLhD0Ym-LslwhSI21_ZLMPlM,6557
3
+ Python/config.py,sha256=Cjm1LazDH2AsveGEELu4WS7xGHjI1lzoadhH-FZT95Y,806
4
+ Python/log_client.py,sha256=P0eWNlN_ANZvYHhL_maU5a9zRHCFUhwyeYJ0Z6VXrLg,4161
5
+ Python/requirements.txt,sha256=ba7WfPMjLGrdgfvZZqxPpZ59Xnvj8Qz5NBT-cDCd82o,93
6
+ Python/server.py,sha256=n8fds_vHQSeJfk2itgmXnL0uclBRU7csOE5YsPm5zYM,2969
7
+ Python/start_server.sh,sha256=G4NJ6LMt0dEo8IPbilQEci7cMKY9EdBgGgdzIflSOz4,559
8
+ Python/tools/__init__.py,sha256=EKi5zu2h0SuPii-sa3xQElfdW-XnO544j_wSa7_5rH0,3044
9
+ Python/tools/log_tools.py,sha256=8K3ZTKeYxPJ1u2-iKerv5YKw4NJ6c711o6o3DqngZns,4255
10
+ Python/tools/scene_tools.py,sha256=4ZJMPzKyUx_LMPeVc22HW1F2GH2vWKB07V_V1fTCYMw,2713
11
+ iflow_mcp_czh2774_cocosmcp-1.0.0.dist-info/METADATA,sha256=kIFwwvy27gEaABk1l9DyAAShgYZIfkFGVat_SU45vik,3720
12
+ iflow_mcp_czh2774_cocosmcp-1.0.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
13
+ iflow_mcp_czh2774_cocosmcp-1.0.0.dist-info/entry_points.txt,sha256=fZoL109GK9mvqSK5NsdLhCyaXbPbYEM_njD6vrV4trQ,41
14
+ iflow_mcp_czh2774_cocosmcp-1.0.0.dist-info/licenses/LICENSE,sha256=GT-xwJTlFeuxP5Z4YRZ0jn-mxGOpUPieje02erjbYNk,1064
15
+ iflow_mcp_czh2774_cocosmcp-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cocosmcp = server:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 czh2774
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.