# MCP HTTP服务器使用指南

## 概述

`mcp_http_server.py` 是基于**无状态HTTP/SSE传输**的MCP服务器实现，与`mcp_server.py`（STDIO传输）的主要区别在于传输层的不同。

## 架构对比

### STDIO传输 (`mcp_server.py`)
- **传输方式**: 标准输入/输出流（stdin/stdout）
- **使用场景**: 本地进程通信、命令行工具集成
- **启动方式**: 直接运行Python脚本
- **通信方式**: 通过进程的标准输入输出进行JSON-RPC通信

### HTTP/SSE传输 (`mcp_http_server.py`) ✨
- **传输方式**: HTTP + Server-Sent Events (SSE)
- **使用场景**: 远程访问、Web应用集成、微服务架构
- **启动方式**: HTTP服务器（默认端口8000）
- **通信方式**: 通过HTTP endpoint进行JSON-RPC通信

## 技术实现

### 核心技术栈
- **Web框架**: FastAPI
- **ASGI服务器**: Uvicorn
- **MCP传输**: `mcp.server.sse.SseServerTransport`
- **无状态设计**: 每个请求独立创建RAGSystem实例

### 架构特点

1. **无状态设计**
   - 每次请求独立创建RAG系统实例
   - 不保存会话状态，便于水平扩展
   - 每个工具调用都是独立的事务

2. **HTTP/SSE传输**
   - SSE用于服务器到客户端的推送
   - POST用于客户端到服务器的消息
   - 完全兼容MCP协议规范

3. **CORS支持**
   - 支持跨域请求（默认允许所有来源）
   - 生产环境应配置具体域名白名单

## 快速开始

### 1. 启动服务器

```bash
# 方式1: 直接运行
python mcp_http_server.py

# 方式2: 使用Uvicorn（推荐用于生产环境）
uvicorn mcp_http_server:app --host 0.0.0.0 --port 8000 --reload
```

### 2. 验证服务

启动后，服务器将在以下地址提供服务：

```
✅ 主页: http://localhost:8000/
✅ 健康检查: http://localhost:8000/health
✅ SSE端点: http://localhost:8000/sse
✅ 消息端点: http://localhost:8000/messages (POST)
✅ API文档: http://localhost:8000/docs
```

### 3. 测试连接

#### 使用浏览器
访问 http://localhost:8000/ 查看服务信息

#### 使用curl测试健康检查
```bash
curl http://localhost:8000/health
```

返回示例：
```json
{
  "status": "healthy",
  "server": "RAG MCP Server",
  "transport": "HTTP/SSE"
}
```

## API端点说明

### 1. 根路径 `GET /`
返回服务器基本信息和可用端点

**响应示例**:
```json
{
  "name": "RAG MCP Server",
  "version": "1.0.0",
  "transport": "HTTP/SSE",
  "endpoints": {
    "sse": "/sse",
    "health": "/health",
    "docs": "/docs"
  }
}
```

### 2. 健康检查 `GET /health`
用于监控和负载均衡器的健康检查

### 3. SSE端点 `GET /sse`
MCP协议的SSE通信端点
- 客户端通过此端点建立SSE连接
- 服务器通过SSE推送响应消息

### 4. 消息端点 `POST /messages`
接收客户端发送的MCP消息
- Content-Type: application/json
- Body: MCP协议JSON-RPC消息

## MCP功能

服务器提供与STDIO版本完全相同的MCP功能：

### Tools（工具）
1. **build_index** - 构建知识库索引
2. **query_knowledge** - 查询知识库
3. **get_index_status** - 获取索引状态
4. **delete_index** - 删除索引

### Resources（资源）
1. **config://system** - 系统配置信息
2. **stats://index** - 索引统计信息

### Prompts（提示词）
1. **rag_query** - RAG查询提示词模板

详细功能说明请参考主README.md

## 客户端连接示例

### Python客户端示例

```python
import httpx
import json

# 创建HTTP客户端
class MCPHTTPClient:
    def __init__(self, base_url="http://localhost:8000"):
        self.base_url = base_url
        self.client = httpx.Client()
    
    def call_tool(self, tool_name: str, arguments: dict):
        """调用MCP工具"""
        message = {
            "jsonrpc": "2.0",
            "method": "tools/call",
            "params": {
                "name": tool_name,
                "arguments": arguments
            },
            "id": 1
        }
        
        response = self.client.post(
            f"{self.base_url}/messages",
            json=message
        )
        
        return response.json()

# 使用示例
client = MCPHTTPClient()

# 查询知识库
result = client.call_tool("query_knowledge", {
    "question": "什么是RAG？",
    "mode": "hybrid",
    "top_k": 3
})

print(result)
```

### JavaScript/TypeScript客户端示例

```typescript
// 使用Fetch API
async function callMCPTool(toolName: string, args: any) {
  const response = await fetch('http://localhost:8000/messages', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      jsonrpc: '2.0',
      method: 'tools/call',
      params: {
        name: toolName,
        arguments: args
      },
      id: 1
    })
  });
  
  return await response.json();
}

// 使用示例
const result = await callMCPTool('query_knowledge', {
  question: '什么是RAG？',
  mode: 'hybrid',
  top_k: 3
});
```

## 配置选项

### 环境变量

服务器配置通过环境变量管理（与STDIO版本共用`.env`配置）：

```bash
# 主要配置项
DEEPSEEK_API_KEY=your-api-key
SILICONFLOW_API_KEY=your-api-key
USE_QDRANT=True
QDRANT_URL=your-qdrant-url
```

详细配置说明请参考主README.md

### 服务器配置

在`mcp_http_server.py`中修改：

```python
# 修改监听地址和端口
HOST = "0.0.0.0"  # 监听所有网络接口
PORT = 8000       # 监听端口

# CORS配置
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 生产环境应改为具体域名列表
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
```

## 生产部署建议

### 1. 使用进程管理器

**使用Supervisor**:
```ini
[program:mcp-http-server]
command=/path/to/venv/bin/python /path/to/mcp_http_server.py
directory=/path/to/project
autostart=true
autorestart=true
stderr_logfile=/var/log/mcp-http-server.err.log
stdout_logfile=/var/log/mcp-http-server.out.log
```

**使用systemd**:
```ini
[Unit]
Description=MCP HTTP Server
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/path/to/project
Environment="PATH=/path/to/venv/bin"
ExecStart=/path/to/venv/bin/python /path/to/mcp_http_server.py
Restart=always

[Install]
WantedBy=multi-user.target
```

### 2. 反向代理配置

**Nginx示例**:
```nginx
server {
    listen 80;
    server_name mcp.example.com;

    location / {
        proxy_pass http://localhost:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # SSE相关配置
        proxy_buffering off;
        proxy_cache off;
        chunked_transfer_encoding off;
    }
}
```

### 3. 安全加固

1. **限制CORS来源**
   ```python
   allow_origins=["https://example.com"]
   ```

2. **添加认证中间件**
   ```python
   from fastapi.security import HTTPBearer
   
   security = HTTPBearer()
   
   @app.get("/sse")
   async def sse_endpoint(credentials: HTTPAuthorizationCredentials = Depends(security)):
       # 验证token
       pass
   ```

3. **使用HTTPS**
   - 配置SSL证书
   - 使用Let's Encrypt

4. **限流保护**
   ```python
   from slowapi import Limiter
   from slowapi.util import get_remote_address
   
   limiter = Limiter(key_func=get_remote_address)
   app.state.limiter = limiter
   ```

### 4. 监控和日志

1. **结构化日志**
   ```python
   logger.add("logs/mcp_http_{time}.log", rotation="1 day", retention="7 days")
   ```

2. **性能监控**
   - 使用Prometheus + Grafana
   - 集成APM工具（如New Relic、DataDog）

3. **健康检查**
   - 配置负载均衡器使用`/health`端点
   - 监控响应时间和错误率

## 性能优化

### 1. 启用多worker

```bash
uvicorn mcp_http_server:app --workers 4 --host 0.0.0.0 --port 8000
```

### 2. 异步优化

服务器已经使用异步架构，但可以进一步优化：

```python
# 使用连接池
from qdrant_client import AsyncQdrantClient

# 复用embedding客户端
# 在应用启动时创建，在关闭时清理
```

### 3. 缓存策略

对于频繁查询的配置和索引状态，可以添加缓存：

```python
from functools import lru_cache

@lru_cache(maxsize=1)
def get_config_cached():
    return Config.display()
```

## 故障排查

### 问题1: 服务器无法启动

**检查项**:
1. 端口是否被占用
   ```bash
   netstat -ano | findstr :8000  # Windows
   lsof -i :8000                 # Linux/Mac
   ```

2. 依赖是否安装完整
   ```bash
   pip install -r requirements.txt
   ```

3. 环境变量是否配置
   ```bash
   # 检查.env文件
   cat .env
   ```

### 问题2: SSE连接失败

**检查项**:
1. 浏览器是否支持SSE
2. 反向代理配置是否正确（需要关闭buffering）
3. 防火墙是否阻止连接

### 问题3: 工具调用失败

**检查项**:
1. 查看服务器日志
2. 验证请求格式是否符合MCP协议
3. 检查RAG系统初始化是否成功

## 与STDIO版本的选择

### 使用HTTP版本的场景
✅ 需要远程访问MCP服务
✅ 构建Web应用或微服务
✅ 需要负载均衡和扩展
✅ 多客户端同时访问
✅ 云原生部署

### 使用STDIO版本的场景
✅ 本地开发和测试
✅ 命令行工具集成
✅ 简单的单机部署
✅ Claude Desktop等本地客户端

## 扩展开发

### 添加新的HTTP端点

```python
@app.get("/custom-endpoint")
async def custom_endpoint():
    """自定义端点"""
    return {"message": "Custom endpoint"}
```

### 添加WebSocket支持

```python
from fastapi import WebSocket

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    # WebSocket通信逻辑
```

### 集成认证

```python
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

async def get_current_user(token: str = Depends(oauth2_scheme)):
    # 验证token并返回用户
    pass

@app.get("/sse")
async def sse_endpoint(current_user = Depends(get_current_user)):
    # 已认证的用户才能访问
    pass
```

## 总结

HTTP版本的MCP服务器提供了更灵活的部署方式，适合生产环境和分布式架构。通过HTTP/SSE传输，可以轻松集成到现有的Web基础设施中，支持远程访问和横向扩展。

选择合适的传输方式取决于您的具体需求：
- **本地开发/简单部署** → 使用STDIO版本
- **生产环境/远程访问** → 使用HTTP版本

两个版本提供完全相同的MCP功能，可以根据需要灵活切换。
