coplay-mcp-server 1.2.0__tar.gz
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.
Potentially problematic release.
This version of coplay-mcp-server might be problematic. Click here for more details.
- coplay_mcp_server-1.2.0/.gitignore +175 -0
- coplay_mcp_server-1.2.0/.python-version +1 -0
- coplay_mcp_server-1.2.0/LICENSE +21 -0
- coplay_mcp_server-1.2.0/PKG-INFO +104 -0
- coplay_mcp_server-1.2.0/README.md +74 -0
- coplay_mcp_server-1.2.0/coplay_mcp_server/__init__.py +3 -0
- coplay_mcp_server-1.2.0/coplay_mcp_server/process_discovery.py +169 -0
- coplay_mcp_server-1.2.0/coplay_mcp_server/server.py +233 -0
- coplay_mcp_server-1.2.0/coplay_mcp_server/unity_client.py +224 -0
- coplay_mcp_server-1.2.0/docs/Publishing.md +214 -0
- coplay_mcp_server-1.2.0/docs/PublishingWorkflows.md +117 -0
- coplay_mcp_server-1.2.0/docs/TestPyPI-Installation.md +64 -0
- coplay_mcp_server-1.2.0/pyproject.toml +51 -0
- coplay_mcp_server-1.2.0/uv.lock +636 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# poetry
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
102
|
+
#poetry.lock
|
|
103
|
+
|
|
104
|
+
# pdm
|
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
106
|
+
#pdm.lock
|
|
107
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
108
|
+
# in version control.
|
|
109
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
110
|
+
.pdm.toml
|
|
111
|
+
|
|
112
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
113
|
+
__pypackages__/
|
|
114
|
+
|
|
115
|
+
# Celery stuff
|
|
116
|
+
celerybeat-schedule
|
|
117
|
+
celerybeat.pid
|
|
118
|
+
|
|
119
|
+
# SageMath parsed files
|
|
120
|
+
*.sage.py
|
|
121
|
+
|
|
122
|
+
# Environments
|
|
123
|
+
.env
|
|
124
|
+
.venv
|
|
125
|
+
env/
|
|
126
|
+
venv/
|
|
127
|
+
ENV/
|
|
128
|
+
env.bak/
|
|
129
|
+
venv.bak/
|
|
130
|
+
|
|
131
|
+
# Spyder project settings
|
|
132
|
+
.spyderproject
|
|
133
|
+
.spyproject
|
|
134
|
+
|
|
135
|
+
# Rope project settings
|
|
136
|
+
.ropeproject
|
|
137
|
+
|
|
138
|
+
# mkdocs documentation
|
|
139
|
+
/site
|
|
140
|
+
|
|
141
|
+
# mypy
|
|
142
|
+
.mypy_cache/
|
|
143
|
+
.dmypy.json
|
|
144
|
+
dmypy.json
|
|
145
|
+
|
|
146
|
+
# Pyre type checker
|
|
147
|
+
.pyre/
|
|
148
|
+
|
|
149
|
+
# pytype static type analyzer
|
|
150
|
+
.pytype/
|
|
151
|
+
|
|
152
|
+
# Cython debug symbols
|
|
153
|
+
cython_debug/
|
|
154
|
+
|
|
155
|
+
# PyCharm
|
|
156
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
157
|
+
# be added to the global gitignore or merged into this project gitignore. For a PyCharm
|
|
158
|
+
# project, it is recommended to ignore the entire .idea directory.
|
|
159
|
+
.idea/
|
|
160
|
+
|
|
161
|
+
# VS Code
|
|
162
|
+
.vscode/
|
|
163
|
+
|
|
164
|
+
# Logs
|
|
165
|
+
logs/
|
|
166
|
+
*.log
|
|
167
|
+
|
|
168
|
+
# OS generated files
|
|
169
|
+
.DS_Store
|
|
170
|
+
.DS_Store?
|
|
171
|
+
._*
|
|
172
|
+
.Spotlight-V100
|
|
173
|
+
.Trashes
|
|
174
|
+
ehthumbs.db
|
|
175
|
+
Thumbs.db
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Coplay Dev
|
|
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.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: coplay-mcp-server
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: A Model Context Protocol (MCP) server for Coplay, providing Unity integration capabilities
|
|
5
|
+
Project-URL: Homepage, https://coplay.dev/
|
|
6
|
+
Project-URL: Repository, https://github.com/CoplayDev/coplay-unity-plugin
|
|
7
|
+
Project-URL: Documentation, https://docs.coplay.dev/
|
|
8
|
+
Project-URL: Issues, https://github.com/CoplayDev/coplay-unity-plugin/issues
|
|
9
|
+
Author-email: Coplay Dev <dev@coplay.com>
|
|
10
|
+
Maintainer-email: Coplay Dev <dev@coplay.com>
|
|
11
|
+
License: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: coplay,mcp,model-context-protocol,unity,unity-editor
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Topic :: Games/Entertainment
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: aiofiles>=24.1.0
|
|
24
|
+
Requires-Dist: anyio>=4.10.0
|
|
25
|
+
Requires-Dist: mcp[cli]>=1.12.4
|
|
26
|
+
Requires-Dist: psutil>=7.0.0
|
|
27
|
+
Requires-Dist: pydantic>=2.11.7
|
|
28
|
+
Requires-Dist: watchdog>=6.0.0
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
|
|
31
|
+
# Coplay MCP Server
|
|
32
|
+
|
|
33
|
+
A Model Context Protocol (MCP) server for Coplay, providing Unity Editor integration capabilities through MCP tools.
|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- **Unity Project Discovery**: Automatically discover running Unity Editor instances and their project roots
|
|
38
|
+
- **Unity Editor State**: Retrieve current Unity Editor state and scene hierarchy information
|
|
39
|
+
- **Script Execution**: Execute arbitrary C# scripts within the Unity Editor
|
|
40
|
+
- **Log Management**: Access and filter Unity console logs
|
|
41
|
+
- **GameObject Hierarchy**: List and filter GameObjects in the scene hierarchy
|
|
42
|
+
- **Task Creation**: Create new Coplay tasks directly from MCP clients
|
|
43
|
+
|
|
44
|
+
## Usage
|
|
45
|
+
|
|
46
|
+
### As an MCP server
|
|
47
|
+
|
|
48
|
+
Add to your MCP client configuration:
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"mcpServers": {
|
|
53
|
+
"coplay-testpypi": {
|
|
54
|
+
"autoApprove": [],
|
|
55
|
+
"disabled": false,
|
|
56
|
+
"timeout": 60,
|
|
57
|
+
"type": "stdio",
|
|
58
|
+
"command": "uvx",
|
|
59
|
+
"args": [
|
|
60
|
+
"--index-url",
|
|
61
|
+
"https://test.pypi.org/simple/",
|
|
62
|
+
"--extra-index-url",
|
|
63
|
+
"https://pypi.org/simple/",
|
|
64
|
+
"coplay-mcp-server@latest"
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Available Tools
|
|
72
|
+
|
|
73
|
+
- `set_unity_project_root` - Set the Unity project root path
|
|
74
|
+
- `list_unity_project_roots` - Discover all running Unity Editor instances
|
|
75
|
+
- `execute_script` - Execute C# scripts in Unity Editor
|
|
76
|
+
- `get_unity_logs` - Retrieve Unity console logs with filtering
|
|
77
|
+
- `get_unity_editor_state` - Get current Unity Editor state
|
|
78
|
+
- `list_game_objects_in_hierarchy` - List GameObjects with filtering options
|
|
79
|
+
- `create_coplay_task` - Create new Coplay tasks
|
|
80
|
+
|
|
81
|
+
## Development
|
|
82
|
+
|
|
83
|
+
To launch the server in development mode:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
uv run mcp dev coplay_mcp_server/server.py
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Prerequisites
|
|
90
|
+
|
|
91
|
+
- Python 3.11+
|
|
92
|
+
- [uv](https://docs.astral.sh/uv/) package manager
|
|
93
|
+
- Unity Editor with Coplay plugin installed
|
|
94
|
+
|
|
95
|
+
### Project Structure
|
|
96
|
+
|
|
97
|
+
- `coplay_mcp_server/server.py` - Main MCP server implementation
|
|
98
|
+
- `coplay_mcp_server/unity_client.py` - Unity RPC client for communication
|
|
99
|
+
- `coplay_mcp_server/process_discovery.py` - Process discovery utilities
|
|
100
|
+
- `pyproject.toml` - Project configuration and dependencies
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
MIT License - see LICENSE file for details.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Coplay MCP Server
|
|
2
|
+
|
|
3
|
+
A Model Context Protocol (MCP) server for Coplay, providing Unity Editor integration capabilities through MCP tools.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Unity Project Discovery**: Automatically discover running Unity Editor instances and their project roots
|
|
8
|
+
- **Unity Editor State**: Retrieve current Unity Editor state and scene hierarchy information
|
|
9
|
+
- **Script Execution**: Execute arbitrary C# scripts within the Unity Editor
|
|
10
|
+
- **Log Management**: Access and filter Unity console logs
|
|
11
|
+
- **GameObject Hierarchy**: List and filter GameObjects in the scene hierarchy
|
|
12
|
+
- **Task Creation**: Create new Coplay tasks directly from MCP clients
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
### As an MCP server
|
|
17
|
+
|
|
18
|
+
Add to your MCP client configuration:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"mcpServers": {
|
|
23
|
+
"coplay-testpypi": {
|
|
24
|
+
"autoApprove": [],
|
|
25
|
+
"disabled": false,
|
|
26
|
+
"timeout": 60,
|
|
27
|
+
"type": "stdio",
|
|
28
|
+
"command": "uvx",
|
|
29
|
+
"args": [
|
|
30
|
+
"--index-url",
|
|
31
|
+
"https://test.pypi.org/simple/",
|
|
32
|
+
"--extra-index-url",
|
|
33
|
+
"https://pypi.org/simple/",
|
|
34
|
+
"coplay-mcp-server@latest"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Available Tools
|
|
42
|
+
|
|
43
|
+
- `set_unity_project_root` - Set the Unity project root path
|
|
44
|
+
- `list_unity_project_roots` - Discover all running Unity Editor instances
|
|
45
|
+
- `execute_script` - Execute C# scripts in Unity Editor
|
|
46
|
+
- `get_unity_logs` - Retrieve Unity console logs with filtering
|
|
47
|
+
- `get_unity_editor_state` - Get current Unity Editor state
|
|
48
|
+
- `list_game_objects_in_hierarchy` - List GameObjects with filtering options
|
|
49
|
+
- `create_coplay_task` - Create new Coplay tasks
|
|
50
|
+
|
|
51
|
+
## Development
|
|
52
|
+
|
|
53
|
+
To launch the server in development mode:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
uv run mcp dev coplay_mcp_server/server.py
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Prerequisites
|
|
60
|
+
|
|
61
|
+
- Python 3.11+
|
|
62
|
+
- [uv](https://docs.astral.sh/uv/) package manager
|
|
63
|
+
- Unity Editor with Coplay plugin installed
|
|
64
|
+
|
|
65
|
+
### Project Structure
|
|
66
|
+
|
|
67
|
+
- `coplay_mcp_server/server.py` - Main MCP server implementation
|
|
68
|
+
- `coplay_mcp_server/unity_client.py` - Unity RPC client for communication
|
|
69
|
+
- `coplay_mcp_server/process_discovery.py` - Process discovery utilities
|
|
70
|
+
- `pyproject.toml` - Project configuration and dependencies
|
|
71
|
+
|
|
72
|
+
## License
|
|
73
|
+
|
|
74
|
+
MIT License - see LICENSE file for details.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""Unity process discovery utilities."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import platform
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import List, Optional
|
|
7
|
+
|
|
8
|
+
import psutil
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def find_unity_processes() -> List[psutil.Process]:
|
|
14
|
+
"""Find all running Unity Editor processes."""
|
|
15
|
+
unity_processes = []
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
|
|
19
|
+
try:
|
|
20
|
+
proc_info = proc.info
|
|
21
|
+
if not proc_info['name']:
|
|
22
|
+
continue
|
|
23
|
+
|
|
24
|
+
name = proc_info['name'].lower()
|
|
25
|
+
|
|
26
|
+
# Check for Unity process names across platforms
|
|
27
|
+
if any(unity_name in name for unity_name in [
|
|
28
|
+
'unity', 'unity.exe', 'unity editor', 'unity hub'
|
|
29
|
+
]):
|
|
30
|
+
# Skip Unity Hub, we only want Editor instances
|
|
31
|
+
if 'hub' not in name:
|
|
32
|
+
unity_processes.append(proc)
|
|
33
|
+
|
|
34
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
35
|
+
continue
|
|
36
|
+
|
|
37
|
+
except Exception as e:
|
|
38
|
+
logger.error(f"Error finding Unity processes: {e}")
|
|
39
|
+
|
|
40
|
+
return unity_processes
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def extract_project_path_from_cmdline(cmdline: List[str]) -> Optional[str]:
|
|
44
|
+
"""Extract Unity project path from command line arguments."""
|
|
45
|
+
if not cmdline:
|
|
46
|
+
return None
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
# Look for -projectPath argument
|
|
50
|
+
for i, arg in enumerate(cmdline):
|
|
51
|
+
if arg.lower() == "-projectpath" and i + 1 < len(cmdline):
|
|
52
|
+
project_path = cmdline[i + 1]
|
|
53
|
+
# Remove quotes if present
|
|
54
|
+
project_path = project_path.strip('"\'')
|
|
55
|
+
return project_path
|
|
56
|
+
|
|
57
|
+
except Exception as e:
|
|
58
|
+
logger.debug(f"Error extracting project path from cmdline: {e}")
|
|
59
|
+
|
|
60
|
+
return None
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def verify_unity_project(project_path: str) -> bool:
|
|
64
|
+
"""Verify that a path is a valid Unity project."""
|
|
65
|
+
try:
|
|
66
|
+
project_dir = Path(project_path)
|
|
67
|
+
if not project_dir.exists() or not project_dir.is_dir():
|
|
68
|
+
return False
|
|
69
|
+
|
|
70
|
+
# Check for Assets folder (required for Unity projects)
|
|
71
|
+
assets_dir = project_dir / "Assets"
|
|
72
|
+
if not assets_dir.exists() or not assets_dir.is_dir():
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
return True
|
|
76
|
+
|
|
77
|
+
except Exception as e:
|
|
78
|
+
logger.debug(f"Error verifying Unity project at {project_path}: {e}")
|
|
79
|
+
return False
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _discover_from_temp_dirs() -> List[str]:
|
|
83
|
+
"""Discover Unity projects from MCP request directories in temp locations."""
|
|
84
|
+
project_roots = []
|
|
85
|
+
|
|
86
|
+
try:
|
|
87
|
+
# Common temp directory locations
|
|
88
|
+
temp_paths = []
|
|
89
|
+
|
|
90
|
+
if platform.system() == "Windows":
|
|
91
|
+
import tempfile
|
|
92
|
+
temp_paths.append(Path(tempfile.gettempdir()))
|
|
93
|
+
# Also check AppData/Local
|
|
94
|
+
try:
|
|
95
|
+
from pathlib import Path
|
|
96
|
+
appdata_local = Path.home() / "AppData" / "Local"
|
|
97
|
+
if appdata_local.exists():
|
|
98
|
+
temp_paths.append(appdata_local)
|
|
99
|
+
except Exception:
|
|
100
|
+
pass
|
|
101
|
+
else:
|
|
102
|
+
# Unix-like systems
|
|
103
|
+
temp_paths.extend([
|
|
104
|
+
Path("/tmp"),
|
|
105
|
+
Path.home() / ".cache",
|
|
106
|
+
Path("/var/tmp")
|
|
107
|
+
])
|
|
108
|
+
|
|
109
|
+
for temp_path in temp_paths:
|
|
110
|
+
if not temp_path.exists():
|
|
111
|
+
continue
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
# Look for Coplay MCP request directories
|
|
115
|
+
for path in temp_path.rglob("**/Temp/Coplay/MCPRequests"):
|
|
116
|
+
if path.is_dir():
|
|
117
|
+
# Try to infer project root from temp path structure
|
|
118
|
+
temp_index = None
|
|
119
|
+
parts = path.parts
|
|
120
|
+
|
|
121
|
+
for i, part in enumerate(parts):
|
|
122
|
+
if part.lower() == "temp":
|
|
123
|
+
temp_index = i
|
|
124
|
+
break
|
|
125
|
+
|
|
126
|
+
if temp_index and temp_index > 0:
|
|
127
|
+
project_path = str(Path(*parts[:temp_index]))
|
|
128
|
+
if verify_unity_project(project_path):
|
|
129
|
+
project_roots.append(project_path)
|
|
130
|
+
|
|
131
|
+
except Exception as e:
|
|
132
|
+
logger.debug(f"Error searching temp path {temp_path}: {e}")
|
|
133
|
+
|
|
134
|
+
except Exception as e:
|
|
135
|
+
logger.debug(f"Error discovering from temp directories: {e}")
|
|
136
|
+
|
|
137
|
+
return project_roots
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def discover_unity_project_roots() -> List[str]:
|
|
141
|
+
"""Discover all Unity project roots from running processes."""
|
|
142
|
+
project_roots = []
|
|
143
|
+
|
|
144
|
+
try:
|
|
145
|
+
unity_processes = find_unity_processes()
|
|
146
|
+
logger.info(f"Found {len(unity_processes)} Unity processes")
|
|
147
|
+
|
|
148
|
+
for proc in unity_processes:
|
|
149
|
+
try:
|
|
150
|
+
cmdline = proc.cmdline()
|
|
151
|
+
project_path = extract_project_path_from_cmdline(cmdline)
|
|
152
|
+
|
|
153
|
+
if project_path and verify_unity_project(project_path):
|
|
154
|
+
if project_path not in project_roots:
|
|
155
|
+
project_roots.append(project_path)
|
|
156
|
+
logger.info(f"Found Unity project: {project_path}")
|
|
157
|
+
|
|
158
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
159
|
+
continue
|
|
160
|
+
except Exception as e:
|
|
161
|
+
logger.debug(f"Error processing Unity process {proc.pid}: {e}")
|
|
162
|
+
|
|
163
|
+
except Exception as e:
|
|
164
|
+
logger.error(f"Error discovering Unity project roots: {e}")
|
|
165
|
+
|
|
166
|
+
# Also check for MCP request directories in temp locations
|
|
167
|
+
project_roots.extend(_discover_from_temp_dirs())
|
|
168
|
+
|
|
169
|
+
return list(set(project_roots)) # Remove duplicates
|