配置专属 MCP 与 Skill 全流程指南
TDuck 私有化部署:配置专属 MCP 与 Skill 全流程指南
在 私有化部署(企业内网 / 私有云) 环境下,将 TDuck 表单引擎接入 AI 客户端(如 WorkBuddy、Cursor、Claude Desktop、Windsurf、Dify 等),核心主要包含以下 三大配置步骤。
📌 标识说明:
- 🔴 【必改 / 必须配置】:私有化部署必须修改,不改将导致功能异常或认证失败。
- ⚪ 【可选 / 按需配置】:默认已包含推荐值,根据实际企业网络与场景按需选用。
🧭 核心配置清单速查
| 阶段 | 配置项 | 类型 | 说明 |
|---|---|---|---|
| 第一步:后端服务 | 🔴 platform.mcp.server-url 根地址 |
必改 🔴 | 必须指向私有部署实际对外的公开 API 根地址 |
| ⚪ Token / Code 有效期与权限 Scopes | 可选 ⚪ | 默认有效期 7 天,按需调整 | |
| ⚪ OpenAPI 永久密钥凭据 (Basic Auth) | 可选 ⚪ | 纯内网或自动化脚本免登录时生成 | |
| 第二步:Skill 技能包 | 🔴 下载官方 Skill 源码仓库 | 必做 🔴 | 从 Gitee / GitHub 克隆 |
🔴 执行 replace_endpoint.js 批量替换域名 |
必改 🔴 | 一键将 Skill 内所有官方域名替换为您自己的私有部署域名 | |
⚪ 执行 setup.js 辅助生成客户端配置 |
可选 ⚪ | 辅助生成带凭据的 mcp.json 片段 |
|
| 🔴 导入 Skill 到 AI 客户端 | 必做 🔴 | 导入 WorkBuddy / Cursor 等客户端生效 | |
| 第三步:Nginx 代理 | 🔴 代理 location /.well-known/ 并置于 location / 前 |
必配 🔴 | 防止协议自发现被前端 SPA try_files 拦截返回 index.html |
🔴 透传 Host 与 X-Forwarded-Proto 请求头 |
必配 🔴 | 防止 OAuth 重定向到内网 IP 或 HTTP 导致认证失败 | |
🔴 关闭代理缓冲 proxy_buffering off |
必配 🔴 | 防止 MCP 流式响应 (SSE) 卡顿与握手挂起 | |
⚪ 延长长连接超时 proxy_read_timeout |
可选 ⚪ | 建议调大避免长会话被意外切断 |
🛠️ 第一步:TDuck 后端服务配置 (Spring Boot)
在私有化部署环境下,首先需要让 TDuck 后端服务明确自身对外的公开访问地址,以便正确分发 OAuth 元数据和重定向地址。
1. 修改配置文件 (application.yml / application-prod.yml)
platform:
mcp:
# 🔴【必改】外部访问的 API 根路径 (务必配置为您私有部署对外实际可访问的完整域名或 IP:端口,末尾不要带斜杠)
server-url: https://form.your-company.com/tduck-api
# ⚪【可选】Token 有效期 (单位: 秒,默认 7 天: 604800,可按需修改)
access-token-expire-seconds: 604800
# ⚪【可选】OAuth 授权码有效期 (单位: 秒,默认 5 分钟: 300,可按需修改)
auth-code-expire-seconds: 300
# ⚪【可选】支持的权限范围 (保持默认即可)
scopes-supported:
- tduck:all
- tduck:form:manage
- tduck:data:read
- tduck:data:write
- tduck:user:profile
[!IMPORTANT] 🔴 为什么
server-url必须修改:
- OAuth 2.0 自动发现协议:AI 客户端连接
/tduck-api/mcp时,服务端会返回401及/.well-known/oauth-protected-resource元数据,客户端据此寻找授权中心。- 防止授权回调异常:若仍保留
localhost,拉起浏览器授权时会跳转至错误地址或提示redirect_uri mismatch。
2. ⚪【可选】生成 OpenAPI 永久密钥凭据 (Basic Auth)
适用场景:纯内网无浏览器交互、后台自动化脚本、CI/CD 环境,希望永久免弹窗授权。若使用 OAuth 2.0 则无需此步骤。
- 登录 TDuck 管理后台,进入 「管理后台 -> 其他工具 -> 应用接入」;
- 新增应用并获取
AppId与AppSecret; - 计算 Base64 凭据:
echo -n "YOUR_APP_ID:YOUR_APP_SECRET" | base64 - 获得 Basic Auth Header:
Authorization: Basic <Base64编码>。
📦 第二步:Skill 技能包改域名与脚本配置
官方开源的 tduckx-skills 技能包中预设的 MCP 端点与提示词示例默认指向官方云端或本地地址。私有化部署时,必须执行脚本一键替换为私有部署域名。
1. 🔴【必做】下载 Skill 仓库源码
# Gitee 国内镜像(推荐国内或内网服务器使用)
git clone https://gitee.com/smalljop/tduckx-skills.git
# 或 GitHub 官方仓库
git clone https://github.com/TDuckCloud/tduckx-skills.git
2. 🔴【必改】执行一键批量替换域名脚本
tduckx-skills 内置了纯原生 Node.js 跨平台批量替换脚本 replace_endpoint.js,无需安装任何第三方 npm 依赖。
进入仓库根目录并执行:
# 语法:node ./skills/tduck/scripts/replace_endpoint.js <你的私有部署API根路径>
node ./skills/tduck/scripts/replace_endpoint.js https://form.your-company.com/tduck-api
[!TIP] ⚪ 【可选参数】:
- 预览模式:若想先预览将要修改的文件而不实际写入,可加上
--dry-run:node ./skills/tduck/scripts/replace_endpoint.js --url https://form.your-company.com/tduck-api --dry-run- 交互模式:直接运行
node ./skills/tduck/scripts/replace_endpoint.js,脚本会交互式提示您输入新域名。
脚本会自动递归扫描并更新 skills/、workbuddy/、trae/、.cursor/ 以及所有的 SKILL.md、README.md 等文件,将所有引用地址批量更新为私有化地址。
3. ⚪【可选】生成客户端 mcp.json 配置片段
若您使用永久密钥认证,可运行内置的 setup.js 快速打印对应的配置代码:
node ./skills/tduck/scripts/setup.js --print-json YOUR_APP_ID YOUR_APP_SECRET
4. 🔴【必做】导入修改后的 Skill 到客户端
- WorkBuddy:进入 「技能 / 专家管理」 -> 点击 「导入 / 上传 Skill」 -> 选择替换好域名的
tduckx-skills目录。 - Cursor / Claude Code / Windsurf:使用
npx skills add本地路径,或直接将skills/tduck/目录放入客户端的 Skills 目录中。
🌐 第三步:Nginx 反向代理配置 (关键:防认证失败)
如果私有部署前端使用了 Nginx 作为反向代理网关,必须正确传递代理头并关闭缓冲,否则 OAuth 认证与 SSE 流式通信一定会失败!
1. 为什么不配 Nginx 会导致认证失败?
- 🔴 丢失
/.well-known/路由导致元数据解析失败(常见大坑):AI 客户端会按 RFC 规范请求/.well-known/oauth-protected-resource自发现端点。如果 Nginx 未单独代理该路径,请求会被前端单页应用(SPA)的location /中的try_files拦截返回index.html网页,导致客户端 JSON 解析报错! - 🔴 丢失主机头与协议导致 OAuth 失败:若未透传原请求的真实域名和
https协议,后端生成的重定向 URL 会回退为容器内网 IP 或http,导致浏览器回调跨域被拦截或提示Redirect URI Mismatch。 - 🔴 代理缓冲导致 SSE 长连接挂起:MCP 协议基于 Streamable HTTP / SSE。Nginx 默认开启缓冲会导致分块数据被截留在缓冲区,导致客户端建立 MCP 连接时超时卡死。
2. Nginx 标准生产配置示例
在 Nginx 的 server 块中配置如下规则(特别注意:/.well-known/ 必须放在 location / 之前):
server {
listen 443 ssl;
server_name form.your-company.com;
# SSL 证书配置略...
# ----------------------------------------------------------------------
# 🔴【必配】MCP OAuth 2.0 协议自发现端点(RFC 8414 / RFC 8707)
# 【必须放在 location / 前面】避免被前端 SPA 的 try_files 拦截返回 index.html
# ----------------------------------------------------------------------
location /.well-known/ {
proxy_pass http://127.0.0.1:8996/tduck-api/.well-known/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
}
# ----------------------------------------------------------------------
# 🔴【必配】TDuck 后端 API 与 MCP 服务代理
# ----------------------------------------------------------------------
location /tduck-api/ {
proxy_pass http://127.0.0.1:8996/tduck-api/;
# 🔴【必配】透传客户端真实主机头与协议,防止 OAuth 重定向域名或协议错误
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-Port $server_port;
# 🔴【必配】关闭代理缓冲,支持 MCP Streamable HTTP / SSE 实时流式通信
proxy_buffering off;
proxy_cache off;
proxy_http_version 1.1;
proxy_set_header Connection "";
# ⚪【可选/推荐】延长长连接超时时间,防止 AI 交互时长连接被 Nginx 主动切断
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
# 前端静态资源 / SPA 页面路由
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
}
💻 第四步:各客户端 MCP 连接配置
1. WorkBuddy
- 进入 「连接器管理」 -> 「添加自定义连接器」;
- 类型选择 HTTP 或 Streamable HTTP / SSE;
- 🔴 服务 URL【必填】:
https://form.your-company.com/tduck-api/mcp(替换为私有部署地址); - 认证方式(二选一):
- OAuth 2.0 自动授权 (推荐):直接点击连接,自动拉起私有化系统登录页授权;
- ⚪ 永久密钥 (可选):在 Headers 中配置:
Authorization: Basic <Base64凭据>。
2. Cursor (.cursor/mcp.json)
{
"mcpServers": {
"tduck": {
"url": "https://form.your-company.com/tduck-api/mcp"
}
}
}
3. Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"tduck": {
"url": "https://form.your-company.com/tduck-api/mcp"
}
}
}
🔍 第五步:验证与排错速查
1. 终端连通性检查
curl -I https://form.your-company.com/tduck-api/mcp
返回
HTTP 401 Unauthorized且响应头包含WWW-Authenticate: Bearer resource_metadata=...即表示服务端、Nginx 与 OAuth 元数据完全正常。
2. AI 对话功能验证
在客户端输入自然语言指令测试:
“列出我在 TDuck 里的表单”
3. 常见报错速查表
| 现象 / 报错 | 核心原因 | 解决办法 |
|---|---|---|
| 客户端解析 JSON 报错,提示返回了 HTML 内容 | 🔴 /.well-known/ 请求被前端 location / 的 try_files 拦截 |
在 Nginx 中将 location /.well-known/ 代理块放置在 location / 之前 |
OAuth 授权跳转到 localhost 或内网 IP |
🔴 Spring Boot server-url 未改或 Nginx 丢失 Host |
检查 platform.mcp.server-url,并在 Nginx 中添加 proxy_set_header Host $http_host; |
跳转授权后提示 Redirect URI Mismatch |
🔴 协议(HTTP 与 HTTPS)不一致 | 检查 Nginx 中的 proxy_set_header X-Forwarded-Proto $scheme; |
| MCP 连接一直处于 Connecting / 超时 | 🔴 Nginx 开启了响应缓冲导致 SSE 阻塞 | 在 Nginx 中配置 proxy_buffering off; 并 nginx -s reload |
| 调用提示 401 Unauthorized | ⚪ 授权过期或 Basic Auth 凭据错误 | 客户端重新点击连接授权,或核对 Base64(AppId:AppSecret) |