在本地电脑上使用n8n、Docker和WSL将MCP客户端连接到MCP服务器和工具
模型上下文协议(MCP)是一种强大的开放标准,它使人工智能系统,尤其是大型语言模型(LLM),能够安全地与外部工具、服务和数据源进行交互。使用MCP服务器和客户端的五大关键点:
- 模块化架构
MCP客户端(AI)可以部署在AWS云上,而MCP服务器可以部署在本地PC上,因此无需将机密数据上传到云端。
- 标准化通信层
由于采用了统一的JSON-RPC协议,任何MCP客户端都可以与任何符合规范的MCP服务器进行通信。
- 安全
MCP(最小化配置协议或类似名称,具体根据上下文确定)允许对数据或功能进行受控暴露。MCP服务器决定暴露什么内容。
- 动态工具发现
您可以插入新的服务器(例如,Google Calendar MCP或GitHub MCP),而无需重新训练或重新部署模型。
然而,这并非易事,人们在尝试这样做时会遇到错误和漏洞。本项目搭建了一个n8n MCP(模型上下文协议)服务器,配备了适当的SSL证书处理功能,以便使用Docker和Traefik反向代理进行本地开发。当在……上运行MCP时 n8n 里面 Docker 容器,你 不能 依赖自签名证书用于 localhost 因为:
- 容器网络导致域不匹配\
localhost 在容器内部指的是容器本身,而不是宿主机器。
- MCP库强制实施HTTPS和SSE规则
- HTTPS 连接必须使用有效且受信任的 SSL/TLS 证书。MCP 还会禁用 gzip 压缩 for 服务器发送事件 (SSE) 在 /mcp 终端节点。
- 在容器内部证书验证失败
- 容器不会自动信任自签名证书。自定义域名如 n8n-demo.local 在Docker或WSL中可能无法正确解析。
解决方案:使用Traefik的反向代理架构
为了清晰地处理SSL和域名路由,请使用 Traefik(可译为“特雷法克”,但通常直接使用原名,因其为专有名词) 作为n8n前面的反向代理。主要优势:
- 客户端打开
https://n8n-demo.local\
MCP客户端或浏览器尝试连接 https://n8n-demo.local在Docker容器内部,当访问n8n-demo.local时,请连接到运行Docker的计算机(主机)。
extra_hosts:
- "n8n-demo.local:host.docker.internal"- 该请求被发送到Traefik。Traefik正在监听443端口(HTTPS)。它是所有发往n8n的安全流量的入口。
- Traefik 显示 SSL 证书(例如,使用 mkcert 创建的证书)。客户端检查证书并确认域名匹配(
n8n-demo.local)。
- Traefik解密HTTPS流量的安全请求(SSL终止)。在Docker网络内部,该请求变为普通的HTTP请求。
- Traefik 将解密后的 HTTP 请求发送到端口 5678 上的 n8n 容器。
- n8n 处理 MCP 请求。
- Traefik 对响应进行重新加密。Traefik 从 n8n 获取原始的 HTTP 响应,再次使用 SSL 进行加密,然后通过 HTTPS 发送回客户端。
- 客户端收到了一个安全响应
先决条件
- Docker 和 Docker Compose
- WSL(Windows子系统用于Linux)
- mkcert 用于本地证书生成
设置说明
1. 安装 mkcert
# Install mkcert in WSL
sudo apt update
sudo apt install mkcert
# Install the root CA
mkcert -install2. 生成证书
# Create certificates directory
mkdir -p certs
# Generate certificates for your domain
mkcert -cert-file ./certs/n8n-demo.local.pem -key-file ./certs/n8n-demo.local-key.pem n8n-demo.local localhost 127.0.0.13. 将域名添加到主机文件中
# Add domain to WSL hosts file
echo "127.0.0.1 n8n-demo.local" | sudo tee -a /etc/hosts4. 创建配置文件
traefik-tls.yml:
tls:
certificates:
- certFile: /certs/n8n-demo.local.pem
keyFile: /certs/n8n-demo.local-key.pem
stores:
default:
defaultCertificate:
certFile: /certs/n8n-demo.local.pem
keyFile: /certs/n8n-demo.local-key.pem.env:(通常表示这是一个环境配置文件,用于存储应用程序的环境变量,如数据库连接信息、密钥等,具体含义需根据上下文确定)
DOMAIN_NAME=n8n-demo.local
GENERIC_TIMEZONE=UTC
USERPROFILE=/home/aidan5. 启动服务
# Start all services
docker-compose up -d
# Check if containers are running
docker ps6. 访问n8n
打开您的浏览器,然后访问: https://n8n-demo.local
关键配置详情
为何此方法有效
extra_hosts允许 n8n 解析n8n-demo.local内部地;在内部地NODE_EXTRA_CA_CERTS告诉 Node.js 信任 mkcert 证书颁发机构- mkcert CA 挂载在容器内提供证书颁发机构(CA)服务
- MCP特定路由禁用服务器发送事件的gzip压缩
- 处处都是同一个域名消除证书验证不匹配的情况
关键环境变量
environment:
- N8N_FEATURE_FLAG_MCP=true # Enable MCP support
- NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/mkcert/rootCA.pem # Trust mkcert CA
- N8N_HOST=${DOMAIN_NAME} # Use consistent domain
- N8N_PROTOCOL=https # Force HTTPS针对MCP的特定Traefik配置
# Disable gzip for MCP endpoints (required for SSE)
- traefik.http.middlewares.nogzip.headers.customResponseHeaders.Content-Encoding=""
- traefik.http.routers.n8n_mcp.rule=Host(`${DOMAIN_NAME}`) && PathPrefix(`/mcp`)
- traefik.http.routers.n8n_mcp.middlewares=nogzip使用MCP服务器
1. 激活您的MCP工作流程
- 首选
https://n8n-demo.local - 找到你的MCP工作流程(例如,“使用Google日历和自定义函数构建MCP服务器”)
- 点击切换开关以 激活 工作流程
- 工作流程应显示为“激活状态”
2. MCP 端点URL
- 生产环境URL:
https://n8n-demo.local/mcp/my-functions/sse - 测试URL:
https://n8n-demo.local/mcp-test/my-functions/sse(临时的,一次性使用)
3. 连接MCP客户端工具
使用 生产环境URL 在您的MCP客户端工具中:
创建证书目录
创建目录(递归创建,若目录不存在则创建)certs
为您的域名生成证书
mkcert -cert-file ./certs/n8n-demo.local.pem -key-file ./certs/n8n-demo.local-key.pem n8n-demo.local localhost 127.0.0.1 验证域名是否在hosts文件中: cat /etc/hosts | grep n8n-demo
- “Bad Gateway”错误
- 检查容器日志: docker logs mcp_server_and_client_with_custom_functions_n8n_1 - 确保没有端口冲突(n8n 应运行在 5678 端口,Traefik 运行在 443 端口)
- 证书验证错误
- 重新生成证书: mkcert -cert-file ./certs/n8n-demo.local.pem -key-file ./certs/n8n-demo.local-key.pem n8n-demo.local localhost 127.0.0.1 - 重启容器: docker-compose down && docker-compose up -d
测试设置
# Test the MCP endpoint
curl -k https://n8n-demo.local/mcp/my-functions/sse
# Should return SSE data like:
# event: endpoint
# data: /mcp/my-functions/messages?sessionId=...将域名添加到主机文件中
将 "127.0.0.1 n8n-demo.local" 追加到 /etc/hosts 文件中(使用sudo权限):echo "127.0.0.1 n8n-demo.local" | sudo tee -a /etc/hosts
- MCP需要HTTPS 持有有效证书
- Docker 网络 导致域名解析问题
- 自签名证书 不跨容器边界工作
- 直接端口访问 绕过正确的SSL终止处理
反向代理解决方案是 唯一可靠的方法 that: (此处“that”为英文单词,中文翻译为“那个”或根据上下文可能有其他含义,但单独作为句子时,通常不直接翻译,而是根据其在句中的作用来翻译)
- 提供一致的域名解析
- 正确处理SSL终止
- 消除证书验证不匹配的情况
- 与MCP客户端工具配合使用
致谢/功劳/积分(根据上下文,"Credits" 可以有多种翻译,这里提供了其中一种可能的翻译)
这个设置是基于“在MCP服务器上运行n8n:文档不完善的SSL证书挑战”中描述的解决方案,并针对WSL/Windows环境进行了调整。
创建配置文件
- traefik-tls.yml 翻译为中文是“Traefik TLS 配置文件”
- .env(通常表示环境配置文件)
启动服务
\docker-compose up -d\ 翻译成中文是:“使用docker-compose启动服务并置于后台运行”
docker ps 翻译为中文是:“列出正在运行的 Docker 容器”
访问N8N
打开你的浏览器,然后访问:https://n8n-demo.local
为何这种架构是必要的
- 在Docker环境中,MCP服务器面临一个根本性挑战:
- MCP要求使用带有有效证书的HTTPS
- Docker 网络设置导致域名解析问题
- 自签名证书在容器边界之间无法正常工作
- 直接端口访问绕过了正确的SSL终止处理
- 反向代理解决方案是唯一可靠的方法,它:
- 提供一致的域名解析
- 正确处理SSL终止
- 消除证书验证不匹配问题
- 与MCP客户端工具配合使用
致谢/鸣谢
功劳/学分
这个设置是基于文中描述的解决方案 “在MCP服务器上运行N8N:SSL证书文档缺失的挑战” 并且已从MacOS环境适配到WSL/Windows环境。它也是从……发展而来的 "Bitovi n8n 入门仓库"
