MCP统一-完整指南
在一个MCP服务器中,12个服务中有80多个工具。用于管理所有凭据的Web仪表板。
服务:Gmail、领英、云端硬盘、日历、YouTube、推特、电报、WhatsApp、Discord、Slack、Twitch、GitHub
______________________________________________________________________
目录
- 谷歌服务 - 领英 - Discord 的中文翻译是“不和谐”或“纷争”。 - Slack - Twitch - - 其他服务
______________________________________________________________________
快速开始
选项1:Docker(推荐)
# Quick start script (Linux/Mac)
chmod +x docker-start.sh
./docker-start.sh
# Quick start script (Windows PowerShell)
.\docker-start.ps1
# Or manually
docker-compose up -d访问权限:
- 仪表盘: http://localhost:5173
- API: http://localhost:3001
方案2:地方发展
npm install
npm run dev # Starts both API and dashboard
# Or separately:
npm run dev:api # Express API on :3001
npm run dev:dashboard # React dashboard on :5173______________________________________________________________________
建筑
src/index.ts ← THE MCP SERVER (all 80+ tools registered here)
src/credentialStore.ts← AES-256-GCM encrypted SQLite
src/api.ts ← Express REST API (dashboard backend, :3001)
src/emailUtils.ts ← Gmail send/read/search tools
src/linkedinClient.ts ← LinkedIn tools
src/googleDriveClient.ts ← Google Drive tools
src/googleCalClient.ts ← Google Calendar tools
src/youtubeClient.ts ← YouTube tools
src/notionClient.ts ← Notion tools
src/telegramClient.ts ← Telegram tools
src/whatsappClient.ts ← WhatsApp tools
src/discordClient.ts ← Discord REST API client
src/slackClient.ts ← Slack Web API client
src/twitchClient.ts ← Twitch Helix API client
src/githubClient.ts ← GitHub REST API client
src/auth/googleAuth.ts ← Google OAuth CLI helper
src/auth/outlookAuth.ts ← Outlook OAuth CLI helper
dashboard/ ← React web UI (:5173)请求流
Dashboard (React/Vite)
↓ HTTP Request
Nginx (Port 80/5173)
↓ Proxy /api → API Container
Express API (Port 3001)
├─ Rate Limit Check
├─ Request Validation
├─ Credential Retrieval (Decrypt)
├─ External API Call
└─ Response (Mask credentials, Add headers)______________________________________________________________________
安全与隐私
🔒 凭证保护
您的凭据永远不会暴露给LLM代理或外部服务。
静态加密
- 算法:AES-256-GCM(军用级加密)
- 主密钥:32字节随机密钥存储在
.master.key(文件权限:0o600) - 存储:加密SQLite数据库(
credentials.db) - 位置:
./data/目录(或~/.mcp-unified/在本地模式下)
什么被加密
✅ 所有服务凭据:
- API密钥(Google、Notion、Telegram等)
- 客户机密
- OAuth令牌(访问令牌、刷新令牌)
- 密码(LinkedIn等)
- 身份验证令牌
什么是本地
🔐 凭证永远不要离开您的机器:
- ❌ 未发送给LLM提供商(OpenAI、Anthropic等)
- ❌ 不发送到外部API(除非您显式调用工具)
- ❌ 未以明文形式登录
- ❌ API响应中未暴露(屏蔽为
••••XXXX) - ✅ 仅在API调用需要时在内存中解密
主密钥管理
自动生成密钥(默认)
如果 MASTER_SECRET 未设置:
- 首次运行时生成随机32字节密钥
- 商店在
./data/.master.key随着0o600权限 - 备份此文件! 没有它,您无法解密凭据
自定义主密钥
集 MASTER_SECRET 环境变量:
# In .env file or docker-compose.yml
MASTER_SECRET=your-strong-random-secret-key-here⚠️ 重要:
- 使用强随机秘密(32+个字符)
- 安全存储(密码管理器)
- 如果丢失,则无法解密现有凭据
API安全
凭证屏蔽
API端点在响应中屏蔽机密:
- 全部秘密:
sk_live_abc123xyz - 蒙面反应:
••••xyz
文件权限
# Data directory
chmod 700 ./data
# Master key file
chmod 600 ./data/.master.key
# Database file
chmod 600 ./data/credentials.dbLLM代理人可以看到什么
✅ LLM代理可以看到:
- 工具名称和说明
- 刀具参数(输入字段)
- 工具结果(输出数据)
- 错误消息(无凭据)
- 服务配置状态(已配置/未配置)
❌ LLM代理无法看到:
- 纯文本凭据
- 主加密密钥
- 解密令牌
- 密码
- API密钥
- OAuth令牌
安全最佳实践
- 备份您的数据
tar -czf mcp-unified-backup-$(date +%Y%m%d).tar.gz data/- 保护主密钥
- 永不承诺 .master.key 到git(已经在 .gitignore) - 从不分享 .master.key 文件 - 如果使用自动生成的密钥,则可以安全备份 - 设置时使用强机密 MASTER_SECRET
- 安全数据目录
chmod 700 ./data- 网络安全
- 地方发展:仅在 localhost - 生产:使用HTTPS反向代理(Nginx、Traefik) - 防火墙:仅限制对必要端口的访问
如果妥协
如果主密钥暴露:
- 立即轮换所有凭据:
- 更改API密钥 - 撤销OAuth令牌 - 更新密码
- 生成新的主密钥:
docker-compose down
mv ./data ./data.backup
docker-compose up -d # Generates new key
# Re-configure all services______________________________________________________________________
速率限制
概述
MCP Unified实施多层次速率限制,以保护API免受滥用并确保公平使用。速率限制适用于每个IP地址,并因端点类型而异。
费率限制级别
1.API通用费率限制
- 限制:每个IP每15分钟100个请求
- 适用于:全部
/api/*端点(工具调用除外) - 目的:防止一般API滥用
- 可配置的:
RATE_LIMIT_GENERAL环境变量
受影响的端点:
GET /api/services-列出服务GET /api/services/:id-获取服务详细信息POST /api/services/:id-保存凭据DELETE /api/services/:id-删除服务
2.刀具调用率限制
- 限制:每个IP每分钟30个请求
- 适用于:
POST /api/tools/invoke - 目的:防止快速工具调用滥用
- 可配置的:
RATE_LIMIT_TOOLS环境变量
为什么更严格?
- 工具调用进行外部API调用(Google、LinkedIn等)
- 防止达到外部API费率限制
- 防止意外循环或滥用
3.OAuth速率限制
- 限制:每个IP每15分钟10个请求
- 适用于:
/auth/*端点 - 目的:防止OAuth流滥用
- 可配置的:
RATE_LIMIT_OAUTH环境变量
速率限制标头
所有速率限制端点都返回标准速率限制标头:
RateLimit-Limit: 30
RateLimit-Remaining: 15
RateLimit-Reset: 1640995200- 比率限制:允许的最大请求数
- 剩余比率限制:当前窗口中剩余的请求数
- 下载中:速率限制重置时的Unix时间戳
错误响应
当超过费率限制时,您将收到:
{
"error": "Too many tool invocations. Limit: 30 per minute. Please slow down and try again in a moment.",
"retryAfter": "1 minute",
"limit": 30,
"window": "1 minute"
}HTTP状态代码: 429 Too Many Requests
配置
将这些设置在您的 .env 文件或 docker-compose.yml:
# General API rate limit (requests per 15 minutes)
RATE_LIMIT_GENERAL=100
# Tool invocation rate limit (requests per minute)
RATE_LIMIT_TOOLS=30
# OAuth rate limit (requests per 15 minutes)
RATE_LIMIT_OAUTH=10利率限制是如何工作的
每IP速率限制
- 相同IP=共享限制:来自同一IP的多个应用程序/客户端共享相同的速率限制
- 不同的IP=单独的限制:每个IP地址都有自己的独立速率限制计数器
速率限制窗口
费率限制使用 滑动窗口:
- 工具调用:每个请求30个 1分钟 (滚动窗口)
- API通用:每个请求100个 15分钟 (滚动窗口)
- OAuth:每个请求10个 15分钟 (滚动窗口)
重要:窗户 自动重置 在时间段到期后。
常见场景
场景1:来自同一IP的多个应用程序
问题:仪表板+外部应用程序都从 localhost
发生了什么:
- 两个应用程序共享相同的速率限制(30/min)
- 如果仪表板使用20个请求,外部应用程序只剩下10个了
- 如果总数超过30,两者都会受到费率限制
解决方案:
- 增加限制(见下面的配置)
- 使用不同的IP(如果可能的话)
- 实施每个应用程序的速率限制(高级)
场景2:快速测试
问题:在Tool Tester中快速测试工具
发生了什么:
- 每次工具调用都会计入限制
- 在1分钟内收到30个请求后,您将获得速率限制
- 必须等待1分钟才能重置
解决方案:
- 等待1分钟-限额自动重置
- 提高开发限额
- 间隔请求
如何解决利率限制问题
解决方案1:增加限制(快速修复)
为了发展:
RATE_LIMIT_TOOLS=100 # Increase from 30 to 100
RATE_LIMIT_GENERAL=500 # Increase from 100 to 500
RATE_LIMIT_OAUTH=50 # Increase from 10 to 50用于生产:
RATE_LIMIT_TOOLS=60 # 1 request per second
RATE_LIMIT_GENERAL=200 # More headroom
RATE_LIMIT_OAUTH=20 # More OAuth attempts重新启动API服务器 在改变限制之后。
解决方案2:在代码中处理速率限制
前端(仪表板/工具测试仪):
async function invokeToolWithRetry(tool: string, args: any, maxRetries = 3) {
for (let i = 0; i 0
? Math.max(0, resetTime * 1000 - Date.now())
: 60000; // Default 1 minute
if (i setTimeout(resolve, waitTime));
continue;
}
throw new Error(data.error || 'Rate limit exceeded');
}
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
if (i === maxRetries - 1) throw error;
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
}
}
}备注:Tool Tester现在内置了针对429个错误的自动重试逻辑。
解决方案3:监控速率限制标头
const response = await fetch('/api/tools/invoke', {...});
const remaining = parseInt(response.headers.get('RateLimit-Remaining') || '0');
if (remaining {
return "light"; // Change default from "dark" to "light"
};______________________________________________________________________
故障排除
仪表板显示“获取失败”
- 确保API服务器正在端口3001上运行
- 检查浏览器控制台是否存在CORS错误
- 验证中的代理设置
dashboard/vite.config.ts
API返回404
- 检查端点路径是否正确
- 验证API服务器是否正在运行
- 检查终端是否有错误消息
端口已在使用中
- 更改以下端口:
- src/api.ts (API_PORT环境变量,默认3001) - dashboard/vite.config.ts (server.port,默认5173)
凭据未保存
- 检查一下
~/.mcp-unified/目录存在 - 验证写入权限
- 检查终端是否存在加密错误
Google OAuth问题
错误:“Gmail API尚未在项目中使用…或已禁用”
- 启用API:https://console.cloud.google.com/apis/library/gmail.googleapis.com
- 等待1-2分钟进行传播
错误:“访问被阻止:项目尚未完成谷歌验证过程”
- 在OAuth同意屏幕中将自己添加为测试用户
- 首选https://console.cloud.google.com/apis/credentials/consent
- 滚动到“测试用户”→ “+添加用户”→ 添加您的电子邮件→ Save
错误:“redirect_uri_mismatch”
- 确保重定向URI完全匹配:
http://localhost:3001/auth/google/callback - 检查尾随斜线或协议不匹配
LinkedIn问题
错误:“LinkedIn身份验证失败”
- 验证凭据是否正确
- 暂时禁用2FA(或使用测试帐户)
- 检查LinkedIn帐户的安全警报
错误:“请求失败,状态代码为401”
- 应用程序将尝试自动重新进行身份验证
- 如果失败,请检查凭据并重新启动API服务器
错误:“请求失败,状态代码429”(速率限制)
- 应用程序通过重试自动处理此问题
- 如果重试失败,请等待5-10分钟
- 降低请求频率
利率限制问题
过于频繁地受到利率限制
- 增加限制
.env文件 - 实现请求批处理
- 添加缓存层
- 使用Redis进行分布式限制
不同的应用共享相同的限制
- 使用不同的IP(如果可能的话)
- 实现每个应用程序的身份验证
- 使用带有应用程序特定密钥的Redis
- 提高总体限额
速率限制重置,但仍出现错误
- 检查你达到了哪个限制(1分钟vs 15分钟)
- 多个应用程序是否达到了极限?
- 检查
RateLimit-Reset实际重置时间的标题 - 验证服务器时间是否正确
______________________________________________________________________
工作流和速率限制行为
完整的请求生命周期
请求成功
1. Dashboard sends request
↓
2. Nginx proxies to API
↓
3. Rate limit check (PASS)
↓
4. Request validation (PASS)
↓
5. Decrypt credentials
↓
6. Call external API
↓
7. External API responds
↓
8. Mask credentials in response
↓
9. Add rate limit headers
↓
10. Return to dashboard价格限制请求
1. Dashboard sends request
↓
2. Nginx proxies to API
↓
3. Rate limit check (FAIL)
↓
4. Return 429 error
├─ Error message
├─ Retry-After header
└─ RateLimit headers
↓
5. Dashboard displays error
↓
6. User waits or implements retry外部API费率受限请求
1. Dashboard sends request
↓
2. Rate limit check (PASS)
↓
3. Call external API (LinkedIn)
↓
4. External API returns 429
↓
5. Automatic retry with backoff
├─ Wait 5s → Retry
├─ Wait 10s → Retry
└─ Wait 20s → Retry
↓
6. If still failing:
└─ Return error to user
↓
7. Dashboard displays error
↓
8. User waits before retrying速率限制存储
内存存储(默认)
赞成的意见:
- 快
- 无依赖关系
- 简单
欺骗:
- 重新启动时重置
- 不跨实例共享
- 容器重新启动时丢失
Redis商店(生产)
赞成的意见:
- 持久
- 跨实例共享
- 生存重启
欺骗:
- 需要Redis
- 额外依赖性
______________________________________________________________________
摘要
✅ 80+工具 12项服务 ✅ AES-256-GCM加密 对于所有凭据 ✅ 多层速率限制 自动重试 ✅ Docker支持 具有数据持久性 ✅ 亮/暗主题 具有持久的偏好 ✅ 全面的错误处理 以及故障排除指南 ✅ 完整的API文件 所有服务
您的凭据是安全的 -它们永远不会让你的机器处于未加密状态,也永远不会暴露给LLM代理。
______________________________________________________________________
支持
如果您遇到问题:
- 查看本指南的故障排除部分
- 验证凭据是否正确
- 查看API日志以了解详细的错误消息
- 确保授予了所需的范围/权限
- 查看上述特定于服务的设置指南
对于安全漏洞,请私下联系维护人员(不要制造公共问题)。
