最近团队在折腾 MCP(Model Context Protocol)生态,想搭建一个开发平台,让用户能自由上传MCP代码,平台自动完成依赖安装、安全检测、沙箱隔离,最后给出一个统一的网关 URL 供调用。我们调研了一圈发现,市面上的方案要么只支持单语言,要么协议受限,要么隔离性不够。于是团队决定自己撸一套:Python/TypeScript 双语言 + SSE/StreamableHTTP 双协议,四种组合全支持,配合 Docker + Firejail 双层隔离。这篇文章聊聊平台设计的完整思路,希望能给有类似需求的同学一些参考。
一、想做什么样的平台?
如果你用过 MCP(Model Context Protocol),可能会觉得:写一个 MCP 服务不难,但把它变成一个可供他人调用的在线服务,却有一堆麻烦事。搭建开发环境、处理依赖、部署运行,这些琐事劝退了不少人。
我们想做的是这样一个平台:
| 用户做的事 | 平台做的事 |
|---|---|
| 写 MCP 代码(Python/TS) | 自动识别语言类型 |
| 上传 ZIP 包 | 自动安装依赖 |
| —— | 安全检测代码 |
| —— | 创建沙箱隔离环境 |
| —— | 启动服务并健康检查 |
| 获得一个网关 URL | 统一路由、协议适配、负载均衡 |
一句话总结:用户只管写代码,平台负责让它安全、稳定地跑起来,并提供统一的服务入口。
二、平台需要解决的核心问题
把这个想法落地,我们面临四个必须跨过的坎:
1. 多语言支持
MCP 生态里,Python 和 TypeScript 是两大主流。平台不能二选一,必须同时支持。
2. 双协议适配
MCP 有 SSE 和 StreamableHTTP 两种传输协议。平台需要自动识别、正确代理,对调用方透明。
3. 安全隔离
这是平台的生命线。需要保证:
- 用户代码不会破坏平台环境
- 不同用户的代码不会互相干扰
- 依赖环境隔离、进程隔离、文件操作隔离
4. 零配置体验
用户不应该关心“怎么装依赖”“怎么配网关”“怎么处理协议”。上传即用,拿到 URL 即可调用。
三、技术选型:为什么是 Docker + Firejail?
面对“安全隔离”这个核心诉求,我们评估了多种方案。最终选择了 Docker + Firejail 双层隔离,这不是“炫技”,而是对平台场景的精准匹配。
双层隔离架构
┌─────────────────────────────────────────┐
│ 宿主机 (Host) │
│ ┌─────────────────────────────────┐ │
│ │ Docker 容器 (平台层) │ │ ← 第一层:平台与宿主机隔离
│ │ ┌─────────────────────────┐ │ │
│ │ │ 用户 A 的 Firejail │ │ │ ← 第二层:用户间隔离
│ │ │ Python/TS 服务 │ │ │
│ │ └─────────────────────────┘ │ │
│ │ ┌─────────────────────────┐ │ │
│ │ │ 用户 B 的 Firejail │ │ │
│ │ │ Python/TS 服务 │ │ │
│ │ └─────────────────────────┘ │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
为什么不用 Docker 嵌套?
| 对比维度 | Firejail(我们选择) | Docker 嵌套 |
|---|---|---|
| 隔离粒度 | 进程级,适合单服务 | 容器级,过重 |
| 启动速度 | 毫秒级,服务可随时启停 | 秒级,每次拉起完整容器 |
| 资源开销 | 极低 | 每个服务一个容器,开销大 |
| 运维复杂度 | 无需管理镜像 | 需要打镜像、管版本、清缓存 |
核心逻辑:平台上每个用户的服务是单进程应用,我们只需要隔离这个进程就够了。Firejail 的进程级隔离完美匹配,且比 Docker 嵌套轻量得多。
双层隔离各司其职
- Docker:做“大边界”,把整个平台与宿主机隔开。即便沙箱被突破,攻击者还在容器内。
- Firejail:做“小边界”,在容器内部隔离不同用户的服务。保证进程隔离、依赖环境隔离、文件操作隔离。
四、平台的核心能力
能力一:多语言自动识别,零配置上手
平台同时支持 Python 和 TypeScript 两种主流 MCP 开发语言。用户上传代码后,平台自动判断语言类型,无需任何额外配置。
平台优势:开发者可以用自己熟悉的语言写 MCP 服务,平台负责识别和处理,体验完全一致。
能力二:双协议自动适配,调用方无感
MCP 支持 SSE(Server-Sent Events)和 StreamableHTTP 两种传输协议。平台在网关层自动识别服务使用的协议类型,并根据请求特征智能路由。
平台优势:开发者无需关心协议细节,调用方也无需区分——同一个网关 URL,自动适配两种协议,开箱即用。
能力三:依赖环境隔离,互不干扰
每个服务拥有独立的依赖环境:
- Python 服务:使用 venv 管理独立的包环境
- TypeScript 服务:使用独立的 node_modules 目录
平台优势:不同服务的依赖版本不会冲突,一个服务的依赖更新不会影响其他服务。同时,平台自动完成依赖安装,开发者只需提供 requirements.txt 或 package.json。
能力四:代码安全检测,防患于未然
每个上传的代码都会经过安全扫描,检测危险函数调用(如 eval、os.system)和敏感模块导入。
平台优势:在沙箱运行前就发现潜在风险,结合后续的隔离机制,形成“检测 + 隔离”双重防护。
能力五:统一网关,服务即 URL
每个服务启动后,平台自动分配一个统一的网关地址:
https://platform.example.com/mcp/{service_name}
网关负责:
- 协议自动适配(SSE / HTTP)
- 服务自动发现与路由
- 会话管理与流量分发
平台优势:开发者无需搭建网关、无需配置路由、无需处理协议细节。一个 URL 搞定所有调用,服务对调用方完全透明。
能力六:自动启停,资源高效利用
平台采用“按需启动”策略:
- 无请求时服务不常驻,零资源消耗
- 请求到来时自动启动服务
- 长时间无访问自动停止
平台优势:开发者不用担心服务器成本,平台自动优化资源利用率。对调用方来说,体验如同调用一个“永远在线”的服务。
五、安全隔离是怎么做到的?
这是平台最核心的部分。我们通过多层机制保证:
| 隔离维度 | 实现方式 |
|---|---|
| 进程隔离 | Firejail 为每个服务创建独立进程空间 |
| 依赖环境隔离 | Python 用 venv,TypeScript 用独立 node_modules |
| 文件系统隔离 | Firejail 白名单机制,只开放必要目录 |
| 资源限制 | CPU 60 秒、内存 2GB、进程数 1000 |
| 系统调用限制 | 禁止音频、视频、3D 等不必要的系统调用 |
| 平台级隔离 | Docker 将整个平台与宿主机隔离 |
效果:用户代码无法破坏平台环境,不同用户的代码不会互相干扰。即使一个服务被恶意控制,影响也被限制在它自己的 Firejail 沙箱内。
六、适用场景
这个平台特别适合:
-
MCP 工具市场
开发者上传自己的 MCP 工具,平台托管并提供服务,其他应用通过统一网关调用 -
团队内部 MCP 服务共享
不同团队用不同语言开发 MCP 服务,统一部署、统一管理、统一调用 -
AI Agent 服务托管
为 AI Agent 提供可调用的工具服务,保证安全隔离和资源管控 -
教学/实验环境
学生上传代码,平台自动运行,无需配置本地环境
七、结语:平台化思路决定技术选型
回顾这个 MCP 开发平台的搭建过程,最核心的决策不是“用什么技术”,而是**“平台需要什么能力”**:
- 需要支持多语言 → 自动识别 + 各自依赖管理
- 需要支持双协议 → 网关层自动适配
- 需要安全隔离 → Docker + Firejail 双层互补
- 需要零配置体验 → 自动启停 + 统一网关
技术选型服务于平台目标。Docker + Firejail 不是最“潮”的方案,但它精准匹配了我们对轻量、快速、隔离、易运维的综合需求。
目前这个平台已经在内部稳定运行,支撑了数十个 Python 和 TypeScript MCP 服务的托管。如果你也在做类似的 MCP 开发平台或服务托管方案,希望这篇文章能给你一些启发。
技术栈:Python 3.10+ | FastAPI | Firejail | Docker | Node.js
支持语言:Python、TypeScript
支持协议:SSE、StreamableHTTP
💬 互动话题:如果你要搭建一个代码托管运行平台,你会选择什么样的隔离方案?进程级隔离(Firejail/gVisor)还是容器级隔离(Docker/Kata)?欢迎在评论区分享!