roblox-studio-physical-operation-mcp 0.1.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.
Files changed (22) hide show
  1. roblox_studio_physical_operation_mcp-0.1.0/.github/workflows/publish.yml +32 -0
  2. roblox_studio_physical_operation_mcp-0.1.0/.gitignore +18 -0
  3. roblox_studio_physical_operation_mcp-0.1.0/LICENSE +21 -0
  4. roblox_studio_physical_operation_mcp-0.1.0/PKG-INFO +273 -0
  5. roblox_studio_physical_operation_mcp-0.1.0/README.md +246 -0
  6. roblox_studio_physical_operation_mcp-0.1.0/pyproject.toml +52 -0
  7. roblox_studio_physical_operation_mcp-0.1.0/requirements.txt +9 -0
  8. roblox_studio_physical_operation_mcp-0.1.0/roblox_studio_physical_operation_mcp/__init__.py +13 -0
  9. roblox_studio_physical_operation_mcp-0.1.0/roblox_studio_physical_operation_mcp/__main__.py +8 -0
  10. roblox_studio_physical_operation_mcp-0.1.0/roblox_studio_physical_operation_mcp/log_filter.py +99 -0
  11. roblox_studio_physical_operation_mcp-0.1.0/roblox_studio_physical_operation_mcp/log_utils.py +467 -0
  12. roblox_studio_physical_operation_mcp-0.1.0/roblox_studio_physical_operation_mcp/server.py +602 -0
  13. roblox_studio_physical_operation_mcp-0.1.0/roblox_studio_physical_operation_mcp/studio_manager.py +476 -0
  14. roblox_studio_physical_operation_mcp-0.1.0/roblox_studio_physical_operation_mcp/toolbar_detector.py +513 -0
  15. roblox_studio_physical_operation_mcp-0.1.0/roblox_studio_physical_operation_mcp/windows_utils.py +578 -0
  16. roblox_studio_physical_operation_mcp-0.1.0/run_server.py +14 -0
  17. roblox_studio_physical_operation_mcp-0.1.0/tests/README.md +65 -0
  18. roblox_studio_physical_operation_mcp-0.1.0/tests/game.rbxl +0 -0
  19. roblox_studio_physical_operation_mcp-0.1.0/tests/test_full.py +216 -0
  20. roblox_studio_physical_operation_mcp-0.1.0/tests/test_postmessage.py +178 -0
  21. roblox_studio_physical_operation_mcp-0.1.0/tests/test_sendinput.py +198 -0
  22. roblox_studio_physical_operation_mcp-0.1.0/tests/test_window_capture.py +256 -0
@@ -0,0 +1,32 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch: # 允许手动触发
7
+
8
+ jobs:
9
+ build-and-publish:
10
+ runs-on: ubuntu-latest
11
+
12
+ permissions:
13
+ id-token: write # 用于 Trusted Publisher
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - name: Set up Python
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: '3.13'
22
+
23
+ - name: Install build dependencies
24
+ run: |
25
+ python -m pip install --upgrade pip
26
+ pip install build
27
+
28
+ - name: Build package
29
+ run: python -m build
30
+
31
+ - name: Publish to PyPI
32
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,18 @@
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ *.pyo
5
+
6
+ *.rbxl.lock
7
+ *.png
8
+ dist/
9
+ # Test outputs
10
+ tests/capture_test_output/
11
+ tests/screenshots/
12
+ screenshots/
13
+
14
+ # Lock files
15
+ *.lock
16
+
17
+ # Reference images (not needed in repo)
18
+ roblox_studio_physical_operation_mcp/buttons*.jpg
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 White Dragon Tools
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,273 @@
1
+ Metadata-Version: 2.4
2
+ Name: roblox-studio-physical-operation-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server for controlling Roblox Studio - toolbar detection, game control, log analysis
5
+ Project-URL: Homepage, https://github.com/white-dragon-tools/roblox-studio-physical-operation-mcp
6
+ Project-URL: Repository, https://github.com/white-dragon-tools/roblox-studio-physical-operation-mcp
7
+ Project-URL: Issues, https://github.com/white-dragon-tools/roblox-studio-physical-operation-mcp/issues
8
+ Author: White Dragon Tools
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: automation,mcp,model-context-protocol,roblox,roblox-studio
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: mcp>=1.0.0
23
+ Requires-Dist: opencv-python
24
+ Requires-Dist: pillow
25
+ Requires-Dist: pywin32
26
+ Description-Content-Type: text/markdown
27
+
28
+ # Roblox Studio MCP
29
+
30
+ 一个用于控制 Roblox Studio 的 MCP (Model Context Protocol) 服务。
31
+
32
+ ## 安装
33
+
34
+ ```bash
35
+ pip install roblox-studio-physical-operation-mcp
36
+ ```
37
+
38
+ ## 配置 MCP
39
+
40
+ ### Claude Desktop
41
+
42
+ 编辑 `%APPDATA%\Claude\claude_desktop_config.json`:
43
+
44
+ ```json
45
+ {
46
+ "mcpServers": {
47
+ "roblox-studio": {
48
+ "command": "python",
49
+ "args": ["-m", "roblox_studio_physical_operation_mcp"]
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ ### Droid
56
+
57
+ 编辑 `~/.factory/mcp.json`:
58
+
59
+ ```json
60
+ {
61
+ "mcpServers": {
62
+ "roblox-studio": {
63
+ "type": "stdio",
64
+ "command": "python",
65
+ "args": ["-m", "roblox_studio_physical_operation_mcp"]
66
+ }
67
+ }
68
+ }
69
+ ```
70
+
71
+ > **注意**:Windows Store 版 Python 可能需要使用完整路径:
72
+ > ```json
73
+ > "command": "C:\\Users\\<用户名>\\AppData\\Local\\Microsoft\\WindowsApps\\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\\python.exe"
74
+ > ```
75
+
76
+ ## 从源码安装
77
+
78
+ ```bash
79
+ git clone https://github.com/white-dragon-tools/roblox-studio-physical-operation-mcp.git
80
+ cd roblox-studio-physical-operation-mcp
81
+ pip install -r requirements.txt
82
+ python -m roblox_studio_physical_operation_mcp
83
+ ```
84
+
85
+ ---
86
+
87
+ ## AI 使用指南
88
+
89
+ ### ⚠️ 重要:获取 place_path 或 place_id
90
+
91
+ **不知道 place_path 或 place_id 时,必须先调用 `studio_list()` 获取!**
92
+
93
+ ```python
94
+ # 先获取当前运行的 Studio 实例
95
+ instances = studio_list()
96
+ # 返回示例:
97
+ # [{"pid": 12345, "type": "local", "place_path": "D:/game.rbxl"},
98
+ # {"pid": 67890, "type": "cloud", "place_id": 110155533210141}]
99
+
100
+ # 然后用返回的 place_path 或 place_id 操作
101
+ logs_get(place_path=instances[0]["place_path"])
102
+ ```
103
+
104
+ ### 推荐工作流程
105
+
106
+ **调试已打开的 Studio**
107
+ ```
108
+ 1. studio_list() # 获取运行中的 Studio 实例
109
+ 2. studio_query(place_path) # 查询状态
110
+ 3. modal_close(place_path) # 如果有模态弹窗,关闭它们
111
+ 4. game_start(place_path) # 开始游戏
112
+ 5. logs_get(place_path) # 获取日志
113
+ 6. game_stop(place_path) # 停止游戏
114
+ ```
115
+
116
+ **打开新的 Studio**
117
+ ```
118
+ 1. studio_open(place_path) # 打开 Studio(本地文件)
119
+ 2. studio_query(place_path) # 查询状态
120
+ 3. modal_close(place_path) # 如果有模态弹窗,关闭它们
121
+ 4. studio_query(place_path) # 确认 ready=true
122
+ 5. game_start(place_path) # 开始游戏
123
+ 6. logs_get(place_path) # 获取日志
124
+ 7. game_stop(place_path) # 停止游戏
125
+ 8. studio_close(place_path) # 关闭 Studio
126
+ ```
127
+
128
+ ### 支持两种 Place 类型
129
+
130
+ 所有工具都支持两种参数(二选一):
131
+ - `place_path` - 本地 .rbxl 文件路径
132
+ - `place_id` - 云端 Roblox Place ID
133
+
134
+ ```python
135
+ # 本地文件
136
+ logs_get(place_path="D:/game.rbxl")
137
+
138
+ # 云端 Place(从网页打开的)
139
+ logs_get(place_id=110155533210141)
140
+ ```
141
+
142
+ ### studio_query 返回值说明
143
+
144
+ ```json
145
+ {
146
+ "active": true, // Studio 是否运行中
147
+ "ready": true, // 是否就绪(无模态弹窗)
148
+ "pid": 12345, // 进程 ID
149
+ "hwnd": 67890, // 主窗口句柄
150
+ "has_modal": false, // 是否有模态弹窗
151
+ "modal_count": 0, // 模态弹窗数量
152
+ "modals": [] // 模态弹窗详情
153
+ }
154
+ ```
155
+
156
+ **重要**: `ready=true` 时才能正常操作 Studio。
157
+
158
+ ---
159
+
160
+ ## 工具列表
161
+
162
+ ### 系统工具
163
+
164
+ | 工具 | 说明 |
165
+ |------|------|
166
+ | `studio_help()` | 获取使用指南 |
167
+ | `studio_list()` | **列出所有运行中的 Studio 实例** |
168
+ | `studio_open(place_path)` | 打开 Studio 并加载 .rbxl 文件 |
169
+ | `studio_close(place_path/place_id)` | 关闭 Studio |
170
+ | `studio_status(place_path/place_id)` | 获取基本状态 |
171
+ | `studio_query(place_path/place_id)` | **综合查询状态(推荐)** |
172
+
173
+ ### 模态弹窗
174
+
175
+ | 工具 | 说明 |
176
+ |------|------|
177
+ | `modal_detect(place_path/place_id)` | 检测模态弹窗 |
178
+ | `modal_close(place_path/place_id)` | 关闭所有模态弹窗 |
179
+
180
+ ### 游戏控制
181
+
182
+ | 工具 | 说明 |
183
+ |------|------|
184
+ | `game_start(place_path/place_id)` | 开始游戏 (F5) |
185
+ | `game_stop(place_path/place_id)` | 停止游戏 (Shift+F5) |
186
+ | `game_pause(place_path/place_id)` | 暂停/恢复游戏 (F12) |
187
+
188
+ ### 工具栏状态检测
189
+
190
+ | 工具 | 说明 |
191
+ |------|------|
192
+ | `toolbar_state(place_path/place_id)` | 检测工具栏按钮状态和游戏状态 |
193
+ | `toolbar_state_debug(place_path/place_id)` | 带调试信息的检测 |
194
+
195
+ 返回示例:
196
+ ```json
197
+ {
198
+ "play": "enabled",
199
+ "pause": "disabled",
200
+ "stop": "disabled",
201
+ "game_state": "stopped"
202
+ }
203
+ ```
204
+
205
+ `game_state` 可能的值:`stopped`, `running`, `paused`
206
+
207
+ ### 日志
208
+
209
+ | 工具 | 说明 |
210
+ |------|------|
211
+ | `logs_get(place_path/place_id, after_line, before_line, timestamps)` | 获取日志 |
212
+ | `logs_search(place_path/place_id, pattern, after_line, before_line, timestamps)` | 搜索日志(正则) |
213
+ | `logs_clean(days)` | 清理旧日志 |
214
+
215
+ **logs_get 参数:**
216
+ ```python
217
+ logs_get(
218
+ place_path: str = None, # 本地文件路径
219
+ place_id: int = None, # 云端 Place ID(二选一)
220
+ after_line: int = None, # 从哪一行之后开始读取
221
+ before_line: int = None, # 到哪一行之前结束
222
+ timestamps: bool = False # 是否附加时间戳 [HH:MM:SS]
223
+ )
224
+ ```
225
+
226
+ **logs_get 返回:**
227
+ ```json
228
+ {
229
+ "logs": "[15:22:01] Hello world!\nThe MCP plugin is ready.",
230
+ "start_line": 100,
231
+ "last_line": 2330,
232
+ "remaining": 0,
233
+ "has_more": false
234
+ }
235
+ ```
236
+
237
+ **续读日志:**
238
+ ```python
239
+ # 首次获取
240
+ result = logs_get(place_path="D:/game.rbxl")
241
+ # 续读新日志
242
+ result = logs_get(place_path="D:/game.rbxl", after_line=result["last_line"])
243
+ ```
244
+
245
+ ### 截图
246
+
247
+ | 工具 | 说明 |
248
+ |------|------|
249
+ | `screenshot(place_path/place_id)` | 截取主窗口 |
250
+ | `screenshot_full(place_path/place_id)` | 截取窗口(包含模态弹窗) |
251
+
252
+ ---
253
+
254
+ ## 注意事项
255
+
256
+ 1. **支持本地和云端 Place** - 使用 `place_path` 或 `place_id` 参数
257
+ 2. **启动后务必查询状态** - 调用 `studio_query` 检查是否有模态弹窗
258
+ 3. **处理模态弹窗** - `ready=false` 时调用 `modal_close` 关闭弹窗
259
+ 4. **最小化窗口自动恢复** - 检测工具栏状态时会自动恢复最小化的窗口
260
+ 5. **自动清理** - 关闭本地文件的 Studio 后会自动清理 .lock 文件
261
+ 6. **日志过滤** - `logs_get` 自动过滤 Studio 内部日志,只返回用户脚本输出
262
+
263
+ ---
264
+
265
+ ## 技术说明
266
+
267
+ - 会话管理通过扫描进程命令行 + 日志文件自动匹配
268
+ - 日志索引缓存减少 IO 操作
269
+ - 游戏控制使用 SendInput API(需短暂切换窗口焦点)
270
+ - 截图使用 PrintWindow API(可捕获被遮挡窗口)
271
+ - 模态弹窗检测通过枚举同进程窗口实现
272
+ - 工具栏状态通过 OpenCV 模板匹配检测
273
+ - 支持多显示器环境
@@ -0,0 +1,246 @@
1
+ # Roblox Studio MCP
2
+
3
+ 一个用于控制 Roblox Studio 的 MCP (Model Context Protocol) 服务。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pip install roblox-studio-physical-operation-mcp
9
+ ```
10
+
11
+ ## 配置 MCP
12
+
13
+ ### Claude Desktop
14
+
15
+ 编辑 `%APPDATA%\Claude\claude_desktop_config.json`:
16
+
17
+ ```json
18
+ {
19
+ "mcpServers": {
20
+ "roblox-studio": {
21
+ "command": "python",
22
+ "args": ["-m", "roblox_studio_physical_operation_mcp"]
23
+ }
24
+ }
25
+ }
26
+ ```
27
+
28
+ ### Droid
29
+
30
+ 编辑 `~/.factory/mcp.json`:
31
+
32
+ ```json
33
+ {
34
+ "mcpServers": {
35
+ "roblox-studio": {
36
+ "type": "stdio",
37
+ "command": "python",
38
+ "args": ["-m", "roblox_studio_physical_operation_mcp"]
39
+ }
40
+ }
41
+ }
42
+ ```
43
+
44
+ > **注意**:Windows Store 版 Python 可能需要使用完整路径:
45
+ > ```json
46
+ > "command": "C:\\Users\\<用户名>\\AppData\\Local\\Microsoft\\WindowsApps\\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\\python.exe"
47
+ > ```
48
+
49
+ ## 从源码安装
50
+
51
+ ```bash
52
+ git clone https://github.com/white-dragon-tools/roblox-studio-physical-operation-mcp.git
53
+ cd roblox-studio-physical-operation-mcp
54
+ pip install -r requirements.txt
55
+ python -m roblox_studio_physical_operation_mcp
56
+ ```
57
+
58
+ ---
59
+
60
+ ## AI 使用指南
61
+
62
+ ### ⚠️ 重要:获取 place_path 或 place_id
63
+
64
+ **不知道 place_path 或 place_id 时,必须先调用 `studio_list()` 获取!**
65
+
66
+ ```python
67
+ # 先获取当前运行的 Studio 实例
68
+ instances = studio_list()
69
+ # 返回示例:
70
+ # [{"pid": 12345, "type": "local", "place_path": "D:/game.rbxl"},
71
+ # {"pid": 67890, "type": "cloud", "place_id": 110155533210141}]
72
+
73
+ # 然后用返回的 place_path 或 place_id 操作
74
+ logs_get(place_path=instances[0]["place_path"])
75
+ ```
76
+
77
+ ### 推荐工作流程
78
+
79
+ **调试已打开的 Studio**
80
+ ```
81
+ 1. studio_list() # 获取运行中的 Studio 实例
82
+ 2. studio_query(place_path) # 查询状态
83
+ 3. modal_close(place_path) # 如果有模态弹窗,关闭它们
84
+ 4. game_start(place_path) # 开始游戏
85
+ 5. logs_get(place_path) # 获取日志
86
+ 6. game_stop(place_path) # 停止游戏
87
+ ```
88
+
89
+ **打开新的 Studio**
90
+ ```
91
+ 1. studio_open(place_path) # 打开 Studio(本地文件)
92
+ 2. studio_query(place_path) # 查询状态
93
+ 3. modal_close(place_path) # 如果有模态弹窗,关闭它们
94
+ 4. studio_query(place_path) # 确认 ready=true
95
+ 5. game_start(place_path) # 开始游戏
96
+ 6. logs_get(place_path) # 获取日志
97
+ 7. game_stop(place_path) # 停止游戏
98
+ 8. studio_close(place_path) # 关闭 Studio
99
+ ```
100
+
101
+ ### 支持两种 Place 类型
102
+
103
+ 所有工具都支持两种参数(二选一):
104
+ - `place_path` - 本地 .rbxl 文件路径
105
+ - `place_id` - 云端 Roblox Place ID
106
+
107
+ ```python
108
+ # 本地文件
109
+ logs_get(place_path="D:/game.rbxl")
110
+
111
+ # 云端 Place(从网页打开的)
112
+ logs_get(place_id=110155533210141)
113
+ ```
114
+
115
+ ### studio_query 返回值说明
116
+
117
+ ```json
118
+ {
119
+ "active": true, // Studio 是否运行中
120
+ "ready": true, // 是否就绪(无模态弹窗)
121
+ "pid": 12345, // 进程 ID
122
+ "hwnd": 67890, // 主窗口句柄
123
+ "has_modal": false, // 是否有模态弹窗
124
+ "modal_count": 0, // 模态弹窗数量
125
+ "modals": [] // 模态弹窗详情
126
+ }
127
+ ```
128
+
129
+ **重要**: `ready=true` 时才能正常操作 Studio。
130
+
131
+ ---
132
+
133
+ ## 工具列表
134
+
135
+ ### 系统工具
136
+
137
+ | 工具 | 说明 |
138
+ |------|------|
139
+ | `studio_help()` | 获取使用指南 |
140
+ | `studio_list()` | **列出所有运行中的 Studio 实例** |
141
+ | `studio_open(place_path)` | 打开 Studio 并加载 .rbxl 文件 |
142
+ | `studio_close(place_path/place_id)` | 关闭 Studio |
143
+ | `studio_status(place_path/place_id)` | 获取基本状态 |
144
+ | `studio_query(place_path/place_id)` | **综合查询状态(推荐)** |
145
+
146
+ ### 模态弹窗
147
+
148
+ | 工具 | 说明 |
149
+ |------|------|
150
+ | `modal_detect(place_path/place_id)` | 检测模态弹窗 |
151
+ | `modal_close(place_path/place_id)` | 关闭所有模态弹窗 |
152
+
153
+ ### 游戏控制
154
+
155
+ | 工具 | 说明 |
156
+ |------|------|
157
+ | `game_start(place_path/place_id)` | 开始游戏 (F5) |
158
+ | `game_stop(place_path/place_id)` | 停止游戏 (Shift+F5) |
159
+ | `game_pause(place_path/place_id)` | 暂停/恢复游戏 (F12) |
160
+
161
+ ### 工具栏状态检测
162
+
163
+ | 工具 | 说明 |
164
+ |------|------|
165
+ | `toolbar_state(place_path/place_id)` | 检测工具栏按钮状态和游戏状态 |
166
+ | `toolbar_state_debug(place_path/place_id)` | 带调试信息的检测 |
167
+
168
+ 返回示例:
169
+ ```json
170
+ {
171
+ "play": "enabled",
172
+ "pause": "disabled",
173
+ "stop": "disabled",
174
+ "game_state": "stopped"
175
+ }
176
+ ```
177
+
178
+ `game_state` 可能的值:`stopped`, `running`, `paused`
179
+
180
+ ### 日志
181
+
182
+ | 工具 | 说明 |
183
+ |------|------|
184
+ | `logs_get(place_path/place_id, after_line, before_line, timestamps)` | 获取日志 |
185
+ | `logs_search(place_path/place_id, pattern, after_line, before_line, timestamps)` | 搜索日志(正则) |
186
+ | `logs_clean(days)` | 清理旧日志 |
187
+
188
+ **logs_get 参数:**
189
+ ```python
190
+ logs_get(
191
+ place_path: str = None, # 本地文件路径
192
+ place_id: int = None, # 云端 Place ID(二选一)
193
+ after_line: int = None, # 从哪一行之后开始读取
194
+ before_line: int = None, # 到哪一行之前结束
195
+ timestamps: bool = False # 是否附加时间戳 [HH:MM:SS]
196
+ )
197
+ ```
198
+
199
+ **logs_get 返回:**
200
+ ```json
201
+ {
202
+ "logs": "[15:22:01] Hello world!\nThe MCP plugin is ready.",
203
+ "start_line": 100,
204
+ "last_line": 2330,
205
+ "remaining": 0,
206
+ "has_more": false
207
+ }
208
+ ```
209
+
210
+ **续读日志:**
211
+ ```python
212
+ # 首次获取
213
+ result = logs_get(place_path="D:/game.rbxl")
214
+ # 续读新日志
215
+ result = logs_get(place_path="D:/game.rbxl", after_line=result["last_line"])
216
+ ```
217
+
218
+ ### 截图
219
+
220
+ | 工具 | 说明 |
221
+ |------|------|
222
+ | `screenshot(place_path/place_id)` | 截取主窗口 |
223
+ | `screenshot_full(place_path/place_id)` | 截取窗口(包含模态弹窗) |
224
+
225
+ ---
226
+
227
+ ## 注意事项
228
+
229
+ 1. **支持本地和云端 Place** - 使用 `place_path` 或 `place_id` 参数
230
+ 2. **启动后务必查询状态** - 调用 `studio_query` 检查是否有模态弹窗
231
+ 3. **处理模态弹窗** - `ready=false` 时调用 `modal_close` 关闭弹窗
232
+ 4. **最小化窗口自动恢复** - 检测工具栏状态时会自动恢复最小化的窗口
233
+ 5. **自动清理** - 关闭本地文件的 Studio 后会自动清理 .lock 文件
234
+ 6. **日志过滤** - `logs_get` 自动过滤 Studio 内部日志,只返回用户脚本输出
235
+
236
+ ---
237
+
238
+ ## 技术说明
239
+
240
+ - 会话管理通过扫描进程命令行 + 日志文件自动匹配
241
+ - 日志索引缓存减少 IO 操作
242
+ - 游戏控制使用 SendInput API(需短暂切换窗口焦点)
243
+ - 截图使用 PrintWindow API(可捕获被遮挡窗口)
244
+ - 模态弹窗检测通过枚举同进程窗口实现
245
+ - 工具栏状态通过 OpenCV 模板匹配检测
246
+ - 支持多显示器环境
@@ -0,0 +1,52 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "roblox-studio-physical-operation-mcp"
7
+ version = "0.1.0"
8
+ description = "MCP server for controlling Roblox Studio - toolbar detection, game control, log analysis"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ { name = "White Dragon Tools" }
14
+ ]
15
+ keywords = [
16
+ "mcp",
17
+ "roblox",
18
+ "roblox-studio",
19
+ "model-context-protocol",
20
+ "automation"
21
+ ]
22
+ classifiers = [
23
+ "Development Status :: 4 - Beta",
24
+ "Intended Audience :: Developers",
25
+ "License :: OSI Approved :: MIT License",
26
+ "Operating System :: Microsoft :: Windows",
27
+ "Programming Language :: Python :: 3",
28
+ "Programming Language :: Python :: 3.10",
29
+ "Programming Language :: Python :: 3.11",
30
+ "Programming Language :: Python :: 3.12",
31
+ "Programming Language :: Python :: 3.13",
32
+ ]
33
+ dependencies = [
34
+ "mcp>=1.0.0",
35
+ "pillow",
36
+ "opencv-python",
37
+ "pywin32",
38
+ ]
39
+
40
+ [project.urls]
41
+ Homepage = "https://github.com/white-dragon-tools/roblox-studio-physical-operation-mcp"
42
+ Repository = "https://github.com/white-dragon-tools/roblox-studio-physical-operation-mcp"
43
+ Issues = "https://github.com/white-dragon-tools/roblox-studio-physical-operation-mcp/issues"
44
+
45
+ [project.scripts]
46
+ roblox-studio-physical-operation-mcp = "roblox_studio_physical_operation_mcp:main"
47
+
48
+ [tool.hatch.build.targets.wheel]
49
+ packages = ["roblox_studio_physical_operation_mcp"]
50
+
51
+ [tool.hatch.build.targets.wheel.shared-data]
52
+ "roblox_studio_physical_operation_mcp/templates" = "roblox_studio_physical_operation_mcp/templates"
@@ -0,0 +1,9 @@
1
+ # MCP 服务核心依赖
2
+ mcp>=1.0.0
3
+ pillow
4
+ opencv-python
5
+ pywin32
6
+
7
+ # 可选:测试依赖
8
+ # dxcam
9
+ # mss
@@ -0,0 +1,13 @@
1
+ """
2
+ Roblox Studio MCP 服务
3
+
4
+ 提供以下功能:
5
+ - 游戏控制: start_game, stop_game, pause_resume_game
6
+ - 日志分析: get_recent_logs, search_logs_by_pattern
7
+ - 视觉捕获: capture_screenshot, start_recording, stop_recording
8
+ - 系统工具: get_studio_status, clean_logs, open_place, close_place
9
+ """
10
+
11
+ from .server import mcp, main
12
+
13
+ __all__ = ["mcp", "main"]
@@ -0,0 +1,8 @@
1
+ """
2
+ Roblox Studio MCP 入口
3
+ """
4
+
5
+ from roblox_studio_physical_operation_mcp import main
6
+
7
+ if __name__ == "__main__":
8
+ main()