核心痛点:为什么不能直接连?
目前开源社区主流的 MCP 服务(例如 @modelcontextprotocol/server-filesystem)默认通过终端标准输入输出(stdio)运行。这对于 Cursor 或桌面版客户端来说开箱即用,但对于运行在浏览器环境下的 Web UI(如 Page Assist),存在两道硬伤:
- 协议不匹配: 浏览器插件仅支持基于 Streamable HTTP 的 MCP 端点。
- CORS 跨域限制: 浏览器会严格拦截前端向局域网发起的非同源 API 请求。
解决思路: 引入 mcp-proxy 工具将 stdio 进程包装为 HTTP 服务,并在外层套用 Nginx 反向代理注入完整的跨域允许头(CORS Headers)。

环境准备
本教程以标准的 Linux 服务器环境 (假设局域网 IP 为 192.168.x.x) 为例,需提前安装好 Docker 与 Docker Compose。
创建项目目录结构:
Bash
mkdir -p /opt/mcp-services/nginx
cd /opt/mcp-services
第一步:编写 Docker Compose 编排文件
我们将同时拉起三个容器:本地文件系统 MCP、GitHub MCP,以及 Nginx 代理网关。
在 /opt/mcp-services 下新建 docker-compose.yml:
YAML
version: '3.8'
services:
# 1. GitHub MCP 服务
mcp-github:
image: node:20-alpine
container_name: mcp-github
restart: always
environment:
- GITHUB_PERSONAL_ACCESS_TOKEN=your_github_pat_here # 替换为你的 GitHub Token
command: sh -c "npx -y @punkpeye/mcp-proxy --port 3001 -- npx -y @modelcontextprotocol/server-github"
ports:
- "3001:3001"
# 2. 本地文件系统 MCP 服务
mcp-filesystem:
image: node:20-alpine
container_name: mcp-filesystem
restart: always
volumes:
# 将宿主机需要让 AI 访问的目录挂载进来,请替换为实际路径
- /your/local/path:/projects
command: sh -c "npx -y @punkpeye/mcp-proxy --port 3002 -- npx -y @modelcontextprotocol/server-filesystem /projects"
ports:
- "3002:3002"
# 3. Nginx 代理网关 (处理跨域 CORS)
mcp-nginx:
image: nginx:alpine
container_name: mcp-nginx
restart: always
ports:
- "8080:80"
volumes:
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- mcp-github
- mcp-filesystem
第二步:配置 Nginx 解决浏览器跨域
Nginx 的核心作用是拦截浏览器的 OPTIONS 预检请求,并强行返回允许跨域的响应头,同时保证 HTTP 流式传输不断开。
在 /opt/mcp-services/nginx/ 目录下新建 default.conf:
Nginx
server {
listen 80;
# 全局跨域 Header 配置
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
# GitHub MCP 路由
location /github {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://mcp-github:3001;
# 关键配置:关闭缓冲,确保大模型可以流式接收数据
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
}
# 文件系统 MCP 路由
location /fs {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://mcp-filesystem:3002;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
}
}
第三步:一键启动与前端对接
返回项目根目录启动服务:
Bash
docker-compose up -d
确认容器全部处于 Up 状态后,打开 Page Assist 设置页面,进入 MCP 服务器 配置项,添加以下信息:
- GitHub 工具集:
http://<你的服务器IP>:8080/github - 本地文件系统工具集:
http://<你的服务器IP>:8080/fs
保存后,打开一个新的对话框,即可直接向大模型下达指令,例如:“读取 /projects 目录下的内容并总结”。此时大模型将成功调用后端 MCP 接口,并直接与本地环境进行交互。
常见问题解答 (FAQ)
Q1:配置完 Nginx 后,Page Assist 依然提示 CORS 跨域报错怎么办? A: 通常由两点引起:一是浏览器强缓存,建议按 Ctrl + F5 强制刷新或在无痕模式下测试;二是 IP 与端口填写错误。请检查 Page Assist 中填写的 URL 是否为 Nginx 的暴露端口(本文为 8080),而不是 MCP 容器的内部端口(如 3001)。
Q2:成功连接了 GitHub MCP,但大模型无法读取私人代码仓库? A: 这是 Token 权限不足导致的。请前往 GitHub Developer Settings 重新生成 Personal Access Token,确保勾选了 repo(完整控制私有仓库)和 read:org 权限。更新 docker-compose.yml 中的环境变量后,执行 docker-compose restart mcp-github 重启服务即可生效。
Q3:未来如何在这套架构上扩容,添加新的 MCP 服务(例如数据库探针)? A: 扩展极其方便。只需两步:首先在 docker-compose.yml 中新增目标 MCP 容器的配置,并分配一个新的映射端口(如 3003);然后在 Nginx 的 default.conf 中复制一段现有的 location 路由块,将代理地址指向新端口(如 proxy_pass http://mcp-database:3003;),最后执行 docker-compose up -d 重新加载即可。