README.md•9.93 kB
# 本地 MCP 服务器
一个模块化、生产就绪的模型上下文协议 (MCP) 服务器,为 LangGraph 代理和其他 MCP 客户端提供计算器和文件操作工具。
## 功能特性
- **18 个工具**:10 个计算器工具 + 8 个文件操作工具
- **异步支持**:完全的异步/等待支持,优化性能
- **沙箱安全**:文件操作限制在工作区目录内
- **可配置**:基于 YAML 的配置,支持环境变量覆盖
- **日志记录**:多级日志记录,支持轮转(文件 + 控制台)
- **类型安全**:完整的类型注解和验证
- **模块化**:易于添加新的工具类别
## 架构
```
local_mcp_server/
├── src/
│ ├── server.py # MCP 服务器实现
│ ├── config.py # 配置管理
│ ├── logger.py # 日志设置
│ └── tools/
│ ├── base.py # 工具注册和 @tool 装饰器
│ ├── calculator/ # 10 个计算工具
│ │ ├── basic.py # 加、减、乘、除
│ │ └── advanced.py # 幂、平方根、对数、正弦、余弦、正切
│ └── file_ops/ # 8 个文件操作工具
│ ├── read.py # 读取、按行读取、检查存在、列表
│ └── write.py # 写入、追加、创建、删除
├── config/
│ └── default.yaml # 默认配置
├── workspace/ # 文件操作沙箱
├── logs/ # 服务器日志
└── examples/
├── test_client.py # 简单 MCP 客户端测试
└── langgraph_integration.py # LangGraph 集成示例
```
## 工具
### 计算器工具(10 个)
**基本操作:**
- `calculator_add`:两数相加
- `calculator_subtract`:两数相减
- `calculator_multiply`:两数相乘
- `calculator_divide`:两数相除(含零检查)
**高级操作:**
- `calculator_power`:计算 base^exponent
- `calculator_sqrt`:计算平方根(验证非负数)
- `calculator_log`:计算对数(支持自定义底数)
- `calculator_sin`:计算正弦(角度/弧度)
- `calculator_cos`:计算余弦(角度/弧度)
- `calculator_tan`:计算正切(角度/弧度)
### 文件操作工具(8 个)
**读取操作:**
- `file_read`:读取完整文件内容
- `file_read_lines`:读取文件的特定行
- `file_exists`:检查文件是否存在
- `file_list`:列出文件(支持 glob 模式)
**写入操作:**
- `file_write`:写入/覆盖文件内容
- `file_append`:追加内容到文件
- `file_create`:创建新文件(如存在则失败)
- `file_delete`:删除文件
**安全特性:**
- 仅接受相对路径(相对于工作区)
- 沙箱强制执行(所有路径必须在工作区内)
- 路径遍历防护
- 文件扩展名过滤
- 文件大小限制(默认:10MB)
## 安装
### 1. 安装依赖
```bash
# 创建虚拟环境(推荐)
python -m venv venv
source venv/bin/activate # Windows 系统:venv\Scripts\activate
# 安装依赖
pip install mcp aiofiles pyyaml
```
或使用项目安装:
```bash
pip install -e .
```
### 2. 配置(可选)
复制并自定义配置:
```bash
cp config/default.yaml config/config.yaml
# 编辑 config/config.yaml 以设置您的首选项
```
或使用环境变量:
```bash
export MCP_LOG_LEVEL=DEBUG
export MCP_WORKSPACE_ROOT=./workspace
export MCP_DEBUG=true
```
## 使用方法
### 运行服务器
服务器使用 stdio 传输进行通信:
```bash
# 直接运行
python src/server.py
# 或作为模块运行
python -m src
```
服务器将:
1. 从 `config/default.yaml` 加载配置(如果存在 `config/config.yaml` 也会加载)
2. 初始化日志到 `logs/mcp_server.log`
3. 从 `tools/` 模块注册所有工具
4. 开始监听 stdin/stdout 的 MCP 消息
### 使用简单客户端测试
测试所有工具而无需 LangGraph:
```bash
python examples/test_client.py
```
这将:
- 连接到 MCP 服务器
- 列出所有可用工具
- 测试计算器操作(加、除、平方根、正弦)
- 测试文件操作(写入、读取、列表、存在)
- 测试错误处理
### 与 LangGraph 集成
```python
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
async def use_mcp_tools():
# 连接到 MCP 服务器
server_params = StdioServerParameters(
command="python",
args=["src/server.py"],
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
# 列出可用工具
tools = await session.list_tools()
# 调用工具
result = await session.call_tool(
"calculator_add",
{"a": 10, "b": 5}
)
print(result.content[0].text)
# 输出:{"result": 15.0, "operation": "add", "operands": {"a": 10, "b": 5}}
asyncio.run(use_mcp_tools())
```
完整示例请参见 `examples/langgraph_integration.py`。
## 配置
### 配置文件(`config/default.yaml`)
```yaml
server:
name: "Local MCP Server"
version: "1.0.0"
debug: false
file_operations:
workspace_root: "./workspace"
enable_sandbox: true
max_file_size: 10 # MB
blocked_extensions: [".exe", ".dll", ".so"]
default_encoding: "utf-8"
logging:
level: "INFO" # DEBUG, INFO, WARNING, ERROR, CRITICAL
file: "./logs/mcp_server.log"
console_output: true
```
### 环境变量
- `MCP_CONFIG_PATH`:用户配置文件路径
- `MCP_LOG_LEVEL`:覆盖日志级别(DEBUG、INFO 等)
- `MCP_WORKSPACE_ROOT`:覆盖工作区根目录
- `MCP_DEBUG`:启用调试模式(true/false)
## 工具返回格式
所有工具返回结构化的 JSON:
**计算器工具:**
```json
{
"result": 15.0,
"operation": "add",
"operands": {"a": 10, "b": 5}
}
```
**文件读取:**
```json
{
"content": "文件内容在这里...",
"metadata": {
"size_bytes": 1024,
"encoding": "utf-8",
"line_count": 50,
"path": "test.txt"
}
}
```
**文件写入:**
```json
{
"success": true,
"bytes_written": 1024,
"path": "output.txt",
"operation": "write"
}
```
**错误:**
```json
{
"error": "不能除以零"
}
```
## 添加新工具
1. 在 `src/tools/your_category/` 中创建新模块
2. 使用 `@tool` 装饰器:
```python
from ..base import tool
@tool(
name="your_tool_name",
description="工具的功能描述",
input_schema={
"type": "object",
"properties": {
"param1": {"type": "string", "description": "参数描述"}
},
"required": ["param1"]
}
)
async def your_tool_function(param1: str) -> dict:
"""工具实现。"""
return {"result": "success"}
```
3. 在 `src/tools/__init__.py` 中导入模块
4. 重启服务器
## 日志记录
日志写入到:
- **文件**:`logs/mcp_server.log`(支持轮转)
- **控制台**:stderr(如果 `console_output: true`)
注意:stdout 保留用于 MCP 协议通信。
日志级别:
- **DEBUG**:详细调试信息(工具参数、结果)
- **INFO**:一般操作(工具调用、文件操作)
- **WARNING**:警告(验证失败、非关键错误)
- **ERROR**:错误(操作失败、异常)
- **CRITICAL**:严重故障(服务器崩溃)
启用调试模式:
```bash
export MCP_DEBUG=true
# 或编辑 config/config.yaml:debug: true
```
## 安全注意事项
### 文件操作安全
1. **沙箱**:所有文件路径必须在 `workspace_root` 内
2. **路径验证**:拒绝绝对路径,防止 `..` 遍历
3. **扩展名过滤**:默认阻止危险扩展名
4. **大小限制**:文件默认限制为 10MB
5. **仅相对路径**:LLM 提供相对路径,如 `data/input.txt`
### 最佳实践
- 以最小权限运行服务器
- 定期检查 `workspace/` 内容
- 根据您的用例自定义 `blocked_extensions`
- 设置适当的 `max_file_size` 限制
- 启用日志记录以监控操作
## 故障排除
### 服务器无法启动
- 检查 Python 版本(需要 Python 3.10+)
- 验证所有依赖已安装:`pip install mcp aiofiles pyyaml`
- 检查 `logs/mcp_server.log` 中的日志
### 工具未找到
- 验证工具模块已在 `src/tools/__init__.py` 中导入
- 检查工具是否使用 `@tool` 装饰器注册
- 添加新工具后重启服务器
### 文件操作错误
- 验证路径是相对的(不是绝对路径)
- 检查路径是否在工作区内:`config.workspace_root`
- 验证文件权限
- 检查文件大小是否超过 `max_file_size` 限制
### 路径验证错误
- 使用正斜杠:`data/file.txt`(不是 `data\file.txt`)
- 不要使用 `..` 或绝对路径
- 确保文件扩展名未被阻止
## 开发
### 运行测试
```bash
# 使用简单客户端测试
python examples/test_client.py
# 使用 LangGraph 测试(需要 API 密钥)
export ANTHROPIC_API_KEY=your_key_here
python examples/langgraph_integration.py
```
### 项目结构
- `src/server.py`:MCP 服务器实现
- `src/config.py`:配置加载和验证
- `src/logger.py`:日志设置
- `src/tools/base.py`:工具注册表和装饰器
- `src/tools/calculator/`:计算器工具
- `src/tools/file_ops/`:文件操作工具
## 许可证
MIT 许可证 - 随意使用和修改您的项目。
## 贡献
欢迎贡献!要添加新工具:
1. 遵循 `src/tools/` 中的模块化结构
2. 使用 `@tool` 装饰器
3. 添加全面的错误处理
4. 更新此 README
## 支持
如有问题或疑问:
1. 查看故障排除部分
2. 查看 `logs/mcp_server.log` 中的日志
3. 启用调试模式以获取详细输出
4. 查看 MCP 文档:https://modelcontextprotocol.io
---
**使用 Anthropic 的 MCP(模型上下文协议)构建**