仅4MCP
具有基于角色的访问控制的经过身份验证的MCP(模型上下文协议)网关。Just4MCP位于您的MCP客户端(Claude Desktop等)和上游MCP服务器之间,通过任何符合OIDC的身份提供者和SurrealDB支持的细粒度工具级权限提供集中身份验证。
建筑
MCP Client (Claude Desktop, etc.)
→ Ingress (JWT validation via Keycloak JWKS)
→ FastAPI MCP Proxy (role extraction + tool ACL from SurrealDB)
→ Upstream MCP Server A
→ Upstream MCP Server B
→ ...特性
- OAuth2+PKCE身份验证 --使用机密客户端与任何OIDC提供商(Keycloak、Auth0、Okta、Azure AD等)配合使用(机密保留在服务器端)
- RFC 9728/RFC 8414 OAuth发现 --MCP客户端可以自动发现授权服务器
- 基于角色的访问控制 --SurrealDB中存储的每个组、每个工具的权限
- 每用户凭据 --需要用户特定令牌的上游MCP服务器的加密凭据存储
- 管理仪表盘 --用于管理MCP服务器注册、工具权限和组访问的web UI
- MCP协议代理 --透明的SSE/流式HTTP代理到上游服务器
- 热可重新加载配置 --可以在运行时通过管理UI添加/删除上游服务器
先决条件
- OIDC身份提供者 (Keycloak、Auth0、Okta、Azure AD等)——用于身份验证
- Docker&Docker编写 --促进地方发展
- Kubernetes集群 (k3s、k8s等)——用于生产部署
- 容器注册表 --托管您构建的图像
快速入门:Docker Compose
这是运行本地开发环境的最快方法。
1.克隆和配置
git clone
cd just4mcps/mcp-gateway
cp backend/.env.example backend/.env编辑 backend/.env 带上你的Keycloak细节:
KEYCLOAK_URL=https://your-keycloak.example.com
KEYCLOAK_REALM=your-realm
KEYCLOAK_CLIENT_ID=mcp-gateway
KEYCLOAK_CLIENT_SECRET=your-client-secret2.更新前端Keycloak配置
在 compose.yml,更新前端环境变量以匹配您的Keycloak实例:
environment:
- VITE_KEYCLOAK_URL=https://your-keycloak.example.com
- VITE_KEYCLOAK_REALM=your-realm
- VITE_KEYCLOAK_CLIENT_ID=mcp-gateway3.启动堆栈
docker compose up --build这将启动三项服务:
| 服务 | 端口 | 描述 |
|---|---|---|
| 网关 | 8000 | FastAPI后端 |
| 前端 | 5173 | React开发服务器(Vite) |
| surrealdb | 8001 | surrealdb数据库 |
4.打开仪表板
导航至 http://localhost:5173 并使用您的Keycloak凭据登录。从管理仪表板,您可以注册上游MCP服务器并配置工具权限。
部署:Kubernetes
1.创建命名空间
kubectl apply -f k8s/namespace/2.创造秘密
复制示例秘密模板并填写您的值:
cp k8s/proxy/secrets.example.yaml k8s/proxy/secrets.yaml
cp k8s/surrealdb/secrets.example.yaml k8s/surrealdb/secrets.yaml使用您的实际凭据编辑这两个文件。要生成加密密钥,请执行以下操作:
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"应用秘密:
kubectl apply -f k8s/surrealdb/secrets.yaml
kubectl apply -f k8s/proxy/secrets.yaml3.部署SurrealDB
kubectl apply -f k8s/surrealdb/
kubectl rollout status deployment/surrealdb -n mcp-platform --timeout=120s注: PVC在k8s/surrealdb/pvc.yaml没有storageClassName集。取消注释并将其设置为与集群的存储类相匹配(例如。standard,longhorn,local-path).
4.构建并推送容器镜像
构建后端和前端图像并将其推送到您的注册表:
# Backend
docker build -t your-registry.example.com/just4mcps/proxy:latest mcp-gateway/backend/
docker push your-registry.example.com/just4mcps/proxy:latest
# Frontend
docker build --target prod -t your-registry.example.com/just4mcps/frontend:latest mcp-gateway/frontend/
docker push your-registry.example.com/just4mcps/frontend:latest5.用你的价值观更新清单
在应用之前,请编辑这些文件以匹配您的环境:
k8s/proxy/deployment.yaml--映像注册表、Keycloak URL/realm/client、管理组、网关URL、CORS源k8s/proxy/ingressroute.yaml--域名、Keycloak JWKS URL、TLS证书解析器k8s/mcp-gateway/frontend/deployment.yaml--映像注册表,Keycloak URL/realm/client
6.部署代理和前端
kubectl apply -f k8s/proxy/
kubectl rollout status deployment/mcp-proxy -n mcp-platform --timeout=120s
kubectl apply -f k8s/mcp-gateway/frontend/
kubectl rollout status deployment/mcp-frontend -n mcp-platform --timeout=120s7.配置入口
包括 k8s/proxy/ingressroute.yaml 是Traefik入口路线。如果您使用不同的入口控制器(nginx、Istio等),请相应地调整路由规则。主要路线如下:
| 路径 | 需要JWT | 目的 |
|---|---|---|
/.well-known/oauth-* | 否 | MCP OAuth发现(RFC 9728) |
/api/auth/* | 否 | 令牌交换代理 |
/api/{slug}/mcp | 应用程序已验证 | MCP协议端点 |
/api/* | 是 | 管理员API |
/* | 否 | 前端SPA |
添加上游MCP服务器
部署后,上游MCP服务器完全通过管理仪表板进行管理,不需要进行清单更改。
- 使用属于配置的管理员组之一的帐户登录仪表板。
- 导航至 MCP服务器 然后单击 注册服务器.
- 提供服务器的名称、slug(URL安全标识符)和上游URL。
- 网关将自动连接并发现可用工具。
- 首选 群组 为Keycloak组分配工具级权限。
MCP客户端连接到 https://your-gateway.example.com/api/{slug}/mcp 并通过OAuth2-PKCE进行身份验证。网关透明地处理凭证注入和工具级访问控制。
配置参考
所有配置都是通过环境变量完成的。后端使用 媒染剂设置 --将它们设置在您的 .env 文件或直接在部署清单中。
| 变量 | 必填 | 默认 | 描述 |
|---|---|---|---|
KEYCLOAK_URL | 是 | -- | OIDC提供商的基本URL(例如。 https://auth.example.com) |
KEYCLOAK_REALM | 是 | -- | 领域或租户路径段(Keycloak:领域名称;其他:见下文注释) |
KEYCLOAK_CLIENT_ID | 是 | -- | OAuth2客户端ID |
KEYCLOAK_CLIENT_SECRET | 无 | -- | 客户机密(适用于机密客户) |
KEYCLOAK_GROUPS_CLAIM | 没有 | groups | 包含组/角色成员资格的JWT声明(适用于任何提供者) |
ADMIN_GROUPS | 没有 | ["/admins"] | 具有管理员访问权限的组路径的JSON列表 |
SURREAL_URL | 没有 | ws://localhost:8000/rpc | 超现实的websocket URL |
SURREAL_USER | 没有 | root | SurrealDB用户名 |
SURREAL_PASS | 没有 | root | SurrealDB密码 |
SURREAL_NAMESPACE | 没有 | just4mcps | SurrealDB命名空间 |
SURREAL_DATABASE | 没有 | mcp_gateway | SurrealDB数据库名称 |
GATEWAY_PUBLIC_URL | 否 | - | API的公共基础URL(包括/API前缀(如果适用)) |
CORS_ORIGINS | 没有 | ["http://localhost:5173"] | 允许的CORS源的JSON列表 |
CREDENTIAL_ENCRYPTION_KEY | 没有用于加密每个用户凭据的Fernet密钥 |
OIDC URL结构说明: 网关将OIDC端点构造为{KEYCLOAK_URL}/realms/{KEYCLOAK_REALM}/protocol/openid-connect/*,这与Keycloak的URL模式相匹配。对于其他提供商,设置KEYCLOAK_URL和KEYCLOAK_REALM以便生成的URL正确解析,或分叉keycloak_issuer财产在config.py以匹配您的提供商的发现端点结构。
前端环境变量
这些在容器开始时通过以下方式注入 docker-entrypoint.sh 进入 window.__env__:
| 变量 | 默认值 | 描述 |
|---|---|---|
VITE_API_URL | http://localhost:8000 | 后端API基本URL |
VITE_KEYCLOAK_URL | -- | OIDC提供商基本URL |
VITE_KEYCLOAK_REALM | -- | 领域/租户路径段 |
VITE_KEYCLOAK_CLIENT_ID | -- | OAuth2客户端ID |
身份提供者设置
Just4MCP可与任何符合OIDC标准的身份提供者配合使用。核心要求是:
- 一个机密的OAuth2客户端 --启用了授权码+PKCE授权
- JWT中的组/角色声明 --网关从可配置的JWT声明中读取组成员资格(默认值:
groups)实施RBAC
将重定向URI设置为 https://your-gateway.example.com/* 您的注销后重定向到 https://your-gateway.example.com.
该团体声称
这是关键部分。网关需要在访问令牌(或ID令牌)中包含一个包含组名或角色名数组的声明。索赔名称可通过以下方式配置 KEYCLOAK_GROUPS_CLAIM (无论名称如何,它都适用于任何提供商)。你的 ADMIN_GROUPS 列表必须与您的提供者在该声明中输入的值相匹配。
例如,如果您的提供商发出 "groups": ["/admins", "/developers"],然后设置 ADMIN_GROUPS='["/admins"]' 授予这些用户管理员权限。
供应商特定指导
钥匙锁:创建机密客户端,然后添加 组成员 映射到您的客户端范围,令牌声明名称设置为 groups.创建组(例如。 /admins)并分配用户。
身份验证0:创建常规Web应用程序。使用Auth0操作(登录流)在自定义声明下向访问令牌添加组/角色成员资格,如 https://your-app/groups.Set KEYCLOAK_GROUPS_CLAIM 以匹配该索赔名称。
八月:使用授权码+PKCE创建Web应用程序。将组声明添加到您的授权服务器(安全→ API → 默认→ 索赔)按您所需的组进行筛选。索赔名称应匹配 KEYCLOAK_GROUPS_CLAIM.
Azure AD / 登录 ID:注册应用程序,启用ID令牌,并配置 令牌配置 → 添加组声明默认情况下,Azure会发出组对象ID——您可能希望将其配置为发出组名,或者将ID映射到您的 ADMIN_GROUPS 配置。
发展
Docker Compose设置包括后端和前端的热重新加载:
cd mcp-gateway
docker compose up --build --watch- 后端更改
backend/app/触发自动重启。 - Vite的开发服务器会立即接收前端更改。
许可证
此项目根据MIT许可证获得许可——请参阅 许可证 了解详情。
