modal-workspace-mcp

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.

Category
Visit Server

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/

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured