uni-mcp网关
一个统一的MCP(模型上下文协议)网关,将多个MCP服务器和API插件聚合在一个端点后面,具有身份验证、细粒度速率限制、审计日志、REST API桥和web仪表板。
通过一个URL、一个API密钥和一个审计跟踪,将您的人工智能代理连接到数十个服务。
我们为什么建造这个
我们在数十个环境中运行AI代理——Cursor、Claude Desktop、Opencode、自定义机器人。每个环境都需要自己的MCP连接、自己的身份验证和自己的配置。它不断地破裂,并严重地膨胀。以下是促使我们构建这个的原因:
重新认证地狱。 每次添加新的IDE、新代理或新机器时,都需要从头开始重新对每个MCP服务器进行身份验证。使用网关,您只需进行一次身份验证。每个环境只需要一个URL和一个API密钥。
上下文窗口膨胀。 连接5台MCP服务器,每台服务器有50个工具,代理的上下文窗口在开始工作之前就塞满了250个工具模式。网关的元工具架构(list_plugins → search_tools → get_tool_schema → call_tool)在上下文中总是意味着只有4个工具。代理商根据需要发现他们需要什么。
多账户混乱。 需要两个Slack工作区吗?三个日历账户?五个电子邮件收件箱?如果没有网关,那就是10个单独的MCP服务器,配备10倍的工具。网关本机处理多个帐户——一个插件、一组工具、pass account="work" 或 account="personal".
代理不需要API文档。 网关兼作REST API网桥。任何工具都可以通过调用 POST /api/v1/call没有Swagger规范,没有SDK设置——代理(和脚本)只需使用JSON参数按名称调用工具。网关是API。
最后是审计和访问控制。 与人员或代理共享API密钥,并确切地知道他们做了什么。每次工具调用都会记录完整的请求、响应、持续时间和调用者。设置粒度范围——此键可以读取Slack但不能发送,可以访问“工作”日历但不能访问“个人”,可以调用 gmail_messages_list 每分钟30次,但 gmail_messages_send 只有5。
特性
核心
- 统一端点 -一个MCP URL,一个API密钥,访问所有内容
- 插件架构 --将Python文件放入
plugins/,重新启动,完成 - 外部MCP桥接 --通过网关代理任何远程MCP服务器(无需代码)
- REST API桥接 --每个工具都可以通过标准HTTP访问
GET/POST端点 - Web仪表板 --登录、查看统计数据、管理密钥、浏览审计日志
安全
- API密钥验证 --具有独立权限的多个密钥
- 按插件访问控制 --每个插件每个密钥的读、写或管理员访问权限
- 粒度速率限制 --全局每个密钥、每个插件、每个帐户、每个工具限制
- IP 白名单 --将密钥限制在特定的CIDR范围内
- 密钥过期 -自动导出API密钥
- 隐身模式 -未经授权的API请求返回404(端点似乎不存在)
- 审核日志记录 --每个工具调用都记录了请求、响应、持续时间和调用者
多租户技术
- 多账户插件 --每个服务有多个帐户(例如,两个Slack工作区、三个Calendary帐户)
- 数据级别范围界定 --将密钥限制到特定的数据子集(例如WhatsApp聊天JID)
- 工具可见性过滤 --密钥只能看到他们有权访问的工具
上下文窗口优化
- 元工具架构 --与其向代理暴露300多个工具,不如暴露4个元工具:
- list_plugins --查看可用内容 - search_tools --按关键字查找工具 - get_tool_schema --获取特定工具的参数 - call_tool --执行任何工具
快速开始
1.克隆并安装
git clone https://github.com/nickcold/uni-mcp-gateway.git
cd uni-mcp-gateway
pip install -e .2.设置您的管理员令牌
export MCP_AUTH_TOKEN=$(python3 -c "import secrets; print(secrets.token_urlsafe(32))")
export MCP_BASE_URL=http://localhost:8080
export GATEWAY_DB_PATH=./gateway.db
echo "Your admin token: $MCP_AUTH_TOKEN"3.跑步
python -m uvicorn main:app --host 0.0.0.0 --port 80804.连接
添加到您的MCP客户端(Cursor、Claude Desktop等):
{
"mcpServers": {
"gateway": {
"url": "http://localhost:8080/mcp",
"headers": {
"Authorization": "Bearer YOUR_ADMIN_TOKEN"
}
}
}
}或者使用REST API:
# List plugins
curl -H "Authorization: Bearer $MCP_AUTH_TOKEN" http://localhost:8080/api/v1/plugins
# Call a tool
curl -X POST -H "Authorization: Bearer $MCP_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"tool": "gmail_messages_list", "params": {"max_results": "5"}}' \
http://localhost:8080/api/v1/call添加插件
选项A:编写一个插件(包装任何API)
复制 plugins/_example.py 并修改:
from plugin_base import MCPPlugin, ToolDef, get_credentials
def list_items(query: str = "") -> dict:
"""List items from the API."""
api_key = get_credentials("myservice").get("api_key", "")
# ... call the API ...
return {"items": [...]}
class MyServicePlugin(MCPPlugin):
name = "myservice"
tools = {
"list_items": ToolDef(access="read", handler=list_items, description="List items"),
}重新启动网关。您的工具显示为 myservice_list_items.
选项B:桥接外部MCP(无代码)
通过管理工具或仪表板连接到任何远程MCP服务器:
gateway_add_external_mcp(
name="acme",
url="https://acme-mcp.example.com/mcp",
auth_header="Bearer their-api-key"
)网关从远程服务器发现所有工具,并将其公开为 acme_ --包含您的身份验证、速率限制和审计日志。
选项C:仪表板用户界面
首选 http://localhost:8080/dash,使用管理员密钥登录,切换到 外部MCP 选项卡,并填写表格。
管理API密钥
为您的团队或代理创建具有不同权限级别的密钥:
# Via MCP tools
gateway_create_key(
key_id="staging-bot",
label="Staging Bot",
permissions={"gmail": "read", "slack": "write"},
rate_limit=50
)
# Via REST API
POST /api/v1/call
{"tool": "gateway_create_key", "params": {"key_id": "staging-bot", ...}}
# Via dashboard
http://localhost:8080/dash/admin → Keys tab → + Create Key粒度速率限制
在任何粒度级别设置限制:
# Per plugin: max 30 Gmail calls/min
gateway_set_rate_limit(key_id="staging-bot", scope="plugin:gmail", rate_limit=30)
# Per account: max 10 calls/min to the "work" Calendly account
gateway_set_rate_limit(key_id="staging-bot", scope="account:calendly:work", rate_limit=10)
# Per tool: max 5 email sends/min
gateway_set_rate_limit(key_id="staging-bot", scope="tool:gmail_messages_send", rate_limit=5)捆绑插件
| 插件 | 服务 | 描述 |
|---|---|---|
gmail | Google Gmail API | 完整的电子邮件管理(发送、阅读、标签、草稿、过滤器、代表) |
calendly | 日历API | 事件类型、预定事件、受邀者、路由表单 |
linear | 线性API | 问题、项目、团队、评论、标签 |
notion | 通知API | 页面、数据库、块、搜索 |
slack | Slack Web API | 消息、频道、用户、反应、文件、用户组 |
bison | EmailBison API | 电子邮件活动管理、预热、工作区 |
ai_ark | AI Ark API | 人员/公司搜索、电子邮件查找、电话查找 |
whatsapp | WhatsApp(自托管网桥) | 发送/接收消息、媒体、联系人(需要Go网桥) |
所有插件都封装了公共API。通过从中删除文件来删除任何不需要的文件 plugins/.
部署到Fly.io
cp fly.toml.example fly.toml
# Edit fly.toml — set app name, region, MCP_BASE_URL
fly launch --no-deploy
fly secrets set MCP_AUTH_TOKEN=$(python3 -c "import secrets; print(secrets.token_urlsafe(32))")
fly volumes create gateway_data --size 1 --region iad
fly deploy建筑
┌─────────────────────────────────────────────┐
│ MCP Client (Agent) │
│ (Cursor, Claude, Opencode) │
└─────────────┬───────────────────────────────┘
│ MCP Protocol (Streamable HTTP)
│ or REST API (/api/v1/*)
▼
┌─────────────────────────────────────────────┐
│ uni-mcp-gateway │
│ │
│ ┌─────────┐ ┌──────────┐ ┌─────────────┐ │
│ │ Auth │ │ Audit │ │ Rate Limit │ │
│ └────┬────┘ └────┬─────┘ └──────┬──────┘ │
│ │ │ │ │
│ ┌────▼───────────▼──────────────▼──────┐ │
│ │ Plugin Registry │ │
│ │ ┌──────┐ ┌──────┐ ┌──────────────┐ │ │
│ │ │Gmail │ │Slack │ │External MCPs │ │ │
│ │ └──────┘ └──────┘ └──────────────┘ │ │
│ └──────────────────────────────────────┘ │
│ │
│ ┌────────────┐ ┌───────────────────────┐ │
│ │ Dashboard │ │ REST API Bridge │ │
│ └────────────┘ └───────────────────────┘ │
└─────────────────────────────────────────────┘配置
| 环境变量 | 默认值 | 描述 |
|---|---|---|
MCP_AUTH_TOKEN | (必需) | 用于引导的管理员API密钥 |
MCP_BASE_URL | http://localhost:8080 | 网关的公共URL |
GATEWAY_DB_PATH | /data/gateway.db | SQLite数据库路径 |
ADMIN_KEY_ID | admin | 管理员密钥的ID |
PORT / MCP_PORT | 8080 | 服务器端口 |
WHATSAPP_BRIDGE_URL | http://localhost:7481 | WhatsApp Go桥接URL |
许可证
麻省理工学院
