MCP浏览器探索
A. 发人深省的探索 在浏览器中运行模型上下文协议(MCP),挑战关于浏览器限制的假设,并研究弥合浏览器环境和MCP服务器之间差距的多种方法。
概述
本项目探讨了一个基本问题: MCP服务器可以在浏览器中运行吗?
最初的假设是这是不可能的,因为MCP服务器通过stdio(stdin/stdout)进行通信,浏览器无法生成子进程或直接访问stdio。然而,这一探索表明 答案比最初想象的更微妙、更有趣.
通过研究不同的架构方法,我们发现:
- 远程MCP服务器可以在浏览器中运行 使用官方的Streamable HTTP传输
- 浏览器原生工具 可以提供类似MCP的功能,而无需外部依赖
- 浏览器安全模型 实际上启用而不是阻止某些MCP实现
架构方法
1.远程MCP服务器方法(/remote/) ⭐ 推荐
概念:使用官方网站连接到远程MCP服务器 可流式HTTP传输.
Browser MCP Client ←→ HTTP/SSE ←→ Remote MCP Server文件:
remote/index.html-具有流式HTTP传输的浏览器MCP客户端remote/README.md-远程MCP方法文件
运作原理:
- 浏览器客户端向远程MCP服务器发出HTTP POST请求
- 服务器以JSON响应或启动SSE流
- 会话管理通过
Mcp-Session-Id头球 - 通过以下方式进行协议版本控制
MCP-Protocol-Version头球 - 通过服务器发送事件进行实时更新
优点:
- 纯浏览器解决方案 -无需外部流程
- MCP官方规范 -使用标准流式HTTP传输
- 生产就绪 -专为web部署而设计
- 实时通信 -SSE用于服务器发起的消息
- 会话持续 -跨请求维护状态
- 适用于任何远程MCP服务器 -Python、Node.js等。
缺点:
- 需要支持HTTP传输的远程MCP服务器
- 取决于互联网连接
- CORS策略可能需要配置
2.WebSocket代理方法(/proxy/)
概念:桥接WebSocket的Node.js代理↔ stdio通信。
Browser MCP Client ←→ WebSocket ←→ Node.js Proxy ←→ stdio ←→ MCP Server文件:
proxy/index.html-带WebSocket通信的浏览器MCP客户端proxy/index.js-Node.js代理服务器(实现不完整)
运作原理:
- 浏览器客户端连接到WebSocket代理
- 代理将MCP服务器作为子进程生成
- 代理桥接WebSocket消息↔ 标准输入输出
- MCP协议流经网桥
优点:
- 可以运行任何MCP服务器(Python、Node.js等)
- 正确的MCP协议生命周期
- 稳健的错误处理
缺点:
- 需要外部Node.js进程
- 不适合纯浏览器部署
3.Web Worker+WASM方法(/worker/)
概念:使用WebAssembly和WASI stdio仿真直接执行浏览器。
Browser MCP Client ←→ Web Worker ←→ WASM Module (with WASI stdio emulation)文件:
worker/index.html-使用Web Workers的浏览器MCP客户端worker/mcp-worker.js-带有WASI stdio仿真的Web Worker
运作原理:
- Web Worker加载WASM模块
- WASI stdio函数在JavaScript中模拟
- MCP协议流经虚拟stdio
- 无需外部流程
优点:
- 纯浏览器解决方案
- 无服务器依赖关系
- WASI stdio仿真很聪明
缺点:
- 需要与WASM兼容的MCP服务器(罕见)
- 仅限于基于WASM的工具
关键见解和发人深省的发现
最初的假设是错误的
探索始于以下假设: MCP服务器无法在浏览器中运行 由于stdio通信要求。然而,这项调查显示 MCP规范实际上提供了多种传输机制,包括一个专门为网络环境设计的。
MCP只是JSON-RPC 2.0
关键的认识: MCP只是不同传输方式下的JSON-RPC 2.0这意味着:
- 无需实施复杂的协议
- 标准JSON-RPC请求/响应模式
- MCP生命周期:
initialize→initialized→ 运营→shutdown - 与交通无关的设计 支持多种实施方法
浏览器限制与机会
传统限制:
- 无法生成子进程(
spawn(),exec()) - 无法直接访问stdio
- 无法运行任意服务器进程
- 无法进行系统级调用
但浏览器允许:
- HTTP通信 使用远程服务器
- WebSocket连接 用于实时通信
- Web工作人员 用于背景处理
- WebAssembly 接近原生性能
- 丰富的API 用于设备访问、存储等
重新审视根本问题
MCP服务器可以在浏览器中运行吗? 答案取决于我们如何定义“run”:
- 本地MCP服务器:由于stdio要求,无法直接运行
- 远程MCP服务器: 可以运行 使用流式HTTP传输
- 浏览器原生MCP类工具: 可以运行 使用浏览器API
- 基于WASM的MCP服务器: 可以跑了 如果专门为WASM编译
替代方案:浏览器原生工具
由于真正的MCP服务器不能在浏览器中运行,因此另一种选择是实现 浏览器原生工具 即:
- 仅使用浏览器API
- 实施类似MCP的协议
- 提供有限但有用的功能
全面的浏览器工具
这 browser-tools.json 文件包含 150多种浏览器原生工具 分为20类:
- 网络:fetch、WebSocket、CORS、beacon
- 存储:本地存储、会话存储、IndexedDB、Cookie、缓存
- 设备:地理位置、方向、电池、屏幕、剪贴板、振动
- 媒体:文件处理、图像处理、音频/视频录制、二维码扫描
- 浏览器:DOM查询、历史记录、下载、打印、全屏
- 加密:哈希、加密、密钥生成、签名
- 效用:base64、URL编码、JSON、正则表达式、日期格式
- 沟通:通知、共享、语音合成/识别
- 演出:指标、内存、网络信息、时间
- 工人:Web Workers、SharedArrayBuffer、服务Workers
- WASM:编译、实例化、WASI操作
- 图形:WebGL、二维画布、WebGPU、OffscreenCanvas
- 实时通信:对等连接、数据通道、屏幕共享
- 支付:付款请求、Apple Pay、Google Pay
- 文件系统:文件系统访问API,文件/目录选取器
- 蓝牙:蓝牙扫描、USB设备、串行端口、HID
- 高级:Web锁、流、Web组件、观察器
- 输入:游戏手柄、触摸、指针、键盘事件
- 磷钨酸:后台同步、推送通知、定期同步
- 实验性:网络传输、网络编解码器、网络NFC、WebAuthn
实施示例
浏览器MCP客户端
class BrowserMCPClient {
async initialize() {
const response = await this.sendRequest({
jsonrpc: '2.0',
id: 1,
method: 'initialize',
params: {
protocolVersion: '2025-06-18',
capabilities: {
roots: { listChanged: true },
sampling: {},
elicitation: {}
},
clientInfo: {
name: 'BrowserMCPClient',
version: '1.0.0'
}
}
});
return response;
}
async listTools() {
return await this.sendRequest({
jsonrpc: '2.0',
id: 2,
method: 'list_tools',
params: {}
});
}
async callTool(name, params) {
return await this.sendRequest({
jsonrpc: '2.0',
id: 3,
method: 'call_tool',
params: { name, arguments: params }
});
}
}浏览器原生工具实现
const browserTools = {
fetch_url: async (params) => {
const response = await fetch(params.url, {
method: params.method || 'GET',
headers: params.headers,
body: params.body
});
return { content: await response.text() };
},
local_storage: async (params) => {
switch (params.action) {
case 'get':
return { value: localStorage.getItem(params.key) };
case 'set':
localStorage.setItem(params.key, params.value);
return { success: true };
case 'remove':
localStorage.removeItem(params.key);
return { success: true };
default:
throw new Error(`Unknown action: ${params.action}`);
}
},
geolocation: async () => {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(
(pos) => resolve({
latitude: pos.coords.latitude,
longitude: pos.coords.longitude
}),
reject
);
});
}
};用法
WebSocket代理方法
# Start the proxy with an MCP server
node proxy/index.js /path/to/mcp-server.py
# Open proxy/index.html in browser
# Connect to ws://localhost:8080Web Worker+WASM方法
# Open worker/index.html in browser
# Provide path to WASM MCP server
# (Requires WASM-compatible MCP server)浏览器原生工具
// Implement MCP-like protocol with browser tools
const client = new BrowserMCPClient();
await client.initialize();
const tools = await client.listTools();
const result = await client.callTool('fetch_url', { url: 'https://example.com' });结论:一段发人深省的旅程
这一探索挑战了关于浏览器局限性的传统观念,并揭示了令人惊讶的可能性:
关键发现
- 最初的假设是错误的 -MCP服务器可以使用官方的Streamable HTTP传输在浏览器中运行
- 与交通无关的设计 -MCP的JSON-RPC基础支持多种实现方法
- 浏览器安全模型启用而不是阻止 某些MCP实现
- 存在多种可行的解决方案 -从远程服务器到浏览器原生工具
- “MCP能在浏览器中运行吗?”这个问题有着微妙的答案 取决于具体的用例
发人深省的含义
- 浏览器限制通常是感知到的约束 而不是绝对的障碍
- 官方规范可以提供意想不到的解决方案 (流式HTTP传输)
- MCP协议的设计 预测web部署场景
- 浏览器API比通常认为的更强大 用于AI工具集成
- 浏览器中AI工具的未来 可能比最初想象的更灵活
实际成果
- 远程MCP方法 是否已为web应用程序做好生产准备
- 浏览器原生工具 为纯客户端部署提供了一种引人注目的替代方案
- 多种架构模式 可以为不同的用例共存
- 探索本身 证明质疑初始假设的价值
本次调查显示 对“不可能”问题的深入探讨 可以带来令人惊讶和实用的解决方案。浏览器环境通常被视为限制性的,当以正确的心态处理时,实际上为人工智能工具集成提供了丰富的机会。
文件
remote/- 远程MCP服务器方法(推荐)proxy/-WebSocket代理方法worker/-Web Worker+WASM方法browser-tools.json-浏览器原生工具的全面列表README.md-本文件
许可证
MIT许可证-您可以自由使用和修改您的项目。
______________________________________________________________________
这一探索展示了质疑假设和调查“不可能”问题的价值。有时,当我们挑战我们自认为了解的系统限制时,最有趣的解决方案就会出现。
