remote-sandbox-mcp 0.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.
- remote_sandbox_mcp-0.2.0/.claude/settings.local.json +17 -0
- remote_sandbox_mcp-0.2.0/LICENSE +21 -0
- remote_sandbox_mcp-0.2.0/PKG-INFO +263 -0
- remote_sandbox_mcp-0.2.0/README.md +239 -0
- remote_sandbox_mcp-0.2.0/pyproject.toml +37 -0
- remote_sandbox_mcp-0.2.0/remote_sandbox_mcp/__init__.py +3 -0
- remote_sandbox_mcp-0.2.0/remote_sandbox_mcp/server.py +1337 -0
- remote_sandbox_mcp-0.2.0/skills/remote-sandbox-script-exec/SKILL.md +76 -0
- remote_sandbox_mcp-0.2.0/skills/remote-sandbox-script-exec/agents/openai.yaml +4 -0
- remote_sandbox_mcp-0.2.0/skills/remote-sandbox-script-exec/references/remote-runbook.md +152 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/.learnings/ERRORS.md +5 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/.learnings/FEATURE_REQUESTS.md +5 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/.learnings/LEARNINGS.md +5 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/SKILL.md +647 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/_meta.json +6 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/assets/LEARNINGS.md +45 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/assets/SKILL-TEMPLATE.md +177 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/hooks/openclaw/HOOK.md +23 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/hooks/openclaw/handler.js +56 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/hooks/openclaw/handler.ts +62 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/references/examples.md +374 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/references/hooks-setup.md +223 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/references/openclaw-integration.md +248 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/scripts/activator.sh +20 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/scripts/error-detector.sh +55 -0
- remote_sandbox_mcp-0.2.0/skills/self-improving-agent/scripts/extract-skill.sh +221 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(tree -L 3 -I \".venv|*.egg-info\" /Users/xiangdebin/Documents/code/remotesandboxmcp 2>/dev/null || find /Users/xiangdebin/Documents/code/remotesandboxmcp -not -path \"*/\\\\.*\" -not -path \"*/.venv*\" -not -path \"*.egg-info*\" -type f | head -20)",
|
|
5
|
+
"Bash(python -c \"import ast; ast.parse\\(open\\('remote_sandbox_mcp/server.py'\\).read\\(\\)\\); print\\('syntax OK'\\)\")",
|
|
6
|
+
"Bash(python -c \"\nimport ast, sys\nsrc = open\\('remote_sandbox_mcp/server.py'\\).read\\(\\)\ntree = ast.parse\\(src\\)\ntools = [n.name for n in ast.walk\\(tree\\) if isinstance\\(n, ast.FunctionDef\\)]\nprint\\('All functions:', tools\\)\nprint\\('Line count:', src.count\\('\\\\n'\\)\\)\n\")",
|
|
7
|
+
"Bash(pip install build twine --quiet 2>&1 | tail -1)",
|
|
8
|
+
"Bash(rm -rf dist/ && python -m build 2>&1)",
|
|
9
|
+
"Bash(rm -rf dist/ build/ && python -m build 2>&1 | grep -E \"Successfully|error|Error|warning|Warning\" | head -20)",
|
|
10
|
+
"Bash(python -m twine check dist/*)",
|
|
11
|
+
"Bash(pip install --upgrade twine build 2>&1 | tail -3 && python -m twine --version)",
|
|
12
|
+
"Bash(rm -rf dist/ build/ && python -m build 2>&1 | grep -E \"Successfully|error|Error|warning|Warning\" && python -m twine check dist/*)",
|
|
13
|
+
"Bash(rm -rf dist/ build/ && python -m build 2>&1 | grep -E \"Successfully|[Ee]rror|[Ww]arning\" && python -m twine check dist/*)",
|
|
14
|
+
"Bash(rm -rf dist/ build/ remote_sandbox_mcp.egg-info/ && uv build 2>&1 && python -m twine check dist/*)"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 xiangdebin
|
|
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,263 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: remote-sandbox-mcp
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: MCP server for SSH-based remote sandboxes: multi-server management, persistent sessions, background tmux tasks, and GPU/CPU/memory resource monitoring
|
|
5
|
+
Project-URL: Homepage, https://github.com/xiangdebin/remote-sandbox-mcp
|
|
6
|
+
Project-URL: Repository, https://github.com/xiangdebin/remote-sandbox-mcp
|
|
7
|
+
Project-URL: Issues, https://github.com/xiangdebin/remote-sandbox-mcp/issues
|
|
8
|
+
Author: xiangdebin
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: ai,claude,gpu,mcp,remote,sandbox,ssh,tmux
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
19
|
+
Classifier: Topic :: System :: Systems Administration
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Requires-Dist: mcp>=1.12.0
|
|
22
|
+
Requires-Dist: paramiko>=3.4.0
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# remote-sandbox-mcp
|
|
26
|
+
|
|
27
|
+
[](https://pypi.org/project/remote-sandbox-mcp/)
|
|
28
|
+
[](https://pypi.org/project/remote-sandbox-mcp/)
|
|
29
|
+
|
|
30
|
+
一个把远程 SSH 服务器当作运行沙箱的 MCP Server,支持:
|
|
31
|
+
|
|
32
|
+
- **多沙箱管理**:配置多台服务器,自动查询 CPU/内存/GPU 占用率,选出最空闲的沙箱
|
|
33
|
+
- **持久 SSH 会话**:每个沙箱维持一条长连接,自动健康检查与断线重连,不再每次调用新建连接
|
|
34
|
+
- **可靠的超时控制**:双层超时(远端 `timeout` 命令 + 客户端 deadline)确保超时真的生效
|
|
35
|
+
- **后台长任务**:通过 `exec_bash_background` 在 tmux 中运行长任务,用 `check_background_task` 异步轮询进度
|
|
36
|
+
- 本地文件/目录同步到远程沙箱(增量,按 `size + mtime` 跳过未变更文件)
|
|
37
|
+
- 远程文件/目录同步回本地
|
|
38
|
+
- 在远程沙箱执行 bash 命令并返回结果
|
|
39
|
+
- 浏览远程文件列表与读取文件内容
|
|
40
|
+
|
|
41
|
+
## 1. 快速添加到 Claude Code
|
|
42
|
+
|
|
43
|
+
无需手动安装,直接用 `claude mcp add` 即可(依赖 [uv](https://docs.astral.sh/uv/) 自动管理运行环境)。
|
|
44
|
+
|
|
45
|
+
### 单沙箱
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
claude mcp add remote-sandbox \
|
|
49
|
+
-e REMOTE_HOST=192.168.9.16 \
|
|
50
|
+
-e REMOTE_PORT=22 \
|
|
51
|
+
-e REMOTE_USER=your_user \
|
|
52
|
+
-e REMOTE_PASSWORD=your_password \
|
|
53
|
+
-- uvx remote-sandbox-mcp
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 多沙箱
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
claude mcp add remote-sandbox \
|
|
60
|
+
-e REMOTE_SANDBOX_LIST='[{"name":"A100","host":"192.168.9.15","port":22,"user":"ubuntu","password":"xxx"},{"name":"H100","host":"192.168.9.16","port":22,"user":"ubuntu","password":"xxx"}]' \
|
|
61
|
+
-- uvx remote-sandbox-mcp
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
添加后验证:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
claude mcp list
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
> **作用域**:默认添加到当前项目(`-s project`)。如需全局可用,加 `-s user`。
|
|
71
|
+
> **更新**:重新执行同一条 `claude mcp add` 命令(会覆盖旧配置),或 `uvx` 每次自动拉取最新版本。
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 2. 手动安装(可选)
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install remote-sandbox-mcp
|
|
79
|
+
# 或
|
|
80
|
+
uv tool install remote-sandbox-mcp
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## 3. 环境变量
|
|
84
|
+
|
|
85
|
+
### 单沙箱(向后兼容)
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
export REMOTE_HOST=1.2.3.4
|
|
89
|
+
export REMOTE_PORT=22
|
|
90
|
+
export REMOTE_USER=your_user
|
|
91
|
+
export REMOTE_PASSWORD=your_password
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 多沙箱(推荐)
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
export REMOTE_SANDBOX_LIST='[
|
|
98
|
+
{"name": "gpu1", "host": "10.0.0.1", "port": 22, "user": "ubuntu", "password": "secret1"},
|
|
99
|
+
{"name": "gpu2", "host": "10.0.0.2", "port": 22, "user": "ubuntu", "password": "secret2"},
|
|
100
|
+
{"name": "cpu-node", "host": "10.0.0.3", "user": "admin", "password": "secret3"}
|
|
101
|
+
]'
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
字段说明:
|
|
105
|
+
- `name`:沙箱标识符(可选,默认使用 host)
|
|
106
|
+
- `host`:SSH 地址(必填)
|
|
107
|
+
- `port`:SSH 端口(可选,默认 22)
|
|
108
|
+
- `user`:用户名(必填)
|
|
109
|
+
- `password`:密码(必填)
|
|
110
|
+
|
|
111
|
+
## 3. 启动 MCP Server
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
remote-sandbox-mcp
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
使用 `stdio` 传输,适合被 MCP Client 作为子进程拉起。
|
|
118
|
+
|
|
119
|
+
## 4. MCP Client 配置示例
|
|
120
|
+
|
|
121
|
+
### 单沙箱
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"mcpServers": {
|
|
126
|
+
"remote-sandbox": {
|
|
127
|
+
"command": "remote-sandbox-mcp",
|
|
128
|
+
"env": {
|
|
129
|
+
"REMOTE_HOST": "192.168.9.16",
|
|
130
|
+
"REMOTE_PORT": "22",
|
|
131
|
+
"REMOTE_USER": "ubuntu",
|
|
132
|
+
"REMOTE_PASSWORD": "mypassword"
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 多沙箱
|
|
140
|
+
|
|
141
|
+
```json
|
|
142
|
+
{
|
|
143
|
+
"mcpServers": {
|
|
144
|
+
"remote-sandbox": {
|
|
145
|
+
"command": "remote-sandbox-mcp",
|
|
146
|
+
"env": {
|
|
147
|
+
"REMOTE_SANDBOX_LIST": "[{\"name\":\"gpu1\",\"host\":\"10.0.0.1\",\"user\":\"ubuntu\",\"password\":\"s1\"},{\"name\":\"gpu2\",\"host\":\"10.0.0.2\",\"user\":\"ubuntu\",\"password\":\"s2\"}]"
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## 5. 可用工具
|
|
155
|
+
|
|
156
|
+
### 沙箱管理
|
|
157
|
+
|
|
158
|
+
#### `list_sandboxes`
|
|
159
|
+
列出所有已配置的沙箱及连接状态。
|
|
160
|
+
|
|
161
|
+
参数:
|
|
162
|
+
- `check_resources` (bool, 默认 `false`):是否同时查询每个沙箱的 CPU/内存/GPU 占用率与 `idle_score`(0=全忙,1=全空)
|
|
163
|
+
|
|
164
|
+
#### `select_sandbox`
|
|
165
|
+
将某个沙箱设为当前会话的活跃沙箱,后续所有工具调用默认使用它。
|
|
166
|
+
|
|
167
|
+
参数:
|
|
168
|
+
- `sandbox_name` (str, 必填)
|
|
169
|
+
|
|
170
|
+
#### `get_active_sandbox`
|
|
171
|
+
返回当前活跃沙箱及其连接健康状态(`connection_alive`)。
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### 命令执行
|
|
176
|
+
|
|
177
|
+
#### `exec_bash`
|
|
178
|
+
在远端执行 bash 命令,适合短任务(< 2 分钟)。
|
|
179
|
+
|
|
180
|
+
参数:
|
|
181
|
+
- `command` (str, 必填)
|
|
182
|
+
- `cwd` (str, 可选):切换到该目录后执行
|
|
183
|
+
- `timeout_s` (int, 默认 120):超时秒数(双层保障,真正生效)
|
|
184
|
+
- `max_output_chars` (int, 默认 20000)
|
|
185
|
+
- `sandbox_name` (str, 可选):临时覆盖活跃沙箱
|
|
186
|
+
|
|
187
|
+
返回额外字段:`timed_out: true`(超时时)、`connection_error: true`(连接断开时)
|
|
188
|
+
|
|
189
|
+
#### `exec_bash_background`
|
|
190
|
+
在远端 tmux 中以后台方式运行长任务,立即返回。输出通过 `tee` 写入日志文件,并在末尾追加 `EXIT_CODE=<n>`。
|
|
191
|
+
|
|
192
|
+
参数:
|
|
193
|
+
- `command` (str, 必填):要执行的命令
|
|
194
|
+
- `session_name` (str, 可选):tmux session 名,默认自动生成(`bg-<timestamp>`)
|
|
195
|
+
- `log_file` (str, 可选):远端日志路径,默认 `.codex_logs/<session_name>.log`
|
|
196
|
+
- `cwd` (str, 可选):工作目录
|
|
197
|
+
- `sandbox_name` (str, 可选)
|
|
198
|
+
|
|
199
|
+
#### `check_background_task`
|
|
200
|
+
查询后台 tmux 任务的运行状态与最新日志。
|
|
201
|
+
|
|
202
|
+
参数:
|
|
203
|
+
- `tmux_session` (str, 必填):`exec_bash_background` 返回的 session 名
|
|
204
|
+
- `log_file` (str, 可选):日志路径(`exec_bash_background` 返回的值)
|
|
205
|
+
- `last_n_lines` (int, 默认 50):返回日志尾部行数
|
|
206
|
+
- `sandbox_name` (str, 可选)
|
|
207
|
+
|
|
208
|
+
返回:`running`(是否仍在运行)、`exit_code`(任务结束后解析自日志)、`log_tail`
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
### 文件操作
|
|
213
|
+
|
|
214
|
+
所有文件操作工具新增 `sandbox_name` 参数(可选,临时覆盖活跃沙箱)。
|
|
215
|
+
|
|
216
|
+
#### `list_remote_files`
|
|
217
|
+
列出远程目录内容。参数:`remote_path`, `recursive`, `max_entries`, `sandbox_name`
|
|
218
|
+
|
|
219
|
+
#### `read_remote_file`
|
|
220
|
+
读取远程文件。参数:`remote_path`, `max_bytes`, `sandbox_name`
|
|
221
|
+
|
|
222
|
+
#### `sync_local_to_remote`
|
|
223
|
+
本地文件或目录同步到远端(SFTP,增量)。
|
|
224
|
+
参数:`local_path`, `remote_path`, `delete_extras`, `excludes`, `exclude_file`, `sandbox_name`
|
|
225
|
+
|
|
226
|
+
#### `sync_remote_to_local`
|
|
227
|
+
远端文件或目录同步到本地(SFTP,增量)。
|
|
228
|
+
参数:`remote_path`, `local_path`, `excludes`, `exclude_file`, `sandbox_name`
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## 6. 多沙箱典型工作流
|
|
233
|
+
|
|
234
|
+
```
|
|
235
|
+
1. list_sandboxes(check_resources=True)
|
|
236
|
+
→ 查看每个沙箱的 idle_score、GPU 占用等
|
|
237
|
+
|
|
238
|
+
2. select_sandbox(sandbox_name="gpu1")
|
|
239
|
+
→ 选择最空闲的沙箱,后续调用都用它
|
|
240
|
+
|
|
241
|
+
3. get_active_sandbox()
|
|
242
|
+
→ 确认连接正常(connection_alive: true)
|
|
243
|
+
|
|
244
|
+
4. exec_bash_background(
|
|
245
|
+
command="python train.py --epochs 100",
|
|
246
|
+
cwd="~/projects/mymodel",
|
|
247
|
+
session_name="train-001"
|
|
248
|
+
)
|
|
249
|
+
→ 后台启动,立即返回 {tmux_session, log_file}
|
|
250
|
+
|
|
251
|
+
5. check_background_task(
|
|
252
|
+
tmux_session="train-001",
|
|
253
|
+
log_file="~/projects/mymodel/.codex_logs/train-001.log"
|
|
254
|
+
)
|
|
255
|
+
→ 每隔几分钟轮询一次,查看日志尾部和运行状态
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## 7. 注意事项
|
|
259
|
+
|
|
260
|
+
- 首次连接会自动接受主机指纹(`AutoAddPolicy`)。生产环境建议改成固定 known_hosts 校验。
|
|
261
|
+
- 后台任务需要远端已安装 `tmux`(大多数 Linux 发行版默认有)。
|
|
262
|
+
- `delete_extras=true` 会删除远端不在本地的文件,请谨慎使用。
|
|
263
|
+
- 持久会话每 30 秒做一次健康检查,断线后下一次工具调用会自动重连。
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# remote-sandbox-mcp
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/remote-sandbox-mcp/)
|
|
4
|
+
[](https://pypi.org/project/remote-sandbox-mcp/)
|
|
5
|
+
|
|
6
|
+
一个把远程 SSH 服务器当作运行沙箱的 MCP Server,支持:
|
|
7
|
+
|
|
8
|
+
- **多沙箱管理**:配置多台服务器,自动查询 CPU/内存/GPU 占用率,选出最空闲的沙箱
|
|
9
|
+
- **持久 SSH 会话**:每个沙箱维持一条长连接,自动健康检查与断线重连,不再每次调用新建连接
|
|
10
|
+
- **可靠的超时控制**:双层超时(远端 `timeout` 命令 + 客户端 deadline)确保超时真的生效
|
|
11
|
+
- **后台长任务**:通过 `exec_bash_background` 在 tmux 中运行长任务,用 `check_background_task` 异步轮询进度
|
|
12
|
+
- 本地文件/目录同步到远程沙箱(增量,按 `size + mtime` 跳过未变更文件)
|
|
13
|
+
- 远程文件/目录同步回本地
|
|
14
|
+
- 在远程沙箱执行 bash 命令并返回结果
|
|
15
|
+
- 浏览远程文件列表与读取文件内容
|
|
16
|
+
|
|
17
|
+
## 1. 快速添加到 Claude Code
|
|
18
|
+
|
|
19
|
+
无需手动安装,直接用 `claude mcp add` 即可(依赖 [uv](https://docs.astral.sh/uv/) 自动管理运行环境)。
|
|
20
|
+
|
|
21
|
+
### 单沙箱
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
claude mcp add remote-sandbox \
|
|
25
|
+
-e REMOTE_HOST=192.168.9.16 \
|
|
26
|
+
-e REMOTE_PORT=22 \
|
|
27
|
+
-e REMOTE_USER=your_user \
|
|
28
|
+
-e REMOTE_PASSWORD=your_password \
|
|
29
|
+
-- uvx remote-sandbox-mcp
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 多沙箱
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
claude mcp add remote-sandbox \
|
|
36
|
+
-e REMOTE_SANDBOX_LIST='[{"name":"A100","host":"192.168.9.15","port":22,"user":"ubuntu","password":"xxx"},{"name":"H100","host":"192.168.9.16","port":22,"user":"ubuntu","password":"xxx"}]' \
|
|
37
|
+
-- uvx remote-sandbox-mcp
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
添加后验证:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
claude mcp list
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
> **作用域**:默认添加到当前项目(`-s project`)。如需全局可用,加 `-s user`。
|
|
47
|
+
> **更新**:重新执行同一条 `claude mcp add` 命令(会覆盖旧配置),或 `uvx` 每次自动拉取最新版本。
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 2. 手动安装(可选)
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install remote-sandbox-mcp
|
|
55
|
+
# 或
|
|
56
|
+
uv tool install remote-sandbox-mcp
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 3. 环境变量
|
|
60
|
+
|
|
61
|
+
### 单沙箱(向后兼容)
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
export REMOTE_HOST=1.2.3.4
|
|
65
|
+
export REMOTE_PORT=22
|
|
66
|
+
export REMOTE_USER=your_user
|
|
67
|
+
export REMOTE_PASSWORD=your_password
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 多沙箱(推荐)
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
export REMOTE_SANDBOX_LIST='[
|
|
74
|
+
{"name": "gpu1", "host": "10.0.0.1", "port": 22, "user": "ubuntu", "password": "secret1"},
|
|
75
|
+
{"name": "gpu2", "host": "10.0.0.2", "port": 22, "user": "ubuntu", "password": "secret2"},
|
|
76
|
+
{"name": "cpu-node", "host": "10.0.0.3", "user": "admin", "password": "secret3"}
|
|
77
|
+
]'
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
字段说明:
|
|
81
|
+
- `name`:沙箱标识符(可选,默认使用 host)
|
|
82
|
+
- `host`:SSH 地址(必填)
|
|
83
|
+
- `port`:SSH 端口(可选,默认 22)
|
|
84
|
+
- `user`:用户名(必填)
|
|
85
|
+
- `password`:密码(必填)
|
|
86
|
+
|
|
87
|
+
## 3. 启动 MCP Server
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
remote-sandbox-mcp
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
使用 `stdio` 传输,适合被 MCP Client 作为子进程拉起。
|
|
94
|
+
|
|
95
|
+
## 4. MCP Client 配置示例
|
|
96
|
+
|
|
97
|
+
### 单沙箱
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"mcpServers": {
|
|
102
|
+
"remote-sandbox": {
|
|
103
|
+
"command": "remote-sandbox-mcp",
|
|
104
|
+
"env": {
|
|
105
|
+
"REMOTE_HOST": "192.168.9.16",
|
|
106
|
+
"REMOTE_PORT": "22",
|
|
107
|
+
"REMOTE_USER": "ubuntu",
|
|
108
|
+
"REMOTE_PASSWORD": "mypassword"
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 多沙箱
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"mcpServers": {
|
|
120
|
+
"remote-sandbox": {
|
|
121
|
+
"command": "remote-sandbox-mcp",
|
|
122
|
+
"env": {
|
|
123
|
+
"REMOTE_SANDBOX_LIST": "[{\"name\":\"gpu1\",\"host\":\"10.0.0.1\",\"user\":\"ubuntu\",\"password\":\"s1\"},{\"name\":\"gpu2\",\"host\":\"10.0.0.2\",\"user\":\"ubuntu\",\"password\":\"s2\"}]"
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## 5. 可用工具
|
|
131
|
+
|
|
132
|
+
### 沙箱管理
|
|
133
|
+
|
|
134
|
+
#### `list_sandboxes`
|
|
135
|
+
列出所有已配置的沙箱及连接状态。
|
|
136
|
+
|
|
137
|
+
参数:
|
|
138
|
+
- `check_resources` (bool, 默认 `false`):是否同时查询每个沙箱的 CPU/内存/GPU 占用率与 `idle_score`(0=全忙,1=全空)
|
|
139
|
+
|
|
140
|
+
#### `select_sandbox`
|
|
141
|
+
将某个沙箱设为当前会话的活跃沙箱,后续所有工具调用默认使用它。
|
|
142
|
+
|
|
143
|
+
参数:
|
|
144
|
+
- `sandbox_name` (str, 必填)
|
|
145
|
+
|
|
146
|
+
#### `get_active_sandbox`
|
|
147
|
+
返回当前活跃沙箱及其连接健康状态(`connection_alive`)。
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### 命令执行
|
|
152
|
+
|
|
153
|
+
#### `exec_bash`
|
|
154
|
+
在远端执行 bash 命令,适合短任务(< 2 分钟)。
|
|
155
|
+
|
|
156
|
+
参数:
|
|
157
|
+
- `command` (str, 必填)
|
|
158
|
+
- `cwd` (str, 可选):切换到该目录后执行
|
|
159
|
+
- `timeout_s` (int, 默认 120):超时秒数(双层保障,真正生效)
|
|
160
|
+
- `max_output_chars` (int, 默认 20000)
|
|
161
|
+
- `sandbox_name` (str, 可选):临时覆盖活跃沙箱
|
|
162
|
+
|
|
163
|
+
返回额外字段:`timed_out: true`(超时时)、`connection_error: true`(连接断开时)
|
|
164
|
+
|
|
165
|
+
#### `exec_bash_background`
|
|
166
|
+
在远端 tmux 中以后台方式运行长任务,立即返回。输出通过 `tee` 写入日志文件,并在末尾追加 `EXIT_CODE=<n>`。
|
|
167
|
+
|
|
168
|
+
参数:
|
|
169
|
+
- `command` (str, 必填):要执行的命令
|
|
170
|
+
- `session_name` (str, 可选):tmux session 名,默认自动生成(`bg-<timestamp>`)
|
|
171
|
+
- `log_file` (str, 可选):远端日志路径,默认 `.codex_logs/<session_name>.log`
|
|
172
|
+
- `cwd` (str, 可选):工作目录
|
|
173
|
+
- `sandbox_name` (str, 可选)
|
|
174
|
+
|
|
175
|
+
#### `check_background_task`
|
|
176
|
+
查询后台 tmux 任务的运行状态与最新日志。
|
|
177
|
+
|
|
178
|
+
参数:
|
|
179
|
+
- `tmux_session` (str, 必填):`exec_bash_background` 返回的 session 名
|
|
180
|
+
- `log_file` (str, 可选):日志路径(`exec_bash_background` 返回的值)
|
|
181
|
+
- `last_n_lines` (int, 默认 50):返回日志尾部行数
|
|
182
|
+
- `sandbox_name` (str, 可选)
|
|
183
|
+
|
|
184
|
+
返回:`running`(是否仍在运行)、`exit_code`(任务结束后解析自日志)、`log_tail`
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
### 文件操作
|
|
189
|
+
|
|
190
|
+
所有文件操作工具新增 `sandbox_name` 参数(可选,临时覆盖活跃沙箱)。
|
|
191
|
+
|
|
192
|
+
#### `list_remote_files`
|
|
193
|
+
列出远程目录内容。参数:`remote_path`, `recursive`, `max_entries`, `sandbox_name`
|
|
194
|
+
|
|
195
|
+
#### `read_remote_file`
|
|
196
|
+
读取远程文件。参数:`remote_path`, `max_bytes`, `sandbox_name`
|
|
197
|
+
|
|
198
|
+
#### `sync_local_to_remote`
|
|
199
|
+
本地文件或目录同步到远端(SFTP,增量)。
|
|
200
|
+
参数:`local_path`, `remote_path`, `delete_extras`, `excludes`, `exclude_file`, `sandbox_name`
|
|
201
|
+
|
|
202
|
+
#### `sync_remote_to_local`
|
|
203
|
+
远端文件或目录同步到本地(SFTP,增量)。
|
|
204
|
+
参数:`remote_path`, `local_path`, `excludes`, `exclude_file`, `sandbox_name`
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## 6. 多沙箱典型工作流
|
|
209
|
+
|
|
210
|
+
```
|
|
211
|
+
1. list_sandboxes(check_resources=True)
|
|
212
|
+
→ 查看每个沙箱的 idle_score、GPU 占用等
|
|
213
|
+
|
|
214
|
+
2. select_sandbox(sandbox_name="gpu1")
|
|
215
|
+
→ 选择最空闲的沙箱,后续调用都用它
|
|
216
|
+
|
|
217
|
+
3. get_active_sandbox()
|
|
218
|
+
→ 确认连接正常(connection_alive: true)
|
|
219
|
+
|
|
220
|
+
4. exec_bash_background(
|
|
221
|
+
command="python train.py --epochs 100",
|
|
222
|
+
cwd="~/projects/mymodel",
|
|
223
|
+
session_name="train-001"
|
|
224
|
+
)
|
|
225
|
+
→ 后台启动,立即返回 {tmux_session, log_file}
|
|
226
|
+
|
|
227
|
+
5. check_background_task(
|
|
228
|
+
tmux_session="train-001",
|
|
229
|
+
log_file="~/projects/mymodel/.codex_logs/train-001.log"
|
|
230
|
+
)
|
|
231
|
+
→ 每隔几分钟轮询一次,查看日志尾部和运行状态
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## 7. 注意事项
|
|
235
|
+
|
|
236
|
+
- 首次连接会自动接受主机指纹(`AutoAddPolicy`)。生产环境建议改成固定 known_hosts 校验。
|
|
237
|
+
- 后台任务需要远端已安装 `tmux`(大多数 Linux 发行版默认有)。
|
|
238
|
+
- `delete_extras=true` 会删除远端不在本地的文件,请谨慎使用。
|
|
239
|
+
- 持久会话每 30 秒做一次健康检查,断线后下一次工具调用会自动重连。
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "remote-sandbox-mcp"
|
|
3
|
+
version = "0.2.0"
|
|
4
|
+
description = "MCP server for SSH-based remote sandboxes: multi-server management, persistent sessions, background tmux tasks, and GPU/CPU/memory resource monitoring"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
requires-python = ">=3.10"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name = "xiangdebin" }
|
|
10
|
+
]
|
|
11
|
+
keywords = ["mcp", "ssh", "sandbox", "remote", "claude", "ai", "tmux", "gpu"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 4 - Beta",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3.10",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Topic :: Software Development :: Libraries",
|
|
20
|
+
"Topic :: System :: Systems Administration",
|
|
21
|
+
]
|
|
22
|
+
dependencies = [
|
|
23
|
+
"mcp>=1.12.0",
|
|
24
|
+
"paramiko>=3.4.0",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
Homepage = "https://github.com/xiangdebin/remote-sandbox-mcp"
|
|
29
|
+
Repository = "https://github.com/xiangdebin/remote-sandbox-mcp"
|
|
30
|
+
Issues = "https://github.com/xiangdebin/remote-sandbox-mcp/issues"
|
|
31
|
+
|
|
32
|
+
[project.scripts]
|
|
33
|
+
remote-sandbox-mcp = "remote_sandbox_mcp.server:main"
|
|
34
|
+
|
|
35
|
+
[build-system]
|
|
36
|
+
requires = ["hatchling"]
|
|
37
|
+
build-backend = "hatchling.build"
|