WebContainer MCP传输

WebContainer MCP传输是一种在浏览器中运行MCP服务器的技术,支持文件模式和生成模式,适用于客户端MCP应用开发。

  • by ahmedrowaihi
  • TypeScript
  • 本地部署
  • 9 星标
  • 更新于
在 GitHub 查看 ahmedrowaihi/webcontainer-mcp-transport

使用说明

网络集装箱MCP运输

此目录包含模型上下文协议(MCP)的非官方WebContainer传输实现。此传输允许您在浏览器中的WebContainer环境中运行MCP服务器。

🚀 完整示例:通过交互式仪表板查看完整的工作实施,网址为 网络容器mcp浏览器

概述

这 WebContainerTransport 类实现了MCP Transport 接口,提供了一种使用WebContainer技术直接在浏览器中运行Node.js MCP服务器的方法。这使得客户端MCP应用程序无需单独的服务器进程。

运输支持两种模式:

  1. 基于文件:装载自定义文件并运行自己的MCP服务器代码
  2. 基于Spawn:通过命令(例如npx包)运行现有的MCP服务器

重要提示:等待“运行”状态

⚠️ 关键的:您必须等待状态变为 "running" 在发送任何工具请求或列出工具之前。过早发送请求会导致错误。

安装(类型安全可选)

npm install @modelcontextprotocol/sdk @webcontainer/api

简单的例子

import { WebContainerTransport } from "./webcontainer-transport";

async function runMCPServer() {
  const transport = new WebContainerTransport({
    type: "files",
    files: {
      "index.js": `
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({ name: "Demo Server", version: "1.0.0" });

server.tool("echo", { message: z.string() }, async ({ message }) => ({
  content: [{ type: "text", text: message }],
}));

server.tool("add", { a: z.number(), b: z.number() }, async ({ a, b }) => ({
  content: [{ type: "text", text: String(a + b) }],
}));

const transport = new StdioServerTransport();
await server.connect(transport);
      `,
      "package.json": JSON.stringify({
        name: "webcontainer-mcp-server",
        version: "1.0.0",
        type: "module",
        dependencies: {
          "@modelcontextprotocol/sdk": "latest",
          zod: "latest",
        },
      }),
    },
    onStatusChange: (status) => {
      console.log("Status:", status);
      if (status === "running") {
        console.log("✅ Server ready - you can now send requests!");
      }
    },
  });

  // Handle responses
  transport.onmessage = (message) => {
    if ("result" in message) {
      console.log("Response:", message.result);
    } else if ("error" in message) {
      console.log("Error:", message.error);
    }
  };

  transport.onerror = (error) => {
    console.error("Transport error:", error);
  };

  // Start the server
  await transport.start();

  // Wait for server to be ready
  await new Promise((resolve) => {
    const checkStatus = () => {
      if (transport._initialized) {
        // Or listen to onStatusChange for "running"
        resolve();
      } else {
        setTimeout(checkStatus, 100);
      }
    };
    checkStatus();
  });

  // Now it's safe to send requests
  console.log("📤 Listing tools...");
  await transport.send({
    jsonrpc: "2.0",
    id: 1,
    method: "tools/list",
    params: {},
  });

  // Call a tool
  console.log("📤 Calling add tool...");
  await transport.send({
    jsonrpc: "2.0",
    id: 2,
    method: "tools/call",
    params: {
      name: "add",
      arguments: { a: 5, b: 3 },
    },
  });

  // Cleanup after some time
  setTimeout(() => {
    transport.close();
  }, 5000);
}

// Run the example
runMCPServer();

api参考

网络集装箱运输

构造函数

new WebContainerTransport(options: WebContainerTransportOptions)

基于文件的选项

{
  type: "files";
  files: Record<string, string>;        // filename -> content mapping
  entrypoint?: string;                  // defaults to "index.js"
  onStatusChange?: (status) => void;    // status callback
  bootOptions?: BootOptions;            // WebContainer boot options
}

基于产卵的选项

{
  type: "spawn";
  command: string;                      // e.g., "npx"
  args: string[];                       // e.g., ["-y", "@modelcontextprotocol/server-filesystem"]
  env?: Record<string, string>;         // environment variables
  onStatusChange?: (status) => void;    // status callback
  bootOptions?: BootOptions;            // WebContainer boot options
}

方法

  • start():初始化并启动服务器
  • send(message):发送JSON-RPC消息(仅在状态为“正在运行”后)
  • close():停止服务器并清理

状态值

  • "booting":WebContainer正在启动
  • "mounting":装载文件(仅基于文件)
  • "installing":安装依赖项(仅基于文件)
  • "running":服务器已准备好接收请求✅
  • "unmounting":卸载文件(仅基于文件)
  • "teardowned":WebContainer被拆除

多文件支持

您可以提供无限的文件:

const transport = new WebContainerTransport({
  type: "files",
  files: {
    "package.json": "...",
    "server.js": "...",
    "tools/math.js": "...",
    "tools/string.js": "...",
    "lib/utils.js": "...",
    "README.md": "...",
  },
  entrypoint: "server.js",
});

基于Spawn的示例

const transport = new WebContainerTransport({
  type: "spawn",
  command: "npx",
  args: ["-y", "@modelcontextprotocol/server-everything"],
  env: {
    NODE_ENV: "development",
  },
  onStatusChange: (status) => console.log("Status:", status),
});

浏览器兼容性

需要支持WebContainer的现代浏览器(建议使用Chrome、Edge)。

浏览器要求

要使用WebContainer,您的应用程序必须提供具有以下HTTP标头的页面:

  "Cross-Origin-Opener-Policy": "same-origin",
  "Cross-Origin-Embedder-Policy": "require-corp"