MCP工具提供商
](https://www.python.org/downloads/)        ](docker-compose.yml)    
⚠️ 进行中 -该项目正在积极开发中。API和功能可能会更改,恕不另行通知。
这是什么?
MCP工具提供商 是一个平台,使组织能够将其AI助手安全地连接到现有的业务系统。管理员只需注册一次API,平台就可以处理发现、授权和安全执行,而不是为每个AI工具构建自定义集成。
两个应用,一个解决方案
| 应用程序 | 目的 | 谁使用它 |
|---|---|---|
| 🔧 工具提供者 | 后端服务,管理员注册API,将工具组织成组,并定义谁可以访问什么 | IT管理员、平台工程师 |
| 🤖 代理主机 | 聊天界面,最终用户与可以安全调用授权工具的AI助手进行交互 | 业务用户、客户 |
为什么使用这个?
- 🔐 企业级安全:用户只能看到他们有权使用的工具。AI助手代表登录用户行事,从不使用提升的权限。
- 📋 完成审计跟踪:每个动作都被记录为一个不可变的事件——谁做了什么,什么时候,通过什么工具。非常适合合规和故障排除。
- 🔧 零代码集成:将平台指向任何OpenAPI记录的服务,工具就会自动被发现并可用。
- 👥 灵活的访问控制:按部门、项目或职能对工具进行分组。根据用户角色或身份提供者的自定义声明分配访问权限。
- 📡 完全可观察性:用于生产监控和调试的内置跟踪、指标和结构化日志记录。
主要特点
| 特性 | 描述 |
|---|---|
| 工具发现 | 自动从OpenAPI v3规范中获取和规范化工具 |
| 工具管理 | 使用基于模式的选择器、显式成员资格和排除列表对工具进行分组 |
| 双重身份验证 | OAuth2/OIDC用于web会话+JWT Bearer令牌用于程序化访问 |
| 身份委派 | 工具通过RFC 8693令牌交换使用最终用户的身份执行 |
| 事件溯源 | 所有更改都存储为事件——重建状态、重放历史记录、永不丢失数据 |
| 实时更新 | 服务器发送的事件在工具或策略更改时通知连接的客户端 |
阅读 全部文件 在https://bvandewe.github.io/tools-provider
🏗️ 建筑
MCP工具提供商充当 动态投影引擎 即:
- 发现 OpenAPI端点(和未来的工作流引擎)的功能
- 正常化 将其纳入标准MCP工具定义
- 助理牧师 将它们分为具有细粒度端点选择的逻辑工具组
- 使安全 通过Keycloak使用JWT基于索赔的策略进行访问
系统架构
graph TD
subgraph "Admin Operations"
Admin[Admin UI/API] --> Commands[CQRS Commands]
Commands --> Sources[UpstreamSource]
Commands --> Tools[SourceTool]
end
subgraph "Event Store - Write Model"
Sources --> KurrentDB[(KurrentDB)]
Tools --> KurrentDB
end
subgraph "Projections - Read Model"
KurrentDB --> Projector[Event Projector]
Projector --> MongoDB[(MongoDB)]
Projector --> Redis[(Redis Cache)]
end
subgraph "Agent Runtime"
Agent((AI Agent)) --> API[REST API]
API --> Queries[CQRS Queries]
Queries --> MongoDB
Agent --> Executor[Tool Executor]
Executor --> Keycloak{Keycloak}
Keycloak --> Upstream[Upstream Services]
end数据库体系结构
| 层 | 技术 | 目的 |
|---|---|---|
| 写入模型 | KurrentDB(EventStoreDB) | 事件持久性、审计跟踪、聚合流 |
| 读取模型 | MongoDB | 复杂查询、全文搜索、可查询投影 |
| 缓存层 | Redis | 会话、解析清单、发布/订阅通知 |
域聚合
UpstreamSource:通过健康监测管理与外部OpenAPI服务和MCP插件的连接SourceTool:具有管理员启用/禁用控件的单个工具/端点ToolGroup:使用基于模式的选择器、显式成员资格和排除列表来管理工具AccessPolicy:将JWT声称允许的工具组映射为基于优先级的解决方案Label:工具的分类元数据
源类型
| 类型 | 描述 | 发现方法 |
|---|---|---|
| 开放API | 具有OpenAPI v3规范的REST API | 解析规范、提取操作 |
| 主控程序 | 模型上下文协议插件 | 连接到服务器,调用 tools/list |
| 工作流程 | 无服务器工作流定义 | 解析工作流,提取操作 |
| 内置 | 内部平台工具 | 静态注册 |
MCP插件支持
该平台支持本地MCP插件,可与任何兼容MCP的工具服务器集成:
POST /api/sources
{
"name": "cml-mcp",
"url": "file:///app/plugins/cml-mcp",
"source_type": "mcp",
"mcp_plugin_dir": "/app/plugins/cml-mcp",
"mcp_transport_type": "stdio",
"mcp_lifecycle_mode": "transient",
"mcp_runtime_hint": "uvx",
"mcp_env_vars": {
"CML_URL": "${secrets:cml-url}",
"CML_TOKEN": "${secrets:cml-token}"
}
}MCP功能:
- 自动发现:通过MCP发现工具
tools/list方法 - 运输选项:支持
stdio,sse,以及http运输 - 生命周期模式:
transient(每次通话的新流程)或singleton(持续) - 秘密决议:环境变量可以引用秘密存储
看 MCP插件指南 详细文档。
项目结构
tools-provider/ # Repository root
├── src/
│ ├── tools-provider/ # Main MCP Tools Provider service
│ │ ├── main.py # FastAPI app factory with Neuroglia DI
│ │ ├── api/ # REST API layer
│ │ │ ├── controllers/ # Sources, Tools, Groups, Policies, Agent
│ │ │ ├── dependencies.py # Auth dependencies (session + JWT)
│ │ │ └── services/ # DualAuthService, OpenAPI config
│ │ ├── application/ # CQRS handlers
│ │ │ ├── commands/ # Write operations (Create*, Update*, Delete*)
│ │ │ ├── queries/ # Read operations (Get*, Search)
│ │ │ ├── events/ # Domain & integration event handlers
│ │ │ └── services/ # ToolExecutor, OpenAPISourceAdapter
│ │ ├── domain/ # Pure domain model
│ │ │ ├── entities/ # Aggregates: Source, Tool, Group, Policy, Label
│ │ │ ├── events/ # Domain events with @cloudevent decorator
│ │ │ └── repositories/ # Repository interfaces (ports)
│ │ ├── integration/ # Concrete implementations
│ │ │ ├── models/ # DTOs with @queryable decorator
│ │ │ └── repositories/ # Motor (MongoDB) repositories
│ │ ├── infrastructure/ # External adapters (Redis, Keycloak)
│ │ ├── ui/ # Admin UI (Bootstrap 5 + Parcel)
│ │ └── tests/ # Pytest suites (domain, application)
│ ├── agent-host/ # Chat interface BFF service
│ │ ├── main.py # FastAPI app with ReActAgent
│ │ ├── api/controllers/ # Chat, Auth, Settings endpoints
│ │ ├── application/ # Commands, Queries, ChatService
│ │ ├── domain/entities/ # Conversation aggregate
│ │ └── ui/ # Chat UI (Bootstrap 5 + Parcel)
│ └── upstream-sample/ # Sample Pizzeria OpenAPI service
│ └── app/ # FastAPI demo backend
├── docs/ # MkDocs documentation
├── deployment/ # Keycloak realm, OTEL collector config
├── docker-compose.yml # Full local stack
└── Makefile # Root orchestration commands🚀 快速开始
先决条件
- Python 3.12+
- 诗歌
- Node.js 20+(用于UI构建)
- Docker&Docker编写
快速设置(推荐)
使用Makefile进行轻松设置和管理:
# Complete setup for new developers
make setup
# Start infrastructure (KurrentDB, MongoDB, Keycloak, Redis)
make up
# Run the application locally
make run
# See all available commands
make helpDocker开发
使用Docker Compose运行完整的堆栈:
# Build and start all services
make up
# View logs
make logs
# Stop services
make down这将开始:
- ✅ 工具提供商应用程序(http://localhost:8040)
- ✅ API文件(http://localhost:8040/api/docs)
- ✅ KurrentDB(http://localhost:2113)-活动商店
- ✅ MongoDB+Mongo Express(http://localhost:8043)
- ✅ 钥匙斗篷(http://localhost:8041)
- ✅ Redis(本地主机:6379)
- ✅ 开放遥测采集器
👥 测试用户
该应用程序包括具有不同角色的测试用户:
| 用户名 | 密码 | 角色 | 访问级别 |
|---|---|---|---|
| admin | test | admin | 完全管理员权限,可以注册/删除源 |
| 用户 | 测试 | 用户 | 对工具的只读访问 |
看 部署/钥匙斗篷/ 用于领域配置。
🔐 认证
工具提供商支持 双重身份验证:
1.OAuth2/OIDC(基于会话)
- 带Keycloak的前端图案后端
- 存储在Redis中的会话Cookie
- 由管理员UI使用
2.JWT承载代币
- 无状态API身份验证
- 用于AI代理的程序化访问
- 通过Keycloak JWKS验证RS256签名
基于角色的访问控制
- 管理员:可以注册源、刷新库存、删除源/工具
- 用户:可以列出和搜索工具
# Admin-only endpoints use require_roles dependency
@delete("/{source_id}")
async def delete_source(self, user: dict = Depends(require_roles("admin"))):
...📡 API终点
来源(上游OpenAPI服务)
| 方法 | 端点 | 角色 | 描述 |
|---|---|---|---|
| 得到 | /api/sources | user | 列出所有已注册的源 |
| 得到 | /api/sources/{id} | user | 获取源详细信息 |
| 职位 | /api/sources | admin | 注册新的OpenAPI源 |
| 职位 | /api/sources/{id}/refresh | admin | 刷新工具清单 |
| 删除 | /api/sources/{id} | admin | 删除源代码(级联到工具) |
工具(从来源发现)
| 方法 | 端点 | 角色 | 描述 |
|---|---|---|---|
| 得到 | /api/tools | user | 列出所有工具 |
| 得到 | /api/tools/{id} | user | 获取工具详细信息 |
| 得到 | /api/tools/search | 用户 | 按名称/描述搜索工具 |
| 删除 | /api/tools/{id} | admin | 删除单个工具 |
| 删除 | /api/tools/orphaned/cleanup | admin | 清理孤立的工具 |
工具组(工具管理)
| 方法 | 端点 | 角色 | 描述 |
|---|---|---|---|
| 得到 | /api/tool-groups | user | 列出所有工具组 |
| 得到 | /api/tool-groups/{id} | user | 获取组详细信息 |
| 得到 | /api/tool-groups/{id}/tools | 用户 | 解析组中的工具 |
| 职位 | /api/tool-groups | admin | 创建工具组 |
| PUT | /api/tool-groups/{id} | admin | 更新组元数据 |
| 职位 | /api/tool-groups/{id}/selectors | admin | 添加模式选择器 |
| 删除 | /api/tool-groups/{id}/selectors/{idx} | admin | 删除选择器 |
| 职位 | /api/tool-groups/{id}/tools | admin | 添加显式工具 |
| 删除 | /api/tool-groups/{id}/tools/{tool_id} | admin | 删除显式工具 |
| 职位 | /api/tool-groups/{id}/exclude | admin | 从组中排除工具 |
| 删除 | /api/tool-groups/{id}/exclude/{tool_id} | admin | 包括排除的工具 |
| 删除 | /api/tool-groups/{id} | admin | 删除工具组 |
访问策略(授权)
| 方法 | 端点 | 角色 | 描述 |
|---|---|---|---|
| 得到 | /api/policies | user | 列出所有访问策略 |
| 得到 | /api/policies/{id} | user | 获取策略详细信息 |
| 职位 | /api/policies | admin | 定义新的访问策略 |
| PUT | /api/policies/{id} | admin | 更新策略 |
| 职位 | /api/policies/{id}/activate | admin | 激活策略 |
| 职位 | /api/policies/{id}/deactivate | admin | 停用策略 |
| 删除 | /api/policies/{id} | admin | 删除策略 |
代理API(工具发现和执行)
| 方法 | 端点 | 身份验证 | 描述 |
|---|---|---|---|
| 得到 | /api/agent/tools | JWT | 让经过身份验证的用户可以访问工具 |
| 职位 | /api/agent/tools/call | JWT | 使用身份委托执行工具 |
| 得到 | /api/agent/sse | JWT | SSE流用于实时工具更新 |
🛠️ 配置
环境变量
关键配置选项(请参见 src/application/settings.py):
# Application
APP_HOST=127.0.0.1
APP_PORT=8040
# Keycloak OAuth2/OIDC
KEYCLOAK_URL=http://localhost:8041
KEYCLOAK_REALM=tools-provider
KEYCLOAK_CLIENT_ID=tools-provider-public
# Database connections (JSON)
CONNECTION_STRINGS='{"eventstore": "esdb://...", "mongo": "mongodb://..."}'
# Redis
REDIS_ENABLED=true
REDIS_URL=redis://redis:6379/0
# OpenTelemetry
OTEL_ENABLED=true
OTEL_ENDPOINT=http://otel-collector:4317📚 文档
API 文档
跑步后,请访问http://localhost:8040/api/docs用于交互式Swagger文档。
设计规范
详细设计文件见 docs/specs/:
- tools-provider.md -带领域模型的完整项目规范
- 设计审查.md -架构审查和建议
- 实施计划.md -分阶段实施路线图
- 模式映射.md -神经胶质细胞图谱
🧰 Makefile命令
Docker命令
make up # Start all services in background
make down # Stop and remove services
make logs # Show logs from all services
make rebuild # Rebuild from scratch (no cache)地方发展
make setup # Complete setup (Python + Node deps, build UI)
make run # Run application locally with hot-reload
make run-debug # Run with LOG_LEVEL=DEBUG测试与质量
make test # Run all tests
make test-cov # Run tests with coverage report
make lint # Run linting checks (Ruff)
make format # Format code with Black🧪 测试
# Run all tests
poetry run pytest
# Run with coverage
poetry run pytest --cov=. --cov-report=html
# Run specific test categories
make test-domain # Domain layer tests
make test-application # CQRS handler tests🔗 相关文件
🪝 预提交钩子
自动格式化、linting和安全检查在您提交之前运行。
包含内容
- 黑色(Python格式)+isort(导入)
- 绒毛(棉绒)
- Bandit(Python安全扫描)
设置
poetry run pre-commit install --install-hooks
poetry run pre-commit run --all-files📦 部署
生产清单
- \[\]为生产OAuth/OIDC配置Keycloak
- \[\]为事件存储设置KurrentDB集群
- \[\]配置MongoDB副本集
- \[\]启用Redis进行会话存储
- \[\]为生产域配置CORS
- \[\]设置OpenTetry收集器终结点
- \[\]使用特定于环境的配置
Docker生产构建
docker build -t tools-provider:latest .
docker run -p 8040:8040 tools-provider:latest🤝 贡献
该项目遵循Neuroglia Python框架模式和清洁架构原则。
📄 许可证
根据Apache许可证2.0版授权。看 LICENSE 全文。
______________________________________________________________________
内置于❤️ 使用 神经胶质细胞Python框架
