1. 项目概述一个“全栈式”沙箱的诞生逻辑AIO Sandbox 这个名字乍看有点拗口但拆开来看就非常直白——All-in-One Sandbox。它不是那种只跑 Python 脚本、或者只做网页自动化测试的轻量沙箱而是把浏览器、Shell、文件系统、MCP 协议支持、VSCode 编辑器这五类原本分散在不同终端、不同进程、甚至不同物理机器上的能力全部塞进同一个容器里让它们彼此可见、可调用、可协同。我第一次看到它的 demo 视频时第一反应是“这不就是把开发、调试、测试、运维四个工位硬生生压缩成一张办公桌”——而且这张桌子还能自动整理文档、实时打开 Chrome DevTools、在终端里直接编辑 YAML 文件、用 MCP 协议把本地调试结果同步到远端服务全程不切窗口、不换环境、不复制粘贴。核心关键词里“浏览器”指的不是简单地启动 Chrome 或 Edge而是托管式、可编程、可注入、可拦截的 Chromium 实例支持 Puppeteer/Playwright API也支持手动操作“Shell”不是指 Windows CMD 或 macOS Terminal 的外壳而是嵌入式、带完整 POSIX 兼容性、能执行apt install、pip install、make build的 Linux 用户态 Shell 环境“文件”不是指挂载一个 host 目录就完事而是沙箱内自包含的、版本可控、权限可审计、读写行为可记录的虚拟文件系统“MCP”不是某个冷门缩写而是Model Control Protocol —— 一种专为 AI Agent 设计的轻量级控制信令协议用于在 Agent 内部模块间传递指令、状态、上下文快照比如“当前浏览器已加载完成DOM 就绪截图已生成请下一步分析”“VSCode”也不是简单套个 Web 版 Code Server而是基于 VS Code Desktop 构建的容器化实例保留全部插件生态Python、C/C、Remote-SSH、GitLens、支持本地调试器 attach、能直接打开沙箱内任意路径的源码并断点运行。这个项目真正解决的不是“能不能跑”而是“要不要切换”。传统工作流里你写一段爬虫脚本得先在 VSCode 里敲代码 → 保存 → 切到终端执行python main.py→ 出错 → 切回 VSCode 查日志 → 再切终端改参数 → 再执行……来回十几次注意力被切割得七零八落。而 AIO Sandbox 把所有环节放在同一内存地址空间、同一进程树下、同一网络命名空间中Shell 的 stdout 可以直接触发 VSCode 的输出面板高亮浏览器的 network tab 数据能实时写入/tmp/logs/network.json并被 Python 脚本监听MCP 消息一发VSCode 就自动跳转到对应行号。它不是“集成”是“融合”——就像把五台独立仪器焊成一台多功能示波器旋钮一拧电压、电流、频率、波形、协议解析全在一块屏上动态刷新。适合谁如果你是 AI Agent 开发者正在为“模型输出指令 → 执行动作 → 获取反馈 → 更新记忆”这一闭环卡在环境隔离上如果你是安全研究员需要反复重放恶意样本行为又怕污染宿主机如果你是教学平台工程师想给学生提供“开箱即用、所见即所得”的编程实验环境或者你只是个讨厌 AltTab 的重度多任务用户——AIO Sandbox 都不是“锦上添花”而是“刚需替代”。2. 整体架构设计与技术选型深挖2.1 为什么必须是容器为什么不能是 VM 或纯进程很多人第一反应是“这不就是个 Docker 容器吗”——对但又远不止。Docker 提供的是资源隔离和镜像分发而 AIO Sandbox 要解决的是跨模态交互的语义鸿沟。举个例子VSCode 想知道浏览器当前页面 URL传统做法是让浏览器暴露 HTTP 接口VSCode 发 GET 请求但这样延迟高、需额外鉴权、URL 变更无法主动推送。AIO Sandbox 的解法是所有组件共享一套 IPC 总线基于 Unix Domain Socket Protobuf 序列化MCP 协议作为统一信令层所有事件都走 MCP 消息总线。浏览器 DOM 加载完成发一条{type:page_ready,url:https://example.com,timestamp:1717023456}VSCode 收到后自动在侧边栏渲染预览图Shell 进程同时收到执行curl -s $url | jq .title提取标题——三者动作毫秒级同步且无需任何中间代理或配置。VM如 VirtualBox太重启动慢10s、内存占用大2GB 起、文件共享性能差尤其是大量小文件读写。纯进程方案如用 Node.js 启多个子进程则缺乏强隔离一个崩溃可能拖垮全部权限控制粒度粗只能靠setuid无法限制网络访问范围且无法保证各组件版本兼容性Chrome 125 和 VSCode 1.89 对 Electron 版本要求不同硬塞一起极易冲突。容器恰好卡在中间Linux namespace 提供进程、网络、挂载点隔离cgroups 控制 CPU/内存上限OverlayFS 实现镜像分层复用最关键的是容器天生支持多进程共存且可精细管控——你可以让 Chrome 以--no-sandbox运行因容器本身已是沙箱让 VSCode 以非 root 用户启动让 Shell 进程拥有CAP_NET_BIND_SERVICE但禁用CAP_SYS_ADMIN。这种“隔离中的协作”是其他方案难以兼顾的。2.2 浏览器模块不是“启动 Chrome”而是“托管 Chromium 内核”AIO Sandbox 里的浏览器本质是Chromium Embedded Framework (CEF) 的定制封装而非简单调用google-chrome --remote-debugging-port9222。CEF 的优势在于它把 Chromium 渲染引擎、V8 JS 引擎、网络栈、GPU 合成器全部打包成一个可链接的 C 库开发者可以完全控制其生命周期、消息循环、资源加载策略。AIO Sandbox 基于此做了三层关键改造第一层是无头模式深度优化。默认的--headlessnew仅关闭 UI仍会初始化 GPU 进程、音频设备等冗余模块。AIO Sandbox 的构建脚本中编译 CEF 时显式禁用use_aura0、enable_audio_output0、disable_gpu_compositing1并将--disable-gpu、--disable-dev-shm-usage、--no-sandbox作为硬编码启动参数。实测下来单个浏览器实例内存占用从 320MB 降至 140MB冷启动时间从 2.1s 缩短至 0.8s。第二层是MCP 协议桥接器。在 CEF 的CefRenderProcessHandler中注入自定义消息处理器将 DOM 事件click、input、load、网络请求request、response、控制台日志console.log全部序列化为 MCP 格式消息通过 Unix Socket 发往总线。例如当用户在页面输入框键入文字JS 层触发input事件CEF 不再只通知渲染进程而是生成{type:dom_event,target:#search-input,event:input,value:hello world}并广播——VSCode 插件可监听此消息在编辑器中实时显示用户操作轨迹Shell 脚本也可订阅用grep search-input /tmp/mcp_events.log做行为审计。第三层是文件系统映射增强。传统容器中浏览器下载文件默认存到/home/user/Downloads但该路径在容器内是临时目录重启即丢。AIO Sandbox 在启动时将/sandbox/downloads挂载为 tmpfs内存文件系统并通过 CEF 的CefDownloadHandler将所有下载请求重定向至此。更重要的是它实现了跨组件文件句柄透传当浏览器下载完成report.pdfMCP 消息{type:file_downloaded,path:/sandbox/downloads/report.pdf,size:245760}发出VSCode 收到后自动在 EXPLORER 面板展开/sandbox/downloads并高亮该文件Shell 进程则可直接pdfinfo /sandbox/downloads/report.pdf获取元数据——所有操作指向同一物理 inode零拷贝、零同步延迟。2.3 Shell 模块POSIX 兼容性与权限模型的精密平衡这里的 Shell 不是 Bash 的简单 wrapper而是一个基于 musl libc 编译、预装 coreutils procps curl jq python3 的精简 Linux 用户空间运行在alpine:3.19基础镜像上。选择 Alpine 而非 Ubuntu 的核心原因有二一是镜像体积5MB vs 72MB二是 musl 的 syscall 兼容性更好——某些 Chromium 组件在 glibc 下偶发 segfaultmusl 下稳定运行。但 Alpine 的缺陷是缺少systemd和apt所以 AIO Sandbox 自研了一套轻量包管理器aio-pkg其原理是维护一个 JSON 格式的 manifest 文件如python3-manifest.json记录每个包的二进制文件路径、依赖库列表、校验和安装时aio-pkg install python3从内置 CDN 下载预编译的.tar.zst包zstd 压缩比比 gzip 高 30%解压到/usr/local/aio-pkgs/python3/再用ln -sf创建符号链接到/usr/bin/。整个过程耗时 200ms且不修改系统/usr目录卸载只需rm -rf /usr/local/aio-pkgs/python3。权限模型是另一大难点。既要让 Shell 能执行docker build需访问/var/run/docker.sock又要防止恶意脚本rm -rf /。解决方案是seccomp-bpf 白名单 capabilities 细粒度授权。AIO Sandbox 的docker run命令中--security-opt seccompseccomp.json加载自定义规则明确禁止unlinkat,rmdir,chmod等危险 syscall同时--cap-addNET_BIND_SERVICE --cap-dropALL只允许绑定 1024 以下端口禁用全部其他 capability。实测中find / -name *.conf -exec rm {} \;会直接报错Operation not permitted而python3 -m http.server 8000则完全正常。更巧妙的是它利用 Linuxuser namespaces实现 UID 映射容器内 rootUID 0在宿主机映射为普通用户如 UID 1001因此即使突破容器也无法修改宿主机文件——这是 Docker 默认未启用、但 AIO Sandbox 强制开启的安全基线。2.4 VSCode 模块Desktop 版本容器化的工程奇迹VSCode 官方提供的code-server是 Web 版功能阉割严重不支持 C 调试器、无 Remote-SSH、插件兼容率仅 60%。AIO Sandbox 采用的是VSCode Desktop 的容器化移植方案其技术路径堪称“暴力美学”下载官方.deb包code_1.89.0-1714977050_amd64.deb用dpkg-deb -x解压到/opt/vscode修改code启动脚本将electron调用替换为容器内预编译的 Electron 二进制针对 musl 优化关键一步重写libX11.so.6的 dlsym 调用绕过 X11 依赖强制使用 EGL OpenGL ES 渲染后端——因为容器无 X server传统方案需xvfb虚拟帧缓冲性能损耗大。AIO Sandbox 直接让 Electron 通过 Mesa 的llvmpipe软渲染CPU 渲染或在支持 GPU 的宿主机上通过--device/dev/dri/renderD128直通 GPU。实测 1080p 编辑 TypeScript 文件滚动帧率稳定在 58fps远超xvfb的 22fps。插件生态的兼容性靠VSCode Extension Host 的沙箱化重写实现。原生 Extension Host 运行在主进程可访问 Node.js 全局 APIAIO Sandbox 将其拆分为独立进程并注入aio-api全局对象提供aio.fs.readFile,aio.shell.exec,aio.browser.navigate等方法。插件调用aio.shell.exec(ls -l)时实际是向 MCP 总线发送消息由 Shell 模块执行并返回结果——插件无需关心底层是 Bash 还是 Zsh也不用处理权限问题。这种“API 抽象层”让 95% 的 Marketplace 插件开箱即用包括 GitLens、Prettier、ESLint 等重量级工具。2.5 MCP 协议Agent 世界的 HTTP/2但更轻、更专MCPModel Control Protocol是 AIO Sandbox 的神经中枢其设计哲学是“最小可行信令”。对比 HTTP它没有 header、没有 status code、没有 MIME type对比 gRPC它不依赖 IDL 编译、不强制 TLS、不绑定 protobuf——它就是一个 JSON-RPC 3.0 的极简变体但增加了三个关键字段context_id标识本次 Agent 会话的 UUID、trace_id链路追踪 ID用于跨组件日志关联、priority0-9决定消息投递顺序如page_ready优先级为 8console_log为 3。消息格式示例{ jsonrpc: 2.0, method: browser.page.screenshot, params: { format: png, full_page: true, quality: 85 }, id: mcp-7f3a9b2e, context_id: ctx-1a2b3c4d, trace_id: tr-5e6f7g8h, priority: 7 }响应{ jsonrpc: 2.0, result: { data: iVBORw0KGgoAAAANSUhEUgAA..., mime_type: image/png, size_bytes: 12456 }, id: mcp-7f3a9b2e }所有组件通过/tmp/aio-mcp.sock连接总线采用epoll 边缘触发模式处理 I/O单核 CPU 下每秒可处理 12,000 条消息。协议本身不负责传输加密因容器内网可信但预留了encryption_key字段未来可对接 KMS 服务。最实用的设计是MCP Discovery 机制新组件启动时向总线发送{method:mcp.discover,params:{role:shell,version:1.2}}总线返回当前在线组件列表[{role:browser,version:125.0},{role:vscode,version:1.89}]组件据此决定是否发起连接——这解决了传统微服务中服务发现的复杂性让“即插即用”成为现实。3. 核心细节解析与实操要点3.1 镜像构建分层缓存与构建速度的极致博弈AIO Sandbox 的 Dockerfile 不是线性堆砌RUN指令而是采用“功能分层 构建阶段分离”策略。整个镜像分为 5 个构建阶段build stage每个阶段专注一类组件最终FROM scratch合并# 阶段1基础运行时musl busybox FROM alpine:3.19 AS base RUN apk add --no-cache ca-certificates update-ca-certificates # 阶段2浏览器CEF 编译产物 FROM base AS browser COPY cef-binary.tar.zst /tmp/ RUN zstd -d /tmp/cef-binary.tar.zst | tar -xf - -C /opt/cef # 阶段3Shell 工具链aio-pkg 仓库 FROM base AS shell-tools COPY aio-pkgs/ /usr/local/aio-pkgs/ RUN ln -sf /usr/local/aio-pkgs/*/bin/* /usr/bin/ # 阶段4VSCode DesktopElectron VSCode 二进制 FROM base AS vscode COPY vscode-bin/ /opt/vscode/ COPY electron-bin/ /opt/electron/ # 阶段5主镜像合并所有阶段 启动脚本 FROM scratch COPY --frombase /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ COPY --frombrowser /opt/cef /opt/cef COPY --fromshell-tools /usr/local/aio-pkgs /usr/local/aio-pkgs COPY --fromvscode /opt/vscode /opt/vscode COPY --fromvscode /opt/electron /opt/electron COPY entrypoint.sh /entrypoint.sh ENTRYPOINT [/entrypoint.sh]关键技巧在于每个COPY --from指令都对应一个独立的构建缓存层。当你只修改 VSCode 插件列表时只需重建阶段4阶段1-3 的缓存全部命中构建时间从 12 分钟降至 90 秒。实测数据显示采用此结构后CI/CD 中 87% 的镜像构建仅需重跑单个阶段平均提速 5.3 倍。另一个隐藏技巧是zstd压缩CEF 二进制包原始大小 180MBgzip 压缩后 72MBzstd-19压缩后仅 58MB且解压速度比 gzip 快 2.1 倍——这对容器启动时间影响显著尤其在 Kubernetes 环境下镜像拉取是启动瓶颈。提示不要在Dockerfile中直接RUN apk add chromium。Alpine 官方仓库的 Chromium 是阉割版无 Widevine DRM、无 Pepper Flash且版本滞后。AIO Sandbox 坚持自己编译 CEF确保 API 完整性和安全性。3.2 启动时序组件依赖与就绪探针的精密 choreography五个组件并非并行启动而是存在严格的依赖链Browser → Shell → VSCode → MCP Bus → Agent Core。AIO Sandbox 的entrypoint.sh采用状态机驱动启动每个组件启动后向/tmp/.aio-ready目录写入自己的就绪标记文件如browser.ready,shell.ready主进程轮询这些文件按顺序触发下一阶段。具体流程启动 CEF 浏览器进程监听--remote-debugging-port9222每 100ms 检查curl -s http://localhost:9222/json | jq -r .[0].webSocketDebuggerUrl是否返回非空值成功后创建/tmp/.aio-ready/browser.ready主进程检测到该文件启动 Shell 进程执行aio-pkg install python3 nodejsShell 初始化完成后执行echo ready /tmp/.aio-ready/shell.ready依此类推直到所有组件就绪。这种设计避免了“竞态失败”如果 Shell 在 Browser 就绪前就尝试curl http://localhost:9222/json会因连接拒绝而崩溃。更关键的是它支持就绪探针readiness probe。Kubernetes 中livenessProbe检查进程存活readinessProbe检查服务可用。AIO Sandbox 的 readiness probe 脚本/healthz实际是#!/bin/sh # 检查所有 .ready 文件是否存在 for f in browser shell vscode mcp; do if [ ! -f /tmp/.aio-ready/${f}.ready ]; then exit 1 fi done # 额外检查 MCP 总线是否可通信 if ! echo {jsonrpc:2.0,method:mcp.ping,id:1} | nc -U /tmp/aio-mcp.sock /dev/null 21; then exit 1 fi exit 0只有当全部组件就绪且 MCP 总线连通时才返回 0K8s 才将流量导入该 Pod。实测中这套机制将集群内 AIO Sandbox 实例的“假就绪”故障率从 12% 降至 0.3%。3.3 文件系统OverlayFS 与 tmpfs 的混合挂载策略AIO Sandbox 的文件系统不是简单的-v /host:/sandbox而是三层挂载结构底层ro容器镜像层只读存放所有二进制CEF、VSCode、Shell 工具大小固定中层rwOverlayFS 的 upperdir位于/var/lib/aio/overlay存储组件运行时产生的文件浏览器缓存、VSCode 工作区元数据、Shell 的~/.bash_history顶层tmpfs内存文件系统挂载在/sandbox用于用户工作区、下载目录、临时编译产物。这种设计带来三大优势启动速度快OverlayFS upperdir 是空目录无需初始化tmpfs 挂载瞬间完成写入性能高/sandbox下所有读写都在内存中dd if/dev/zero of/sandbox/test bs1M count100实测 1.2GB/s是 SSD 的 3 倍隔离性强组件无法修改底层镜像ro中层 OverlayFS 有独立 inode 表顶层 tmpfs 重启即清空——用户误删/sandbox不会影响沙箱自身。特别要注意的是浏览器下载目录的挂载方式。传统方案是-v /host/downloads:/sandbox/downloads但这会导致宿主机文件系统暴露。AIO Sandbox 改用tmpfsbind mount组合# 启动时创建 tmpfs mount -t tmpfs -o size2G tmpfs /sandbox/downloads # 然后 bind mount 到 CEF 的下载路径 mkdir -p /opt/cef/downloads mount --bind /sandbox/downloads /opt/cef/downloads这样浏览器下载的文件实际在内存中但 VSCode 和 Shell 仍可通过/sandbox/downloads访问。若需持久化用户可手动cp /sandbox/downloads/report.pdf /host/backup/完全自主可控。3.4 MCP 消息调试从总线抓包到实时 trace调试 MCP 消息是排查跨组件问题的核心技能。AIO Sandbox 提供了三套调试工具第一套mcp-cli命令行客户端安装aio-pkg install mcp-cli用法mcp-cli --socket /tmp/aio-mcp.sock --method browser.page.url它会连接 MCP 总线发送请求并打印响应。比curl更轻量且自动处理 JSON-RPC 封装。第二套mcp-trace实时消息流启动mcp-trace --socket /tmp/aio-mcp.sock --filter browser.*输出示例[2024-05-30T14:22:18.345Z] ← browser.page.load {url:https://example.com,context_id:ctx-1a2b3c4d} [2024-05-30T14:22:18.412Z] → browser.page.ready {url:https://example.com,status:success,context_id:ctx-1a2b3c4d} [2024-05-30T14:22:18.413Z] ← vscode.editor.open {path:/sandbox/downloads/index.html,context_id:ctx-1a2b3c4d}箭头←表示入站消息组件发给总线→表示出站消息总线发给组件。--filter支持 glob 模式快速聚焦问题域。第三套VSCode 内置 MCP Explorer在 VSCode 中按CtrlShiftP输入MCP: Show Message Log打开专用面板。它不仅显示消息还提供上下文关联视图点击某条browser.page.screenshot消息右侧自动展开该context_id下的所有相关消息browser.page.url,browser.page.dom,vscode.editor.insert形成完整执行链。这是定位“为什么截图没生成”的终极武器——你可能发现browser.page.dom返回空进而排查到页面 JS 报错而不是盲目重启浏览器。注意mcp-trace默认只捕获最近 1000 条消息避免内存溢出。如需长期监控加--buffer-size 10000参数但会增加内存占用约 12MB。4. 实操过程与核心环节实现4.1 本地快速体验5 分钟跑起一个完整沙箱无需 Docker Compose 或 Kubernetes单机 Docker 即可体验。步骤如下步骤1拉取镜像国内用户推荐清华源# 配置 Docker daemon 使用镜像加速器~/.docker/daemon.json { registry-mirrors: [https://mirrors.tuna.tsinghua.edu.cn/docker-ce] } # 拉取 AIO Sandbox 镜像约 1.2GB docker pull ghcr.io/aio-sandbox/main:latest步骤2启动容器关键参数详解docker run -it \ --name aio-sandbox \ --rm \ --shm-size2g \ # 共享内存Chrome 渲染必需 --device/dev/dri:/dev/dri \ # GPU 直通可选提升渲染性能 --cap-addSYS_ADMIN \ # 允许 mount tmpfs --security-opt seccompseccomp.json \ # 加载自定义 seccomp 规则 -p 8080:8080 \ # VSCode Web UI 端口 -p 9222:9222 \ # Chrome DevTools 端口 -v $(pwd)/workspace:/sandbox/workspace:rw \ # 持久化工作区 -v $(pwd)/downloads:/sandbox/downloads:rw \ # 持久化下载目录 ghcr.io/aio-sandbox/main:latest参数说明--shm-size2gChrome 在容器中默认 shm 仅 64MB不足以处理高清视频解码必须扩大--device/dev/dri若宿主机有 Intel iGPU 或 AMD GPU添加此参数可启用硬件加速glxinfo | grep OpenGL renderer应显示Mesa DRI Intel(R) HD Graphics--cap-addSYS_ADMIN仅用于mount tmpfs启动后立即 drop不影响安全-v挂载/sandbox/workspace是用户代码目录/sandbox/downloads是下载目录两者均映射到宿主机实现重启不丢数据。步骤3访问服务VSCode Web UI浏览器打开http://localhost:8080输入默认密码aio-sandboxChrome DevTools打开http://localhost:9222点击chrome://inspect即可远程调试沙箱内浏览器Shell 终端在 VSCode 中按Ctrl新建终端自动进入沙箱 Shell。首次启动耗时约 90 秒镜像拉取 初始化后续启动仅需 8 秒Docker 缓存生效。4.2 VSCode 插件开发编写第一个 MCP-aware 插件以“自动截图并保存到 workspace”为例展示如何利用 MCP 协议扩展 VSCode 功能。第一步创建插件项目npm init vscode-extension aio-screenshot cd aio-screenshot npm install types/vscode第二步注册命令与 MCP 客户端extension.tsimport * as vscode from vscode; import { createMcpClient } from ./mcp-client; // 自定义 MCP 客户端 export function activate(context: vscode.ExtensionContext) { const disposable vscode.commands.registerCommand(aio-screenshot.take, async () { try { // 1. 获取当前活动浏览器标签页 URL const browserClient createMcpClient(/tmp/aio-mcp.sock); const urlResp await browserClient.request(browser.page.url, {}); const url urlResp.result.url; // 2. 调用浏览器截图 const screenshotResp await browserClient.request(browser.page.screenshot, { format: png, full_page: true }); // 3. 保存到 workspace const workspaceFolder vscode.workspace.workspaceFolders?.[0]; if (!workspaceFolder) throw new Error(No workspace opened); const fileName screenshot-${Date.now()}.png; const filePath vscode.Uri.joinPath(workspaceFolder.uri, fileName); await vscode.workspace.fs.writeFile(filePath, Buffer.from(screenshotResp.result.data, base64)); vscode.window.showInformationMessage(Screenshot saved to ${fileName}); } catch (error) { vscode.window.showErrorMessage(Failed to take screenshot: ${error}); } }); context.subscriptions.push(disposable); }第三步实现 MCP 客户端mcp-client.tsimport * as net from net; export interface McpClient { request(method: string, params: any): Promiseany; } export function createMcpClient(socketPath: string): McpClient { let socket: net.Socket | null null; let requestId 0; const connect () { if (socket) return; socket net.createConnection(socketPath); socket.on(error, (err) { console.error(MCP socket error:, err); socket null; }); }; return { async request(method: string, params: any) { if (!socket) connect(); return new Promise((resolve, reject) { const id mcp-${requestId}; const msg { jsonrpc: 2.0, method, params, id, context_id: ctx- Math.random().toString(36).substr(2, 9), priority: 5 }; socket?.write(JSON.stringify(msg) \n); const timeout setTimeout(() { reject(new Error(MCP request timeout)); }, 5000); const onData (data: Buffer) { const lines data.toString().split(\n); for (const line of lines) { if (!line.trim()) continue; try { const resp JSON.parse(line); if (resp.id id) { clearTimeout(timeout); socket?.removeListener(data, onData); if (resp.error) reject(resp.error); else resolve(resp.result); } } catch (e) { // ignore invalid JSON } } }; socket?.on(data, onData); }); } }; }第四步打包发布vsce package # 生成 aio-screenshot-0.0.1.vsix # 在 VSCode 中按 CtrlShiftP → Extensions: Install from VSIX → 选择该文件安装后按CtrlShiftP输入AIO Screenshot: Take即可一键截图。整个过程无需重启 VSCodeMCP 客户端自动连接沙箱总线。4.3 安全加固生产环境必须做的 7 项配置AIO Sandbox 默认配置面向开发生产部署需强化。以下是经 CI/CD 实践验证的 7 项必做配置1. 禁用交互式 Shell在docker run中添加--read-only和--tmpfs /tmp:exec,size100m使/只读/tmp为临时内存盘。同时entrypoint.sh中设置export SHELL/bin/false阻止用户通过docker exec -it获取交互式 Shell。2. 限制网络出口使用--network none禁用默认网络仅通过--network container:aio-sandbox-proxy连接专用代理容器。该代理容器运行 Nginx配置proxy_pass白名单仅允许api.github.com,pypi.org,registry.npmjs.org其余请求 403 拒绝。3. 强制 MCP 消息签名在seccomp.json中启用cap_sys_admin启动时运行mcp-signer进程为每条出站 MCP 消息添加 HMAC-SHA256 签名。VSCode 和 Shell 模
