modal-workspace-mcp
A remote MCP bridge that lets MCP clients use Modal sandboxes for Linux execution, dependency installation, Git operations, GPU jobs, and invoking deployed Modal Functions.
README
modal-workspace-mcp
modal-workspace-mcp 是一个部署在你自己 Modal 账户里的 实时 Remote Workspace 网关。
它的目标不是“远程执行一条命令”,而是让 ChatGPT、GitHub Copilot、MCP Client 或未来 Web UI 获得一个可以持续使用的远程实验工作区:
ChatGPT / Copilot / MCP Client
│
│ HTTPS + Bearer
▼
modal-workspace-mcp
├── /api/* GPT Actions / REST
└── /mcp/ Remote MCP
│
▼
Remote Workspace (ws-*)
│
Modal Sandbox (sb-*)
├── realtime process runtime
├── GitHub clone / fetch / checkout
├── apt / curl / wget
├── uv / pip / Python
├── CPU / GPU
└── Filesystem
对上层 Agent 来说,
ws-*是主要对象;sb-*只是底层实现和诊断信息。
v0.5:Workspace-first + Realtime GitHub
v0.5 在已经上线的 v0.4 实时 Runtime 上增加两层:
P0 Realtime Runtime ✅
P1 Workspace abstraction ✅
P2 Realtime Git / Repo ✅
P3 Filesystem watch 下一阶段
P4 Snapshot / Resume 下一阶段
P5 Experiment / GPU 下一阶段
Workspace
每个在线 Workspace 有稳定 ID:
ws-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Gateway 使用 Modal Sandbox 原生 tags 把 ws-* 映射到实际 sb-*:
managed-by=modal-workspace-mcp
workspace-id=ws-...
workspace-root=/workspace
repo-slug=OWNER/REPO # clone 后
repo-path=/workspace/repo # clone 后
repo-ref=main/HEAD/... # clone/checkout 后
因此不同 HTTP 请求、GPT Action 调用或 MCP 调用都能仅凭 workspace_id 找回同一个实时环境。
当前 v0.5 的 Workspace 是在线态抽象:Sandbox 终止后该 Workspace 离线。长期恢复/分叉会在 P4 通过 Snapshot + Volume 实现,不假装已经有永久 Workspace 数据库。
推荐使用流程
1. 创建 Workspace
GPT Action:
createRemoteWorkspace
MCP:
workspace_create
返回:
{
"workspace_id": "ws-...",
"sandbox_id": "sb-...",
"root": "/workspace",
"running": true
}
后续尽量只使用 workspace_id。
2. 实时拉取 GitHub 仓库
GPT Action:
cloneGitHubRepoToWorkspace
MCP:
repo_clone
示例参数:
{
"workspace_id": "ws-...",
"repository": "xiaoqianran/modal-workspace-mcp",
"ref": "main",
"depth": 1
}
默认 clone 到:
/workspace/repo
立即返回:
{
"workspace_id": "ws-...",
"exec_id": "ex-...",
"cursor": 0,
"operation": "repo_clone"
}
然后持续读取:
getRealtimeWorkspaceExecEvents
或 MCP:
workspace_realtime_exec_events
始终把上一批的 next_cursor 作为下一次 cursor。
git clone --progress 的 stdout/stderr 会作为增量事件返回,所以大仓库、LFS、下载、编译不会等到任务结束才一次性看到日志。
3. 查看 Repo
getWorkspaceGitStatus
getWorkspaceGitDiff
fetchWorkspaceGitRepo
checkoutWorkspaceGitRef
对应 MCP:
repo_status
repo_diff
repo_fetch
repo_checkout
repo_status 返回结构化信息:
{
"head": "40位commit SHA",
"branch": "main",
"remote": "https://github.com/OWNER/REPO.git",
"status": "## main...origin/main",
"clean": true
}
4. 在 Repo 里实时实验
clone 成功后,Workspace 默认 workdir 自动变为 Repo 路径。
例如:
startRealtimeWorkspaceExec
command = "uv sync && uv run pytest -q"
无需再告诉 Agent /workspace/repo。
实时 Runtime
实时执行不是“不断返回整个日志”,而是 append-only event stream:
start
↓
exec_id + cursor=0
↓
events(cursor=0, wait_seconds=...)
↓
只返回新增事件
↓
next_cursor
↓
继续 long-poll
事件:
{
"seq": 42,
"timestamp": "...",
"type": "stdout",
"data": "Receiving objects: 57%\n"
}
类型:
status
stdout
stderr
error
exit
支持:
- stdout / stderr 增量读取;
- cursor;
- long-poll;
- stdin;
- PTY;
- TERM / INT / HUP / KILL;
- Gateway 跨请求重新连接同一个 Sandbox 后继续读取。
生产 E2E 已实际验证:进程阻塞等待 stdin 时,Gateway 已经能先取得 stdout;随后另一个 HTTP 请求发送 stdin,再由后续 cursor 请求取得完成事件。
Workspace API
GPT Actions / REST
| operationId | 用途 |
|---|---|
createRemoteWorkspace |
创建在线 Workspace |
listRemoteWorkspaces |
列出在线 Workspace |
getRemoteWorkspace |
用 ws-* 查询状态/Repo |
terminateRemoteWorkspace |
终止 Workspace |
executeInRemoteWorkspace |
很短的同步命令 |
startRealtimeWorkspaceExec |
启动实时命令 |
getRealtimeWorkspaceExecEvents |
cursor 增量事件 |
getRealtimeWorkspaceExecStatus |
进程状态 |
sendRealtimeWorkspaceExecInput |
stdin / EOF |
cancelRealtimeWorkspaceExec |
发送信号取消 |
cloneGitHubRepoToWorkspace |
实时 clone GitHub Repo |
fetchWorkspaceGitRepo |
实时 fetch |
checkoutWorkspaceGitRef |
实时 checkout |
getWorkspaceGitStatus |
HEAD / branch / remote / status |
getWorkspaceGitDiff |
diff / cached / stat |
Raw sandbox_* API 仍保留,作为底层兼容和 escape hatch。
MCP tools
推荐的新工具:
workspace_create
workspace_get
workspace_list
workspace_exec
workspace_realtime_exec_start
workspace_realtime_exec_events
workspace_realtime_exec_status
workspace_realtime_exec_input
workspace_realtime_exec_cancel
workspace_terminate
repo_clone
repo_fetch
repo_checkout
repo_status
repo_diff
旧 sandbox_* 工具继续可用。
GitHub 中转的安全边界
Repo API 不允许 Agent 任意把字符串拼成 git clone shell。
repository 只接受:
OWNER/REPO
https://github.com/OWNER/REPO
https://github.com/OWNER/REPO.git
拒绝:
非 github.com host
URL 内 username/password/token
query / fragment
多余路径
越界 destination
危险 Git ref
Git 参数会在服务端验证并 shell quote。
私有 GitHub
不要这样:
https://TOKEN@github.com/OWNER/REPO.git
推荐创建 Modal Secret:
modal secret create github-agent GH_TOKEN="$GH_TOKEN"
GitHub Variable:
MODAL_WORKSPACE_ALLOWED_SECRETS=github-agent
调用 clone/fetch:
{
"secret_names": ["github-agent"],
"use_github_token": true
}
Gateway 只把 Secret 名称传给 Modal。Sandbox 内临时 GIT_ASKPASS 从环境变量 $GH_TOKEN 读取凭据;token 值不会拼进 clone URL、API response 或事件日志。
默认 Workspace 环境
未指定 Named Image 时使用 Debian Slim,并预装:
ca-certificates
curl
git
git-lfs
jq
openssh-client
ripgrep
unzip
wget
uv
所以默认 Workspace 就能:
git clone
curl / wget
uv / pip
apt
Python
默认资源:
CPU request 2
CPU hard limit 4
Memory request 4096 MiB
Memory hard limit 8192 MiB
可按 Workspace 调整 cpu / cpu_limit / memory / gpu / cloud / region。
Secrets / Volumes:默认拒绝
未配置时:
MODAL_WORKSPACE_ALLOWED_SECRETS = 空
MODAL_WORKSPACE_ALLOWED_VOLUMES = 空
MODAL_WORKSPACE_DEFAULT_IMAGE_NAME = None
公开 GitHub clone 不需要任何 Secret。
可选 GitHub Variables:
MODAL_WORKSPACE_ALLOWED_SECRETS=github-agent,huggingface-agent
MODAL_WORKSPACE_ALLOWED_VOLUMES=model-cache,workspace-cache
MODAL_WORKSPACE_DEFAULT_IMAGE_NAME=modal-workspace-base:latest
Named Image / Snapshot / Volume
推荐长期边界:
Named Image = 稳定软件环境
Sandbox = 当前在线 Workspace
Snapshot = 会话保存/恢复/分叉(P4)
Volume = dataset / cache / artifact(P4+)
Git = 源码版本
当前已有底层 sandbox_snapshot,但 v0.5 还没有把它包装成 workspace_save/resume/fork;这会在 P4 做,而不是把未完成能力写成已完成。
部署
必需 GitHub Actions Secrets:
MODAL_TOKEN_ID
MODAL_TOKEN_SECRET
MODAL_WORKSPACE_MCP_TOKEN
main 变更后 Deploy workflow 会真实执行:
install
→ Modal auth
→ deploy
→ /healthz
→ /api/apps
→ createRemoteWorkspace
→ 用 ws-* 重新解析 Sandbox tag
→ Workspace realtime stdout + stdin
→ cloneGitHubRepoToWorkspace
→ cursor 拉取 clone events
→ getWorkspaceGitStatus
→ 验证 HEAD / remote / repo metadata
→ terminateRemoteWorkspace
因此“Deploy success”代表线上 Workspace + GitHub 中转链路真的跑过,不只是 import/compile 成功。
ChatGPT GPT Actions
OpenAPI:
https://YOUR-ENDPOINT.modal.run/action-openapi.json
认证:
API Key
Auth Type: Bearer
Key: MODAL_WORKSPACE_MCP_TOKEN
推荐给 GPT 的核心指令:
优先使用 Remote Workspace,而不是直接操作 raw Sandbox。
新任务先 createRemoteWorkspace。
GitHub 仓库使用 cloneGitHubRepoToWorkspace,不要自己拼带 token 的 git URL。
安装、下载、Git、编译、实验优先使用 realtime 操作。
每次读取事件都把 next_cursor 用作下一次 cursor。
任务完成后 terminateRemoteWorkspace,除非用户明确要求保持在线。
Remote MCP
https://YOUR-ENDPOINT.modal.run/mcp/
请求头:
Authorization: Bearer <MODAL_WORKSPACE_MCP_TOKEN>
下一阶段
P0 Realtime Runtime ✅
P1 Workspace abstraction ✅ v0.5
P2 Realtime Git / Repo ✅ v0.5
↓
P3 Filesystem watch
↓
P4 workspace_save / resume / fork + Volume
↓
P5 Experiment + GPU metrics
↓
P6 Artifact / GitHub branch / PR 回传
↓
WebSocket UI / browser terminal
测试
python -m unittest discover -s tests -v
python -m compileall -q modal_workspace_mcp modal_app.py
测试包括:
- 实时 stdout 必须在进程结束前出现;
- stdin roundtrip;
- Workspace ID 校验;
- GitHub Repo URL / ref / path 安全校验;
- 私有 Git askpass 不包含 token 值;
- Modal Sandbox tags API contract;
- Workspace/Repo Action operationId contract;
- 生产真实 Workspace + GitHub clone E2E。
项目结构
modal-workspace-mcp/
├── modal_app.py
├── modal_workspace_mcp/
│ ├── action_api.py
│ ├── config.py
│ ├── helpers.py
│ ├── realtime_agent.py
│ ├── realtime_service.py
│ ├── workspace_service.py
│ ├── repo_service.py
│ ├── server.py
│ └── service.py
├── .github/workflows/
│ ├── ci.yml
│ └── deploy-modal.yml
├── tests/
├── plugins/
├── skills/
└── examples/
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。