手搓一个 MCP 开发平台:让用户上传代码即获得安全服务

6 阅读7分钟

最近团队在折腾 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:做“小边界”,在容器内部隔离不同用户的服务。保证进程隔离、依赖环境隔离、文件操作隔离。

四、平台的核心能力

能力一:多语言自动识别,零配置上手

平台同时支持 PythonTypeScript 两种主流 MCP 开发语言。用户上传代码后,平台自动判断语言类型,无需任何额外配置。

平台优势:开发者可以用自己熟悉的语言写 MCP 服务,平台负责识别和处理,体验完全一致。


能力二:双协议自动适配,调用方无感

MCP 支持 SSE(Server-Sent Events)和 StreamableHTTP 两种传输协议。平台在网关层自动识别服务使用的协议类型,并根据请求特征智能路由。

平台优势:开发者无需关心协议细节,调用方也无需区分——同一个网关 URL,自动适配两种协议,开箱即用。


能力三:依赖环境隔离,互不干扰

每个服务拥有独立的依赖环境:

  • Python 服务:使用 venv 管理独立的包环境
  • TypeScript 服务:使用独立的 node_modules 目录

平台优势:不同服务的依赖版本不会冲突,一个服务的依赖更新不会影响其他服务。同时,平台自动完成依赖安装,开发者只需提供 requirements.txtpackage.json


能力四:代码安全检测,防患于未然

每个上传的代码都会经过安全扫描,检测危险函数调用(如 evalos.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 沙箱内。


六、适用场景

这个平台特别适合:

  1. MCP 工具市场
    开发者上传自己的 MCP 工具,平台托管并提供服务,其他应用通过统一网关调用

  2. 团队内部 MCP 服务共享
    不同团队用不同语言开发 MCP 服务,统一部署、统一管理、统一调用

  3. AI Agent 服务托管
    为 AI Agent 提供可调用的工具服务,保证安全隔离和资源管控

  4. 教学/实验环境
    学生上传代码,平台自动运行,无需配置本地环境


七、结语:平台化思路决定技术选型

回顾这个 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)?欢迎在评论区分享!