180 lines
5.8 KiB
Markdown
180 lines
5.8 KiB
Markdown
|
|
# MCP 集成系统
|
|||
|
|
|
|||
|
|
## 概述
|
|||
|
|
|
|||
|
|
这是一个统一的外部接口管理层,集成了 MCP (Model Context Protocol),同时支持数据库缓存和降级到模拟数据。
|
|||
|
|
|
|||
|
|
## 架构设计
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────────┐
|
|||
|
|
│ 子图 (Subgraphs) │
|
|||
|
|
│ contact_api │ dictionary_api │ news_api │
|
|||
|
|
└─────────────────────────────────────────────────────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────────────────────────────────────────────┐
|
|||
|
|
│ MCP Manager (统一入口) │
|
|||
|
|
│ ┌─────────────────────────────────────────────────┐ │
|
|||
|
|
│ │ Adapters (适配器层) │ │
|
|||
|
|
│ │ ContactAdapter │ DictionaryAdapter │ NewsAdapter│ │
|
|||
|
|
│ └─────────────────────────────────────────────────┘ │
|
|||
|
|
└─────────────────────────────────────────────────────────┘
|
|||
|
|
│
|
|||
|
|
┌─────────────────┼─────────────────┐
|
|||
|
|
▼ ▼ ▼
|
|||
|
|
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|||
|
|
│ MCP Client │ │ Database │ │ Mock Data │
|
|||
|
|
│ (真实服务) │ │ (缓存层) │ │ (降级层) │
|
|||
|
|
└──────────────┘ └──────────────┘ └──────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 目录结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
backend/app/mcp/
|
|||
|
|
├── __init__.py # 模块初始化
|
|||
|
|
├── mcp_manager.py # MCP管理器(统一入口)
|
|||
|
|
├── mcp_client.py # MCP客户端
|
|||
|
|
├── base_adapter.py # 适配器基类
|
|||
|
|
├── mcp_config.example.yaml # 配置示例
|
|||
|
|
├── mcp_example.py # 使用示例
|
|||
|
|
└── adapters/
|
|||
|
|
├── __init__.py
|
|||
|
|
├── contact_adapter.py # 通讯录适配器
|
|||
|
|
├── dictionary_adapter.py# 词典适配器
|
|||
|
|
└── news_adapter.py # 新闻适配器
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 快速开始
|
|||
|
|
|
|||
|
|
### 1. 基本使用(自动降级)
|
|||
|
|
|
|||
|
|
现有的子图API已经无缝迁移,无需修改代码:
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# 通讯录 - 和之前一样使用
|
|||
|
|
from backend.app.subgraphs.contact.api_client import contact_api
|
|||
|
|
|
|||
|
|
contacts = await contact_api.list_contacts(user_id="default")
|
|||
|
|
|
|||
|
|
# 词典 - 和之前一样使用
|
|||
|
|
from backend.app.subgraphs.dictionary.api_client import dictionary_api
|
|||
|
|
|
|||
|
|
word_data = await dictionary_api.query_word(word="ephemeral")
|
|||
|
|
|
|||
|
|
# 新闻 - 和之前一样使用
|
|||
|
|
from backend.app.subgraphs.news_analysis.api_client import news_api
|
|||
|
|
|
|||
|
|
news_list = await news_api.query_news(query="AI")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 直接使用MCP管理器
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from backend.app.mcp import mcp_manager, ContactAdapter, DictionaryAdapter, NewsAdapter
|
|||
|
|
|
|||
|
|
# 注册适配器
|
|||
|
|
mcp_manager.register_adapter(ContactAdapter())
|
|||
|
|
mcp_manager.register_adapter(DictionaryAdapter())
|
|||
|
|
mcp_manager.register_adapter(NewsAdapter())
|
|||
|
|
|
|||
|
|
# 初始化
|
|||
|
|
await mcp_manager.initialize()
|
|||
|
|
|
|||
|
|
# 统一调用接口
|
|||
|
|
result = await mcp_manager.execute(
|
|||
|
|
"dictionary",
|
|||
|
|
"query_word",
|
|||
|
|
word="serendipity",
|
|||
|
|
user_id="default"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
print(f"来源: {result.source}") # mcp_dictionary / database / mock
|
|||
|
|
print(f"数据: {result.data}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 配置MCP服务器
|
|||
|
|
|
|||
|
|
复制配置示例:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cp backend/app/mcp/mcp_config.example.yaml backend/app/mcp/mcp_config.yaml
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
编辑 `mcp_config.yaml`,启用需要的MCP服务器:
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
mcp_servers:
|
|||
|
|
# Gmail 邮件服务
|
|||
|
|
gmail:
|
|||
|
|
type: stdio
|
|||
|
|
command: npx
|
|||
|
|
args:
|
|||
|
|
- "-y"
|
|||
|
|
- "@modelcontextprotocol/server-gmail"
|
|||
|
|
enabled: true
|
|||
|
|
|
|||
|
|
# GitHub
|
|||
|
|
github:
|
|||
|
|
type: stdio
|
|||
|
|
command: npx
|
|||
|
|
args:
|
|||
|
|
- "-y"
|
|||
|
|
- "@modelcontextprotocol/server-github"
|
|||
|
|
env:
|
|||
|
|
GITHUB_PERSONAL_ACCESS_TOKEN: "ghp_your_token_here"
|
|||
|
|
enabled: true
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 特性
|
|||
|
|
|
|||
|
|
### 1. 三层降级策略
|
|||
|
|
|
|||
|
|
- **MCP层**: 优先使用真实的MCP服务
|
|||
|
|
- **数据库层**: 其次使用数据库缓存
|
|||
|
|
- **模拟层**: 最后降级到模拟数据,确保系统始终可用
|
|||
|
|
|
|||
|
|
### 2. 统一接口
|
|||
|
|
|
|||
|
|
所有外部服务都通过 `mcp_manager.execute()` 统一调用,返回标准化的 `AdapterResult`。
|
|||
|
|
|
|||
|
|
### 3. 向后兼容
|
|||
|
|
|
|||
|
|
保留了原有的 `api_client` 接口,现有代码无需修改即可使用新系统。
|
|||
|
|
|
|||
|
|
### 4. 可扩展
|
|||
|
|
|
|||
|
|
通过继承 `BaseAdapter` 可以轻松添加新的适配器。
|
|||
|
|
|
|||
|
|
## 创建自定义适配器
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from backend.app.mcp import BaseAdapter, AdapterResult
|
|||
|
|
|
|||
|
|
class MyAdapter(BaseAdapter):
|
|||
|
|
name = "my_service"
|
|||
|
|
description = "我的自定义服务"
|
|||
|
|
|
|||
|
|
async def execute(self, action: str, **kwargs) -> AdapterResult:
|
|||
|
|
# 1. 尝试MCP
|
|||
|
|
# 2. 尝试数据库
|
|||
|
|
# 3. 降级到模拟
|
|||
|
|
pass
|
|||
|
|
|
|||
|
|
# 注册
|
|||
|
|
mcp_manager.register_adapter(MyAdapter())
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 可用的MCP服务器
|
|||
|
|
|
|||
|
|
- **@modelcontextprotocol/server-filesystem** - 文件系统访问
|
|||
|
|
- **@modelcontextprotocol/server-github** - GitHub 集成
|
|||
|
|
- **@modelcontextprotocol/server-gmail** - Gmail 邮件
|
|||
|
|
- **@modelcontextprotocol/server-brave-search** - 网页搜索
|
|||
|
|
- 更多社区服务器...
|
|||
|
|
|
|||
|
|
## 完整示例
|
|||
|
|
|
|||
|
|
参见 `backend/app/mcp/mcp_example.py` 获取完整的使用示例。
|