Skip to main content
Glama
xiaoqianran

modal-workspace-mcp

by xiaoqianran

modal-workspace-mcp

一个远程 MCP 桥接器,让 GitHub Copilot、Copilot CLI 和其他 MCP 客户端使用你的 Modal 账户来执行 Linux 操作、安装依赖、进行 Git 操作、运行 GPU 任务,以及调用已部署的 Modal Functions。

这个项目刻意是一个桥接器,而不是 IDE 或托管的开发者工作区。

GitHub Copilot / MCP client
          |
          | Streamable HTTP MCP + Bearer token
          v
https://...modal.run/mcp/
          |
          v
modal-workspace-mcp gateway
          |
          +--> Modal Sandbox --> apt / git / curl / uv / pip / GPU / Internet
          |
          +--> deployed Modal Function

V1 工具

  • sandbox_create — 创建一个独立的 Sandbox,可配置 CPU/RAM/GPU、apt/pip 包、网络策略、允许列表中的 Secrets 和 Volumes。

  • sandbox_exec — 执行 bash -lc 命令并返回退出码/stdout/stderr。

  • sandbox_status — 检查 Sandbox 是否在运行。

  • sandbox_list — 列出由该 MCP 管理的 Sandbox。

  • sandbox_snapshot — 将 Sandbox 文件系统快照到 Modal Image。

  • sandbox_terminate — 终止一个 Sandbox。

  • function_call — 按 app/function 名称调用已部署的 Modal Function。

  • app_get — 解析指定的 Modal App 和仪表盘 URL。

  • app_list — 通过官方 modal app list --json CLI 界面列出 Modal Apps。

Related MCP server: MCP4Modal Sandbox

为什么这能解决 GitHub 容器 DNS 问题

GitHub 代理不会在本地执行 apt、curl、git clone 或 pip。它只会向你的 Modal 端点发起一个 MCP HTTP 请求。实际的网络和 shell 操作发生在 Modal Sandbox 内部。

1. 配置网关令牌

在本地生成一个随机令牌:

python -c "import secrets; print(secrets.token_urlsafe(48))"

创建一个名为 modal-workspace-mcp-auth 的 Modal Secret,其中包含该值:

modal secret create modal-workspace-mcp-auth MODAL_WORKSPACE_MCP_TOKEN='<generated-token>'

同一个网关 Secret 还可以携带非机密配置,例如允许列表,从而使已部署的 Function 将这些配置作为环境变量接收。

不要提交该令牌。

2. 可选:允许 Sandbox Secrets 和 Volumes

默认情况下,MCP 拒绝任意的 Secret/Volume 挂载。如果你需要,请在网关 Function 上配置允许列表。

服务器支持的环境变量:

MODAL_WORKSPACE_ALLOWED_SECRETS=github-agent,huggingface-agent
MODAL_WORKSPACE_ALLOWED_VOLUMES=model-cache,workspace-cache
MODAL_WORKSPACE_SANDBOX_APP=modal-workspace-sandboxes
MODAL_WORKSPACE_MAX_OUTPUT_CHARS=120000

例如,将凭据创建为独立的 Modal Secrets:

modal secret create github-agent GH_TOKEN="$GH_TOKEN"
modal secret create huggingface-agent HF_TOKEN="$HF_TOKEN"

然后更新网关 Secret,使这些 Secret 名称 被显式加入允许列表(它们的值仍然保存在各自的 Secrets 中):

modal secret create modal-workspace-mcp-auth \
  MODAL_WORKSPACE_MCP_TOKEN='<generated-token>' \
  MODAL_WORKSPACE_ALLOWED_SECRETS='github-agent,huggingface-agent'

3. 部署

在本地通过 Modal 身份验证后:

uv sync
uv run modal deploy modal_app.py

Modal 会打印公共 Web Function URL。MCP 端点就是该 URL 加上 /mcp/。

健康检查:

curl https://YOUR-ENDPOINT.modal.run/healthz

对于 MCP Inspector:

npx @modelcontextprotocol/inspector

使用 Streamable HTTP,URL:

https://YOUR-ENDPOINT.modal.run/mcp/

以及请求头:

Authorization: Bearer <generated-token>

4. GitHub Copilot 云代理

在目标 GitHub 仓库中配置以下 Agents 值:

COPILOT_MCP_MODAL_URL=https://YOUR-ENDPOINT.modal.run
COPILOT_MCP_MODAL_GATEWAY_TOKEN=<generated-token>

然后使用来自 .mcp.json 的仓库 MCP 配置:

{
  "mcpServers": {
    "modal-workspace": {
      "type": "http",
      "url": "${COPILOT_MCP_MODAL_URL}/mcp/",
      "headers": {
        "Authorization": "Bearer ${COPILOT_MCP_MODAL_GATEWAY_TOKEN}"
      },
      "tools": [
        "sandbox_create",
        "sandbox_exec",
        "sandbox_status",
        "sandbox_list",
        "sandbox_snapshot",
        "sandbox_terminate",
        "function_call",
        "app_get",
        "app_list"
      ]
    }
  }
}

GitHub Copilot 云代理支持远程 HTTP MCP 服务器,并支持替换以 COPILOT_MCP_ 为前缀的 Agents 机密/变量。这里有意不使用基于 OAuth 的远程 MCP;网关使用 Bearer 令牌。

4A. 作为 GitHub Copilot 插件安装

这个仓库同时也是一个小型 Copilot 插件市场。在 GitHub 上发布后,目标仓库可以使用 examples/github-copilot-settings.json 中的模板,通过 .github/copilot/settings.json 启用该插件:

{
  "enabledPlugins": {
    "modal-workspace@modal-workspace-mcp": true
  },
  "extraKnownMarketplaces": {
    "modal-workspace-mcp": {
      "source": {
        "source": "github",
        "repo": "xiaoqianran/modal-workspace-mcp"
      }
    }
  }
}

该市场条目指向 plugins/modal-workspace/,其中的 .mcp.json 将 Copilot 连接到已部署的 Modal HTTP MCP 端点。在测试插件安装之前,你也可以直接在仓库的 Copilot MCP 设置中配置相同的远程 MCP,以便进行首次调试。

5. 首次端到端测试

让 Copilot 执行与以下内容等效的操作:

1. Call sandbox_create with timeout_seconds=1800.
2. Call sandbox_exec on the returned sandbox_id with:
   apt-get update && apt-get install -y ffmpeg && git --version && curl -I https://github.com
3. Return the exit code and the last part of stdout/stderr.
4. Call sandbox_terminate.

一个更强的测试:

Create a Modal Sandbox, clone a public GitHub repository into /root/repo,
install its dependencies, run its tests, report results, then terminate the Sandbox.
Do not use the local GitHub agent shell for network operations.

安全模型

  • HTTP MCP 端点需要 Bearer 令牌。

  • Sandbox Secret 和 Volume 的挂载默认拒绝,并基于允许列表。

  • Secret 值永远不会被接受为 MCP 工具参数。

  • 输出会被截断,以避免 MCP 响应失控。

  • Sandbox 会在专用的 Modal App 下被标记和隔离。

  • 将破坏性操作保留在 Sandbox 内部。

  • 建议优先使用具有最小仓库权限的专用 GitHub 令牌,而不是权限范围过宽的个人令牌。

本地验证

该仓库包含无依赖的辅助测试:

python -m unittest discover -s tests -v
python -m compileall modal_workspace_mcp modal_app.py

完整的 MCP/Modal 集成测试需要互联网连接和一个已通过身份验证的 Modal 账户。

Related MCP Connectors

Related MCP Servers